Get storage API, with storage leaf CID and raw IPLD block.

This commit is contained in:
Ashwin Phatak 2021-05-26 17:07:25 +05:30 committed by Arijit Das
parent b90fcb53e6
commit a284a566d5
4 changed files with 59 additions and 13 deletions

View File

@ -767,7 +767,7 @@ func (b *Backend) GetStorageByHash(ctx context.Context, address common.Address,
return nil, err
}
_, storageRlp, err := b.IPLDRetriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address, key, hash)
_, _, storageRlp, err := b.IPLDRetriever.RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address, key, hash)
return storageRlp, err
}

View File

@ -29,15 +29,15 @@ import (
const (
RetrieveHeadersByHashesPgStr = `SELECT cid, data
FROM eth.header_cids
FROM eth.header_cids
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
WHERE block_hash = ANY($1::VARCHAR(66)[])`
RetrieveHeadersByBlockNumberPgStr = `SELECT cid, data
FROM eth.header_cids
FROM eth.header_cids
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
WHERE block_number = $1`
RetrieveHeaderByHashPgStr = `SELECT cid, data
FROM eth.header_cids
FROM eth.header_cids
INNER JOIN public.blocks ON (header_cids.mh_key = blocks.key)
WHERE block_hash = $1`
RetrieveUnclesByHashesPgStr = `SELECT cid, data
@ -429,25 +429,25 @@ func (r *IPLDRetriever) RetrieveAccountByAddressAndBlockNumber(address common.Ad
}
// RetrieveStorageAtByAddressAndStorageSlotAndBlockHash returns the cid and rlp bytes for the storage value corresponding to the provided address, storage slot, and block hash
func (r *IPLDRetriever) RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address common.Address, key, hash common.Hash) (string, []byte, error) {
func (r *IPLDRetriever) RetrieveStorageAtByAddressAndStorageSlotAndBlockHash(address common.Address, key, hash common.Hash) (string, []byte, []byte, error) {
storageResult := new(nodeInfo)
stateLeafKey := crypto.Keccak256Hash(address.Bytes())
storageHash := crypto.Keccak256Hash(key.Bytes())
if err := r.db.Get(storageResult, RetrieveStorageLeafByAddressHashAndLeafKeyAndBlockHashPgStr, stateLeafKey.Hex(), storageHash.Hex(), hash.Hex()); err != nil {
return "", nil, err
return "", nil, nil, err
}
if storageResult.Removed {
return "", []byte{}, nil
return "", []byte{}, []byte{}, nil
}
var i []interface{}
if err := rlp.DecodeBytes(storageResult.Data, &i); err != nil {
err = fmt.Errorf("error decoding storage leaf node rlp: %s", err.Error())
return "", nil, err
return "", nil, nil, err
}
if len(i) != 2 {
return "", nil, fmt.Errorf("eth IPLDRetriever expected storage leaf node rlp to decode into two elements")
return "", nil, nil, fmt.Errorf("eth IPLDRetriever expected storage leaf node rlp to decode into two elements")
}
return storageResult.CID, i[1].([]byte), nil
return storageResult.CID, storageResult.Data, i[1].([]byte), nil
}
// RetrieveStorageAtByAddressAndStorageKeyAndBlockNumber returns the cid and rlp bytes for the storage value corresponding to the provided address, storage key, and block number

View File

@ -956,12 +956,47 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria
return runFilter(ctx, r.backend, filter)
}
// StorageResult represents a storage slot value. All arguments are mandatory.
type StorageResult struct {
value []byte
cid string
ipldBlock []byte
}
func (s *StorageResult) Value(ctx context.Context) common.Hash {
return common.BytesToHash(s.value)
}
func (s *StorageResult) Cid(ctx context.Context) string {
return s.cid
}
func (s *StorageResult) IpldBlock(ctx context.Context) hexutil.Bytes {
return hexutil.Bytes(s.ipldBlock)
}
func (r *Resolver) GetStorageAt(ctx context.Context, args struct {
BlockHash common.Hash
Contract common.Address
Slot common.Hash
}) (*common.Hash, error) {
ret := common.BytesToHash([]byte{})
}) (*StorageResult, error) {
cid, ipldBlock, rlpValue, err := r.backend.IPLDRetriever.RetrieveStorageAtByAddressAndStorageKeyAndBlockHash(args.Contract, args.Slot, args.BlockHash)
if err != nil {
return nil, err
}
var value interface{}
err = rlp.DecodeBytes(rlpValue, &value)
if err != nil {
return nil, err
}
if err != nil {
return nil, err
}
ret := StorageResult{value: value.([]byte), cid: cid, ipldBlock: ipldBlock}
return &ret, nil
}

View File

@ -265,6 +265,17 @@ const schema string = `
topics: [[Bytes32!]!]
}
# Storage trie value with IPLD data.
type StorageResult {
value: Bytes32!
# CID for the storage trie IPLD block.
cid: String!
# Storage trie IPLD block.
ipldBlock: Bytes!
}
type Query {
# Block fetches an Ethereum block by number or by hash. If neither is
# supplied, the most recent known block is returned.
@ -281,7 +292,7 @@ const schema string = `
logs(filter: FilterCriteria!): [Log!]!
# Get storage slot by block hash and contract address.
getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): Bytes32
getStorageAt(blockHash: Bytes32!, contract: Address!, slot: Bytes32!): StorageResult
# Get contract logs by block hash and contract address.
getLogs(blockHash: Bytes32!, contract: Address!): [Log!]