Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add snapshots to state database #2161

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/cortex/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ func dump(ctx *cli.Context) error {
fmt.Println("{}")
utils.Fatalf("block not found")
} else {
state, err := state.New(block.Root(), state.NewDatabase(chainDb), nil)
state, err := state.New(block.Root(), state.NewDatabase(chainDb, nil), nil)
if err != nil {
utils.Fatalf("could not create new state: %v", err)
}
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func NewBlockChain(db ctxcdb.Database, cacheConfig *CacheConfig, chainConfig *pa
}

// Open trie database with provided config
triedb := state.NewDatabaseWithConfig(db, &trie.Config{
triedb := state.NewDatabaseWithConfig(db, nil, &trie.Config{
Cache: cacheConfig.TrieCleanLimit,
Journal: cacheConfig.TrieCleanJournal,
Preimages: cacheConfig.Preimages,
Expand Down
2 changes: 1 addition & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
return nil, nil
}
for i := 0; i < n; i++ {
statedb, err := state.New(parent.Root(), state.NewDatabase(db), nil)
statedb, err := state.New(parent.Root(), state.NewDatabase(db, nil), nil)
if err != nil {
panic(err)
}
Expand Down
4 changes: 2 additions & 2 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func SetupGenesisBlock(db ctxcdb.Database, genesis *Genesis) (*params.ChainConfi
// We have the genesis block in database(perhaps in ancient database)
// but the corresponding state is missing.
header := rawdb.ReadHeader(db, stored, 0)
if _, err := state.New(header.Root, state.NewDatabaseWithConfig(db, nil), nil); err != nil {
if _, err := state.New(header.Root, state.NewDatabaseWithConfig(db, nil, nil), nil); err != nil {
if genesis == nil {
genesis = DefaultGenesisBlock()
}
Expand Down Expand Up @@ -254,7 +254,7 @@ func (g *Genesis) ToBlock(db ctxcdb.Database) *types.Block {
if db == nil {
db = rawdb.NewMemoryDatabase()
}
statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil)
statedb, err := state.New(common.Hash{}, state.NewDatabase(db, nil), nil)
if err != nil {
panic(err)
}
Expand Down
17 changes: 14 additions & 3 deletions core/state/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/CortexFoundation/CortexTheseus/common"
"github.com/CortexFoundation/CortexTheseus/common/lru"
"github.com/CortexFoundation/CortexTheseus/core/rawdb"
"github.com/CortexFoundation/CortexTheseus/core/state/snapshot"
"github.com/CortexFoundation/CortexTheseus/core/types"
"github.com/CortexFoundation/CortexTheseus/crypto"
"github.com/CortexFoundation/CortexTheseus/ctxcdb"
Expand Down Expand Up @@ -59,6 +60,9 @@ type Database interface {

// TrieDB retrieves the low level trie database used for data storage.
TrieDB() *trie.Database

// Snapshot returns the underlying state snapshot.
Snapshot() *snapshot.Tree
}

// Trie is a Merkle Patricia trie.
Expand Down Expand Up @@ -132,17 +136,18 @@ type Trie interface {
// NewDatabase creates a backing store for state. The returned database is safe for
// concurrent use, but does not retain any recent trie nodes in memory. To keep some
// historical state in memory, use the NewDatabaseWithCache constructor.
func NewDatabase(db ctxcdb.Database) Database {
return NewDatabaseWithConfig(db, nil)
func NewDatabase(db ctxcdb.Database, snap *snapshot.Tree) Database {
return NewDatabaseWithConfig(db, snap, nil)
}

// NewDatabaseWithCache creates a backing store for state. The returned database
// is safe for concurrent use and retains a lot of collapsed RLP trie nodes in a
// large memory cache.
func NewDatabaseWithConfig(db ctxcdb.Database, config *trie.Config) Database {
func NewDatabaseWithConfig(db ctxcdb.Database, snap *snapshot.Tree, config *trie.Config) Database {
return &cachingDB{
triedb: trie.NewDatabaseWithConfig(db, config),
disk: db,
snap: snap,
codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize),
codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize),
}
Expand All @@ -151,6 +156,7 @@ func NewDatabaseWithConfig(db ctxcdb.Database, config *trie.Config) Database {
type cachingDB struct {
triedb *trie.Database
disk ctxcdb.KeyValueStore
snap *snapshot.Tree
codeSizeCache *lru.Cache[common.Hash, int]
codeCache *lru.SizeConstrainedCache[common.Hash, []byte]
}
Expand Down Expand Up @@ -233,3 +239,8 @@ func (db *cachingDB) DiskDB() ctxcdb.KeyValueStore {
func (db *cachingDB) TrieDB() *trie.Database {
return db.triedb
}

// Snapshot returns the underlying state snapshot.
func (db *cachingDB) Snapshot() *snapshot.Tree {
return db.snap
}
6 changes: 3 additions & 3 deletions core/state/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ type stateTest struct {

func newStateTest() *stateTest {
db := rawdb.NewMemoryDatabase()
sdb, _ := New(common.Hash{}, NewDatabase(db), nil)
sdb, _ := New(common.Hash{}, NewDatabase(db, nil), nil)
return &stateTest{db: db, state: sdb}
}

func TestDump(t *testing.T) {
db := rawdb.NewMemoryDatabase()
sdb, _ := New(common.Hash{}, NewDatabaseWithConfig(db, &trie.Config{Preimages: true}), nil)
sdb, _ := New(common.Hash{}, NewDatabaseWithConfig(db, nil, &trie.Config{Preimages: true}), nil)
s := &stateTest{db: db, state: sdb}

// generate a few entries
Expand Down Expand Up @@ -146,7 +146,7 @@ func (s *StateSuite) TestSnapshotEmpty(c *checker.C) {
// use testing instead of checker because checker does not support
// printing/logging in tests (-check.vv does not work)
func TestSnapshot2(t *testing.T) {
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(types.EmptyRootHash, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
addr := common.BytesToAddress([]byte("so0"))
snap := state.Snapshot()

Expand Down
10 changes: 10 additions & 0 deletions core/state/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -1108,10 +1108,20 @@ func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool) (common.Hash, er
s.SnapshotCommits += time.Since(start)
s.snap = nil
}

if root == (common.Hash{}) {
root = types.EmptyRootHash
}

origin := s.originalRoot
if origin == (common.Hash{}) {
origin = types.EmptyRootHash
}

if root != origin {
s.originalRoot = root
}

// Clear all internal flags at the end of commit operation.
s.accounts = make(map[common.Hash][]byte)
s.storages = make(map[common.Hash]map[common.Hash][]byte)
Expand Down
26 changes: 13 additions & 13 deletions core/state/statedb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import (
func TestUpdateLeaks(t *testing.T) {
// Create an empty state database
db := rawdb.NewMemoryDatabase()
state, _ := New(common.Hash{}, NewDatabase(db), nil)
state, _ := New(common.Hash{}, NewDatabase(db, nil), nil)

// Update it with some accounts
for i := byte(0); i < 255; i++ {
Expand Down Expand Up @@ -71,8 +71,8 @@ func TestIntermediateLeaks(t *testing.T) {
// Create two state databases, one transitioning to the final state, the other final from the beginning
transDb := rawdb.NewMemoryDatabase()
finalDb := rawdb.NewMemoryDatabase()
transState, _ := New(common.Hash{}, NewDatabase(transDb), nil)
finalState, _ := New(common.Hash{}, NewDatabase(finalDb), nil)
transState, _ := New(common.Hash{}, NewDatabase(transDb, nil), nil)
finalState, _ := New(common.Hash{}, NewDatabase(finalDb, nil), nil)

modify := func(state *StateDB, addr common.Address, i, tweak byte) {
state.SetBalance(addr, big.NewInt(int64(11*i)+int64(tweak)))
Expand Down Expand Up @@ -147,7 +147,7 @@ func TestIntermediateLeaks(t *testing.T) {
// https://github.com/CortexFoundation/CortexTheseus/pull/15549.
func TestCopy(t *testing.T) {
// Create a random state test to copy and modify "independently"
orig, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
orig, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)

for i := byte(0); i < 255; i++ {
obj := orig.getOrNewStateObject(common.BytesToAddress([]byte{i}))
Expand Down Expand Up @@ -366,7 +366,7 @@ func (test *snapshotTest) String() string {
func (test *snapshotTest) run() bool {
// Run all actions and create snapshots.
var (
state, _ = New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ = New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
snapshotRevs = make([]int, len(test.snapshots))
sindex = 0
checkstates = make([]*StateDB, len(test.snapshots))
Expand Down Expand Up @@ -517,7 +517,7 @@ func (s *StateSuite) TestTouchDelete(c *check.C) {
// TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy.
// See https://github.com/CortexFoundation/CortexTheseus/pull/15225#issuecomment-380191512
func TestCopyOfCopy(t *testing.T) {
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
addr := common.HexToAddress("aaaa")
state.SetBalance(addr, big.NewInt(42))

Expand All @@ -534,7 +534,7 @@ func TestCopyOfCopy(t *testing.T) {
//
// See https://github.com/CortexFoundation/CortexTheseus/issues/20106.
func TestCopyCommitCopy(t *testing.T) {
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)

// Create an account and check if the retrieved balance is correct
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
Expand Down Expand Up @@ -606,7 +606,7 @@ func TestCopyCommitCopy(t *testing.T) {
//
// See https://github.com/CortexFoundation/CortexTheseus/issues/20106.
func TestCopyCopyCommitCopy(t *testing.T) {
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)

// Create an account and check if the retrieved balance is correct
addr := common.HexToAddress("0xaffeaffeaffeaffeaffeaffeaffeaffeaffeaffe")
Expand Down Expand Up @@ -696,7 +696,7 @@ func TestCopyCopyCommitCopy(t *testing.T) {
// first, but the journal wiped the entire state object on create-revert.
func TestDeleteCreateRevert(t *testing.T) {
// Create an initial state with a single contract
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase()), nil)
state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)

addr := toAddr([]byte("so"))
state.SetBalance(addr, big.NewInt(1))
Expand Down Expand Up @@ -728,7 +728,7 @@ func TestMissingTrieNodes(t *testing.T) {

// Create an initial state with a few accounts
memDb := rawdb.NewMemoryDatabase()
db := NewDatabase(memDb)
db := NewDatabase(memDb, nil)
var root common.Hash
state, _ := New(common.Hash{}, db, nil)
addr := toAddr([]byte("so"))
Expand Down Expand Up @@ -778,7 +778,7 @@ func TestStateDBAccessList(t *testing.T) {
}

memDb := rawdb.NewMemoryDatabase()
db := NewDatabase(memDb)
db := NewDatabase(memDb, nil)
state, _ := New(common.Hash{}, db, nil)
state.accessList = newAccessList()

Expand Down Expand Up @@ -948,7 +948,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
// Create a state trie with many accounts and slots
var (
memdb = rawdb.NewMemoryDatabase()
statedb = NewDatabase(memdb)
statedb = NewDatabase(memdb, nil)
state, _ = New(types.EmptyRootHash, statedb, nil)
)
for a := byte(0); a < 10; a++ {
Expand All @@ -969,7 +969,7 @@ func TestFlushOrderDataLoss(t *testing.T) {
t.Fatalf("failed to commit state trie: %v", err)
}
// Reopen the state trie from flushed disk and verify it
state, err = New(root, NewDatabase(memdb), nil)
state, err = New(root, NewDatabase(memdb, nil), nil)
if err != nil {
t.Fatalf("failed to reopen state trie: %v", err)
}
Expand Down
8 changes: 4 additions & 4 deletions core/txpool/txpool2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func TestTransactionFutureAttack(t *testing.T) {
t.Parallel()

// Create the pool to test the limit enforcement with
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
config := testTxPoolConfig
config.GlobalQueue = 100
Expand Down Expand Up @@ -114,7 +114,7 @@ func TestTransactionFutureAttack(t *testing.T) {
func TestTransactionFuture1559(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
defer pool.Stop()
Expand Down Expand Up @@ -146,7 +146,7 @@ func TestTransactionFuture1559(t *testing.T) {
func TestTransactionZAttack(t *testing.T) {
t.Parallel()
// Create the pool to test the pricing enforcement with
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
pool := NewTxPool(testTxPoolConfig, eip1559Config, blockchain)
defer pool.Stop()
Expand Down Expand Up @@ -213,7 +213,7 @@ func TestTransactionZAttack(t *testing.T) {

func BenchmarkFutureAttack(b *testing.B) {
// Create the pool to test the limit enforcement with
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase()), nil)
statedb, _ := state.New(common.Hash{}, state.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil)
blockchain := newTestBlockChain(1000000, statedb, new(event.Feed))
config := testTxPoolConfig
config.GlobalQueue = 100
Expand Down
Loading