Exemplo n.º 1
0
func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, block *types.Block, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
	// If we are mining this block and validating we want to set the logs back to 0
	//statedb.EmptyLogs()

	cb := statedb.GetStateObject(coinbase.Address())
	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, block), tx, cb)
	if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
		// If the account is managed, remove the invalid nonce.
		//from, _ := tx.From()
		//self.bc.TxState().RemoveNonce(from, tx.Nonce())
		return nil, nil, err
	}

	// Update the state with pending changes
	statedb.Update()

	cumulative := new(big.Int).Set(usedGas.Add(usedGas, gas))
	receipt := types.NewReceipt(statedb.Root().Bytes(), cumulative)

	logs := statedb.GetLogs(tx.Hash())
	receipt.SetLogs(logs)
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

	glog.V(logger.Debug).Infoln(receipt)

	// Notify all subscribers
	if !transientProcess {
		go self.eventMux.Post(TxPostEvent{tx})
		go self.eventMux.Post(logs)
	}

	return receipt, gas, err
}
Exemplo n.º 2
0
func NewTx(tx *types.Transaction) *Transaction {
	sender, err := tx.From()
	if err != nil {
		return nil
	}
	hash := tx.Hash().Hex()

	var receiver string
	if to := tx.To(); to != nil {
		receiver = to.Hex()
	} else {
		from, _ := tx.From()
		receiver = crypto.CreateAddress(from, tx.Nonce()).Hex()
	}
	createsContract := core.MessageCreatesContract(tx)

	var data string
	if createsContract {
		data = strings.Join(core.Disassemble(tx.Data()), "\n")
	} else {
		data = common.ToHex(tx.Data())
	}

	return &Transaction{ref: tx, Hash: hash, Value: common.CurrencyToString(tx.Value()), Address: receiver, Contract: createsContract, Gas: tx.Gas().String(), GasPrice: tx.GasPrice().String(), Data: data, Sender: sender.Hex(), CreatesContract: createsContract, RawData: common.ToHex(tx.Data())}
}
Exemplo n.º 3
0
func (self *BlockProcessor) ApplyTransaction(gp GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, gp)
	if err != nil {
		return nil, nil, err
	}

	// Update the state with pending changes
	statedb.SyncIntermediate()

	usedGas.Add(usedGas, gas)
	receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas)
	receipt.TxHash = tx.Hash()
	receipt.GasUsed = new(big.Int).Set(gas)
	if MessageCreatesContract(tx) {
		from, _ := tx.From()
		receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce())
	}

	logs := statedb.GetLogs(tx.Hash())
	receipt.SetLogs(logs)
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

	glog.V(logger.Debug).Infoln(receipt)

	// Notify all subscribers
	if !transientProcess {
		go self.eventMux.Post(TxPostEvent{tx})
		go self.eventMux.Post(logs)
	}

	return receipt, gas, err
}
Exemplo n.º 4
0
// validate and queue transactions.
func (self *TxPool) add(tx *types.Transaction) error {
	hash := tx.Hash()

	if self.pending[hash] != nil {
		return fmt.Errorf("Known transaction (%x)", hash[:4])
	}
	err := self.validateTx(tx)
	if err != nil {
		return err
	}
	self.queueTx(hash, tx)

	if glog.V(logger.Debug) {
		var toname string
		if to := tx.To(); to != nil {
			toname = common.Bytes2Hex(to[:4])
		} else {
			toname = "[NEW_CONTRACT]"
		}
		// we can ignore the error here because From is
		// verified in ValidateTransaction.
		f, _ := tx.From()
		from := common.Bytes2Hex(f[:4])
		glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, hash)
	}

	return nil
}
Exemplo n.º 5
0
func (self *BlockProcessor) ApplyTransaction(coinbase *state.StateObject, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, transientProcess bool) (*types.Receipt, *big.Int, error) {
	// If we are mining this block and validating we want to set the logs back to 0

	cb := statedb.GetStateObject(coinbase.Address())
	_, gas, err := ApplyMessage(NewEnv(statedb, self.bc, tx, header), tx, cb)
	if err != nil && (IsNonceErr(err) || state.IsGasLimitErr(err) || IsInvalidTxErr(err)) {
		return nil, nil, err
	}

	// Update the state with pending changes
	statedb.Update()

	usedGas.Add(usedGas, gas)
	receipt := types.NewReceipt(statedb.Root().Bytes(), usedGas)
	logs := statedb.GetLogs(tx.Hash())
	receipt.SetLogs(logs)
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

	glog.V(logger.Debug).Infoln(receipt)

	// Notify all subscribers
	if !transientProcess {
		go self.eventMux.Post(TxPostEvent{tx})
		go self.eventMux.Post(logs)
	}

	return receipt, gas, err
}
Exemplo n.º 6
0
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
	hash := tx.Hash()
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
		return tx, err
	}
	return tx.WithSignature(sig)
}
Exemplo n.º 7
0
func (self *ImportMaster) importTx(tx *types.Transaction, blockId *bson.ObjectId) {
	if glog.V(logger.Info) {
		glog.Infoln("Importing tx", tx.Hash().Hex())
	}
	err := self.txCollection.Insert(self.parseTx(tx, blockId))
	if err != nil {
		clilogger.Infoln(err)
	}
}
Exemplo n.º 8
0
func (pool *TxPool) addTx(tx *types.Transaction) {
	if _, ok := pool.txs[tx.Hash()]; !ok {
		pool.txs[tx.Hash()] = tx
		// Notify the subscribers. This event is posted in a goroutine
		// because it's possible that somewhere during the post "Remove transaction"
		// gets called which will then wait for the global tx pool lock and deadlock.
		go pool.eventMux.Post(TxPreEvent{tx})
	}
}
Exemplo n.º 9
0
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
	hash := tx.Hash()
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}
Exemplo n.º 10
0
// validateTx checks whether a transaction is valid according
// to the consensus rules.
func (pool *TxPool) validateTx(tx *types.Transaction) error {
	local := pool.localTx.contains(tx.Hash())
	// Drop transactions under our own minimal accepted gas price
	if !local && pool.minGasPrice.Cmp(tx.GasPrice()) > 0 {
		return ErrCheap
	}

	currentState, err := pool.currentState()
	if err != nil {
		return err
	}

	from, err := tx.From()
	if err != nil {
		return ErrInvalidSender
	}

	// Make sure the account exist. Non existent accounts
	// haven't got funds and well therefor never pass.
	if !currentState.HasAccount(from) {
		return ErrNonExistentAccount
	}

	// Last but not least check for nonce errors
	if currentState.GetNonce(from) > tx.Nonce() {
		return ErrNonce
	}

	// Check the transaction doesn't exceed the current
	// block limit gas.
	if pool.gasLimit().Cmp(tx.Gas()) < 0 {
		return ErrGasLimit
	}

	// Transactions can't be negative. This may never happen
	// using RLP decoded transactions but may occur if you create
	// a transaction using the RPC for example.
	if tx.Value().Cmp(common.Big0) < 0 {
		return ErrNegativeValue
	}

	// Transactor should have enough funds to cover the costs
	// cost == V + GP * GL
	if currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
		return ErrInsufficientFunds
	}

	intrGas := IntrinsicGas(tx.Data(), MessageCreatesContract(tx), pool.homestead)
	if tx.Gas().Cmp(intrGas) < 0 {
		return ErrIntrinsicGas
	}

	return nil
}
Exemplo n.º 11
0
// AddTx adds a transaction to the generated block. If no coinbase has
// been set, the block's coinbase is set to the zero address.
//
// AddTx panics if the transaction cannot be executed. In addition to
// the protocol-imposed limitations (gas limit, etc.), there are some
// further limitations on the content of transactions that can be
// added. Notably, contract code relying on the BLOCKHASH instruction
// will panic during execution.
func (b *BlockGen) AddTx(tx *types.Transaction) {
	if b.gasPool == nil {
		b.SetCoinbase(common.Address{})
	}
	b.statedb.StartRecord(tx.Hash(), common.Hash{}, len(b.txs))
	receipt, _, _, err := ApplyTransaction(nil, b.gasPool, b.statedb, b.header, tx, b.header.GasUsed, nil)
	if err != nil {
		panic(err)
	}
	b.txs = append(b.txs, tx)
	b.receipts = append(b.receipts, receipt)
}
Exemplo n.º 12
0
func (self *ImportMaster) parseTx(tx *types.Transaction, blockId *bson.ObjectId) *Transaction {
	hash := tx.Hash().Hex()
	from, err := tx.From()
	if err != nil {
		utils.Fatalf("Could not parse from address: %v", err)
	}
	var recipient string
	if tx.Recipient != nil {
		recipient = tx.Recipient.Hex()
	}
	txx := &Transaction{hash, recipient, from.Hex(), tx.Amount.String(), tx.Price.String(), tx.GasLimit.String(), tx.Payload, blockId}
	return txx
}
Exemplo n.º 13
0
// AddTx adds a transaction to the generated block. If no coinbase has
// been set, the block's coinbase is set to the zero address.
//
// AddTx panics if the transaction cannot be executed. In addition to
// the protocol-imposed limitations (gas limit, etc.), there are some
// further limitations on the content of transactions that can be
// added. Notably, contract code relying on the BLOCKHASH instruction
// will panic during execution.
func (b *BlockGen) AddTx(tx *types.Transaction) {
	if b.coinbase == nil {
		b.SetCoinbase(common.Address{})
	}
	_, gas, err := ApplyMessage(NewEnv(b.statedb, nil, tx, b.header), tx, b.coinbase)
	if err != nil {
		panic(err)
	}
	b.statedb.SyncIntermediate()
	b.header.GasUsed.Add(b.header.GasUsed, gas)
	receipt := types.NewReceipt(b.statedb.Root().Bytes(), b.header.GasUsed)
	logs := b.statedb.GetLogs(tx.Hash())
	receipt.SetLogs(logs)
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
	b.txs = append(b.txs, tx)
	b.receipts = append(b.receipts, receipt)
}
Exemplo n.º 14
0
func newTx(t *types.Transaction) *tx {
	from, _ := t.From()
	var to string
	if t := t.To(); t != nil {
		to = t.Hex()
	}

	return &tx{
		tx:       t,
		To:       to,
		From:     from.Hex(),
		Value:    t.Value().String(),
		Nonce:    strconv.Itoa(int(t.Nonce())),
		Data:     "0x" + common.Bytes2Hex(t.Data()),
		GasLimit: t.Gas().String(),
		GasPrice: t.GasPrice().String(),
		Hash:     t.Hash().Hex(),
	}
}
Exemplo n.º 15
0
func NewTransactionRes(tx *types.Transaction) *TransactionRes {
	if tx == nil {
		return nil
	}

	var v = new(TransactionRes)
	v.Hash = newHexData(tx.Hash())
	v.Nonce = newHexNum(tx.Nonce())
	// v.BlockHash =
	// v.BlockNumber =
	// v.TxIndex =
	from, _ := tx.From()
	v.From = newHexData(from)
	v.To = newHexData(tx.To())
	v.Value = newHexNum(tx.Value())
	v.Gas = newHexNum(tx.Gas())
	v.GasPrice = newHexNum(tx.GasPrice())
	v.Input = newHexData(tx.Data())
	return v
}
Exemplo n.º 16
0
func (self *XEth) PushTx(encodedTx string) (string, error) {
	tx := new(types.Transaction)
	err := rlp.DecodeBytes(common.FromHex(encodedTx), tx)
	if err != nil {
		glog.V(logger.Error).Infoln(err)
		return "", err
	}

	err = self.backend.TxPool().Add(tx)
	if err != nil {
		return "", err
	}

	if tx.To() == nil {
		from, err := tx.From()
		if err != nil {
			return "", err
		}

		addr := crypto.CreateAddress(from, tx.Nonce())
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
	}

	return tx.Hash().Hex(), nil
}
Exemplo n.º 17
0
func putTx(db common.Database, tx *types.Transaction, block *types.Block, i uint64) {
	rlpEnc, err := rlp.EncodeToBytes(tx)
	if err != nil {
		glog.V(logger.Debug).Infoln("Failed encoding tx", err)
		return
	}
	db.Put(tx.Hash().Bytes(), rlpEnc)

	var txExtra struct {
		BlockHash  common.Hash
		BlockIndex uint64
		Index      uint64
	}
	txExtra.BlockHash = block.Hash()
	txExtra.BlockIndex = block.NumberU64()
	txExtra.Index = i
	rlpMeta, err := rlp.EncodeToBytes(txExtra)
	if err != nil {
		glog.V(logger.Debug).Infoln("Failed encoding tx meta data", err)
		return
	}
	db.Put(append(tx.Hash().Bytes(), 0x0001), rlpMeta)
}
Exemplo n.º 18
0
func (self *TxPool) add(tx *types.Transaction) error {
	hash := tx.Hash()

	/* XXX I'm unsure about this. This is extremely dangerous and may result
	 in total black listing of certain transactions
	if self.invalidHashes.Has(hash) {
		return fmt.Errorf("Invalid transaction (%x)", hash[:4])
	}
	*/
	if self.txs[hash] != nil {
		return fmt.Errorf("Known transaction (%x)", hash[:4])
	}
	err := self.ValidateTransaction(tx)
	if err != nil {
		return err
	}

	self.queueTx(tx)

	var toname string
	if to := tx.To(); to != nil {
		toname = common.Bytes2Hex(to[:4])
	} else {
		toname = "[NEW_CONTRACT]"
	}
	// we can ignore the error here because From is
	// verified in ValidateTransaction.
	f, _ := tx.From()
	from := common.Bytes2Hex(f[:4])

	if glog.V(logger.Debug) {
		glog.Infof("(t) %x => %s (%v) %x\n", from, toname, tx.Value, tx.Hash())
	}

	return nil
}
Exemplo n.º 19
0
// ApplyTransaction attempts to apply a transaction to the given state database
// and uses the input parameters for its environment.
//
// ApplyTransactions returns the generated receipts and vm logs during the
// execution of the state transition phase.
func ApplyTransaction(config *ChainConfig, bc *BlockChain, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *big.Int, cfg vm.Config) (*types.Receipt, vm.Logs, *big.Int, error) {
	_, gas, err := ApplyMessage(NewEnv(statedb, config, bc, tx, header, cfg), tx, gp)
	if err != nil {
		return nil, nil, nil, err
	}

	// Update the state with pending changes
	usedGas.Add(usedGas, gas)
	receipt := types.NewReceipt(statedb.IntermediateRoot().Bytes(), usedGas)
	receipt.TxHash = tx.Hash()
	receipt.GasUsed = new(big.Int).Set(gas)
	if MessageCreatesContract(tx) {
		from, _ := tx.From()
		receipt.ContractAddress = crypto.CreateAddress(from, tx.Nonce())
	}

	logs := statedb.GetLogs(tx.Hash())
	receipt.Logs = logs
	receipt.Bloom = types.CreateBloom(types.Receipts{receipt})

	glog.V(logger.Debug).Infoln(receipt)

	return receipt, logs, gas, err
}
Exemplo n.º 20
0
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {
	var (
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
		value            = common.NewValue(valueStr)
		gas              = common.Big(gasStr)
		price            = common.Big(gasPriceStr)
		data             []byte
		contractCreation bool
	)

	// TODO if no_private_key then
	//if _, exists := p.register[args.From]; exists {
	//	p.register[args.From] = append(p.register[args.From], args)
	//} else {
	/*
		account := accounts.Get(common.FromHex(args.From))
		if account != nil {
			if account.Unlocked() {
				if !unlockAccount(account) {
					return
				}
			}

			result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data))
			if len(result) > 0 {
				*reply = common.ToHex(result)
			}
		} else if _, exists := p.register[args.From]; exists {
			p.register[ags.From] = append(p.register[args.From], args)
		}
	*/

	// TODO: align default values to have the same type, e.g. not depend on
	// common.Value conversions later on
	if gas.Cmp(big.NewInt(0)) == 0 {
		gas = DefaultGas()
	}

	if price.Cmp(big.NewInt(0)) == 0 {
		price = DefaultGasPrice()
	}

	data = common.FromHex(codeStr)
	if len(toStr) == 0 {
		contractCreation = true
	}

	var tx *types.Transaction
	if contractCreation {
		tx = types.NewContractCreationTx(value.BigInt(), gas, price, data)
	} else {
		tx = types.NewTransactionMessage(to, value.BigInt(), gas, price, data)
	}

	state := self.backend.ChainManager().TxState()

	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
		nonce = state.NewNonce(from)
	}
	tx.SetNonce(nonce)

	if err := self.sign(tx, from, false); err != nil {
		return "", err
	}
	if err := self.backend.TxPool().Add(tx); err != nil {
		return "", err
	}

	if contractCreation {
		addr := core.AddressFromMessage(tx)
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)

		return core.AddressFromMessage(tx).Hex(), nil
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
	}
	return tx.Hash().Hex(), nil
}
Exemplo n.º 21
0
func (self *XEth) Transact(fromStr, toStr, nonceStr, valueStr, gasStr, gasPriceStr, codeStr string) (string, error) {

	// this minimalistic recoding is enough (works for natspec.js)
	var jsontx = fmt.Sprintf(`{"params":[{"to":"%s","data": "%s"}]}`, toStr, codeStr)
	if !self.ConfirmTransaction(jsontx) {
		err := fmt.Errorf("Transaction not confirmed")
		return "", err
	}

	var (
		from             = common.HexToAddress(fromStr)
		to               = common.HexToAddress(toStr)
		value            = common.Big(valueStr)
		gas              *big.Int
		price            *big.Int
		data             []byte
		contractCreation bool
	)

	if len(gasStr) == 0 {
		gas = DefaultGas()
	} else {
		gas = common.Big(gasStr)
	}

	if len(gasPriceStr) == 0 {
		price = self.DefaultGasPrice()
	} else {
		price = common.Big(gasPriceStr)
	}

	data = common.FromHex(codeStr)
	if len(toStr) == 0 {
		contractCreation = true
	}

	// 2015-05-18 Is this still needed?
	// TODO if no_private_key then
	//if _, exists := p.register[args.From]; exists {
	//	p.register[args.From] = append(p.register[args.From], args)
	//} else {
	/*
		account := accounts.Get(common.FromHex(args.From))
		if account != nil {
			if account.Unlocked() {
				if !unlockAccount(account) {
					return
				}
			}

			result, _ := account.Transact(common.FromHex(args.To), common.FromHex(args.Value), common.FromHex(args.Gas), common.FromHex(args.GasPrice), common.FromHex(args.Data))
			if len(result) > 0 {
				*reply = common.ToHex(result)
			}
		} else if _, exists := p.register[args.From]; exists {
			p.register[ags.From] = append(p.register[args.From], args)
		}
	*/

	// TODO: align default values to have the same type, e.g. not depend on
	// common.Value conversions later on
	var nonce uint64
	if len(nonceStr) != 0 {
		nonce = common.Big(nonceStr).Uint64()
	} else {
		state := self.backend.TxPool().State()
		nonce = state.GetNonce(from)
	}
	var tx *types.Transaction
	if contractCreation {
		tx = types.NewContractCreation(nonce, value, gas, price, data)
	} else {
		tx = types.NewTransaction(nonce, to, value, gas, price, data)
	}

	signed, err := self.sign(tx, from, false)
	if err != nil {
		return "", err
	}
	if err = self.backend.TxPool().Add(signed); err != nil {
		return "", err
	}

	if contractCreation {
		addr := crypto.CreateAddress(from, nonce)
		glog.V(logger.Info).Infof("Tx(%x) created: %x\n", tx.Hash(), addr)
	} else {
		glog.V(logger.Info).Infof("Tx(%x) to: %x\n", tx.Hash(), tx.To())
	}

	return signed.Hash().Hex(), nil
}
Exemplo n.º 22
0
func (p *peer) sendTransaction(tx *types.Transaction) error {
	p.txHashes.Add(tx.Hash())

	return p2p.Send(p.rw, TxMsg, []*types.Transaction{tx})
}
Exemplo n.º 23
0
// SetLocal marks a transaction as local, skipping gas price
//  check against local miner minimum in the future
func (pool *TxPool) SetLocal(tx *types.Transaction) {
	pool.mu.Lock()
	defer pool.mu.Unlock()
	pool.localTx.add(tx.Hash())
}
Exemplo n.º 24
0
// Tests that if a transaction is dropped from the current pending pool (e.g. out
// of fund), all consecutive (still valid, but not executable) transactions are
// postponed back into the future queue to prevent broadcasting them.
func TestTransactionPostponing(t *testing.T) {
	// Create a test account and fund it
	pool, key := setupTxPool()
	account, _ := transaction(0, big.NewInt(0), key).From()

	state, _ := pool.currentState()
	state.AddBalance(account, big.NewInt(1000))

	// Add a batch consecutive pending transactions for validation
	txns := []*types.Transaction{}
	for i := 0; i < 100; i++ {
		var tx *types.Transaction
		if i%2 == 0 {
			tx = transaction(uint64(i), big.NewInt(100), key)
		} else {
			tx = transaction(uint64(i), big.NewInt(500), key)
		}
		pool.addTx(tx.Hash(), account, tx)
		txns = append(txns, tx)
	}
	// Check that pre and post validations leave the pool as is
	if len(pool.pending) != len(txns) {
		t.Errorf("pending transaction mismatch: have %d, want %d", len(pool.pending), len(txns))
	}
	if len(pool.queue[account]) != 0 {
		t.Errorf("queued transaction mismatch: have %d, want %d", len(pool.queue), 0)
	}
	pool.resetState()
	if len(pool.pending) != len(txns) {
		t.Errorf("pending transaction mismatch: have %d, want %d", len(pool.pending), len(txns))
	}
	if len(pool.queue[account]) != 0 {
		t.Errorf("queued transaction mismatch: have %d, want %d", len(pool.queue), 0)
	}
	// Reduce the balance of the account, and check that transactions are reorganised
	state.AddBalance(account, big.NewInt(-750))
	pool.resetState()

	if _, ok := pool.pending[txns[0].Hash()]; !ok {
		t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txns[0])
	}
	if _, ok := pool.queue[account][txns[0].Hash()]; ok {
		t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txns[0])
	}
	for i, tx := range txns[1:] {
		if i%2 == 1 {
			if _, ok := pool.pending[tx.Hash()]; ok {
				t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx)
			}
			if _, ok := pool.queue[account][tx.Hash()]; !ok {
				t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx)
			}
		} else {
			if _, ok := pool.pending[tx.Hash()]; ok {
				t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx)
			}
			if _, ok := pool.queue[account][tx.Hash()]; ok {
				t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx)
			}
		}
	}
}
Exemplo n.º 25
0
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) error {
	sig, err := self.backend.AccountManager().Sign(accounts.Account{Address: from.Bytes()}, tx.Hash().Bytes())
	if err == accounts.ErrLocked {
		if didUnlock {
			return fmt.Errorf("sender account still locked after successful unlock")
		}
		if !self.frontend.UnlockAccount(from.Bytes()) {
			return fmt.Errorf("could not unlock sender account")
		}
		// retry signing, the account should now be unlocked.
		return self.sign(tx, from, true)
	} else if err != nil {
		return err
	}
	tx.SetSignatureValues(sig)
	return nil
}