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,11 +89,11 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
if err != nil {
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 {
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 {
return StateDiff{}, fmt.Errorf("error building diff for deleted accounts: %v", err)
}
@ -101,9 +101,9 @@ func (sdb *builder) BuildStateDiff(oldStateRoot, newStateRoot common.Hash, block
return StateDiff{
BlockNumber: blockNumber,
BlockHash: blockHash,
CreatedAccounts: createdAccounts,
DeletedAccounts: deletedAccounts,
UpdatedAccounts: updatedAccounts,
CreatedNodes: createdAccounts,
DeletedNodes: deletedAccounts,
UpdatedNodes: updatedAccounts,
}, nil
}
@ -184,52 +184,66 @@ func (sdb *builder) collectDiffNodes(a, b trie.NodeIterator) (AccountsMap, error
return diffAccounts, nil
}
func (sdb *builder) buildDiffEventual(accounts AccountsMap) ([]AccountDiff, error) {
accountDiffs := make([]AccountDiff, 0)
func (sdb *builder) buildDiffCreations(accounts AccountsMap) ([]StateNode, error) {
accountDiffs := make([]StateNode, 0, len(accounts))
var err error
for _, val := range accounts {
// If account is not nil, we need to process storage diffs
var storageDiffs []StorageDiff
var storageDiffs []StorageNode
if val.Account != nil {
storageDiffs, err = sdb.buildStorageDiffsEventual(val.Account.Root)
storageDiffs, err = sdb.buildStorageNodesEventual(val.Account.Root)
if err != nil {
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,
Path: val.Path,
LeafKey: val.LeafKey,
NodeValue: val.NodeValue,
Storage: storageDiffs,
StorageDiffs: storageDiffs,
})
}
return accountDiffs, nil
}
func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions AccountsMap, updatedKeys []string) ([]AccountDiff, error) {
updatedAccounts := make([]AccountDiff, 0)
func (sdb *builder) buildDiffDeletions(accounts AccountsMap) ([]StateNode, error) {
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
for _, val := range updatedKeys {
hashKey := common.HexToHash(val)
createdAcc := creations[hashKey]
deletedAcc := deletions[hashKey]
var storageDiffs []StorageDiff
var storageDiffs []StorageNode
if deletedAcc.Account != nil && createdAcc.Account != nil {
oldSR := deletedAcc.Account.Root
newSR := createdAcc.Account.Root
storageDiffs, err = sdb.buildStorageDiffsIncremental(oldSR, newSR)
storageDiffs, err = sdb.buildStorageNodesIncremental(oldSR, newSR)
if err != nil {
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,
Path: createdAcc.Path,
NodeValue: createdAcc.NodeValue,
LeafKey: createdAcc.LeafKey,
Storage: storageDiffs,
StorageDiffs: storageDiffs,
})
delete(creations, common.HexToHash(val))
delete(deletions, common.HexToHash(val))
@ -238,7 +252,10 @@ func (sdb *builder) buildDiffIncremental(creations AccountsMap, deletions Accoun
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())
stateCache := sdb.blockChain.StateCache()
sTrie, err := stateCache.OpenTrie(sr)
@ -247,10 +264,10 @@ func (sdb *builder) buildStorageDiffsEventual(sr common.Hash) ([]StorageDiff, er
return nil, err
}
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())
stateCache := sdb.blockChain.StateCache()
@ -266,11 +283,11 @@ func (sdb *builder) buildStorageDiffsIncremental(oldSR common.Hash, newSR common
oldIt := oldTrie.NodeIterator(make([]byte, 0))
newIt := newTrie.NodeIterator(make([]byte, 0))
it, _ := trie.NewDifferenceIterator(oldIt, newIt)
return sdb.buildStorageDiffsFromTrie(it)
return sdb.buildStorageNodesFromTrie(it)
}
func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDiff, error) {
storageDiffs := make([]StorageDiff, 0)
func (sdb *builder) buildStorageNodesFromTrie(it trie.NodeIterator) ([]StorageNode, error) {
storageDiffs := make([]StorageNode, 0)
for it.Next(true) {
// skip value nodes
if it.Leaf() {
@ -299,7 +316,7 @@ func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDi
valueNodePath := append(nodePath, partialPath...)
encodedPath := trie.HexToCompact(valueNodePath)
leafKey := encodedPath[1:]
sd := StorageDiff{
sd := StorageNode{
NodeType: ty,
Path: nodePath,
NodeValue: node,
@ -308,7 +325,7 @@ func (sdb *builder) buildStorageDiffsFromTrie(it trie.NodeIterator) ([]StorageDi
storageDiffs = append(storageDiffs, sd)
case Extension, Branch:
if sdb.config.IntermediateNodes {
storageDiffs = append(storageDiffs, StorageDiff{
storageDiffs = append(storageDiffs, StorageNode{
NodeType: ty,
Path: nodePath,
NodeValue: node,

View File

@ -34,8 +34,8 @@ import (
// TODO: add test that filters on address
var (
contractLeafKey []byte
emptyAccounts = make([]statediff.AccountDiff, 0)
emptyStorage = make([]statediff.StorageDiff, 0)
emptyAccounts = make([]statediff.StateNode, 0)
emptyStorage = make([]statediff.StorageNode, 0)
block0, block1, block2, block3 *types.Block
builder statediff.Builder
miningReward = int64(2000000000000000000)
@ -302,9 +302,9 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts,
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
CreatedNodes: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -319,17 +319,17 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -344,39 +344,39 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
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)
Path: []byte{},
NodeType: statediff.Leaf,
NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage,
NodeValue: []byte{},
StorageDiffs: emptyStorage,
},
},
UpdatedAccounts: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -393,13 +393,13 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
@ -413,31 +413,31 @@ func TestBuilder(t *testing.T) {
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -455,22 +455,22 @@ func TestBuilder(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{},
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock3LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{'\x02'},
NodeType: statediff.Leaf,
@ -490,7 +490,7 @@ func TestBuilder(t *testing.T) {
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock3LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -549,9 +549,9 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts,
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
CreatedNodes: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -566,17 +566,17 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -591,36 +591,36 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block1BranchNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -639,13 +639,13 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
@ -659,37 +659,37 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block2BranchNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountAtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -707,28 +707,28 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{},
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
NodeValue: block3BranchNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock3LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Branch,
@ -753,7 +753,7 @@ func TestBuilderWithIntermediateNodes(t *testing.T) {
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account2LeafKey,
NodeValue: account2AtBlock3LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -813,9 +813,9 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts,
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
CreatedNodes: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -830,9 +830,9 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block0.Number(),
BlockHash: block0.Hash(),
CreatedAccounts: emptyAccounts,
DeletedAccounts: emptyAccounts,
UpdatedAccounts: emptyAccounts,
CreatedNodes: emptyAccounts,
DeletedNodes: emptyAccounts,
UpdatedNodes: emptyAccounts,
},
},
{
@ -847,17 +847,17 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{},
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{},
},
},
{
@ -873,13 +873,13 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock2LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{},
NodeType: statediff.Leaf,
@ -889,14 +889,14 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
},
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1AtBlock2LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
},
@ -914,15 +914,15 @@ func TestBuilderWithWatchedAddressList(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{},
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{'\x06'},
NodeType: statediff.Leaf,
LeafKey: contractLeafKey,
NodeValue: contractAccountAtBlock3LeafNode,
Storage: []statediff.StorageDiff{
StorageDiffs: []statediff.StorageNode{
{
Path: []byte{'\x02'},
NodeType: statediff.Leaf,

View File

@ -26,7 +26,7 @@ import (
)
func sortKeys(data AccountsMap) []string {
var keys []string
keys := make([]string, 0, len(data))
for key := range data {
keys = append(keys, key.Hex())
}
@ -35,7 +35,8 @@ func sortKeys(data AccountsMap) []string {
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
func findIntersection(a, b []string) []string {
lenA := len(a)

View File

@ -47,8 +47,8 @@ var (
block1CoinbaseAddr, block2CoinbaseAddr, block3CoinbaseAddr common.Address
block1CoinbaseHash, block2CoinbaseHash, block3CoinbaseHash common.Hash
builder statediff.Builder
emptyAccounts = make([]statediff.AccountDiff, 0)
emptyStorage = make([]statediff.StorageDiff, 0)
emptyAccounts = make([]statediff.StateNode, 0)
emptyStorage = make([]statediff.StorageNode, 0)
// block 1 data
block1CoinbaseAccount, _ = rlp.EncodeToBytes(state.Account{
@ -498,33 +498,33 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x04', '\x0b', '\x0e'},
NodeType: statediff.Leaf,
LeafKey: block1CoinbaseHash.Bytes(),
NodeValue: block1CoinbaseLeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block1RootBranchNode,
},
{
Path: []byte{'\x04'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block1x04BranchNode,
},
{
Path: []byte{'\x04', '\x0b'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block1x040bBranchNode,
},
},
@ -544,49 +544,49 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block2.Number(),
BlockHash: block2.Hash(),
CreatedAccounts: []statediff.AccountDiff{
// this new leaf at x00 x08 x0d x00 was created when a premine account (leaf) was moved from path x00 x08 x0d
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 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)
{
Path: []byte{'\x00', '\x08', '\x0d', '\x00'},
NodeType: statediff.Leaf,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("08d0f2e24db7943eab4415f99e109698863b0fecca1cf9ffc500f38cefbbe29e").Bytes(),
NodeValue: block2MovedPremineLeafNode,
},
{
Path: []byte{'\x00', '\x08', '\x0d', '\x04'},
NodeType: statediff.Leaf,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
LeafKey: block2CoinbaseHash.Bytes(),
NodeValue: block2CoinbaseLeafNode,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block2RootBranchNode,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block2x00BranchNode,
},
{
Path: []byte{'\x00', '\x08'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block2x0008BranchNode,
},
{
Path: []byte{'\x00', '\x08', '\x0d'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block2x00080dBranchNode,
},
},
@ -605,71 +605,71 @@ func TestBuilderOnMainnetBlocks(t *testing.T) {
&statediff.StateDiff{
BlockNumber: block3.Number(),
BlockHash: block3.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{ // How was this account created???
Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x03'},
NodeType: statediff.Leaf,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("ce573ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190").Bytes(),
NodeValue: block3MovedPremineLeafNode1,
},
{ // This account (leaf) used to be at 0c 0e 05 07, not sure why it moves...
Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x08'},
NodeType: statediff.Leaf,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
LeafKey: common.HexToHash("ce5783bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012").Bytes(),
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
Path: []byte{'\x06', '\x0e', '\x0f'},
NodeType: statediff.Leaf,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
LeafKey: block3CoinbaseHash.Bytes(),
NodeValue: block3CoinbaseLeafNode,
},
},
DeletedAccounts: emptyAccounts,
UpdatedAccounts: []statediff.AccountDiff{
DeletedNodes: emptyAccounts,
UpdatedNodes: []statediff.StateNode{
{
Path: []byte{},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3RootBranchNode,
},
{
Path: []byte{'\x06'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x06BranchNode,
},
{
Path: []byte{'\x06', '\x0e'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x060eBranchNode,
},
{
Path: []byte{'\x0c'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x0cBranchNode,
},
{
Path: []byte{'\x0c', '\x0e'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x0c0eBranchNode,
},
{
Path: []byte{'\x0c', '\x0e', '\x05'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x0c0e05BranchNode,
},
{
Path: []byte{'\x0c', '\x0e', '\x05', '\x07'},
NodeType: statediff.Branch,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
NodeValue: block3x0c0e0507BranchNode,
},
},

View File

@ -33,11 +33,11 @@ import (
)
var (
emptyStorage = make([]statediff.StorageDiff, 0)
emptyAccounts = make([]statediff.AccountDiff, 0)
emptyStorage = make([]statediff.StorageNode, 0)
emptyAccounts = make([]statediff.StateNode, 0)
block0, block1 *types.Block
minerLeafKey = testhelpers.AddressToLeafKey(common.HexToAddress("0x0"))
emptyAccountDiffEventualMap = make([]statediff.AccountDiff, 0)
emptyStateNodeEventualMap = make([]statediff.StateNode, 0)
account1, _ = rlp.EncodeToBytes(state.Account{
Nonce: uint64(0),
Balance: big.NewInt(10000),
@ -102,39 +102,39 @@ func testSubscriptionAPI(t *testing.T) {
expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountLeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
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)
Path: []byte{},
NodeType: statediff.Leaf,
NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage,
NodeValue: []byte{},
StorageDiffs: emptyStorage,
},
},
UpdatedAccounts: emptyAccounts,
UpdatedNodes: emptyAccounts,
}
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
blockChan := make(chan *types.Block)
@ -201,39 +201,39 @@ func testHTTPAPI(t *testing.T) {
expectedStateDiff := statediff.StateDiff{
BlockNumber: block1.Number(),
BlockHash: block1.Hash(),
CreatedAccounts: []statediff.AccountDiff{
CreatedNodes: []statediff.StateNode{
{
Path: []byte{'\x05'},
NodeType: statediff.Leaf,
LeafKey: minerLeafKey,
NodeValue: minerAccountLeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x0e'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.Account1LeafKey,
NodeValue: account1LeafNode,
Storage: emptyStorage,
StorageDiffs: emptyStorage,
},
{
Path: []byte{'\x00'},
NodeType: statediff.Leaf,
LeafKey: testhelpers.BankLeafKey,
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)
Path: []byte{},
NodeType: statediff.Leaf,
NodeType: statediff.Removed,
LeafKey: testhelpers.BankLeafKey,
NodeValue: bankAccountAtBlock0LeafNode,
Storage: emptyStorage,
NodeValue: []byte{},
StorageDiffs: emptyStorage,
},
},
UpdatedAccounts: emptyAccounts,
UpdatedNodes: emptyAccounts,
}
expectedStateDiffBytes, _ := rlp.EncodeToBytes(expectedStateDiff)
config := statediff.Config{

View File

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