diff --git a/core/blockchain.go b/core/blockchain.go index c3da61b281..5e8b31d14f 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -416,7 +416,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis } if bc.logger != nil && bc.logger.OnGenesisBlock != nil { if block := bc.CurrentBlock(); block.Number.Uint64() == 0 { - alloc, err := getGenesisState(bc.db, block.Hash()) + alloc, err := GetGenesisState(bc.db, block.Hash()) if err != nil { return nil, fmt.Errorf("failed to get genesis state: %w", err) } diff --git a/core/genesis.go b/core/genesis.go index eff92084eb..c2dba97879 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -177,7 +177,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e return root, nil } -func getGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.GenesisAlloc, err error) { +func GetGenesisState(db ethdb.Database, blockhash common.Hash) (alloc types.GenesisAlloc, err error) { blob := rawdb.ReadGenesisStateSpec(db, blockhash) if len(blob) != 0 { if err := alloc.UnmarshalJSON(blob); err != nil { diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/live/supply_fill_test.go similarity index 77% rename from eth/tracers/internal/tracetest/supply_test.go rename to eth/tracers/live/supply_fill_test.go index 2391add91b..a0741b2617 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/live/supply_fill_test.go @@ -14,7 +14,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -package tracetest +package live import ( "bufio" @@ -28,7 +28,6 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/beacon" "github.com/ethereum/go-ethereum/consensus/ethash" "github.com/ethereum/go-ethereum/core" @@ -37,34 +36,10 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" - - // Force-load live packages, to trigger registration - _ "github.com/ethereum/go-ethereum/eth/tracers/live" ) -type supplyInfoIssuance struct { - GenesisAlloc *hexutil.Big `json:"genesisAlloc,omitempty"` - Reward *hexutil.Big `json:"reward,omitempty"` - Withdrawals *hexutil.Big `json:"withdrawals,omitempty"` -} - -type supplyInfoBurn struct { - EIP1559 *hexutil.Big `json:"1559,omitempty"` - Blob *hexutil.Big `json:"blob,omitempty"` - Misc *hexutil.Big `json:"misc,omitempty"` -} - -type supplyInfo struct { - Issuance *supplyInfoIssuance `json:"issuance,omitempty"` - Burn *supplyInfoBurn `json:"burn,omitempty"` - - // Block info - Number uint64 `json:"blockNumber"` - Hash common.Hash `json:"hash"` - ParentHash common.Hash `json:"parentHash"` -} - func emptyBlockGenerationFunc(b *core.BlockGen) {} func TestSupplyOmittedFields(t *testing.T) { @@ -73,25 +48,27 @@ func TestSupplyOmittedFields(t *testing.T) { gspec = &core.Genesis{ Config: &config, } + expected = []supplyInfo{{ + Number: 0, + Hash: common.HexToHash("0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703"), + ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + }, { + Number: 1, + Hash: common.HexToHash("0xe430cdf604a88b9d713d4f89fd100ddddf38c1cc6b049e3d5df563c7bfd320fc"), + ParentHash: common.HexToHash("0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703"), + }} ) - gspec.Config.TerminalTotalDifficulty = big.NewInt(0) - - out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) { + out, db, chain, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) { b.SetPoS() }) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } - expected := supplyInfo{ - Number: 0, - Hash: common.HexToHash("0xc02ee8ee5b54a40e43f0fa827d431e1bd4f217e941790dda10b2521d1925a20b"), - ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), - } - actual := out[expected.Number] + compareAsJSON(t, expected, out) + writeArtifact(t, "omitted_fields_cancun", db, chain, expected) - compareAsJSON(t, expected, actual) } func TestSupplyGenesisAlloc(t *testing.T) { @@ -103,61 +80,36 @@ func TestSupplyGenesisAlloc(t *testing.T) { eth1 = new(big.Int).Mul(common.Big1, big.NewInt(params.Ether)) config = *params.AllEthashProtocolChanges - - gspec = &core.Genesis{ + gspec = &core.Genesis{ Config: &config, Alloc: types.GenesisAlloc{ addr1: {Balance: eth1}, addr2: {Balance: eth1}, }, } + expected = []supplyInfo{{ + Issuance: &supplyInfoIssuance{ + GenesisAlloc: new(big.Int).Mul(common.Big2, big.NewInt(params.Ether)), + }, + Number: 0, + Hash: common.HexToHash("0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca"), + ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + }, { + Issuance: &supplyInfoIssuance{ + Reward: new(big.Int).Mul(common.Big2, big.NewInt(params.Ether)), + }, + Number: 1, + Hash: common.HexToHash("0x37bb7e9b45f4fb7b311abb5f815e3e00d3382d83a2c39b9b0bd22b717566cd04"), + ParentHash: common.HexToHash("0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca"), + }} ) - expected := supplyInfo{ - Issuance: &supplyInfoIssuance{ - GenesisAlloc: (*hexutil.Big)(new(big.Int).Mul(common.Big2, big.NewInt(params.Ether))), - }, - Number: 0, - Hash: common.HexToHash("0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca"), - ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), - } - - out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) + out, db, chain, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } - - actual := out[expected.Number] - - compareAsJSON(t, expected, actual) -} - -func TestSupplyRewards(t *testing.T) { - var ( - config = *params.AllEthashProtocolChanges - - gspec = &core.Genesis{ - Config: &config, - } - ) - - expected := supplyInfo{ - Issuance: &supplyInfoIssuance{ - Reward: (*hexutil.Big)(new(big.Int).Mul(common.Big2, big.NewInt(params.Ether))), - }, - Number: 1, - Hash: common.HexToHash("0xcbb08370505be503dafedc4e96d139ea27aba3cbc580148568b8a307b3f51052"), - ParentHash: common.HexToHash("0xadeda0a83e337b6c073e3f0e9a17531a04009b397a9588c093b628f21b8bc5a3"), - } - - out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) - if err != nil { - t.Fatalf("failed to test supply tracer: %v", err) - } - - actual := out[expected.Number] - - compareAsJSON(t, expected, actual) + compareAsJSON(t, expected, out) + writeArtifact(t, "genesis_alloc_grayGlacier", db, chain, expected) } func TestSupplyEip1559Burn(t *testing.T) { @@ -179,9 +131,8 @@ func TestSupplyEip1559Burn(t *testing.T) { }, } ) - - signer := types.LatestSigner(gspec.Config) - + config.ChainID = big.NewInt(1) + signer := types.LatestSigner(&config) eip1559BlockGenerationFunc := func(b *core.BlockGen) { txdata := &types.DynamicFeeTx{ ChainID: gspec.Config.ChainID, @@ -197,7 +148,7 @@ func TestSupplyEip1559Burn(t *testing.T) { b.AddTx(tx) } - out, chain, err := testSupplyTracer(t, gspec, eip1559BlockGenerationFunc) + out, db, chain, err := testSupplyTracer(t, gspec, eip1559BlockGenerationFunc) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -205,21 +156,27 @@ func TestSupplyEip1559Burn(t *testing.T) { head = chain.CurrentBlock() reward = new(big.Int).Mul(common.Big2, big.NewInt(params.Ether)) burn = new(big.Int).Mul(big.NewInt(21000), head.BaseFee) - expected = supplyInfo{ + expected = []supplyInfo{{ Issuance: &supplyInfoIssuance{ - Reward: (*hexutil.Big)(reward), + GenesisAlloc: eth1, + }, + Number: 0, + Hash: common.HexToHash("0xc4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7"), + ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), + }, { + Issuance: &supplyInfoIssuance{ + Reward: reward, }, Burn: &supplyInfoBurn{ - EIP1559: (*hexutil.Big)(burn), + EIP1559: burn, }, Number: 1, Hash: head.Hash(), ParentHash: head.ParentHash, - } + }} ) - - actual := out[expected.Number] - compareAsJSON(t, expected, actual) + compareAsJSON(t, expected, out) + writeArtifact(t, "eip1559_burn_grayGlacier", db, chain, expected) } func TestSupplyWithdrawals(t *testing.T) { @@ -240,7 +197,7 @@ func TestSupplyWithdrawals(t *testing.T) { }) } - out, chain, err := testSupplyTracer(t, gspec, withdrawalsBlockGenerationFunc) + out, _, chain, err := testSupplyTracer(t, gspec, withdrawalsBlockGenerationFunc) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -249,7 +206,7 @@ func TestSupplyWithdrawals(t *testing.T) { head = chain.CurrentBlock() expected = supplyInfo{ Issuance: &supplyInfoIssuance{ - Withdrawals: (*hexutil.Big)(big.NewInt(1337000000000)), + Withdrawals: big.NewInt(1337000000000), }, Number: 1, Hash: head.Hash(), @@ -320,7 +277,7 @@ func TestSupplySelfdestruct(t *testing.T) { } // 1. Test pre Cancun - preCancunOutput, preCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + preCancunOutput, _, preCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) if err != nil { t.Fatalf("Pre-cancun failed to test supply tracer: %v", err) } @@ -344,8 +301,8 @@ func TestSupplySelfdestruct(t *testing.T) { // Check live trace output expected := supplyInfo{ Burn: &supplyInfoBurn{ - EIP1559: (*hexutil.Big)(big.NewInt(55289500000000)), - Misc: (*hexutil.Big)(big.NewInt(5000000000)), + EIP1559: big.NewInt(55289500000000), + Misc: big.NewInt(5000000000), }, Number: 1, Hash: head.Hash(), @@ -361,7 +318,7 @@ func TestSupplySelfdestruct(t *testing.T) { gspec.Config.ShanghaiTime = &cancunTime gspec.Config.CancunTime = &cancunTime - postCancunOutput, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + postCancunOutput, _, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) if err != nil { t.Fatalf("Post-cancun failed to test supply tracer: %v", err) } @@ -385,7 +342,7 @@ func TestSupplySelfdestruct(t *testing.T) { head = postCancunChain.CurrentBlock() expected = supplyInfo{ Burn: &supplyInfoBurn{ - EIP1559: (*hexutil.Big)(big.NewInt(55289500000000)), + EIP1559: big.NewInt(55289500000000), }, Number: 1, Hash: head.Hash(), @@ -501,7 +458,7 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { b.AddTx(tx) } - output, chain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + output, _, chain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -530,8 +487,8 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { expected := supplyInfo{ Burn: &supplyInfoBurn{ - EIP1559: (*hexutil.Big)(new(big.Int).Mul(block.BaseFee(), big.NewInt(int64(block.GasUsed())))), - Misc: (*hexutil.Big)(eth5), // 5ETH burned from contract B + EIP1559: new(big.Int).Mul(block.BaseFee(), big.NewInt(int64(block.GasUsed()))), + Misc: eth5, // 5ETH burned from contract B }, Number: 1, Hash: block.Hash(), @@ -543,7 +500,7 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { compareAsJSON(t, expected, actual) } -func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) { +func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, ethdb.Database, *core.BlockChain, error) { var ( engine = beacon.New(ethash.NewFaker()) ) @@ -554,12 +511,13 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG // Load supply tracer tracer, err := tracers.LiveDirectory.New("supply", json.RawMessage(fmt.Sprintf(`{"path":"%s"}`, traceOutputPath))) if err != nil { - return nil, nil, fmt.Errorf("failed to create call tracer: %v", err) + return nil, nil, nil, fmt.Errorf("failed to create call tracer: %v", err) } - chain, err := core.NewBlockChain(rawdb.NewMemoryDatabase(), core.DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, engine, vm.Config{Tracer: tracer}, nil) + db := rawdb.NewMemoryDatabase() + chain, err := core.NewBlockChain(db, core.DefaultCacheConfigWithScheme(rawdb.PathScheme), genesis, nil, engine, vm.Config{Tracer: tracer}, nil) if err != nil { - return nil, nil, fmt.Errorf("failed to create tester chain: %v", err) + return nil, nil, nil, fmt.Errorf("failed to create tester chain: %v", err) } defer chain.Stop() @@ -568,14 +526,15 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG gen(b) }) + fmt.Printf("blocks: %v\n", blocks) if n, err := chain.InsertChain(blocks); err != nil { - return nil, chain, fmt.Errorf("block %d: failed to insert into chain: %v", n, err) + return nil, nil, chain, fmt.Errorf("block %d: failed to insert into chain: %v", n, err) } // Check and compare the results file, err := os.OpenFile(traceOutputFilename, os.O_RDONLY, 0666) if err != nil { - return nil, chain, fmt.Errorf("failed to open output file: %v", err) + return nil, nil, chain, fmt.Errorf("failed to open output file: %v", err) } defer file.Close() @@ -587,13 +546,13 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG var info supplyInfo if err := json.Unmarshal(blockBytes, &info); err != nil { - return nil, chain, fmt.Errorf("failed to unmarshal result: %v", err) + return nil, nil, chain, fmt.Errorf("failed to unmarshal result: %v", err) } output = append(output, info) } - return output, chain, nil + return output, db, chain, nil } func compareAsJSON(t *testing.T, expected interface{}, actual interface{}) { @@ -602,13 +561,26 @@ func compareAsJSON(t *testing.T, expected interface{}, actual interface{}) { if err != nil { t.Fatalf("failed to marshal expected value to JSON: %v", err) } - have, err := json.Marshal(actual) if err != nil { t.Fatalf("failed to marshal actual value to JSON: %v", err) } - if !bytes.Equal(want, have) { t.Fatalf("incorrect supply info:\nwant %s\nhave %s", string(want), string(have)) } } + +func writeArtifact(t *testing.T, name string, db ethdb.Database, chain *core.BlockChain, expected []supplyInfo) { + bt, err := btFromChain(db, chain) + if err != nil { + t.Fatalf("failed to fill tests from chain: %v", err) + } + bt.Expected = expected + result := make(map[string]any) + result[name] = bt + enc, err := json.MarshalIndent(&result, "", " ") + if err != nil { + t.Fatalf("failed to marshal tests: %v", err) + } + t.Logf("Tests: %s", enc) +} diff --git a/eth/tracers/live/supply_test.go b/eth/tracers/live/supply_test.go index 18c4b94d9c..aa08b68cf4 100644 --- a/eth/tracers/live/supply_test.go +++ b/eth/tracers/live/supply_test.go @@ -10,8 +10,6 @@ import ( "strings" "testing" "unicode" - - "github.com/ethereum/go-ethereum/tests" ) func TestSupplyTracerBlockchain(t *testing.T) { @@ -25,7 +23,7 @@ func TestSupplyTracerBlockchain(t *testing.T) { continue } file := file // capture range variable - var testcases map[string]*tests.BlockTest + var testcases map[string]*BlockTest var blob []byte // Call tracer test found, read if from disk if blob, err = os.ReadFile(filepath.Join("testdata", dirPath, file.Name())); err != nil { @@ -45,7 +43,7 @@ func TestSupplyTracerBlockchain(t *testing.T) { if err != nil { t.Fatalf("failed to create call tracer: %v", err) } - if err := test.Run(false, "path", false, tracer, nil); err != nil { + if err := test.bt.Run(false, "path", false, tracer, nil); err != nil { t.Errorf("failed to run test: %v\n", err) } // Check and compare the results @@ -54,20 +52,26 @@ func TestSupplyTracerBlockchain(t *testing.T) { t.Fatalf("failed to open output file: %v", err) } defer file.Close() - var output []supplyInfo - scanner := bufio.NewScanner(file) + var ( + output []supplyInfo + scanner = bufio.NewScanner(file) + ) for scanner.Scan() { blockBytes := scanner.Bytes() - var info supplyInfo if err := json.Unmarshal(blockBytes, &info); err != nil { t.Fatalf("failed to unmarshal result: %v", err) } - output = append(output, info) } - fmt.Printf("output: %v\n", output) + if len(output) != len(test.Expected) { + fmt.Printf("output: %v\n", output) + t.Fatalf("expected %d supply infos, got %d", len(test.Expected), len(output)) + } + for i, expected := range test.Expected { + compareAsJSON(t, expected, output[i]) + } }) } } diff --git a/eth/tracers/live/supply_test_util.go b/eth/tracers/live/supply_test_util.go new file mode 100644 index 0000000000..ca04ad934b --- /dev/null +++ b/eth/tracers/live/supply_test_util.go @@ -0,0 +1,50 @@ +package live + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/tests" +) + +type BlockTest struct { + bt *tests.BlockTest + Expected []supplyInfo `json:"expected"` +} + +func btFromChain(db ethdb.Database, chain *core.BlockChain) (*BlockTest, error) { + bt, err := tests.FromChain(db, chain) + if err != nil { + return nil, err + } + return &BlockTest{bt: &bt}, nil +} + +func (bt *BlockTest) UnmarshalJSON(data []byte) error { + tmp := make(map[string]json.RawMessage) + if err := json.Unmarshal(data, &tmp); err != nil { + return err + } + if err := json.Unmarshal(tmp["expected"], &bt.Expected); err != nil { + return err + } + if err := json.Unmarshal(data, &bt.bt); err != nil { + return err + } + return nil +} + +func (bt *BlockTest) MarshalJSON() ([]byte, error) { + enc, err := json.Marshal(bt.bt) + if err != nil { + return nil, err + } + // Insert the expected supply info + result := make(map[string]any) + if err := json.Unmarshal(enc, &result); err != nil { + return nil, err + } + result["expected"] = bt.Expected + return json.Marshal(result) +} diff --git a/eth/tracers/live/testdata/supply/eip1559_burn.json b/eth/tracers/live/testdata/supply/eip1559_burn.json new file mode 100644 index 0000000000..44fe0a328e --- /dev/null +++ b/eth/tracers/live/testdata/supply/eip1559_burn.json @@ -0,0 +1,87 @@ +{ + "eip1559_burn_grayGlacier": { + "blocks": [ + { + "BlockHeader": { + "BaseFeePerGas": "0x342770c0", + "BlobGasUsed": null, + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0100000000000000000000000000000000000000", + "Difficulty": "0x20000", + "ExcessBlobGas": null, + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x5208", + "Hash": "0x7891c11e0cc121c578c62c4b42622b909f4ded1a66fea03336c303e6bc8d6f88", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x1", + "ParentBeaconBlockRoot": null, + "ParentHash": "0xc4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7", + "ReceiptTrie": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "StateRoot": "0x208dc296c4dc37b673a99aed4837174a2ed7f5380ad802d5aed0295e6795241d", + "Timestamp": "0xa", + "TransactionsTrie": "0x4ff793bd96fb3d8d186476e59a5118de9f1813b3f22bd8a64875a535422ac62f", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": null + }, + "ExpectException": "", + "Rlp": "0xf9026cf901faa0c4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a0208dc296c4dc37b673a99aed4837174a2ed7f5380ad802d5aed0295e6795241da04ff793bd96fb3d8d186476e59a5118de9f1813b3f22bd8a64875a535422ac62fa0f78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efab901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018347e7c48252080a80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000084342770c0f86cb86a02f86701800285012a05f20082520894000000000000000000000000000000000000aaaa8080c001a083b46f9cdfcb2c087934d9ae79eedeaa53df39b73c58b7cba5c77d69039bdc64a05af6144d3123f5b9850f9c40fc4b8ce02bf4782f6d6bca3f88e553689d66480bc0", + "UncleHeaders": null + } + ], + "expected": [ + { + "issuance": { + "genesisAlloc": "0xde0b6b3a7640000" + }, + "blockNumber": 0, + "hash": "0xc4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "issuance": { + "reward": "0x1bc16d674ec80000" + }, + "burn": { + "1559": "0x10b643590600" + }, + "blockNumber": 1, + "hash": "0x7891c11e0cc121c578c62c4b42622b909f4ded1a66fea03336c303e6bc8d6f88", + "parentHash": "0xc4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7" + } + ], + "genesisBlockHeader": { + "BaseFeePerGas": "0x3b9aca00", + "BlobGasUsed": null, + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0000000000000000000000000000000000000000", + "Difficulty": "0x20000", + "ExcessBlobGas": null, + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x0", + "Hash": "0xc4265421181cafc43e4b97ae4f21530e37e00320f219a13311482c9c552bcdc7", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x0", + "ParentBeaconBlockRoot": null, + "ParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ReceiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "StateRoot": "0x9f88be00eee1114edfd9372f52560aab3980a142efe8b5b39a09644075084275", + "Timestamp": "0x0", + "TransactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": null + }, + "lastblockhash": "7891c11e0cc121c578c62c4b42622b909f4ded1a66fea03336c303e6bc8d6f88", + "network": "GrayGlacier", + "postState": {}, + "pre": { + "0x71562b71999873db5b286df957af199ec94617f7": { + "balance": "0xde0b6b3a7640000" + } + }, + "sealEngine": "" + } +} \ No newline at end of file diff --git a/eth/tracers/live/testdata/supply/genesis_alloc.json b/eth/tracers/live/testdata/supply/genesis_alloc.json new file mode 100644 index 0000000000..940ef6735d --- /dev/null +++ b/eth/tracers/live/testdata/supply/genesis_alloc.json @@ -0,0 +1,87 @@ +{ + "genesis_alloc_grayGlacier": { + "blocks": [ + { + "BlockHeader": { + "BaseFeePerGas": "0x342770c0", + "BlobGasUsed": null, + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0100000000000000000000000000000000000000", + "Difficulty": "0x20000", + "ExcessBlobGas": null, + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x0", + "Hash": "0x37bb7e9b45f4fb7b311abb5f815e3e00d3382d83a2c39b9b0bd22b717566cd04", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x1", + "ParentBeaconBlockRoot": null, + "ParentHash": "0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca", + "ReceiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "StateRoot": "0x98d03dd72cdfee5c55acc619a1f1bcb1be6d1a10b25b512e7c4e4c4413357940", + "Timestamp": "0xa", + "TransactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": null + }, + "ExpectException": "", + "Rlp": "0xf901fdf901f8a0bcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2caa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a098d03dd72cdfee5c55acc619a1f1bcb1be6d1a10b25b512e7c4e4c4413357940a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000083020000018347e7c4800a80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000084342770c0c0c0", + "UncleHeaders": null + } + ], + "expected": [ + { + "issuance": { + "genesisAlloc": "0x1bc16d674ec80000" + }, + "blockNumber": 0, + "hash": "0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "issuance": { + "reward": "0x1bc16d674ec80000" + }, + "blockNumber": 1, + "hash": "0x37bb7e9b45f4fb7b311abb5f815e3e00d3382d83a2c39b9b0bd22b717566cd04", + "parentHash": "0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca" + } + ], + "genesisBlockHeader": { + "BaseFeePerGas": "0x3b9aca00", + "BlobGasUsed": null, + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0000000000000000000000000000000000000000", + "Difficulty": "0x20000", + "ExcessBlobGas": null, + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x0", + "Hash": "0xbcc9466e9fc6a8b56f4b29ca353a421ff8b51a0c1a58ca4743b427605b08f2ca", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x0", + "ParentBeaconBlockRoot": null, + "ParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ReceiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "StateRoot": "0x4eaed1ec95373a6cad785d6b2506606a2c19e2e7c6d7faf4bab3472c21861b27", + "Timestamp": "0x0", + "TransactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": null + }, + "lastblockhash": "37bb7e9b45f4fb7b311abb5f815e3e00d3382d83a2c39b9b0bd22b717566cd04", + "network": "GrayGlacier", + "postState": {}, + "pre": { + "0x703c4b2bd70c169f5717101caee543299fc946c7": { + "balance": "0xde0b6b3a7640000" + }, + "0x71562b71999873db5b286df957af199ec94617f7": { + "balance": "0xde0b6b3a7640000" + } + }, + "sealEngine": "" + } +} \ No newline at end of file diff --git a/eth/tracers/live/testdata/supply/omitted_fields.json b/eth/tracers/live/testdata/supply/omitted_fields.json new file mode 100644 index 0000000000..2ffbfe81fd --- /dev/null +++ b/eth/tracers/live/testdata/supply/omitted_fields.json @@ -0,0 +1,74 @@ +{ + "omitted_fields_cancun": { + "expected": [ + { + "blockNumber": 0, + "hash": "0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "blockNumber": 1, + "hash": "0xe430cdf604a88b9d713d4f89fd100ddddf38c1cc6b049e3d5df563c7bfd320fc", + "parentHash": "0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703" + } + ], + "blocks": [ + { + "BlockHeader": { + "BaseFeePerGas": "0x342770c0", + "BlobGasUsed": "0x0", + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0100000000000000000000000000000000000000", + "Difficulty": "0x0", + "ExcessBlobGas": "0x0", + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x0", + "Hash": "0xe430cdf604a88b9d713d4f89fd100ddddf38c1cc6b049e3d5df563c7bfd320fc", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x1", + "ParentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ParentHash": "0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703", + "ReceiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "StateRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "Timestamp": "0xa", + "TransactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "ExpectException": "", + "Rlp": "0xf9023ff90239a052f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940100000000000000000000000000000000000000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b901000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080018347e7c4800a80a0000000000000000000000000000000000000000000000000000000000000000088000000000000000084342770c0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218080a00000000000000000000000000000000000000000000000000000000000000000c0c0c0", + "UncleHeaders": null + } + ], + "genesisBlockHeader": { + "BaseFeePerGas": "0x3b9aca00", + "BlobGasUsed": "0x0", + "Bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Coinbase": "0x0000000000000000000000000000000000000000", + "Difficulty": "0x20000", + "ExcessBlobGas": "0x0", + "ExtraData": "0x", + "GasLimit": "0x47e7c4", + "GasUsed": "0x0", + "Hash": "0x52f276d96f0afaaf2c3cb358868bdc2779c4b0cb8de3e7e5302e247c0b66a703", + "MixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "Nonce": "0x0000000000000000", + "Number": "0x0", + "ParentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ParentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ReceiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "StateRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "Timestamp": "0x0", + "TransactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "UncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "WithdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + }, + "lastblockhash": "e430cdf604a88b9d713d4f89fd100ddddf38c1cc6b049e3d5df563c7bfd320fc", + "network": "Cancun", + "postState": {}, + "pre": {}, + "sealEngine": "" + } +} \ No newline at end of file diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 578b7489a3..e7a013e382 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -26,6 +26,7 @@ import ( "math/big" "os" "reflect" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -38,6 +39,7 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" @@ -56,10 +58,41 @@ func (t *BlockTest) UnmarshalJSON(in []byte) error { return json.Unmarshal(in, &t.json) } -func (t *BlockTest) FromChain(chain *core.BlockChain, start, end uint64) (BlockTest, error) { - bt := BlockTest{} - if head := chain.CurrentHeader().Number.Uint64(); head < end { - return bt, fmt.Errorf("Chain is shorter than requested segment: %d < %d", head, end) +// MarshalJSON implements json.Marshaler interface. +func (t *BlockTest) MarshalJSON() ([]byte, error) { + return json.Marshal(t.json) +} + +// FromChain creates a BlockTest from the history of the given chain. +func FromChain(db ethdb.Database, chain *core.BlockChain) (BlockTest, error) { + var ( + bt = BlockTest{} + head = chain.CurrentHeader() + blocks = make([]btBlock, head.Number.Uint64()) + ) + for i := 1; i <= int(head.Number.Uint64()); i++ { + block := chain.GetBlockByNumber(uint64(i)) + fmt.Printf("block: %v\n", block) + if block == nil { + return bt, fmt.Errorf("block %d not found", i) + } + btBlock, err := FromBlock(block) + if err != nil { + return bt, err + } + blocks[i-1] = btBlock + } + alloc, err := core.GetGenesisState(db, chain.Genesis().Hash()) + if err != nil { + return bt, fmt.Errorf("failed to get genesis alloc: %v", err) + } + bt.json = btJSON{ + Network: capitalize(chain.Config().LatestFork(head.Number, head.Time).String()), + Blocks: blocks, + Genesis: FromHeader(chain.Genesis().Header()), + Pre: alloc, + Post: make(types.GenesisAlloc), + BestBlock: common.UnprefixedHash(head.Hash()), } return bt, nil } @@ -81,6 +114,18 @@ type btBlock struct { UncleHeaders []*btHeader } +func FromBlock(block *types.Block) (btBlock, error) { + header := FromHeader(block.Header()) + enc, err := rlp.EncodeToBytes(block) + if err != nil { + return btBlock{}, err + } + return btBlock{ + BlockHeader: &header, + Rlp: "0x" + common.Bytes2Hex(enc), + }, nil +} + //go:generate go run github.com/fjl/gencodec -type btHeader -field-override btHeaderMarshaling -out gen_btheader.go type btHeader struct { @@ -107,6 +152,32 @@ type btHeader struct { ParentBeaconBlockRoot *common.Hash } +func FromHeader(header *types.Header) btHeader { + return btHeader{ + Bloom: header.Bloom, + Coinbase: header.Coinbase, + MixHash: header.MixDigest, + Nonce: header.Nonce, + Number: header.Number, + Hash: header.Hash(), + ParentHash: header.ParentHash, + ReceiptTrie: header.ReceiptHash, + StateRoot: header.Root, + TransactionsTrie: header.TxHash, + UncleHash: header.UncleHash, + ExtraData: header.Extra, + Difficulty: header.Difficulty, + GasLimit: header.GasLimit, + GasUsed: header.GasUsed, + Timestamp: header.Time, + BaseFeePerGas: header.BaseFee, + WithdrawalsRoot: header.WithdrawalsHash, + BlobGasUsed: header.BlobGasUsed, + ExcessBlobGas: header.ExcessBlobGas, + ParentBeaconBlockRoot: header.ParentBeaconRoot, + } +} + type btHeaderMarshaling struct { ExtraData hexutil.Bytes Number *math.HexOrDecimal256 @@ -393,3 +464,11 @@ func (bb *btBlock) decode() (*types.Block, error) { err = rlp.DecodeBytes(data, &b) return &b, err } + +func capitalize(s string) string { + // Check if the string is empty + if len(s) == 0 { + return s + } + return strings.ToUpper(string(s[0])) + s[1:] +}