github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/core/state/state_prove.go (about)

     1  package state
     2  
     3  import (
     4  	"fmt"
     5  
     6  	zkt "github.com/scroll-tech/zktrie/types"
     7  
     8  	zktrie "github.com/scroll-tech/go-ethereum/trie"
     9  
    10  	"github.com/scroll-tech/go-ethereum/common"
    11  	"github.com/scroll-tech/go-ethereum/crypto"
    12  	"github.com/scroll-tech/go-ethereum/ethdb"
    13  )
    14  
    15  type TrieProve interface {
    16  	Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error
    17  }
    18  
    19  type ZktrieProofTracer struct {
    20  	*zktrie.ProofTracer
    21  }
    22  
    23  // MarkDeletion overwrite the underlayer method with secure key
    24  func (t ZktrieProofTracer) MarkDeletion(key common.Hash) {
    25  	key_s, _ := zkt.ToSecureKeyBytes(key.Bytes())
    26  	t.ProofTracer.MarkDeletion(key_s.Bytes())
    27  }
    28  
    29  // Merge overwrite underlayer method with proper argument
    30  func (t ZktrieProofTracer) Merge(another ZktrieProofTracer) {
    31  	t.ProofTracer.Merge(another.ProofTracer)
    32  }
    33  
    34  func (t ZktrieProofTracer) Available() bool {
    35  	return t.ProofTracer != nil
    36  }
    37  
    38  // NewProofTracer is not in Db interface and used explictily for reading proof in storage trie (not updated by the dirty value)
    39  func (s *StateDB) NewProofTracer(trieS Trie) ZktrieProofTracer {
    40  	if s.IsZktrie() {
    41  		zkTrie := trieS.(*zktrie.ZkTrie)
    42  		if zkTrie == nil {
    43  			panic("unexpected trie type for zktrie")
    44  		}
    45  		return ZktrieProofTracer{zkTrie.NewProofTracer()}
    46  	}
    47  	return ZktrieProofTracer{}
    48  }
    49  
    50  // GetStorageTrieForProof is not in Db interface and used explictily for reading proof in storage trie (not updated by the dirty value)
    51  func (s *StateDB) GetStorageTrieForProof(addr common.Address) (Trie, error) {
    52  
    53  	// try the trie in stateObject first, else we would create one
    54  	stateObject := s.getStateObject(addr)
    55  	if stateObject == nil {
    56  		// still return a empty trie
    57  		addrHash := crypto.Keccak256Hash(addr[:])
    58  		dummy_trie, _ := s.db.OpenStorageTrie(addrHash, common.Hash{})
    59  		return dummy_trie, nil
    60  	}
    61  
    62  	trie := stateObject.trie
    63  	var err error
    64  	if trie == nil {
    65  		// use a new, temporary trie
    66  		trie, err = s.db.OpenStorageTrie(stateObject.addrHash, stateObject.data.Root)
    67  		if err != nil {
    68  			return nil, fmt.Errorf("can't create storage trie on root %s: %v ", stateObject.data.Root, err)
    69  		}
    70  	}
    71  
    72  	return trie, nil
    73  }
    74  
    75  // GetSecureTrieProof handle any interface with Prove (should be a Trie in most case) and
    76  // deliver the proof in bytes
    77  func (s *StateDB) GetSecureTrieProof(trieProve TrieProve, key common.Hash) ([][]byte, error) {
    78  
    79  	var proof proofList
    80  	var err error
    81  	if s.IsZktrie() {
    82  		key_s, _ := zkt.ToSecureKeyBytes(key.Bytes())
    83  		err = trieProve.Prove(key_s.Bytes(), 0, &proof)
    84  	} else {
    85  		err = trieProve.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
    86  	}
    87  	return proof, err
    88  }