Skip to content

Commit

Permalink
trie: remove parameter 'fromLevel' in Prove (ethereum#27512)
Browse files Browse the repository at this point in the history
This removes the feature where top nodes of the proof can be elided.
It was intended to be used by the LES server, to save bandwidth 
when the client had already fetched parts of the state and only needed
some extra nodes to complete the proof. Alas, it never got implemented
in the client.
  • Loading branch information
rjl493456442 authored Jun 19, 2023
1 parent 091c25d commit ceca457
Show file tree
Hide file tree
Showing 16 changed files with 87 additions and 91 deletions.
2 changes: 1 addition & 1 deletion core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ type Trie interface {
// 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), ending
// with the node that proves the absence of the key.
Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error
Prove(key []byte, proofDb ethdb.KeyValueWriter) error
}

// NewDatabase creates a backing store for state. The returned database is safe for
Expand Down
4 changes: 2 additions & 2 deletions core/state/snapshot/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ func (dl *diskLayer) proveRange(ctx *generatorContext, trieId *trie.ID, prefix [
if origin == nil {
origin = common.Hash{}.Bytes()
}
if err := tr.Prove(origin, 0, proof); err != nil {
if err := tr.Prove(origin, proof); err != nil {
log.Debug("Failed to prove range", "kind", kind, "origin", origin, "err", err)
return &proofResult{
keys: keys,
Expand All @@ -267,7 +267,7 @@ func (dl *diskLayer) proveRange(ctx *generatorContext, trieId *trie.ID, prefix [
}, nil
}
if last != nil {
if err := tr.Prove(last, 0, proof); err != nil {
if err := tr.Prove(last, proof); err != nil {
log.Debug("Failed to prove range", "kind", kind, "last", last, "err", err)
return &proofResult{
keys: keys,
Expand Down
4 changes: 2 additions & 2 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ func (s *StateDB) GetProof(addr common.Address) ([][]byte, error) {
// GetProofByHash returns the Merkle proof for a given account.
func (s *StateDB) GetProofByHash(addrHash common.Hash) ([][]byte, error) {
var proof proofList
err := s.trie.Prove(addrHash[:], 0, &proof)
err := s.trie.Prove(addrHash[:], &proof)
return proof, err
}

Expand All @@ -346,7 +346,7 @@ func (s *StateDB) GetStorageProof(a common.Address, key common.Hash) ([][]byte,
return nil, errors.New("storage trie for requested address does not exist")
}
var proof proofList
err = trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
err = trie.Prove(crypto.Keccak256(key.Bytes()), &proof)
if err != nil {
return nil, err
}
Expand Down
8 changes: 4 additions & 4 deletions eth/protocols/snap/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,12 @@ func ServiceGetAccountRangeQuery(chain *core.BlockChain, req *GetAccountRangePac

// Generate the Merkle proofs for the first and last account
proof := light.NewNodeSet()
if err := tr.Prove(req.Origin[:], 0, proof); err != nil {
if err := tr.Prove(req.Origin[:], proof); err != nil {
log.Warn("Failed to prove account range", "origin", req.Origin, "err", err)
return nil, nil
}
if last != (common.Hash{}) {
if err := tr.Prove(last[:], 0, proof); err != nil {
if err := tr.Prove(last[:], proof); err != nil {
log.Warn("Failed to prove account range", "last", last, "err", err)
return nil, nil
}
Expand Down Expand Up @@ -428,12 +428,12 @@ func ServiceGetStorageRangesQuery(chain *core.BlockChain, req *GetStorageRangesP
return nil, nil
}
proof := light.NewNodeSet()
if err := stTrie.Prove(origin[:], 0, proof); err != nil {
if err := stTrie.Prove(origin[:], proof); err != nil {
log.Warn("Failed to prove storage range", "origin", req.Origin, "err", err)
return nil, nil
}
if last != (common.Hash{}) {
if err := stTrie.Prove(last[:], 0, proof); err != nil {
if err := stTrie.Prove(last[:], proof); err != nil {
log.Warn("Failed to prove storage range", "last", last, "err", err)
return nil, nil
}
Expand Down
16 changes: 8 additions & 8 deletions eth/protocols/snap/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,12 @@ func createAccountRequestResponse(t *testPeer, root common.Hash, origin common.H
// Actually, we need to supply proofs either way! This seems to be an implementation
// quirk in go-ethereum
proof := light.NewNodeSet()
if err := t.accountTrie.Prove(origin[:], 0, proof); err != nil {
if err := t.accountTrie.Prove(origin[:], proof); err != nil {
t.logger.Error("Could not prove inexistence of origin", "origin", origin, "error", err)
}
if len(keys) > 0 {
lastK := (keys[len(keys)-1])[:]
if err := t.accountTrie.Prove(lastK, 0, proof); err != nil {
if err := t.accountTrie.Prove(lastK, proof); err != nil {
t.logger.Error("Could not prove last item", "error", err)
}
}
Expand Down Expand Up @@ -358,12 +358,12 @@ func createStorageRequestResponse(t *testPeer, root common.Hash, accounts []comm
// Here's a potential gotcha: when constructing the proof, we cannot
// use the 'origin' slice directly, but must use the full 32-byte
// hash form.
if err := stTrie.Prove(originHash[:], 0, proof); err != nil {
if err := stTrie.Prove(originHash[:], proof); err != nil {
t.logger.Error("Could not prove inexistence of origin", "origin", originHash, "error", err)
}
if len(keys) > 0 {
lastK := (keys[len(keys)-1])[:]
if err := stTrie.Prove(lastK, 0, proof); err != nil {
if err := stTrie.Prove(lastK, proof); err != nil {
t.logger.Error("Could not prove last item", "error", err)
}
}
Expand Down Expand Up @@ -416,13 +416,13 @@ func createStorageRequestResponseAlwaysProve(t *testPeer, root common.Hash, acco
// Here's a potential gotcha: when constructing the proof, we cannot
// use the 'origin' slice directly, but must use the full 32-byte
// hash form.
if err := stTrie.Prove(origin[:], 0, proof); err != nil {
if err := stTrie.Prove(origin[:], proof); err != nil {
t.logger.Error("Could not prove inexistence of origin", "origin", origin,
"error", err)
}
if len(keys) > 0 {
lastK := (keys[len(keys)-1])[:]
if err := stTrie.Prove(lastK, 0, proof); err != nil {
if err := stTrie.Prove(lastK, proof); err != nil {
t.logger.Error("Could not prove last item", "error", err)
}
}
Expand Down Expand Up @@ -594,12 +594,12 @@ func TestSyncBloatedProof(t *testing.T) {
}
// The proofs
proof := light.NewNodeSet()
if err := t.accountTrie.Prove(origin[:], 0, proof); err != nil {
if err := t.accountTrie.Prove(origin[:], proof); err != nil {
t.logger.Error("Could not prove origin", "origin", origin, "error", err)
}
// The bloat: add proof of every single element
for _, entry := range t.accountValues {
if err := t.accountTrie.Prove(entry.k, 0, proof); err != nil {
if err := t.accountTrie.Prove(entry.k, proof); err != nil {
t.logger.Error("Could not prove item", "error", err)
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ func (s *BlockChainAPI) GetProof(ctx context.Context, address common.Address, st
continue
}
var proof proofList
if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof); err != nil {
if err := storageTrie.Prove(crypto.Keccak256(key.Bytes()), &proof); err != nil {
return nil, err
}
storageProof[i] = StorageResult{storageKeys[i],
Expand Down
8 changes: 4 additions & 4 deletions les/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ func testGetProofs(t *testing.T, protocol int) {
Key: crypto.Keccak256(acc[:]),
}
proofreqs = append(proofreqs, req)
trie.Prove(crypto.Keccak256(acc[:]), 0, proofsV2)
trie.Prove(crypto.Keccak256(acc[:]), proofsV2)
}
}
// Send the proof request and verify the response
Expand Down Expand Up @@ -458,7 +458,7 @@ func testGetStaleProof(t *testing.T, protocol int) {
if wantOK {
proofsV2 := light.NewNodeSet()
t, _ := trie.New(trie.StateTrieID(header.Root), trie.NewDatabase(server.db))
t.Prove(account, 0, proofsV2)
t.Prove(account, proofsV2)
expected = proofsV2.NodeList()
}
if err := expectResponse(rawPeer.app, ProofsV2Msg, 42, testBufLimit, expected); err != nil {
Expand Down Expand Up @@ -514,7 +514,7 @@ func testGetCHTProofs(t *testing.T, protocol int) {
}
root := light.GetChtRoot(server.db, 0, bc.GetHeaderByNumber(config.ChtSize-1).Hash())
trie, _ := trie.New(trie.TrieID(root), trie.NewDatabase(rawdb.NewTable(server.db, string(rawdb.ChtTablePrefix))))
trie.Prove(key, 0, &proofsV2.Proofs)
trie.Prove(key, &proofsV2.Proofs)
// Assemble the requests for the different protocols
requestsV2 := []HelperTrieReq{{
Type: htCanonical,
Expand Down Expand Up @@ -579,7 +579,7 @@ func testGetBloombitsProofs(t *testing.T, protocol int) {

root := light.GetBloomTrieRoot(server.db, 0, bc.GetHeaderByNumber(config.BloomTrieSize-1).Hash())
trie, _ := trie.New(trie.TrieID(root), trie.NewDatabase(rawdb.NewTable(server.db, string(rawdb.BloomTrieTablePrefix))))
trie.Prove(key, 0, &proofs.Proofs)
trie.Prove(key, &proofs.Proofs)

// Send the proof request and verify the response
sendRequest(rawPeer.app, GetHelperTrieProofsMsg, 42, requests)
Expand Down
4 changes: 2 additions & 2 deletions les/server_requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ func handleGetProofs(msg Decoder) (serveRequestFn, uint64, uint64, error) {
}
}
// Prove the user's request from the account or storage trie
if err := trie.Prove(request.Key, request.FromLevel, nodes); err != nil {
if err := trie.Prove(request.Key, nodes); err != nil {
p.Log().Warn("Failed to prove state request", "block", header.Number, "hash", header.Hash(), "err", err)
continue
}
Expand Down Expand Up @@ -480,7 +480,7 @@ func handleGetHelperTrieProofs(msg Decoder) (serveRequestFn, uint64, uint64, err
// the headers with no valid proof. Keep the compatibility for
// legacy les protocol and drop this hack when the les2/3 are
// not supported.
err := auxTrie.Prove(request.Key, request.FromLevel, nodes)
err := auxTrie.Prove(request.Key, nodes)
if p.version >= lpv4 && err != nil {
return nil
}
Expand Down
2 changes: 1 addition & 1 deletion light/odr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func (odr *testOdr) Retrieve(ctx context.Context, req OdrRequest) error {
panic(err)
}
nodes := NewNodeSet()
t.Prove(req.Key, 0, nodes)
t.Prove(req.Key, nodes)
req.Proof = nodes
case *CodeRequest:
req.Data = rawdb.ReadCode(odr.sdb, req.Hash)
Expand Down
2 changes: 1 addition & 1 deletion light/trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ func (t *odrTrie) GetKey(sha []byte) []byte {
return nil
}

func (t *odrTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error {
func (t *odrTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
return errors.New("not implemented, needs client/server interface split")
}

Expand Down
4 changes: 2 additions & 2 deletions tests/fuzzers/rangeproof/rangeproof-fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,10 @@ func (f *fuzzer) fuzz() int {
break
}
proof := memorydb.New()
if err := tr.Prove(entries[start].k, 0, proof); err != nil {
if err := tr.Prove(entries[start].k, proof); err != nil {
panic(fmt.Sprintf("Failed to prove the first node %v", err))
}
if err := tr.Prove(entries[end-1].k, 0, proof); err != nil {
if err := tr.Prove(entries[end-1].k, proof); err != nil {
panic(fmt.Sprintf("Failed to prove the last node %v", err))
}
var keys [][]byte
Expand Down
2 changes: 1 addition & 1 deletion tests/fuzzers/trie/trie-fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func runRandTest(rt randTest) error {
return errors.New("hash mismatch in opItercheckhash")
}
case opProve:
rt[i].err = tr.Prove(step.key, 0, proofDb{})
rt[i].err = tr.Prove(step.key, proofDb{})
}
// Abort the test on error.
if rt[i].err != nil {
Expand Down
10 changes: 3 additions & 7 deletions trie/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import (
// 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.KeyValueWriter) error {
func (t *Trie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
// Collect all nodes on the path to key.
var (
prefix []byte
Expand Down Expand Up @@ -81,10 +81,6 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) e
defer returnHasherToPool(hasher)

for i, n := range nodes {
if fromLevel > 0 {
fromLevel--
continue
}
var hn node
n, hn = hasher.proofHash(n)
if hash, ok := hn.(hashNode); ok || i == 0 {
Expand All @@ -107,8 +103,8 @@ func (t *Trie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) e
// 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 *StateTrie) Prove(key []byte, fromLevel uint, proofDb ethdb.KeyValueWriter) error {
return t.trie.Prove(key, fromLevel, proofDb)
func (t *StateTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error {
return t.trie.Prove(key, proofDb)
}

// VerifyProof checks merkle proofs. The given proof must contain the value for
Expand Down
Loading

0 comments on commit ceca457

Please sign in to comment.