Example #1
0
// queueTx will queue an unknown transaction
func (self *TxPool) queueTx(hash common.Hash, tx *types.Transaction) {
	from, _ := tx.From() // already validated
	if self.queue[from] == nil {
		self.queue[from] = make(map[common.Hash]*types.Transaction)
	}
	self.queue[from][hash] = tx
}
Example #2
0
// queueTx will queue an unknown transaction
func (self *TxPool) queueTx(hash common.Hash, tx *types.Transaction, owned bool) {
	from, _ := tx.From() // already validated
	if self.queue[from] == nil {
		self.queue[from] = make(map[common.Hash]*poolTx)
	}
	self.queue[from][hash] = &poolTx{tx, owned, time.Now(), time.Time{}, 0}
}
Example #3
0
func (self *XEth) sign(tx *types.Transaction, from common.Address, didUnlock bool) (*types.Transaction, error) {
	hash := tx.SigHash()
	sig, err := self.doSign(from, hash, didUnlock)
	if err != nil {
		return tx, err
	}
	return tx.WithSignature(sig)
}
Example #4
0
// addTx will add a transaction to the pending (processable queue) list of transactions
func (pool *TxPool) addTx(hash common.Hash, addr common.Address, tx *types.Transaction) {
	if _, ok := pool.pending[hash]; !ok {
		pool.pending[hash] = tx

		// Increment the nonce on the pending state. This can only happen if
		// the nonce is +1 to the previous one.
		pool.pendingState.SetNonce(addr, tx.Nonce()+1)
		// 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})
	}
}
Example #5
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
}
Example #6
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)
}
Example #7
0
// validate and queue transactions.
func (self *TxPool) add(tx *types.Transaction, owned bool) 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, owned)

	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
}
Example #8
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
	}

	if len(toStr) > 0 && toStr != "0x" && !isAddress(toStr) {
		return "", errors.New("Invalid address")
	}

	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
	}

	if gas.Cmp(big.NewInt(90000)) < 0 {
		glog.Infof("(Gas set to %v for hash: %x. Miners can ignore transactions with a low amount of gas.", gas, toStr)
	}

	// 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)
		}
	*/

	self.transactMu.Lock()
	defer self.transactMu.Unlock()

	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, true); err != nil {
		return "", err
	}

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

	return signed.Hash().Hex(), nil
}
Example #9
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, true)
	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
}
Example #10
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
}
Example #11
0
// validateTx checks whether a transaction is valid according
// to the consensus rules.
func (pool *TxPool) validateTx(tx *types.Transaction) error {
	// Validate sender
	var (
		from common.Address
		err  error
	)

	// Drop transactions under our own minimal accepted gas price
	if pool.minGasPrice.Cmp(tx.GasPrice()) > 0 {
		return ErrCheap
	}

	// Validate the transaction sender and it's sig. Throw
	// if the from fields is invalid.
	if from, err = tx.From(); err != nil {
		return ErrInvalidSender
	}

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

	// Last but not least check for nonce errors
	if pool.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 pool.currentState().GetBalance(from).Cmp(tx.Cost()) < 0 {
		return ErrInsufficientFunds
	}

	// Should supply enough intrinsic gas
	if tx.Gas().Cmp(IntrinsicGas(tx.Data())) < 0 {
		return ErrIntrinsicGas
	}

	return nil
}
Example #12
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(),
	}
}
Example #13
0
func verifyTxFields(txTest TransactionTest, decodedTx *types.Transaction) (err error) {
	defer func() {
		if recovered := recover(); recovered != nil {
			buf := make([]byte, 64<<10)
			buf = buf[:runtime.Stack(buf, false)]
			err = fmt.Errorf("%v\n%s", recovered, buf)
		}
	}()

	decodedSender, err := decodedTx.From()
	if err != nil {
		return err
	}

	expectedSender := mustConvertAddress(txTest.Sender)
	if expectedSender != decodedSender {
		return fmt.Errorf("Sender mismatch: %v %v", expectedSender, decodedSender)
	}

	expectedData := mustConvertBytes(txTest.Transaction.Data)
	if !bytes.Equal(expectedData, decodedTx.Data()) {
		return fmt.Errorf("Tx input data mismatch: %#v %#v", expectedData, decodedTx.Data())
	}

	expectedGasLimit := mustConvertBigInt(txTest.Transaction.GasLimit, 16)
	if expectedGasLimit.Cmp(decodedTx.Gas()) != 0 {
		return fmt.Errorf("GasLimit mismatch: %v %v", expectedGasLimit, decodedTx.Gas())
	}

	expectedGasPrice := mustConvertBigInt(txTest.Transaction.GasPrice, 16)
	if expectedGasPrice.Cmp(decodedTx.GasPrice()) != 0 {
		return fmt.Errorf("GasPrice mismatch: %v %v", expectedGasPrice, decodedTx.GasPrice())
	}

	expectedNonce := mustConvertUint(txTest.Transaction.Nonce, 16)
	if expectedNonce != decodedTx.Nonce() {
		return fmt.Errorf("Nonce mismatch: %v %v", expectedNonce, decodedTx.Nonce())
	}

	v, r, s := decodedTx.SignatureValues()
	expectedR := mustConvertBigInt(txTest.Transaction.R, 16)
	if r.Cmp(expectedR) != 0 {
		return fmt.Errorf("R mismatch: %v %v", expectedR, r)
	}
	expectedS := mustConvertBigInt(txTest.Transaction.S, 16)
	if s.Cmp(expectedS) != 0 {
		return fmt.Errorf("S mismatch: %v %v", expectedS, s)
	}
	expectedV := mustConvertUint(txTest.Transaction.V, 16)
	if uint64(v) != expectedV {
		return fmt.Errorf("V mismatch: %v %v", expectedV, v)
	}

	expectedTo := mustConvertAddress(txTest.Transaction.To)
	if decodedTx.To() == nil {
		if expectedTo != common.BytesToAddress([]byte{}) { // "empty" or "zero" address
			return fmt.Errorf("To mismatch when recipient is nil (contract creation): %v", expectedTo)
		}
	} else {
		if expectedTo != *decodedTx.To() {
			return fmt.Errorf("To mismatch: %v %v", expectedTo, *decodedTx.To())
		}
	}

	expectedValue := mustConvertBigInt(txTest.Transaction.Value, 16)
	if expectedValue.Cmp(decodedTx.Value()) != 0 {
		return fmt.Errorf("Value mismatch: %v %v", expectedValue, decodedTx.Value())
	}

	return nil
}
Example #14
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())}
}