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 triedb race test #1913

Merged
merged 10 commits into from
Oct 18, 2023
1 change: 1 addition & 0 deletions execution/gethexec/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func ConfigDefaultTest() *Config {
config.ParentChainReader = headerreader.Config{}
config.Sequencer = TestSequencerConfig
config.ForwardingTarget = "null"
config.ParentChainReader = headerreader.TestConfig

_ = config.Validate()

Expand Down
2 changes: 1 addition & 1 deletion go-ethereum
28 changes: 11 additions & 17 deletions system_tests/recreatestate_rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,8 @@ func TestRecreateStateForRPCNoDepthLimit(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0
nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32)
Expand All @@ -121,7 +120,6 @@ func TestRecreateStateForRPCNoDepthLimit(t *testing.T) {
if balance.Cmp(expectedBalance) != 0 {
Fatal(t, "unexpected balance result for last block, want: ", expectedBalance, " have: ", balance)
}

}

func TestRecreateStateForRPCBigEnoughDepthLimit(t *testing.T) {
Expand All @@ -133,9 +131,8 @@ func TestRecreateStateForRPCBigEnoughDepthLimit(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0
nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32)
Expand Down Expand Up @@ -168,9 +165,8 @@ func TestRecreateStateForRPCDepthLimitExceeded(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0
nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32)
Expand Down Expand Up @@ -203,9 +199,8 @@ func TestRecreateStateForRPCMissingBlockParent(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0
nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, headerCacheLimit+5)
Expand Down Expand Up @@ -249,9 +244,8 @@ func TestRecreateStateForRPCBeyondGenesis(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0
nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, 32)
Expand Down Expand Up @@ -285,9 +279,9 @@ func TestRecreateStateForRPCBlockNotFoundWhileRecreating(t *testing.T) {
nodeConfig.Sequencer.MaxBlockSpeed = 0
nodeConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
nodeConfig.Caching.Archive = true
// disable caching of states in BlockChain.stateCache
// disable trie/Database.cleans cache, so as states removed from ChainDb won't be cached there
nodeConfig.Caching.TrieCleanCache = 0
nodeConfig.Caching.TrieDirtyCache = 0

nodeConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 0
nodeConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
_, execNode, l2client, cancelNode := prepareNodeWithHistory(t, ctx, nodeConfig, blockCacheLimit+4)
Expand Down Expand Up @@ -421,6 +415,9 @@ func testSkippingSavingStateAndRecreatingAfterRestart(t *testing.T, cacheConfig
}
for i := genesis + 1; i <= genesis+uint64(txCount); i += i % 10 {
_, err = client.BalanceAt(ctx, GetTestAddressForAccountName(t, "User2"), new(big.Int).SetUint64(i))
if err != nil {
t.Log("skipBlocks:", skipBlocks, "skipGas:", skipGas)
}
Require(t, err)
}

Expand All @@ -434,10 +431,7 @@ func testSkippingSavingStateAndRecreatingAfterRestart(t *testing.T, cacheConfig
func TestSkippingSavingStateAndRecreatingAfterRestart(t *testing.T) {
cacheConfig := gethexec.DefaultCachingConfig
cacheConfig.Archive = true
// disable caching of states in BlockChain.stateCache
cacheConfig.TrieCleanCache = 0
cacheConfig.TrieDirtyCache = 0
// test defaults
//// test defaults
testSkippingSavingStateAndRecreatingAfterRestart(t, &cacheConfig, 512)

cacheConfig.MaxNumberOfBlocksToSkipStateSaving = 127
Expand Down
84 changes: 84 additions & 0 deletions system_tests/triedb_race_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package arbtest

import (
"context"
"sync"
"testing"
"time"

"github.com/ethereum/go-ethereum/arbitrum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/rpc"
"github.com/offchainlabs/nitro/execution/gethexec"
"github.com/offchainlabs/nitro/util/testhelpers"
)

func TestTrieDBCommitRace(t *testing.T) {
_ = testhelpers.InitTestLog(t, log.LvlError)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
execConfig := gethexec.ConfigDefaultTest()
execConfig.RPC.MaxRecreateStateDepth = arbitrum.InfiniteMaxRecreateStateDepth
execConfig.Sequencer.MaxBlockSpeed = 0
execConfig.Sequencer.MaxTxDataSize = 150 // 1 test tx ~= 110
execConfig.Caching.Archive = true
execConfig.Caching.BlockCount = 127
execConfig.Caching.BlockAge = 0
execConfig.Caching.MaxNumberOfBlocksToSkipStateSaving = 127
execConfig.Caching.MaxAmountOfGasToSkipStateSaving = 0
l2info, node, l2client, _, _, _, l1stack := createTestNodeOnL1WithConfig(t, ctx, true, nil, execConfig, nil, nil)
cancel = func() {
defer requireClose(t, l1stack)
defer node.StopAndWait()
}
defer cancel()
execNode := getExecNode(t, node)
l2info.GenerateAccount("User2")
bc := execNode.Backend.ArbInterface().BlockChain()

var wg sync.WaitGroup
quit := make(chan struct{})
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
default:
TransferBalance(t, "Faucet", "User2", common.Big1, l2info, l2client, ctx)
case <-quit:
return
}
}
}()
api := execNode.Backend.APIBackend()
blockNumber := 1
for i := 0; i < 5; i++ {
var roots []common.Hash
for len(roots) < 1024 {
select {
default:
block, err := api.BlockByNumber(ctx, rpc.BlockNumber(blockNumber))
if err == nil && block != nil {
root := block.Root()
if statedb, err := bc.StateAt(root); err == nil {
err := statedb.Database().TrieDB().Reference(root, common.Hash{})
Require(t, err)
roots = append(roots, root)
}
blockNumber += 1
}
case <-quit:
return
}
}
t.Log("dereferencing...")
for _, root := range roots {
err := bc.TrieDB().Dereference(root)
Require(t, err)
time.Sleep(1)
}
}
close(quit)
wg.Wait()
}
Loading