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 }