stop using olddb in simulated backend (#7219)

This commit is contained in:
Alex Sharov 2023-03-30 10:31:15 +07:00 committed by GitHub
parent 3008c25c9e
commit 2161c5ed8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 113 additions and 61 deletions

View File

@ -47,7 +47,6 @@ import (
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/ethdb/olddb"
"github.com/ledgerwatch/erigon/event"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/turbo/snapshotsync"
@ -79,6 +78,7 @@ type SimulatedBackend struct {
gasPool *core.GasPool
pendingBlock *types.Block // Currently pending block that will be imported on request
pendingReader *state.PlainStateReader
pendingReaderTx kv.Tx
pendingState *state.IntraBlockState // Currently pending state that will be the active on request
rmLogsFeed event.Feed
@ -112,9 +112,7 @@ func NewSimulatedBackendWithConfig(alloc types.GenesisAlloc, config *chain.Confi
// A simulated backend always uses chainID 1337.
func NewSimulatedBackend(t *testing.T, alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
b := NewSimulatedBackendWithConfig(alloc, params.TestChainConfig, gasLimit)
t.Cleanup(func() {
b.Close()
})
t.Cleanup(b.Close)
//if b.m.HistoryV3 {
// t.Skip("TODO: Fixme")
//}
@ -123,9 +121,7 @@ func NewSimulatedBackend(t *testing.T, alloc types.GenesisAlloc, gasLimit uint64
func NewTestSimulatedBackendWithConfig(t *testing.T, alloc types.GenesisAlloc, config *chain.Config, gasLimit uint64) *SimulatedBackend {
b := NewSimulatedBackendWithConfig(alloc, config, gasLimit)
t.Cleanup(func() {
b.Close()
})
t.Cleanup(b.Close)
//if b.m.HistoryV3 {
// t.Skip("TODO: Fixme")
//}
@ -141,6 +137,9 @@ func (b *SimulatedBackend) Engine() consensus.Engine { return b.m.Engine }
// Close terminates the underlying blockchain's update loop.
func (b *SimulatedBackend) Close() {
if b.pendingReaderTx != nil {
b.pendingReaderTx.Rollback()
}
b.m.Close()
}
@ -194,7 +193,15 @@ func (b *SimulatedBackend) emptyPendingBlock() {
defer agg.StartUnbufferedWrites().FinishWrites()
*/
}
b.pendingReader = state.NewPlainStateReader(olddb.NewObjectDatabase(b.m.DB))
if b.pendingReaderTx != nil {
b.pendingReaderTx.Rollback()
}
tx, err := b.m.DB.BeginRo(context.Background())
if err != nil {
panic(err)
}
b.pendingReaderTx = tx
b.pendingReader = state.NewPlainStateReader(b.pendingReaderTx)
b.pendingState = state.New(b.pendingReader)
}

View File

@ -18,6 +18,7 @@ package clique_test
import (
"bytes"
"context"
"crypto/ecdsa"
"sort"
"testing"
@ -25,13 +26,13 @@ import (
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/length"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/consensus/clique"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/eth/stagedsync"
"github.com/ledgerwatch/erigon/ethdb/olddb"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/turbo/stages"
)
@ -504,8 +505,14 @@ func TestClique(t *testing.T) {
// No failure was produced or requested, generate the final voting snapshot
head := chain.Blocks[len(chain.Blocks)-1]
snap, err := engine.Snapshot(stagedsync.ChainReader{Cfg: config, Db: olddb.NewObjectDatabase(m.DB)}, head.NumberU64(), head.Hash(), nil)
if err != nil {
var snap *clique.Snapshot
if err := m.DB.View(context.Background(), func(tx kv.Tx) error {
snap, err = engine.Snapshot(stagedsync.ChainReader{Cfg: config, Db: tx}, head.NumberU64(), head.Hash(), nil)
if err != nil {
return err
}
return nil
}); err != nil {
t.Errorf("test %d: failed to retrieve voting snapshot %d(%s): %v",
i, head.NumberU64(), head.Hash().Hex(), err)
engine.Close()

View File

@ -17,13 +17,14 @@
package core_test
import (
"context"
"testing"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/consensus/ethash"
"github.com/ledgerwatch/erigon/core"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/eth/stagedsync"
"github.com/ledgerwatch/erigon/ethdb/olddb"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/turbo/stages"
)
@ -44,19 +45,23 @@ func TestHeaderVerification(t *testing.T) {
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
for i := 0; i < chain.Length(); i++ {
for j, valid := range []bool{true, false} {
if valid {
engine := ethash.NewFaker()
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: olddb.NewObjectDatabase(m.DB)}, chain.Headers[i], true)
} else {
engine := ethash.NewFakeFailer(chain.Headers[i].Number.Uint64())
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: olddb.NewObjectDatabase(m.DB)}, chain.Headers[i], true)
}
if (err == nil) != valid {
t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, err, valid)
if err := m.DB.View(context.Background(), func(tx kv.Tx) error {
for j, valid := range []bool{true, false} {
if valid {
engine := ethash.NewFaker()
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: tx}, chain.Headers[i], true)
} else {
engine := ethash.NewFakeFailer(chain.Headers[i].Number.Uint64())
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: tx}, chain.Headers[i], true)
}
if (err == nil) != valid {
t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, err, valid)
}
}
return nil
}); err != nil {
panic(err)
}
if err = m.InsertChain(chain.Slice(i, i+1)); err != nil {
t.Fatalf("test %d: error inserting the block: %v", i, err)
}
@ -81,19 +86,23 @@ func TestHeaderWithSealVerification(t *testing.T) {
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
for i := 0; i < chain.Length(); i++ {
for j, valid := range []bool{true, false} {
if valid {
engine := ethash.NewFaker()
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainAuraConfig, Db: olddb.NewObjectDatabase(m.DB)}, chain.Headers[i], true)
} else {
engine := ethash.NewFakeFailer(chain.Headers[i].Number.Uint64())
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainAuraConfig, Db: olddb.NewObjectDatabase(m.DB)}, chain.Headers[i], true)
}
if (err == nil) != valid {
t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, err, valid)
if err := m.DB.View(context.Background(), func(tx kv.Tx) error {
for j, valid := range []bool{true, false} {
if valid {
engine := ethash.NewFaker()
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainAuraConfig, Db: tx}, chain.Headers[i], true)
} else {
engine := ethash.NewFakeFailer(chain.Headers[i].Number.Uint64())
err = engine.VerifyHeader(stagedsync.ChainReader{Cfg: *params.TestChainAuraConfig, Db: tx}, chain.Headers[i], true)
}
if (err == nil) != valid {
t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, err, valid)
}
}
return nil
}); err != nil {
panic(err)
}
if err = m.InsertChain(chain.Slice(i, i+1)); err != nil {
t.Fatalf("test %d: error inserting the block: %v", i, err)
}

