github.com/haliliceylan/bsc@v1.1.10-0.20220501224556-eb78d644ebcb/core/types/transaction_test.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 "bytes" 21 "crypto/ecdsa" 22 "encoding/json" 23 "fmt" 24 "math/big" 25 "reflect" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/common" 30 "github.com/ethereum/go-ethereum/crypto" 31 "github.com/ethereum/go-ethereum/rlp" 32 ) 33 34 // The values in those tests are from the Transaction Tests 35 // at github.com/ethereum/tests. 36 var ( 37 testAddr = common.HexToAddress("b94f5374fce5edbc8e2a8697c15331677e6ebf0b") 38 39 emptyTx = NewTransaction( 40 0, 41 common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), 42 big.NewInt(0), 0, big.NewInt(0), 43 nil, 44 ) 45 46 rightvrsTx, _ = NewTransaction( 47 3, 48 testAddr, 49 big.NewInt(10), 50 2000, 51 big.NewInt(1), 52 common.FromHex("5544"), 53 ).WithSignature( 54 HomesteadSigner{}, 55 common.Hex2Bytes("98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a301"), 56 ) 57 58 emptyEip2718Tx = NewTx(&AccessListTx{ 59 ChainID: big.NewInt(1), 60 Nonce: 3, 61 To: &testAddr, 62 Value: big.NewInt(10), 63 Gas: 25000, 64 GasPrice: big.NewInt(1), 65 Data: common.FromHex("5544"), 66 }) 67 68 signedEip2718Tx, _ = emptyEip2718Tx.WithSignature( 69 NewEIP2930Signer(big.NewInt(1)), 70 common.Hex2Bytes("c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b266032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d3752101"), 71 ) 72 ) 73 74 func TestDecodeEmptyTypedTx(t *testing.T) { 75 input := []byte{0x80} 76 var tx Transaction 77 err := rlp.DecodeBytes(input, &tx) 78 if err != errEmptyTypedTx { 79 t.Fatal("wrong error:", err) 80 } 81 } 82 83 func TestTransactionSigHash(t *testing.T) { 84 var homestead HomesteadSigner 85 if homestead.Hash(emptyTx) != common.HexToHash("c775b99e7ad12f50d819fcd602390467e28141316969f4b57f0626f74fe3b386") { 86 t.Errorf("empty transaction hash mismatch, got %x", emptyTx.Hash()) 87 } 88 if homestead.Hash(rightvrsTx) != common.HexToHash("fe7a79529ed5f7c3375d06b26b186a8644e0e16c373d7a12be41c62d6042b77a") { 89 t.Errorf("RightVRS transaction hash mismatch, got %x", rightvrsTx.Hash()) 90 } 91 } 92 93 func TestTransactionEncode(t *testing.T) { 94 txb, err := rlp.EncodeToBytes(rightvrsTx) 95 if err != nil { 96 t.Fatalf("encode error: %v", err) 97 } 98 should := common.FromHex("f86103018207d094b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a8255441ca098ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4aa08887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3") 99 if !bytes.Equal(txb, should) { 100 t.Errorf("encoded RLP mismatch, got %x", txb) 101 } 102 } 103 104 func TestEIP2718TransactionSigHash(t *testing.T) { 105 s := NewEIP2930Signer(big.NewInt(1)) 106 if s.Hash(emptyEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") { 107 t.Errorf("empty EIP-2718 transaction hash mismatch, got %x", s.Hash(emptyEip2718Tx)) 108 } 109 if s.Hash(signedEip2718Tx) != common.HexToHash("49b486f0ec0a60dfbbca2d30cb07c9e8ffb2a2ff41f29a1ab6737475f6ff69f3") { 110 t.Errorf("signed EIP-2718 transaction hash mismatch, got %x", s.Hash(signedEip2718Tx)) 111 } 112 } 113 114 // This test checks signature operations on access list transactions. 115 func TestEIP2930Signer(t *testing.T) { 116 117 var ( 118 key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 119 keyAddr = crypto.PubkeyToAddress(key.PublicKey) 120 signer1 = NewEIP2930Signer(big.NewInt(1)) 121 signer2 = NewEIP2930Signer(big.NewInt(2)) 122 tx0 = NewTx(&AccessListTx{Nonce: 1}) 123 tx1 = NewTx(&AccessListTx{ChainID: big.NewInt(1), Nonce: 1}) 124 tx2, _ = SignNewTx(key, signer2, &AccessListTx{ChainID: big.NewInt(2), Nonce: 1}) 125 ) 126 127 tests := []struct { 128 tx *Transaction 129 signer Signer 130 wantSignerHash common.Hash 131 wantSenderErr error 132 wantSignErr error 133 wantHash common.Hash // after signing 134 }{ 135 { 136 tx: tx0, 137 signer: signer1, 138 wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), 139 wantSenderErr: ErrInvalidChainId, 140 wantHash: common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"), 141 }, 142 { 143 tx: tx1, 144 signer: signer1, 145 wantSenderErr: ErrInvalidSig, 146 wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), 147 wantHash: common.HexToHash("1ccd12d8bbdb96ea391af49a35ab641e219b2dd638dea375f2bc94dd290f2549"), 148 }, 149 { 150 // This checks what happens when trying to sign an unsigned tx for the wrong chain. 151 tx: tx1, 152 signer: signer2, 153 wantSenderErr: ErrInvalidChainId, 154 wantSignerHash: common.HexToHash("367967247499343401261d718ed5aa4c9486583e4d89251afce47f4a33c33362"), 155 wantSignErr: ErrInvalidChainId, 156 }, 157 { 158 // This checks what happens when trying to re-sign a signed tx for the wrong chain. 159 tx: tx2, 160 signer: signer1, 161 wantSenderErr: ErrInvalidChainId, 162 wantSignerHash: common.HexToHash("846ad7672f2a3a40c1f959cd4a8ad21786d620077084d84c8d7c077714caa139"), 163 wantSignErr: ErrInvalidChainId, 164 }, 165 } 166 167 for i, test := range tests { 168 sigHash := test.signer.Hash(test.tx) 169 if sigHash != test.wantSignerHash { 170 t.Errorf("test %d: wrong sig hash: got %x, want %x", i, sigHash, test.wantSignerHash) 171 } 172 sender, err := Sender(test.signer, test.tx) 173 if err != test.wantSenderErr { 174 t.Errorf("test %d: wrong Sender error %q", i, err) 175 } 176 if err == nil && sender != keyAddr { 177 t.Errorf("test %d: wrong sender address %x", i, sender) 178 } 179 signedTx, err := SignTx(test.tx, test.signer, key) 180 if err != test.wantSignErr { 181 t.Fatalf("test %d: wrong SignTx error %q", i, err) 182 } 183 if signedTx != nil { 184 if signedTx.Hash() != test.wantHash { 185 t.Errorf("test %d: wrong tx hash after signing: got %x, want %x", i, signedTx.Hash(), test.wantHash) 186 } 187 } 188 } 189 } 190 191 func TestEIP2718TransactionEncode(t *testing.T) { 192 // RLP representation 193 { 194 have, err := rlp.EncodeToBytes(signedEip2718Tx) 195 if err != nil { 196 t.Fatalf("encode error: %v", err) 197 } 198 want := common.FromHex("b86601f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521") 199 if !bytes.Equal(have, want) { 200 t.Errorf("encoded RLP mismatch, got %x", have) 201 } 202 } 203 // Binary representation 204 { 205 have, err := signedEip2718Tx.MarshalBinary() 206 if err != nil { 207 t.Fatalf("encode error: %v", err) 208 } 209 want := common.FromHex("01f8630103018261a894b94f5374fce5edbc8e2a8697c15331677e6ebf0b0a825544c001a0c9519f4f2b30335884581971573fadf60c6204f59a911df35ee8a540456b2660a032f1e8e2c5dd761f9e4f88f41c8310aeaba26a8bfcdacfedfa12ec3862d37521") 210 if !bytes.Equal(have, want) { 211 t.Errorf("encoded RLP mismatch, got %x", have) 212 } 213 } 214 } 215 216 func decodeTx(data []byte) (*Transaction, error) { 217 var tx Transaction 218 t, err := &tx, rlp.Decode(bytes.NewReader(data), &tx) 219 return t, err 220 } 221 222 func defaultTestKey() (*ecdsa.PrivateKey, common.Address) { 223 key, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") 224 addr := crypto.PubkeyToAddress(key.PublicKey) 225 return key, addr 226 } 227 228 func TestRecipientEmpty(t *testing.T) { 229 _, addr := defaultTestKey() 230 tx, err := decodeTx(common.Hex2Bytes("f8498080808080011ca09b16de9d5bdee2cf56c28d16275a4da68cd30273e2525f3959f5d62557489921a0372ebd8fb3345f7db7b5a86d42e24d36e983e259b0664ceb8c227ec9af572f3d")) 231 if err != nil { 232 t.Fatal(err) 233 } 234 235 from, err := Sender(HomesteadSigner{}, tx) 236 if err != nil { 237 t.Fatal(err) 238 } 239 if addr != from { 240 t.Fatal("derived address doesn't match") 241 } 242 } 243 244 func TestRecipientNormal(t *testing.T) { 245 _, addr := defaultTestKey() 246 247 tx, err := decodeTx(common.Hex2Bytes("f85d80808094000000000000000000000000000000000000000080011ca0527c0d8f5c63f7b9f41324a7c8a563ee1190bcbf0dac8ab446291bdbf32f5c79a0552c4ef0a09a04395074dab9ed34d3fbfb843c2f2546cc30fe89ec143ca94ca6")) 248 if err != nil { 249 t.Fatal(err) 250 } 251 252 from, err := Sender(HomesteadSigner{}, tx) 253 if err != nil { 254 t.Fatal(err) 255 } 256 if addr != from { 257 t.Fatal("derived address doesn't match") 258 } 259 } 260 261 // Tests that transactions can be correctly sorted according to their price in 262 // decreasing order, but at the same time with increasing nonces when issued by 263 // the same account. 264 func TestTransactionPriceNonceSort(t *testing.T) { 265 // Generate a batch of accounts to start with 266 keys := make([]*ecdsa.PrivateKey, 25) 267 for i := 0; i < len(keys); i++ { 268 keys[i], _ = crypto.GenerateKey() 269 } 270 signer := HomesteadSigner{} 271 272 // Generate a batch of transactions with overlapping values, but shifted nonces 273 groups := map[common.Address]Transactions{} 274 for start, key := range keys { 275 addr := crypto.PubkeyToAddress(key.PublicKey) 276 for i := 0; i < 25; i++ { 277 tx, _ := SignTx(NewTransaction(uint64(start+i), common.Address{}, big.NewInt(100), 100, big.NewInt(int64(start+i)), nil), signer, key) 278 groups[addr] = append(groups[addr], tx) 279 } 280 } 281 // Sort the transactions and cross check the nonce ordering 282 txset := NewTransactionsByPriceAndNonce(signer, groups) 283 284 txs := Transactions{} 285 for tx := txset.Peek(); tx != nil; tx = txset.Peek() { 286 txs = append(txs, tx) 287 txset.Shift() 288 } 289 if len(txs) != 25*25 { 290 t.Errorf("expected %d transactions, found %d", 25*25, len(txs)) 291 } 292 for i, txi := range txs { 293 fromi, _ := Sender(signer, txi) 294 295 // Make sure the nonce order is valid 296 for j, txj := range txs[i+1:] { 297 fromj, _ := Sender(signer, txj) 298 if fromi == fromj && txi.Nonce() > txj.Nonce() { 299 t.Errorf("invalid nonce ordering: tx #%d (A=%x N=%v) < tx #%d (A=%x N=%v)", i, fromi[:4], txi.Nonce(), i+j, fromj[:4], txj.Nonce()) 300 } 301 } 302 // If the next tx has different from account, the price must be lower than the current one 303 if i+1 < len(txs) { 304 next := txs[i+1] 305 fromNext, _ := Sender(signer, next) 306 if fromi != fromNext && txi.GasPrice().Cmp(next.GasPrice()) < 0 { 307 t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice()) 308 } 309 } 310 } 311 } 312 313 // Tests that if multiple transactions have the same price, the ones seen earlier 314 // are prioritized to avoid network spam attacks aiming for a specific ordering. 315 func TestTransactionTimeSort(t *testing.T) { 316 // Generate a batch of accounts to start with 317 keys := make([]*ecdsa.PrivateKey, 5) 318 for i := 0; i < len(keys); i++ { 319 keys[i], _ = crypto.GenerateKey() 320 } 321 signer := HomesteadSigner{} 322 323 // Generate a batch of transactions with overlapping prices, but different creation times 324 groups := map[common.Address]Transactions{} 325 for start, key := range keys { 326 addr := crypto.PubkeyToAddress(key.PublicKey) 327 328 tx, _ := SignTx(NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key) 329 tx.time = time.Unix(0, int64(len(keys)-start)) 330 331 groups[addr] = append(groups[addr], tx) 332 } 333 // Sort the transactions and cross check the nonce ordering 334 txset := NewTransactionsByPriceAndNonce(signer, groups) 335 336 txs := Transactions{} 337 for tx := txset.Peek(); tx != nil; tx = txset.Peek() { 338 txs = append(txs, tx) 339 txset.Shift() 340 } 341 if len(txs) != len(keys) { 342 t.Errorf("expected %d transactions, found %d", len(keys), len(txs)) 343 } 344 for i, txi := range txs { 345 fromi, _ := Sender(signer, txi) 346 if i+1 < len(txs) { 347 next := txs[i+1] 348 fromNext, _ := Sender(signer, next) 349 350 if txi.GasPrice().Cmp(next.GasPrice()) < 0 { 351 t.Errorf("invalid gasprice ordering: tx #%d (A=%x P=%v) < tx #%d (A=%x P=%v)", i, fromi[:4], txi.GasPrice(), i+1, fromNext[:4], next.GasPrice()) 352 } 353 // Make sure time order is ascending if the txs have the same gas price 354 if txi.GasPrice().Cmp(next.GasPrice()) == 0 && txi.time.After(next.time) { 355 t.Errorf("invalid received time ordering: tx #%d (A=%x T=%v) > tx #%d (A=%x T=%v)", i, fromi[:4], txi.time, i+1, fromNext[:4], next.time) 356 } 357 } 358 } 359 } 360 361 func TestTransactionForward(t *testing.T) { 362 // Generate a batch of accounts to start with 363 keys := make([]*ecdsa.PrivateKey, 5) 364 for i := 0; i < len(keys); i++ { 365 keys[i], _ = crypto.GenerateKey() 366 } 367 signer := HomesteadSigner{} 368 369 // Generate a batch of transactions with overlapping prices, but different creation times 370 groups := map[common.Address]Transactions{} 371 for start, key := range keys { 372 addr := crypto.PubkeyToAddress(key.PublicKey) 373 374 tx, _ := SignTx(NewTransaction(0, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key) 375 tx2, _ := SignTx(NewTransaction(1, common.Address{}, big.NewInt(100), 100, big.NewInt(1), nil), signer, key) 376 377 tx.time = time.Unix(0, int64(len(keys)-start)) 378 tx2.time = time.Unix(1, int64(len(keys)-start)) 379 380 groups[addr] = append(groups[addr], tx) 381 groups[addr] = append(groups[addr], tx2) 382 383 } 384 // Sort the transactions 385 txset := NewTransactionsByPriceAndNonce(signer, groups) 386 txsetCpy := txset.Copy() 387 388 txs := Transactions{} 389 for tx := txsetCpy.Peek(); tx != nil; tx = txsetCpy.Peek() { 390 txs = append(txs, tx) 391 txsetCpy.Shift() 392 } 393 394 tmp := txset.Copy() 395 for j := 0; j < 11; j++ { 396 txset = tmp.Copy() 397 txsetCpy = tmp.Copy() 398 i := 0 399 for ; i < j; i++ { 400 txset.Shift() 401 } 402 tx := txset.Peek() 403 if tx == nil { 404 continue 405 } 406 txsetCpy.Forward(tx) 407 txCpy := txsetCpy.Peek() 408 if txCpy == nil { 409 if tx == nil { 410 continue 411 } 412 txset.Shift() 413 if txset.Peek() != nil { 414 t.Errorf("forward got an incorrect result, got %v, want %v", txCpy, tx) 415 } else { 416 continue 417 } 418 } 419 txset.Shift() 420 for ; i < len(txs)-1; i++ { 421 tx = txset.Peek() 422 txCpy = txsetCpy.Peek() 423 if txCpy != tx { 424 t.Errorf("forward got an incorrect result, got %v, want %v", txCpy, tx) 425 } 426 txsetCpy.Shift() 427 txset.Shift() 428 } 429 430 } 431 } 432 433 // TestTransactionCoding tests serializing/de-serializing to/from rlp and JSON. 434 func TestTransactionCoding(t *testing.T) { 435 key, err := crypto.GenerateKey() 436 if err != nil { 437 t.Fatalf("could not generate key: %v", err) 438 } 439 var ( 440 signer = NewEIP2930Signer(common.Big1) 441 addr = common.HexToAddress("0x0000000000000000000000000000000000000001") 442 recipient = common.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") 443 accesses = AccessList{{Address: addr, StorageKeys: []common.Hash{{0}}}} 444 ) 445 for i := uint64(0); i < 500; i++ { 446 var txdata TxData 447 switch i % 5 { 448 case 0: 449 // Legacy tx. 450 txdata = &LegacyTx{ 451 Nonce: i, 452 To: &recipient, 453 Gas: 1, 454 GasPrice: big.NewInt(2), 455 Data: []byte("abcdef"), 456 } 457 case 1: 458 // Legacy tx contract creation. 459 txdata = &LegacyTx{ 460 Nonce: i, 461 Gas: 1, 462 GasPrice: big.NewInt(2), 463 Data: []byte("abcdef"), 464 } 465 case 2: 466 // Tx with non-zero access list. 467 txdata = &AccessListTx{ 468 ChainID: big.NewInt(1), 469 Nonce: i, 470 To: &recipient, 471 Gas: 123457, 472 GasPrice: big.NewInt(10), 473 AccessList: accesses, 474 Data: []byte("abcdef"), 475 } 476 case 3: 477 // Tx with empty access list. 478 txdata = &AccessListTx{ 479 ChainID: big.NewInt(1), 480 Nonce: i, 481 To: &recipient, 482 Gas: 123457, 483 GasPrice: big.NewInt(10), 484 Data: []byte("abcdef"), 485 } 486 case 4: 487 // Contract creation with access list. 488 txdata = &AccessListTx{ 489 ChainID: big.NewInt(1), 490 Nonce: i, 491 Gas: 123457, 492 GasPrice: big.NewInt(10), 493 AccessList: accesses, 494 } 495 } 496 tx, err := SignNewTx(key, signer, txdata) 497 if err != nil { 498 t.Fatalf("could not sign transaction: %v", err) 499 } 500 // RLP 501 parsedTx, err := encodeDecodeBinary(tx) 502 if err != nil { 503 t.Fatal(err) 504 } 505 assertEqual(parsedTx, tx) 506 507 // JSON 508 parsedTx, err = encodeDecodeJSON(tx) 509 if err != nil { 510 t.Fatal(err) 511 } 512 assertEqual(parsedTx, tx) 513 } 514 } 515 516 func encodeDecodeJSON(tx *Transaction) (*Transaction, error) { 517 data, err := json.Marshal(tx) 518 if err != nil { 519 return nil, fmt.Errorf("json encoding failed: %v", err) 520 } 521 var parsedTx = &Transaction{} 522 if err := json.Unmarshal(data, &parsedTx); err != nil { 523 return nil, fmt.Errorf("json decoding failed: %v", err) 524 } 525 return parsedTx, nil 526 } 527 528 func encodeDecodeBinary(tx *Transaction) (*Transaction, error) { 529 data, err := tx.MarshalBinary() 530 if err != nil { 531 return nil, fmt.Errorf("rlp encoding failed: %v", err) 532 } 533 var parsedTx = &Transaction{} 534 if err := parsedTx.UnmarshalBinary(data); err != nil { 535 return nil, fmt.Errorf("rlp decoding failed: %v", err) 536 } 537 return parsedTx, nil 538 } 539 540 func assertEqual(orig *Transaction, cpy *Transaction) error { 541 // compare nonce, price, gaslimit, recipient, amount, payload, V, R, S 542 if want, got := orig.Hash(), cpy.Hash(); want != got { 543 return fmt.Errorf("parsed tx differs from original tx, want %v, got %v", want, got) 544 } 545 if want, got := orig.ChainId(), cpy.ChainId(); want.Cmp(got) != 0 { 546 return fmt.Errorf("invalid chain id, want %d, got %d", want, got) 547 } 548 if orig.AccessList() != nil { 549 if !reflect.DeepEqual(orig.AccessList(), cpy.AccessList()) { 550 return fmt.Errorf("access list wrong!") 551 } 552 } 553 return nil 554 }