internalize some node type utils from geth as they are no longer used over there in v5

This commit is contained in:
i-norden 2023-03-07 21:48:58 -06:00
parent 573a3dc991
commit 4c29841c21
4 changed files with 123 additions and 48 deletions

View File

@ -45,8 +45,6 @@ import (
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
ethServerShared "github.com/ethereum/go-ethereum/statediff/indexer/shared" ethServerShared "github.com/ethereum/go-ethereum/statediff/indexer/shared"
sdtrie "github.com/ethereum/go-ethereum/statediff/trie_helpers"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
"github.com/jmoiron/sqlx" "github.com/jmoiron/sqlx"
) )
@ -953,7 +951,7 @@ func (b *Backend) getSliceStem(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth { if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached metaData.maxDepth = depthReached
} }
if node.NodeType == sdtypes.Leaf { if node.NodeType == Leaf {
metaData.leafCount++ metaData.leafCount++
} }
leavesFetchTime += leafFetchTime leavesFetchTime += leafFetchTime
@ -995,7 +993,7 @@ func (b *Backend) getSliceHead(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth { if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached metaData.maxDepth = depthReached
} }
if node.NodeType == sdtypes.Leaf { if node.NodeType == Leaf {
metaData.leafCount++ metaData.leafCount++
} }
@ -1037,7 +1035,7 @@ func (b *Backend) getSliceTrie(headPath []byte, t state.Trie, response *GetSlice
continue continue
} }
node, nodeElements, err := sdtrie.ResolveNode(it, b.StateDatabase.TrieDB()) node, nodeElements, err := ResolveNodeIt(it, b.StateDatabase.TrieDB())
if err != nil { if err != nil {
return err return err
} }
@ -1052,7 +1050,7 @@ func (b *Backend) getSliceTrie(headPath []byte, t state.Trie, response *GetSlice
if depthReached > metaData.maxDepth { if depthReached > metaData.maxDepth {
metaData.maxDepth = depthReached metaData.maxDepth = depthReached
} }
if node.NodeType == sdtypes.Leaf { if node.NodeType == Leaf {
metaData.leafCount++ metaData.leafCount++
} }
leavesFetchTime += leafFetchTime leavesFetchTime += leafFetchTime

View File

@ -35,8 +35,6 @@ import (
"github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
sdtrie "github.com/ethereum/go-ethereum/statediff/trie_helpers"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
"github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie"
) )
@ -334,7 +332,7 @@ func fillSliceNodeData(
ethDB ethdb.KeyValueReader, ethDB ethdb.KeyValueReader,
nodesMap map[string]string, nodesMap map[string]string,
leavesMap map[string]GetSliceResponseAccount, leavesMap map[string]GetSliceResponseAccount,
node sdtypes.StateNode, node StateNode,
nodeElements []interface{}, nodeElements []interface{},
storage bool, storage bool,
) (int64, error) { ) (int64, error) {
@ -344,7 +342,7 @@ func fillSliceNodeData(
// Extract account data if it's a Leaf node // Extract account data if it's a Leaf node
leafStartTime := makeTimestamp() leafStartTime := makeTimestamp()
if node.NodeType == sdtypes.Leaf && !storage { if node.NodeType == Leaf && !storage {
stateLeafKey, storageRoot, code, err := extractContractAccountInfo(ethDB, node, nodeElements) stateLeafKey, storageRoot, code, err := extractContractAccountInfo(ethDB, node, nodeElements)
if err != nil { if err != nil {
return 0, fmt.Errorf("GetSlice account lookup error: %s", err.Error()) return 0, fmt.Errorf("GetSlice account lookup error: %s", err.Error())
@ -362,7 +360,7 @@ func fillSliceNodeData(
return makeTimestamp() - leafStartTime, nil return makeTimestamp() - leafStartTime, nil
} }
func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node sdtypes.StateNode, nodeElements []interface{}) (string, string, []byte, error) { func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node StateNode, nodeElements []interface{}) (string, string, []byte, error) {
var account types.StateAccount var account types.StateAccount
if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil {
return "", "", nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err) return "", "", nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err)
@ -387,23 +385,3 @@ func extractContractAccountInfo(ethDB ethdb.KeyValueReader, node sdtypes.StateNo
return stateLeafKeyString, storageRootString, codeBytes, nil return stateLeafKeyString, storageRootString, codeBytes, nil
} }
func ResolveNode(path []byte, node []byte, trieDB *trie.Database) (sdtypes.StateNode, []interface{}, error) {
nodePath := make([]byte, len(path))
copy(nodePath, path)
var nodeElements []interface{}
if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
return sdtypes.StateNode{}, nil, err
}
ty, err := sdtrie.CheckKeyType(nodeElements)
if err != nil {
return sdtypes.StateNode{}, nil, err
}
return sdtypes.StateNode{
NodeType: ty,
Path: nodePath,
NodeValue: node,
}, nodeElements, nil
}

View File

@ -18,25 +18,8 @@ package eth
import ( import (
"time" "time"
sdtypes "github.com/ethereum/go-ethereum/statediff/types"
) )
func ResolveToNodeType(nodeType int) sdtypes.NodeType {
switch nodeType {
case 0:
return sdtypes.Branch
case 1:
return sdtypes.Extension
case 2:
return sdtypes.Leaf
case 3:
return sdtypes.Removed
default:
return sdtypes.Unknown
}
}
// Timestamp in milliseconds // Timestamp in milliseconds
func makeTimestamp() int64 { func makeTimestamp() int64 {
return time.Now().UnixNano() / int64(time.Millisecond) return time.Now().UnixNano() / int64(time.Millisecond)

116
pkg/eth/node_types.go Normal file
View File

@ -0,0 +1,116 @@
package eth
import (
"fmt"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
)
// NodeType for explicitly setting type of node
type NodeType string
const (
Unknown NodeType = "Unknown"
Branch NodeType = "Branch"
Extension NodeType = "Extension"
Leaf NodeType = "Leaf"
Removed NodeType = "Removed" // used to represent paths which have been emptied
)
func (n NodeType) Int() int {
switch n {
case Branch:
return 0
case Extension:
return 1
case Leaf:
return 2
case Removed:
return 3
default:
return -1
}
}
// CheckKeyType checks what type of key we have
func CheckKeyType(elements []interface{}) (NodeType, error) {
if len(elements) > 2 {
return Branch, nil
}
if len(elements) < 2 {
return Unknown, fmt.Errorf("node cannot be less than two elements in length")
}
switch elements[0].([]byte)[0] / 16 {
case '\x00':
return Extension, nil
case '\x01':
return Extension, nil
case '\x02':
return Leaf, nil
case '\x03':
return Leaf, nil
default:
return Unknown, fmt.Errorf("unknown hex prefix")
}
}
// 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"`
StorageNodes []StorageNode `json:"storage"`
LeafKey []byte `json:"leafKey"`
}
// 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"`
LeafKey []byte `json:"leafKey"`
}
func ResolveNode(path []byte, node []byte, trieDB *trie.Database) (StateNode, []interface{}, error) {
nodePath := make([]byte, len(path))
copy(nodePath, path)
var nodeElements []interface{}
if err := rlp.DecodeBytes(node, &nodeElements); err != nil {
return StateNode{}, nil, err
}
ty, err := CheckKeyType(nodeElements)
if err != nil {
return StateNode{}, nil, err
}
return StateNode{
NodeType: ty,
Path: nodePath,
NodeValue: node,
}, nodeElements, nil
}
// ResolveNodeIt return the state diff node pointed by the iterator.
func ResolveNodeIt(it trie.NodeIterator, trieDB *trie.Database) (StateNode, []interface{}, error) {
nodePath := make([]byte, len(it.Path()))
copy(nodePath, it.Path())
node, err := trieDB.Node(it.Hash())
if err != nil {
return StateNode{}, nil, err
}
var nodeElements []interface{}
if err = rlp.DecodeBytes(node, &nodeElements); err != nil {
return StateNode{}, nil, err
}
ty, err := CheckKeyType(nodeElements)
if err != nil {
return StateNode{}, nil, err
}
return StateNode{
NodeType: ty,
Path: nodePath,
NodeValue: node,
}, nodeElements, nil
}