Skip to content

Commit

Permalink
API GetReceiptProof test
Browse files Browse the repository at this point in the history
  • Loading branch information
wgr523 committed Sep 27, 2023
1 parent ab8f6cb commit 6f04951
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 34 deletions.
36 changes: 2 additions & 34 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import (

"github.com/XinFinOrg/XDC-Subnet/XDCxlending/lendingstate"
"github.com/XinFinOrg/XDC-Subnet/consensus"
"github.com/XinFinOrg/XDC-Subnet/trie"

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

Expand Down Expand Up @@ -535,35 +534,6 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
return b, state.Error()
}

// proofPairList implements ethdb.KeyValueWriter and collects the proofs as
// hex-strings of key and value for delivery to rpc-caller.
type proofPairList struct {
keys []string
values []string
}

func (n *proofPairList) Put(key []byte, value []byte) error {
n.keys = append(n.keys, hexutil.Encode(key))
n.values = append(n.values, hexutil.Encode(value))
return nil
}

func (n *proofPairList) Delete(key []byte) error {
panic("not supported")
}

// modified from core/types/derive_sha.go
func deriveTrie(list types.DerivableList) *trie.Trie {
keybuf := new(bytes.Buffer)
trie := new(trie.Trie)
for i := 0; i < list.Len(); i++ {
keybuf.Reset()
rlp.Encode(keybuf, uint(i))
trie.Update(keybuf.Bytes(), list.GetRlp(i))
}
return trie
}

// GetReceiptProof returns the Trie proof of the receipt for a given transaction.
func (s *PublicBlockChainAPI) GetReceiptProof(ctx context.Context, hash common.Hash) (map[string]interface{}, error) {
tx, blockHash, _, index := core.GetTransaction(s.b.ChainDb(), hash)
Expand All @@ -585,10 +555,8 @@ func (s *PublicBlockChainAPI) GetReceiptProof(ctx context.Context, hash common.H
return nil, err
}
fields := map[string]interface{}{
"keys": proof.keys,
"values": proof.values,
"index": index,
"leafValue": receipts.GetRlp(int(index)),
"keys": proof.keys,
"values": proof.values,
}
return fields, nil
}
Expand Down
39 changes: 39 additions & 0 deletions internal/ethapi/receipt_proof.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ethapi

import (
"bytes"

"github.com/XinFinOrg/XDC-Subnet/common/hexutil"
"github.com/XinFinOrg/XDC-Subnet/core/types"
"github.com/XinFinOrg/XDC-Subnet/rlp"
"github.com/XinFinOrg/XDC-Subnet/trie"
)

// proofPairList implements ethdb.KeyValueWriter and collects the proofs as
// hex-strings of key and value for delivery to rpc-caller.
type proofPairList struct {
keys []string
values []string
}

func (n *proofPairList) Put(key []byte, value []byte) error {
n.keys = append(n.keys, hexutil.Encode(key))
n.values = append(n.values, hexutil.Encode(value))
return nil
}

func (n *proofPairList) Delete(key []byte) error {
panic("not supported")
}

// modified from core/types/derive_sha.go
func deriveTrie(list types.DerivableList) *trie.Trie {
keybuf := new(bytes.Buffer)
trie := new(trie.Trie)
for i := 0; i < list.Len(); i++ {
keybuf.Reset()
rlp.Encode(keybuf, uint(i))
trie.Update(keybuf.Bytes(), list.GetRlp(i))
}
return trie
}
71 changes: 71 additions & 0 deletions internal/ethapi/receipt_proof_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package ethapi

import (
"bytes"
"fmt"
"reflect"
"testing"

"github.com/XinFinOrg/XDC-Subnet/common/hexutil"
"github.com/XinFinOrg/XDC-Subnet/core/types"
"github.com/XinFinOrg/XDC-Subnet/rlp"
"github.com/XinFinOrg/XDC-Subnet/trie"
)

// implement interface only for testing verifyProof
func (n *proofPairList) Has(key []byte) (bool, error) {
key_hex := hexutil.Encode(key)
for _, k := range n.keys {
if k == key_hex {
return true, nil
}
}
return false, nil
}

func (n *proofPairList) Get(key []byte) ([]byte, error) {
key_hex := hexutil.Encode(key)
for i, k := range n.keys {
if k == key_hex {
b, err := hexutil.Decode(n.values[i])
if err != nil {
return nil, err
}
return b, nil
}
}
return nil, fmt.Errorf("key not found")
}

func TestReceiptProof(t *testing.T) {
root1 := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
root2 := []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
r1 := types.NewReceipt(root1, false, 1)
r2 := types.NewReceipt(root2, true, 2)
r3 := types.NewReceipt(root2, false, 3)
r4 := types.NewReceipt(root1, true, 4)
receipts := types.Receipts([]*types.Receipt{r1, r2, r3, r4})
tr := deriveTrie(receipts)
// for verifying the proof
root := types.DeriveSha(receipts)
for i := 0; i < receipts.Len(); i++ {
var proof proofPairList
keybuf := new(bytes.Buffer)
rlp.Encode(keybuf, uint(i))
if err := tr.Prove(keybuf.Bytes(), 0, &proof); err != nil {
t.Fatal("Prove err:", err)
}
// verify the proof
value, err := trie.VerifyProof(root, keybuf.Bytes(), &proof)
if err != nil {
t.Fatal("verify proof error")
}
encodedReceipt, err := rlp.EncodeToBytes(receipts[i])
if err != nil {
t.Fatal("encode receipt error")
}
if !reflect.DeepEqual(encodedReceipt, value) {
t.Fatal("verify does not return the receipt we want")
}
}
}

0 comments on commit 6f04951

Please sign in to comment.