diff type for representing deleted accounts

This commit is contained in:
Ian Norden 2020-05-10 15:44:21 -05:00
parent 5c3e0d6437
commit b7c412d303
6 changed files with 414 additions and 395 deletions

View File

@ -89,21 +89,21 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
if err != nil { if err != nil {
return StateDiff{}, fmt.Errorf("error building diff for updated accounts: %v", err) return StateDiff{}, fmt.Errorf("error building diff for updated accounts: %v", err)
} }
createdAccounts, err := sdb.buildDiffEventual(creations) createdAccounts, err := sdb.buildDiffCreations(creations)
if err != nil { if err != nil {
return StateDiff{}, fmt.Errorf("error building diff for created accounts: %v", err) return StateDiff{}, fmt.Errorf("error building diff for created accounts: %v", err)
} }
deletedAccounts, err := sdb.buildDiffEventual(deletions) deletedAccounts, err := sdb.buildDiffDeletions(deletions)
if err != nil { if err != nil {
return StateDiff{}, fmt.Errorf("error building diff for deleted accounts: %v", err) return StateDiff{}, fmt.Errorf("error building diff for deleted accounts: %v", err)
} }
return StateDiff{ return StateDiff{
BlockNumber: blockNumber, BlockNumber: blockNumber,
BlockHash: blockHash, BlockHash: blockHash,
CreatedAccounts: createdAccounts, CreatedNodes: createdAccounts,
DeletedAccounts: deletedAccounts, DeletedNodes: deletedAccounts,
UpdatedAccounts: updatedAccounts, UpdatedNodes: updatedAccounts,
}, nil }, nil
} }
@ -184,52 +184,66 @@ func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error
return diffAccounts, nil return diffAccounts, nil
} }
func (sdb *builder) buildDiffEventual(accounts AccountsMap) ([]AccountDiff, error) { func (sdb *builder) buildDiffCreations(accounts AccountsMap) ([]StateNode, error) {
accountDiffs := make([]AccountDiff, 0) accountDiffs := make([]StateNode, 0, len(accounts))
var err error var err error
for _, val := range accounts { for _, val := range accounts {
// If account is not nil, we need to process storage diffs // If account is not nil, we need to process storage diffs
var storageDiffs []StorageDiff var storageDiffs []StorageNode
if val.Account != nil { if val.Account != nil {
storageDiffs, err = sdb.buildStorageDiffsEventual(val.Account.Root) storageDiffs, err = sdb.buildStorageNodesEventual(val.Account.Root)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err) return nil, fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err)
} }
} }
accountDiffs = append(accountDiffs, AccountDiff{ accountDiffs = append(accountDiffs, StateNode{
NodeType: val.NodeType, NodeType: val.NodeType,
Path: val.Path, Path: val.Path,
LeafKey: val.LeafKey, LeafKey: val.LeafKey,
NodeValue: val.NodeValue, NodeValue: val.NodeValue,
Storage: storageDiffs, StorageDiffs: storageDiffs,
}) })
} }
return accountDiffs, nil return accountDiffs, nil
} }
func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) ([]AccountDiff, error) { func (sdb *builder) buildDiffDeletions(accounts AccountsMap) ([]StateNode, error) {
updatedAccounts := make([]AccountDiff, 0) accountDiffs := make([]StateNode, 0, len(accounts))
for _, val := range accounts {
// deleted account can not have storage or it would not be deleted
accountDiffs = append(accountDiffs, StateNode{
NodeType: Removed,
Path: val.Path,
LeafKey: val.LeafKey,
NodeValue: []byte{},
})
}
return accountDiffs, nil
}
func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) ([]StateNode, error) {
updatedAccounts := make([]StateNode, 0, len(updatedKeys))
var err error var err error
for _, val := range updatedKeys { for _, val := range updatedKeys {
hashKey := common.HexToHash(val) hashKey := common.HexToHash(val)
createdAcc := creations[hashKey] createdAcc := creations[hashKey]
deletedAcc := deletions[hashKey] deletedAcc := deletions[hashKey]
var storageDiffs []StorageDiff var storageDiffs []StorageNode
if deletedAcc.Account != nil && createdAcc.Account != nil { if deletedAcc.Account != nil && createdAcc.Account != nil {
oldSR := deletedAcc.Account.Root oldSR := deletedAcc.Account.Root
newSR := createdAcc.Account.Root newSR := createdAcc.Account.Root
storageDiffs, err = sdb.buildStorageDiffsIncremental(oldSR, newSR) storageDiffs, err = sdb.buildStorageNodesIncremental(oldSR, newSR)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed building incremental storage diffs for %s\r\nerror: %v", hashKey.Hex(), err) return nil, fmt.Errorf("failed building incremental storage diffs for %s\r\nerror: %v", hashKey.Hex(), err)
} }
} }
updatedAccounts = append(updatedAccounts, AccountDiff{ updatedAccounts = append(updatedAccounts, StateNode{
NodeType: createdAcc.NodeType, NodeType: createdAcc.NodeType,
Path: createdAcc.Path, Path: createdAcc.Path,
NodeValue: createdAcc.NodeValue, NodeValue: createdAcc.NodeValue,
LeafKey: createdAcc.LeafKey, LeafKey: createdAcc.LeafKey,
Storage: storageDiffs, StorageDiffs: storageDiffs,
}) })
delete(creations, common.HexToHash(val)) delete(creations, common.HexToHash(val))
delete(deletions, common.HexToHash(val)) delete(deletions, common.HexToHash(val))
@ -238,7 +252,10 @@ func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions Accoun
return updatedAccounts, nil return updatedAccounts, nil
} }
func (sdb *builder) buildStorageDiffsEventual(sr common.Hash) ([]StorageDiff, error) { // if an account is moved to a new path that didn't previously have a node, it appears to have been "created"
// but it actually has a previous state associated with, a previous storage trie, so this would produce the
// wrong result... it would produce a node for the entire trie, not just the diffs since the last state
func (sdb *builder) buildStorageNodesEventual(sr common.Hash) ([]StorageNode, error) {
log.Debug("Storage Root For Eventual Diff", "root", sr.Hex()) log.Debug("Storage Root For Eventual Diff", "root", sr.Hex())
stateCache := sdb.blockChain.StateCache() stateCache := sdb.blockChain.StateCache()
sTrie, err := stateCache.OpenTrie(sr) sTrie, err := stateCache.OpenTrie(sr)
@ -247,10 +264,10 @@ func (sdb *builder) buildStorageDiffsEventual(sr common.Hash) ([]StorageDiff, er
return nil, err return nil, err
} }
it := sTrie.NodeIterator(make([]byte, 0)) it := sTrie.NodeIterator(make([]byte, 0))
return sdb.buildStorageDiffsFromTrie(it) return sdb.buildStorageNodesFromTrie(it)
} }
func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common.Hash) ([]StorageDiff, error) { func (sdb *builder) buildStorageNodesIncremental(oldSR common.Hash, newSR common.Hash) ([]StorageNode, error) {
log.Debug("Storage Roots for Incremental Diff", "old", oldSR.Hex(), "new", newSR.Hex()) log.Debug("Storage Roots for Incremental Diff", "old", oldSR.Hex(), "new", newSR.Hex())
stateCache := sdb.blockChain.StateCache() stateCache := sdb.blockChain.StateCache()
@ -266,11 +283,11 @@ func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common
oldIt := oldTrie.NodeIterator(make([]byte, 0)) oldIt := oldTrie.NodeIterator(make([]byte, 0))
newIt := newTrie.NodeIterator(make([]byte, 0)) newIt := newTrie.NodeIterator(make([]byte, 0))
it, _ := trie.NewDifferenceIterator(oldIt, newIt) it, _ := trie.NewDifferenceIterator(oldIt, newIt)
return sdb.buildStorageDiffsFromTrie(it) return sdb.buildStorageNodesFromTrie(it)
} }
func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDiff, error) { func (sdb *builder) buildStorageNodesFromTrie(it trie.NodeIterator) ([]StorageNode, error) {
storageDiffs := make([]StorageDiff, 0) storageDiffs := make([]StorageNode, 0)
for it.Next(true) { for it.Next(true) {
// skip value nodes // skip value nodes
if it.Leaf() { if it.Leaf() {
@ -299,7 +316,7 @@ func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDi
valueNodePath := append(nodePath, partialPath...) valueNodePath := append(nodePath, partialPath...)
encodedPath := trie.HexToCompact(valueNodePath) encodedPath := trie.HexToCompact(valueNodePath)
leafKey := encodedPath[1:] leafKey := encodedPath[1:]
sd := StorageDiff{ sd := StorageNode{
NodeType: ty, NodeType: ty,
Path: nodePath, Path: nodePath,
NodeValue: node, NodeValue: node,
@ -308,7 +325,7 @@ func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDi
storageDiffs = append(storageDiffs, sd) storageDiffs = append(storageDiffs, sd)
case Extension, Branch: case Extension, Branch:
if sdb.config.IntermediateNodes { if sdb.config.IntermediateNodes {
storageDiffs = append(storageDiffs, StorageDiff{ storageDiffs = append(storageDiffs, StorageNode{
NodeType: ty, NodeType: ty,
Path: nodePath, Path: nodePath,
NodeValue: node, NodeValue: node,

View File

@ -34,8 +34,8 @@ import (
// TODO: add test that filters on address // TODO: add test that filters on address
var ( var (
contractLeafKey []byte contractLeafKey []byte
emptyAccounts = make([]statediff.AccountDiff, 0) emptyAccounts = make([]statediff.StateNode, 0)
emptyStorage = make([]statediff.StorageDiff, 0) emptyStorage = make([]statediff.StorageNode, 0)
block0, block1, block2, block3 *types.Block block0, block1, block2, block3 *types.Block
builder statediff.Builder builder statediff.Builder
miningReward = int64(2000000000000000000) miningReward = int64(2000000000000000000)
@ -300,11 +300,11 @@ func TestBuilder(t *testing.T) {
blockHash: block0.Hash(), blockHash: block0.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts, CreatedNodes: emptyAccounts,
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -319,17 +319,17 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode, NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -344,39 +344,39 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock1LeafNode, NodeValue: bankAccountAtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock1LeafNode, NodeValue: minerAccountAtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock1LeafNode, NodeValue: account1AtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: []statediff.AccountDiff{ // This leaf appears to be deleted since it is turned into a branch node DeletedNodes: []statediff.StateNode{ // This leaf appears to be deleted since it is turned into a branch node and the account is moved to \x00
{ // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below) { // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below)
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode, NodeValue: []byte{},
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -393,13 +393,13 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block2.Number(), BlockNumber: block2.Number(),
BlockHash: block2.Hash(), BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode, NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
@ -409,35 +409,35 @@ func TestBuilder(t *testing.T) {
}, },
}, },
{ {
Path: []byte{'\x0c'}, Path: []byte{'\x0c'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey, LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock2LeafNode, NodeValue: account2AtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock2LeafNode, NodeValue: bankAccountAtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock2LeafNode, NodeValue: minerAccountAtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode, NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -453,24 +453,24 @@ func TestBuilder(t *testing.T) {
blockHash: block3.Hash(), blockHash: block3.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block3.Number(), BlockNumber: block3.Number(),
BlockHash: block3.Hash(), BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{}, CreatedNodes: []statediff.StateNode{},
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock3LeafNode, NodeValue: bankAccountAtBlock3LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode, NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{'\x02'}, Path: []byte{'\x02'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
@ -486,11 +486,11 @@ func TestBuilder(t *testing.T) {
}, },
}, },
{ {
Path: []byte{'\x0c'}, Path: []byte{'\x0c'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey, LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock3LeafNode, NodeValue: account2AtBlock3LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -547,11 +547,11 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
blockHash: block0.Hash(), blockHash: block0.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts, CreatedNodes: emptyAccounts,
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -566,17 +566,17 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode, NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -591,36 +591,36 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock1LeafNode, NodeValue: bankAccountAtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock1LeafNode, NodeValue: minerAccountAtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock1LeafNode, NodeValue: account1AtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
NodeValue: block1BranchNode, NodeValue: block1BranchNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -639,13 +639,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block2.Number(), BlockNumber: block2.Number(),
BlockHash: block2.Hash(), BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode, NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
@ -655,41 +655,41 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
}, },
}, },
{ {
Path: []byte{'\x0c'}, Path: []byte{'\x0c'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey, LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock2LeafNode, NodeValue: account2AtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
NodeValue: block2BranchNode, NodeValue: block2BranchNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock2LeafNode, NodeValue: bankAccountAtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock2LeafNode, NodeValue: minerAccountAtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode, NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -705,30 +705,30 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
blockHash: block3.Hash(), blockHash: block3.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block3.Number(), BlockNumber: block3.Number(),
BlockHash: block3.Hash(), BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{}, CreatedNodes: []statediff.StateNode{},
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
NodeValue: block3BranchNode, NodeValue: block3BranchNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock3LeafNode, NodeValue: bankAccountAtBlock3LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode, NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
@ -749,11 +749,11 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
}, },
}, },
{ {
Path: []byte{'\x0c'}, Path: []byte{'\x0c'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey, LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock3LeafNode, NodeValue: account2AtBlock3LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -811,11 +811,11 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
blockHash: block0.Hash(), blockHash: block0.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts, CreatedNodes: emptyAccounts,
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -828,11 +828,11 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
blockHash: block0.Hash(), blockHash: block0.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block0.Number(), BlockNumber: block0.Number(),
BlockHash: block0.Hash(), BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts, CreatedNodes: emptyAccounts,
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
}, },
}, },
{ {
@ -847,17 +847,17 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock1LeafNode, NodeValue: account1AtBlock1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{}, UpdatedNodes: []statediff.StateNode{},
}, },
}, },
{ {
@ -873,13 +873,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block2.Number(), BlockNumber: block2.Number(),
BlockHash: block2.Hash(), BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode, NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
@ -889,14 +889,14 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
}, },
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode, NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
}, },
@ -912,17 +912,17 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
blockHash: block3.Hash(), blockHash: block3.Hash(),
}, },
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block3.Number(), BlockNumber: block3.Number(),
BlockHash: block3.Hash(), BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{}, CreatedNodes: []statediff.StateNode{},
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: contractLeafKey, LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode, NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{ StorageDiffs: []statediff.StorageNode{
{ {
Path: []byte{'\x02'}, Path: []byte{'\x02'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,

View File

@ -26,7 +26,7 @@ import (
) )
func sortKeys(data AccountsMap) []string { func sortKeys(data AccountsMap) []string {
var keys []string keys := make([]string, 0, len(data))
for key := range data { for key := range data {
keys = append(keys, key.Hex()) keys = append(keys, key.Hex())
} }
@ -35,7 +35,8 @@ func sortKeys(data AccountsMap) []string {
return keys return keys
} }
// findIntersection finds the set of strings from both arrays that are equivalent (same key as same index) // findIntersection finds the set of strings from both arrays that are equivalent
// a and b must first be sorted
// this is used to find which keys have been both "deleted" and "created" i.e. they were updated // this is used to find which keys have been both "deleted" and "created" i.e. they were updated
func findIntersection(a, b []string) []string { func findIntersection(a, b []string) []string {
lenA := len(a) lenA := len(a)

View File

@ -47,8 +47,8 @@ var (
block1CoinbaseAddr, block2CoinbaseAddr, block3CoinbaseAddr common.Address block1CoinbaseAddr, block2CoinbaseAddr, block3CoinbaseAddr common.Address
block1CoinbaseHash, block2CoinbaseHash, block3CoinbaseHash common.Hash block1CoinbaseHash, block2CoinbaseHash, block3CoinbaseHash common.Hash
builder statediff.Builder builder statediff.Builder
emptyAccounts = make([]statediff.AccountDiff, 0) emptyAccounts = make([]statediff.StateNode, 0)
emptyStorage = make([]statediff.StorageDiff, 0) emptyStorage = make([]statediff.StorageNode, 0)
// block 1 data // block 1 data
block1CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{ block1CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{
@ -498,34 +498,34 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x04', '\x0b', '\x0e'}, Path: []byte{'\x04', '\x0b', '\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: block1CoinbaseHash.Bytes(), LeafKey: block1CoinbaseHash.Bytes(),
NodeValue: block1CoinbaseLeafNode, NodeValue: block1CoinbaseLeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block1RootBranchNode, NodeValue: block1RootBranchNode,
}, },
{ {
Path: []byte{'\x04'}, Path: []byte{'\x04'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block1x04BranchNode, NodeValue: block1x04BranchNode,
}, },
{ {
Path: []byte{'\x04', '\x0b'}, Path: []byte{'\x04', '\x0b'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block1x040bBranchNode, NodeValue: block1x040bBranchNode,
}, },
}, },
}, },
@ -544,50 +544,50 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block2.Number(), BlockNumber: block2.Number(),
BlockHash: block2.Hash(), BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
// this new leaf at x00 x08 x0d x00 was created when a premine account (leaf) was moved from path x00 x08 x0d // this new leaf at x00 x08 x0d x00 was "created" when a premine account (leaf) was moved from path x00 x08 x0d
// this occurred because of the creation of the new coinbase receiving account (leaf) at x00 x08 x0d x04 // this occurred because of the creation of the new coinbase receiving account (leaf) at x00 x08 x0d x04
// which necessitates we create a branch at x00 x08 x0d (as shown in the below UpdateAccounts) // which necessitates we create a branch at x00 x08 x0d (as shown in the below UpdateAccounts)
{ {
Path: []byte{'\x00', '\x08', '\x0d', '\x00'}, Path: []byte{'\x00', '\x08', '\x0d', '\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
Storage: emptyStorage, StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("08d0f2e24db7943eab4415f99e109698863b0fecca1cf9ffc500f38cefbbe29e").Bytes(), LeafKey: common.HexToHash("08d0f2e24db7943eab4415f99e109698863b0fecca1cf9ffc500f38cefbbe29e").Bytes(),
NodeValue: block2MovedPremineLeafNode, NodeValue: block2MovedPremineLeafNode,
}, },
{ {
Path: []byte{'\x00', '\x08', '\x0d', '\x04'}, Path: []byte{'\x00', '\x08', '\x0d', '\x04'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
Storage: emptyStorage, StorageDiffs: emptyStorage,
LeafKey: block2CoinbaseHash.Bytes(), LeafKey: block2CoinbaseHash.Bytes(),
NodeValue: block2CoinbaseLeafNode, NodeValue: block2CoinbaseLeafNode,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block2RootBranchNode, NodeValue: block2RootBranchNode,
}, },
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block2x00BranchNode, NodeValue: block2x00BranchNode,
}, },
{ {
Path: []byte{'\x00', '\x08'}, Path: []byte{'\x00', '\x08'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block2x0008BranchNode, NodeValue: block2x0008BranchNode,
}, },
{ {
Path: []byte{'\x00', '\x08', '\x0d'}, Path: []byte{'\x00', '\x08', '\x0d'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block2x00080dBranchNode, NodeValue: block2x00080dBranchNode,
}, },
}, },
}, },
@ -605,72 +605,72 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{ &statediff.StateDiff{
BlockNumber: block3.Number(), BlockNumber: block3.Number(),
BlockHash: block3.Hash(), BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ // How was this account created??? { // How was this account created???
Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x03'}, Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x03'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
Storage: emptyStorage, StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("ce573ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190").Bytes(), LeafKey: common.HexToHash("ce573ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190").Bytes(),
NodeValue: block3MovedPremineLeafNode1, NodeValue: block3MovedPremineLeafNode1,
}, },
{ // This account (leaf) used to be at 0c 0e 05 07, not sure why it moves... { // This account (leaf) used to be at 0c 0e 05 07, not sure why it moves...
Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x08'}, Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x08'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
Storage: emptyStorage, StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("ce5783bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012").Bytes(), LeafKey: common.HexToHash("ce5783bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012").Bytes(),
NodeValue: block3MovedPremineLeafNode2, NodeValue: block3MovedPremineLeafNode2,
}, },
{ // this is the new account created due to the coinbase mining a block, it's creation shouldn't affect 0x 0e 05 07 { // this is the new account created due to the coinbase mining a block, it's creation shouldn't affect 0x 0e 05 07
Path: []byte{'\x06', '\x0e', '\x0f'}, Path: []byte{'\x06', '\x0e', '\x0f'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
Storage: emptyStorage, StorageDiffs: emptyStorage,
LeafKey: block3CoinbaseHash.Bytes(), LeafKey: block3CoinbaseHash.Bytes(),
NodeValue: block3CoinbaseLeafNode, NodeValue: block3CoinbaseLeafNode,
}, },
}, },
DeletedAccounts: emptyAccounts, DeletedNodes: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{ UpdatedNodes: []statediff.StateNode{
{ {
Path: []byte{}, Path: []byte{},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3RootBranchNode, NodeValue: block3RootBranchNode,
}, },
{ {
Path: []byte{'\x06'}, Path: []byte{'\x06'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x06BranchNode, NodeValue: block3x06BranchNode,
}, },
{ {
Path: []byte{'\x06', '\x0e'}, Path: []byte{'\x06', '\x0e'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x060eBranchNode, NodeValue: block3x060eBranchNode,
}, },
{ {
Path: []byte{'\x0c'}, Path: []byte{'\x0c'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x0cBranchNode, NodeValue: block3x0cBranchNode,
}, },
{ {
Path: []byte{'\x0c', '\x0e'}, Path: []byte{'\x0c', '\x0e'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x0c0eBranchNode, NodeValue: block3x0c0eBranchNode,
}, },
{ {
Path: []byte{'\x0c', '\x0e', '\x05'}, Path: []byte{'\x0c', '\x0e', '\x05'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x0c0e05BranchNode, NodeValue: block3x0c0e05BranchNode,
}, },
{ {
Path: []byte{'\x0c', '\x0e', '\x05', '\x07'}, Path: []byte{'\x0c', '\x0e', '\x05', '\x07'},
NodeType: statediff.Branch, NodeType: statediff.Branch,
Storage: emptyStorage, StorageDiffs: emptyStorage,
NodeValue: block3x0c0e0507BranchNode, NodeValue: block3x0c0e0507BranchNode,
}, },
}, },
}, },

View File

@ -33,12 +33,12 @@ import (
) )
var ( var (
emptyStorage = make([]statediff.StorageDiff, 0) emptyStorage = make([]statediff.StorageNode, 0)
emptyAccounts = make([]statediff.AccountDiff, 0) emptyAccounts = make([]statediff.StateNode, 0)
block0, block1 *types.Block block0, block1 *types.Block
minerLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0")) minerLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0"))
emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0) emptyStateNodeEventualMap = make([]statediff.StateNode, 0)
account1, _ = rlp.EncodeToBytes(state.Account{ account1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0), Nonce: uint64(0),
Balance: big.NewInt(10000), Balance: big.NewInt(10000),
CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(),
@ -102,39 +102,39 @@ func testSubscriptionAPI(t *testing.T) {
expectedStateDiff := statediff.StateDiff{ expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountLeafNode, NodeValue: minerAccountLeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1LeafNode, NodeValue: account1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountLeafNode, NodeValue: bankAccountLeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: []statediff.AccountDiff{ // This leaf appears to be deleted since it is turned into a branch node DeletedNodes: []statediff.StateNode{ // This leaf appears to be deleted since it is turned into a branch node
{ // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below) { // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below)
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode, NodeValue: []byte{},
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
} }
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff) expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
blockChan := make(chan *types.Block) blockChan := make(chan *types.Block)
@ -201,39 +201,39 @@ func testHTTPAPI(t *testing.T) {
expectedStateDiff := statediff.StateDiff{ expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(), BlockNumber: block1.Number(),
BlockHash: block1.Hash(), BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{ CreatedNodes: []statediff.StateNode{
{ {
Path: []byte{'\x05'}, Path: []byte{'\x05'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: minerLeafKey, LeafKey: minerLeafKey,
NodeValue: minerAccountLeafNode, NodeValue: minerAccountLeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x0e'}, Path: []byte{'\x0e'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey, LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1LeafNode, NodeValue: account1LeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
{ {
Path: []byte{'\x00'}, Path: []byte{'\x00'},
NodeType: statediff.Leaf, NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountLeafNode, NodeValue: bankAccountLeafNode,
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
DeletedAccounts: []statediff.AccountDiff{ // This leaf appears to be deleted since it is turned into a branch node DeletedNodes: []statediff.StateNode{ // This leaf appears to be deleted since it is turned into a branch node
{ // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below) { // It would instead show up in the UpdateAccounts as new branch node IF intermediate node diffing was turned on (as it is in the test below)
Path: []byte{}, Path: []byte{},
NodeType: statediff.Leaf, NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey, LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode, NodeValue: []byte{},
Storage: emptyStorage, StorageDiffs: emptyStorage,
}, },
}, },
UpdatedAccounts: emptyAccounts, UpdatedNodes: emptyAccounts,
} }
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff) expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
config := statediff.Config{ config := statediff.Config{

View File

@ -65,27 +65,27 @@ func (sd *Payload) Encode() ([]byte, error) {
// StateDiff is the final output structure from the builder // StateDiff is the final output structure from the builder
type StateDiff struct { type StateDiff struct {
BlockNumber *big.Int `json:"blockNumber" gencodec:"required"` BlockNumber *big.Int `json:"blockNumber" gencodec:"required"`
BlockHash common.Hash `json:"blockHash" gencodec:"required"` BlockHash common.Hash `json:"blockHash" gencodec:"required"`
CreatedAccounts []AccountDiff `json:"createdAccounts" gencodec:"required"` CreatedNodes []StateNode `json:"createdAccounts" gencodec:"required"`
DeletedAccounts []AccountDiff `json:"deletedAccounts" gencodec:"required"` DeletedNodes []StateNode `json:"deletedAccounts" gencodec:"required"`
UpdatedAccounts []AccountDiff `json:"updatedAccounts" gencodec:"required"` UpdatedNodes []StateNode `json:"updatedAccounts" gencodec:"required"`
encoded []byte encoded []byte
err error err error
} }
// AccountDiff holds the data for a single state diff node // StateNode holds the data for a single state diff node
type AccountDiff struct { type StateNode struct {
NodeType NodeType `json:"nodeType" gencodec:"required"` NodeType NodeType `json:"nodeType" gencodec:"required"`
Path []byte `json:"path" gencodec:"required"` Path []byte `json:"path" gencodec:"required"`
NodeValue []byte `json:"value" gencodec:"required"` NodeValue []byte `json:"value" gencodec:"required"`
Storage []StorageDiff `json:"storage"` StorageDiffs []StorageNode `json:"storage"`
LeafKey []byte `json:"leafKey"` LeafKey []byte `json:"leafKey"`
} }
// StorageDiff holds the data for a single storage diff node // StorageNode holds the data for a single storage diff node
type StorageDiff struct { type StorageNode struct {
NodeType NodeType `json:"nodeType" gencodec:"required"` NodeType NodeType `json:"nodeType" gencodec:"required"`
Path []byte `json:"path" gencodec:"required"` Path []byte `json:"path" gencodec:"required"`
NodeValue []byte `json:"value" gencodec:"required"` NodeValue []byte `json:"value" gencodec:"required"`
@ -112,4 +112,5 @@ const (
Leaf NodeType = "Leaf" Leaf NodeType = "Leaf"
Extension NodeType = "Extension" Extension NodeType = "Extension"
Branch NodeType = "Branch" Branch NodeType = "Branch"
Removed NodeType = "Removed" // used to represent nodes which have been deleted (e.g. accounts due to EIp-158)
) )