diff --git a/statediff/builder.go b/statediff/builder.go index 9b79b1dee..eca144d65 100644 --- a/statediff/builder.go +++ b/statediff/builder.go @@ -42,6 +42,7 @@ var ( emptyNode, _ = rlp.EncodeToBytes(&[]byte{}) emptyContractRoot = crypto.Keccak256Hash(emptyNode) nullCodeHash = crypto.Keccak256Hash([]byte{}).Bytes() + nullNodeHash = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") ) // Builder interface exposes the method for building a state diff between two blocks @@ -218,6 +219,9 @@ func (sdb *StateDiffBuilder) createdAndUpdatedState(a, b trie.NodeIterator, diffAccountsAtB[common.Bytes2Hex(accountW.LeafKey)] = *accountW } else { // trie nodes will be written to blockstore only // reminder that this includes leaf nodes, since the geth iterator.Leaf() actually signifies a "value" node + if bytes.Equal(it.Hash().Bytes(), nullNodeHash) { + continue + } nodeVal := make([]byte, len(it.NodeBlob())) copy(nodeVal, it.NodeBlob()) if len(watchedAddressesLeafPaths) > 0 { @@ -279,7 +283,6 @@ func (sdb *StateDiffBuilder) processStateValueNode(it trie.NodeIterator, watched if err != nil { return nil, err } - return &types2.AccountWrapper{ LeafKey: leafKey, Account: &account, @@ -578,6 +581,9 @@ func (sdb *StateDiffBuilder) createdAndUpdatedStorage(a, b trie.NodeIterator, ou } diffSlotsAtB[common.Bytes2Hex(storageLeafNode.LeafKey)] = true } else { + if bytes.Equal(it.Hash().Bytes(), nullNodeHash) { + continue + } nodeVal := make([]byte, len(it.NodeBlob())) copy(nodeVal, it.NodeBlob()) nodeHash := make([]byte, len(it.Hash().Bytes())) diff --git a/statediff/builder_test.go b/statediff/builder_test.go index 6b3897c86..865da91ac 100644 --- a/statediff/builder_test.go +++ b/statediff/builder_test.go @@ -47,10 +47,10 @@ var ( minerAddress = common.HexToAddress("0x0") minerLeafKey = test_helpers.AddressToLeafKey(minerAddress) - slot0 = common.HexToHash("0") - slot1 = common.HexToHash("1") - slot2 = common.HexToHash("2") - slot3 = common.HexToHash("3") + slot0 = common.BigToHash(big.NewInt(0)) + slot1 = common.BigToHash(big.NewInt(1)) + slot2 = common.BigToHash(big.NewInt(2)) + slot3 = common.BigToHash(big.NewInt(3)) slot0StorageKey = crypto.Keccak256Hash(slot0[:]) slot1StorageKey = crypto.Keccak256Hash(slot1[:]) @@ -504,7 +504,7 @@ func init() { } } -func TestBuilderF(t *testing.T) { +func TestBuilder(t *testing.T) { blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen) contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) defer chain.Stop() @@ -886,22 +886,19 @@ func TestBuilderF(t *testing.T) { t.Logf("Test failed: %s", test.name) t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } - // Let's also confirm that our root state nodes form the state root hash in the headers - /* - if i > 0 { - block := blocks[i-1] - expectedStateRoot := block.Root() - for _, node := range test.expected.Nodes { - if bytes.Equal(node.Path, []byte{}) { - stateRoot := crypto.Keccak256Hash(node.NodeValue) - if !bytes.Equal(expectedStateRoot.Bytes(), stateRoot.Bytes()) { - t.Logf("Test failed: %s", test.name) - t.Errorf("actual stateroot: %x\r\nexpected stateroot: %x", stateRoot.Bytes(), expectedStateRoot.Bytes()) - } - } - } - } - */ + } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) { + t.Errorf("block0 expected root %x does not match actual root %x", block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) + } + if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) { + t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) + } + if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) { + t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) + } + if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) { + t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) } } @@ -1159,6 +1156,19 @@ func TestBuilderWithWatchedAddressList(t *testing.T) { t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) { + t.Errorf("block0 expected root %x does not match actual root %x", block0.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock0LeafNode)) + } + if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) { + t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1BranchRootNode)) + } + if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) { + t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2BranchRootNode)) + } + if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) { + t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3BranchRootNode)) + } } func TestBuilderWithRemovedAccountAndStorage(t *testing.T) { @@ -1472,6 +1482,16 @@ func TestBuilderWithRemovedAccountAndStorage(t *testing.T) { t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) { + t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) + } + if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) { + t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) + } + if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) { + t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) + } } func TestBuilderWithRemovedNonWatchedAccount(t *testing.T) { @@ -1652,6 +1672,16 @@ func TestBuilderWithRemovedNonWatchedAccount(t *testing.T) { t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) { + t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) + } + if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) { + t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) + } + if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) { + t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) + } } func TestBuilderWithRemovedWatchedAccount(t *testing.T) { @@ -1905,6 +1935,16 @@ func TestBuilderWithRemovedWatchedAccount(t *testing.T) { t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) { + t.Errorf("block4 expected root %x does not match actual root %x", block4.Root().Bytes(), crypto.Keccak256(block4BranchRootNode)) + } + if !bytes.Equal(block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) { + t.Errorf("block5 expected root %x does not match actual root %x", block5.Root().Bytes(), crypto.Keccak256(block5BranchRootNode)) + } + if !bytes.Equal(block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) { + t.Errorf("block6 expected root %x does not match actual root %x", block6.Root().Bytes(), crypto.Keccak256(block6BranchRootNode)) + } } var ( @@ -2177,6 +2217,13 @@ func TestBuilderWithMovedAccount(t *testing.T) { t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) } } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block01BranchRootNode)) { + t.Errorf("block01 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block01BranchRootNode)) + } + if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock02LeafNode)) { + t.Errorf("block02 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(bankAccountAtBlock02LeafNode)) + } } /* @@ -2209,3 +2256,853 @@ contract test { } } */ + +var ( + b = big.NewInt(0).Sub(test_helpers.TestBIGBankFunds, test_helpers.BalanceChangeBIG) + block1BankBigBalance = big.NewInt(0).Sub(b, big.NewInt(test_helpers.GasFees2)) + bankAccountAtBlock1b = &types.StateAccount{ + Nonce: 1, + Balance: block1BankBigBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + } + bankAccountAtBlock1bRLP, _ = rlp.EncodeToBytes(bankAccountAtBlock1b) + bankAccountAtBlock1bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock1bRLP, + }) + + account1AtBlock1b = &types.StateAccount{ + Nonce: 0, + Balance: test_helpers.Block1bAccount1Balance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + } + account1AtBlock1bRLP, _ = rlp.EncodeToBytes(account1AtBlock1b) + account1AtBlock1bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock1bRLP, + }) + + account1AtBlock2bBalance, _ = big.NewInt(0).SetString("1999999999999999999999999761539571000000000", 10) + account1AtBlock2b = &types.StateAccount{ + Nonce: 1, + Balance: account1AtBlock2bBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + } + account1AtBlock2bRLP, _ = rlp.EncodeToBytes(account1AtBlock2b) + account1AtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock2bRLP, + }) + + minerAccountAtBlock2b = &types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(4055891787808414571), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + } + minerAccountAtBlock2bRLP, _ = rlp.EncodeToBytes(minerAccountAtBlock2b) + minerAccountAtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccountAtBlock2bRLP, + }) + + contractAccountAtBlock2b = &types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: test_helpers.CodeHashForInternalizedLeafNode.Bytes(), + Root: crypto.Keccak256Hash(block2StorageBranchRootNode), + } + contractAccountAtBlock2bRLP, _ = rlp.EncodeToBytes(contractAccountAtBlock2b) + contractAccountAtBlock2bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3d7e14f1723fa19b5d6d9f8b86b49acefbc9c400bf4ed686c10d6b6467fc5b3a"), + contractAccountAtBlock2bRLP, + }) + + bankAccountAtBlock3bBalance, _ = big.NewInt(0).SetString("18000000000000000000000001999920365757724976", 10) + bankAccountAtBlock3b = &types.StateAccount{ + Nonce: 3, + Balance: bankAccountAtBlock3bBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + } + bankAccountAtBlock3bRLP, _ = rlp.EncodeToBytes(bankAccountAtBlock3b) + bankAccountAtBlock3bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock3bRLP, + }) + + contractAccountAtBlock3b = &types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: test_helpers.CodeHashForInternalizedLeafNode.Bytes(), + Root: crypto.Keccak256Hash(block3bStorageBranchRootNode), + } + contractAccountAtBlock3bRLP, _ = rlp.EncodeToBytes(contractAccountAtBlock3b) + contractAccountAtBlock3bLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3d7e14f1723fa19b5d6d9f8b86b49acefbc9c400bf4ed686c10d6b6467fc5b3a"), + contractAccountAtBlock3bRLP, + }) + + slot40364 = common.BigToHash(big.NewInt(40364)) + slot105566 = common.BigToHash(big.NewInt(105566)) + + slot40364StorageValue = common.Hex2Bytes("01") + slot105566StorageValue = common.Hex2Bytes("02") + + slot40364StorageKey = crypto.Keccak256Hash(slot40364[:]) + slot105566StorageKey = crypto.Keccak256Hash(slot105566[:]) + + slot40364StorageInternalLeafNode = []interface{}{ + common.Hex2Bytes("3077bbc951a04529defc15da8c06e427cde0d7a1499c50975bbe8aab"), + slot40364StorageValue, + } + slot105566StorageInternalLeafNode = []interface{}{ + common.Hex2Bytes("3c62586c18bf1ecfda161ced374b7a894630e2db426814c24e5d42af"), + slot105566StorageValue, + } + + block3bStorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot0StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(slot1StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(block3bStorageExtensionNode), + []byte{}, + }) + + block3bStorageExtensionNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("1291631c"), + crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves), + }) + + block3bStorageBranchNodeWithInternalLeaves, _ = rlp.EncodeToBytes(&[]interface{}{ + slot105566StorageInternalLeafNode, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + slot40364StorageInternalLeafNode, + []byte{}, + []byte{}, + []byte{}, + }) + + block1bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock1bLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock1LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account1AtBlock1bLeafNode), + []byte{}, + []byte{}, + }) + + block2bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock1bLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2bLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account1AtBlock2bLeafNode), + crypto.Keccak256(contractAccountAtBlock2bLeafNode), + []byte{}, + }) + + block3bBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock3bLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2bLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account1AtBlock2bLeafNode), + crypto.Keccak256(contractAccountAtBlock3bLeafNode), + []byte{}, + }) +) + +func TestBuilderWithInternalizedLeafNode(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.GenesisForInternalLeafNodeTest, test_helpers.TestChainGenWithInternalLeafNode) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + params := statediff.Params{} + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testEmptyDiff", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock0", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: test_helpers.NullHash, + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: bankAccountAtBlock0, + LeafKey: test_helpers.BankLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String()}, + StorageDiff: emptyStorage, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock0LeafNode)).String(), + Content: bankAccountAtBlock0LeafNode, + }, + }, + }, + }, + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: bankAccountAtBlock1b, + LeafKey: test_helpers.BankLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1bLeafNode)).String()}, + StorageDiff: emptyStorage, + }, + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: minerAccountAtBlock1, + LeafKey: minerLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String()}, + StorageDiff: emptyStorage, + }, + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: account1AtBlock1b, + LeafKey: test_helpers.Account1LeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1bLeafNode)).String()}, + StorageDiff: emptyStorage, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1bBranchRootNode)).String(), + Content: block1bBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock1bLeafNode)).String(), + Content: bankAccountAtBlock1bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock1LeafNode)).String(), + Content: minerAccountAtBlock1LeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock1bLeafNode)).String(), + Content: account1AtBlock1bLeafNode, + }, + }, + }, + }, + { + "testBlock2", + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: minerAccountAtBlock2b, + LeafKey: minerLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2bLeafNode)).String()}, + StorageDiff: emptyStorage, + }, + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: account1AtBlock2b, + LeafKey: test_helpers.Account1LeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2bLeafNode)).String()}, + StorageDiff: emptyStorage, + }, + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: contractAccountAtBlock2b, + LeafKey: contractLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String()}, + StorageDiff: []types2.StorageLeafNode{ + { + Removed: false, + Value: slot0StorageValue, + LeafKey: slot0StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(), + }, + { + Removed: false, + Value: slot1StorageValue, + LeafKey: slot1StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(), + }, + }, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHashForInternalizedLeafNode.Bytes()).String(), + Content: test_helpers.ByteCodeAfterDeploymentForInternalLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2bBranchRootNode)).String(), + Content: block2bBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(minerAccountAtBlock2bLeafNode)).String(), + Content: minerAccountAtBlock2bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(account1AtBlock2bLeafNode)).String(), + Content: account1AtBlock2bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String(), + Content: contractAccountAtBlock2bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(), + Content: block2StorageBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(), + Content: slot0StorageLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(), + Content: slot1StorageLeafNode, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: bankAccountAtBlock3b, + LeafKey: test_helpers.BankLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3bLeafNode)).String()}, + StorageDiff: emptyStorage, + }, + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: contractAccountAtBlock3b, + LeafKey: contractLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String()}, + StorageDiff: []types2.StorageLeafNode{ + { + Removed: false, + Value: slot105566StorageValue, + LeafKey: slot105566StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + }, + { + Removed: false, + Value: slot40364StorageValue, + LeafKey: slot40364StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + }, + }, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3bBranchRootNode)).String(), + Content: block3bBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(bankAccountAtBlock3bLeafNode)).String(), + Content: bankAccountAtBlock3bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String(), + Content: contractAccountAtBlock3bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchRootNode)).String(), + Content: block3bStorageBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageExtensionNode)).String(), + Content: block3bStorageExtensionNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + Content: block3bStorageBranchNodeWithInternalLeaves, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + actual, err := json.Marshal(diff) + if err != nil { + t.Error(err) + } + expected, err := json.Marshal(test.expected) + if err != nil { + t.Error(err) + } + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) + } + } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) { + t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) + } + if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) { + t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) + } + if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) { + t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) + } +} + +func TestBuilderWithInternalizedLeafNodeAndWatchedAddress(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.GenesisForInternalLeafNodeTest, test_helpers.TestChainGenWithInternalLeafNode) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + params := statediff.Params{ + WatchedAddresses: []common.Address{ + test_helpers.ContractAddr, + }, + } + params.ComputeWatchedAddressesLeafPaths() + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testEmptyDiff", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock0", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: test_helpers.NullHash, + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: []types2.StateLeafNode{}, + IPLDs: []types2.IPLD{}, // there's some kind of weird behavior where if our root node is a leaf node + // even though it is along the path to the watched leaf (necessarily, as it is the root) it doesn't get included + // unconsequential, but kinda odd. + }, + }, + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateLeafNode{}, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block1bBranchRootNode)).String(), + Content: block1bBranchRootNode, + }, + }, + }, + }, + { + "testBlock2", + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: contractAccountAtBlock2b, + LeafKey: contractLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String()}, + StorageDiff: []types2.StorageLeafNode{ + { + Removed: false, + Value: slot0StorageValue, + LeafKey: slot0StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(), + }, + { + Removed: false, + Value: slot1StorageValue, + LeafKey: slot1StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(), + }, + }, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.RawBinary, test_helpers.CodeHashForInternalizedLeafNode.Bytes()).String(), + Content: test_helpers.ByteCodeAfterDeploymentForInternalLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block2bBranchRootNode)).String(), + Content: block2bBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock2bLeafNode)).String(), + Content: contractAccountAtBlock2bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block2StorageBranchRootNode)).String(), + Content: block2StorageBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot0StorageLeafNode)).String(), + Content: slot0StorageLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(slot1StorageLeafNode)).String(), + Content: slot1StorageLeafNode, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateLeafNode{ + { + Removed: false, + AccountWrapper: struct { + Account *types.StateAccount + LeafKey []byte + CID string + }{ + Account: contractAccountAtBlock3b, + LeafKey: contractLeafKey, + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String()}, + StorageDiff: []types2.StorageLeafNode{ + { + Removed: false, + Value: slot105566StorageValue, + LeafKey: slot105566StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + }, + { + Removed: false, + Value: slot40364StorageValue, + LeafKey: slot40364StorageKey.Bytes(), + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + }, + }, + }, + }, + IPLDs: []types2.IPLD{ + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(block3bBranchRootNode)).String(), + Content: block3bBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStateTrie, crypto.Keccak256(contractAccountAtBlock3bLeafNode)).String(), + Content: contractAccountAtBlock3bLeafNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchRootNode)).String(), + Content: block3bStorageBranchRootNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageExtensionNode)).String(), + Content: block3bStorageExtensionNode, + }, + { + CID: ipld2.Keccak256ToCid(ipld2.MEthStorageTrie, crypto.Keccak256(block3bStorageBranchNodeWithInternalLeaves)).String(), + Content: block3bStorageBranchNodeWithInternalLeaves, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + actual, err := json.Marshal(diff) + if err != nil { + t.Error(err) + } + expected, err := json.Marshal(test.expected) + if err != nil { + t.Error(err) + } + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %s\r\n\r\n\r\nexpected state diff: %s", actual, expected) + } + } + // Let's also confirm that our root state nodes form the state root hash in the headers + if !bytes.Equal(block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) { + t.Errorf("block1 expected root %x does not match actual root %x", block1.Root().Bytes(), crypto.Keccak256(block1bBranchRootNode)) + } + if !bytes.Equal(block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) { + t.Errorf("block2 expected root %x does not match actual root %x", block2.Root().Bytes(), crypto.Keccak256(block2bBranchRootNode)) + } + if !bytes.Equal(block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) { + t.Errorf("block3 expected root %x does not match actual root %x", block3.Root().Bytes(), crypto.Keccak256(block3bBranchRootNode)) + } +} + +/* +pragma solidity ^0.5.10; + +contract test { + address payable owner; + + modifier onlyOwner { + require( + msg.sender == owner, + "Only owner can call this function." + ); + _; + } + + uint256[105566] data; + + constructor() public { + owner = msg.sender; + data = [1]; + } + + function Put(uint256 addr, uint256 value) public { + data[addr] = value; + } + + function close() public onlyOwner { //onlyOwner is custom modifier + selfdestruct(owner); // `owner` is the owners address + } +} +*/ diff --git a/statediff/test_helpers/constant.go b/statediff/test_helpers/constant.go index ba591ebb4..da41827d7 100644 --- a/statediff/test_helpers/constant.go +++ b/statediff/test_helpers/constant.go @@ -23,11 +23,14 @@ import ( ) var ( - BalanceChange1000 = int64(1000) - BalanceChange10000 = int64(10000) - BalanceChange1Ether = int64(params.Ether) - Block1Account1Balance = big.NewInt(BalanceChange10000) - Block2Account2Balance = big.NewInt(21000000000000) - GasFees = int64(params.GWei) * int64(params.TxGas) - ContractGasLimit = uint64(1000000) + BalanceChange1000 = int64(1000) + BalanceChange10000 = int64(10000) + BalanceChangeBIG, _ = big.NewInt(0).SetString("2000000000000000000000000000000000000000000", 10) + BalanceChange1Ether = int64(params.Ether) + Block1Account1Balance = big.NewInt(BalanceChange10000) + Block1bAccount1Balance = BalanceChangeBIG + GasFees = int64(params.GWei) * int64(params.TxGas) + GasFees2 = int64(params.TxGas) * int64(params.InitialBaseFee) + ContractGasLimit = uint64(1000000) + ContractForInternalLeafNodeGasLimit = uint64(500000000) ) diff --git a/statediff/test_helpers/helpers.go b/statediff/test_helpers/helpers.go index 5e3823be2..5fd6c861a 100644 --- a/statediff/test_helpers/helpers.go +++ b/statediff/test_helpers/helpers.go @@ -29,10 +29,13 @@ import ( "github.com/ethereum/go-ethereum/params" ) -func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { +func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance, baseFee *big.Int, initialGasLimit uint64) *types.Block { g := core.Genesis{ Alloc: core.GenesisAlloc{addr: {Balance: balance}}, - BaseFee: big.NewInt(params.InitialBaseFee), + BaseFee: baseFee, + } + if initialGasLimit != 0 { + g.GasLimit = initialGasLimit } return g.MustCommit(db) } @@ -135,3 +138,32 @@ func TestChainGen(i int, block *core.BlockGen) { block.AddTx(tx) } } + +func TestChainGenWithInternalLeafNode(i int, block *core.BlockGen) { + signer := types.HomesteadSigner{} + switch i { + case 0: + // In block 1, the test bank sends account #1 some ether. + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, BalanceChangeBIG, params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, TestBankKey) + block.AddTx(tx) + case 1: + // In block 2 Account1Addr creates a test contract. + nonce := block.TxNonce(Account1Addr) + tx1, _ := types.SignTx(types.NewContractCreation(block.TxNonce(Account1Addr), big.NewInt(0), ContractForInternalLeafNodeGasLimit, big.NewInt(params.InitialBaseFee), ContractCodeForInternalLeafNode), signer, Account1Key) + ContractAddr = crypto.CreateAddress(Account1Addr, nonce) + block.AddTx(tx1) + case 2: + // Block 3 has two transactions which set slots 223 and 648 with small values + // The goal here is to induce a branch node with an internalized leaf node + block.SetCoinbase(TestBankAddress) + data1 := common.Hex2Bytes("C16431B90000000000000000000000000000000000000000000000000000000000009dab0000000000000000000000000000000000000000000000000000000000000001") + data2 := common.Hex2Bytes("C16431B90000000000000000000000000000000000000000000000000000000000019c5d0000000000000000000000000000000000000000000000000000000000000002") + + nonce := block.TxNonce(TestBankAddress) + tx1, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data1), signer, TestBankKey) + nonce++ + tx2, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data2), signer, TestBankKey) + block.AddTx(tx1) + block.AddTx(tx2) + } +} diff --git a/statediff/test_helpers/test_data.go b/statediff/test_helpers/test_data.go index e5a06a2a1..438917795 100644 --- a/statediff/test_helpers/test_data.go +++ b/statediff/test_helpers/test_data.go @@ -50,23 +50,27 @@ var ( StorageValue = common.Hex2Bytes("0x03") NullHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") - Testdb = rawdb.NewMemoryDatabase() - TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7 - BankLeafKey = AddressToLeafKey(TestBankAddress) - TestBankFunds = big.NewInt(params.Ether * 2) - Genesis = 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("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e4565b82606481019282156100ae579160200282015b828111156100ad578251829060ff1690559160200191906001019061008d565b5b5090506100bb91906100bf565b5090565b6100e191905b808211156100dd5760008160009055506001016100c5565b5090565b90565b6101ca806100f36000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") - ByteCodeAfterDeployment = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") - CodeHash = common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127") - ContractAddr common.Address + Testdb = rawdb.NewMemoryDatabase() + TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7 + BankLeafKey = AddressToLeafKey(TestBankAddress) + TestBankFunds = big.NewInt(params.Ether * 2) + TestBIGBankFunds, _ = big.NewInt(0).SetString("20000000000000000000000000000000000000000000", 10) + Genesis = GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds, big.NewInt(params.InitialBaseFee), 0) + GenesisForInternalLeafNodeTest = GenesisBlockForTesting(Testdb, TestBankAddress, TestBIGBankFunds, big.NewInt(params.InitialBaseFee), params.MaxGasLimit) + 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("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e4565b82606481019282156100ae579160200282015b828111156100ad578251829060ff1690559160200191906001019061008d565b5b5090506100bb91906100bf565b5090565b6100e191905b808211156100dd5760008160009055506001016100c5565b5090565b90565b6101ca806100f36000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") + ByteCodeAfterDeployment = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") + CodeHash = common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127") + ContractCodeForInternalLeafNode = common.Hex2Bytes("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e6565b8262019c5e81019282156100b0579160200282015b828111156100af578251829060ff1690559160200191906001019061008f565b5b5090506100bd91906100c1565b5090565b6100e391905b808211156100df5760008160009055506001016100c7565b5090565b90565b6101cc806100f56000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101766022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018362019c5e811061016c57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a7231582007250e2c86ac8989891c4aa9c4737119491578200b9104c574143607ed71642b64736f6c63430005110032") + ByteCodeAfterDeploymentForInternalLeafNode = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101766022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b8060018362019c5e811061016c57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a7231582007250e2c86ac8989891c4aa9c4737119491578200b9104c574143607ed71642b64736f6c63430005110032") + CodeHashForInternalizedLeafNode = common.HexToHash("8327d45b7e6ffe26fc9728db4cd3c1c8177f7af2de0d31dfe5435e83101db04f") + ContractAddr common.Address EmptyRootNode, _ = rlp.EncodeToBytes(&[]byte{}) EmptyContractRoot = crypto.Keccak256Hash(EmptyRootNode)