View File

@ -17,6 +17,7 @@
package runtime
import (
"context"
"math"
"math/big"
"time"
@ -24,11 +25,11 @@ import (
"github.com/holiman/uint256"
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon-lib/kv/memdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/ethdb/olddb"
)
// Config is a basic type specifying certain configuration flags for running
@ -112,11 +113,19 @@ func Execute(code, input []byte, cfg *Config, bn uint64) ([]byte, *state.IntraBl
}
setDefaults(cfg)
if cfg.State == nil {
db := olddb.NewObjectDatabase(memdb.New(""))
externalState := cfg.State != nil
var tx kv.RwTx
var err error
if !externalState {
db := memdb.New("")
defer db.Close()
cfg.r = state.NewDbStateReader(db)
cfg.w = state.NewDbStateWriter(db, 0)
tx, err = db.BeginRw(context.Background())
if err != nil {
return nil, nil, err
}
defer tx.Rollback()
cfg.r = state.NewPlainStateReader(tx)
cfg.w = state.NewPlainStateWriter(tx, tx, 0)
cfg.State = state.New(cfg.r)
}
var (
@ -150,11 +159,19 @@ func Create(input []byte, cfg *Config, blockNr uint64) ([]byte, libcommon.Addres
}
setDefaults(cfg)
if cfg.State == nil {
db := olddb.NewObjectDatabase(memdb.New(""))
externalState := cfg.State != nil
var tx kv.RwTx
var err error
if !externalState {
db := memdb.New("")
defer db.Close()
cfg.r = state.NewDbStateReader(db)
cfg.w = state.NewDbStateWriter(db, 0)
tx, err = db.BeginRw(context.Background())
if err != nil {
return nil, [20]byte{}, 0, err
}
defer tx.Rollback()
cfg.r = state.NewPlainStateReader(tx)
cfg.w = state.NewPlainStateWriter(tx, tx, 0)
cfg.State = state.New(cfg.r)
}
var (

View File

@ -17,6 +17,7 @@
package runtime
import (
"context"
"fmt"
"math/big"
"os"
@ -35,7 +36,6 @@ import (
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/eth/tracers/logger"
"github.com/ledgerwatch/erigon/ethdb/olddb"
)
func TestDefaults(t *testing.T) {
@ -152,13 +152,17 @@ func BenchmarkCall(b *testing.B) {
b.Fatal(err)
}
cfg := &Config{}
db := olddb.NewObjectDatabase(memdb.New(""))
db := memdb.New("")
defer db.Close()
cfg.r = state.NewDbStateReader(db)
cfg.w = state.NewDbStateWriter(db, 0)
tx, err := db.BeginRw(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
cfg.r = state.NewPlainStateReader(tx)
cfg.w = state.NewPlainStateWriter(tx, tx, 0)
cfg.State = state.New(cfg.r)
cfg.State = state.New(cfg.r)
cfg.Debug = true
b.ResetTimer()
for i := 0; i < b.N; i++ {

View File

@ -17,6 +17,7 @@
package tests
import (
"context"
"math/big"
"testing"
@ -25,8 +26,6 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/stretchr/testify/require"
"github.com/ledgerwatch/erigon/ethdb/olddb"
"github.com/ledgerwatch/erigon/accounts/abi/bind"
"github.com/ledgerwatch/erigon/accounts/abi/bind/backends"
"github.com/ledgerwatch/erigon/core"
@ -61,8 +60,6 @@ func TestSelfDestructReceive(t *testing.T) {
)
m := stages.MockWithGenesis(t, gspec, key, false)
db := olddb.NewObjectDatabase(m.DB)
defer db.Close()
contractBackend := backends.NewTestSimulatedBackendWithConfig(t, gspec.Alloc, gspec.Config, gspec.GasLimit)
transactOpts, err := bind.NewKeyedTransactorWithChainID(key, m.ChainConfig.ChainID)
@ -77,23 +74,23 @@ func TestSelfDestructReceive(t *testing.T) {
// The second block is empty and is only used to force the newly created blockchain object to reload the trie
// from the database.
chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 2, func(i int, block *core.BlockGen) {
var tx types.Transaction
var txn types.Transaction
switch i {
case 0:
contractAddress, tx, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend)
contractAddress, txn, selfDestructorContract, err = contracts.DeploySelfDestructor(transactOpts, contractBackend)
if err != nil {
t.Fatal(err)
}
block.AddTx(tx)
tx, err = selfDestructorContract.SelfDestruct(transactOpts)
block.AddTx(txn)
txn, err = selfDestructorContract.SelfDestruct(transactOpts)
if err != nil {
t.Fatal(err)
}
block.AddTx(tx)
block.AddTx(txn)
// Send 1 wei to contract after self-destruction
tx, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key)
block.AddTx(tx)
txn, err = types.SignTx(types.NewTransaction(block.TxNonce(address), contractAddress, uint256.NewInt(1000), 21000, uint256.NewInt(1), nil), *signer, key)
block.AddTx(txn)
}
contractBackend.Commit()
}, false /* intermediateHashes */)
@ -101,7 +98,13 @@ func TestSelfDestructReceive(t *testing.T) {
t.Fatalf("generate blocks: %v", err)
}
st := state.New(state.NewPlainStateReader(db))
tx, err := m.DB.BeginRo(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
st := state.New(state.NewPlainStateReader(tx))
if !st.Exist(address) {
t.Error("expected account to exist")
}
@ -122,7 +125,12 @@ func TestSelfDestructReceive(t *testing.T) {
// and that means that the state of the accounts written in the first block was correct.
// This test checks that the storage root of the account is properly set to the root of the empty tree
st = state.New(state.NewPlainStateReader(db))
tx, err = m.DB.BeginRo(context.Background())
if err != nil {
panic(err)
}
defer tx.Rollback()
st = state.New(state.NewPlainStateReader(tx))
if !st.Exist(address) {
t.Error("expected account to exist")
}