@@ -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.
539598func (s * PublicBlockChainAPI ) GetBlockByNumber (ctx context.Context , blockNr rpc.BlockNumber , fullTx bool ) (map [string ]interface {}, error ) {
0 commit comments