Bor proof findpath (#8764)

Added trie findpath to support bor receipt format.

This requires testing against the polygon deployed contracts to confirm
parent path format
This commit is contained in:
Mark Holt 2023-11-17 19:39:59 +03:00 committed by GitHub
parent d4cd712da0
commit de60e03f03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 7 deletions

View File

@ -244,7 +244,7 @@ func (pg *ProofGenerator) buildPayloadForExit(ctx context.Context, burnTxHash li
[]interface{}{
rootBlockNumber,
hexutility.Encode(bytes.Join(blockProofs, []byte{})),
txBlockNum,
block.Number.Uint64(),
block.Time,
hexutility.Encode(block.TxHash[:]),
hexutility.Encode(block.ReceiptHash[:]),
@ -309,7 +309,7 @@ func getReceiptProof(ctx context.Context, node requests.RequestGenerator, receip
}
path, _ := rlp.EncodeToBytes(receipt.TransactionIndex)
result, ok := receiptsTrie.Get(path)
result, parents, ok := receiptsTrie.FindPath(path)
if !ok {
return nil, fmt.Errorf("node does not contain the key")
@ -325,7 +325,7 @@ func getReceiptProof(ctx context.Context, node requests.RequestGenerator, receip
return &receiptProof{
blockHash: receipt.BlockHash,
parentNodes: nil, //TODO - not sure how to get this result.stack.map(s => s.raw()),
parentNodes: parents,
root: block.ReceiptHash[:],
path: path,
value: nodeValue,

View File

@ -14,6 +14,7 @@ import (
"github.com/ledgerwatch/erigon-lib/chain"
"github.com/ledgerwatch/erigon-lib/common"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/hexutility"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/accounts/abi/bind"
@ -340,7 +341,7 @@ func TestBlockProof(t *testing.T) {
}
func TestReceiptProof(t *testing.T) {
sentry, chain, err := generateBlocks(t, 1)
sentry, chain, err := generateBlocks(t, 10)
if err != nil {
t.Fatal(err)
@ -374,14 +375,19 @@ func TestReceiptProof(t *testing.T) {
t.Fatal(err)
}
//TODO the receiptProof needs parents formatted from trie - need to confirm format for that
_ /*receiptProof*/, err = getReceiptProof(context.Background(), rg, receipt, block, nil)
receiptProof, err := getReceiptProof(context.Background(), rg, receipt, block, nil)
if err != nil {
t.Fatal(err)
}
//fmt.Println(receiptProof)
parentNodesBytes, err := rlp.EncodeToBytes(receiptProof.parentNodes)
if err != nil {
t.Fatal(err)
}
fmt.Println(hexutility.Encode(parentNodesBytes), hexutility.Encode(append([]byte{0}, receiptProof.path...)))
}
func generateBlocks(t *testing.T, number int) (*mock.MockSentry, *core.ChainPack, error) {

View File

@ -94,6 +94,15 @@ func (t *Trie) Get(key []byte) (value []byte, gotValue bool) {
return t.get(t.root, hex, 0)
}
func (t *Trie) FindPath(key []byte) (value []byte, parents [][]byte, gotValue bool) {
if t.root == nil {
return nil, nil, true
}
hex := keybytesToHex(key)
return t.getPath(t.root, nil, hex, 0)
}
func (t *Trie) GetAccount(key []byte) (value *accounts.Account, gotValue bool) {
if t.root == nil {
return nil, true
@ -233,6 +242,46 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, gotValue b
}
}
func (t *Trie) getPath(origNode node, parents [][]byte, key []byte, pos int) ([]byte, [][]byte, bool) {
switch n := (origNode).(type) {
case nil:
return nil, parents, true
case valueNode:
return n, parents, true
case *accountNode:
return t.getPath(n.storage, append(parents, n.reference()), key, pos)
case *shortNode:
matchlen := prefixLen(key[pos:], n.Key)
if matchlen == len(n.Key) || n.Key[matchlen] == 16 {
return t.getPath(n.Val, append(parents, n.reference()), key, pos+matchlen)
} else {
return nil, parents, true
}
case *duoNode:
i1, i2 := n.childrenIdx()
switch key[pos] {
case i1:
return t.getPath(n.child1, append(parents, n.reference()), key, pos+1)
case i2:
return t.getPath(n.child2, append(parents, n.reference()), key, pos+1)
default:
return nil, parents, true
}
case *fullNode:
child := n.Children[key[pos]]
if child == nil {
return nil, parents, true
}
return t.getPath(child, append(parents, n.reference()), key, pos+1)
case hashNode:
return n.hash, parents, false
default:
panic(fmt.Sprintf("%T: invalid node: %v", origNode, origNode))
}
}
// Update associates key with value in the trie. Subsequent calls to
// Get will return value. If value has length zero, any existing value
// is deleted from the trie and calls to Get will return nil.