Skip to content

Commit 127a515

Browse files
authored
Run pebble database tests in Nightly CI Builds (#4026)
1 parent f5f5be8 commit 127a515

26 files changed

+183
-69
lines changed

.github/workflows/gotestsum.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ tags=""
1212
run=""
1313
skip=""
1414
test_state_scheme=""
15+
test_database_engine=""
1516
junitfile=""
1617
log=true
1718
race=false
@@ -49,6 +50,12 @@ while [[ $# -gt 0 ]]; do
4950
test_state_scheme=$1
5051
shift
5152
;;
53+
--test_database_engine)
54+
shift
55+
check_missing_value $# "$1" "--test_database_engine"
56+
test_database_engine=$1
57+
shift
58+
;;
5259
--race)
5360
race=true
5461
shift
@@ -130,6 +137,10 @@ else
130137
cmd="$cmd -args -- --test_loglevel=8" # Use error log level, which is the value 8 in the slog level enum for tests.
131138
fi
132139

140+
if [ "$test_database_engine" != "" ]; then
141+
cmd="$cmd --test_database_engine=$test_database_engine"
142+
fi
143+
133144
if [ "$log" == true ]; then
134145
cmd="$cmd > >(stdbuf -oL tee -a full.log | grep -vE \"DEBUG|TRACE|INFO|seal\")"
135146
else

.github/workflows/nightly-ci.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
strategy:
2424
fail-fast: false
2525
matrix:
26-
test-mode: [legacychallenge, long, challenge, l3challenge, execution-spec-tests]
26+
test-mode: [legacychallenge, long, challenge, l3challenge, execution-spec-tests, pebble]
2727

2828
steps:
2929
- name: Checkout
@@ -85,6 +85,11 @@ jobs:
8585
if: matrix.test-mode == 'execution-spec-tests'
8686
run: ${{ github.workspace }}/.github/workflows/runExecutionSpecTests.sh
8787

88+
- name: run tests with pebble db
89+
if: matrix.test-mode == 'pebble'
90+
run: |
91+
${{ github.workspace }}/.github/workflows/gotestsum.sh --timeout 90m --test_database_engine pebble
92+
8893
- name: Archive detailed run log
8994
uses: actions/upload-artifact@v5
9095
with:

cmd/nitro/init_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ func TestOpenInitializeChainDbIncompatibleStateScheme(t *testing.T) {
418418
defer cancel()
419419

420420
stackConfig := testhelpers.CreateStackConfigForTest(t.TempDir())
421+
stackConfig.DBEngine = rawdb.DBPebble
421422
stack, err := node.New(stackConfig)
422423
Require(t, err)
423424
defer stack.Close()
@@ -685,6 +686,7 @@ func TestOpenInitializeChainDbEmptyInit(t *testing.T) {
685686
defer cancel()
686687

687688
stackConfig := testhelpers.CreateStackConfigForTest(t.TempDir())
689+
stackConfig.DBEngine = rawdb.DBPebble
688690
stack, err := node.New(stackConfig)
689691
Require(t, err)
690692
defer stack.Close()

system_tests/archival_path_scheme_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
func TestAccessingPathSchemeState(t *testing.T) {
1515
ctx, cancel := context.WithCancel(context.Background())
1616
defer cancel()
17-
builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
17+
builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDatabase(rawdb.DBPebble)
1818

1919
// This test is PathScheme specific, it shouldn't be run with HashScheme
2020
builder.RequireScheme(t, rawdb.PathScheme)
@@ -56,7 +56,7 @@ func TestAccessingPathSchemeState(t *testing.T) {
5656
func TestAccessingPathSchemeArchivalState(t *testing.T) {
5757
ctx, cancel := context.WithCancel(context.Background())
5858
defer cancel()
59-
builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
59+
builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDatabase(rawdb.DBPebble)
6060
builder.execConfig.Caching.Archive = true
6161
builder.execConfig.Caching.StateHistory = 2
6262

system_tests/block_validator_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
2929
"github.com/offchainlabs/nitro/util/arbmath"
3030
"github.com/offchainlabs/nitro/util/redisutil"
31-
"github.com/offchainlabs/nitro/util/testhelpers/flag"
31+
testflag "github.com/offchainlabs/nitro/util/testhelpers/flag"
3232
"github.com/offchainlabs/nitro/util/testhelpers/github"
3333
"github.com/offchainlabs/nitro/validator/client/redis"
3434
)

system_tests/bold_challenge_protocol_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ func createTestNodeOnL1ForBoldProtocol(
568568
nodeConfig.BatchPoster.DataPoster.MaxMempoolTransactions = 18
569569
fatalErrChan := make(chan error, 10)
570570
withoutClientWrapper := false
571-
l1info, l1client, l1backend, l1stack, _, _ = createTestL1BlockChain(t, nil, withoutClientWrapper)
571+
l1info, l1client, l1backend, l1stack, _, _ = createTestL1BlockChain(t, nil, withoutClientWrapper, testhelpers.CreateStackConfigForTest(""))
572572
var l2chainDb ethdb.Database
573573
var l2arbDb ethdb.Database
574574
var l2blockchain *core.BlockChain
@@ -636,8 +636,10 @@ func createTestNodeOnL1ForBoldProtocol(
636636

637637
execConfig := ExecConfigDefaultNonSequencerTest(t, rawdb.HashScheme)
638638
Require(t, execConfig.Validate())
639+
stackConfig := testhelpers.CreateStackConfigForTest("")
640+
stackConfig.DBEngine = rawdb.DBPebble
639641
initMessage := getInitMessage(ctx, t, l1client, addresses)
640-
_, l2stack, l2chainDb, l2arbDb, l2blockchain = createNonL1BlockChainWithStackConfig(t, l2info, "", chainConfig, nil, initMessage, nil, execConfig)
642+
_, l2stack, l2chainDb, l2arbDb, l2blockchain = createNonL1BlockChainWithStackConfig(t, l2info, "", chainConfig, nil, initMessage, stackConfig, execConfig)
641643
var sequencerTxOptsPtr *bind.TransactOpts
642644
var dataSigner signature.DataSignerFunc
643645
if isSequencer {
@@ -848,6 +850,7 @@ func create2ndNodeWithConfigForBoldProtocol(
848850
nodeConfig.BatchPoster.DataPoster.MaxMempoolTransactions = 18
849851
if stackConfig == nil {
850852
stackConfig = testhelpers.CreateStackConfigForTest(t.TempDir())
853+
stackConfig.DBEngine = rawdb.DBPebble
851854
}
852855
l2stack, err := node.New(stackConfig)
853856
Require(t, err)

system_tests/common_test.go

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ type NodeBuilder struct {
289289
isSequencer bool
290290
takeOwnership bool
291291
withL1 bool
292-
defaultDbScheme string
292+
defaultStateScheme string
293293
addresses *chaininfo.RollupAddresses
294294
l3Addresses *chaininfo.RollupAddresses
295295
initMessage *arbostypes.ParsedInitMessage
@@ -377,12 +377,27 @@ func (b *NodeBuilder) DefaultConfig(t *testing.T, withL1 bool) *NodeBuilder {
377377
b.l2StackConfig = testhelpers.CreateStackConfigForTest(b.dataDir)
378378
cp := valnode.TestValidationConfig
379379
b.valnodeConfig = &cp
380-
b.defaultDbScheme = rawdb.HashScheme
380+
b.defaultStateScheme = rawdb.HashScheme
381381
if *testflag.StateSchemeFlag == rawdb.PathScheme || *testflag.StateSchemeFlag == rawdb.HashScheme {
382-
b.defaultDbScheme = *testflag.StateSchemeFlag
382+
b.defaultStateScheme = *testflag.StateSchemeFlag
383383
}
384-
b.execConfig = ExecConfigDefaultTest(t, b.defaultDbScheme)
384+
b.execConfig = ExecConfigDefaultTest(t, b.defaultStateScheme)
385385
b.l3Config = L3NitroConfigDefaultTest(t)
386+
387+
return b
388+
}
389+
390+
// Overrides the database selected with `--test_database_engine` flag
391+
//
392+
// Useful if the test needs a specific database engine to be used
393+
func (b *NodeBuilder) WithDatabase(database string) *NodeBuilder {
394+
if database != env.MemoryDB && database != rawdb.DBPebble && database != rawdb.DBLeveldb {
395+
panic("unknown database engine: " + database)
396+
}
397+
398+
b.l1StackConfig.DBEngine = database
399+
b.l2StackConfig.DBEngine = database
400+
b.l3Config.stackConfig.DBEngine = database
386401
return b
387402
}
388403

@@ -435,19 +450,19 @@ func (b *NodeBuilder) RequireScheme(t *testing.T, scheme string) *NodeBuilder {
435450
if testflag.StateSchemeFlag != nil && *testflag.StateSchemeFlag != "" && *testflag.StateSchemeFlag != scheme {
436451
t.Skip("skipping because db scheme is set and not ", scheme)
437452
}
438-
if b.defaultDbScheme != scheme && b.execConfig != nil {
453+
if b.defaultStateScheme != scheme && b.execConfig != nil {
439454
b.execConfig.Caching.StateScheme = scheme
440455
Require(t, b.execConfig.Validate())
441456
}
442-
b.defaultDbScheme = scheme
457+
b.defaultStateScheme = scheme
443458
return b
444459
}
445460

446461
func (b *NodeBuilder) ExecConfigDefaultTest(t *testing.T, sequencer bool) *gethexec.Config {
447462
if sequencer {
448-
ExecConfigDefaultTest(t, b.defaultDbScheme)
463+
ExecConfigDefaultTest(t, b.defaultStateScheme)
449464
}
450-
return ExecConfigDefaultNonSequencerTest(t, b.defaultDbScheme)
465+
return ExecConfigDefaultNonSequencerTest(t, b.defaultStateScheme)
451466
}
452467

453468
// WithL1ClientWrapper creates a ClientWrapper for the L1 RPC client before passing it to the L2 node.
@@ -584,8 +599,8 @@ func (b *NodeBuilder) CheckConfig(t *testing.T) {
584599
// validation currently requires hash
585600
b.RequireScheme(t, rawdb.HashScheme)
586601
}
587-
if b.defaultDbScheme == "" {
588-
b.defaultDbScheme = env.GetTestStateScheme()
602+
if b.defaultStateScheme == "" {
603+
b.defaultStateScheme = env.GetTestStateScheme()
589604
}
590605
if b.execConfig == nil {
591606
b.execConfig = b.ExecConfigDefaultTest(t, true)
@@ -615,7 +630,7 @@ func (b *NodeBuilder) BuildL1(t *testing.T) {
615630
t.Fatal(err)
616631
}
617632
b.L1 = NewTestClient(b.ctx)
618-
b.L1Info, b.L1.Client, b.L1.L1Backend, b.L1.Stack, b.L1.ClientWrapper, b.L1.L1BlobReader = createTestL1BlockChain(t, b.L1Info, b.withL1ClientWrapper)
633+
b.L1Info, b.L1.Client, b.L1.L1Backend, b.L1.Stack, b.L1.ClientWrapper, b.L1.L1BlobReader = createTestL1BlockChain(t, b.L1Info, b.withL1ClientWrapper, b.l1StackConfig)
619634
locator, err := server_common.NewMachineLocator(b.valnodeConfig.Wasm.RootPath)
620635
Require(t, err)
621636
b.addresses, b.initMessage = deployOnParentChain(
@@ -1399,7 +1414,7 @@ func createTestValidationNode(t *testing.T, ctx context.Context, config *valnode
13991414
stackConf.WSModules = []string{server_api.Namespace}
14001415
stackConf.P2P.NoDiscovery = true
14011416
stackConf.P2P.ListenAddr = ""
1402-
stackConf.DBEngine = "leveldb" // TODO Try pebble again in future once iterator race condition issues are fixed
1417+
stackConf.DBEngine = env.GetTestDatabaseEngine()
14031418

14041419
valnode.EnsureValidationExposedViaAuthRPC(&stackConf)
14051420

@@ -1484,11 +1499,10 @@ func AddValNode(t *testing.T, ctx context.Context, nodeConfig *arbnode.Config, u
14841499
configByValidationNode(nodeConfig, valStack)
14851500
}
14861501

1487-
func createTestL1BlockChain(t *testing.T, l1info info, withClientWrapper bool) (info, *ethclient.Client, *eth.Ethereum, *node.Node, *ClientWrapper, daprovider.BlobReader) {
1502+
func createTestL1BlockChain(t *testing.T, l1info info, withClientWrapper bool, stackConfig *node.Config) (info, *ethclient.Client, *eth.Ethereum, *node.Node, *ClientWrapper, daprovider.BlobReader) {
14881503
if l1info == nil {
14891504
l1info = NewL1TestInfo(t)
14901505
}
1491-
stackConfig := testhelpers.CreateStackConfigForTest("")
14921506
l1info.GenerateAccount("Faucet")
14931507
for _, acct := range DefaultChainAccounts {
14941508
l1info.GenerateAccount(acct)
@@ -1497,6 +1511,7 @@ func createTestL1BlockChain(t *testing.T, l1info info, withClientWrapper bool) (
14971511
chainConfig := chaininfo.ArbitrumDevTestChainConfig()
14981512
chainConfig.ArbitrumChainParams = params.ArbitrumChainParams{}
14991513

1514+
stackConfig.DataDir = ""
15001515
stack, err := node.New(stackConfig)
15011516
Require(t, err)
15021517

@@ -1738,15 +1753,23 @@ func createNonL1BlockChainWithStackConfig(
17381753
stack, err := node.New(stackConfig)
17391754
Require(t, err)
17401755

1741-
chainData, err := stack.OpenDatabaseWithOptions("l2chaindata", node.DatabaseOptions{MetricsNamespace: "l2chaindata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("l2chaindata")})
1742-
Require(t, err)
1743-
1744-
wasmData, err := stack.OpenDatabaseWithOptions("wasm", node.DatabaseOptions{MetricsNamespace: "wasm/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("wasm"), NoFreezer: true})
1745-
Require(t, err)
1756+
chainData := rawdb.NewMemoryDatabase()
1757+
if stack.Config().DBEngine != env.MemoryDB {
1758+
chainData, err = stack.OpenDatabaseWithOptions("l2chaindata", node.DatabaseOptions{MetricsNamespace: "l2chaindata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("l2chaindata")})
1759+
Require(t, err)
1760+
}
1761+
wasmData := rawdb.NewMemoryDatabase()
1762+
if stack.Config().DBEngine != env.MemoryDB {
1763+
wasmData, err = stack.OpenDatabaseWithOptions("wasm", node.DatabaseOptions{MetricsNamespace: "wasm/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("wasm"), NoFreezer: true})
1764+
Require(t, err)
1765+
}
17461766

17471767
chainDb := rawdb.WrapDatabaseWithWasm(chainData, wasmData)
1748-
arbDb, err := stack.OpenDatabaseWithOptions("arbitrumdata", node.DatabaseOptions{MetricsNamespace: "arbitrumdata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("arbitrumdata"), NoFreezer: true})
1749-
Require(t, err)
1768+
arbDb := rawdb.NewMemoryDatabase()
1769+
if stack.Config().DBEngine != env.MemoryDB {
1770+
arbDb, err = stack.OpenDatabaseWithOptions("arbitrumdata", node.DatabaseOptions{MetricsNamespace: "arbitrumdata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("arbitrumdata"), NoFreezer: true})
1771+
Require(t, err)
1772+
}
17501773

17511774
initReader := statetransfer.NewMemoryInitDataReader(&info.ArbInitData)
17521775
if initMessage == nil {
@@ -1836,14 +1859,23 @@ func Create2ndNodeWithConfig(
18361859
chainStack, err := node.New(stackConfig)
18371860
Require(t, err)
18381861

1839-
chainData, err := chainStack.OpenDatabaseWithOptions("l2chaindata", node.DatabaseOptions{MetricsNamespace: "l2chaindata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("l2chaindata")})
1840-
Require(t, err)
1841-
wasmData, err := chainStack.OpenDatabaseWithOptions("wasm", node.DatabaseOptions{MetricsNamespace: "wasm/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("wasm"), NoFreezer: true})
1842-
Require(t, err)
1862+
chainData := rawdb.NewMemoryDatabase()
1863+
if chainStack.Config().DBEngine != env.MemoryDB {
1864+
chainData, err = chainStack.OpenDatabaseWithOptions("l2chaindata", node.DatabaseOptions{MetricsNamespace: "l2chaindata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("l2chaindata")})
1865+
Require(t, err)
1866+
}
1867+
wasmData := rawdb.NewMemoryDatabase()
1868+
if chainStack.Config().DBEngine != env.MemoryDB {
1869+
wasmData, err = chainStack.OpenDatabaseWithOptions("wasm", node.DatabaseOptions{MetricsNamespace: "wasm/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("wasm"), NoFreezer: true})
1870+
Require(t, err)
1871+
}
18431872
chainDb := rawdb.WrapDatabaseWithWasm(chainData, wasmData)
18441873

1845-
arbDb, err := chainStack.OpenDatabaseWithOptions("arbitrumdata", node.DatabaseOptions{MetricsNamespace: "arbitrumdata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("arbitrumdata"), NoFreezer: true})
1846-
Require(t, err)
1874+
arbDb := rawdb.NewMemoryDatabase()
1875+
if chainStack.Config().DBEngine != env.MemoryDB {
1876+
arbDb, err = chainStack.OpenDatabaseWithOptions("arbitrumdata", node.DatabaseOptions{MetricsNamespace: "arbitrumdata/", PebbleExtraOptions: conf.PersistentConfigDefault.Pebble.ExtraOptions("arbitrumdata"), NoFreezer: true})
1877+
Require(t, err)
1878+
}
18471879
initReader := statetransfer.NewMemoryInitDataReader(chainInitData)
18481880

18491881
dataSigner := signature.DataSignerFromPrivateKey(parentChainInfo.GetInfoWithPrivKey("Sequencer").PrivateKey)

system_tests/fees_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919

2020
"github.com/ethereum/go-ethereum/accounts/abi/bind"
2121
"github.com/ethereum/go-ethereum/common"
22+
"github.com/ethereum/go-ethereum/core/rawdb"
2223
"github.com/ethereum/go-ethereum/core/types"
2324
"github.com/ethereum/go-ethereum/params"
2425

@@ -33,7 +34,7 @@ func TestSequencerFeePaid(t *testing.T) {
3334
ctx, cancel := context.WithCancel(context.Background())
3435
defer cancel()
3536

36-
builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
37+
builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDatabase(rawdb.DBPebble)
3738
cleanup := builder.Build(t)
3839
defer cleanup()
3940

@@ -135,7 +136,7 @@ func testSequencerPriceAdjustsFrom(t *testing.T, initialEstimate uint64) {
135136
ctx, cancel := context.WithCancel(context.Background())
136137
defer cancel()
137138

138-
builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
139+
builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDatabase(rawdb.DBPebble)
139140
builder.nodeConfig.DelayedSequencer.FinalizeDistance = 1
140141
cleanup := builder.Build(t)
141142
defer cleanup()

system_tests/finality_data_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func TestFinalizedBlocksMovedToAncients(t *testing.T) {
3636
ctx, cancel := context.WithCancel(context.Background())
3737
defer cancel()
3838

39-
builder := NewNodeBuilder(ctx).DefaultConfig(t, true)
39+
builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDatabase(rawdb.DBPebble)
4040
// The procedure that periodically pushes finality data, from consensus to execution,
4141
// will not be able to get finalized/safe block numbers since UseFinalityData is false.
4242
// Therefore, with UseFinalityData set to false, ExecutionEngine will not be able to move data to ancients by itself,

system_tests/forwarder_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616

1717
"github.com/alicebob/miniredis/v2"
1818

19+
"github.com/ethereum/go-ethereum/core/rawdb"
1920
"github.com/ethereum/go-ethereum/ethclient"
2021

2122
"github.com/offchainlabs/nitro/arbnode"
@@ -299,7 +300,7 @@ func TestRedisForwarderFallbackNoRedis(t *testing.T) {
299300
ipcPath: fallbackIpcPath,
300301
redisUrl: redisUrl,
301302
enableSecCoordinator: false,
302-
})
303+
}).WithDatabase(rawdb.DBPebble)
303304
cleanup := builder.Build(t)
304305
defer cleanup()
305306
fallbackClient := builder.L2.Client

0 commit comments

Comments
 (0)