diff --git a/internal/util.go b/internal/util.go index 59fe5a2..81acff8 100644 --- a/internal/util.go +++ b/internal/util.go @@ -48,7 +48,19 @@ func ReadLegacyTrieNode(db ethdb.KeyValueReader, hash common.Hash, codec uint64) return enc, nil } -func WriteLegacyTrieNode(db ethdb.KeyValueWriter, hash common.Hash, codec uint64, data []byte) error { +// HasLegacyTrieNode checks if the trie node with the provided hash is present in db. +func HasLegacyTrieNode(db ethdb.KeyValueReader, hash common.Hash, codec uint64) bool { + cid, err := Keccak256ToCid(codec, hash[:]) + if err != nil { + return false + } + ok, _ := db.Has(cid.Bytes()) + return ok +} + +func WriteLegacyTrieNode(db ethdb.KeyValueWriter, hash common.Hash, data []byte, codec uint64) error { + // + panic("Writing to the DB is disabled") cid, err := Keccak256ToCid(codec, hash[:]) if err != nil { return err @@ -61,5 +73,5 @@ func ReadCode(db ethdb.KeyValueReader, hash common.Hash) ([]byte, error) { } func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) error { - return WriteLegacyTrieNode(db, hash, ipld.RawBinary, code) + return WriteLegacyTrieNode(db, hash, code, ipld.RawBinary) } diff --git a/trie_by_cid/doc.go b/trie_by_cid/doc.go index 4b9b440..e615661 100644 --- a/trie_by_cid/doc.go +++ b/trie_by_cid/doc.go @@ -1,3 +1,15 @@ // This package is a near complete copy of go-ethereum/trie and go-ethereum/core/state, modified to use // a v0 IPFS blockstore as the backing DB, i.e. DB values are indexed by CID rather than hash. package trie_by_cid + +// Note: This is written so as to minimize the difference from the geth packages to allow easier +// patching during upgrades. +// +// Changes to the original functionality should be marked with (ipld-eth-statedb change) +// The main changes are within the triedb/hashdb package. +// +// Writes are currently disabled and will panic, but they may be useful for testing if possible. +// +// Tests from the original source are preserved as much as reasonably possible. Memory DBs are +// replaced with Postgres connections within the state package, but not the trie packages, since +// they mostly check the structural consistency of the trie. diff --git a/trie_by_cid/state/statedb.go b/trie_by_cid/state/statedb.go index e70f17c..53eed75 100644 --- a/trie_by_cid/state/statedb.go +++ b/trie_by_cid/state/statedb.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" + "github.com/cerc-io/ipld-eth-statedb/internal" "github.com/cerc-io/ipld-eth-statedb/trie_by_cid/trie" "github.com/cerc-io/ipld-eth-statedb/trie_by_cid/trie/trienode" "github.com/cerc-io/ipld-eth-statedb/trie_by_cid/trie/triestate" @@ -1192,7 +1193,8 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er } // Write any contract code associated with the state object if obj.code != nil && obj.dirtyCode { - rawdb.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) + // Writes are currently disabled and this will panic (ipld-eth-statedb change) + internal.WriteCode(codeWriter, common.BytesToHash(obj.CodeHash()), obj.code) obj.dirtyCode = false } // Write any storage changes in the state object to its storage trie diff --git a/trie_by_cid/triedb/database.go b/trie_by_cid/triedb/database.go index fc3a519..1cbc345 100644 --- a/trie_by_cid/triedb/database.go +++ b/trie_by_cid/triedb/database.go @@ -109,7 +109,8 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database { log.Crit("Both 'hash' and 'path' mode are configured") } if config.PathDB != nil { - db.backend = pathdb.New(diskdb, config.PathDB) + // Disable PathDB (ipld-eth-statedb change). TODO: look into implementing it + panic("PathDB is not compatible with ipld-eth-statedb") } else { var resolver hashdb.ChildResolver if config.IsVerkle { diff --git a/trie_by_cid/triedb/hashdb/database.go b/trie_by_cid/triedb/hashdb/database.go index 68f539f..e63fbd1 100644 --- a/trie_by_cid/triedb/hashdb/database.go +++ b/trie_by_cid/triedb/hashdb/database.go @@ -359,7 +359,7 @@ func (db *Database) Cap(limit common.StorageSize) error { for size > limit && oldest != (common.Hash{}) { // Fetch the oldest referenced node and push into the batch node := db.dirties[oldest] - rawdb.WriteLegacyTrieNode(batch, oldest, node.node) + internal.WriteLegacyTrieNode(batch, oldest, node.node, 0) // If we exceeded the ideal batch size, commit and reset if batch.ValueSize() >= ethdb.IdealBatchSize { @@ -482,7 +482,9 @@ func (db *Database) commit(hash common.Hash, batch ethdb.Batch, uncacher *cleane return err } // If we've reached an optimal batch size, commit and start over - rawdb.WriteLegacyTrieNode(batch, hash, node.node) + // FIXME: placeholder - this won't work unless we know the codec we need here, + // so writes are currently disabled and this will panic (ipld-eth-statedb change) + internal.WriteLegacyTrieNode(batch, hash, node.node, 0) if batch.ValueSize() >= ethdb.IdealBatchSize { if err := batch.Write(); err != nil { return err @@ -552,7 +554,7 @@ func (c *cleaner) Delete(key []byte) error { // Initialized returns an indicator if state data is already initialized // in hash-based scheme by checking the presence of genesis state. func (db *Database) Initialized(genesisRoot common.Hash) bool { - return rawdb.HasLegacyTrieNode(db.diskdb, genesisRoot) + return internal.HasLegacyTrieNode(db.diskdb, genesisRoot, internal.StateTrieCodec) } // Update inserts the dirty nodes in provided nodeset into database and link the