github.com/codingfuture/orig-energi3@v0.8.4/core/types/transaction.go (about)

     1  // Copyright 2018 The Energi Core Authors
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the Energi Core library.
     4  //
     5  // The Energi Core library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The Energi Core library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package types
    19  
    20  import (
    21  	"container/heap"
    22  	"errors"
    23  	"io"
    24  	"math/big"
    25  	"sync/atomic"
    26  
    27  	"github.com/ethereum/go-ethereum/common"
    28  	"github.com/ethereum/go-ethereum/common/hexutil"
    29  	"github.com/ethereum/go-ethereum/crypto"
    30  	"github.com/ethereum/go-ethereum/rlp"
    31  )
    32  
    33  //go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
    34  
    35  var (
    36  	ErrInvalidSig = errors.New("invalid transaction v, r, s values")
    37  )
    38  
    39  type Transaction struct {
    40  	data txdata
    41  	// caches
    42  	hash atomic.Value
    43  	size atomic.Value
    44  	from atomic.Value
    45  }
    46  
    47  type txdata struct {
    48  	AccountNonce uint64          `json:"nonce"    gencodec:"required"`
    49  	Price        *big.Int        `json:"gasPrice" gencodec:"required"`
    50  	GasLimit     uint64          `json:"gas"      gencodec:"required"`
    51  	Recipient    *common.Address `json:"to"       rlp:"nil"` // nil means contract creation
    52  	Amount       *big.Int        `json:"value"    gencodec:"required"`
    53  	Payload      []byte          `json:"input"    gencodec:"required"`
    54  
    55  	// Signature values
    56  	V *big.Int `json:"v" gencodec:"required"`
    57  	R *big.Int `json:"r" gencodec:"required"`
    58  	S *big.Int `json:"s" gencodec:"required"`
    59  
    60  	// This is only used when marshaling to JSON.
    61  	Hash *common.Hash `json:"hash" rlp:"-"`
    62  }
    63  
    64  type txdataMarshaling struct {
    65  	AccountNonce hexutil.Uint64
    66  	Price        *hexutil.Big
    67  	GasLimit     hexutil.Uint64
    68  	Amount       *hexutil.Big
    69  	Payload      hexutil.Bytes
    70  	V            *hexutil.Big
    71  	R            *hexutil.Big
    72  	S            *hexutil.Big
    73  }
    74  
    75  func NewTransaction(nonce uint64, to common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    76  	return newTransaction(nonce, &to, amount, gasLimit, gasPrice, data)
    77  }
    78  
    79  func NewContractCreation(nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    80  	return newTransaction(nonce, nil, amount, gasLimit, gasPrice, data)
    81  }
    82  
    83  func newTransaction(nonce uint64, to *common.Address, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte) *Transaction {
    84  	if len(data) > 0 {
    85  		data = common.CopyBytes(data)
    86  	}
    87  	d := txdata{
    88  		AccountNonce: nonce,
    89  		Recipient:    to,
    90  		Payload:      data,
    91  		Amount:       new(big.Int),
    92  		GasLimit:     gasLimit,
    93  		Price:        new(big.Int),
    94  		V:            new(big.Int),
    95  		R:            new(big.Int),
    96  		S:            new(big.Int),
    97  	}
    98  	if amount != nil {
    99  		d.Amount.Set(amount)
   100  	}
   101  	if gasPrice != nil {
   102  		d.Price.Set(gasPrice)
   103  	}
   104  
   105  	return &Transaction{data: d}
   106  }
   107  
   108  // ChainId returns which chain id this transaction was signed for (if at all)
   109  func (tx *Transaction) ChainId() *big.Int {
   110  	return deriveChainId(tx.data.V)
   111  }
   112  
   113  // Protected returns whether the transaction is protected from replay protection.
   114  func (tx *Transaction) Protected() bool {
   115  	return isProtectedV(tx.data.V)
   116  }
   117  
   118  func isProtectedV(V *big.Int) bool {
   119  	if V.BitLen() <= 8 {
   120  		v := V.Uint64()
   121  		return v != 27 && v != 28
   122  	}
   123  	// anything not 27 or 28 is considered protected
   124  	return true
   125  }
   126  
   127  // EncodeRLP implements rlp.Encoder
   128  func (tx *Transaction) EncodeRLP(w io.Writer) error {
   129  	return rlp.Encode(w, &tx.data)
   130  }
   131  
   132  // DecodeRLP implements rlp.Decoder
   133  func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
   134  	_, size, _ := s.Kind()
   135  	err := s.Decode(&tx.data)
   136  	if err == nil {
   137  		tx.size.Store(common.StorageSize(rlp.ListSize(size)))
   138  	}
   139  
   140  	return err
   141  }
   142  
   143  // MarshalJSON encodes the web3 RPC transaction format.
   144  func (tx *Transaction) MarshalJSON() ([]byte, error) {
   145  	hash := tx.Hash()
   146  	data := tx.data
   147  	data.Hash = &hash
   148  	return data.MarshalJSON()
   149  }
   150  
   151  // UnmarshalJSON decodes the web3 RPC transaction format.
   152  func (tx *Transaction) UnmarshalJSON(input []byte) error {
   153  	var dec txdata
   154  	if err := dec.UnmarshalJSON(input); err != nil {
   155  		return err
   156  	}
   157  
   158  	withSignature := dec.V.Sign() != 0 || dec.R.Sign() != 0 || dec.S.Sign() != 0
   159  	if withSignature {
   160  		var V byte
   161  		if isProtectedV(dec.V) {
   162  			chainID := deriveChainId(dec.V).Uint64()
   163  			V = byte(dec.V.Uint64() - 35 - 2*chainID)
   164  		} else {
   165  			V = byte(dec.V.Uint64() - 27)
   166  		}
   167  		if !crypto.ValidateSignatureValues(V, dec.R, dec.S, false) {
   168  			return ErrInvalidSig
   169  		}
   170  	}
   171  
   172  	*tx = Transaction{data: dec}
   173  	return nil
   174  }
   175  
   176  func (tx *Transaction) Data() []byte       { return common.CopyBytes(tx.data.Payload) }
   177  func (tx *Transaction) Gas() uint64        { return tx.data.GasLimit }
   178  func (tx *Transaction) GasPrice() *big.Int { return new(big.Int).Set(tx.data.Price) }
   179  func (tx *Transaction) Value() *big.Int    { return new(big.Int).Set(tx.data.Amount) }
   180  func (tx *Transaction) Nonce() uint64      { return tx.data.AccountNonce }
   181  func (tx *Transaction) CheckNonce() bool   { return true }
   182  
   183  const MethodIDLen = 4
   184  
   185  type MethodID [MethodIDLen]byte
   186  
   187  func (tx *Transaction) MethodID() (res MethodID) {
   188  	if len(tx.data.Payload) < MethodIDLen {
   189  		return MethodID{}
   190  	}
   191  
   192  	copy(res[:], tx.data.Payload[:MethodIDLen])
   193  	return
   194  }
   195  
   196  // To returns the recipient address of the transaction.
   197  // It returns nil if the transaction is a contract creation.
   198  func (tx *Transaction) To() *common.Address {
   199  	if tx.data.Recipient == nil {
   200  		return nil
   201  	}
   202  	to := *tx.data.Recipient
   203  	return &to
   204  }
   205  
   206  // Hash hashes the RLP encoding of tx.
   207  // It uniquely identifies the transaction.
   208  func (tx *Transaction) Hash() common.Hash {
   209  	if hash := tx.hash.Load(); hash != nil {
   210  		return hash.(common.Hash)
   211  	}
   212  	v := rlpHash(tx)
   213  	tx.hash.Store(v)
   214  	return v
   215  }
   216  
   217  // Size returns the true RLP encoded storage size of the transaction, either by
   218  // encoding and returning it, or returning a previsouly cached value.
   219  func (tx *Transaction) Size() common.StorageSize {
   220  	if size := tx.size.Load(); size != nil {
   221  		return size.(common.StorageSize)
   222  	}
   223  	c := writeCounter(0)
   224  	rlp.Encode(&c, &tx.data)
   225  	tx.size.Store(common.StorageSize(c))
   226  	return common.StorageSize(c)
   227  }
   228  
   229  // AsMessage returns the transaction as a core.Message.
   230  //
   231  // AsMessage requires a signer to derive the sender.
   232  //
   233  // XXX Rename message to something less arbitrary?
   234  func (tx *Transaction) AsMessage(s Signer) (Message, error) {
   235  	msg := Message{
   236  		nonce:      tx.data.AccountNonce,
   237  		gasLimit:   tx.data.GasLimit,
   238  		gasPrice:   new(big.Int).Set(tx.data.Price),
   239  		to:         tx.data.Recipient,
   240  		amount:     tx.data.Amount,
   241  		data:       tx.data.Payload,
   242  		checkNonce: true,
   243  	}
   244  
   245  	var err error
   246  	msg.from, err = Sender(s, tx)
   247  	return msg, err
   248  }
   249  
   250  // WithSignature returns a new transaction with the given signature.
   251  // This signature needs to be in the [R || S || V] format where V is 0 or 1.
   252  func (tx *Transaction) WithSignature(signer Signer, sig []byte) (*Transaction, error) {
   253  	r, s, v, err := signer.SignatureValues(tx, sig)
   254  	if err != nil {
   255  		return nil, err
   256  	}
   257  	cpy := &Transaction{data: tx.data}
   258  	cpy.data.R, cpy.data.S, cpy.data.V = r, s, v
   259  	return cpy, nil
   260  }
   261  
   262  // Cost returns amount + gasprice * gaslimit.
   263  func (tx *Transaction) Cost() *big.Int {
   264  	total := new(big.Int).Mul(tx.data.Price, new(big.Int).SetUint64(tx.data.GasLimit))
   265  	total.Add(total, tx.data.Amount)
   266  	return total
   267  }
   268  
   269  func (tx *Transaction) RawSignatureValues() (*big.Int, *big.Int, *big.Int) {
   270  	return tx.data.V, tx.data.R, tx.data.S
   271  }
   272  
   273  //---
   274  // NOTE: must only be used for presentation purposes!
   275  func (tx *Transaction) IsConsensus() bool {
   276  	return (tx.data.V.Sign() != 0) && (tx.data.R.Sign() == 0) && (tx.data.S.Sign() == 0)
   277  }
   278  
   279  func (tx *Transaction) ConsensusSender() common.Address {
   280  	return common.BigToAddress(tx.data.V)
   281  }
   282  func (tx *Transaction) WithConsensusSender(sender common.Address) *Transaction {
   283  	cpy := &Transaction{data: tx.data}
   284  	cpy.data.V = sender.Big()
   285  	cpy.data.R, cpy.data.S = new(big.Int), new(big.Int)
   286  	return cpy
   287  }
   288  
   289  //---
   290  
   291  // Transactions is a Transaction slice type for basic sorting.
   292  type Transactions []*Transaction
   293  
   294  // Len returns the length of s.
   295  func (s Transactions) Len() int { return len(s) }
   296  
   297  // Swap swaps the i'th and the j'th element in s.
   298  func (s Transactions) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
   299  
   300  // GetRlp implements Rlpable and returns the i'th element of s in rlp.
   301  func (s Transactions) GetRlp(i int) []byte {
   302  	enc, _ := rlp.EncodeToBytes(s[i])
   303  	return enc
   304  }
   305  
   306  // TxDifference returns a new set which is the difference between a and b.
   307  func TxDifference(a, b Transactions) Transactions {
   308  	keep := make(Transactions, 0, len(a))
   309  
   310  	remove := make(map[common.Hash]struct{})
   311  	for _, tx := range b {
   312  		remove[tx.Hash()] = struct{}{}
   313  	}
   314  
   315  	for _, tx := range a {
   316  		if _, ok := remove[tx.Hash()]; !ok {
   317  			keep = append(keep, tx)
   318  		}
   319  	}
   320  
   321  	return keep
   322  }
   323  
   324  // TxByNonce implements the sort interface to allow sorting a list of transactions
   325  // by their nonces. This is usually only useful for sorting transactions from a
   326  // single account, otherwise a nonce comparison doesn't make much sense.
   327  type TxByNonce Transactions
   328  
   329  func (s TxByNonce) Len() int           { return len(s) }
   330  func (s TxByNonce) Less(i, j int) bool { return s[i].data.AccountNonce < s[j].data.AccountNonce }
   331  func (s TxByNonce) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   332  
   333  // TxByPrice implements both the sort and the heap interface, making it useful
   334  // for all at once sorting as well as individually adding and removing elements.
   335  type TxByPrice Transactions
   336  
   337  func (s TxByPrice) Len() int           { return len(s) }
   338  func (s TxByPrice) Less(i, j int) bool { return s[i].data.Price.Cmp(s[j].data.Price) > 0 }
   339  func (s TxByPrice) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
   340  
   341  func (s *TxByPrice) Push(x interface{}) {
   342  	*s = append(*s, x.(*Transaction))
   343  }
   344  
   345  func (s *TxByPrice) Pop() interface{} {
   346  	old := *s
   347  	n := len(old)
   348  	x := old[n-1]
   349  	*s = old[0 : n-1]
   350  	return x
   351  }
   352  
   353  // TransactionsByPriceAndNonce represents a set of transactions that can return
   354  // transactions in a profit-maximizing sorted order, while supporting removing
   355  // entire batches of transactions for non-executable accounts.
   356  type TransactionsByPriceAndNonce struct {
   357  	txs    map[common.Address]Transactions // Per account nonce-sorted list of transactions
   358  	heads  TxByPrice                       // Next transaction for each unique account (price heap)
   359  	signer Signer                          // Signer for the set of transactions
   360  }
   361  
   362  // NewTransactionsByPriceAndNonce creates a transaction set that can retrieve
   363  // price sorted transactions in a nonce-honouring way.
   364  //
   365  // Note, the input map is reowned so the caller should not interact any more with
   366  // if after providing it to the constructor.
   367  func NewTransactionsByPriceAndNonce(signer Signer, txs map[common.Address]Transactions) *TransactionsByPriceAndNonce {
   368  	// Initialize a price based heap with the head transactions
   369  	heads := make(TxByPrice, 0, len(txs))
   370  	for from, accTxs := range txs {
   371  		heads = append(heads, accTxs[0])
   372  		// Ensure the sender address is from the signer
   373  		acc, _ := Sender(signer, accTxs[0])
   374  		txs[acc] = accTxs[1:]
   375  		if from != acc {
   376  			delete(txs, from)
   377  		}
   378  	}
   379  	heap.Init(&heads)
   380  
   381  	// Assemble and return the transaction set
   382  	return &TransactionsByPriceAndNonce{
   383  		txs:    txs,
   384  		heads:  heads,
   385  		signer: signer,
   386  	}
   387  }
   388  
   389  // Peek returns the next transaction by price.
   390  func (t *TransactionsByPriceAndNonce) Peek() *Transaction {
   391  	if len(t.heads) == 0 {
   392  		return nil
   393  	}
   394  	return t.heads[0]
   395  }
   396  
   397  // Shift replaces the current best head with the next one from the same account.
   398  func (t *TransactionsByPriceAndNonce) Shift() {
   399  	acc, _ := Sender(t.signer, t.heads[0])
   400  	if txs, ok := t.txs[acc]; ok && len(txs) > 0 {
   401  		t.heads[0], t.txs[acc] = txs[0], txs[1:]
   402  		heap.Fix(&t.heads, 0)
   403  	} else {
   404  		heap.Pop(&t.heads)
   405  	}
   406  }
   407  
   408  // Pop removes the best transaction, *not* replacing it with the next one from
   409  // the same account. This should be used when a transaction cannot be executed
   410  // and hence all subsequent ones should be discarded from the same account.
   411  func (t *TransactionsByPriceAndNonce) Pop() {
   412  	heap.Pop(&t.heads)
   413  }
   414  
   415  // Message is a fully derived transaction and implements core.Message
   416  //
   417  // NOTE: In a future PR this will be removed.
   418  type Message struct {
   419  	to         *common.Address
   420  	from       common.Address
   421  	nonce      uint64
   422  	amount     *big.Int
   423  	gasLimit   uint64
   424  	gasPrice   *big.Int
   425  	data       []byte
   426  	checkNonce bool
   427  }
   428  
   429  func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
   430  	return Message{
   431  		from:       from,
   432  		to:         to,
   433  		nonce:      nonce,
   434  		amount:     amount,
   435  		gasLimit:   gasLimit,
   436  		gasPrice:   gasPrice,
   437  		data:       data,
   438  		checkNonce: checkNonce,
   439  	}
   440  }
   441  
   442  func (m Message) From() common.Address { return m.from }
   443  func (m Message) To() *common.Address  { return m.to }
   444  func (m Message) GasPrice() *big.Int   { return m.gasPrice }
   445  func (m Message) Value() *big.Int      { return m.amount }
   446  func (m Message) Gas() uint64          { return m.gasLimit }
   447  func (m Message) Nonce() uint64        { return m.nonce }
   448  func (m Message) Data() []byte         { return m.data }
   449  func (m Message) CheckNonce() bool     { return m.checkNonce }