Refactor builder code to make it reusable
This commit is contained in:
parent
5e3de63be6
commit
df70d03133
@ -48,24 +48,28 @@ type Builder interface {
|
|||||||
WriteStateDiffObject(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error
|
WriteStateDiffObject(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type builder struct {
|
type StateDiffBuilder struct {
|
||||||
stateCache state.Database
|
StateCache state.Database
|
||||||
|
}
|
||||||
|
|
||||||
|
type IterPair struct {
|
||||||
|
Older, Newer trie.NodeIterator
|
||||||
}
|
}
|
||||||
|
|
||||||
// convenience
|
// convenience
|
||||||
func stateNodeAppender(nodes *[]types2.StateNode) types2.StateNodeSink {
|
func StateNodeAppender(nodes *[]types2.StateNode) types2.StateNodeSink {
|
||||||
return func(node types2.StateNode) error {
|
return func(node types2.StateNode) error {
|
||||||
*nodes = append(*nodes, node)
|
*nodes = append(*nodes, node)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func storageNodeAppender(nodes *[]types2.StorageNode) types2.StorageNodeSink {
|
func StorageNodeAppender(nodes *[]types2.StorageNode) types2.StorageNodeSink {
|
||||||
return func(node types2.StorageNode) error {
|
return func(node types2.StorageNode) error {
|
||||||
*nodes = append(*nodes, node)
|
*nodes = append(*nodes, node)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func codeMappingAppender(codeAndCodeHashes *[]types2.CodeAndCodeHash) types2.CodeSink {
|
func CodeMappingAppender(codeAndCodeHashes *[]types2.CodeAndCodeHash) types2.CodeSink {
|
||||||
return func(c types2.CodeAndCodeHash) error {
|
return func(c types2.CodeAndCodeHash) error {
|
||||||
*codeAndCodeHashes = append(*codeAndCodeHashes, c)
|
*codeAndCodeHashes = append(*codeAndCodeHashes, c)
|
||||||
return nil
|
return nil
|
||||||
@ -74,14 +78,14 @@ func codeMappingAppender(codeAndCodeHashes *[]types2.CodeAndCodeHash) types2.Cod
|
|||||||
|
|
||||||
// NewBuilder is used to create a statediff builder
|
// NewBuilder is used to create a statediff builder
|
||||||
func NewBuilder(stateCache state.Database) Builder {
|
func NewBuilder(stateCache state.Database) Builder {
|
||||||
return &builder{
|
return &StateDiffBuilder{
|
||||||
stateCache: stateCache, // state cache is safe for concurrent reads
|
StateCache: stateCache, // state cache is safe for concurrent reads
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildStateTrieObject builds a state trie object from the provided block
|
// BuildStateTrieObject builds a state trie object from the provided block
|
||||||
func (sdb *builder) BuildStateTrieObject(current *types.Block) (types2.StateObject, error) {
|
func (sdb *StateDiffBuilder) BuildStateTrieObject(current *types.Block) (types2.StateObject, error) {
|
||||||
currentTrie, err := sdb.stateCache.OpenTrie(current.Root())
|
currentTrie, err := sdb.StateCache.OpenTrie(current.Root())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types2.StateObject{}, fmt.Errorf("error creating trie for block %d: %v", current.Number(), err)
|
return types2.StateObject{}, fmt.Errorf("error creating trie for block %d: %v", current.Number(), err)
|
||||||
}
|
}
|
||||||
@ -98,7 +102,7 @@ func (sdb *builder) BuildStateTrieObject(current *types.Block) (types2.StateObje
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []types2.CodeAndCodeHash, error) {
|
func (sdb *StateDiffBuilder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []types2.CodeAndCodeHash, error) {
|
||||||
stateNodes := make([]types2.StateNode, 0)
|
stateNodes := make([]types2.StateNode, 0)
|
||||||
codeAndCodeHashes := make([]types2.CodeAndCodeHash, 0)
|
codeAndCodeHashes := make([]types2.CodeAndCodeHash, 0)
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
@ -106,7 +110,7 @@ func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []
|
|||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -123,14 +127,14 @@ func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []
|
|||||||
node.LeafKey = leafKey
|
node.LeafKey = leafKey
|
||||||
if !bytes.Equal(account.CodeHash, nullCodeHash) {
|
if !bytes.Equal(account.CodeHash, nullCodeHash) {
|
||||||
var storageNodes []types2.StorageNode
|
var storageNodes []types2.StorageNode
|
||||||
err := sdb.buildStorageNodesEventual(account.Root, true, storageNodeAppender(&storageNodes))
|
err := sdb.buildStorageNodesEventual(account.Root, true, StorageNodeAppender(&storageNodes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed building eventual storage diffs for account %+v\r\nerror: %v", account, err)
|
return nil, nil, fmt.Errorf("failed building eventual storage diffs for account %+v\r\nerror: %v", account, err)
|
||||||
}
|
}
|
||||||
node.StorageNodes = storageNodes
|
node.StorageNodes = storageNodes
|
||||||
// emit codehash => code mappings for cod
|
// emit codehash => code mappings for cod
|
||||||
codeHash := common.BytesToHash(account.CodeHash)
|
codeHash := common.BytesToHash(account.CodeHash)
|
||||||
code, err := sdb.stateCache.ContractCode(common.Hash{}, codeHash)
|
code, err := sdb.StateCache.ContractCode(common.Hash{}, codeHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err)
|
return nil, nil, fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err)
|
||||||
}
|
}
|
||||||
@ -150,12 +154,12 @@ func (sdb *builder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters
|
// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters
|
||||||
func (sdb *builder) BuildStateDiffObject(args Args, params Params) (types2.StateObject, error) {
|
func (sdb *StateDiffBuilder) BuildStateDiffObject(args Args, params Params) (types2.StateObject, error) {
|
||||||
var stateNodes []types2.StateNode
|
var stateNodes []types2.StateNode
|
||||||
var codeAndCodeHashes []types2.CodeAndCodeHash
|
var codeAndCodeHashes []types2.CodeAndCodeHash
|
||||||
err := sdb.WriteStateDiffObject(
|
err := sdb.WriteStateDiffObject(
|
||||||
types2.StateRoots{OldStateRoot: args.OldStateRoot, NewStateRoot: args.NewStateRoot},
|
types2.StateRoots{OldStateRoot: args.OldStateRoot, NewStateRoot: args.NewStateRoot},
|
||||||
params, stateNodeAppender(&stateNodes), codeMappingAppender(&codeAndCodeHashes))
|
params, StateNodeAppender(&stateNodes), CodeMappingAppender(&codeAndCodeHashes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types2.StateObject{}, err
|
return types2.StateObject{}, err
|
||||||
}
|
}
|
||||||
@ -168,32 +172,46 @@ func (sdb *builder) BuildStateDiffObject(args Args, params Params) (types2.State
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WriteStateDiffObject writes a statediff object to output callback
|
// WriteStateDiffObject writes a statediff object to output callback
|
||||||
func (sdb *builder) WriteStateDiffObject(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
func (sdb *StateDiffBuilder) WriteStateDiffObject(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
||||||
if !params.IntermediateStateNodes || len(params.WatchedAddresses) > 0 {
|
|
||||||
// if we are watching only specific accounts then we are only diffing leaf nodes
|
|
||||||
return sdb.buildStateDiffWithoutIntermediateStateNodes(args, params, output, codeOutput)
|
|
||||||
} else {
|
|
||||||
return sdb.buildStateDiffWithIntermediateStateNodes(args, params, output, codeOutput)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sdb *builder) buildStateDiffWithIntermediateStateNodes(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
|
||||||
// Load tries for old and new states
|
// Load tries for old and new states
|
||||||
oldTrie, err := sdb.stateCache.OpenTrie(args.OldStateRoot)
|
oldTrie, err := sdb.StateCache.OpenTrie(args.OldStateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating trie for oldStateRoot: %v", err)
|
return fmt.Errorf("error creating trie for oldStateRoot: %v", err)
|
||||||
}
|
}
|
||||||
newTrie, err := sdb.stateCache.OpenTrie(args.NewStateRoot)
|
newTrie, err := sdb.StateCache.OpenTrie(args.NewStateRoot)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error creating trie for newStateRoot: %v", err)
|
return fmt.Errorf("error creating trie for newStateRoot: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect a slice of all the intermediate nodes that were touched and exist at B
|
// we do two state trie iterations:
|
||||||
|
// one for new/updated nodes,
|
||||||
|
// one for deleted/updated nodes;
|
||||||
|
// prepare 2 iterator instances for each task
|
||||||
|
iterPairs := []IterPair{
|
||||||
|
{
|
||||||
|
Older: oldTrie.NodeIterator([]byte{}),
|
||||||
|
Newer: newTrie.NodeIterator([]byte{}),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Older: oldTrie.NodeIterator([]byte{}),
|
||||||
|
Newer: newTrie.NodeIterator([]byte{}),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !params.IntermediateStateNodes || len(params.WatchedAddresses) > 0 {
|
||||||
|
// if we are watching only specific accounts then we are only diffing leaf nodes
|
||||||
|
return sdb.BuildStateDiffWithoutIntermediateStateNodes(iterPairs, params, output, codeOutput)
|
||||||
|
} else {
|
||||||
|
return sdb.BuildStateDiffWithIntermediateStateNodes(iterPairs, params, output, codeOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sdb *StateDiffBuilder) BuildStateDiffWithIntermediateStateNodes(iterPairs []IterPair, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
||||||
|
// collect a slice of all the nodes that were touched and exist at B (B-A)
|
||||||
// a map of their leafkey to all the accounts that were touched and exist at B
|
// a map of their leafkey to all the accounts that were touched and exist at B
|
||||||
// and a slice of all the paths for the nodes in both of the above sets
|
// and a slice of all the paths for the nodes in both of the above sets
|
||||||
diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedStateWithIntermediateNodes(
|
diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedStateWithIntermediateNodes(
|
||||||
oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}),
|
iterPairs[0].Older, iterPairs[0].Newer, output)
|
||||||
output)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err)
|
return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err)
|
||||||
}
|
}
|
||||||
@ -201,9 +219,9 @@ func (sdb *builder) buildStateDiffWithIntermediateStateNodes(args types2.StateRo
|
|||||||
// collect a slice of all the nodes that existed at a path in A that doesn't exist in B
|
// collect a slice of all the nodes that existed at a path in A that doesn't exist in B
|
||||||
// a map of their leafkey to all the accounts that were touched and exist at A
|
// a map of their leafkey to all the accounts that were touched and exist at A
|
||||||
diffAccountsAtA, err := sdb.deletedOrUpdatedState(
|
diffAccountsAtA, err := sdb.deletedOrUpdatedState(
|
||||||
oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}),
|
iterPairs[1].Older, iterPairs[1].Newer,
|
||||||
diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafKeys,
|
diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafKeys,
|
||||||
params.IntermediateStorageNodes, output)
|
params.IntermediateStateNodes, params.IntermediateStorageNodes, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err)
|
return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err)
|
||||||
}
|
}
|
||||||
@ -233,21 +251,11 @@ func (sdb *builder) buildStateDiffWithIntermediateStateNodes(args types2.StateRo
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) buildStateDiffWithoutIntermediateStateNodes(args types2.StateRoots, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
func (sdb *StateDiffBuilder) BuildStateDiffWithoutIntermediateStateNodes(iterPairs []IterPair, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
||||||
// Load tries for old (A) and new (B) states
|
|
||||||
oldTrie, err := sdb.stateCache.OpenTrie(args.OldStateRoot)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating trie for oldStateRoot: %v", err)
|
|
||||||
}
|
|
||||||
newTrie, err := sdb.stateCache.OpenTrie(args.NewStateRoot)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error creating trie for newStateRoot: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// collect a map of their leafkey to all the accounts that were touched and exist at B
|
// collect a map of their leafkey to all the accounts that were touched and exist at B
|
||||||
// and a slice of all the paths for the nodes in both of the above sets
|
// and a slice of all the paths for the nodes in both of the above sets
|
||||||
diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedState(
|
diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedState(
|
||||||
oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}),
|
iterPairs[0].Older, iterPairs[0].Newer,
|
||||||
params.watchedAddressesLeafKeys)
|
params.watchedAddressesLeafKeys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err)
|
return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err)
|
||||||
@ -256,9 +264,9 @@ func (sdb *builder) buildStateDiffWithoutIntermediateStateNodes(args types2.Stat
|
|||||||
// collect a slice of all the nodes that existed at a path in A that doesn't exist in B
|
// collect a slice of all the nodes that existed at a path in A that doesn't exist in B
|
||||||
// a map of their leafkey to all the accounts that were touched and exist at A
|
// a map of their leafkey to all the accounts that were touched and exist at A
|
||||||
diffAccountsAtA, err := sdb.deletedOrUpdatedState(
|
diffAccountsAtA, err := sdb.deletedOrUpdatedState(
|
||||||
oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}),
|
iterPairs[1].Older, iterPairs[1].Newer,
|
||||||
diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafKeys,
|
diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafKeys,
|
||||||
params.IntermediateStorageNodes, output)
|
params.IntermediateStateNodes, params.IntermediateStorageNodes, output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err)
|
return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err)
|
||||||
}
|
}
|
||||||
@ -291,7 +299,7 @@ func (sdb *builder) buildStateDiffWithoutIntermediateStateNodes(args types2.Stat
|
|||||||
// createdAndUpdatedState returns
|
// createdAndUpdatedState returns
|
||||||
// a mapping of their leafkeys to all the accounts that exist in a different state at B than A
|
// a mapping of their leafkeys to all the accounts that exist in a different state at B than A
|
||||||
// and a slice of the paths for all of the nodes included in both
|
// and a slice of the paths for all of the nodes included in both
|
||||||
func (sdb *builder) createdAndUpdatedState(a, b trie.NodeIterator, watchedAddressesLeafKeys map[common.Hash]struct{}) (types2.AccountMap, map[string]bool, error) {
|
func (sdb *StateDiffBuilder) createdAndUpdatedState(a, b trie.NodeIterator, watchedAddressesLeafKeys map[common.Hash]struct{}) (types2.AccountMap, map[string]bool, error) {
|
||||||
diffPathsAtB := make(map[string]bool)
|
diffPathsAtB := make(map[string]bool)
|
||||||
diffAcountsAtB := make(types2.AccountMap)
|
diffAcountsAtB := make(types2.AccountMap)
|
||||||
it, _ := trie.NewDifferenceIterator(a, b)
|
it, _ := trie.NewDifferenceIterator(a, b)
|
||||||
@ -300,7 +308,8 @@ func (sdb *builder) createdAndUpdatedState(a, b trie.NodeIterator, watchedAddres
|
|||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
|
||||||
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -335,7 +344,7 @@ func (sdb *builder) createdAndUpdatedState(a, b trie.NodeIterator, watchedAddres
|
|||||||
// a slice of all the intermediate nodes that exist in a different state at B than A
|
// a slice of all the intermediate nodes that exist in a different state at B than A
|
||||||
// a mapping of their leafkeys to all the accounts that exist in a different state at B than A
|
// a mapping of their leafkeys to all the accounts that exist in a different state at B than A
|
||||||
// and a slice of the paths for all of the nodes included in both
|
// and a slice of the paths for all of the nodes included in both
|
||||||
func (sdb *builder) createdAndUpdatedStateWithIntermediateNodes(a, b trie.NodeIterator, output types2.StateNodeSink) (types2.AccountMap, map[string]bool, error) {
|
func (sdb *StateDiffBuilder) createdAndUpdatedStateWithIntermediateNodes(a, b trie.NodeIterator, output types2.StateNodeSink) (types2.AccountMap, map[string]bool, error) {
|
||||||
diffPathsAtB := make(map[string]bool)
|
diffPathsAtB := make(map[string]bool)
|
||||||
diffAcountsAtB := make(types2.AccountMap)
|
diffAcountsAtB := make(types2.AccountMap)
|
||||||
it, _ := trie.NewDifferenceIterator(a, b)
|
it, _ := trie.NewDifferenceIterator(a, b)
|
||||||
@ -344,7 +353,7 @@ func (sdb *builder) createdAndUpdatedStateWithIntermediateNodes(a, b trie.NodeIt
|
|||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -388,7 +397,7 @@ func (sdb *builder) createdAndUpdatedStateWithIntermediateNodes(a, b trie.NodeIt
|
|||||||
|
|
||||||
// deletedOrUpdatedState returns a slice of all the pathes that are emptied at B
|
// deletedOrUpdatedState returns a slice of all the pathes that are emptied at B
|
||||||
// and a mapping of their leafkeys to all the accounts that exist in a different state at A than B
|
// and a mapping of their leafkeys to all the accounts that exist in a different state at A than B
|
||||||
func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAtB types2.AccountMap, diffPathsAtB map[string]bool, watchedAddressesLeafKeys map[common.Hash]struct{}, intermediateStorageNodes bool, output types2.StateNodeSink) (types2.AccountMap, error) {
|
func (sdb *StateDiffBuilder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAtB types2.AccountMap, diffPathsAtB map[string]bool, watchedAddressesLeafKeys map[common.Hash]struct{}, intermediateStateNodes, intermediateStorageNodes bool, output types2.StateNodeSink) (types2.AccountMap, error) {
|
||||||
diffAccountAtA := make(types2.AccountMap)
|
diffAccountAtA := make(types2.AccountMap)
|
||||||
it, _ := trie.NewDifferenceIterator(b, a)
|
it, _ := trie.NewDifferenceIterator(b, a)
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
@ -396,7 +405,8 @@ func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAt
|
|||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
|
||||||
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -436,7 +446,7 @@ func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAt
|
|||||||
}
|
}
|
||||||
|
|
||||||
var storageDiffs []types2.StorageNode
|
var storageDiffs []types2.StorageNode
|
||||||
err := sdb.buildRemovedAccountStorageNodes(account.Root, intermediateStorageNodes, storageNodeAppender(&storageDiffs))
|
err := sdb.buildRemovedAccountStorageNodes(account.Root, intermediateStorageNodes, StorageNodeAppender(&storageDiffs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed building storage diffs for removed node %x\r\nerror: %v", node.Path, err)
|
return nil, fmt.Errorf("failed building storage diffs for removed node %x\r\nerror: %v", node.Path, err)
|
||||||
}
|
}
|
||||||
@ -459,6 +469,7 @@ func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAt
|
|||||||
// if this node's path did not show up in diffPathsAtB
|
// if this node's path did not show up in diffPathsAtB
|
||||||
// that means the node at this path was deleted (or moved) in B
|
// that means the node at this path was deleted (or moved) in B
|
||||||
// emit an empty "removed" diff to signify as such
|
// emit an empty "removed" diff to signify as such
|
||||||
|
if intermediateStateNodes {
|
||||||
if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok {
|
if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok {
|
||||||
if err := output(types2.StateNode{
|
if err := output(types2.StateNode{
|
||||||
Path: node.Path,
|
Path: node.Path,
|
||||||
@ -468,6 +479,7 @@ func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAt
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// fall through, we did everything we need to do with these node types
|
// fall through, we did everything we need to do with these node types
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unexpected node type %s", node.NodeType)
|
return nil, fmt.Errorf("unexpected node type %s", node.NodeType)
|
||||||
@ -480,7 +492,7 @@ func (sdb *builder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAt
|
|||||||
// to generate the statediff node objects for all of the accounts that existed at both A and B but in different states
|
// to generate the statediff node objects for all of the accounts that existed at both A and B but in different states
|
||||||
// needs to be called before building account creations and deletions as this mutates
|
// needs to be called before building account creations and deletions as this mutates
|
||||||
// those account maps to remove the accounts which were updated
|
// those account maps to remove the accounts which were updated
|
||||||
func (sdb *builder) buildAccountUpdates(creations, deletions types2.AccountMap, updatedKeys []string, intermediateStorageNodes bool, output types2.StateNodeSink) error {
|
func (sdb *StateDiffBuilder) buildAccountUpdates(creations, deletions types2.AccountMap, updatedKeys []string, intermediateStorageNodes bool, output types2.StateNodeSink) error {
|
||||||
var err error
|
var err error
|
||||||
for _, key := range updatedKeys {
|
for _, key := range updatedKeys {
|
||||||
createdAcc := creations[key]
|
createdAcc := creations[key]
|
||||||
@ -491,7 +503,7 @@ func (sdb *builder) buildAccountUpdates(creations, deletions types2.AccountMap,
|
|||||||
newSR := createdAcc.Account.Root
|
newSR := createdAcc.Account.Root
|
||||||
err = sdb.buildStorageNodesIncremental(
|
err = sdb.buildStorageNodesIncremental(
|
||||||
oldSR, newSR, intermediateStorageNodes,
|
oldSR, newSR, intermediateStorageNodes,
|
||||||
storageNodeAppender(&storageDiffs))
|
StorageNodeAppender(&storageDiffs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed building incremental storage diffs for account with leafkey %s\r\nerror: %v", key, err)
|
return fmt.Errorf("failed building incremental storage diffs for account with leafkey %s\r\nerror: %v", key, err)
|
||||||
}
|
}
|
||||||
@ -514,7 +526,7 @@ func (sdb *builder) buildAccountUpdates(creations, deletions types2.AccountMap,
|
|||||||
|
|
||||||
// buildAccountCreations returns the statediff node objects for all the accounts that exist at B but not at A
|
// buildAccountCreations returns the statediff node objects for all the accounts that exist at B but not at A
|
||||||
// it also returns the code and codehash for created contract accounts
|
// it also returns the code and codehash for created contract accounts
|
||||||
func (sdb *builder) buildAccountCreations(accounts types2.AccountMap, intermediateStorageNodes bool, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
func (sdb *StateDiffBuilder) buildAccountCreations(accounts types2.AccountMap, intermediateStorageNodes bool, output types2.StateNodeSink, codeOutput types2.CodeSink) error {
|
||||||
for _, val := range accounts {
|
for _, val := range accounts {
|
||||||
diff := types2.StateNode{
|
diff := types2.StateNode{
|
||||||
NodeType: val.NodeType,
|
NodeType: val.NodeType,
|
||||||
@ -525,14 +537,14 @@ func (sdb *builder) buildAccountCreations(accounts types2.AccountMap, intermedia
|
|||||||
if !bytes.Equal(val.Account.CodeHash, nullCodeHash) {
|
if !bytes.Equal(val.Account.CodeHash, nullCodeHash) {
|
||||||
// For contract creations, any storage node contained is a diff
|
// For contract creations, any storage node contained is a diff
|
||||||
var storageDiffs []types2.StorageNode
|
var storageDiffs []types2.StorageNode
|
||||||
err := sdb.buildStorageNodesEventual(val.Account.Root, intermediateStorageNodes, storageNodeAppender(&storageDiffs))
|
err := sdb.buildStorageNodesEventual(val.Account.Root, intermediateStorageNodes, StorageNodeAppender(&storageDiffs))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err)
|
return fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err)
|
||||||
}
|
}
|
||||||
diff.StorageNodes = storageDiffs
|
diff.StorageNodes = storageDiffs
|
||||||
// emit codehash => code mappings for cod
|
// emit codehash => code mappings for cod
|
||||||
codeHash := common.BytesToHash(val.Account.CodeHash)
|
codeHash := common.BytesToHash(val.Account.CodeHash)
|
||||||
code, err := sdb.stateCache.ContractCode(common.Hash{}, codeHash)
|
code, err := sdb.StateCache.ContractCode(common.Hash{}, codeHash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err)
|
return fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err)
|
||||||
}
|
}
|
||||||
@ -553,12 +565,12 @@ func (sdb *builder) buildAccountCreations(accounts types2.AccountMap, intermedia
|
|||||||
|
|
||||||
// buildStorageNodesEventual builds the storage diff node objects for a created account
|
// buildStorageNodesEventual builds the storage diff node objects for a created account
|
||||||
// i.e. it returns all the storage nodes at this state, since there is no previous state
|
// i.e. it returns all the storage nodes at this state, since there is no previous state
|
||||||
func (sdb *builder) buildStorageNodesEventual(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) buildStorageNodesEventual(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) {
|
if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Debug("Storage Root For Eventual Diff", "root", sr.Hex())
|
log.Debug("Storage Root For Eventual Diff", "root", sr.Hex())
|
||||||
sTrie, err := sdb.stateCache.OpenTrie(sr)
|
sTrie, err := sdb.StateCache.OpenTrie(sr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("error in build storage diff eventual", "error", err)
|
log.Info("error in build storage diff eventual", "error", err)
|
||||||
return err
|
return err
|
||||||
@ -573,13 +585,13 @@ func (sdb *builder) buildStorageNodesEventual(sr common.Hash, intermediateNodes
|
|||||||
|
|
||||||
// buildStorageNodesFromTrie returns all the storage diff node objects in the provided node interator
|
// buildStorageNodesFromTrie returns all the storage diff node objects in the provided node interator
|
||||||
// including intermediate nodes can be turned on or off
|
// including intermediate nodes can be turned on or off
|
||||||
func (sdb *builder) buildStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) buildStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
// skip value nodes
|
// skip value nodes
|
||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -615,12 +627,12 @@ func (sdb *builder) buildStorageNodesFromTrie(it trie.NodeIterator, intermediate
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildRemovedAccountStorageNodes builds the "removed" diffs for all the storage nodes for a destroyed account
|
// buildRemovedAccountStorageNodes builds the "removed" diffs for all the storage nodes for a destroyed account
|
||||||
func (sdb *builder) buildRemovedAccountStorageNodes(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) buildRemovedAccountStorageNodes(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) {
|
if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Debug("Storage Root For Removed Diffs", "root", sr.Hex())
|
log.Debug("Storage Root For Removed Diffs", "root", sr.Hex())
|
||||||
sTrie, err := sdb.stateCache.OpenTrie(sr)
|
sTrie, err := sdb.StateCache.OpenTrie(sr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Info("error in build removed account storage diffs", "error", err)
|
log.Info("error in build removed account storage diffs", "error", err)
|
||||||
return err
|
return err
|
||||||
@ -635,13 +647,13 @@ func (sdb *builder) buildRemovedAccountStorageNodes(sr common.Hash, intermediate
|
|||||||
|
|
||||||
// buildRemovedStorageNodesFromTrie returns diffs for all the storage nodes in the provided node interator
|
// buildRemovedStorageNodesFromTrie returns diffs for all the storage nodes in the provided node interator
|
||||||
// including intermediate nodes can be turned on or off
|
// including intermediate nodes can be turned on or off
|
||||||
func (sdb *builder) buildRemovedStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) buildRemovedStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
// skip value nodes
|
// skip value nodes
|
||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -677,16 +689,16 @@ func (sdb *builder) buildRemovedStorageNodesFromTrie(it trie.NodeIterator, inter
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildStorageNodesIncremental builds the storage diff node objects for all nodes that exist in a different state at B than A
|
// buildStorageNodesIncremental builds the storage diff node objects for all nodes that exist in a different state at B than A
|
||||||
func (sdb *builder) buildStorageNodesIncremental(oldSR common.Hash, newSR common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) buildStorageNodesIncremental(oldSR common.Hash, newSR common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
if bytes.Equal(newSR.Bytes(), oldSR.Bytes()) {
|
if bytes.Equal(newSR.Bytes(), oldSR.Bytes()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
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())
|
||||||
oldTrie, err := sdb.stateCache.OpenTrie(oldSR)
|
oldTrie, err := sdb.StateCache.OpenTrie(oldSR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newTrie, err := sdb.stateCache.OpenTrie(newSR)
|
newTrie, err := sdb.StateCache.OpenTrie(newSR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -705,7 +717,7 @@ func (sdb *builder) buildStorageNodesIncremental(oldSR common.Hash, newSR common
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) createdAndUpdatedStorage(a, b trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) (map[string]bool, map[string]bool, error) {
|
func (sdb *StateDiffBuilder) createdAndUpdatedStorage(a, b trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) (map[string]bool, map[string]bool, error) {
|
||||||
diffPathsAtB := make(map[string]bool)
|
diffPathsAtB := make(map[string]bool)
|
||||||
diffSlotsAtB := make(map[string]bool)
|
diffSlotsAtB := make(map[string]bool)
|
||||||
it, _ := trie.NewDifferenceIterator(a, b)
|
it, _ := trie.NewDifferenceIterator(a, b)
|
||||||
@ -714,7 +726,7 @@ func (sdb *builder) createdAndUpdatedStorage(a, b trie.NodeIterator, intermediat
|
|||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -751,14 +763,14 @@ func (sdb *builder) createdAndUpdatedStorage(a, b trie.NodeIterator, intermediat
|
|||||||
return diffSlotsAtB, diffPathsAtB, it.Error()
|
return diffSlotsAtB, diffPathsAtB, it.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sdb *builder) deletedOrUpdatedStorage(a, b trie.NodeIterator, diffSlotsAtB, diffPathsAtB map[string]bool, intermediateNodes bool, output types2.StorageNodeSink) error {
|
func (sdb *StateDiffBuilder) deletedOrUpdatedStorage(a, b trie.NodeIterator, diffSlotsAtB, diffPathsAtB map[string]bool, intermediateNodes bool, output types2.StorageNodeSink) error {
|
||||||
it, _ := trie.NewDifferenceIterator(b, a)
|
it, _ := trie.NewDifferenceIterator(b, a)
|
||||||
for it.Next(true) {
|
for it.Next(true) {
|
||||||
// skip value nodes
|
// skip value nodes
|
||||||
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.stateCache.TrieDB())
|
node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,6 @@ func (p *Params) ComputeWatchedAddressesLeafKeys() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Params) WatchedAddressesLeafKeys() map[common.Hash]struct{} {
|
|
||||||
return p.watchedAddressesLeafKeys
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParamsWithMutex allows to lock the parameters while they are being updated | read from
|
// ParamsWithMutex allows to lock the parameters while they are being updated | read from
|
||||||
type ParamsWithMutex struct {
|
type ParamsWithMutex struct {
|
||||||
Params
|
Params
|
||||||
|
Loading…
Reference in New Issue
Block a user