core, trie: intermediate mempool between trie and database (#15857)
This commit reduces database I/O by not writing every state trie to disk.
This commit is contained in:
committed by
Felix Lange
parent
59336283c0
commit
55599ee95d
@ -22,20 +22,19 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
)
|
||||
|
||||
// Prove constructs a merkle proof for key. The result contains all
|
||||
// encoded nodes on the path to the value at key. The value itself is
|
||||
// also included in the last node and can be retrieved by verifying
|
||||
// the proof.
|
||||
// Prove constructs a merkle proof for key. The result contains all encoded nodes
|
||||
// on the path to the value at key. The value itself is also included in the last
|
||||
// node and can be retrieved by verifying the proof.
|
||||
//
|
||||
// If the trie does not contain a value for key, the returned proof
|
||||
// contains all nodes of the longest existing prefix of the key
|
||||
// (at least the root node), ending with the node that proves the
|
||||
// absence of the key.
|
||||
func (t *Trie) Prove(key []byte, fromLevel uint, proofDb DatabaseWriter) error {
|
||||
// If the trie does not contain a value for key, the returned proof contains all
|
||||
// nodes of the longest existing prefix of the key (at least the root node), ending
|
||||
// with the node that proves the absence of the key.
|
||||
func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
|
||||
// Collect all nodes on the path to key.
|
||||
key = keybytesToHex(key)
|
||||
nodes := []node{}
|
||||
@ -66,7 +65,7 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb DatabaseWriter) error {
|
||||
panic(fmt.Sprintf("%T: invalid node: %v", tn, tn))
|
||||
}
|
||||
}
|
||||
hasher := newHasher(0, 0)
|
||||
hasher := newHasher(0, 0, nil)
|
||||
for i, n := range nodes {
|
||||
// Don't bother checking for errors here since hasher panics
|
||||
// if encoding doesn't work and we're not writing to any database.
|
||||
@ -89,19 +88,29 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb DatabaseWriter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// VerifyProof checks merkle proofs. The given proof must contain the
|
||||
// value for key in a trie with the given root hash. VerifyProof
|
||||
// returns an error if the proof contains invalid trie nodes or the
|
||||
// wrong value.
|
||||
// Prove constructs a merkle proof for key. The result contains all encoded nodes
|
||||
// on the path to the value at key. The value itself is also included in the last
|
||||
// node and can be retrieved by verifying the proof.
|
||||
//
|
||||
// If the trie does not contain a value for key, the returned proof contains all
|
||||
// nodes of the longest existing prefix of the key (at least the root node), ending
|
||||
// with the node that proves the absence of the key.
|
||||
func (t *SecureTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.Putter) error {
|
||||
return t.trie.Prove(key, fromLevel, proofDb)
|
||||
}
|
||||
|
||||
// VerifyProof checks merkle proofs. The given proof must contain the value for
|
||||
// key in a trie with the given root hash. VerifyProof returns an error if the
|
||||
// proof contains invalid trie nodes or the wrong value.
|
||||
func VerifyProof(rootHash common.Hash, key []byte, proofDb DatabaseReader) (value []byte, err error, nodes int) {
|
||||
key = keybytesToHex(key)
|
||||
wantHash := rootHash[:]
|
||||
wantHash := rootHash
|
||||
for i := 0; ; i++ {
|
||||
buf, _ := proofDb.Get(wantHash)
|
||||
buf, _ := proofDb.Get(wantHash[:])
|
||||
if buf == nil {
|
||||
return nil, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash[:]), i
|
||||
return nil, fmt.Errorf("proof node %d (hash %064x) missing", i, wantHash), i
|
||||
}
|
||||
n, err := decodeNode(wantHash, buf, 0)
|
||||
n, err := decodeNode(wantHash[:], buf, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("bad proof node %d: %v", i, err), i
|
||||
}
|
||||
@ -112,7 +121,7 @@ func VerifyProof(rootHash common.Hash, key []byte, proofDb DatabaseReader) (valu
|
||||
return nil, nil, i
|
||||
case hashNode:
|
||||
key = keyrest
|
||||
wantHash = cld
|
||||
copy(wantHash[:], cld)
|
||||
case valueNode:
|
||||
return cld, nil, i + 1
|
||||
}
|
||||
|
Reference in New Issue
Block a user