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 }