mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
all: distinguish empty state root in merkle and verkle
This commit is contained in:
parent
804d45cc2e
commit
4c3e54b772
66 changed files with 396 additions and 303 deletions
|
|
@ -479,7 +479,7 @@ func (s *Suite) TestSnapGetByteCodes(t *utesting.T) {
|
||||||
{
|
{
|
||||||
desc: `Here we request the empty state root (which is not an existing code hash). The server should deliver an empty response with no items.`,
|
desc: `Here we request the empty state root (which is not an existing code hash). The server should deliver an empty response with no items.`,
|
||||||
nBytes: 10000,
|
nBytes: 10000,
|
||||||
hashes: []common.Hash{types.EmptyRootHash},
|
hashes: []common.Hash{types.EmptyMerkleHash}, // TODO add verkle tests
|
||||||
expHashes: 0,
|
expHashes: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -427,7 +427,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
|
||||||
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB {
|
||||||
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
sdb := state.NewDatabase(tdb, nil)
|
sdb := state.NewDatabase(tdb, nil)
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
statedb, _ := state.New(types.EmptyMerkleHash, sdb) // TODO support verkle node in t8n
|
||||||
for addr, a := range accounts {
|
for addr, a := range accounts {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce)
|
statedb.SetNonce(addr, a.Nonce)
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,8 @@ func checkDanglingStorage(ctx *cli.Context) error {
|
||||||
// traverseState is a helper function used for pruning verification.
|
// traverseState is a helper function used for pruning verification.
|
||||||
// Basically it just iterates the trie, ensure all nodes and associated
|
// Basically it just iterates the trie, ensure all nodes and associated
|
||||||
// contract codes are present.
|
// contract codes are present.
|
||||||
|
//
|
||||||
|
// TODO(rjl493456442) this command is not compatible with verkle.
|
||||||
func traverseState(ctx *cli.Context) error {
|
func traverseState(ctx *cli.Context) error {
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
@ -324,7 +326,7 @@ func traverseState(ctx *cli.Context) error {
|
||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyMerkleHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.Key), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -374,6 +376,8 @@ func traverseState(ctx *cli.Context) error {
|
||||||
// Basically it just iterates the trie, ensure all nodes and associated
|
// Basically it just iterates the trie, ensure all nodes and associated
|
||||||
// contract codes are present. It's basically identical to traverseState
|
// contract codes are present. It's basically identical to traverseState
|
||||||
// but it will check each trie node.
|
// but it will check each trie node.
|
||||||
|
//
|
||||||
|
// TODO(rjl493456442) this command is not compatible with verkle.
|
||||||
func traverseRawState(ctx *cli.Context) error {
|
func traverseRawState(ctx *cli.Context) error {
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
@ -462,7 +466,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||||
log.Error("Invalid account encountered during traversal", "err", err)
|
log.Error("Invalid account encountered during traversal", "err", err)
|
||||||
return errors.New("invalid account")
|
return errors.New("invalid account")
|
||||||
}
|
}
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyMerkleHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb)
|
storageTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -537,6 +541,7 @@ func parseRoot(input string) (common.Hash, error) {
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dumpState is not compatible with verkle mode.
|
||||||
func dumpState(ctx *cli.Context) error {
|
func dumpState(ctx *cli.Context) error {
|
||||||
stack, _ := makeConfigNode(ctx)
|
stack, _ := makeConfigNode(ctx)
|
||||||
defer stack.Close()
|
defer stack.Close()
|
||||||
|
|
@ -578,7 +583,7 @@ func dumpState(ctx *cli.Context) error {
|
||||||
Root common.Hash `json:"root"`
|
Root common.Hash `json:"root"`
|
||||||
}{root})
|
}{root})
|
||||||
for accIt.Next() {
|
for accIt.Next() {
|
||||||
account, err := types.FullAccount(accIt.Account())
|
account, err := types.FullAccount(accIt.Account(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -567,6 +567,8 @@ func ExportPreimages(db ethdb.Database, fn string) error {
|
||||||
|
|
||||||
// ExportSnapshotPreimages exports the preimages corresponding to the enumeration of
|
// ExportSnapshotPreimages exports the preimages corresponding to the enumeration of
|
||||||
// the snapshot for a given root.
|
// the snapshot for a given root.
|
||||||
|
//
|
||||||
|
// TODO(rjl493456442) this command is not compatible with verkle.
|
||||||
func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn string, root common.Hash) error {
|
func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn string, root common.Hash) error {
|
||||||
log.Info("Exporting preimages", "file", fn)
|
log.Info("Exporting preimages", "file", fn)
|
||||||
|
|
||||||
|
|
@ -608,7 +610,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn
|
||||||
defer accIt.Release()
|
defer accIt.Release()
|
||||||
|
|
||||||
for accIt.Next() {
|
for accIt.Next() {
|
||||||
acc, err := types.FullAccount(accIt.Account())
|
acc, err := types.FullAccount(accIt.Account(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to get full account", "error", err)
|
log.Error("Failed to get full account", "error", err)
|
||||||
return
|
return
|
||||||
|
|
@ -616,7 +618,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn
|
||||||
preimages += 1
|
preimages += 1
|
||||||
hashCh <- hashAndPreimageSize{Hash: accIt.Hash(), Size: common.AddressLength}
|
hashCh <- hashAndPreimageSize{Hash: accIt.Hash(), Size: common.AddressLength}
|
||||||
|
|
||||||
if acc.Root != (common.Hash{}) && acc.Root != types.EmptyRootHash {
|
if acc.Root != (common.Hash{}) && acc.Root != types.EmptyMerkleHash {
|
||||||
stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
|
stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to create storage iterator", "error", err)
|
log.Error("Failed to create storage iterator", "error", err)
|
||||||
|
|
|
||||||
|
|
@ -128,7 +128,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
||||||
// Create an ephemeral in-memory database for computing hash,
|
// Create an ephemeral in-memory database for computing hash,
|
||||||
// all the derived states will be discarded to not pollute disk.
|
// all the derived states will be discarded to not pollute disk.
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb.NewDatabase(db, config), nil))
|
statedb, err := state.New(types.EmptyRootHash(isVerkle), state.NewDatabase(triedb.NewDatabase(db, config), nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +148,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) {
|
||||||
// flushAlloc is very similar with hash, but the main difference is all the
|
// flushAlloc is very similar with hash, but the main difference is all the
|
||||||
// generated states will be persisted into the given database.
|
// generated states will be persisted into the given database.
|
||||||
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) {
|
func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) {
|
||||||
statedb, err := state.New(types.EmptyRootHash, state.NewDatabase(triedb, nil))
|
statedb, err := state.New(types.EmptyRootHash(triedb.IsVerkle()), state.NewDatabase(triedb, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -169,7 +169,7 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
// Commit newly generated states into disk if it's not empty.
|
// Commit newly generated states into disk if it's not empty.
|
||||||
if root != types.EmptyRootHash {
|
if root != types.EmptyRootHash(triedb.IsVerkle()) {
|
||||||
if err := triedb.Commit(root, true); err != nil {
|
if err := triedb.Commit(root, true); err != nil {
|
||||||
return common.Hash{}, err
|
return common.Hash{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -292,7 +292,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g
|
||||||
// is initialized with an external ancient store. Commit genesis state
|
// is initialized with an external ancient store. Commit genesis state
|
||||||
// in this case.
|
// in this case.
|
||||||
header := rawdb.ReadHeader(db, stored, 0)
|
header := rawdb.ReadHeader(db, stored, 0)
|
||||||
if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) {
|
if header.Root != types.EmptyRootHash(triedb.IsVerkle()) && !triedb.Initialized(header.Root) {
|
||||||
if genesis == nil {
|
if genesis == nil {
|
||||||
genesis = DefaultGenesisBlock()
|
genesis = DefaultGenesisBlock()
|
||||||
}
|
}
|
||||||
|
|
@ -494,6 +494,9 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo
|
||||||
if config.Clique != nil && len(g.ExtraData) < 32+crypto.SignatureLength {
|
if config.Clique != nil && len(g.ExtraData) < 32+crypto.SignatureLength {
|
||||||
return nil, errors.New("can't start clique chain without signers")
|
return nil, errors.New("can't start clique chain without signers")
|
||||||
}
|
}
|
||||||
|
if g.IsVerkle() != triedb.IsVerkle() {
|
||||||
|
return nil, errors.New("supplied triedb is in wrong mode")
|
||||||
|
}
|
||||||
// flush the data to disk and compute the state root
|
// flush the data to disk and compute the state root
|
||||||
root, err := flushAlloc(&g.Alloc, triedb)
|
root, err := flushAlloc(&g.Alloc, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -175,11 +175,18 @@ func TestGenesisHashes(t *testing.T) {
|
||||||
want common.Hash
|
want common.Hash
|
||||||
}{
|
}{
|
||||||
{DefaultGenesisBlock(), params.MainnetGenesisHash},
|
{DefaultGenesisBlock(), params.MainnetGenesisHash},
|
||||||
|
{DefaultHoleskyGenesisBlock(), params.HoleskyGenesisHash},
|
||||||
{DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash},
|
{DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash},
|
||||||
|
|
||||||
|
// TODO (rjl493456442, gballet) add verkle genesis tests
|
||||||
} {
|
} {
|
||||||
// Test via MustCommit
|
// Test via MustCommit
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
if have := c.genesis.MustCommit(db, triedb.NewDatabase(db, triedb.HashDefaults)).Hash(); have != c.want {
|
config := triedb.HashDefaults
|
||||||
|
if c.genesis.IsVerkle() {
|
||||||
|
config = triedb.VerkleDefaults
|
||||||
|
}
|
||||||
|
if have := c.genesis.MustCommit(db, triedb.NewDatabase(db, config)).Hash(); have != c.want {
|
||||||
t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
|
t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
|
||||||
}
|
}
|
||||||
// Test via ToBlock
|
// Test via ToBlock
|
||||||
|
|
|
||||||
|
|
@ -183,14 +183,14 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) {
|
||||||
// then construct the legacy snap reader.
|
// then construct the legacy snap reader.
|
||||||
snap := db.snap.Snapshot(stateRoot)
|
snap := db.snap.Snapshot(stateRoot)
|
||||||
if snap != nil {
|
if snap != nil {
|
||||||
readers = append(readers, newFlatReader(snap))
|
readers = append(readers, newFlatReader(snap, db.triedb.IsVerkle()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If standalone state snapshot is not available, try to construct
|
// If standalone state snapshot is not available, try to construct
|
||||||
// the state reader with database.
|
// the state reader with database.
|
||||||
reader, err := db.triedb.StateReader(stateRoot)
|
reader, err := db.triedb.StateReader(stateRoot)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
readers = append(readers, newFlatReader(reader)) // state reader is optional
|
readers = append(readers, newFlatReader(reader, db.triedb.IsVerkle())) // state reader is optional
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set up the trie reader, which is expected to always be available
|
// Set up the trie reader, which is expected to always be available
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ func extractGenesis(db ethdb.Database, stateBloom *stateBloom) error {
|
||||||
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
if err := rlp.DecodeBytes(accIter.LeafBlob(), &acc); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyMerkleHash {
|
||||||
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
id := trie.StorageTrieID(genesis.Root(), common.BytesToHash(accIter.LeafKey()), acc.Root)
|
||||||
storageTrie, err := trie.NewStateTrie(id, triedb.NewDatabase(db, triedb.HashDefaults))
|
storageTrie, err := trie.NewStateTrie(id, triedb.NewDatabase(db, triedb.HashDefaults))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -125,15 +125,17 @@ func (r *cachingCodeReader) CodeSize(addr common.Address, codeHash common.Hash)
|
||||||
|
|
||||||
// flatReader wraps a database state reader.
|
// flatReader wraps a database state reader.
|
||||||
type flatReader struct {
|
type flatReader struct {
|
||||||
reader database.StateReader
|
reader database.StateReader
|
||||||
buff crypto.KeccakState
|
buff crypto.KeccakState
|
||||||
|
isVerkle bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFlatReader constructs a state reader with on the given state root.
|
// newFlatReader constructs a state reader with on the given state root.
|
||||||
func newFlatReader(reader database.StateReader) *flatReader {
|
func newFlatReader(reader database.StateReader, isVerkle bool) *flatReader {
|
||||||
return &flatReader{
|
return &flatReader{
|
||||||
reader: reader,
|
reader: reader,
|
||||||
buff: crypto.NewKeccakState(),
|
buff: crypto.NewKeccakState(),
|
||||||
|
isVerkle: isVerkle,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,8 +162,9 @@ func (r *flatReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
if len(acct.CodeHash) == 0 {
|
if len(acct.CodeHash) == 0 {
|
||||||
acct.CodeHash = types.EmptyCodeHash.Bytes()
|
acct.CodeHash = types.EmptyCodeHash.Bytes()
|
||||||
}
|
}
|
||||||
|
// Annotate the empty root hash, especially for merkle tree.
|
||||||
if acct.Root == (common.Hash{}) {
|
if acct.Root == (common.Hash{}) {
|
||||||
acct.Root = types.EmptyRootHash
|
acct.Root = types.EmptyRootHash(r.isVerkle)
|
||||||
}
|
}
|
||||||
return acct, nil
|
return acct, nil
|
||||||
}
|
}
|
||||||
|
|
@ -240,7 +243,7 @@ func (r *trieReader) Account(addr common.Address) (*types.StateAccount, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if account == nil {
|
if account == nil {
|
||||||
r.subRoots[addr] = types.EmptyRootHash
|
r.subRoots[addr] = types.EmptyRootHash(r.db.IsVerkle())
|
||||||
} else {
|
} else {
|
||||||
r.subRoots[addr] = account.Root
|
r.subRoots[addr] = account.Root
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -290,7 +290,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
||||||
fullData []byte
|
fullData []byte
|
||||||
)
|
)
|
||||||
if leafCallback == nil {
|
if leafCallback == nil {
|
||||||
fullData, err = types.FullAccountRLP(it.(AccountIterator).Account())
|
fullData, err = types.FullAccountRLP(it.(AccountIterator).Account(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
|
|
@ -302,7 +302,7 @@ func generateTrieRoot(db ethdb.KeyValueWriter, scheme string, it Iterator, accou
|
||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
// Fetch the next account and process it concurrently
|
// Fetch the next account and process it concurrently
|
||||||
account, err := types.FullAccount(it.(AccountIterator).Account())
|
account, err := types.FullAccount(it.(AccountIterator).Account(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return stop(err)
|
return stop(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -582,7 +582,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
if bytes.Equal(acc.CodeHash, types.EmptyCodeHash[:]) {
|
||||||
dataLen -= 32
|
dataLen -= 32
|
||||||
}
|
}
|
||||||
if acc.Root == types.EmptyRootHash {
|
if acc.Root == types.EmptyMerkleHash {
|
||||||
dataLen -= 32
|
dataLen -= 32
|
||||||
}
|
}
|
||||||
snapRecoveredAccountMeter.Mark(1)
|
snapRecoveredAccountMeter.Mark(1)
|
||||||
|
|
@ -609,7 +609,7 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
|
|
||||||
// If the iterated account is the contract, create a further loop to
|
// If the iterated account is the contract, create a further loop to
|
||||||
// verify or regenerate the contract storage.
|
// verify or regenerate the contract storage.
|
||||||
if acc.Root == types.EmptyRootHash {
|
if acc.Root == types.EmptyMerkleHash {
|
||||||
ctx.removeStorageAt(account)
|
ctx.removeStorageAt(account)
|
||||||
} else {
|
} else {
|
||||||
var storeMarker []byte
|
var storeMarker []byte
|
||||||
|
|
@ -627,7 +627,11 @@ func generateAccounts(ctx *generatorContext, dl *diskLayer, accMarker []byte) er
|
||||||
origin := common.CopyBytes(accMarker)
|
origin := common.CopyBytes(accMarker)
|
||||||
for {
|
for {
|
||||||
id := trie.StateTrieID(dl.root)
|
id := trie.StateTrieID(dl.root)
|
||||||
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountCheckRange, onAccount, types.FullAccountRLP)
|
exhausted, last, err := dl.generateRange(ctx, id, rawdb.SnapshotAccountPrefix, snapAccount, origin, accountCheckRange, onAccount,
|
||||||
|
func(data []byte) ([]byte, error) {
|
||||||
|
return types.FullAccountRLP(data, false)
|
||||||
|
},
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err // The procedure it aborted, either by external signal or internal error.
|
return err // The procedure it aborted, either by external signal or internal error.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ func testGeneration(t *testing.T, scheme string) {
|
||||||
stRoot := helper.makeStorageTrie("", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
stRoot := helper.makeStorageTrie("", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, false)
|
||||||
|
|
||||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
|
|
@ -102,8 +102,8 @@ func testGenerateExistentState(t *testing.T, scheme string) {
|
||||||
helper.addSnapAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
@ -171,7 +171,7 @@ func newHelper(scheme string) *testHelper {
|
||||||
config.HashDB = &hashdb.Config{} // disable caching
|
config.HashDB = &hashdb.Config{} // disable caching
|
||||||
}
|
}
|
||||||
db := triedb.NewDatabase(diskdb, config)
|
db := triedb.NewDatabase(diskdb, config)
|
||||||
accTrie, _ := trie.NewStateTrie(trie.StateTrieID(types.EmptyRootHash), db)
|
accTrie, _ := trie.NewStateTrie(trie.StateTrieID(types.EmptyMerkleHash), db)
|
||||||
return &testHelper{
|
return &testHelper{
|
||||||
diskdb: diskdb,
|
diskdb: diskdb,
|
||||||
triedb: db,
|
triedb: db,
|
||||||
|
|
@ -210,7 +210,7 @@ func (t *testHelper) addSnapStorage(accKey string, keys []string, vals []string)
|
||||||
func (t *testHelper) makeStorageTrie(accKey string, keys []string, vals []string, commit bool) common.Hash {
|
func (t *testHelper) makeStorageTrie(accKey string, keys []string, vals []string, commit bool) common.Hash {
|
||||||
owner := hashData([]byte(accKey))
|
owner := hashData([]byte(accKey))
|
||||||
addr := common.BytesToAddress([]byte(accKey))
|
addr := common.BytesToAddress([]byte(accKey))
|
||||||
id := trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash)
|
id := trie.StorageTrieID(types.EmptyMerkleHash, owner, types.EmptyMerkleHash)
|
||||||
stTrie, _ := trie.NewStateTrie(id, t.triedb)
|
stTrie, _ := trie.NewStateTrie(id, t.triedb)
|
||||||
for i, k := range keys {
|
for i, k := range keys {
|
||||||
stTrie.MustUpdate([]byte(k), []byte(vals[i]))
|
stTrie.MustUpdate([]byte(k), []byte(vals[i]))
|
||||||
|
|
@ -238,7 +238,7 @@ func (t *testHelper) Commit() common.Hash {
|
||||||
if nodes != nil {
|
if nodes != nil {
|
||||||
t.nodes.Merge(nodes)
|
t.nodes.Merge(nodes)
|
||||||
}
|
}
|
||||||
t.triedb.Update(root, types.EmptyRootHash, 0, t.nodes, t.states)
|
t.triedb.Update(root, types.EmptyMerkleHash, 0, t.nodes, t.states)
|
||||||
t.triedb.Commit(root, false)
|
t.triedb.Commit(root, false)
|
||||||
return root
|
return root
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +276,7 @@ func testGenerateExistentStateWithWrongStorage(t *testing.T, scheme string) {
|
||||||
helper := newHelper(scheme)
|
helper := newHelper(scheme)
|
||||||
|
|
||||||
// Account one, empty root but non-empty database
|
// Account one, empty root but non-empty database
|
||||||
helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
helper.addSnapStorage("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"})
|
||||||
|
|
||||||
// Account two, non empty root but empty database
|
// Account two, non empty root but empty database
|
||||||
|
|
@ -394,14 +394,14 @@ func testGenerateExistentStateWithWrongAccounts(t *testing.T, scheme string) {
|
||||||
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
helper.addSnapAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: common.Hex2Bytes("0x1234")})
|
||||||
|
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addSnapAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra accounts, only in the snap
|
// Extra accounts, only in the snap
|
||||||
{
|
{
|
||||||
helper.addSnapAccount("acc-0", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
helper.addSnapAccount("acc-0", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // before the beginning
|
||||||
helper.addSnapAccount("acc-5", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
helper.addSnapAccount("acc-5", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: common.Hex2Bytes("0x1234")}) // Middle
|
||||||
helper.addSnapAccount("acc-7", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
helper.addSnapAccount("acc-7", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // after the end
|
||||||
}
|
}
|
||||||
|
|
||||||
root, snap := helper.CommitAndGenerate()
|
root, snap := helper.CommitAndGenerate()
|
||||||
|
|
@ -435,9 +435,9 @@ func testGenerateCorruptAccountTrie(t *testing.T, scheme string) {
|
||||||
// without any storage slots to keep the test smaller.
|
// without any storage slots to keep the test smaller.
|
||||||
helper := newHelper(scheme)
|
helper := newHelper(scheme)
|
||||||
|
|
||||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0xc7a30f39aff471c95d8a837497ad0e49b65be475cc0953540f80cfcdbdcd9074
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x19ead688e907b0fab07176120dceec244a72aff2f0aa51e8b827584e378772f4
|
||||||
|
|
||||||
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
root := helper.Commit() // Root: 0xa04693ea110a31037fb5ee814308a6f1d76bdab0b11676bdf4541d2de55ba978
|
||||||
|
|
||||||
|
|
@ -479,9 +479,9 @@ func testGenerateMissingStorageTrie(t *testing.T, scheme string) {
|
||||||
acc3 = hashData([]byte("acc-3"))
|
acc3 = hashData([]byte("acc-3"))
|
||||||
helper = newHelper(scheme)
|
helper = newHelper(scheme)
|
||||||
)
|
)
|
||||||
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
|
|
@ -519,9 +519,9 @@ func testGenerateCorruptStorageTrie(t *testing.T, scheme string) {
|
||||||
// two of which also has the same 3-slot storage trie attached.
|
// two of which also has the same 3-slot storage trie attached.
|
||||||
helper := newHelper(scheme)
|
helper := newHelper(scheme)
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true) // 0xddefcd9376dd029653ef384bd2f0a126bb755fe84fdcc9e7cf421ba454f2bc67
|
||||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x9250573b9c18c664139f3b6a7a8081b7d8f8916a8fcc5d94feec6c29f5fd4e9e
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x65145f923027566669a1ae5ccac66f945b55ff6eaeb17d2ea8e048b7d381f2d7
|
||||||
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot = helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()}) // 0x50815097425d000edfc8b3a4a13e175fc2bdcfee8bdfbf2d1ff61041d3c235b2
|
||||||
|
|
||||||
|
|
@ -653,7 +653,7 @@ func testGenerateWithManyExtraAccounts(t *testing.T, scheme string) {
|
||||||
{
|
{
|
||||||
// 100 accounts exist only in snapshot
|
// 100 accounts exist only in snapshot
|
||||||
for i := 0; i < 1000; i++ {
|
for i := 0; i < 1000; i++ {
|
||||||
acc := &types.StateAccount{Balance: uint256.NewInt(uint64(i)), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: uint256.NewInt(uint64(i)), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
|
key := hashData([]byte(fmt.Sprintf("acc-%d", i)))
|
||||||
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
rawdb.WriteAccountSnapshot(helper.diskdb, key, val)
|
||||||
|
|
@ -695,7 +695,7 @@ func testGenerateWithExtraBeforeAndAfter(t *testing.T, scheme string) {
|
||||||
}
|
}
|
||||||
helper := newHelper(scheme)
|
helper := newHelper(scheme)
|
||||||
{
|
{
|
||||||
acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x07").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x07").Bytes(), val)
|
||||||
|
|
@ -737,7 +737,7 @@ func testGenerateWithMalformedSnapdata(t *testing.T, scheme string) {
|
||||||
}
|
}
|
||||||
helper := newHelper(scheme)
|
helper := newHelper(scheme)
|
||||||
{
|
{
|
||||||
acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
acc := &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()}
|
||||||
val, _ := rlp.EncodeToBytes(acc)
|
val, _ := rlp.EncodeToBytes(acc)
|
||||||
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
helper.accTrie.MustUpdate(common.HexToHash("0x03").Bytes(), val)
|
||||||
|
|
||||||
|
|
@ -921,7 +921,7 @@ func testGenerateCompleteSnapshotWithDanglingStorage(t *testing.T, scheme string
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(1), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
@ -961,7 +961,7 @@ func testGenerateBrokenSnapshotWithDanglingStorage(t *testing.T, scheme string)
|
||||||
|
|
||||||
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
stRoot := helper.makeStorageTrie("acc-1", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-1", &types.StateAccount{Balance: uint256.NewInt(1), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyRootHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-2", &types.StateAccount{Balance: uint256.NewInt(2), Root: types.EmptyMerkleHash, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
||||||
helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
helper.makeStorageTrie("acc-3", []string{"key-1", "key-2", "key-3"}, []string{"val-1", "val-2", "val-3"}, true)
|
||||||
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
helper.addTrieAccount("acc-3", &types.StateAccount{Balance: uint256.NewInt(3), Root: stRoot, CodeHash: types.EmptyCodeHash.Bytes()})
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
||||||
baseRoot := rawdb.ReadSnapshotRoot(db)
|
baseRoot := rawdb.ReadSnapshotRoot(db)
|
||||||
fmt.Printf("Disklayer: Root: %x\n", baseRoot)
|
fmt.Printf("Disklayer: Root: %x\n", baseRoot)
|
||||||
if data := rawdb.ReadAccountSnapshot(db, hash); data != nil {
|
if data := rawdb.ReadAccountSnapshot(db, hash); data != nil {
|
||||||
account, err := types.FullAccount(data)
|
account, err := types.FullAccount(data, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
@ -128,7 +128,7 @@ func CheckJournalAccount(db ethdb.KeyValueStore, hash common.Hash) error {
|
||||||
}
|
}
|
||||||
fmt.Printf("Disklayer+%d: Root: %x, parent %x\n", depth, root, pRoot)
|
fmt.Printf("Disklayer+%d: Root: %x, parent %x\n", depth, root, pRoot)
|
||||||
if data, ok := accounts[hash]; ok {
|
if data, ok := accounts[hash]; ok {
|
||||||
account, err := types.FullAccount(data)
|
account, err := types.FullAccount(data, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ func (s *stateObject) empty() bool {
|
||||||
func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject {
|
func newObject(db *StateDB, address common.Address, acct *types.StateAccount) *stateObject {
|
||||||
origin := acct
|
origin := acct
|
||||||
if acct == nil {
|
if acct == nil {
|
||||||
acct = types.NewEmptyStateAccount()
|
acct = types.NewEmptyStateAccount(db.db.TrieDB().IsVerkle())
|
||||||
}
|
}
|
||||||
return &stateObject{
|
return &stateObject{
|
||||||
db: db,
|
db: db,
|
||||||
|
|
@ -142,7 +142,8 @@ func (s *stateObject) getTrie() (Trie, error) {
|
||||||
func (s *stateObject) getPrefetchedTrie() Trie {
|
func (s *stateObject) getPrefetchedTrie() Trie {
|
||||||
// If there's nothing to meaningfully return, let the user figure it out by
|
// If there's nothing to meaningfully return, let the user figure it out by
|
||||||
// pulling the trie from disk.
|
// pulling the trie from disk.
|
||||||
if (s.data.Root == types.EmptyRootHash && !s.db.db.TrieDB().IsVerkle()) || s.db.prefetcher == nil {
|
isVerkle := s.db.db.TrieDB().IsVerkle()
|
||||||
|
if (s.data.Root == types.EmptyRootHash(isVerkle) && !isVerkle) || s.db.prefetcher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Attempt to retrieve the trie from the prefetcher
|
// Attempt to retrieve the trie from the prefetcher
|
||||||
|
|
@ -197,9 +198,17 @@ func (s *stateObject) GetCommittedState(key common.Hash) common.Hash {
|
||||||
s.db.StorageReads += time.Since(start)
|
s.db.StorageReads += time.Since(start)
|
||||||
|
|
||||||
// Schedule the resolved storage slots for prefetching if it's enabled.
|
// Schedule the resolved storage slots for prefetching if it's enabled.
|
||||||
if s.db.prefetcher != nil && s.data.Root != types.EmptyRootHash {
|
// Verkle tree is always available for prefetching, or the storage trie is
|
||||||
if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, nil, []common.Hash{key}, true); err != nil {
|
// existent in merkle.
|
||||||
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
if s.db.prefetcher != nil {
|
||||||
|
if s.db.db.TrieDB().IsVerkle() {
|
||||||
|
if err = s.db.prefetcher.prefetch(s.addrHash, common.Hash{}, s.address, nil, []common.Hash{key}, true); err != nil {
|
||||||
|
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
||||||
|
}
|
||||||
|
} else if s.data.Root != types.EmptyMerkleHash {
|
||||||
|
if err = s.db.prefetcher.prefetch(s.addrHash, s.origin.Root, s.address, nil, []common.Hash{key}, true); err != nil {
|
||||||
|
log.Error("Failed to prefetch storage slot", "addr", s.address, "key", key, "err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.originStorage[key] = value
|
s.originStorage[key] = value
|
||||||
|
|
@ -258,9 +267,17 @@ func (s *stateObject) finalise() {
|
||||||
// byzantium fork) and entry is necessary to modify the value back.
|
// byzantium fork) and entry is necessary to modify the value back.
|
||||||
s.pendingStorage[key] = value
|
s.pendingStorage[key] = value
|
||||||
}
|
}
|
||||||
if s.db.prefetcher != nil && len(slotsToPrefetch) > 0 && s.data.Root != types.EmptyRootHash {
|
// Verkle tree is always available for prefetching, or the storage trie is
|
||||||
if err := s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, nil, slotsToPrefetch, false); err != nil {
|
// existent in merkle.
|
||||||
log.Error("Failed to prefetch slots", "addr", s.address, "slots", len(slotsToPrefetch), "err", err)
|
if s.db.prefetcher != nil && len(slotsToPrefetch) > 0 {
|
||||||
|
if s.db.db.TrieDB().IsVerkle() {
|
||||||
|
if err := s.db.prefetcher.prefetch(s.addrHash, common.Hash{}, s.address, nil, slotsToPrefetch, false); err != nil {
|
||||||
|
log.Error("Failed to prefetch slots", "addr", s.address, "slots", len(slotsToPrefetch), "err", err)
|
||||||
|
}
|
||||||
|
} else if s.data.Root != types.EmptyMerkleHash {
|
||||||
|
if err := s.db.prefetcher.prefetch(s.addrHash, s.data.Root, s.address, nil, slotsToPrefetch, false); err != nil {
|
||||||
|
log.Error("Failed to prefetch slots", "addr", s.address, "slots", len(slotsToPrefetch), "err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(s.dirtyStorage) > 0 {
|
if len(s.dirtyStorage) > 0 {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ type stateEnv struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newStateEnv() *stateEnv {
|
func newStateEnv() *stateEnv {
|
||||||
sdb, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
sdb, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
return &stateEnv{state: sdb}
|
return &stateEnv{state: sdb}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ func TestDump(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
tdb := NewDatabase(triedb, nil)
|
tdb := NewDatabase(triedb, nil)
|
||||||
sdb, _ := New(types.EmptyRootHash, tdb)
|
sdb, _ := New(types.EmptyMerkleHash, tdb)
|
||||||
s := &stateEnv{state: sdb}
|
s := &stateEnv{state: sdb}
|
||||||
|
|
||||||
// generate a few entries
|
// generate a few entries
|
||||||
|
|
@ -100,7 +100,7 @@ func TestIterativeDump(t *testing.T) {
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
triedb := triedb.NewDatabase(db, &triedb.Config{Preimages: true})
|
||||||
tdb := NewDatabase(triedb, nil)
|
tdb := NewDatabase(triedb, nil)
|
||||||
sdb, _ := New(types.EmptyRootHash, tdb)
|
sdb, _ := New(types.EmptyMerkleHash, tdb)
|
||||||
s := &stateEnv{state: sdb}
|
s := &stateEnv{state: sdb}
|
||||||
|
|
||||||
// generate a few entries
|
// generate a few entries
|
||||||
|
|
@ -193,7 +193,7 @@ func TestSnapshotEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateObjectRevert(t *testing.T) {
|
func TestCreateObjectRevert(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
addr := common.BytesToAddress([]byte("so0"))
|
addr := common.BytesToAddress([]byte("so0"))
|
||||||
snap := state.Snapshot()
|
snap := state.Snapshot()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1075,8 +1075,10 @@ func (s *StateDB) handleDestruction() (map[common.Hash]*accountDelete, []*trieno
|
||||||
}
|
}
|
||||||
deletes[addrHash] = op
|
deletes[addrHash] = op
|
||||||
|
|
||||||
// Short circuit if the origin storage was empty.
|
// Short circuit if the origin storage was empty. Notably, this
|
||||||
if prev.Root == types.EmptyRootHash || s.db.TrieDB().IsVerkle() {
|
// condition is always true for verkle and storage deletion is
|
||||||
|
// not supported.
|
||||||
|
if prev.Root == types.EmptyRootHash(s.db.TrieDB().IsVerkle()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Remove storage slots belonging to the account.
|
// Remove storage slots belonging to the account.
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,10 @@ func (test *stateTest) run() bool {
|
||||||
Recovery: false,
|
Recovery: false,
|
||||||
NoBuild: false,
|
NoBuild: false,
|
||||||
AsyncBuild: false,
|
AsyncBuild: false,
|
||||||
}, disk, tdb, types.EmptyRootHash)
|
}, disk, tdb, types.EmptyMerkleHash)
|
||||||
}
|
}
|
||||||
for i, actions := range test.actions {
|
for i, actions := range test.actions {
|
||||||
root := types.EmptyRootHash
|
root := types.EmptyMerkleHash
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
root = roots[len(roots)-1]
|
root = roots[len(roots)-1]
|
||||||
}
|
}
|
||||||
|
|
@ -239,7 +239,7 @@ func (test *stateTest) run() bool {
|
||||||
roots = append(roots, ret.root)
|
roots = append(roots, ret.root)
|
||||||
}
|
}
|
||||||
for i := 0; i < len(test.actions); i++ {
|
for i := 0; i < len(test.actions); i++ {
|
||||||
root := types.EmptyRootHash
|
root := types.EmptyMerkleHash
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
root = roots[i-1]
|
root = roots[i-1]
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +275,7 @@ func (test *stateTest) verifyAccountCreation(next common.Hash, db *triedb.Databa
|
||||||
if len(nBlob) == 0 {
|
if len(nBlob) == 0 {
|
||||||
return fmt.Errorf("missing account in new trie, %x", addrHash)
|
return fmt.Errorf("missing account in new trie, %x", addrHash)
|
||||||
}
|
}
|
||||||
full, err := types.FullAccountRLP(account)
|
full, err := types.FullAccountRLP(account, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ func (test *stateTest) verifyAccountCreation(next common.Hash, db *triedb.Databa
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Account has no slot, empty slot set is expected
|
// Account has no slot, empty slot set is expected
|
||||||
if nAcct.Root == types.EmptyRootHash {
|
if nAcct.Root == types.EmptyMerkleHash {
|
||||||
if len(storagesOrigin) != 0 {
|
if len(storagesOrigin) != 0 {
|
||||||
return fmt.Errorf("unexpected slot changes %x", addrHash)
|
return fmt.Errorf("unexpected slot changes %x", addrHash)
|
||||||
}
|
}
|
||||||
|
|
@ -319,7 +319,7 @@ func (test *stateTest) verifyAccountCreation(next common.Hash, db *triedb.Databa
|
||||||
if len(storagesOrigin) != len(storages) {
|
if len(storagesOrigin) != len(storages) {
|
||||||
return fmt.Errorf("extra storage found, want: %d, got: %d", len(storagesOrigin), len(storages))
|
return fmt.Errorf("extra storage found, want: %d, got: %d", len(storagesOrigin), len(storages))
|
||||||
}
|
}
|
||||||
if st.Hash() != types.EmptyRootHash {
|
if st.Hash() != types.EmptyMerkleHash {
|
||||||
return errors.New("invalid slot changes")
|
return errors.New("invalid slot changes")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -346,7 +346,7 @@ func (test *stateTest) verifyAccountUpdate(next common.Hash, db *triedb.Database
|
||||||
if len(oBlob) == 0 {
|
if len(oBlob) == 0 {
|
||||||
return fmt.Errorf("missing account in old trie, %x", addrHash)
|
return fmt.Errorf("missing account in old trie, %x", addrHash)
|
||||||
}
|
}
|
||||||
full, err := types.FullAccountRLP(accountOrigin)
|
full, err := types.FullAccountRLP(accountOrigin, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -358,7 +358,7 @@ func (test *stateTest) verifyAccountUpdate(next common.Hash, db *triedb.Database
|
||||||
return errors.New("unexpected account data")
|
return errors.New("unexpected account data")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
full, _ = types.FullAccountRLP(account)
|
full, _ = types.FullAccountRLP(account, false)
|
||||||
if !bytes.Equal(full, nBlob) {
|
if !bytes.Equal(full, nBlob) {
|
||||||
return fmt.Errorf("unexpected account data, %x, want %v, got: %v", addrHash, full, nBlob)
|
return fmt.Errorf("unexpected account data, %x, want %v, got: %v", addrHash, full, nBlob)
|
||||||
}
|
}
|
||||||
|
|
@ -373,7 +373,7 @@ func (test *stateTest) verifyAccountUpdate(next common.Hash, db *triedb.Database
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(nBlob) == 0 {
|
if len(nBlob) == 0 {
|
||||||
nRoot = types.EmptyRootHash
|
nRoot = types.EmptyMerkleHash
|
||||||
} else {
|
} else {
|
||||||
if err := rlp.DecodeBytes(nBlob, &nAcct); err != nil {
|
if err := rlp.DecodeBytes(nBlob, &nAcct); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ func TestBurn(t *testing.T) {
|
||||||
// 3. contract B sends ether to A
|
// 3. contract B sends ether to A
|
||||||
|
|
||||||
var burned = new(uint256.Int)
|
var burned = new(uint256.Int)
|
||||||
s, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
s, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
hooked := NewHookedState(s, &tracing.Hooks{
|
hooked := NewHookedState(s, &tracing.Hooks{
|
||||||
OnBalanceChange: func(addr common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) {
|
OnBalanceChange: func(addr common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) {
|
||||||
if reason == tracing.BalanceDecreaseSelfdestructBurn {
|
if reason == tracing.BalanceDecreaseSelfdestructBurn {
|
||||||
|
|
@ -79,7 +79,7 @@ func TestBurn(t *testing.T) {
|
||||||
|
|
||||||
// TestHooks is a basic sanity-check of all hooks
|
// TestHooks is a basic sanity-check of all hooks
|
||||||
func TestHooks(t *testing.T) {
|
func TestHooks(t *testing.T) {
|
||||||
inner, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
inner, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
inner.SetTxContext(common.Hash{0x11}, 100) // For the log
|
inner.SetTxContext(common.Hash{0x11}, 100) // For the log
|
||||||
var result []string
|
var result []string
|
||||||
var wants = []string{
|
var wants = []string{
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ func TestUpdateLeaks(t *testing.T) {
|
||||||
tdb = triedb.NewDatabase(db, nil)
|
tdb = triedb.NewDatabase(db, nil)
|
||||||
sdb = NewDatabase(tdb, nil)
|
sdb = NewDatabase(tdb, nil)
|
||||||
)
|
)
|
||||||
state, _ := New(types.EmptyRootHash, sdb)
|
state, _ := New(types.EmptyMerkleHash, sdb)
|
||||||
|
|
||||||
// Update it with some accounts
|
// Update it with some accounts
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
|
|
@ -90,8 +90,8 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
finalDb := rawdb.NewMemoryDatabase()
|
finalDb := rawdb.NewMemoryDatabase()
|
||||||
transNdb := triedb.NewDatabase(transDb, nil)
|
transNdb := triedb.NewDatabase(transDb, nil)
|
||||||
finalNdb := triedb.NewDatabase(finalDb, nil)
|
finalNdb := triedb.NewDatabase(finalDb, nil)
|
||||||
transState, _ := New(types.EmptyRootHash, NewDatabase(transNdb, nil))
|
transState, _ := New(types.EmptyMerkleHash, NewDatabase(transNdb, nil))
|
||||||
finalState, _ := New(types.EmptyRootHash, NewDatabase(finalNdb, nil))
|
finalState, _ := New(types.EmptyMerkleHash, NewDatabase(finalNdb, nil))
|
||||||
|
|
||||||
modify := func(state *StateDB, addr common.Address, i, tweak byte) {
|
modify := func(state *StateDB, addr common.Address, i, tweak byte) {
|
||||||
state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(uint64(11*i)+uint64(tweak)), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -166,7 +166,7 @@ func TestIntermediateLeaks(t *testing.T) {
|
||||||
// https://github.com/ethereum/go-ethereum/pull/15549.
|
// https://github.com/ethereum/go-ethereum/pull/15549.
|
||||||
func TestCopy(t *testing.T) {
|
func TestCopy(t *testing.T) {
|
||||||
// Create a random state test to copy and modify "independently"
|
// Create a random state test to copy and modify "independently"
|
||||||
orig, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
orig, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
|
||||||
|
|
@ -231,7 +231,7 @@ func TestCopy(t *testing.T) {
|
||||||
// stateDB with dirty journal present.
|
// stateDB with dirty journal present.
|
||||||
func TestCopyWithDirtyJournal(t *testing.T) {
|
func TestCopyWithDirtyJournal(t *testing.T) {
|
||||||
db := NewDatabaseForTesting()
|
db := NewDatabaseForTesting()
|
||||||
orig, _ := New(types.EmptyRootHash, db)
|
orig, _ := New(types.EmptyMerkleHash, db)
|
||||||
|
|
||||||
// Fill up the initial states
|
// Fill up the initial states
|
||||||
for i := byte(0); i < 255; i++ {
|
for i := byte(0); i < 255; i++ {
|
||||||
|
|
@ -277,7 +277,7 @@ func TestCopyWithDirtyJournal(t *testing.T) {
|
||||||
// to affect S2. This test checks that the copy properly deep-copies the objectstate
|
// to affect S2. This test checks that the copy properly deep-copies the objectstate
|
||||||
func TestCopyObjectState(t *testing.T) {
|
func TestCopyObjectState(t *testing.T) {
|
||||||
db := NewDatabaseForTesting()
|
db := NewDatabaseForTesting()
|
||||||
orig, _ := New(types.EmptyRootHash, db)
|
orig, _ := New(types.EmptyMerkleHash, db)
|
||||||
|
|
||||||
// Fill up the initial states
|
// Fill up the initial states
|
||||||
for i := byte(0); i < 5; i++ {
|
for i := byte(0); i < 5; i++ {
|
||||||
|
|
@ -404,7 +404,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction {
|
||||||
contractHash := s.GetCodeHash(addr)
|
contractHash := s.GetCodeHash(addr)
|
||||||
emptyCode := contractHash == (common.Hash{}) || contractHash == types.EmptyCodeHash
|
emptyCode := contractHash == (common.Hash{}) || contractHash == types.EmptyCodeHash
|
||||||
storageRoot := s.GetStorageRoot(addr)
|
storageRoot := s.GetStorageRoot(addr)
|
||||||
emptyStorage := storageRoot == (common.Hash{}) || storageRoot == types.EmptyRootHash
|
emptyStorage := storageRoot == (common.Hash{}) || storageRoot == types.EmptyMerkleHash
|
||||||
if s.GetNonce(addr) == 0 && emptyCode && emptyStorage {
|
if s.GetNonce(addr) == 0 && emptyCode && emptyStorage {
|
||||||
s.CreateContract(addr)
|
s.CreateContract(addr)
|
||||||
// We also set some code here, to prevent the
|
// We also set some code here, to prevent the
|
||||||
|
|
@ -529,7 +529,7 @@ func (test *snapshotTest) String() string {
|
||||||
func (test *snapshotTest) run() bool {
|
func (test *snapshotTest) run() bool {
|
||||||
// Run all actions and create snapshots.
|
// Run all actions and create snapshots.
|
||||||
var (
|
var (
|
||||||
state, _ = New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ = New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
snapshotRevs = make([]int, len(test.snapshots))
|
snapshotRevs = make([]int, len(test.snapshots))
|
||||||
sindex = 0
|
sindex = 0
|
||||||
checkstates = make([]*StateDB, len(test.snapshots))
|
checkstates = make([]*StateDB, len(test.snapshots))
|
||||||
|
|
@ -714,7 +714,7 @@ func TestTouchDelete(t *testing.T) {
|
||||||
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
|
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
|
||||||
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
|
// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512
|
||||||
func TestCopyOfCopy(t *testing.T) {
|
func TestCopyOfCopy(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
addr := common.HexToAddress("aaaa")
|
addr := common.HexToAddress("aaaa")
|
||||||
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
|
|
@ -732,7 +732,7 @@ func TestCopyOfCopy(t *testing.T) {
|
||||||
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
||||||
func TestCopyCommitCopy(t *testing.T) {
|
func TestCopyCommitCopy(t *testing.T) {
|
||||||
tdb := NewDatabaseForTesting()
|
tdb := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, tdb)
|
state, _ := New(types.EmptyMerkleHash, tdb)
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -805,7 +805,7 @@ func TestCopyCommitCopy(t *testing.T) {
|
||||||
//
|
//
|
||||||
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
// See https://github.com/ethereum/go-ethereum/issues/20106.
|
||||||
func TestCopyCopyCommitCopy(t *testing.T) {
|
func TestCopyCopyCommitCopy(t *testing.T) {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -875,7 +875,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
|
||||||
// TestCommitCopy tests the copy from a committed state is not fully functional.
|
// TestCommitCopy tests the copy from a committed state is not fully functional.
|
||||||
func TestCommitCopy(t *testing.T) {
|
func TestCommitCopy(t *testing.T) {
|
||||||
db := NewDatabaseForTesting()
|
db := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, db)
|
state, _ := New(types.EmptyMerkleHash, db)
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -938,7 +938,7 @@ func TestCommitCopy(t *testing.T) {
|
||||||
// first, but the journal wiped the entire state object on create-revert.
|
// first, but the journal wiped the entire state object on create-revert.
|
||||||
func TestDeleteCreateRevert(t *testing.T) {
|
func TestDeleteCreateRevert(t *testing.T) {
|
||||||
// Create an initial state with a single contract
|
// Create an initial state with a single contract
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
addr := common.BytesToAddress([]byte("so"))
|
addr := common.BytesToAddress([]byte("so"))
|
||||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -990,7 +990,7 @@ func testMissingTrieNodes(t *testing.T, scheme string) {
|
||||||
db := NewDatabase(tdb, nil)
|
db := NewDatabase(tdb, nil)
|
||||||
|
|
||||||
var root common.Hash
|
var root common.Hash
|
||||||
state, _ := New(types.EmptyRootHash, db)
|
state, _ := New(types.EmptyMerkleHash, db)
|
||||||
addr := common.BytesToAddress([]byte("so"))
|
addr := common.BytesToAddress([]byte("so"))
|
||||||
{
|
{
|
||||||
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -1034,7 +1034,7 @@ func TestStateDBAccessList(t *testing.T) {
|
||||||
slot := common.HexToHash
|
slot := common.HexToHash
|
||||||
|
|
||||||
db := NewDatabaseForTesting()
|
db := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, db)
|
state, _ := New(types.EmptyMerkleHash, db)
|
||||||
state.accessList = newAccessList()
|
state.accessList = newAccessList()
|
||||||
|
|
||||||
verifyAddrs := func(astrings ...string) {
|
verifyAddrs := func(astrings ...string) {
|
||||||
|
|
@ -1205,7 +1205,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||||
memdb = rawdb.NewMemoryDatabase()
|
memdb = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(memdb, triedb.HashDefaults)
|
tdb = triedb.NewDatabase(memdb, triedb.HashDefaults)
|
||||||
statedb = NewDatabase(tdb, nil)
|
statedb = NewDatabase(tdb, nil)
|
||||||
state, _ = New(types.EmptyRootHash, statedb)
|
state, _ = New(types.EmptyMerkleHash, statedb)
|
||||||
)
|
)
|
||||||
for a := byte(0); a < 10; a++ {
|
for a := byte(0); a < 10; a++ {
|
||||||
state.CreateAccount(common.Address{a})
|
state.CreateAccount(common.Address{a})
|
||||||
|
|
@ -1240,7 +1240,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
|
||||||
|
|
||||||
func TestStateDBTransientStorage(t *testing.T) {
|
func TestStateDBTransientStorage(t *testing.T) {
|
||||||
db := NewDatabaseForTesting()
|
db := NewDatabaseForTesting()
|
||||||
state, _ := New(types.EmptyRootHash, db)
|
state, _ := New(types.EmptyMerkleHash, db)
|
||||||
|
|
||||||
key := common.Hash{0x01}
|
key := common.Hash{0x01}
|
||||||
value := common.Hash{0x02}
|
value := common.Hash{0x02}
|
||||||
|
|
@ -1275,9 +1275,9 @@ func TestDeleteStorage(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(disk, nil)
|
tdb = triedb.NewDatabase(disk, nil)
|
||||||
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyRootHash)
|
snaps, _ = snapshot.New(snapshot.Config{CacheSize: 10}, disk, tdb, types.EmptyMerkleHash)
|
||||||
db = NewDatabase(tdb, snaps)
|
db = NewDatabase(tdb, snaps)
|
||||||
state, _ = New(types.EmptyRootHash, db)
|
state, _ = New(types.EmptyMerkleHash, db)
|
||||||
addr = common.HexToAddress("0x1")
|
addr = common.HexToAddress("0x1")
|
||||||
)
|
)
|
||||||
// Initialize account and populate storage
|
// Initialize account and populate storage
|
||||||
|
|
@ -1331,7 +1331,7 @@ func TestStorageDirtiness(t *testing.T) {
|
||||||
disk = rawdb.NewMemoryDatabase()
|
disk = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(disk, nil)
|
tdb = triedb.NewDatabase(disk, nil)
|
||||||
db = NewDatabase(tdb, nil)
|
db = NewDatabase(tdb, nil)
|
||||||
state, _ = New(types.EmptyRootHash, db)
|
state, _ = New(types.EmptyMerkleHash, db)
|
||||||
addr = common.HexToAddress("0x1")
|
addr = common.HexToAddress("0x1")
|
||||||
checkDirty = func(key common.Hash, value common.Hash, dirty bool) {
|
checkDirty = func(key common.Hash, value common.Hash, dirty bool) {
|
||||||
obj := state.getStateObject(addr)
|
obj := state.getStateObject(addr)
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import (
|
||||||
"maps"
|
"maps"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
"github.com/ethereum/go-ethereum/triedb"
|
"github.com/ethereum/go-ethereum/triedb"
|
||||||
)
|
)
|
||||||
|
|
@ -133,8 +132,8 @@ func newStateUpdate(originRoot common.Hash, root common.Hash, deletes map[common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &stateUpdate{
|
return &stateUpdate{
|
||||||
originRoot: types.TrieRootHash(originRoot),
|
originRoot: originRoot,
|
||||||
root: types.TrieRootHash(root),
|
root: root,
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
accountsOrigin: accountsOrigin,
|
accountsOrigin: accountsOrigin,
|
||||||
storages: storages,
|
storages: storages,
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ func makeTestState(scheme string) (ethdb.Database, Database, *triedb.Database, c
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
nodeDb := triedb.NewDatabase(db, config)
|
nodeDb := triedb.NewDatabase(db, config)
|
||||||
sdb := NewDatabase(nodeDb, nil)
|
sdb := NewDatabase(nodeDb, nil)
|
||||||
state, _ := New(types.EmptyRootHash, sdb)
|
state, _ := New(types.EmptyMerkleHash, sdb)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
var accounts []*testAccount
|
var accounts []*testAccount
|
||||||
|
|
@ -134,11 +134,11 @@ func TestEmptyStateSync(t *testing.T) {
|
||||||
dbA := triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil)
|
dbA := triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil)
|
||||||
dbB := triedb.NewDatabase(rawdb.NewMemoryDatabase(), &triedb.Config{PathDB: pathdb.Defaults})
|
dbB := triedb.NewDatabase(rawdb.NewMemoryDatabase(), &triedb.Config{PathDB: pathdb.Defaults})
|
||||||
|
|
||||||
sync := NewStateSync(types.EmptyRootHash, rawdb.NewMemoryDatabase(), nil, dbA.Scheme())
|
sync := NewStateSync(types.EmptyMerkleHash, rawdb.NewMemoryDatabase(), nil, dbA.Scheme())
|
||||||
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
||||||
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
||||||
}
|
}
|
||||||
sync = NewStateSync(types.EmptyRootHash, rawdb.NewMemoryDatabase(), nil, dbB.Scheme())
|
sync = NewStateSync(types.EmptyMerkleHash, rawdb.NewMemoryDatabase(), nil, dbB.Scheme())
|
||||||
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
if paths, nodes, codes := sync.Missing(1); len(paths) != 0 || len(nodes) != 0 || len(codes) != 0 {
|
||||||
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
t.Errorf("content requested for empty state: %v, %v, %v", nodes, paths, codes)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func filledStateDB() *StateDB {
|
func filledStateDB() *StateDB {
|
||||||
state, _ := New(types.EmptyRootHash, NewDatabaseForTesting())
|
state, _ := New(types.EmptyMerkleHash, NewDatabaseForTesting())
|
||||||
|
|
||||||
// Create an account and check if the retrieved balance is correct
|
// Create an account and check if the retrieved balance is correct
|
||||||
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
|
||||||
|
|
@ -71,7 +71,7 @@ func TestVerklePrefetcher(t *testing.T) {
|
||||||
db := triedb.NewDatabase(disk, triedb.VerkleDefaults)
|
db := triedb.NewDatabase(disk, triedb.VerkleDefaults)
|
||||||
sdb := NewDatabase(db, nil)
|
sdb := NewDatabase(db, nil)
|
||||||
|
|
||||||
state, err := New(types.EmptyRootHash, sdb)
|
state, err := New(types.EmptyVerkleHash, sdb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to initialize state: %v", err)
|
t.Fatalf("failed to initialize state: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -373,7 +373,7 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserve txpool.Addres
|
||||||
// fully synced).
|
// fully synced).
|
||||||
state, err := p.chain.StateAt(head.Root)
|
state, err := p.chain.StateAt(head.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
state, err = p.chain.StateAt(types.EmptyRootHash)
|
state, err = p.chain.StateAt(types.EmptyMerkleHash) // TODO (rjl493456442) support verkle
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -636,7 +636,7 @@ func TestOpenDrops(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// Create a blob pool out of the pre-seeded data
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(gapper.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(dangler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(crypto.PubkeyToAddress(filler.PublicKey), uint256.NewInt(1000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -767,7 +767,7 @@ func TestOpenIndex(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// Create a blob pool out of the pre-seeded data
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.Commit(0, true)
|
statedb.Commit(0, true)
|
||||||
|
|
||||||
|
|
@ -867,7 +867,7 @@ func TestOpenHeap(t *testing.T) {
|
||||||
store.Close()
|
store.Close()
|
||||||
|
|
||||||
// Create a blob pool out of the pre-seeded data
|
// Create a blob pool out of the pre-seeded data
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -947,7 +947,7 @@ func TestOpenCap(t *testing.T) {
|
||||||
// with a high cap to ensure everything was persisted previously
|
// with a high cap to ensure everything was persisted previously
|
||||||
for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
|
for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} {
|
||||||
// Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction
|
// Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -1376,7 +1376,7 @@ func TestAdd(t *testing.T) {
|
||||||
keys = make(map[string]*ecdsa.PrivateKey)
|
keys = make(map[string]*ecdsa.PrivateKey)
|
||||||
addrs = make(map[string]common.Address)
|
addrs = make(map[string]common.Address)
|
||||||
)
|
)
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
for acc, seed := range tt.seeds {
|
for acc, seed := range tt.seeds {
|
||||||
// Generate a new random key/address for the seed account
|
// Generate a new random key/address for the seed account
|
||||||
keys[acc], _ = crypto.GenerateKey()
|
keys[acc], _ = crypto.GenerateKey()
|
||||||
|
|
@ -1482,7 +1482,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) {
|
||||||
basefee = uint64(1050)
|
basefee = uint64(1050)
|
||||||
blobfee = uint64(105)
|
blobfee = uint64(105)
|
||||||
signer = types.LatestSigner(params.MainnetChainConfig)
|
signer = types.LatestSigner(params.MainnetChainConfig)
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
chain = &testBlockChain{
|
chain = &testBlockChain{
|
||||||
config: params.MainnetChainConfig,
|
config: params.MainnetChainConfig,
|
||||||
basefee: uint256.NewInt(basefee),
|
basefee: uint256.NewInt(basefee),
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,7 @@ func (pool *LegacyPool) Init(gasTip uint64, head *types.Header, reserve txpool.A
|
||||||
// fully synced).
|
// fully synced).
|
||||||
statedb, err := pool.chain.StateAt(head.Root)
|
statedb, err := pool.chain.StateAt(head.Root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
statedb, err = pool.chain.StateAt(types.EmptyRootHash)
|
statedb, err = pool.chain.StateAt(types.EmptyMerkleHash) // TODO (rjl493456442) support verkle
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
|
|
@ -116,7 +116,7 @@ func TestTransactionFutureAttack(t *testing.T) {
|
||||||
func TestTransactionFuture1559(t *testing.T) {
|
func TestTransactionFuture1559(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
||||||
|
|
@ -149,7 +149,7 @@ func TestTransactionFuture1559(t *testing.T) {
|
||||||
func TestTransactionZAttack(t *testing.T) {
|
func TestTransactionZAttack(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
pool.Init(testTxPoolConfig.PriceLimit, blockchain.CurrentBlock(), makeAddressReserver())
|
||||||
|
|
@ -217,7 +217,7 @@ func TestTransactionZAttack(t *testing.T) {
|
||||||
|
|
||||||
func BenchmarkFutureAttack(b *testing.B) {
|
func BenchmarkFutureAttack(b *testing.B) {
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
config.GlobalQueue = 100
|
config.GlobalQueue = 100
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ func setupPool() (*LegacyPool, *ecdsa.PrivateKey) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) {
|
func setupPoolWithConfig(config *params.ChainConfig) (*LegacyPool, *ecdsa.PrivateKey) {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(config, 10000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
key, _ := crypto.GenerateKey()
|
key, _ := crypto.GenerateKey()
|
||||||
|
|
@ -250,7 +250,7 @@ func (c *testChain) State() (*state.StateDB, error) {
|
||||||
// a state change between those fetches.
|
// a state change between those fetches.
|
||||||
stdb := c.statedb
|
stdb := c.statedb
|
||||||
if *c.trigger {
|
if *c.trigger {
|
||||||
c.statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
c.statedb, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
// simulate that the new head block included tx0 and tx1
|
// simulate that the new head block included tx0 and tx1
|
||||||
c.statedb.SetNonce(c.address, 2)
|
c.statedb.SetNonce(c.address, 2)
|
||||||
c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified)
|
c.statedb.SetBalance(c.address, new(uint256.Int).SetUint64(params.Ether), tracing.BalanceChangeUnspecified)
|
||||||
|
|
@ -268,7 +268,7 @@ func TestStateChangeDuringReset(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
key, _ = crypto.GenerateKey()
|
key, _ = crypto.GenerateKey()
|
||||||
address = crypto.PubkeyToAddress(key.PublicKey)
|
address = crypto.PubkeyToAddress(key.PublicKey)
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
trigger = false
|
trigger = false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -467,7 +467,7 @@ func TestChainFork(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
@ -496,7 +496,7 @@ func TestDoubleNonce(t *testing.T) {
|
||||||
|
|
||||||
addr := crypto.PubkeyToAddress(key.PublicKey)
|
addr := crypto.PubkeyToAddress(key.PublicKey)
|
||||||
resetState := func() {
|
resetState := func() {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
statedb.AddBalance(addr, uint256.NewInt(100000000000000), tracing.BalanceChangeUnspecified)
|
||||||
|
|
||||||
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
pool.chain = newTestBlockChain(pool.chainconfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
@ -696,7 +696,7 @@ func TestPostponing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the postponing with
|
// Create the pool to test the postponing with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -909,7 +909,7 @@ func testQueueGlobalLimiting(t *testing.T, nolocals bool) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1002,7 +1002,7 @@ func testQueueTimeLimiting(t *testing.T, nolocals bool) {
|
||||||
evictionInterval = time.Millisecond * 100
|
evictionInterval = time.Millisecond * 100
|
||||||
|
|
||||||
// Create the pool to test the non-expiration enforcement
|
// Create the pool to test the non-expiration enforcement
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1188,7 +1188,7 @@ func TestPendingGlobalLimiting(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1290,7 +1290,7 @@ func TestCapClearsFromAll(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1325,7 +1325,7 @@ func TestPendingMinimumAllowance(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the limit enforcement with
|
// Create the pool to test the limit enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1374,7 +1374,7 @@ func TestRepricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -1494,7 +1494,7 @@ func TestMinGasPriceEnforced(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 10000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
txPoolConfig := DefaultConfig
|
txPoolConfig := DefaultConfig
|
||||||
|
|
@ -1667,7 +1667,7 @@ func TestRepricingKeepsLocals(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(eip1559Config, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -1741,7 +1741,7 @@ func TestUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -1856,7 +1856,7 @@ func TestStableUnderpricing(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -2089,7 +2089,7 @@ func TestDeduplication(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -2156,7 +2156,7 @@ func TestReplacement(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the pricing enforcement with
|
// Create the pool to test the pricing enforcement with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
@ -2362,7 +2362,7 @@ func testJournaling(t *testing.T, nolocals bool) {
|
||||||
os.Remove(journal)
|
os.Remove(journal)
|
||||||
|
|
||||||
// Create the original pool to inject transaction into the journal
|
// Create the original pool to inject transaction into the journal
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
config := testTxPoolConfig
|
config := testTxPoolConfig
|
||||||
|
|
@ -2463,7 +2463,7 @@ func TestStatusCheck(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// Create the pool to test the status retrievals with
|
// Create the pool to test the status retrievals with
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
blockchain := newTestBlockChain(params.TestChainConfig, 1000000, statedb, new(event.Feed))
|
||||||
|
|
||||||
pool := New(testTxPoolConfig, blockchain)
|
pool := New(testTxPoolConfig, blockchain)
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,9 @@ package types
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// EmptyRootHash is the known root hash of an empty merkle trie.
|
|
||||||
EmptyRootHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
|
||||||
|
|
||||||
// EmptyUncleHash is the known hash of the empty uncle set.
|
// EmptyUncleHash is the known hash of the empty uncle set.
|
||||||
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
|
EmptyUncleHash = rlpHash([]*Header(nil)) // 1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
|
||||||
|
|
||||||
|
|
@ -46,14 +42,15 @@ var (
|
||||||
|
|
||||||
// EmptyVerkleHash is the known hash of an empty verkle trie.
|
// EmptyVerkleHash is the known hash of an empty verkle trie.
|
||||||
EmptyVerkleHash = common.Hash{}
|
EmptyVerkleHash = common.Hash{}
|
||||||
|
|
||||||
|
// EmptyMerkleHash is the known root hash of an empty merkle trie.
|
||||||
|
EmptyMerkleHash = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")
|
||||||
)
|
)
|
||||||
|
|
||||||
// TrieRootHash returns the hash itself if it's non-empty or the predefined
|
// EmptyRootHash returns the empty root tree hash of the specific tree type.
|
||||||
// emptyHash one instead.
|
func EmptyRootHash(isVerkle bool) common.Hash {
|
||||||
func TrieRootHash(hash common.Hash) common.Hash {
|
if !isVerkle {
|
||||||
if hash == (common.Hash{}) {
|
return EmptyMerkleHash
|
||||||
log.Error("Zero trie root hash!")
|
|
||||||
return EmptyRootHash
|
|
||||||
}
|
}
|
||||||
return hash
|
return EmptyVerkleHash
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,14 @@ type StateAccount struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewEmptyStateAccount constructs an empty state account.
|
// NewEmptyStateAccount constructs an empty state account.
|
||||||
func NewEmptyStateAccount() *StateAccount {
|
func NewEmptyStateAccount(isVerkle bool) *StateAccount {
|
||||||
|
emptyRoot := EmptyMerkleHash
|
||||||
|
if isVerkle {
|
||||||
|
emptyRoot = EmptyVerkleHash
|
||||||
|
}
|
||||||
return &StateAccount{
|
return &StateAccount{
|
||||||
Balance: new(uint256.Int),
|
Balance: new(uint256.Int),
|
||||||
Root: EmptyRootHash,
|
Root: emptyRoot,
|
||||||
CodeHash: EmptyCodeHash.Bytes(),
|
CodeHash: EmptyCodeHash.Bytes(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +78,11 @@ func SlimAccountRLP(account StateAccount) []byte {
|
||||||
Nonce: account.Nonce,
|
Nonce: account.Nonce,
|
||||||
Balance: account.Balance,
|
Balance: account.Balance,
|
||||||
}
|
}
|
||||||
if account.Root != EmptyRootHash {
|
// It is highly unlikely for a valid hash (value = [32]byte{}) to appear
|
||||||
|
// in a Merkle tree, or for a valid hash (value = EmptyMerkleHash) to appear
|
||||||
|
// in a Verkle tree. Therefore, in both cases, any other value is considered
|
||||||
|
// a non-empty root hash.
|
||||||
|
if account.Root != EmptyMerkleHash && account.Root != EmptyVerkleHash {
|
||||||
slim.Root = account.Root[:]
|
slim.Root = account.Root[:]
|
||||||
}
|
}
|
||||||
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
|
if !bytes.Equal(account.CodeHash, EmptyCodeHash[:]) {
|
||||||
|
|
@ -89,7 +97,7 @@ func SlimAccountRLP(account StateAccount) []byte {
|
||||||
|
|
||||||
// FullAccount decodes the data on the 'slim RLP' format and returns
|
// FullAccount decodes the data on the 'slim RLP' format and returns
|
||||||
// the consensus format account.
|
// the consensus format account.
|
||||||
func FullAccount(data []byte) (*StateAccount, error) {
|
func FullAccount(data []byte, isVerkle bool) (*StateAccount, error) {
|
||||||
var slim SlimAccount
|
var slim SlimAccount
|
||||||
if err := rlp.DecodeBytes(data, &slim); err != nil {
|
if err := rlp.DecodeBytes(data, &slim); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -99,7 +107,11 @@ func FullAccount(data []byte) (*StateAccount, error) {
|
||||||
|
|
||||||
// Interpret the storage root and code hash in slim format.
|
// Interpret the storage root and code hash in slim format.
|
||||||
if len(slim.Root) == 0 {
|
if len(slim.Root) == 0 {
|
||||||
account.Root = EmptyRootHash
|
if isVerkle {
|
||||||
|
account.Root = EmptyVerkleHash
|
||||||
|
} else {
|
||||||
|
account.Root = EmptyMerkleHash
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
account.Root = common.BytesToHash(slim.Root)
|
account.Root = common.BytesToHash(slim.Root)
|
||||||
}
|
}
|
||||||
|
|
@ -112,8 +124,8 @@ func FullAccount(data []byte) (*StateAccount, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
|
// FullAccountRLP converts data on the 'slim RLP' format into the full RLP-format.
|
||||||
func FullAccountRLP(data []byte) ([]byte, error) {
|
func FullAccountRLP(data []byte, isVerkle bool) ([]byte, error) {
|
||||||
account, err := FullAccount(data)
|
account, err := FullAccount(data, isVerkle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ func TestProcessParentBlockHash(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.Run("MPT", func(t *testing.T) {
|
t.Run("MPT", func(t *testing.T) {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
checkBlockHashes(statedb)
|
checkBlockHashes(statedb)
|
||||||
})
|
})
|
||||||
t.Run("Verkle", func(t *testing.T) {
|
t.Run("Verkle", func(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -467,7 +467,7 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
|
||||||
storageRoot := evm.StateDB.GetStorageRoot(address)
|
storageRoot := evm.StateDB.GetStorageRoot(address)
|
||||||
if evm.StateDB.GetNonce(address) != 0 ||
|
if evm.StateDB.GetNonce(address) != 0 ||
|
||||||
(contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code
|
(contractHash != (common.Hash{}) && contractHash != types.EmptyCodeHash) || // non-empty code
|
||||||
(storageRoot != (common.Hash{}) && storageRoot != types.EmptyRootHash) { // non-empty storage
|
(storageRoot != (common.Hash{}) && storageRoot != types.EmptyMerkleHash) { // non-empty storage TODO (rjl493456442) support verkle
|
||||||
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
if evm.Config.Tracer != nil && evm.Config.Tracer.OnGasChange != nil {
|
||||||
evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution)
|
evm.Config.Tracer.OnGasChange(gas, 0, tracing.GasChangeCallFailedExecution)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ func TestEIP2200(t *testing.T) {
|
||||||
for i, tt := range eip2200Tests {
|
for i, tt := range eip2200Tests {
|
||||||
address := common.BytesToAddress([]byte("contract"))
|
address := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, hexutil.MustDecode(tt.input))
|
statedb.SetCode(address, hexutil.MustDecode(tt.input))
|
||||||
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original}))
|
||||||
|
|
@ -137,7 +137,7 @@ func TestCreateGas(t *testing.T) {
|
||||||
var gasUsed = uint64(0)
|
var gasUsed = uint64(0)
|
||||||
doCheck := func(testGas int) bool {
|
doCheck := func(testGas int) bool {
|
||||||
address := common.BytesToAddress([]byte("contract"))
|
address := common.BytesToAddress([]byte("contract"))
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, hexutil.MustDecode(tt.code))
|
statedb.SetCode(address, hexutil.MustDecode(tt.code))
|
||||||
statedb.Finalise(true)
|
statedb.Finalise(true)
|
||||||
|
|
|
||||||
|
|
@ -569,7 +569,7 @@ func BenchmarkOpMstore(bench *testing.B) {
|
||||||
|
|
||||||
func TestOpTstore(t *testing.T) {
|
func TestOpTstore(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
evm = NewEVM(BlockContext{}, statedb, params.TestChainConfig, Config{})
|
evm = NewEVM(BlockContext{}, statedb, params.TestChainConfig, Config{})
|
||||||
stack = newstack()
|
stack = newstack()
|
||||||
mem = NewMemory()
|
mem = NewMemory()
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ func TestLoopInterrupt(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range loopInterruptTests {
|
for i, tt := range loopInterruptTests {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.CreateAccount(address)
|
statedb.CreateAccount(address)
|
||||||
statedb.SetCode(address, common.Hex2Bytes(tt))
|
statedb.SetCode(address, common.Hex2Bytes(tt))
|
||||||
statedb.Finalise(true)
|
statedb.Finalise(true)
|
||||||
|
|
|
||||||
|
|
@ -116,6 +116,8 @@ func setDefaults(cfg *Config) {
|
||||||
//
|
//
|
||||||
// Execute sets up an in-memory, temporary, environment for the execution of
|
// Execute sets up an in-memory, temporary, environment for the execution of
|
||||||
// the given code. It makes sure that it's restored to its original state afterwards.
|
// the given code. It makes sure that it's restored to its original state afterwards.
|
||||||
|
//
|
||||||
|
// TODO (rjl493456442) support verkle mode.
|
||||||
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = new(Config)
|
cfg = new(Config)
|
||||||
|
|
@ -123,7 +125,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
cfg.State, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
address = common.BytesToAddress([]byte("contract"))
|
address = common.BytesToAddress([]byte("contract"))
|
||||||
|
|
@ -156,6 +158,8 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create executes the code using the EVM create method
|
// Create executes the code using the EVM create method
|
||||||
|
//
|
||||||
|
// TODO (rjl493456442) support verkle mode.
|
||||||
func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
if cfg == nil {
|
if cfg == nil {
|
||||||
cfg = new(Config)
|
cfg = new(Config)
|
||||||
|
|
@ -163,7 +167,7 @@ func Create(input []byte, cfg *Config) ([]byte, common.Address, uint64, error) {
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
|
|
||||||
if cfg.State == nil {
|
if cfg.State == nil {
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
cfg.State, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
vmenv = NewEnv(cfg)
|
vmenv = NewEnv(cfg)
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ func TestExecute(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCall(t *testing.T) {
|
func TestCall(t *testing.T) {
|
||||||
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
state, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
address := common.HexToAddress("0xaa")
|
address := common.HexToAddress("0xaa")
|
||||||
state.SetCode(address, []byte{
|
state.SetCode(address, []byte{
|
||||||
byte(vm.PUSH1), 10,
|
byte(vm.PUSH1), 10,
|
||||||
|
|
@ -162,7 +162,7 @@ func BenchmarkCall(b *testing.B) {
|
||||||
}
|
}
|
||||||
func benchmarkEVM_Create(bench *testing.B, code string) {
|
func benchmarkEVM_Create(bench *testing.B, code string) {
|
||||||
var (
|
var (
|
||||||
statedb, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
sender = common.BytesToAddress([]byte("sender"))
|
sender = common.BytesToAddress([]byte("sender"))
|
||||||
receiver = common.BytesToAddress([]byte("receiver"))
|
receiver = common.BytesToAddress([]byte("receiver"))
|
||||||
)
|
)
|
||||||
|
|
@ -228,7 +228,7 @@ func BenchmarkEVM_SWAP1(b *testing.B) {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
state, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
contractAddr := common.BytesToAddress([]byte("contract"))
|
contractAddr := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
b.Run("10k", func(b *testing.B) {
|
b.Run("10k", func(b *testing.B) {
|
||||||
|
|
@ -256,7 +256,7 @@ func BenchmarkEVM_RETURN(b *testing.B) {
|
||||||
return contract
|
return contract
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
state, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
contractAddr := common.BytesToAddress([]byte("contract"))
|
contractAddr := common.BytesToAddress([]byte("contract"))
|
||||||
|
|
||||||
for _, n := range []uint64{1_000, 10_000, 100_000, 1_000_000} {
|
for _, n := range []uint64{1_000, 10_000, 100_000, 1_000_000} {
|
||||||
|
|
@ -394,7 +394,7 @@ func TestBlockhash(t *testing.T) {
|
||||||
func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) {
|
func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode string, b *testing.B) {
|
||||||
cfg := new(Config)
|
cfg := new(Config)
|
||||||
setDefaults(cfg)
|
setDefaults(cfg)
|
||||||
cfg.State, _ = state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
cfg.State, _ = state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
cfg.GasLimit = gas
|
cfg.GasLimit = gas
|
||||||
if len(tracerCode) > 0 {
|
if len(tracerCode) > 0 {
|
||||||
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil, cfg.ChainConfig)
|
tracer, err := tracers.DefaultDirectory.New(tracerCode, new(tracers.Context), nil, cfg.ChainConfig)
|
||||||
|
|
@ -780,7 +780,7 @@ func TestRuntimeJSTracer(t *testing.T) {
|
||||||
main := common.HexToAddress("0xaa")
|
main := common.HexToAddress("0xaa")
|
||||||
for i, jsTracer := range jsTracers {
|
for i, jsTracer := range jsTracers {
|
||||||
for j, tc := range tests {
|
for j, tc := range tests {
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
statedb.SetCode(main, tc.code)
|
statedb.SetCode(main, tc.code)
|
||||||
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
|
statedb.SetCode(common.HexToAddress("0xbb"), calleeCode)
|
||||||
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
|
statedb.SetCode(common.HexToAddress("0xcc"), calleeCode)
|
||||||
|
|
@ -822,7 +822,7 @@ func TestJSTracerCreateTx(t *testing.T) {
|
||||||
exit: function(res) { this.exits++ }}`
|
exit: function(res) { this.exits++ }}`
|
||||||
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
|
code := []byte{byte(vm.PUSH1), 0, byte(vm.PUSH1), 0, byte(vm.RETURN)}
|
||||||
|
|
||||||
statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting())
|
statedb, _ := state.New(types.EmptyMerkleHash, state.NewDatabaseForTesting())
|
||||||
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.MergedTestChainConfig)
|
tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.MergedTestChainConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|
|
||||||
|
|
@ -231,7 +231,7 @@ func (api *DebugAPI) StorageRangeAt(ctx context.Context, blockNrOrHash rpc.Block
|
||||||
|
|
||||||
func storageRangeAt(statedb *state.StateDB, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) {
|
func storageRangeAt(statedb *state.StateDB, root common.Hash, address common.Address, start []byte, maxResult int) (StorageRangeResult, error) {
|
||||||
storageRoot := statedb.GetStorageRoot(address)
|
storageRoot := statedb.GetStorageRoot(address)
|
||||||
if storageRoot == types.EmptyRootHash || storageRoot == (common.Hash{}) {
|
if storageRoot == types.EmptyMerkleHash || storageRoot == (common.Hash{}) {
|
||||||
return StorageRangeResult{}, nil // empty storage
|
return StorageRangeResult{}, nil // empty storage
|
||||||
}
|
}
|
||||||
id := trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
|
id := trie.StorageTrieID(root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func TestAccountRange(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
mdb = rawdb.NewMemoryDatabase()
|
mdb = rawdb.NewMemoryDatabase()
|
||||||
statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), nil)
|
statedb = state.NewDatabase(triedb.NewDatabase(mdb, &triedb.Config{Preimages: true}), nil)
|
||||||
sdb, _ = state.New(types.EmptyRootHash, statedb)
|
sdb, _ = state.New(types.EmptyMerkleHash, statedb)
|
||||||
addrs = [AccountRangeMaxResults * 2]common.Address{}
|
addrs = [AccountRangeMaxResults * 2]common.Address{}
|
||||||
m = map[common.Address]bool{}
|
m = map[common.Address]bool{}
|
||||||
)
|
)
|
||||||
|
|
@ -137,11 +137,11 @@ func TestEmptyAccountRange(t *testing.T) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
statedb = state.NewDatabaseForTesting()
|
statedb = state.NewDatabaseForTesting()
|
||||||
st, _ = state.New(types.EmptyRootHash, statedb)
|
st, _ = state.New(types.EmptyMerkleHash, statedb)
|
||||||
)
|
)
|
||||||
// Commit(although nothing to flush) and re-init the statedb
|
// Commit(although nothing to flush) and re-init the statedb
|
||||||
st.Commit(0, true)
|
st.Commit(0, true)
|
||||||
st, _ = state.New(types.EmptyRootHash, statedb)
|
st, _ = state.New(types.EmptyMerkleHash, statedb)
|
||||||
|
|
||||||
results := st.RawDump(&state.DumpConfig{
|
results := st.RawDump(&state.DumpConfig{
|
||||||
SkipCode: true,
|
SkipCode: true,
|
||||||
|
|
@ -165,7 +165,7 @@ func TestStorageRangeAt(t *testing.T) {
|
||||||
mdb = rawdb.NewMemoryDatabase()
|
mdb = rawdb.NewMemoryDatabase()
|
||||||
tdb = triedb.NewDatabase(mdb, &triedb.Config{Preimages: true})
|
tdb = triedb.NewDatabase(mdb, &triedb.Config{Preimages: true})
|
||||||
db = state.NewDatabase(tdb, nil)
|
db = state.NewDatabase(tdb, nil)
|
||||||
sdb, _ = state.New(types.EmptyRootHash, db)
|
sdb, _ = state.New(types.EmptyMerkleHash, db)
|
||||||
addr = common.Address{0x01}
|
addr = common.Address{0x01}
|
||||||
keys = []common.Hash{ // hashes of Keys of storage
|
keys = []common.Hash{ // hashes of Keys of storage
|
||||||
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
common.HexToHash("340dd630ad21bf010b4e676dbfa9ba9a02175262d1fa356232cfde6cb5b47ef2"),
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ func ServiceGetReceiptsQuery(chain *core.BlockChain, query GetReceiptsRequest) [
|
||||||
// Retrieve the requested block's receipts
|
// Retrieve the requested block's receipts
|
||||||
results := chain.GetReceiptsByHash(hash)
|
results := chain.GetReceiptsByHash(hash)
|
||||||
if results == nil {
|
if results == nil {
|
||||||
if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyRootHash {
|
if header := chain.GetHeaderByHash(hash); header == nil || header.ReceiptHash != types.EmptyMerkleHash {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,7 +104,7 @@ func (p *AccountRangePacket) Unpack() ([]common.Hash, [][]byte, error) {
|
||||||
accounts = make([][]byte, len(p.Accounts))
|
accounts = make([][]byte, len(p.Accounts))
|
||||||
)
|
)
|
||||||
for i, acc := range p.Accounts {
|
for i, acc := range p.Accounts {
|
||||||
val, err := types.FullAccountRLP(acc.Body)
|
val, err := types.FullAccountRLP(acc.Body, false) // TODO support verkle snap sync
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err)
|
return nil, nil, fmt.Errorf("invalid account %x: %v", acc.Body, err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1907,7 +1907,7 @@ func (s *Syncer) processAccountResponse(res *accountResponse) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if the account is a contract with an unknown storage trie
|
// Check if the account is a contract with an unknown storage trie
|
||||||
if account.Root != types.EmptyRootHash {
|
if account.Root != types.EmptyMerkleHash {
|
||||||
// If the storage was already retrieved in the last cycle, there's no need
|
// If the storage was already retrieved in the last cycle, there's no need
|
||||||
// to resync it again, regardless of whether the storage root is consistent
|
// to resync it again, regardless of whether the storage root is consistent
|
||||||
// or not.
|
// or not.
|
||||||
|
|
@ -2422,7 +2422,7 @@ func (s *Syncer) forwardAccountTask(task *accountTask) {
|
||||||
if !task.needHeal[i] {
|
if !task.needHeal[i] {
|
||||||
// If the storage task is complete, drop it into the stack trie
|
// If the storage task is complete, drop it into the stack trie
|
||||||
// to generate account trie nodes for it
|
// to generate account trie nodes for it
|
||||||
full, err := types.FullAccountRLP(slim) // TODO(karalabe): Slim parsing can be omitted
|
full, err := types.FullAccountRLP(slim, false) // TODO(karalabe): Slim parsing can be omitted
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err) // Really shouldn't ever happen
|
panic(err) // Really shouldn't ever happen
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1502,7 +1502,7 @@ func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv)
|
||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: i,
|
Nonce: i,
|
||||||
Balance: uint256.NewInt(i),
|
Balance: uint256.NewInt(i),
|
||||||
Root: types.EmptyRootHash,
|
Root: types.EmptyMerkleHash,
|
||||||
CodeHash: getCodeHash(i),
|
CodeHash: getCodeHash(i),
|
||||||
})
|
})
|
||||||
key := key32(i)
|
key := key32(i)
|
||||||
|
|
@ -1515,7 +1515,7 @@ func makeAccountTrieNoStorage(n int, scheme string) (string, *trie.Trie, []*kv)
|
||||||
// Commit the state changes into db and re-create the trie
|
// Commit the state changes into db and re-create the trie
|
||||||
// for accessing later.
|
// for accessing later.
|
||||||
root, nodes := accTrie.Commit(false)
|
root, nodes := accTrie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
|
db.Update(root, types.EmptyMerkleHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
|
||||||
|
|
||||||
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
||||||
return db.Scheme(), accTrie, entries
|
return db.Scheme(), accTrie, entries
|
||||||
|
|
@ -1553,7 +1553,7 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
|
||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: uint64(0),
|
Nonce: uint64(0),
|
||||||
Balance: uint256.NewInt(uint64(i)),
|
Balance: uint256.NewInt(uint64(i)),
|
||||||
Root: types.EmptyRootHash,
|
Root: types.EmptyMerkleHash,
|
||||||
CodeHash: getCodeHash(uint64(i)),
|
CodeHash: getCodeHash(uint64(i)),
|
||||||
})
|
})
|
||||||
elem := &kv{boundaries[i].Bytes(), value}
|
elem := &kv{boundaries[i].Bytes(), value}
|
||||||
|
|
@ -1565,7 +1565,7 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
|
||||||
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
value, _ := rlp.EncodeToBytes(&types.StateAccount{
|
||||||
Nonce: i,
|
Nonce: i,
|
||||||
Balance: uint256.NewInt(i),
|
Balance: uint256.NewInt(i),
|
||||||
Root: types.EmptyRootHash,
|
Root: types.EmptyMerkleHash,
|
||||||
CodeHash: getCodeHash(i),
|
CodeHash: getCodeHash(i),
|
||||||
})
|
})
|
||||||
elem := &kv{key32(i), value}
|
elem := &kv{key32(i), value}
|
||||||
|
|
@ -1577,7 +1577,7 @@ func makeBoundaryAccountTrie(scheme string, n int) (string, *trie.Trie, []*kv) {
|
||||||
// Commit the state changes into db and re-create the trie
|
// Commit the state changes into db and re-create the trie
|
||||||
// for accessing later.
|
// for accessing later.
|
||||||
root, nodes := accTrie.Commit(false)
|
root, nodes := accTrie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
|
db.Update(root, types.EmptyMerkleHash, 0, trienode.NewWithNodeSet(nodes), triedb.NewStateSet())
|
||||||
|
|
||||||
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
||||||
return db.Scheme(), accTrie, entries
|
return db.Scheme(), accTrie, entries
|
||||||
|
|
@ -1626,7 +1626,7 @@ func makeAccountTrieWithStorageWithUniqueStorage(scheme string, accounts, slots
|
||||||
nodes.Merge(set)
|
nodes.Merge(set)
|
||||||
|
|
||||||
// Commit gathered dirty nodes into database
|
// Commit gathered dirty nodes into database
|
||||||
db.Update(root, types.EmptyRootHash, 0, nodes, triedb.NewStateSet())
|
db.Update(root, types.EmptyMerkleHash, 0, nodes, triedb.NewStateSet())
|
||||||
|
|
||||||
// Re-create tries with new root
|
// Re-create tries with new root
|
||||||
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
accTrie, _ = trie.New(trie.StateTrieID(root), db)
|
||||||
|
|
@ -1693,7 +1693,7 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda
|
||||||
nodes.Merge(set)
|
nodes.Merge(set)
|
||||||
|
|
||||||
// Commit gathered dirty nodes into database
|
// Commit gathered dirty nodes into database
|
||||||
db.Update(root, types.EmptyRootHash, 0, nodes, triedb.NewStateSet())
|
db.Update(root, types.EmptyMerkleHash, 0, nodes, triedb.NewStateSet())
|
||||||
|
|
||||||
// Re-create tries with new root
|
// Re-create tries with new root
|
||||||
accTrie, err := trie.New(trie.StateTrieID(root), db)
|
accTrie, err := trie.New(trie.StateTrieID(root), db)
|
||||||
|
|
@ -1716,7 +1716,7 @@ func makeAccountTrieWithStorage(scheme string, accounts, slots int, code, bounda
|
||||||
// not-yet-committed trie and the sorted entries. The seeds can be used to ensure
|
// not-yet-committed trie and the sorted entries. The seeds can be used to ensure
|
||||||
// that tries are unique.
|
// that tries are unique.
|
||||||
func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *triedb.Database) (common.Hash, *trienode.NodeSet, []*kv) {
|
func makeStorageTrieWithSeed(owner common.Hash, n, seed uint64, db *triedb.Database) (common.Hash, *trienode.NodeSet, []*kv) {
|
||||||
trie, _ := trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
|
trie, _ := trie.New(trie.StorageTrieID(types.EmptyMerkleHash, owner, types.EmptyMerkleHash), db)
|
||||||
var entries []*kv
|
var entries []*kv
|
||||||
for i := uint64(1); i <= n; i++ {
|
for i := uint64(1); i <= n; i++ {
|
||||||
// store 'x' at slot 'x'
|
// store 'x' at slot 'x'
|
||||||
|
|
@ -1742,7 +1742,7 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *triedb.Database) (com
|
||||||
var (
|
var (
|
||||||
entries []*kv
|
entries []*kv
|
||||||
boundaries []common.Hash
|
boundaries []common.Hash
|
||||||
trie, _ = trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
|
trie, _ = trie.New(trie.StorageTrieID(types.EmptyMerkleHash, owner, types.EmptyMerkleHash), db)
|
||||||
)
|
)
|
||||||
// Initialize boundaries
|
// Initialize boundaries
|
||||||
var next common.Hash
|
var next common.Hash
|
||||||
|
|
@ -1791,7 +1791,7 @@ func makeBoundaryStorageTrie(owner common.Hash, n int, db *triedb.Database) (com
|
||||||
func makeUnevenStorageTrie(owner common.Hash, slots int, db *triedb.Database) (common.Hash, *trienode.NodeSet, []*kv) {
|
func makeUnevenStorageTrie(owner common.Hash, slots int, db *triedb.Database) (common.Hash, *trienode.NodeSet, []*kv) {
|
||||||
var (
|
var (
|
||||||
entries []*kv
|
entries []*kv
|
||||||
tr, _ = trie.New(trie.StorageTrieID(types.EmptyRootHash, owner, types.EmptyRootHash), db)
|
tr, _ = trie.New(trie.StorageTrieID(types.EmptyMerkleHash, owner, types.EmptyMerkleHash), db)
|
||||||
chosen = make(map[byte]struct{})
|
chosen = make(map[byte]struct{})
|
||||||
)
|
)
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
|
|
@ -1838,7 +1838,7 @@ func verifyTrie(scheme string, db ethdb.KeyValueStore, root common.Hash, t *test
|
||||||
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
log.Crit("Invalid account encountered during snapshot creation", "err", err)
|
||||||
}
|
}
|
||||||
accounts++
|
accounts++
|
||||||
if acc.Root != types.EmptyRootHash {
|
if acc.Root != types.EmptyMerkleHash {
|
||||||
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
id := trie.StorageTrieID(root, common.BytesToHash(accIt.Key), acc.Root)
|
||||||
storeTrie, err := trie.NewStateTrie(id, triedb)
|
storeTrie, err := trie.NewStateTrie(id, triedb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,8 @@ func (n *proofList) Delete(key []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProof returns the Merkle-proof for a given account and optionally some storage keys.
|
// GetProof returns the Merkle-proof for a given account and optionally some storage keys.
|
||||||
|
//
|
||||||
|
// TODO (rjl493456442) This function needs to be rewritten for verkle compatibility.
|
||||||
func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) {
|
func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNrOrHash rpc.BlockNumberOrHash) (*AccountResult, error) {
|
||||||
var (
|
var (
|
||||||
keys = make([]common.Hash, len(storageKeys))
|
keys = make([]common.Hash, len(storageKeys))
|
||||||
|
|
@ -385,7 +387,7 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address,
|
||||||
|
|
||||||
if len(keys) > 0 {
|
if len(keys) > 0 {
|
||||||
var storageTrie state.Trie
|
var storageTrie state.Trie
|
||||||
if storageRoot != types.EmptyRootHash && storageRoot != (common.Hash{}) {
|
if storageRoot != types.EmptyMerkleHash && storageRoot != (common.Hash{}) {
|
||||||
id := trie.StorageTrieID(header.Root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
|
id := trie.StorageTrieID(header.Root, crypto.Keccak256Hash(address.Bytes()), storageRoot)
|
||||||
st, err := trie.NewStateTrie(id, statedb.Database().TrieDB())
|
st, err := trie.NewStateTrie(id, statedb.Database().TrieDB())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -198,7 +198,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
||||||
AccessList: types.AccessList{
|
AccessList: types.AccessList{
|
||||||
types.AccessTuple{
|
types.AccessTuple{
|
||||||
Address: common.Address{0x2},
|
Address: common.Address{0x2},
|
||||||
StorageKeys: []common.Hash{types.EmptyRootHash},
|
StorageKeys: []common.Hash{types.EmptyMerkleHash},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
V: big.NewInt(32),
|
V: big.NewInt(32),
|
||||||
|
|
@ -244,7 +244,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
||||||
AccessList: types.AccessList{
|
AccessList: types.AccessList{
|
||||||
types.AccessTuple{
|
types.AccessTuple{
|
||||||
Address: common.Address{0x2},
|
Address: common.Address{0x2},
|
||||||
StorageKeys: []common.Hash{types.EmptyRootHash},
|
StorageKeys: []common.Hash{types.EmptyMerkleHash},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
V: big.NewInt(32),
|
V: big.NewInt(32),
|
||||||
|
|
@ -291,7 +291,7 @@ func allTransactionTypes(addr common.Address, config *params.ChainConfig) []txDa
|
||||||
AccessList: types.AccessList{
|
AccessList: types.AccessList{
|
||||||
types.AccessTuple{
|
types.AccessTuple{
|
||||||
Address: common.Address{0x2},
|
Address: common.Address{0x2},
|
||||||
StorageKeys: []common.Hash{types.EmptyRootHash},
|
StorageKeys: []common.Hash{types.EmptyMerkleHash},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
V: big.NewInt(32),
|
V: big.NewInt(32),
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,9 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo
|
||||||
}
|
}
|
||||||
triedb := triedb.NewDatabase(db, tconf)
|
triedb := triedb.NewDatabase(db, tconf)
|
||||||
sdb := state.NewDatabase(triedb, nil)
|
sdb := state.NewDatabase(triedb, nil)
|
||||||
statedb, _ := state.New(types.EmptyRootHash, sdb)
|
|
||||||
|
// TODO (rjl493456442) support verkle state tests
|
||||||
|
statedb, _ := state.New(types.EmptyMerkleHash, sdb)
|
||||||
for addr, a := range accounts {
|
for addr, a := range accounts {
|
||||||
statedb.SetCode(addr, a.Code)
|
statedb.SetCode(addr, a.Code)
|
||||||
statedb.SetNonce(addr, a.Nonce)
|
statedb.SetNonce(addr, a.Nonce)
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ type testDb struct {
|
||||||
func newTestDatabase(diskdb ethdb.Database, scheme string) *testDb {
|
func newTestDatabase(diskdb ethdb.Database, scheme string) *testDb {
|
||||||
return &testDb{
|
return &testDb{
|
||||||
disk: diskdb,
|
disk: diskdb,
|
||||||
root: types.EmptyRootHash,
|
root: types.EmptyMerkleHash,
|
||||||
scheme: scheme,
|
scheme: scheme,
|
||||||
nodes: make(map[common.Hash]*trienode.MergedNodeSet),
|
nodes: make(map[common.Hash]*trienode.MergedNodeSet),
|
||||||
parents: make(map[common.Hash]common.Hash),
|
parents: make(map[common.Hash]common.Hash),
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ func (e seekError) Error() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
|
func newNodeIterator(trie *Trie, start []byte) NodeIterator {
|
||||||
if trie.Hash() == types.EmptyRootHash {
|
if trie.Hash() == types.EmptyMerkleHash {
|
||||||
return &nodeIterator{
|
return &nodeIterator{
|
||||||
trie: trie,
|
trie: trie,
|
||||||
err: errIteratorEnd,
|
err: errIteratorEnd,
|
||||||
|
|
@ -323,7 +323,7 @@ func (it *nodeIterator) seek(prefix []byte) error {
|
||||||
func (it *nodeIterator) init() (*nodeIteratorState, error) {
|
func (it *nodeIterator) init() (*nodeIteratorState, error) {
|
||||||
root := it.trie.Hash()
|
root := it.trie.Hash()
|
||||||
state := &nodeIteratorState{node: it.trie.root, index: -1}
|
state := &nodeIteratorState{node: it.trie.root, index: -1}
|
||||||
if root != types.EmptyRootHash {
|
if root != types.EmptyMerkleHash {
|
||||||
state.hash = root
|
state.hash = root
|
||||||
}
|
}
|
||||||
return state, state.resolve(it, nil)
|
return state, state.resolve(it, nil)
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ func TestIterator(t *testing.T) {
|
||||||
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
trie, _ = New(TrieID(root), db)
|
trie, _ = New(TrieID(root), db)
|
||||||
found := make(map[string]string)
|
found := make(map[string]string)
|
||||||
|
|
@ -258,7 +258,7 @@ func TestDifferenceIterator(t *testing.T) {
|
||||||
triea.MustUpdate([]byte(val.k), []byte(val.v))
|
triea.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
rootA, nodesA := triea.Commit(false)
|
rootA, nodesA := triea.Commit(false)
|
||||||
dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA))
|
dba.Update(rootA, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesA))
|
||||||
triea, _ = New(TrieID(rootA), dba)
|
triea, _ = New(TrieID(rootA), dba)
|
||||||
|
|
||||||
dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
||||||
|
|
@ -267,7 +267,7 @@ func TestDifferenceIterator(t *testing.T) {
|
||||||
trieb.MustUpdate([]byte(val.k), []byte(val.v))
|
trieb.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
rootB, nodesB := trieb.Commit(false)
|
rootB, nodesB := trieb.Commit(false)
|
||||||
dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB))
|
dbb.Update(rootB, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesB))
|
||||||
trieb, _ = New(TrieID(rootB), dbb)
|
trieb, _ = New(TrieID(rootB), dbb)
|
||||||
|
|
||||||
found := make(map[string]string)
|
found := make(map[string]string)
|
||||||
|
|
@ -300,7 +300,7 @@ func TestUnionIterator(t *testing.T) {
|
||||||
triea.MustUpdate([]byte(val.k), []byte(val.v))
|
triea.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
rootA, nodesA := triea.Commit(false)
|
rootA, nodesA := triea.Commit(false)
|
||||||
dba.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA))
|
dba.Update(rootA, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesA))
|
||||||
triea, _ = New(TrieID(rootA), dba)
|
triea, _ = New(TrieID(rootA), dba)
|
||||||
|
|
||||||
dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
dbb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
||||||
|
|
@ -309,7 +309,7 @@ func TestUnionIterator(t *testing.T) {
|
||||||
trieb.MustUpdate([]byte(val.k), []byte(val.v))
|
trieb.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
rootB, nodesB := trieb.Commit(false)
|
rootB, nodesB := trieb.Commit(false)
|
||||||
dbb.Update(rootB, types.EmptyRootHash, trienode.NewWithNodeSet(nodesB))
|
dbb.Update(rootB, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesB))
|
||||||
trieb, _ = New(TrieID(rootB), dbb)
|
trieb, _ = New(TrieID(rootB), dbb)
|
||||||
|
|
||||||
di, _ := NewUnionIterator([]NodeIterator{triea.MustNodeIterator(nil), trieb.MustNodeIterator(nil)})
|
di, _ := NewUnionIterator([]NodeIterator{triea.MustNodeIterator(nil), trieb.MustNodeIterator(nil)})
|
||||||
|
|
@ -372,7 +372,7 @@ func testIteratorContinueAfterError(t *testing.T, memonly bool, scheme string) {
|
||||||
tr.MustUpdate([]byte(val.k), []byte(val.v))
|
tr.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
root, nodes := tr.Commit(false)
|
root, nodes := tr.Commit(false)
|
||||||
tdb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
tdb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
if !memonly {
|
if !memonly {
|
||||||
tdb.Commit(root)
|
tdb.Commit(root)
|
||||||
}
|
}
|
||||||
|
|
@ -488,7 +488,7 @@ func testIteratorContinueAfterSeekError(t *testing.T, memonly bool, scheme strin
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
triedb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
if !memonly {
|
if !memonly {
|
||||||
triedb.Commit(root)
|
triedb.Commit(root)
|
||||||
}
|
}
|
||||||
|
|
@ -562,7 +562,7 @@ func testIteratorNodeBlob(t *testing.T, scheme string) {
|
||||||
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
triedb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
triedb.Commit(root)
|
triedb.Commit(root)
|
||||||
|
|
||||||
var found = make(map[common.Hash][]byte)
|
var found = make(map[common.Hash][]byte)
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func newEmptySecure() *StateTrie {
|
func newEmptySecure() *StateTrie {
|
||||||
trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
|
trie, _ := NewStateTrie(TrieID(types.EmptyMerkleHash), newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
|
||||||
return trie
|
return trie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,7 +39,7 @@ func newEmptySecure() *StateTrie {
|
||||||
func makeTestStateTrie() (*testDb, *StateTrie, map[string][]byte) {
|
func makeTestStateTrie() (*testDb, *StateTrie, map[string][]byte) {
|
||||||
// Create an empty trie
|
// Create an empty trie
|
||||||
triedb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
triedb := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)
|
||||||
trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), triedb)
|
trie, _ := NewStateTrie(TrieID(types.EmptyMerkleHash), triedb)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
content := make(map[string][]byte)
|
content := make(map[string][]byte)
|
||||||
|
|
@ -61,7 +61,7 @@ func makeTestStateTrie() (*testDb, *StateTrie, map[string][]byte) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil {
|
if err := triedb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes)); err != nil {
|
||||||
panic(fmt.Errorf("failed to commit db %v", err))
|
panic(fmt.Errorf("failed to commit db %v", err))
|
||||||
}
|
}
|
||||||
// Re-create the trie based on the new state
|
// Re-create the trie based on the new state
|
||||||
|
|
|
||||||
|
|
@ -312,7 +312,7 @@ func (t *StackTrie) hash(st *stNode, path []byte) {
|
||||||
return
|
return
|
||||||
|
|
||||||
case emptyNode:
|
case emptyNode:
|
||||||
st.val = types.EmptyRootHash.Bytes()
|
st.val = types.EmptyMerkleHash.Bytes()
|
||||||
st.key = st.key[:0]
|
st.key = st.key[:0]
|
||||||
st.typ = hashedNode
|
st.typ = hashedNode
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ func fuzz(data []byte, debugging bool) {
|
||||||
// Flush trie -> database
|
// Flush trie -> database
|
||||||
rootA, nodes := trieA.Commit(false)
|
rootA, nodes := trieA.Commit(false)
|
||||||
if nodes != nil {
|
if nodes != nil {
|
||||||
dbA.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
dbA.Update(rootA, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
}
|
}
|
||||||
// Flush memdb -> disk (sponge)
|
// Flush memdb -> disk (sponge)
|
||||||
dbA.Commit(rootA)
|
dbA.Commit(rootA)
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,7 @@ func NewSync(root common.Hash, database ethdb.KeyValueReader, callback LeafCallb
|
||||||
// parent for completion tracking. The given path is a unique node path in
|
// parent for completion tracking. The given path is a unique node path in
|
||||||
// hex format and contain all the parent path if it's layered trie node.
|
// hex format and contain all the parent path if it's layered trie node.
|
||||||
func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, parentPath []byte, callback LeafCallback) {
|
func (s *Sync) AddSubTrie(root common.Hash, path []byte, parent common.Hash, parentPath []byte, callback LeafCallback) {
|
||||||
if root == types.EmptyRootHash {
|
if root == types.EmptyMerkleHash {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
owner, inner := ResolvePath(path)
|
owner, inner := ResolvePath(path)
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ func makeTestTrie(scheme string) (ethdb.Database, *testDb, *StateTrie, map[strin
|
||||||
// Create an empty trie
|
// Create an empty trie
|
||||||
db := rawdb.NewMemoryDatabase()
|
db := rawdb.NewMemoryDatabase()
|
||||||
triedb := newTestDatabase(db, scheme)
|
triedb := newTestDatabase(db, scheme)
|
||||||
trie, _ := NewStateTrie(TrieID(types.EmptyRootHash), triedb)
|
trie, _ := NewStateTrie(TrieID(types.EmptyMerkleHash), triedb)
|
||||||
|
|
||||||
// Fill it with some arbitrary data
|
// Fill it with some arbitrary data
|
||||||
content := make(map[string][]byte)
|
content := make(map[string][]byte)
|
||||||
|
|
@ -59,7 +59,7 @@ func makeTestTrie(scheme string) (ethdb.Database, *testDb, *StateTrie, map[strin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
if err := triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)); err != nil {
|
if err := triedb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes)); err != nil {
|
||||||
panic(fmt.Errorf("failed to commit db %v", err))
|
panic(fmt.Errorf("failed to commit db %v", err))
|
||||||
}
|
}
|
||||||
if err := triedb.Commit(root); err != nil {
|
if err := triedb.Commit(root); err != nil {
|
||||||
|
|
@ -139,9 +139,9 @@ func TestEmptySync(t *testing.T) {
|
||||||
dbD := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme)
|
dbD := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme)
|
||||||
|
|
||||||
emptyA := NewEmpty(dbA)
|
emptyA := NewEmpty(dbA)
|
||||||
emptyB, _ := New(TrieID(types.EmptyRootHash), dbB)
|
emptyB, _ := New(TrieID(types.EmptyMerkleHash), dbB)
|
||||||
emptyC := NewEmpty(dbC)
|
emptyC := NewEmpty(dbC)
|
||||||
emptyD, _ := New(TrieID(types.EmptyRootHash), dbD)
|
emptyD, _ := New(TrieID(types.EmptyMerkleHash), dbD)
|
||||||
|
|
||||||
for i, trie := range []*Trie{emptyA, emptyB, emptyC, emptyD} {
|
for i, trie := range []*Trie{emptyA, emptyB, emptyC, emptyD} {
|
||||||
sync := NewSync(trie.Hash(), memorydb.New(), nil, []*testDb{dbA, dbB, dbC, dbD}[i].Scheme())
|
sync := NewSync(trie.Hash(), memorydb.New(), nil, []*testDb{dbA, dbB, dbC, dbD}[i].Scheme())
|
||||||
|
|
@ -821,7 +821,7 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) {
|
||||||
var (
|
var (
|
||||||
srcDisk = rawdb.NewMemoryDatabase()
|
srcDisk = rawdb.NewMemoryDatabase()
|
||||||
srcTrieDB = newTestDatabase(srcDisk, scheme)
|
srcTrieDB = newTestDatabase(srcDisk, scheme)
|
||||||
srcTrie, _ = New(TrieID(types.EmptyRootHash), srcTrieDB)
|
srcTrie, _ = New(TrieID(types.EmptyMerkleHash), srcTrieDB)
|
||||||
|
|
||||||
deleteFn = func(key []byte, tr *Trie, states map[string][]byte) {
|
deleteFn = func(key []byte, tr *Trie, states map[string][]byte) {
|
||||||
tr.Delete(key)
|
tr.Delete(key)
|
||||||
|
|
@ -848,7 +848,7 @@ func testPivotMove(t *testing.T, scheme string, tiny bool) {
|
||||||
writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateA)
|
writeFn([]byte{0x13, 0x44}, nil, srcTrie, stateA)
|
||||||
|
|
||||||
rootA, nodesA := srcTrie.Commit(false)
|
rootA, nodesA := srcTrie.Commit(false)
|
||||||
if err := srcTrieDB.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)); err != nil {
|
if err := srcTrieDB.Update(rootA, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesA)); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := srcTrieDB.Commit(rootA); err != nil {
|
if err := srcTrieDB.Commit(rootA); err != nil {
|
||||||
|
|
@ -922,7 +922,7 @@ func testSyncAbort(t *testing.T, scheme string) {
|
||||||
var (
|
var (
|
||||||
srcDisk = rawdb.NewMemoryDatabase()
|
srcDisk = rawdb.NewMemoryDatabase()
|
||||||
srcTrieDB = newTestDatabase(srcDisk, scheme)
|
srcTrieDB = newTestDatabase(srcDisk, scheme)
|
||||||
srcTrie, _ = New(TrieID(types.EmptyRootHash), srcTrieDB)
|
srcTrie, _ = New(TrieID(types.EmptyMerkleHash), srcTrieDB)
|
||||||
|
|
||||||
deleteFn = func(key []byte, tr *Trie, states map[string][]byte) {
|
deleteFn = func(key []byte, tr *Trie, states map[string][]byte) {
|
||||||
tr.Delete(key)
|
tr.Delete(key)
|
||||||
|
|
@ -947,7 +947,7 @@ func testSyncAbort(t *testing.T, scheme string) {
|
||||||
writeFn(key, val, srcTrie, stateA)
|
writeFn(key, val, srcTrie, stateA)
|
||||||
|
|
||||||
rootA, nodesA := srcTrie.Commit(false)
|
rootA, nodesA := srcTrie.Commit(false)
|
||||||
if err := srcTrieDB.Update(rootA, types.EmptyRootHash, trienode.NewWithNodeSet(nodesA)); err != nil {
|
if err := srcTrieDB.Update(rootA, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodesA)); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
if err := srcTrieDB.Commit(rootA); err != nil {
|
if err := srcTrieDB.Commit(rootA); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) {
|
||||||
insertSet := copySet(trie.tracer.inserts) // copy before commit
|
insertSet := copySet(trie.tracer.inserts) // copy before commit
|
||||||
deleteSet := copySet(trie.tracer.deletes) // copy before commit
|
deleteSet := copySet(trie.tracer.deletes) // copy before commit
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
seen := setKeys(iterNodes(db, root))
|
seen := setKeys(iterNodes(db, root))
|
||||||
if !compareSet(insertSet, seen) {
|
if !compareSet(insertSet, seen) {
|
||||||
|
|
@ -138,7 +138,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) {
|
||||||
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
trie, _ = New(TrieID(root), db)
|
trie, _ = New(TrieID(root), db)
|
||||||
if err := verifyAccessList(orig, trie, nodes); err != nil {
|
if err := verifyAccessList(orig, trie, nodes); err != nil {
|
||||||
|
|
@ -220,7 +220,7 @@ func TestAccessListLeak(t *testing.T) {
|
||||||
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
trie.MustUpdate([]byte(val.k), []byte(val.v))
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
var cases = []struct {
|
var cases = []struct {
|
||||||
op func(tr *Trie)
|
op func(tr *Trie)
|
||||||
|
|
@ -270,7 +270,7 @@ func TestTinyTree(t *testing.T) {
|
||||||
trie.MustUpdate([]byte(val.k), randBytes(32))
|
trie.MustUpdate([]byte(val.k), randBytes(32))
|
||||||
}
|
}
|
||||||
root, set := trie.Commit(false)
|
root, set := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(set))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(set))
|
||||||
|
|
||||||
parent := root
|
parent := root
|
||||||
trie, _ = New(TrieID(root), db)
|
trie, _ = New(TrieID(root), db)
|
||||||
|
|
|
||||||
12
trie/trie.go
12
trie/trie.go
|
|
@ -84,7 +84,7 @@ func (t *Trie) Copy() *Trie {
|
||||||
// empty, otherwise, the root node must be present in database or returns
|
// empty, otherwise, the root node must be present in database or returns
|
||||||
// a MissingNodeError if not.
|
// a MissingNodeError if not.
|
||||||
func New(id *ID, db database.NodeDatabase) (*Trie, error) {
|
func New(id *ID, db database.NodeDatabase) (*Trie, error) {
|
||||||
reader, err := newTrieReader(id.StateRoot, id.Owner, db)
|
reader, err := newTrieReader(false, id.StateRoot, id.Owner, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ func New(id *ID, db database.NodeDatabase) (*Trie, error) {
|
||||||
reader: reader,
|
reader: reader,
|
||||||
tracer: newTracer(),
|
tracer: newTracer(),
|
||||||
}
|
}
|
||||||
if id.Root != (common.Hash{}) && id.Root != types.EmptyRootHash {
|
if id.Root != types.EmptyMerkleHash {
|
||||||
rootnode, err := trie.resolveAndTrack(id.Root[:], nil)
|
rootnode, err := trie.resolveAndTrack(id.Root[:], nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -105,7 +105,7 @@ func New(id *ID, db database.NodeDatabase) (*Trie, error) {
|
||||||
|
|
||||||
// NewEmpty is a shortcut to create empty tree. It's mostly used in tests.
|
// NewEmpty is a shortcut to create empty tree. It's mostly used in tests.
|
||||||
func NewEmpty(db database.NodeDatabase) *Trie {
|
func NewEmpty(db database.NodeDatabase) *Trie {
|
||||||
tr, _ := New(TrieID(types.EmptyRootHash), db)
|
tr, _ := New(TrieID(types.EmptyMerkleHash), db)
|
||||||
return tr
|
return tr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -621,13 +621,13 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) {
|
||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
paths := t.tracer.deletedNodes()
|
paths := t.tracer.deletedNodes()
|
||||||
if len(paths) == 0 {
|
if len(paths) == 0 {
|
||||||
return types.EmptyRootHash, nil // case (a)
|
return types.EmptyMerkleHash, nil // case (a)
|
||||||
}
|
}
|
||||||
nodes := trienode.NewNodeSet(t.owner)
|
nodes := trienode.NewNodeSet(t.owner)
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
nodes.AddNode([]byte(path), trienode.NewDeleted())
|
nodes.AddNode([]byte(path), trienode.NewDeleted())
|
||||||
}
|
}
|
||||||
return types.EmptyRootHash, nodes // case (b)
|
return types.EmptyMerkleHash, nodes // case (b)
|
||||||
}
|
}
|
||||||
// Derive the hash for all dirty nodes first. We hold the assumption
|
// Derive the hash for all dirty nodes first. We hold the assumption
|
||||||
// in the following procedure that all nodes are hashed.
|
// in the following procedure that all nodes are hashed.
|
||||||
|
|
@ -654,7 +654,7 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) {
|
||||||
// hashRoot calculates the root hash of the given trie
|
// hashRoot calculates the root hash of the given trie
|
||||||
func (t *Trie) hashRoot() (node, node) {
|
func (t *Trie) hashRoot() (node, node) {
|
||||||
if t.root == nil {
|
if t.root == nil {
|
||||||
return hashNode(types.EmptyRootHash.Bytes()), nil
|
return hashNode(types.EmptyMerkleHash.Bytes()), nil
|
||||||
}
|
}
|
||||||
// If the number of changes is below 100, we let one thread handle it
|
// If the number of changes is below 100, we let one thread handle it
|
||||||
h := newHasher(t.unhashed >= 100)
|
h := newHasher(t.unhashed >= 100)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ package trie
|
||||||
import (
|
import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
|
||||||
"github.com/ethereum/go-ethereum/triedb/database"
|
"github.com/ethereum/go-ethereum/triedb/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -32,11 +31,11 @@ type trieReader struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// newTrieReader initializes the trie reader with the given node reader.
|
// newTrieReader initializes the trie reader with the given node reader.
|
||||||
func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) {
|
func newTrieReader(isVerkle bool, stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) {
|
||||||
if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash {
|
if isVerkle && stateRoot == types.EmptyVerkleHash {
|
||||||
if stateRoot == (common.Hash{}) {
|
return &trieReader{owner: owner}, nil
|
||||||
log.Error("Zero state root hash!")
|
}
|
||||||
}
|
if !isVerkle && stateRoot == types.EmptyMerkleHash {
|
||||||
return &trieReader{owner: owner}, nil
|
return &trieReader{owner: owner}, nil
|
||||||
}
|
}
|
||||||
reader, err := db.NodeReader(stateRoot)
|
reader, err := db.NodeReader(stateRoot)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ func init() {
|
||||||
func TestEmptyTrie(t *testing.T) {
|
func TestEmptyTrie(t *testing.T) {
|
||||||
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
|
trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme))
|
||||||
res := trie.Hash()
|
res := trie.Hash()
|
||||||
exp := types.EmptyRootHash
|
exp := types.EmptyMerkleHash
|
||||||
if res != exp {
|
if res != exp {
|
||||||
t.Errorf("expected %x got %x", exp, res)
|
t.Errorf("expected %x got %x", exp, res)
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ func testMissingNode(t *testing.T, memonly bool, scheme string) {
|
||||||
updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
|
updateString(trie, "120000", "qwerqwerqwerqwerqwerqwerqwerqwer")
|
||||||
updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
|
updateString(trie, "123456", "asdfasdfasdfasdfasdfasdfasdfasdf")
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
triedb.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
triedb.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
if !memonly {
|
if !memonly {
|
||||||
triedb.Commit(root)
|
triedb.Commit(root)
|
||||||
|
|
@ -212,7 +212,7 @@ func TestGet(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
trie, _ = New(TrieID(root), db)
|
trie, _ = New(TrieID(root), db)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -285,7 +285,7 @@ func TestReplication(t *testing.T) {
|
||||||
updateString(trie, val.k, val.v)
|
updateString(trie, val.k, val.v)
|
||||||
}
|
}
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
|
|
||||||
// create a new trie on top of the database and check that lookups work.
|
// create a new trie on top of the database and check that lookups work.
|
||||||
trie2, err := New(TrieID(root), db)
|
trie2, err := New(TrieID(root), db)
|
||||||
|
|
@ -304,7 +304,7 @@ func TestReplication(t *testing.T) {
|
||||||
|
|
||||||
// recreate the trie after commit
|
// recreate the trie after commit
|
||||||
if nodes != nil {
|
if nodes != nil {
|
||||||
db.Update(hash, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(hash, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
}
|
}
|
||||||
trie2, err = New(TrieID(hash), db)
|
trie2, err = New(TrieID(hash), db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -493,7 +493,7 @@ func runRandTest(rt randTest) error {
|
||||||
scheme = rawdb.PathScheme
|
scheme = rawdb.PathScheme
|
||||||
}
|
}
|
||||||
var (
|
var (
|
||||||
origin = types.EmptyRootHash
|
origin = types.EmptyMerkleHash
|
||||||
triedb = newTestDatabase(rawdb.NewMemoryDatabase(), scheme)
|
triedb = newTestDatabase(rawdb.NewMemoryDatabase(), scheme)
|
||||||
tr = NewEmpty(triedb)
|
tr = NewEmpty(triedb)
|
||||||
values = make(map[string]string) // tracks content of the trie
|
values = make(map[string]string) // tracks content of the trie
|
||||||
|
|
@ -518,7 +518,7 @@ func runRandTest(rt randTest) error {
|
||||||
}
|
}
|
||||||
case opProve:
|
case opProve:
|
||||||
hash := tr.Hash()
|
hash := tr.Hash()
|
||||||
if hash == types.EmptyRootHash {
|
if hash == types.EmptyMerkleHash {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
proofDb := rawdb.NewMemoryDatabase()
|
proofDb := rawdb.NewMemoryDatabase()
|
||||||
|
|
@ -790,7 +790,7 @@ func makeAccounts(size int) (addresses [][20]byte, accounts [][]byte) {
|
||||||
for i := 0; i < len(accounts); i++ {
|
for i := 0; i < len(accounts); i++ {
|
||||||
var (
|
var (
|
||||||
nonce = uint64(random.Int63())
|
nonce = uint64(random.Int63())
|
||||||
root = types.EmptyRootHash
|
root = types.EmptyMerkleHash
|
||||||
code = crypto.Keccak256(nil)
|
code = crypto.Keccak256(nil)
|
||||||
)
|
)
|
||||||
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
// The big.Rand function is not deterministic with regards to 64 vs 32 bit systems,
|
||||||
|
|
@ -897,7 +897,7 @@ func TestCommitSequence(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Flush trie -> database
|
// Flush trie -> database
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
// Flush memdb -> disk (sponge)
|
// Flush memdb -> disk (sponge)
|
||||||
db.Commit(root)
|
db.Commit(root)
|
||||||
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
|
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
|
||||||
|
|
@ -938,7 +938,7 @@ func TestCommitSequenceRandomBlobs(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Flush trie -> database
|
// Flush trie -> database
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
// Flush memdb -> disk (sponge)
|
// Flush memdb -> disk (sponge)
|
||||||
db.Commit(root)
|
db.Commit(root)
|
||||||
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
|
if got, exp := s.sponge.Sum(nil), tc.expWriteSeqHash; !bytes.Equal(got, exp) {
|
||||||
|
|
@ -988,7 +988,7 @@ func TestCommitSequenceStackTrie(t *testing.T) {
|
||||||
// Flush trie -> database
|
// Flush trie -> database
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
// Flush memdb -> disk (sponge)
|
// Flush memdb -> disk (sponge)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
db.Commit(root)
|
db.Commit(root)
|
||||||
s.Flush()
|
s.Flush()
|
||||||
|
|
||||||
|
|
@ -1046,7 +1046,7 @@ func TestCommitSequenceSmallRoot(t *testing.T) {
|
||||||
// Flush trie -> database
|
// Flush trie -> database
|
||||||
root, nodes := trie.Commit(false)
|
root, nodes := trie.Commit(false)
|
||||||
// Flush memdb -> disk (sponge)
|
// Flush memdb -> disk (sponge)
|
||||||
db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes))
|
db.Update(root, types.EmptyMerkleHash, trienode.NewWithNodeSet(nodes))
|
||||||
db.Commit(root)
|
db.Commit(root)
|
||||||
|
|
||||||
// And flush stacktrie -> disk
|
// And flush stacktrie -> disk
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ type VerkleTrie struct {
|
||||||
|
|
||||||
// NewVerkleTrie constructs a verkle tree based on the specified root hash.
|
// NewVerkleTrie constructs a verkle tree based on the specified root hash.
|
||||||
func NewVerkleTrie(root common.Hash, db database.NodeDatabase, cache *utils.PointCache) (*VerkleTrie, error) {
|
func NewVerkleTrie(root common.Hash, db database.NodeDatabase, cache *utils.PointCache) (*VerkleTrie, error) {
|
||||||
reader, err := newTrieReader(root, common.Hash{}, db)
|
reader, err := newTrieReader(true, root, common.Hash{}, db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Parse the root verkle node if it's not empty.
|
// Parse the root verkle node if it's not empty.
|
||||||
node := verkle.New()
|
node := verkle.New()
|
||||||
if root != types.EmptyVerkleHash && root != types.EmptyRootHash {
|
if root != types.EmptyVerkleHash {
|
||||||
blob, err := reader.node(nil, common.Hash{})
|
blob, err := reader.node(nil, common.Hash{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, n
|
||||||
}
|
}
|
||||||
switch b := db.backend.(type) {
|
switch b := db.backend.(type) {
|
||||||
case *hashdb.Database:
|
case *hashdb.Database:
|
||||||
return b.Update(root, parent, block, nodes)
|
return b.Update(parent, nodes)
|
||||||
case *pathdb.Database:
|
case *pathdb.Database:
|
||||||
return b.Update(root, parent, block, nodes, states.internal())
|
return b.Update(root, parent, block, nodes, states.internal())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,8 @@ var Defaults = &Config{
|
||||||
// Database is an intermediate write layer between the trie data structures and
|
// Database is an intermediate write layer between the trie data structures and
|
||||||
// the disk database. The aim is to accumulate trie writes in-memory and only
|
// the disk database. The aim is to accumulate trie writes in-memory and only
|
||||||
// periodically flush a couple tries to disk, garbage collecting the remainder.
|
// periodically flush a couple tries to disk, garbage collecting the remainder.
|
||||||
|
//
|
||||||
|
// This database is not compatible with verkle tree node.
|
||||||
type Database struct {
|
type Database struct {
|
||||||
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
||||||
cleans *fastcache.Cache // GC friendly memory cache of clean node RLPs
|
cleans *fastcache.Cache // GC friendly memory cache of clean node RLPs
|
||||||
|
|
@ -540,9 +542,9 @@ func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
||||||
|
|
||||||
// Update inserts the dirty nodes in provided nodeset into database and link the
|
// Update inserts the dirty nodes in provided nodeset into database and link the
|
||||||
// account trie with multiple storage tries if necessary.
|
// account trie with multiple storage tries if necessary.
|
||||||
func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet) error {
|
func (db *Database) Update(parent common.Hash, nodes *trienode.MergedNodeSet) error {
|
||||||
// Ensure the parent state is present and signal a warning if not.
|
// Ensure the parent state is present and signal a warning if not.
|
||||||
if parent != types.EmptyRootHash {
|
if parent != types.EmptyMerkleHash {
|
||||||
if blob, _ := db.node(parent); len(blob) == 0 {
|
if blob, _ := db.node(parent); len(blob) == 0 {
|
||||||
log.Error("parent state is not present")
|
log.Error("parent state is not present")
|
||||||
}
|
}
|
||||||
|
|
@ -583,7 +585,7 @@ func (db *Database) Update(root common.Hash, parent common.Hash, block uint64, n
|
||||||
if err := rlp.DecodeBytes(n.Blob, &account); err != nil {
|
if err := rlp.DecodeBytes(n.Blob, &account); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if account.Root != types.EmptyRootHash {
|
if account.Root != types.EmptyMerkleHash {
|
||||||
db.reference(account.Root, n.Parent)
|
db.reference(account.Root, n.Parent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
|
"github.com/ethereum/go-verkle"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -148,6 +149,29 @@ var Defaults = &Config{
|
||||||
// ReadOnly is the config in order to open database in read only mode.
|
// ReadOnly is the config in order to open database in read only mode.
|
||||||
var ReadOnly = &Config{ReadOnly: true}
|
var ReadOnly = &Config{ReadOnly: true}
|
||||||
|
|
||||||
|
// nodeHasher is the function to compute the hash of supplied node blob.
|
||||||
|
type nodeHasher func([]byte) (common.Hash, error)
|
||||||
|
|
||||||
|
// merkleNodeHasher computes the hash of the given merkle node.
|
||||||
|
func merkleNodeHasher(blob []byte) (common.Hash, error) {
|
||||||
|
if len(blob) == 0 {
|
||||||
|
return types.EmptyMerkleHash, nil
|
||||||
|
}
|
||||||
|
return crypto.Keccak256Hash(blob), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// verkleNodeHasher computes the hash of the given verkle node.
|
||||||
|
func verkleNodeHasher(blob []byte) (common.Hash, error) {
|
||||||
|
if len(blob) == 0 {
|
||||||
|
return types.EmptyVerkleHash, nil
|
||||||
|
}
|
||||||
|
n, err := verkle.ParseNode(blob, 0)
|
||||||
|
if err != nil {
|
||||||
|
return common.Hash{}, err
|
||||||
|
}
|
||||||
|
return n.Commit().Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
// Database is a multiple-layered structure for maintaining in-memory states
|
// Database is a multiple-layered structure for maintaining in-memory states
|
||||||
// along with its dirty trie nodes. It consists of one persistent base layer
|
// along with its dirty trie nodes. It consists of one persistent base layer
|
||||||
// backed by a key-value store, on top of which arbitrarily many in-memory diff
|
// backed by a key-value store, on top of which arbitrarily many in-memory diff
|
||||||
|
|
@ -164,9 +188,10 @@ type Database struct {
|
||||||
// readOnly is the flag whether the mutation is allowed to be applied.
|
// readOnly is the flag whether the mutation is allowed to be applied.
|
||||||
// It will be set automatically when the database is journaled during
|
// It will be set automatically when the database is journaled during
|
||||||
// the shutdown to reject all following unexpected mutations.
|
// the shutdown to reject all following unexpected mutations.
|
||||||
readOnly bool // Flag if database is opened in read only mode
|
readOnly bool // Flag if database is opened in read only mode
|
||||||
waitSync bool // Flag if database is deactivated due to initial state sync
|
waitSync bool // Flag if database is deactivated due to initial state sync
|
||||||
isVerkle bool // Flag if database is used for verkle tree
|
isVerkle bool // Flag if database is used for verkle tree
|
||||||
|
hasher nodeHasher // Trie node hasher
|
||||||
|
|
||||||
config *Config // Configuration for database
|
config *Config // Configuration for database
|
||||||
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
diskdb ethdb.Database // Persistent storage for matured trie nodes
|
||||||
|
|
@ -184,19 +209,21 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database {
|
||||||
}
|
}
|
||||||
config = config.sanitize()
|
config = config.sanitize()
|
||||||
|
|
||||||
|
db := &Database{
|
||||||
|
readOnly: config.ReadOnly,
|
||||||
|
isVerkle: isVerkle,
|
||||||
|
config: config,
|
||||||
|
diskdb: diskdb,
|
||||||
|
hasher: merkleNodeHasher,
|
||||||
|
}
|
||||||
// Establish a dedicated database namespace tailored for verkle-specific
|
// Establish a dedicated database namespace tailored for verkle-specific
|
||||||
// data, ensuring the isolation of both verkle and merkle tree data. It's
|
// data, ensuring the isolation of both verkle and merkle tree data. It's
|
||||||
// important to note that the introduction of a prefix won't lead to
|
// important to note that the introduction of a prefix won't lead to
|
||||||
// substantial storage overhead, as the underlying database will efficiently
|
// substantial storage overhead, as the underlying database will efficiently
|
||||||
// compress the shared key prefix.
|
// compress the shared key prefix.
|
||||||
if isVerkle {
|
if isVerkle {
|
||||||
diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix))
|
db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix))
|
||||||
}
|
db.hasher = verkleNodeHasher
|
||||||
db := &Database{
|
|
||||||
readOnly: config.ReadOnly,
|
|
||||||
isVerkle: isVerkle,
|
|
||||||
config: config,
|
|
||||||
diskdb: diskdb,
|
|
||||||
}
|
}
|
||||||
// Construct the layer tree by resolving the in-disk singleton state
|
// Construct the layer tree by resolving the in-disk singleton state
|
||||||
// and in-memory layer journal.
|
// and in-memory layer journal.
|
||||||
|
|
@ -300,6 +327,8 @@ func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint6
|
||||||
// Commit traverses downwards the layer tree from a specified layer with the
|
// Commit traverses downwards the layer tree from a specified layer with the
|
||||||
// provided state root and all the layers below are flattened downwards. It
|
// provided state root and all the layers below are flattened downwards. It
|
||||||
// can be used alone and mostly for test purposes.
|
// can be used alone and mostly for test purposes.
|
||||||
|
//
|
||||||
|
// The supplied root must be a valid trie hash value.
|
||||||
func (db *Database) Commit(root common.Hash, report bool) error {
|
func (db *Database) Commit(root common.Hash, report bool) error {
|
||||||
// Hold the lock to prevent concurrent mutations.
|
// Hold the lock to prevent concurrent mutations.
|
||||||
db.lock.Lock()
|
db.lock.Lock()
|
||||||
|
|
@ -341,6 +370,8 @@ func (db *Database) Disable() error {
|
||||||
|
|
||||||
// Enable activates database and resets the state tree with the provided persistent
|
// Enable activates database and resets the state tree with the provided persistent
|
||||||
// state root once the state sync is finished.
|
// state root once the state sync is finished.
|
||||||
|
//
|
||||||
|
// The supplied root must be a valid trie hash value.
|
||||||
func (db *Database) Enable(root common.Hash) error {
|
func (db *Database) Enable(root common.Hash) error {
|
||||||
db.lock.Lock()
|
db.lock.Lock()
|
||||||
defer db.lock.Unlock()
|
defer db.lock.Unlock()
|
||||||
|
|
@ -350,10 +381,9 @@ func (db *Database) Enable(root common.Hash) error {
|
||||||
return errDatabaseReadOnly
|
return errDatabaseReadOnly
|
||||||
}
|
}
|
||||||
// Ensure the provided state root matches the stored one.
|
// Ensure the provided state root matches the stored one.
|
||||||
root = types.TrieRootHash(root)
|
stored, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil))
|
||||||
stored := types.EmptyRootHash
|
if err != nil {
|
||||||
if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 {
|
return err
|
||||||
stored = crypto.Keccak256Hash(blob)
|
|
||||||
}
|
}
|
||||||
if stored != root {
|
if stored != root {
|
||||||
return fmt.Errorf("state root mismatch: stored %x, synced %x", stored, root)
|
return fmt.Errorf("state root mismatch: stored %x, synced %x", stored, root)
|
||||||
|
|
@ -389,6 +419,8 @@ func (db *Database) Enable(root common.Hash) error {
|
||||||
// Recover rollbacks the database to a specified historical point.
|
// Recover rollbacks the database to a specified historical point.
|
||||||
// The state is supported as the rollback destination only if it's
|
// The state is supported as the rollback destination only if it's
|
||||||
// canonical state and the corresponding trie histories are existent.
|
// canonical state and the corresponding trie histories are existent.
|
||||||
|
//
|
||||||
|
// The supplied root must be a valid trie hash value.
|
||||||
func (db *Database) Recover(root common.Hash) error {
|
func (db *Database) Recover(root common.Hash) error {
|
||||||
db.lock.Lock()
|
db.lock.Lock()
|
||||||
defer db.lock.Unlock()
|
defer db.lock.Unlock()
|
||||||
|
|
@ -401,7 +433,6 @@ func (db *Database) Recover(root common.Hash) error {
|
||||||
return errors.New("state rollback is non-supported")
|
return errors.New("state rollback is non-supported")
|
||||||
}
|
}
|
||||||
// Short circuit if the target state is not recoverable
|
// Short circuit if the target state is not recoverable
|
||||||
root = types.TrieRootHash(root)
|
|
||||||
if !db.Recoverable(root) {
|
if !db.Recoverable(root) {
|
||||||
return errStateUnrecoverable
|
return errStateUnrecoverable
|
||||||
}
|
}
|
||||||
|
|
@ -434,9 +465,10 @@ func (db *Database) Recover(root common.Hash) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recoverable returns the indicator if the specified state is recoverable.
|
// Recoverable returns the indicator if the specified state is recoverable.
|
||||||
|
//
|
||||||
|
// The supplied root must be a valid trie hash value.
|
||||||
func (db *Database) Recoverable(root common.Hash) bool {
|
func (db *Database) Recoverable(root common.Hash) bool {
|
||||||
// Ensure the requested state is a known state.
|
// Ensure the requested state is a known state.
|
||||||
root = types.TrieRootHash(root)
|
|
||||||
id := rawdb.ReadStateID(db.diskdb, root)
|
id := rawdb.ReadStateID(db.diskdb, root)
|
||||||
if id == nil {
|
if id == nil {
|
||||||
return false
|
return false
|
||||||
|
|
@ -504,7 +536,7 @@ func (db *Database) Size() (diffs common.StorageSize, nodes common.StorageSize)
|
||||||
func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
func (db *Database) Initialized(genesisRoot common.Hash) bool {
|
||||||
var inited bool
|
var inited bool
|
||||||
db.tree.forEach(func(layer layer) {
|
db.tree.forEach(func(layer layer) {
|
||||||
if layer.rootHash() != types.EmptyRootHash {
|
if layer.rootHash() != types.EmptyRootHash(db.isVerkle) {
|
||||||
inited = true
|
inited = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,7 @@ func newCtx(stateRoot common.Hash) *genctx {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rjl493456442) support verkle for testing
|
||||||
type tester struct {
|
type tester struct {
|
||||||
db *Database
|
db *Database
|
||||||
roots []common.Hash
|
roots []common.Hash
|
||||||
|
|
@ -121,7 +122,7 @@ func newTester(t *testing.T, historyLimit uint64) *tester {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
for i := 0; i < 12; i++ {
|
for i := 0; i < 12; i++ {
|
||||||
var parent = types.EmptyRootHash
|
var parent = types.EmptyMerkleHash
|
||||||
if len(obj.roots) != 0 {
|
if len(obj.roots) != 0 {
|
||||||
parent = obj.roots[len(obj.roots)-1]
|
parent = obj.roots[len(obj.roots)-1]
|
||||||
}
|
}
|
||||||
|
|
@ -159,7 +160,7 @@ func (t *tester) generateStorage(ctx *genctx, addr common.Address) common.Hash {
|
||||||
storage[hash] = v
|
storage[hash] = v
|
||||||
origin[hash] = nil
|
origin[hash] = nil
|
||||||
}
|
}
|
||||||
root, set := updateTrie(t.db, ctx.stateRoot, addrHash, types.EmptyRootHash, storage)
|
root, set := updateTrie(t.db, ctx.stateRoot, addrHash, types.EmptyMerkleHash, storage)
|
||||||
|
|
||||||
ctx.storages[addrHash] = storage
|
ctx.storages[addrHash] = storage
|
||||||
ctx.storageOrigin[addr] = origin
|
ctx.storageOrigin[addr] = origin
|
||||||
|
|
@ -207,7 +208,7 @@ func (t *tester) clearStorage(ctx *genctx, addr common.Address, root common.Hash
|
||||||
storage[hash] = nil
|
storage[hash] = nil
|
||||||
}
|
}
|
||||||
root, set := updateTrie(t.db, ctx.stateRoot, addrHash, root, storage)
|
root, set := updateTrie(t.db, ctx.stateRoot, addrHash, root, storage)
|
||||||
if root != types.EmptyRootHash {
|
if root != types.EmptyMerkleHash {
|
||||||
panic("failed to clear storage trie")
|
panic("failed to clear storage trie")
|
||||||
}
|
}
|
||||||
ctx.storages[addrHash] = storage
|
ctx.storages[addrHash] = storage
|
||||||
|
|
@ -252,7 +253,7 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode
|
||||||
}
|
}
|
||||||
dirties[addrHash] = struct{}{}
|
dirties[addrHash] = struct{}{}
|
||||||
|
|
||||||
acct, _ := types.FullAccount(account)
|
acct, _ := types.FullAccount(account, false)
|
||||||
stRoot := t.mutateStorage(ctx, addr, acct.Root)
|
stRoot := t.mutateStorage(ctx, addr, acct.Root)
|
||||||
newAccount := types.SlimAccountRLP(generateAccount(stRoot))
|
newAccount := types.SlimAccountRLP(generateAccount(stRoot))
|
||||||
|
|
||||||
|
|
@ -271,8 +272,8 @@ func (t *tester) generate(parent common.Hash) (common.Hash, *trienode.MergedNode
|
||||||
}
|
}
|
||||||
dirties[addrHash] = struct{}{}
|
dirties[addrHash] = struct{}{}
|
||||||
|
|
||||||
acct, _ := types.FullAccount(account)
|
acct, _ := types.FullAccount(account, false)
|
||||||
if acct.Root != types.EmptyRootHash {
|
if acct.Root != types.EmptyMerkleHash {
|
||||||
t.clearStorage(ctx, addr, acct.Root)
|
t.clearStorage(ctx, addr, acct.Root)
|
||||||
}
|
}
|
||||||
ctx.accounts[addrHash] = nil
|
ctx.accounts[addrHash] = nil
|
||||||
|
|
@ -371,7 +372,7 @@ func (t *tester) verifyHistory() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
parent := types.EmptyRootHash
|
parent := types.EmptyMerkleHash
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
parent = t.roots[i-1]
|
parent = t.roots[i-1]
|
||||||
}
|
}
|
||||||
|
|
@ -412,7 +413,7 @@ func TestDatabaseRollback(t *testing.T) {
|
||||||
}
|
}
|
||||||
// Revert database from top to bottom
|
// Revert database from top to bottom
|
||||||
for i := tester.bottomIndex(); i >= 0; i-- {
|
for i := tester.bottomIndex(); i >= 0; i-- {
|
||||||
parent := types.EmptyRootHash
|
parent := types.EmptyMerkleHash
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
parent = tester.roots[i-1]
|
parent = tester.roots[i-1]
|
||||||
}
|
}
|
||||||
|
|
@ -451,10 +452,10 @@ func TestDatabaseRecoverable(t *testing.T) {
|
||||||
{common.Hash{0x1}, false},
|
{common.Hash{0x1}, false},
|
||||||
|
|
||||||
// Initial state should be recoverable
|
// Initial state should be recoverable
|
||||||
{types.EmptyRootHash, true},
|
{types.EmptyMerkleHash, true},
|
||||||
|
|
||||||
// Initial state should be recoverable
|
// Invalid (unknown) state should be rejected
|
||||||
{common.Hash{}, true},
|
{common.Hash{}, false},
|
||||||
|
|
||||||
// Layers below current disk layer are recoverable
|
// Layers below current disk layer are recoverable
|
||||||
{tester.roots[index-1], true},
|
{tester.roots[index-1], true},
|
||||||
|
|
@ -489,7 +490,7 @@ func TestDisable(t *testing.T) {
|
||||||
if err := tester.db.Disable(); err != nil {
|
if err := tester.db.Disable(); err != nil {
|
||||||
t.Fatalf("Failed to deactivate database: %v", err)
|
t.Fatalf("Failed to deactivate database: %v", err)
|
||||||
}
|
}
|
||||||
if err := tester.db.Enable(types.EmptyRootHash); err == nil {
|
if err := tester.db.Enable(types.EmptyMerkleHash); err == nil {
|
||||||
t.Fatal("Invalid activation should be rejected")
|
t.Fatal("Invalid activation should be rejected")
|
||||||
}
|
}
|
||||||
if err := tester.db.Enable(stored); err != nil {
|
if err := tester.db.Enable(stored); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
defer h.release()
|
defer h.release()
|
||||||
|
|
||||||
addrHash := h.hash(addr.Bytes())
|
addrHash := h.hash(addr.Bytes())
|
||||||
prev, err := types.FullAccount(ctx.accounts[addr])
|
prev, err := types.FullAccount(ctx.accounts[addr], false) // TODO support verkle mode
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +97,7 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
post := types.NewEmptyStateAccount()
|
post := types.NewEmptyStateAccount(false) // TODO support verkle mode
|
||||||
if len(blob) != 0 {
|
if len(blob) != 0 {
|
||||||
if err := rlp.DecodeBytes(blob, &post); err != nil {
|
if err := rlp.DecodeBytes(blob, &post); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -171,7 +171,7 @@ func deleteAccount(ctx *context, db database.NodeDatabase, addr common.Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
root, result := st.Commit(false)
|
root, result := st.Commit(false)
|
||||||
if root != types.EmptyRootHash {
|
if root != types.EmptyMerkleHash { // TODO (rjl493456442) support verkle
|
||||||
return errors.New("failed to clear storage trie")
|
return errors.New("failed to clear storage trie")
|
||||||
}
|
}
|
||||||
// The returned set can be nil if storage trie is not changed
|
// The returned set can be nil if storage trie is not changed
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ func randomStateSet(n int) (map[common.Address][]byte, map[common.Address]map[co
|
||||||
v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32)))
|
v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32)))
|
||||||
storages[addr][testrand.Hash()] = v
|
storages[addr][testrand.Hash()] = v
|
||||||
}
|
}
|
||||||
account := generateAccount(types.EmptyRootHash)
|
account := generateAccount(types.EmptyMerkleHash)
|
||||||
accounts[addr] = types.SlimAccountRLP(account)
|
accounts[addr] = types.SlimAccountRLP(account)
|
||||||
}
|
}
|
||||||
return accounts, storages
|
return accounts, storages
|
||||||
|
|
@ -51,12 +51,12 @@ func randomStateSet(n int) (map[common.Address][]byte, map[common.Address]map[co
|
||||||
|
|
||||||
func makeHistory() *history {
|
func makeHistory() *history {
|
||||||
accounts, storages := randomStateSet(3)
|
accounts, storages := randomStateSet(3)
|
||||||
return newHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages)
|
return newHistory(testrand.Hash(), types.EmptyMerkleHash, 0, accounts, storages)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeHistories(n int) []*history {
|
func makeHistories(n int) []*history {
|
||||||
var (
|
var (
|
||||||
parent = types.EmptyRootHash
|
parent = types.EmptyMerkleHash
|
||||||
result []*history
|
result []*history
|
||||||
)
|
)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
)
|
)
|
||||||
|
|
@ -93,9 +92,9 @@ func (db *Database) loadJournal(diskRoot common.Hash) (layer, error) {
|
||||||
// loadLayers loads a pre-existing state layer backed by a key-value store.
|
// loadLayers loads a pre-existing state layer backed by a key-value store.
|
||||||
func (db *Database) loadLayers() layer {
|
func (db *Database) loadLayers() layer {
|
||||||
// Retrieve the root node of persistent state.
|
// Retrieve the root node of persistent state.
|
||||||
var root = types.EmptyRootHash
|
root, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil))
|
||||||
if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 {
|
if err != nil {
|
||||||
root = crypto.Keccak256Hash(blob)
|
log.Crit("Failed to compute node hash", "err", err)
|
||||||
}
|
}
|
||||||
// Load the layers by resolving the journal
|
// Load the layers by resolving the journal
|
||||||
head, err := db.loadJournal(root)
|
head, err := db.loadJournal(root)
|
||||||
|
|
@ -105,7 +104,7 @@ func (db *Database) loadLayers() layer {
|
||||||
// journal is not matched(or missing) with the persistent state, discard
|
// journal is not matched(or missing) with the persistent state, discard
|
||||||
// it. Display log for discarding journal, but try to avoid showing
|
// it. Display log for discarding journal, but try to avoid showing
|
||||||
// useless information when the db is created from scratch.
|
// useless information when the db is created from scratch.
|
||||||
if !(root == types.EmptyRootHash && errors.Is(err, errMissJournal)) {
|
if !(root == types.EmptyRootHash(db.isVerkle) && errors.Is(err, errMissJournal)) {
|
||||||
log.Info("Failed to load journal, discard it", "err", err)
|
log.Info("Failed to load journal, discard it", "err", err)
|
||||||
}
|
}
|
||||||
// Return single layer with persistent state.
|
// Return single layer with persistent state.
|
||||||
|
|
@ -265,9 +264,9 @@ func (db *Database) Journal(root common.Hash) error {
|
||||||
}
|
}
|
||||||
// Secondly write out the state root in disk, ensure all layers
|
// Secondly write out the state root in disk, ensure all layers
|
||||||
// on top are continuous with disk.
|
// on top are continuous with disk.
|
||||||
diskRoot := types.EmptyRootHash
|
diskRoot, err := db.hasher(rawdb.ReadAccountTrieNode(db.diskdb, nil))
|
||||||
if blob := rawdb.ReadAccountTrieNode(db.diskdb, nil); len(blob) > 0 {
|
if err != nil {
|
||||||
diskRoot = crypto.Keccak256Hash(blob)
|
return err
|
||||||
}
|
}
|
||||||
if err := rlp.Encode(journal, diskRoot); err != nil {
|
if err := rlp.Encode(journal, diskRoot); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
|
||||||
"github.com/ethereum/go-ethereum/trie/trienode"
|
"github.com/ethereum/go-ethereum/trie/trienode"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -58,11 +57,13 @@ func (tree *layerTree) reset(head layer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get retrieves a layer belonging to the given state root.
|
// get retrieves a layer belonging to the given state root.
|
||||||
|
//
|
||||||
|
// The supplied root must be a valid trie hash value.
|
||||||
func (tree *layerTree) get(root common.Hash) layer {
|
func (tree *layerTree) get(root common.Hash) layer {
|
||||||
tree.lock.RLock()
|
tree.lock.RLock()
|
||||||
defer tree.lock.RUnlock()
|
defer tree.lock.RUnlock()
|
||||||
|
|
||||||
return tree.layers[types.TrieRootHash(root)]
|
return tree.layers[root]
|
||||||
}
|
}
|
||||||
|
|
||||||
// forEach iterates the stored layers inside and applies the
|
// forEach iterates the stored layers inside and applies the
|
||||||
|
|
@ -85,6 +86,8 @@ func (tree *layerTree) len() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// add inserts a new layer into the tree if it can be linked to an existing old parent.
|
// add inserts a new layer into the tree if it can be linked to an existing old parent.
|
||||||
|
//
|
||||||
|
// The supplied root and parentRoot must be a valid trie hash value.
|
||||||
func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *StateSetWithOrigin) error {
|
func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *StateSetWithOrigin) error {
|
||||||
// Reject noop updates to avoid self-loops. This is a special case that can
|
// Reject noop updates to avoid self-loops. This is a special case that can
|
||||||
// happen for clique networks and proof-of-stake networks where empty blocks
|
// happen for clique networks and proof-of-stake networks where empty blocks
|
||||||
|
|
@ -92,7 +95,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6
|
||||||
//
|
//
|
||||||
// Although we could silently ignore this internally, it should be the caller's
|
// Although we could silently ignore this internally, it should be the caller's
|
||||||
// responsibility to avoid even attempting to insert such a layer.
|
// responsibility to avoid even attempting to insert such a layer.
|
||||||
root, parentRoot = types.TrieRootHash(root), types.TrieRootHash(parentRoot)
|
|
||||||
if root == parentRoot {
|
if root == parentRoot {
|
||||||
return errors.New("layer cycle")
|
return errors.New("layer cycle")
|
||||||
}
|
}
|
||||||
|
|
@ -112,7 +114,6 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6
|
||||||
// are crossed. All diffs beyond the permitted number are flattened downwards.
|
// are crossed. All diffs beyond the permitted number are flattened downwards.
|
||||||
func (tree *layerTree) cap(root common.Hash, layers int) error {
|
func (tree *layerTree) cap(root common.Hash, layers int) error {
|
||||||
// Retrieve the head layer to cap from
|
// Retrieve the head layer to cap from
|
||||||
root = types.TrieRootHash(root)
|
|
||||||
l := tree.get(root)
|
l := tree.get(root)
|
||||||
if l == nil {
|
if l == nil {
|
||||||
return fmt.Errorf("triedb layer [%#x] missing", root)
|
return fmt.Errorf("triedb layer [%#x] missing", root)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue