forked from cerc-io/ipld-eth-server
internalize some node type utils from geth as they are no longer used over there in v5
This commit is contained in:
parent
573a3dc991
commit
4c29841c21
@ -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
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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
116
pkg/eth/node_types.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user