diff --git a/cmd/geth/main.go b/cmd/geth/main.go index bc6a2639578e..ae18062f11f3 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -147,7 +147,6 @@ var ( utils.EWASMInterpreterFlag, utils.EVMInterpreterFlag, utils.StateDiffFlag, - utils.StateDiffPathsAndProofs, utils.StateDiffIntermediateNodes, utils.StateDiffStreamBlock, utils.StateDiffWatchedAddresses, diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go index 7c863f4eb03a..f90b8759cbeb 100644 --- a/cmd/geth/usage.go +++ b/cmd/geth/usage.go @@ -255,7 +255,6 @@ var AppHelpFlagGroups = []flagGroup{ Name: "STATE DIFF", Flags: []cli.Flag{ utils.StateDiffFlag, - utils.StateDiffPathsAndProofs, utils.StateDiffIntermediateNodes, utils.StateDiffStreamBlock, utils.StateDiffWatchedAddresses, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 35107feb29f6..6701041ed5ee 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -761,10 +761,6 @@ var ( Name: "statediff", Usage: "Enables the processing of state diffs between each block", } - StateDiffPathsAndProofs = cli.BoolFlag{ - Name: "statediff.pathsandproofs", - Usage: "Set to true to generate paths and proof sets for diffed state and storage trie leaf nodes", - } StateDiffIntermediateNodes = cli.BoolFlag{ Name: "statediff.intermediatenodes", Usage: "Set to include intermediate (branch and extension) nodes; default (false) processes leaf nodes only", @@ -1651,7 +1647,6 @@ func RegisterGraphQLService(stack *node.Node, endpoint string, cors, vhosts []st // RegisterStateDiffService configures and registers a service to stream state diff data over RPC func RegisterStateDiffService(stack *node.Node, ctx *cli.Context) { config := statediff.Config{ - PathsAndProofs: ctx.GlobalBool(StateDiffPathsAndProofs.Name), IntermediateNodes: ctx.GlobalBool(StateDiffIntermediateNodes.Name), StreamBlock: ctx.GlobalBool(StateDiffStreamBlock.Name), WatchedAddresses: ctx.GlobalStringSlice(StateDiffWatchedAddresses.Name), @@ -1659,9 +1654,8 @@ func RegisterStateDiffService(stack *node.Node, ctx *cli.Context) { if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) { var ethServ *eth.Ethereum ctx.Service(ðServ) - chainDb := ethServ.ChainDb() blockChain := ethServ.BlockChain() - return statediff.NewStateDiffService(chainDb, blockChain, config) + return statediff.NewStateDiffService(blockChain, config) }); err != nil { Fatalf("Failed to register State Diff Service", err) } diff --git a/statediff/builder.go b/statediff/builder.go index bbd523a5f6f5..beb865093de4 100644 --- a/statediff/builder.go +++ b/statediff/builder.go @@ -28,7 +28,6 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" @@ -42,16 +41,14 @@ type Builder interface { } type builder struct { - chainDB ethdb.Database config Config blockChain *core.BlockChain stateCache state.Database } // NewBuilder is used to create a statediff builder -func NewBuilder(db ethdb.Database, blockChain *core.BlockChain, config Config) Builder { +func NewBuilder(blockChain *core.BlockChain, config Config) Builder { return &builder{ - chainDB: db, config: config, blockChain: blockChain, } @@ -71,17 +68,13 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block } // Find created accounts - oldIt := oldTrie.NodeIterator([]byte{}) - newIt := newTrie.NodeIterator([]byte{}) - creations, err := sdb.collectDiffNodes(oldIt, newIt) + creations, err := sdb.collectDiffNodes(oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{})) if err != nil { return StateDiff{}, fmt.Errorf("error collecting creation diff nodes: %v", err) } // Find deleted accounts - oldIt = oldTrie.NodeIterator([]byte{}) - newIt = newTrie.NodeIterator([]byte{}) - deletions, err := sdb.collectDiffNodes(newIt, oldIt) + deletions, err := sdb.collectDiffNodes(newTrie.NodeIterator([]byte{}), oldTrie.NodeIterator([]byte{})) if err != nil { return StateDiff{}, fmt.Errorf("error collecting deletion diff nodes: %v", err) } @@ -131,58 +124,62 @@ func (sdb *builder) isWatchedAddress(hashKey []byte) bool { } func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error) { - var diffAccounts = make(AccountsMap) + diffAccounts := make(AccountsMap) it, _ := trie.NewDifferenceIterator(a, b) - for { - log.Debug("Current Path and Hash", "path", pathToStr(it), "old hash", it.Hash()) - if it.Leaf() && sdb.isWatchedAddress(it.LeafKey()) { - leafKey := make([]byte, len(it.LeafKey())) - copy(leafKey, it.LeafKey()) - leafKeyHash := common.BytesToHash(leafKey) - leafValue := make([]byte, len(it.LeafBlob())) - copy(leafValue, it.LeafBlob()) - // lookup account state + for it.Next(true) { + // skip value nodes + if it.Leaf() { + continue + } + if bytes.Equal(nullNode, it.Hash().Bytes()) { + continue + } + nodePath := make([]byte, len(it.Path())) + copy(nodePath, it.Path()) + node, err := sdb.stateCache.TrieDB().Node(it.Hash()) + if err != nil { + return nil, err + } + var nodeElements []interface{} + if err := rlp.DecodeBytes(node, &nodeElements); err != nil { + return nil, err + } + ty, err := CheckKeyType(nodeElements) + if err != nil { + return nil, err + } + switch ty { + case Leaf: var account state.Account - if err := rlp.DecodeBytes(leafValue, &account); err != nil { - return nil, fmt.Errorf("error looking up account via address %s\r\nerror: %v", leafKeyHash.Hex(), err) - } - aw := accountWrapper{ - Leaf: true, - Account: &account, - RawKey: leafKey, - RawValue: leafValue, + if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { + return nil, fmt.Errorf("error decoding account for leaf node at path %x\r\nerror: %v\r\n", nodePath, err) } - if sdb.config.PathsAndProofs { - leafProof := make([][]byte, len(it.LeafProof())) - copy(leafProof, it.LeafProof()) - leafPath := make([]byte, len(it.Path())) - copy(leafPath, it.Path()) - aw.Proof = leafProof - aw.Path = leafPath + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(nodePath, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + if sdb.isWatchedAddress(leafKey) { + aw := accountWrapper{ + NodeType: ty, + Path: nodePath, + NodeValue: node, + LeafKey: leafKey, + Account: &account, + } + diffAccounts[common.BytesToHash(encodedPath)] = aw } - // record account to diffs (creation if we are looking at new - old; deletion if old - new) - log.Debug("Account lookup successful", "address", leafKeyHash, "account", account) - diffAccounts[leafKeyHash] = aw - } else if sdb.config.IntermediateNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) { - nodeKey := it.Hash() - node, err := sdb.stateCache.TrieDB().Node(nodeKey) - if err != nil { - return nil, fmt.Errorf("error looking up intermediate state trie node %s\r\nerror: %v", nodeKey.Hex(), err) + case Extension, Branch: + if sdb.config.IntermediateNodes { + diffAccounts[common.BytesToHash(nodePath)] = accountWrapper{ + NodeType: ty, + Path: nodePath, + NodeValue: node, + } } - aw := accountWrapper{ - Leaf: false, - RawKey: nodeKey.Bytes(), - RawValue: node, - } - log.Debug("intermediate state trie node lookup successful", "key", nodeKey.Hex(), "value", node) - diffAccounts[nodeKey] = aw - } - cont := it.Next(true) - if !cont { - break + default: + return nil, fmt.Errorf("unexpected node type %s", ty) } } - return diffAccounts, nil } @@ -195,16 +192,15 @@ func (sdb *builder) buildDiffEventual(accounts AccountsMap) ([]AccountDiff, erro if val.Account != nil { storageDiffs, err = sdb.buildStorageDiffsEventual(val.Account.Root) if err != nil { - return nil, fmt.Errorf("failed building eventual storage diffs for %s\r\nerror: %v", common.BytesToHash(val.RawKey), err) + return nil, fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err) } } accountDiffs = append(accountDiffs, AccountDiff{ - Leaf: val.Leaf, - Key: val.RawKey, - Value: val.RawValue, - Proof: val.Proof, - Path: val.Path, - Storage: storageDiffs, + NodeType: val.NodeType, + Path: val.Path, + LeafKey: val.LeafKey, + NodeValue: val.NodeValue, + Storage: storageDiffs, }) } @@ -228,12 +224,11 @@ func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions Accoun } } updatedAccounts = append(updatedAccounts, AccountDiff{ - Leaf: createdAcc.Leaf, - Key: createdAcc.RawKey, - Value: createdAcc.RawValue, - Proof: createdAcc.Proof, - Path: createdAcc.Path, - Storage: storageDiffs, + NodeType: createdAcc.NodeType, + Path: createdAcc.Path, + NodeValue: createdAcc.NodeValue, + LeafKey: createdAcc.LeafKey, + Storage: storageDiffs, }) delete(creations, common.HexToHash(val)) delete(deletions, common.HexToHash(val)) @@ -275,46 +270,52 @@ func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDiff, error) { storageDiffs := make([]StorageDiff, 0) - for { - log.Debug("Iterating over state at path ", "path", pathToStr(it)) + for it.Next(true) { + // skip value nodes if it.Leaf() { - log.Debug("Found leaf in storage", "path", pathToStr(it)) - leafKey := make([]byte, len(it.LeafKey())) - copy(leafKey, it.LeafKey()) - leafValue := make([]byte, len(it.LeafBlob())) - copy(leafValue, it.LeafBlob()) + continue + } + if bytes.Equal(nullNode, it.Hash().Bytes()) { + continue + } + nodePath := make([]byte, len(it.Path())) + copy(nodePath, it.Path()) + node, err := sdb.stateCache.TrieDB().Node(it.Hash()) + if err != nil { + return nil, err + } + var nodeElements []interface{} + if err := rlp.DecodeBytes(node, &nodeElements); err != nil { + return nil, err + } + ty, err := CheckKeyType(nodeElements) + if err != nil { + return nil, err + } + switch ty { + case Leaf: + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(nodePath, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] sd := StorageDiff{ - Leaf: true, - Key: leafKey, - Value: leafValue, - } - if sdb.config.PathsAndProofs { - leafProof := make([][]byte, len(it.LeafProof())) - copy(leafProof, it.LeafProof()) - leafPath := make([]byte, len(it.Path())) - copy(leafPath, it.Path()) - sd.Proof = leafProof - sd.Path = leafPath + NodeType: ty, + Path: nodePath, + NodeValue: node, + LeafKey: leafKey, } storageDiffs = append(storageDiffs, sd) - } else if sdb.config.IntermediateNodes && !bytes.Equal(nullNode, it.Hash().Bytes()) { - nodeKey := it.Hash() - node, err := sdb.stateCache.TrieDB().Node(nodeKey) - if err != nil { - return nil, fmt.Errorf("error looking up intermediate storage trie node %s\r\nerror: %v", nodeKey.Hex(), err) + case Extension, Branch: + if sdb.config.IntermediateNodes { + storageDiffs = append(storageDiffs, StorageDiff{ + NodeType: ty, + Path: nodePath, + NodeValue: node, + }) } - storageDiffs = append(storageDiffs, StorageDiff{ - Leaf: false, - Key: nodeKey.Bytes(), - Value: node, - }) - log.Debug("intermediate storage trie node lookup successful", "key", nodeKey.Hex(), "value", node) - } - cont := it.Next(true) - if !cont { - break + default: + return nil, fmt.Errorf("unexpected node type %s", ty) } } - return storageDiffs, nil } diff --git a/statediff/builder_test.go b/statediff/builder_test.go index 1cd5cdf38d88..24ab3e0a1f49 100644 --- a/statediff/builder_test.go +++ b/statediff/builder_test.go @@ -31,101 +31,153 @@ import ( "github.com/ethereum/go-ethereum/statediff/testhelpers" ) +// TODO: add test that filters on address var ( - contractLeafKey common.Hash + contractLeafKey []byte emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0) emptyAccountDiffIncrementalMap = make([]statediff.AccountDiff, 0) block0, block1, block2, block3 *types.Block builder statediff.Builder miningReward = int64(2000000000000000000) - burnAddress = common.HexToAddress("0x0") - burnLeafKey = testhelpers.AddressToLeafKey(burnAddress) + minerAddress = common.HexToAddress("0x0") + minerLeafKey = testhelpers.AddressToEncodedPath(minerAddress) - balanceChange10000 = int64(10000) - balanceChange1000 = int64(1000) - block1BankBalance = int64(99990000) - block1Account1Balance = int64(10000) - block2Account2Balance = int64(1000) - nonce0 = uint64(0) - nonce1 = uint64(1) - nonce2 = uint64(2) - nonce3 = uint64(3) - originalContractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - contractContractRoot = "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0" - newContractRoot = "0x71e0d14b2b93e5c7f9748e69e1fe5f17498a1c3ac3cec29f96af13d7f8a4e070" - originalStorageLocation = common.HexToHash("0") - originalStorageKey = crypto.Keccak256Hash(originalStorageLocation[:]).Bytes() - updatedStorageLocation = common.HexToHash("2") - updatedStorageKey = crypto.Keccak256Hash(updatedStorageLocation[:]).Bytes() - originalStorageValue = common.Hex2Bytes("01") - updatedStorageValue = common.Hex2Bytes("03") - - account1, _ = rlp.EncodeToBytes(state.Account{ + balanceChange10000 = int64(10000) + balanceChange1000 = int64(1000) + block1BankBalance = int64(99990000) + block1Account1Balance = int64(10000) + block2Account2Balance = int64(1000) + nonce0 = uint64(0) + nonce1 = uint64(1) + nonce2 = uint64(2) + nonce3 = uint64(3) + originalContractRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + contractContractRoot = "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0" + newContractRoot = "0x71e0d14b2b93e5c7f9748e69e1fe5f17498a1c3ac3cec29f96af13d7f8a4e070" + originalStorageLocation = common.HexToHash("0") + originalStorageKey = append(testhelpers.EvenLeafFlag, crypto.Keccak256Hash(originalStorageLocation[:]).Bytes()...) + updatedStorageLocation = common.HexToHash("2") + updatedStorageKey = append(testhelpers.EvenLeafFlag, crypto.Keccak256Hash(updatedStorageLocation[:]).Bytes()...) + originalStorageValue = common.Hex2Bytes("01") + originalStorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"), + originalStorageValue, + }) + updatedStorageValue = common.Hex2Bytes("03") + updatedStorageLeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("305787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"), + updatedStorageValue, + }) + account1AtBlock1, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce0, Balance: big.NewInt(balanceChange10000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - burnAccount1, _ = rlp.EncodeToBytes(state.Account{ + account1AtBlock1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock1, + }) + minerAccountAtBlock1, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce0, Balance: big.NewInt(miningReward), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - bankAccount1, _ = rlp.EncodeToBytes(state.Account{ + minerAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccountAtBlock1, + }) + bankAccountAtBlock1, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce1, Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - balanceChange10000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - account2, _ = rlp.EncodeToBytes(state.Account{ + bankAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock1, + }) + account2AtBlock2, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce0, Balance: big.NewInt(balanceChange1000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - contractAccount, _ = rlp.EncodeToBytes(state.Account{ + account2AtBlock2LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock2, + }) + contractAccountAtBlock2, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce1, Balance: big.NewInt(0), CodeHash: common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea").Bytes(), Root: common.HexToHash(contractContractRoot), }) - bankAccount2, _ = rlp.EncodeToBytes(state.Account{ + contractAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock2, + }) + bankAccountAtBlock2, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce2, Balance: big.NewInt(block1BankBalance - balanceChange1000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - account3, _ = rlp.EncodeToBytes(state.Account{ + bankAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock2, + }) + account1AtBlock2, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce2, Balance: big.NewInt(block1Account1Balance - balanceChange1000 + balanceChange1000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - burnAccount2, _ = rlp.EncodeToBytes(state.Account{ + account1AtBlock2LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock2, + }) + minerAccountAtBlock2, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce0, Balance: big.NewInt(miningReward + miningReward), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - account4, _ = rlp.EncodeToBytes(state.Account{ + minerAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccountAtBlock2, + }) + account2AtBlock3, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce0, Balance: big.NewInt(block2Account2Balance + miningReward), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) - contractAccount2, _ = rlp.EncodeToBytes(state.Account{ + account2AtBlock3LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock3, + }) + contractAccountAtBlock3, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce1, Balance: big.NewInt(0), CodeHash: common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea").Bytes(), Root: common.HexToHash(newContractRoot), }) - bankAccount3, _ = rlp.EncodeToBytes(state.Account{ + contractAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock3, + }) + bankAccountAtBlock3, _ = rlp.EncodeToBytes(state.Account{ Nonce: nonce3, Balance: big.NewInt(99989000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash(originalContractRoot), }) + bankAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock3, + }) ) type arguments struct { @@ -137,17 +189,17 @@ type arguments struct { func TestBuilder(t *testing.T) { blockHashes, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis) - contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) + contractLeafKey = testhelpers.AddressToEncodedPath(testhelpers.ContractAddr) defer chain.Stop() block0 = blockMap[blockHashes[3]] block1 = blockMap[blockHashes[2]] block2 = blockMap[blockHashes[1]] block3 = blockMap[blockHashes[0]] config := statediff.Config{ - PathsAndProofs: true, + LeafProofs: true, IntermediateNodes: false, } - builder = statediff.NewBuilder(testhelpers.Testdb, chain, config) + builder = statediff.NewBuilder(chain, config) var tests = []struct { name string @@ -185,33 +237,30 @@ func TestBuilder(t *testing.T) { BlockHash: block1.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: burnLeafKey.Bytes(), - Value: burnAccount1, + NodeType: statediff.Leaf, + EncodedPath: minerLeafKey, + NodeValue: minerAccountAtBlock1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.BankLeafKey.Bytes(), - Value: bankAccount1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.BankLeafKey, + NodeValue: bankAccountAtBlock1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 1, 132, 5, 245, 185, 240, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -219,8 +268,9 @@ func TestBuilder(t *testing.T) { }, { "testBlock2", - //1000 transferred from testBankAddress to account1Addr - //1000 transferred from account1Addr to account2Addr + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract arguments{ oldStateRoot: block1.Root(), newStateRoot: block2.Root(), @@ -232,59 +282,53 @@ func TestBuilder(t *testing.T) { BlockHash: block2.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: contractLeafKey.Bytes(), - Value: contractAccount, + NodeType: statediff.Leaf, + EncodedPath: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 130, 30, 37, 86, 162, 144, 200, 100, 5, 248, 22, 10, 45, 102, 32, 66, 164, 49, 186, 69, 107, 157, 178, 101, 199, 155, 184, 55, 192, 75, 229, 240, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}}, - Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16}, Storage: []statediff.StorageDiff{ { - Leaf: true, - Key: originalStorageKey, - Value: originalStorageValue, - Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}}, - Path: []byte{2, 9, 0, 13, 14, 12, 13, 9, 5, 4, 8, 11, 6, 2, 10, 8, 13, 6, 0, 3, 4, 5, 10, 9, 8, 8, 3, 8, 6, 15, 12, 8, 4, 11, 10, 6, 11, 12, 9, 5, 4, 8, 4, 0, 0, 8, 15, 6, 3, 6, 2, 15, 9, 3, 1, 6, 0, 14, 15, 3, 14, 5, 6, 3, 16}, + NodeType: statediff.Leaf, + EncodedPath: originalStorageKey, + NodeValue: originalStorageLeafNode, + Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}}, }, }, }, { - Leaf: true, - Key: testhelpers.Account2LeafKey.Bytes(), - Value: account2, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account2LeafKey, + NodeValue: account2AtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 107, 160, 57, 87, 243, 226, 240, 74, 7, 100, 195, 160, 73, 27, 23, 95, 105, 146, 109, 166, 30, 251, 204, 143, 97, 250, 20, 85, 253, 45, 43, 76, 221, 69, 184, 72, 248, 70, 128, 130, 3, 232, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{12, 9, 5, 7, 15, 3, 14, 2, 15, 0, 4, 10, 0, 7, 6, 4, 12, 3, 10, 0, 4, 9, 1, 11, 1, 7, 5, 15, 6, 9, 9, 2, 6, 13, 10, 6, 1, 14, 15, 11, 12, 12, 8, 15, 6, 1, 15, 10, 1, 4, 5, 5, 15, 13, 2, 13, 2, 11, 4, 12, 13, 13, 4, 5, 16}, Storage: []statediff.StorageDiff{}, }, }, DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.BankLeafKey.Bytes(), - Value: bankAccount2, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.BankLeafKey, + NodeValue: bankAccountAtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 2, 132, 5, 245, 182, 8, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: burnLeafKey.Bytes(), - Value: burnAccount2, + NodeType: statediff.Leaf, + EncodedPath: minerLeafKey, + NodeValue: minerAccountAtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 55, 130, 218, 206, 157, 144, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account3, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 2, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -307,39 +351,35 @@ func TestBuilder(t *testing.T) { DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.BankLeafKey.Bytes(), - Value: bankAccount3, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.BankLeafKey, + NodeValue: bankAccountAtBlock3LeafNode, Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 3, 132, 5, 245, 182, 8, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: contractLeafKey.Bytes(), - Value: contractAccount2, + NodeType: statediff.Leaf, + EncodedPath: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 113, 224, 209, 75, 43, 147, 229, 199, 249, 116, 142, 105, 225, 254, 95, 23, 73, 138, 28, 58, 195, 206, 194, 159, 150, 175, 19, 215, 248, 164, 224, 112, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}}, - Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16}, Storage: []statediff.StorageDiff{ { - Leaf: true, - Key: updatedStorageKey, - Value: updatedStorageValue, + NodeType: statediff.Leaf, + EncodedPath: updatedStorageKey, + NodeValue: updatedStorageLeafNode, Proof: [][]byte{{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 160, 205, 69, 114, 89, 105, 97, 21, 35, 94, 100, 199, 130, 35, 52, 214, 33, 41, 226, 241, 96, 68, 37, 167, 218, 100, 148, 243, 95, 196, 91, 229, 24, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {226, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 3}}, - Path: []byte{4, 0, 5, 7, 8, 7, 15, 10, 1, 2, 10, 8, 2, 3, 14, 0, 15, 2, 11, 7, 6, 3, 1, 12, 12, 4, 1, 11, 3, 11, 10, 8, 8, 2, 8, 11, 3, 3, 2, 1, 12, 10, 8, 1, 1, 1, 1, 1, 15, 10, 7, 5, 12, 13, 3, 10, 10, 3, 11, 11, 5, 10, 12, 14, 16}, }, }, }, { - Leaf: true, - Key: testhelpers.Account2LeafKey.Bytes(), - Value: account4, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account2LeafKey, + NodeValue: account2AtBlock3LeafNode, Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 113, 160, 57, 87, 243, 226, 240, 74, 7, 100, 195, 160, 73, 27, 23, 95, 105, 146, 109, 166, 30, 251, 204, 143, 97, 250, 20, 85, 253, 45, 43, 76, 221, 69, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 3, 232, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{12, 9, 5, 7, 15, 3, 14, 2, 15, 0, 4, 10, 0, 7, 6, 4, 12, 3, 10, 0, 4, 9, 1, 11, 1, 7, 5, 15, 6, 9, 9, 2, 6, 13, 10, 6, 1, 14, 15, 11, 12, 12, 8, 15, 6, 1, 15, 10, 1, 4, 5, 5, 15, 13, 2, 13, 2, 11, 4, 12, 13, 13, 4, 5, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -372,18 +412,18 @@ func TestBuilder(t *testing.T) { func TestBuilderWithWatchedAddressList(t *testing.T) { blockHashes, blockMap, chain := testhelpers.MakeChain(3, testhelpers.Genesis) - contractLeafKey = testhelpers.AddressToLeafKey(testhelpers.ContractAddr) + contractLeafKey = testhelpers.AddressToEncodedPath(testhelpers.ContractAddr) defer chain.Stop() block0 = blockMap[blockHashes[3]] block1 = blockMap[blockHashes[2]] block2 = blockMap[blockHashes[1]] block3 = blockMap[blockHashes[0]] config := statediff.Config{ - PathsAndProofs: true, + LeafProofs: true, IntermediateNodes: false, WatchedAddresses: []string{testhelpers.Account1Addr.Hex(), testhelpers.ContractAddr.Hex()}, } - builder = statediff.NewBuilder(testhelpers.Testdb, chain, config) + builder = statediff.NewBuilder(chain, config) var tests = []struct { name string @@ -420,12 +460,11 @@ func TestBuilderWithWatchedAddressList(t *testing.T) { BlockHash: block1.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -448,19 +487,17 @@ func TestBuilderWithWatchedAddressList(t *testing.T) { BlockHash: block2.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: contractLeafKey.Bytes(), - Value: contractAccount, + NodeType: statediff.Leaf, + EncodedPath: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 130, 30, 37, 86, 162, 144, 200, 100, 5, 248, 22, 10, 45, 102, 32, 66, 164, 49, 186, 69, 107, 157, 178, 101, 199, 155, 184, 55, 192, 75, 229, 240, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}}, - Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16}, Storage: []statediff.StorageDiff{ { - Leaf: true, - Key: originalStorageKey, - Value: originalStorageValue, - Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}}, - Path: []byte{2, 9, 0, 13, 14, 12, 13, 9, 5, 4, 8, 11, 6, 2, 10, 8, 13, 6, 0, 3, 4, 5, 10, 9, 8, 8, 3, 8, 6, 15, 12, 8, 4, 11, 10, 6, 11, 12, 9, 5, 4, 8, 4, 0, 0, 8, 15, 6, 3, 6, 2, 15, 9, 3, 1, 6, 0, 14, 15, 3, 14, 5, 6, 3, 16}, + NodeType: statediff.Leaf, + EncodedPath: originalStorageKey, + NodeValue: originalStorageLeafNode, + Proof: [][]byte{{227, 161, 32, 41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1}}, }, }, }, @@ -468,12 +505,11 @@ func TestBuilderWithWatchedAddressList(t *testing.T) { DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account3, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, Proof: [][]byte{{248, 177, 160, 177, 155, 238, 178, 242, 47, 83, 2, 49, 141, 155, 92, 149, 175, 245, 120, 233, 177, 101, 67, 46, 200, 23, 250, 41, 74, 135, 94, 61, 133, 51, 162, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 114, 57, 32, 11, 115, 232, 140, 238, 165, 222, 121, 226, 208, 2, 192, 216, 67, 198, 179, 31, 181, 27, 208, 243, 99, 202, 48, 148, 207, 107, 106, 177, 128, 128, 128, 128, 128, 160, 10, 173, 165, 125, 110, 240, 77, 112, 149, 100, 135, 237, 25, 228, 116, 7, 195, 9, 210, 166, 208, 148, 101, 23, 244, 238, 84, 84, 211, 249, 138, 137, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 2, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -496,20 +532,18 @@ func TestBuilderWithWatchedAddressList(t *testing.T) { DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: contractLeafKey.Bytes(), - Value: contractAccount2, + NodeType: statediff.Leaf, + EncodedPath: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, Proof: [][]byte{{248, 177, 160, 101, 223, 138, 81, 34, 40, 229, 170, 198, 188, 136, 99, 7, 55, 33, 112, 160, 111, 181, 131, 167, 201, 131, 24, 201, 211, 177, 30, 159, 229, 246, 6, 128, 128, 128, 128, 160, 179, 86, 53, 29, 96, 188, 152, 148, 207, 31, 29, 108, 182, 140, 129, 95, 1, 49, 213, 15, 29, 168, 60, 64, 35, 160, 158, 200, 85, 207, 255, 145, 160, 32, 135, 108, 213, 150, 150, 110, 44, 170, 65, 75, 154, 74, 249, 94, 65, 74, 107, 100, 115, 39, 5, 3, 26, 22, 238, 138, 114, 254, 21, 6, 171, 128, 128, 128, 128, 128, 160, 4, 228, 121, 222, 255, 218, 60, 247, 15, 0, 34, 198, 28, 229, 180, 129, 109, 157, 68, 181, 248, 229, 200, 123, 29, 81, 145, 114, 90, 209, 205, 210, 128, 160, 255, 115, 147, 190, 57, 135, 174, 188, 86, 51, 227, 70, 22, 253, 237, 49, 24, 19, 149, 199, 142, 195, 186, 244, 70, 51, 138, 0, 146, 148, 117, 60, 128, 128}, {248, 105, 160, 49, 20, 101, 138, 116, 217, 204, 159, 122, 207, 44, 92, 214, 150, 195, 73, 77, 124, 52, 77, 120, 191, 236, 58, 221, 13, 145, 236, 78, 141, 28, 69, 184, 70, 248, 68, 1, 128, 160, 113, 224, 209, 75, 43, 147, 229, 199, 249, 116, 142, 105, 225, 254, 95, 23, 73, 138, 28, 58, 195, 206, 194, 159, 150, 175, 19, 215, 248, 164, 224, 112, 160, 117, 63, 152, 168, 212, 50, 139, 21, 99, 110, 70, 246, 111, 44, 180, 188, 134, 1, 0, 170, 23, 150, 124, 193, 69, 252, 209, 125, 29, 71, 16, 234}}, - Path: []byte{6, 1, 1, 4, 6, 5, 8, 10, 7, 4, 13, 9, 12, 12, 9, 15, 7, 10, 12, 15, 2, 12, 5, 12, 13, 6, 9, 6, 12, 3, 4, 9, 4, 13, 7, 12, 3, 4, 4, 13, 7, 8, 11, 15, 14, 12, 3, 10, 13, 13, 0, 13, 9, 1, 14, 12, 4, 14, 8, 13, 1, 12, 4, 5, 16}, Storage: []statediff.StorageDiff{ { - Leaf: true, - Key: updatedStorageKey, - Value: updatedStorageValue, + NodeType: statediff.Leaf, + EncodedPath: updatedStorageKey, + NodeValue: updatedStorageLeafNode, Proof: [][]byte{{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 160, 205, 69, 114, 89, 105, 97, 21, 35, 94, 100, 199, 130, 35, 52, 214, 33, 41, 226, 241, 96, 68, 37, 167, 218, 100, 148, 243, 95, 196, 91, 229, 24, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, {226, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 3}}, - Path: []byte{4, 0, 5, 7, 8, 7, 15, 10, 1, 2, 10, 8, 2, 3, 14, 0, 15, 2, 11, 7, 6, 3, 1, 12, 12, 4, 1, 11, 3, 11, 10, 8, 8, 2, 8, 11, 3, 3, 2, 1, 12, 10, 8, 1, 1, 1, 1, 1, 15, 10, 7, 5, 12, 13, 3, 10, 10, 3, 11, 11, 5, 10, 12, 14, 16}, }, }, }, diff --git a/statediff/config.go b/statediff/config.go index 70f09a749824..39625391f129 100644 --- a/statediff/config.go +++ b/statediff/config.go @@ -18,7 +18,6 @@ package statediff // Config is used to carry in parameters from CLI configuration type Config struct { - PathsAndProofs bool IntermediateNodes bool StreamBlock bool WatchedAddresses []string diff --git a/statediff/doc.go b/statediff/doc.go index 35c48c02d58c..184bc242ccc0 100644 --- a/statediff/doc.go +++ b/statediff/doc.go @@ -24,7 +24,6 @@ The service is spun up using the below CLI flags --statediff: boolean flag, turns on the service --statediff.streamblock: boolean flag, configures the service to associate and stream out the rest of the block data with the state diffs. --statediff.intermediatenodes: boolean flag, tells service to include intermediate (branch and extension) nodes; default (false) processes leaf nodes only. ---statediff.pathsandproofs: boolean flag, tells service to generate paths and proofs for the diffed storage and state trie leaf nodes. --statediff.watchedaddresses: string slice flag, used to limit the state diffing process to the given addresses. Usage: --statediff.watchedaddresses=addr1 --statediff.watchedaddresses=addr2 --statediff.watchedaddresses=addr3 If you wish to use the websocket endpoint to subscribe to the statediff service, be sure to open up the Websocket RPC server with the `--ws` flag. The IPC-RPC server is turned on by default. diff --git a/statediff/helpers.go b/statediff/helpers.go index 2c5ddeb45f49..8ecb7be49980 100644 --- a/statediff/helpers.go +++ b/statediff/helpers.go @@ -20,6 +20,7 @@ package statediff import ( + "fmt" "sort" "strings" @@ -99,3 +100,25 @@ func pathToStr(it trie.NodeIterator) string { func hasTerm(s []byte) bool { return len(s) > 0 && s[len(s)-1] == 16 } + +// CheckKeyType checks what type of key we have +func CheckKeyType(elements []interface{}) (NodeType, error) { + if len(elements) > 2 { + return Branch, nil + } + if len(elements) < 2 { + return Unknown, nil + } + switch elements[0].([]byte)[0] / 16 { + case '\x00': + return Extension, nil + case '\x01': + return Extension, nil + case '\x02': + return Leaf, nil + case '\x03': + return Leaf, nil + default: + return Unknown, fmt.Errorf("unknown hex prefix") + } +} diff --git a/statediff/service.go b/statediff/service.go index 7e8aa52389d2..651f92cfc697 100644 --- a/statediff/service.go +++ b/statediff/service.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" @@ -81,11 +80,11 @@ type Service struct { } // NewStateDiffService creates a new statediff.Service -func NewStateDiffService(db ethdb.Database, blockChain *core.BlockChain, config Config) (*Service, error) { +func NewStateDiffService(blockChain *core.BlockChain, config Config) (*Service, error) { return &Service{ Mutex: sync.Mutex{}, BlockChain: blockChain, - Builder: NewBuilder(db, blockChain, config), + Builder: NewBuilder(blockChain, config), QuitChan: make(chan bool), Subscriptions: make(map[rpc.ID]Subscription), StreamBlock: config.StreamBlock, diff --git a/statediff/testhelpers/helpers.go b/statediff/testhelpers/helpers.go index ea41ec7bccb2..29d3046524f5 100644 --- a/statediff/testhelpers/helpers.go +++ b/statediff/testhelpers/helpers.go @@ -68,7 +68,7 @@ func testChainGen(i int, block *core.BlockGen) { block.AddTx(tx2) block.AddTx(tx3) case 2: - // Block 3 is empty but was mined by account #2. + // Block 3 has a single tx from the bankAccount to the contract, that transfers no value, that is mined by account2 block.SetCoinbase(Account2Addr) //get function: 60cd2685 //put function: c16431b9 diff --git a/statediff/testhelpers/mocks/api_test.go b/statediff/testhelpers/mocks/api_test.go index c95712fd644e..9d8f5dca1436 100644 --- a/statediff/testhelpers/mocks/api_test.go +++ b/statediff/testhelpers/mocks/api_test.go @@ -34,7 +34,7 @@ import ( var ( block0, block1 *types.Block - burnLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0")) + burnLeafKey = testhelpers.AddressToEncodedPath(common.HexToAddress("0x0")) emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0) account1, _ = rlp.EncodeToBytes(state.Account{ Nonce: uint64(0), @@ -42,18 +42,30 @@ var ( CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), }) + account1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1, + }) burnAccount1, _ = rlp.EncodeToBytes(state.Account{ Nonce: uint64(0), Balance: big.NewInt(2000000000000000000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), }) + burnAccount1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + burnAccount1, + }) bankAccount1, _ = rlp.EncodeToBytes(state.Account{ Nonce: uint64(1), Balance: big.NewInt(testhelpers.TestBankFunds.Int64() - 10000), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), }) + bankAccount1LeafNode, _ = rlp.EncodeToBytes([]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccount1, + }) mockTotalDifficulty = big.NewInt(1337) ) @@ -80,33 +92,30 @@ func testSubscriptionAPI(t *testing.T) { BlockHash: block1.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: burnLeafKey.Bytes(), - Value: burnAccount1, + NodeType: statediff.Leaf, + EncodedPath: burnLeafKey, + NodeValue: burnAccount1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.BankLeafKey.Bytes(), - Value: bankAccount1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.BankLeafKey, + NodeValue: bankAccount1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 1, 132, 5, 245, 185, 240, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, }, @@ -116,7 +125,7 @@ func testSubscriptionAPI(t *testing.T) { parentBlockChain := make(chan *types.Block) serviceQuitChan := make(chan bool) config := statediff.Config{ - PathsAndProofs: true, + LeafProofs: true, IntermediateNodes: false, } mockBlockChain := &BlockChain{} @@ -124,7 +133,7 @@ func testSubscriptionAPI(t *testing.T) { mockBlockChain.SetTdByHash(block1Hash, mockTotalDifficulty) mockService := MockStateDiffService{ Mutex: sync.Mutex{}, - Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config), + Builder: statediff.NewBuilder(chain, config), BlockChan: blockChan, BlockChain: mockBlockChain, ParentBlockChan: parentBlockChain, @@ -179,40 +188,37 @@ func testHTTPAPI(t *testing.T) { BlockHash: block1.Hash(), CreatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: burnLeafKey.Bytes(), - Value: burnAccount1, + NodeType: statediff.Leaf, + EncodedPath: burnLeafKey, + NodeValue: burnAccount1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 113, 160, 51, 128, 199, 183, 174, 129, 165, 142, 185, 141, 156, 120, 222, 74, 31, 215, 253, 149, 53, 252, 149, 62, 210, 190, 96, 45, 170, 164, 23, 103, 49, 42, 184, 78, 248, 76, 128, 136, 27, 193, 109, 103, 78, 200, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{5, 3, 8, 0, 12, 7, 11, 7, 10, 14, 8, 1, 10, 5, 8, 14, 11, 9, 8, 13, 9, 12, 7, 8, 13, 14, 4, 10, 1, 15, 13, 7, 15, 13, 9, 5, 3, 5, 15, 12, 9, 5, 3, 14, 13, 2, 11, 14, 6, 0, 2, 13, 10, 10, 10, 4, 1, 7, 6, 7, 3, 1, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, { - Leaf: true, - Key: testhelpers.Account1LeafKey.Bytes(), - Value: account1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.Account1LeafKey, + NodeValue: account1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 107, 160, 57, 38, 219, 105, 170, 206, 213, 24, 233, 185, 240, 244, 52, 164, 115, 231, 23, 65, 9, 201, 67, 84, 139, 184, 242, 59, 228, 28, 167, 109, 154, 210, 184, 72, 248, 70, 128, 130, 39, 16, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{14, 9, 2, 6, 13, 11, 6, 9, 10, 10, 12, 14, 13, 5, 1, 8, 14, 9, 11, 9, 15, 0, 15, 4, 3, 4, 10, 4, 7, 3, 14, 7, 1, 7, 4, 1, 0, 9, 12, 9, 4, 3, 5, 4, 8, 11, 11, 8, 15, 2, 3, 11, 14, 4, 1, 12, 10, 7, 6, 13, 9, 10, 13, 2, 16}, Storage: []statediff.StorageDiff{}, }, }, DeletedAccounts: emptyAccountDiffEventualMap, UpdatedAccounts: []statediff.AccountDiff{ { - Leaf: true, - Key: testhelpers.BankLeafKey.Bytes(), - Value: bankAccount1, + NodeType: statediff.Leaf, + EncodedPath: testhelpers.BankLeafKey, + NodeValue: bankAccount1LeafNode, Proof: [][]byte{{248, 113, 160, 87, 118, 82, 182, 37, 183, 123, 219, 91, 247, 123, 196, 63, 49, 37, 202, 215, 70, 77, 103, 157, 21, 117, 86, 82, 119, 211, 97, 27, 128, 83, 231, 128, 128, 128, 128, 160, 254, 136, 159, 16, 229, 219, 143, 44, 43, 243, 85, 146, 129, 82, 161, 127, 110, 59, 185, 154, 146, 65, 172, 109, 132, 199, 126, 98, 100, 80, 156, 121, 128, 128, 128, 128, 128, 128, 128, 128, 160, 17, 219, 12, 218, 52, 168, 150, 218, 190, 182, 131, 155, 176, 106, 56, 244, 149, 20, 207, 164, 134, 67, 89, 132, 235, 1, 59, 125, 249, 238, 133, 197, 128, 128}, {248, 109, 160, 48, 191, 73, 244, 64, 161, 205, 5, 39, 228, 208, 110, 39, 101, 101, 76, 15, 86, 69, 34, 87, 81, 109, 121, 58, 155, 141, 96, 77, 207, 223, 42, 184, 74, 248, 72, 1, 132, 5, 245, 185, 240, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112}}, - Path: []byte{0, 0, 11, 15, 4, 9, 15, 4, 4, 0, 10, 1, 12, 13, 0, 5, 2, 7, 14, 4, 13, 0, 6, 14, 2, 7, 6, 5, 6, 5, 4, 12, 0, 15, 5, 6, 4, 5, 2, 2, 5, 7, 5, 1, 6, 13, 7, 9, 3, 10, 9, 11, 8, 13, 6, 0, 4, 13, 12, 15, 13, 15, 2, 10, 16}, Storage: []statediff.StorageDiff{}, }, }, } expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff) config := statediff.Config{ - PathsAndProofs: true, + LeafProofs: true, IntermediateNodes: false, } mockBlockChain := &BlockChain{} @@ -222,7 +228,7 @@ func testHTTPAPI(t *testing.T) { mockBlockChain.SetTdByHash(block1Hash, big.NewInt(1337)) mockService := MockStateDiffService{ Mutex: sync.Mutex{}, - Builder: statediff.NewBuilder(testhelpers.Testdb, chain, config), + Builder: statediff.NewBuilder(chain, config), BlockChain: mockBlockChain, streamBlock: true, } diff --git a/statediff/testhelpers/test_data.go b/statediff/testhelpers/test_data.go index 604bd23b74eb..7368f542a693 100644 --- a/statediff/testhelpers/test_data.go +++ b/statediff/testhelpers/test_data.go @@ -27,12 +27,20 @@ import ( ) // AddressToLeafKey hashes an returns an address -func AddressToLeafKey(address common.Address) common.Hash { - return common.BytesToHash(crypto.Keccak256(address[:])) +func AddressToLeafKey(address common.Address) []byte { + return crypto.Keccak256(address[:]) +} + +// AddressToEncodedPath hashes an address and appends the even-number leaf flag to it +func AddressToEncodedPath(address common.Address) []byte { + addrHash := crypto.Keccak256(address[:]) + decodedPath := append(EvenLeafFlag, addrHash...) + return decodedPath } // Test variables var ( + EvenLeafFlag = []byte{byte(2) << 4} BlockNumber = big.NewInt(rand.Int63()) BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73" CodeHash = common.Hex2Bytes("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") @@ -43,7 +51,7 @@ var ( Testdb = rawdb.NewMemoryDatabase() TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7 - BankLeafKey = AddressToLeafKey(TestBankAddress) + BankLeafKey = AddressToEncodedPath(TestBankAddress) TestBankFunds = big.NewInt(100000000) Genesis = core.GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds) @@ -51,8 +59,8 @@ var ( Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7 Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e - Account1LeafKey = AddressToLeafKey(Account1Addr) - Account2LeafKey = AddressToLeafKey(Account2Addr) + Account1LeafKey = AddressToEncodedPath(Account1Addr) + Account2LeafKey = AddressToEncodedPath(Account2Addr) ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50602060405190810160405280600160ff16815250600090600161003592919061003b565b506100a5565b826064810192821561006f579160200282015b8281111561006e578251829060ff1690559160200191906001019061004e565b5b50905061007c9190610080565b5090565b6100a291905b8082111561009e576000816000905550600101610086565b5090565b90565b610124806100b46000396000f3fe6080604052348015600f57600080fd5b5060043610604f576000357c01000000000000000000000000000000000000000000000000000000009004806360cd2685146054578063c16431b9146093575b600080fd5b607d60048036036020811015606857600080fd5b810190808035906020019092919050505060c8565b6040518082815260200191505060405180910390f35b60c66004803603604081101560a757600080fd5b81019080803590602001909291908035906020019092919050505060e0565b005b6000808260648110151560d757fe5b01549050919050565b8060008360648110151560ef57fe5b0181905550505056fea165627a7a7230582064e918c3140a117bf3aa65865a9b9e83fae21ad1720506e7933b2a9f54bb40260029") ContractAddr common.Address ) diff --git a/statediff/types.go b/statediff/types.go index b527221b64ef..4ca73daba0a7 100644 --- a/statediff/types.go +++ b/statediff/types.go @@ -77,21 +77,19 @@ type StateDiff struct { // AccountDiff holds the data for a single state diff node type AccountDiff struct { - Leaf bool `json:"leaf" gencodec:"required"` - Key []byte `json:"key" gencodec:"required"` - Value []byte `json:"value" gencodec:"required"` - Proof [][]byte `json:"proof" gencodec:"required"` - Path []byte `json:"path" gencodec:"required"` - Storage []StorageDiff `json:"storage" gencodec:"required"` + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + Storage []StorageDiff `json:"storage"` + LeafKey []byte `json:"leafKey"` } // StorageDiff holds the data for a single storage diff node type StorageDiff struct { - Leaf bool `json:"leaf" gencodec:"required"` - Key []byte `json:"key" gencodec:"required"` - Value []byte `json:"value" gencodec:"required"` - Proof [][]byte `json:"proof" gencodec:"required"` - Path []byte `json:"path" gencodec:"required"` + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + LeafKey []byte `json:"leafKey"` } // AccountsMap is a mapping of keccak256(address) => accountWrapper @@ -99,10 +97,19 @@ type AccountsMap map[common.Hash]accountWrapper // AccountWrapper is used to temporary associate the unpacked account with its raw values type accountWrapper struct { - Account *state.Account - Leaf bool - RawKey []byte - RawValue []byte - Proof [][]byte - Path []byte + Account *state.Account + NodeType NodeType + Path []byte + NodeValue []byte + LeafKey []byte } + +// NodeType for explicitly setting type of node +type NodeType string + +const ( + Unknown NodeType = "Unknown" + Leaf NodeType = "Leaf" + Extension NodeType = "Extension" + Branch NodeType = "Branch" +) diff --git a/trie/encoding.go b/trie/encoding.go index 425326db8fca..49c42a3a4a4a 100644 --- a/trie/encoding.go +++ b/trie/encoding.go @@ -34,6 +34,11 @@ package trie // in the case of an odd number. All remaining nibbles (now an even number) fit properly // into the remaining bytes. Compact encoding is used for nodes stored on disk. +// HexToCompact converts a hex path to the compact encoded format +func HexToCompact(hex []byte) []byte { + return hexToCompact(hex) +} + func hexToCompact(hex []byte) []byte { terminator := byte(0) if hasTerm(hex) { @@ -51,6 +56,11 @@ func hexToCompact(hex []byte) []byte { return buf } +// CompactToHex converts a compact encoded path to hex format +func CompactToHex(compact []byte) []byte { + return compactToHex(compact) +} + func compactToHex(compact []byte) []byte { if len(compact) == 0 { return compact