From 3c514837f3d7c358fe3ac96972d1206c4bbb62be Mon Sep 17 00:00:00 2001 From: Ian Norden Date: Fri, 15 May 2020 20:05:21 -0500 Subject: [PATCH] adjust chain maker for tests to add an empty account in block1 and switch to EIP-158 afterwards (now we just need to generate enough accounts until one causes the empty account to be touched and removed post-EIP-158 so we can simulate and test that process...); also added 2 new blocks where more contract storage is set and old slots are set to zero so they are removed so we can test that --- statediff/builder_test.go | 54 ++++++++++++++++++++++-------- statediff/testhelpers/helpers.go | 38 ++++++++++++++++++--- statediff/testhelpers/test_data.go | 21 +++++++----- 3 files changed, 87 insertions(+), 26 deletions(-) diff --git a/statediff/builder_test.go b/statediff/builder_test.go index 5cf6787b5..e7e927b4d 100644 --- a/statediff/builder_test.go +++ b/statediff/builder_test.go @@ -33,14 +33,14 @@ import ( // TODO: add test that filters on address var ( - contractLeafKey []byte - emptyDiffs = make([]statediff.StateNode, 0) - emptyStorage = make([]statediff.StorageNode, 0) - block0, block1, block2, block3 *types.Block - builder statediff.Builder - miningReward = int64(2000000000000000000) - minerAddress = common.HexToAddress("0x0") - minerLeafKey = testhelpers.AddressToLeafKey(minerAddress) + contractLeafKey, emptyContractLeafKey []byte + emptyDiffs = make([]statediff.StateNode, 0) + emptyStorage = make([]statediff.StorageNode, 0) + block0, block1, block2, block3 *types.Block + builder statediff.Builder + miningReward = int64(2000000000000000000) + minerAddress = common.HexToAddress("0x0") + minerLeafKey = testhelpers.AddressToLeafKey(minerAddress) balanceChange10000 = int64(10000) balanceChange1000 = int64(1000) @@ -77,6 +77,16 @@ var ( common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), bankAccountAtBlock0, }) + emptyContractAtBlock1, _ = rlp.EncodeToBytes(state.Account{ + Nonce: testhelpers.Nonce0, + Balance: big.NewInt(0), + CodeHash: testhelpers.NullCodeHash.Bytes(), + Root: testhelpers.EmptyContractRoot, + }) + emptyContractAtBlock1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("38f0847834712d0d4a56cc9fd09ca7a91cd58d022e0f3790ef365ae82a471419"), + emptyContractAtBlock1, + }) account1AtBlock1, _ = rlp.EncodeToBytes(state.Account{ Nonce: testhelpers.Nonce0, Balance: big.NewInt(balanceChange10000), @@ -98,7 +108,7 @@ var ( minerAccountAtBlock1, }) bankAccountAtBlock1, _ = rlp.EncodeToBytes(state.Account{ - Nonce: testhelpers.Nonce1, + Nonce: testhelpers.Nonce2, Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - balanceChange10000), CodeHash: testhelpers.NullCodeHash.Bytes(), Root: testhelpers.EmptyContractRoot, @@ -128,7 +138,7 @@ var ( contractAccountAtBlock2, }) bankAccountAtBlock2, _ = rlp.EncodeToBytes(state.Account{ - Nonce: testhelpers.Nonce2, + Nonce: testhelpers.Nonce3, Balance: big.NewInt(block1BankBalance - balanceChange1000), CodeHash: testhelpers.NullCodeHash.Bytes(), Root: testhelpers.EmptyContractRoot, @@ -178,7 +188,7 @@ var ( contractAccountAtBlock3, }) bankAccountAtBlock3, _ = rlp.EncodeToBytes(state.Account{ - Nonce: testhelpers.Nonce3, + Nonce: testhelpers.Nonce4, Balance: big.NewInt(99989000), CodeHash: testhelpers.NullCodeHash.Bytes(), Root: testhelpers.EmptyContractRoot, @@ -191,7 +201,7 @@ var ( block1BranchNode, _ = rlp.EncodeToBytes([]interface{}{ crypto.Keccak256(bankAccountAtBlock1LeafNode), []byte{}, - []byte{}, + crypto.Keccak256(emptyContractAtBlock1LeafNode), []byte{}, []byte{}, crypto.Keccak256(minerAccountAtBlock1LeafNode), @@ -210,7 +220,7 @@ var ( block2BranchNode, _ = rlp.EncodeToBytes([]interface{}{ crypto.Keccak256(bankAccountAtBlock2LeafNode), []byte{}, - []byte{}, + crypto.Keccak256(emptyContractAtBlock1LeafNode), []byte{}, []byte{}, crypto.Keccak256(minerAccountAtBlock2LeafNode), @@ -229,7 +239,7 @@ var ( block3BranchNode, _ = rlp.EncodeToBytes([]interface{}{ crypto.Keccak256(bankAccountAtBlock3LeafNode), []byte{}, - []byte{}, + crypto.Keccak256(emptyContractAtBlock1LeafNode), []byte{}, []byte{}, crypto.Keccak256(minerAccountAtBlock2LeafNode), @@ -269,6 +279,7 @@ var ( func TestBuilder(t *testing.T) { blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) + emptyContractLeafKey = testhelpers.AddressToLeafKey(testhelpers.EmptyContractAddr) defer chain.Stop() block0 = testhelpers.Genesis block1 = blocks[0] @@ -339,6 +350,13 @@ func TestBuilder(t *testing.T) { NodeValue: bankAccountAtBlock1LeafNode, StorageDiffs: emptyStorage, }, + { + Path: []byte{'\x02'}, + NodeType: statediff.Leaf, + LeafKey: emptyContractLeafKey, + NodeValue: emptyContractAtBlock1LeafNode, + StorageDiffs: emptyStorage, + }, { Path: []byte{'\x05'}, NodeType: statediff.Leaf, @@ -494,6 +512,7 @@ func TestBuilder(t *testing.T) { func TestBuilderWithIntermediateNodes(t *testing.T) { blocks, chain := testhelpers.MakeChain(3, testhelpers.Genesis) contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) + emptyContractLeafKey = testhelpers.AddressToLeafKey(testhelpers.EmptyContractAddr) defer chain.Stop() block0 = testhelpers.Genesis block1 = blocks[0] @@ -573,6 +592,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) { NodeValue: bankAccountAtBlock1LeafNode, StorageDiffs: emptyStorage, }, + { + Path: []byte{'\x02'}, + NodeType: statediff.Leaf, + LeafKey: emptyContractLeafKey, + NodeValue: emptyContractAtBlock1LeafNode, + StorageDiffs: emptyStorage, + }, { Path: []byte{'\x05'}, NodeType: statediff.Leaf, diff --git a/statediff/testhelpers/helpers.go b/statediff/testhelpers/helpers.go index c67e00dec..5a6ac8fff 100644 --- a/statediff/testhelpers/helpers.go +++ b/statediff/testhelpers/helpers.go @@ -31,7 +31,10 @@ import ( // MakeChain creates a chain of n blocks starting at and including parent. // the returned hash chain is ordered head->parent. func MakeChain(n int, parent *types.Block) ([]*types.Block, *core.BlockChain) { - blocks, _ := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), Testdb, n, testChainGen) + config := params.TestChainConfig + config.EIP158Block = big.NewInt(2) + config.ByzantiumBlock = big.NewInt(2) + blocks, _ := core.GenerateChain(config, parent, ethash.NewFaker(), Testdb, n, testChainGen) chain, _ := core.NewBlockChain(Testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil) return blocks, chain } @@ -41,8 +44,14 @@ func testChainGen(i int, block *core.BlockGen) { switch i { case 0: // In block 1, the test bank sends account #1 some ether. - tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, TestBankKey) - block.AddTx(tx) + // And the bank makes an empty contract account (to be removed by EIP-158) + nonce := block.TxNonce(TestBankAddress) + tx1, _ := types.SignTx(types.NewTransaction(nonce, Account1Addr, big.NewInt(10000), params.TxGas, nil, nil), signer, TestBankKey) + nonce++ + tx2, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), 1000000, big.NewInt(0), EmptyContractCode), signer, TestBankKey) + EmptyContractAddr = crypto.CreateAddress(TestBankAddress, nonce) + block.AddTx(tx1) + block.AddTx(tx2) case 1: // In block 2, the test bank sends some more ether to account #1. // account1Addr passes it on to account #2. @@ -57,12 +66,33 @@ func testChainGen(i int, block *core.BlockGen) { block.AddTx(tx2) block.AddTx(tx3) case 2: - // Block 3 has a single tx from the bankAccount to the contract, that transfers no value, that is mined by account2 + // Block 3 has a single tx from the bankAccount to the contract, that transfers no value + // Block is mined by account2 block.SetCoinbase(Account2Addr) //get function: 60cd2685 //put function: c16431b9 data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data), signer, TestBankKey) block.AddTx(tx) + case 3: + // Block 4 has two more txs from the bankAccount to the contract, that transfer no value + // Block is mined by account1 + block.SetCoinbase(Account1Addr) + data1 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000005") + data2 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002") + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data1), signer, TestBankKey) + tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data2), signer, TestBankKey) + block.AddTx(tx1) + block.AddTx(tx2) + case 4: + // Block 5 has two more txs from the bankAccount to the contract, that transfer no value and set slot positions to 0 + // Block is mined by new Account3Addr + block.SetCoinbase(Account3Addr) + data1 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000") + data2 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000") + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data1), signer, TestBankKey) + tx2, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), 100000, nil, data2), signer, TestBankKey) + block.AddTx(tx1) + block.AddTx(tx2) } } diff --git a/statediff/testhelpers/test_data.go b/statediff/testhelpers/test_data.go index e144797c9..b92791bee 100644 --- a/statediff/testhelpers/test_data.go +++ b/statediff/testhelpers/test_data.go @@ -57,14 +57,18 @@ var ( TestBankFunds = big.NewInt(100000000) Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds) - Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") - Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") - Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7 - Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e - Account1LeafKey = AddressToLeafKey(Account1Addr) - Account2LeafKey = AddressToLeafKey(Account2Addr) - ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50602060405190810160405280600160ff16815250600090600161003592919061003b565b506100a5565b826064810192821561006f579160200282015b8281111561006e578251829060ff1690559160200191906001019061004e565b5b50905061007c9190610080565b5090565b6100a291905b8082111561009e576000816000905550600101610086565b5090565b90565b610124806100b46000396000f3fe6080604052348015600f57600080fd5b5060043610604f576000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146054578063c16431b9146093575b600080fd5b607d60048036036020811015606857600080fd5b810190808035906020019092919050505060c8565b6040518082815260200191505060405180910390f35b60c66004803603604081101560a757600080fd5b81019080803590602001909291908035906020019092919050505060e0565b005b6000808260648110151560d757fe5b01549050919050565b8060008360648110151560ef57fe5b0181905550505056fea165627a7a7230582064e918c3140a117bf3aa65865a9b9e83fae21ad1720506e7933b2a9f54bb40260029") - ContractAddr common.Address + Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") + Account3Key, _ = crypto.HexToECDSA("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") + Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7 + Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e + Account3Addr = crypto.PubkeyToAddress(Account3Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e + Account1LeafKey = AddressToLeafKey(Account1Addr) + Account2LeafKey = AddressToLeafKey(Account2Addr) + Account3LeafKey = AddressToLeafKey(Account3Addr) + ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50602060405190810160405280600160ff16815250600090600161003592919061003b565b506100a5565b826064810192821561006f579160200282015b8281111561006e578251829060ff1690559160200191906001019061004e565b5b50905061007c9190610080565b5090565b6100a291905b8082111561009e576000816000905550600101610086565b5090565b90565b610124806100b46000396000f3fe6080604052348015600f57600080fd5b5060043610604f576000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146054578063c16431b9146093575b600080fd5b607d60048036036020811015606857600080fd5b810190808035906020019092919050505060c8565b6040518082815260200191505060405180910390f35b60c66004803603604081101560a757600080fd5b81019080803590602001909291908035906020019092919050505060e0565b005b6000808260648110151560d757fe5b01549050919050565b8060008360648110151560ef57fe5b0181905550505056fea165627a7a7230582064e918c3140a117bf3aa65865a9b9e83fae21ad1720506e7933b2a9f54bb40260029") + EmptyContractCode []byte + ContractAddr, EmptyContractAddr common.Address EmptyRootNode, _ = rlp.EncodeToBytes([]byte{}) EmptyContractRoot = crypto.Keccak256Hash(EmptyRootNode) @@ -72,4 +76,5 @@ var ( Nonce1 = uint64(1) Nonce2 = uint64(2) Nonce3 = uint64(3) + Nonce4 = uint64(4) )