Skip to content

Commit ab8f6cb

Browse files
committed
API GetReceiptProof
1 parent 3643104 commit ab8f6cb

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

internal/ethapi/api.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/XinFinOrg/XDC-Subnet/XDCxlending/lendingstate"
3030
"github.com/XinFinOrg/XDC-Subnet/consensus"
31+
"github.com/XinFinOrg/XDC-Subnet/trie"
3132

3233
"github.com/XinFinOrg/XDC-Subnet/XDCx/tradingstate"
3334

@@ -534,6 +535,64 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
534535
return b, state.Error()
535536
}
536537

538+
// proofPairList implements ethdb.KeyValueWriter and collects the proofs as
539+
// hex-strings of key and value for delivery to rpc-caller.
540+
type proofPairList struct {
541+
keys []string
542+
values []string
543+
}
544+
545+
func (n *proofPairList) Put(key []byte, value []byte) error {
546+
n.keys = append(n.keys, hexutil.Encode(key))
547+
n.values = append(n.values, hexutil.Encode(value))
548+
return nil
549+
}
550+
551+
func (n *proofPairList) Delete(key []byte) error {
552+
panic("not supported")
553+
}
554+
555+
// modified from core/types/derive_sha.go
556+
func deriveTrie(list types.DerivableList) *trie.Trie {
557+
keybuf := new(bytes.Buffer)
558+
trie := new(trie.Trie)
559+
for i := 0; i < list.Len(); i++ {
560+
keybuf.Reset()
561+
rlp.Encode(keybuf, uint(i))
562+
trie.Update(keybuf.Bytes(), list.GetRlp(i))
563+
}
564+
return trie
565+
}
566+
567+
// GetReceiptProof returns the Trie proof of the receipt for a given transaction.
568+
func (s *PublicBlockChainAPI) GetReceiptProof(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
569+
tx, blockHash, _, index := core.GetTransaction(s.b.ChainDb(), hash)
570+
if tx == nil {
571+
return nil, nil
572+
}
573+
receipts, err := s.b.GetReceipts(ctx, blockHash)
574+
if err != nil {
575+
return nil, err
576+
}
577+
if len(receipts) <= int(index) {
578+
return nil, nil
579+
}
580+
tr := deriveTrie(receipts)
581+
var proof proofPairList
582+
keybuf := new(bytes.Buffer)
583+
rlp.Encode(keybuf, uint(index))
584+
if err := tr.Prove(keybuf.Bytes(), 0, &proof); err != nil {
585+
return nil, err
586+
}
587+
fields := map[string]interface{}{
588+
"keys": proof.keys,
589+
"values": proof.values,
590+
"index": index,
591+
"leafValue": receipts.GetRlp(int(index)),
592+
}
593+
return fields, nil
594+
}
595+
537596
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
538597
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
539598
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {

0 commit comments

Comments
 (0)