github.com/ethereum/go-ethereum@v1.16.1/core/stateless/database.go (about)

     1  // Copyright 2024 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package stateless
    18  
    19  import (
    20  	"github.com/ethereum/go-ethereum/common"
    21  	"github.com/ethereum/go-ethereum/core/rawdb"
    22  	"github.com/ethereum/go-ethereum/crypto"
    23  	"github.com/ethereum/go-ethereum/ethdb"
    24  )
    25  
    26  // MakeHashDB imports tries, codes and block hashes from a witness into a new
    27  // hash-based memory db. We could eventually rewrite this into a pathdb, but
    28  // simple is better for now.
    29  //
    30  // Note, this hashdb approach is quite strictly self-validating:
    31  //   - Headers are persisted keyed by hash, so blockhash will error on junk
    32  //   - Codes are persisted keyed by hash, so bytecode lookup will error on junk
    33  //   - Trie nodes are persisted keyed by hash, so trie expansion will error on junk
    34  //
    35  // Acceleration structures built would need to explicitly validate the witness.
    36  func (w *Witness) MakeHashDB() ethdb.Database {
    37  	var (
    38  		memdb  = rawdb.NewMemoryDatabase()
    39  		hasher = crypto.NewKeccakState()
    40  		hash   = make([]byte, 32)
    41  	)
    42  	// Inject all the "block hashes" (i.e. headers) into the ephemeral database
    43  	for _, header := range w.Headers {
    44  		rawdb.WriteHeader(memdb, header)
    45  	}
    46  	// Inject all the bytecodes into the ephemeral database
    47  	for code := range w.Codes {
    48  		blob := []byte(code)
    49  
    50  		hasher.Reset()
    51  		hasher.Write(blob)
    52  		hasher.Read(hash)
    53  
    54  		rawdb.WriteCode(memdb, common.BytesToHash(hash), blob)
    55  	}
    56  	// Inject all the MPT trie nodes into the ephemeral database
    57  	for node := range w.State {
    58  		blob := []byte(node)
    59  
    60  		hasher.Reset()
    61  		hasher.Write(blob)
    62  		hasher.Read(hash)
    63  
    64  		rawdb.WriteLegacyTrieNode(memdb, common.BytesToHash(hash), blob)
    65  	}
    66  	return memdb
    67  }