@@ -25,10 +25,12 @@ import (
25
25
"math/rand"
26
26
"os"
27
27
"path"
28
+ "reflect"
28
29
"sync"
29
30
"testing"
30
31
"time"
31
32
33
+ "github.com/davecgh/go-spew/spew"
32
34
"github.com/ethereum/go-ethereum/common"
33
35
"github.com/ethereum/go-ethereum/consensus"
34
36
"github.com/ethereum/go-ethereum/consensus/beacon"
@@ -46,6 +48,7 @@ import (
46
48
"github.com/ethereum/go-ethereum/params"
47
49
"github.com/ethereum/go-ethereum/trie"
48
50
"github.com/holiman/uint256"
51
+ "github.com/stretchr/testify/assert"
49
52
)
50
53
51
54
// So we can deterministically seed different blockchains
@@ -1004,29 +1007,47 @@ func testChainTxReorgs(t *testing.T, scheme string) {
1004
1007
1005
1008
// removed tx
1006
1009
for i , tx := range (types.Transactions {pastDrop , freshDrop }) {
1007
- if txn , _ , _ , _ := rawdb .ReadTransaction (db , tx .Hash ()); txn != nil {
1010
+ if txn , _ , _ , _ := rawdb .ReadCanonicalTransaction (db , tx .Hash ()); txn != nil {
1008
1011
t .Errorf ("drop %d: tx %v found while shouldn't have been" , i , txn )
1009
1012
}
1010
- if rcpt , _ , _ , _ := rawdb .ReadReceipt (db , tx .Hash (), blockchain .Config ()); rcpt != nil {
1013
+ if rcpt , _ , _ , _ := rawdb .ReadCanonicalReceipt (db , tx .Hash (), blockchain .Config ()); rcpt != nil {
1011
1014
t .Errorf ("drop %d: receipt %v found while shouldn't have been" , i , rcpt )
1012
1015
}
1013
1016
}
1014
1017
// added tx
1015
1018
for i , tx := range (types.Transactions {pastAdd , freshAdd , futureAdd }) {
1016
- if txn , _ , _ , _ := rawdb .ReadTransaction (db , tx .Hash ()); txn == nil {
1019
+ if txn , _ , _ , _ := rawdb .ReadCanonicalTransaction (db , tx .Hash ()); txn == nil {
1017
1020
t .Errorf ("add %d: expected tx to be found" , i )
1018
1021
}
1019
- if rcpt , _ , _ , _ := rawdb .ReadReceipt (db , tx .Hash (), blockchain .Config ()); rcpt == nil {
1022
+ if rcpt , _ , _ , index := rawdb .ReadCanonicalReceipt (db , tx .Hash (), blockchain .Config ()); rcpt == nil {
1020
1023
t .Errorf ("add %d: expected receipt to be found" , i )
1024
+ } else if rawRcpt , ctx , _ := rawdb .ReadCanonicalRawReceipt (db , rcpt .BlockHash , rcpt .BlockNumber .Uint64 (), index ); rawRcpt == nil {
1025
+ t .Errorf ("add %d: expected raw receipt to be found" , i )
1026
+ } else {
1027
+ if rcpt .GasUsed != ctx .GasUsed {
1028
+ t .Errorf ("add %d, raw gasUsedSoFar doesn't make sense" , i )
1029
+ }
1030
+ if len (rcpt .Logs ) > 0 && rcpt .Logs [0 ].Index != ctx .LogIndex {
1031
+ t .Errorf ("add %d, raw startingLogIndex doesn't make sense" , i )
1032
+ }
1021
1033
}
1022
1034
}
1023
1035
// shared tx
1024
1036
for i , tx := range (types.Transactions {postponed , swapped }) {
1025
- if txn , _ , _ , _ := rawdb .ReadTransaction (db , tx .Hash ()); txn == nil {
1037
+ if txn , _ , _ , _ := rawdb .ReadCanonicalTransaction (db , tx .Hash ()); txn == nil {
1026
1038
t .Errorf ("share %d: expected tx to be found" , i )
1027
1039
}
1028
- if rcpt , _ , _ , _ := rawdb .ReadReceipt (db , tx .Hash (), blockchain .Config ()); rcpt == nil {
1040
+ if rcpt , _ , _ , index := rawdb .ReadCanonicalReceipt (db , tx .Hash (), blockchain .Config ()); rcpt == nil {
1029
1041
t .Errorf ("share %d: expected receipt to be found" , i )
1042
+ } else if rawRcpt , ctx , _ := rawdb .ReadCanonicalRawReceipt (db , rcpt .BlockHash , rcpt .BlockNumber .Uint64 (), index ); rawRcpt == nil {
1043
+ t .Errorf ("add %d: expected raw receipt to be found" , i )
1044
+ } else {
1045
+ if rcpt .GasUsed != ctx .GasUsed {
1046
+ t .Errorf ("add %d, raw gasUsedSoFar doesn't make sense" , i )
1047
+ }
1048
+ if len (rcpt .Logs ) > 0 && rcpt .Logs [0 ].Index != ctx .LogIndex {
1049
+ t .Errorf ("add %d, raw startingLogIndex doesn't make sense" , i )
1050
+ }
1030
1051
}
1031
1052
}
1032
1053
}
@@ -4404,6 +4425,93 @@ func testInsertChainWithCutoff(t *testing.T, cutoff uint64, ancientLimit uint64,
4404
4425
if receipts == nil || len (receipts ) != 1 {
4405
4426
t .Fatalf ("Missed block receipts: %d, cutoff: %d" , num , cutoffBlock .NumberU64 ())
4406
4427
}
4428
+ for indx , receipt := range receipts {
4429
+ receiptByLookup , err := chain .GetCanonicalReceipt (body .Transactions [indx ], receipt .BlockHash ,
4430
+ receipt .BlockNumber .Uint64 (), uint64 (indx ))
4431
+ assert .NoError (t , err )
4432
+ assert .Equal (t , receipt , receiptByLookup )
4433
+ }
4434
+ }
4435
+ }
4436
+ }
4437
+
4438
+ func TestGetCanonicalReceipt (t * testing.T ) {
4439
+ const chainLength = 64
4440
+
4441
+ // Configure and generate a sample block chain
4442
+ var (
4443
+ key , _ = crypto .HexToECDSA ("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
4444
+ address = crypto .PubkeyToAddress (key .PublicKey )
4445
+ funds = big .NewInt (1000000000000000000 )
4446
+ gspec = & Genesis {
4447
+ Config : params .MergedTestChainConfig ,
4448
+ Alloc : types.GenesisAlloc {address : {Balance : funds }},
4449
+ BaseFee : big .NewInt (params .InitialBaseFee ),
4450
+ }
4451
+ signer = types .LatestSigner (gspec .Config )
4452
+ engine = beacon .New (ethash .NewFaker ())
4453
+ codeBin = common .FromHex ("0x608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033" )
4454
+ )
4455
+ _ , blocks , receipts := GenerateChainWithGenesis (gspec , engine , chainLength , func (i int , block * BlockGen ) {
4456
+ // SPDX-License-Identifier: MIT
4457
+ // pragma solidity ^0.8.0;
4458
+ //
4459
+ // contract ConstructorLogger {
4460
+ // event ConstructorLog(address sender, uint256 timestamp, string message);
4461
+ //
4462
+ // constructor() {
4463
+ // emit ConstructorLog(msg.sender, block.timestamp, "Constructor was called");
4464
+ // }
4465
+ // }
4466
+ //
4467
+ // 608060405234801561000f575f5ffd5b507f8ae1c8c6e5f91159d0bc1c4b9a47ce45301753843012cbe641e4456bfc73538b33426040516100419291906100ff565b60405180910390a1610139565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100778261004e565b9050919050565b6100878161006d565b82525050565b5f819050919050565b61009f8161008d565b82525050565b5f82825260208201905092915050565b7f436f6e7374727563746f72207761732063616c6c6564000000000000000000005f82015250565b5f6100e96016836100a5565b91506100f4826100b5565b602082019050919050565b5f6060820190506101125f83018561007e565b61011f6020830184610096565b8181036040830152610130816100dd565b90509392505050565b603e806101455f395ff3fe60806040525f5ffdfea2646970667358221220e8bc3c31e3ac337eab702e8fdfc1c71894f4df1af4221bcde4a2823360f403fb64736f6c634300081e0033
4468
+ nonce := block .TxNonce (address )
4469
+ tx , err := types .SignTx (types .NewContractCreation (nonce , big .NewInt (0 ), 100_000 , block .header .BaseFee , codeBin ), signer , key )
4470
+ if err != nil {
4471
+ panic (err )
4472
+ }
4473
+ block .AddTx (tx )
4474
+
4475
+ tx2 , err := types .SignTx (types .NewContractCreation (nonce + 1 , big .NewInt (0 ), 100_000 , block .header .BaseFee , codeBin ), signer , key )
4476
+ if err != nil {
4477
+ panic (err )
4478
+ }
4479
+ block .AddTx (tx2 )
4480
+
4481
+ tx3 , err := types .SignTx (types .NewContractCreation (nonce + 2 , big .NewInt (0 ), 100_000 , block .header .BaseFee , codeBin ), signer , key )
4482
+ if err != nil {
4483
+ panic (err )
4484
+ }
4485
+ block .AddTx (tx3 )
4486
+ })
4487
+
4488
+ db , _ := rawdb .Open (rawdb .NewMemoryDatabase (), rawdb.OpenOptions {})
4489
+ defer db .Close ()
4490
+ options := DefaultConfig ().WithStateScheme (rawdb .PathScheme )
4491
+ chain , _ := NewBlockChain (db , gspec , beacon .New (ethash .NewFaker ()), options )
4492
+ defer chain .Stop ()
4493
+
4494
+ chain .InsertReceiptChain (blocks , types .EncodeBlockReceiptLists (receipts ), 0 )
4495
+
4496
+ for i := 0 ; i < chainLength ; i ++ {
4497
+ block := blocks [i ]
4498
+ blockReceipts := chain .GetReceiptsByHash (block .Hash ())
4499
+ chain .receiptsCache .Purge () // ugly hack
4500
+ for txIndex , tx := range block .Body ().Transactions {
4501
+ receipt , err := chain .GetCanonicalReceipt (tx , block .Hash (), block .NumberU64 (), uint64 (txIndex ))
4502
+ if err != nil {
4503
+ t .Fatalf ("Unexpected error %v" , err )
4504
+ }
4505
+ if ! reflect .DeepEqual (receipts [i ][txIndex ], receipt ) {
4506
+ want := spew .Sdump (receipts [i ][txIndex ])
4507
+ got := spew .Sdump (receipt )
4508
+ t .Fatalf ("Receipt is not matched, want %s, got: %s" , want , got )
4509
+ }
4510
+ if ! reflect .DeepEqual (blockReceipts [txIndex ], receipt ) {
4511
+ want := spew .Sdump (blockReceipts [txIndex ])
4512
+ got := spew .Sdump (receipt )
4513
+ t .Fatalf ("Receipt is not matched, want %s, got: %s" , want , got )
4514
+ }
4407
4515
}
4408
4516
}
4409
4517
}
0 commit comments