github.com/snowblossomcoin/go-ethereum@v1.9.25/core/types/transaction.go (about)

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