Populate extra contract leaves field in the response

This commit is contained in:
Prathamesh Musale 2022-12-14 13:46:58 +05:30
parent 16fc1d4957
commit 4ea8620bc8
3 changed files with 59 additions and 8 deletions

View File

@ -1145,8 +1145,4 @@ var _ = Describe("API", func() {
Expect(code).To(BeEmpty())
})
})
Describe("eth_getSlice", func() {
// TODO Implement
})
})

View File

@ -109,9 +109,21 @@ const (
AND state_cids.state_path = state_accounts.state_path
AND state_cids.header_id = state_accounts.header_id
AND state_cids.block_number = state_accounts.block_number
AND state_cids.node_type != 3
AND state_accounts.header_id = (SELECT canonical_header_hash(state_accounts.block_number))
ORDER BY state_accounts.block_number DESC
LIMIT 1`
RetrieveAccountByStateCID = `SELECT state_leaf_key, storage_root, code_hash
FROM eth.state_cids
INNER JOIN eth.state_accounts ON (
state_cids.state_path = state_accounts.state_path
AND state_cids.header_id = state_accounts.header_id
AND state_cids.block_number = state_accounts.block_number
)
WHERE state_cids.cid = $1
AND state_cids.block_number <= $2
ORDER BY state_cids.block_number DESC
LIMIT 1`
)
const (
@ -971,7 +983,24 @@ func (b *Backend) GetStateSlice(path string, depth int, root common.Hash) (*GetS
leafNodes = append(leafNodes, stemLeafCIDs...)
leafNodes = append(leafNodes, sliceLeafCIDs...)
leafNodes = append(leafNodes, headLeafCID...)
// TODO: fill in contract data `response.Leaves`
contractCount := 0
for _, leafNodeCID := range leafNodes {
stateLeafKey, storageRoot, code, err := b.getAccountByStateCID(tx, leafNodeCID.String(), blockHeight)
if err != nil {
return nil, fmt.Errorf("GetStateSlice account lookup error: %s", err.Error())
}
response.Leaves[stateLeafKey] = GetSliceResponseAccount{
StorageRoot: storageRoot,
EVMCode: common.Bytes2Hex(code),
}
if len(code) > 0 {
contractCount++
}
}
response.MetaData.TimeStats["03-fetch-leaves-info"] = strconv.Itoa(int(makeTimestamp() - leafFetchStart))
maxDepth := deepestPath - len(headPath)
@ -982,7 +1011,7 @@ func (b *Backend) GetStateSlice(path string, depth int, root common.Hash) (*GetS
response.MetaData.NodeStats["02-total-trie-nodes"] = strconv.Itoa(len(response.TrieNodes.Stem) + len(response.TrieNodes.Head) + len(response.TrieNodes.Slice))
response.MetaData.NodeStats["03-leaves"] = strconv.Itoa(len(leafNodes))
response.MetaData.NodeStats["04-smart-contracts"] = "" // TODO: count # of contracts
response.MetaData.NodeStats["04-smart-contracts"] = strconv.Itoa(contractCount)
response.MetaData.NodeStats["00-stem-and-head-nodes"] = strconv.Itoa(len(response.TrieNodes.Stem) + len(response.TrieNodes.Head))
return response, nil
@ -1102,6 +1131,32 @@ func (b *Backend) getStateNodesByPathsAndBlockNumber(tx *sqlx.Tx, paths [][]byte
return nodes, leafCIDs, deepestPath, strconv.Itoa(int(makeTimestamp() - fetchStart)), nil
}
func (b *Backend) getAccountByStateCID(tx *sqlx.Tx, cid string, blockHeight uint64) (string, string, []byte, error) {
var err error
var res struct {
StateLeafKey string `db:"state_leaf_key"`
StorageRoot string `db:"storage_root"`
CodeHash []byte `db:"code_hash"`
}
if err = tx.Get(&res, RetrieveAccountByStateCID, cid, blockHeight); err != nil {
return "", "", nil, err
}
mhKey, err := ethServerShared.MultihashKeyFromKeccak256(common.BytesToHash(res.CodeHash))
if err != nil {
return "", "", nil, err
}
code := make([]byte, 0)
err = tx.Get(&code, RetrieveCodeByMhKey, mhKey)
if err != nil {
return "", "", nil, err
}
return res.StateLeafKey, res.StorageRoot, code, nil
}
func (b *Backend) getStorageNodesByStateLeafKeyAndPathsAndBlockNumber(tx *sqlx.Tx, stateLeafKey string, paths [][]byte, blockHeight uint64) (map[string]string, []cid.Cid, int, string, error) {
nodes := make(map[string]string)
fetchStart := makeTimestamp()

View File

@ -271,7 +271,7 @@ type GetSliceResponse struct {
SliceID string `json:"sliceId"`
MetaData GetSliceResponseMetadata `json:"metadata"`
TrieNodes GetSliceResponseTrieNodes `json:"trieNodes"`
Leaves map[string]GetSliceResponseAccount `json:"leaves"` // we won't be using addresses, but keccak256(address) // TODO: address comment
Leaves map[string]GetSliceResponseAccount `json:"leaves"` // key: Keccak256Hash(address) in hex (leafKey)
}
func (sr *GetSliceResponse) init(path string, depth int, root common.Hash) {
@ -294,7 +294,7 @@ type GetSliceResponseMetadata struct {
}
type GetSliceResponseTrieNodes struct {
Stem map[string]string `json:"stem"`
Stem map[string]string `json:"stem"` // key: Keccak256Hash(data) in hex, value: trie node data in hex
Head map[string]string `json:"head"`
Slice map[string]string `json:"sliceNodes"`
}