Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d21b735
add draft of debug block
magicxyyz Sep 24, 2025
55880e4
Merge branch 'master' into debug-block
magicxyyz Sep 25, 2025
dc79489
set chain config in debug block
magicxyyz Sep 25, 2025
0fa4d20
cleanup sequencer config
magicxyyz Sep 25, 2025
94f58b2
open arbosstate for writing chain config in debug block
magicxyyz Sep 25, 2025
b7583c5
use chainConfig.ArbitrumChainParams.DebugAddress in debug block
magicxyyz Sep 26, 2025
9664d99
update geth pin
magicxyyz Sep 29, 2025
28a48ba
Merge branch 'master' into debug-block
magicxyyz Sep 29, 2025
0089af3
use build tag to guard debug block injection
magicxyyz Sep 30, 2025
f591e5a
add dangerous config for debugblock, guard impl with build tag
magicxyyz Oct 1, 2025
b6deb16
publish debug tx to trigger next block
magicxyyz Oct 2, 2025
8f96031
update geth pin
magicxyyz Oct 2, 2025
f0d4fd9
Merge branch 'master' into debug-block
magicxyyz Oct 2, 2025
45039a6
fix returning error from stubbed debugblock.ConfigAddOptions
magicxyyz Oct 2, 2025
c55d177
use hardcoded account to trigger debug block
magicxyyz Oct 3, 2025
0e1dd84
add system test for debug block injection
magicxyyz Oct 3, 2025
4352417
expand trigger account comment
magicxyyz Oct 3, 2025
01a3e3c
test that debug block injection doesn't affect prod build
magicxyyz Oct 3, 2025
7c10a57
rename debug block test file
magicxyyz Oct 3, 2025
e737880
fix challenge test build
magicxyyz Oct 6, 2025
967954d
update geth pin
magicxyyz Oct 6, 2025
efdc491
Merge branch 'master' into debug-block
magicxyyz Oct 6, 2025
f1434ef
Merge branch 'master' into debug-block
magicxyyz Oct 7, 2025
3fcbad7
add experimental tooling tests to ci workflow
magicxyyz Oct 7, 2025
6d32415
execute only TestExperimental tests in experimental ci step
magicxyyz Oct 7, 2025
6a4986c
add nitro-node-experimental to Dockerfile
magicxyyz Oct 7, 2025
2668155
Merge branch 'master' into debug-block
magicxyyz Oct 7, 2025
a989d74
copy debugblock package into wasm-bin-builder
magicxyyz Oct 7, 2025
4e34dce
Merge branch 'master' into debug-block
magicxyyz Oct 7, 2025
229410c
Merge branch 'master' into debug-block
magicxyyz Oct 8, 2025
009dbb1
use DebugAddress as pointer
magicxyyz Oct 9, 2025
1d954f8
update geth pin
magicxyyz Oct 9, 2025
373946d
add missing newline
magicxyyz Oct 10, 2025
d7d885a
Merge branch 'master' into debug-block
magicxyyz Oct 10, 2025
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
11 changes: 9 additions & 2 deletions .github/workflows/_go-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
strategy:
fail-fast: false
matrix:
test-mode: [defaults-A, defaults-B, flaky, pathdb, challenge, stylus, l3challenge]
test-mode: [defaults-A, defaults-B, flaky, pathdb, challenge, stylus, l3challenge, experimental]
services:
redis:
image: redis
Expand Down Expand Up @@ -147,14 +147,21 @@ jobs:
${{ github.workspace }}/.github/workflows/gotestsum.sh
--tags challengetest --run TestL3Challenge --timeout 120m --cover

# --------------------- CHALLENGE MODES ---------------------
# --------------------- STYLUS MODE --------------------------

- name: run stylus tests
if: matrix.test-mode == 'stylus'
run: >-
${{ github.workspace }}/.github/workflows/gotestsum.sh
--tags stylustest --run TestProgramArbitrator --timeout 60m --cover

# --------------------- EXPERIMENTAL MODE --------------------
- name: run experimental tooling tests
if: matrix.test-mode == 'experimental'
run: >-
${{ github.workspace }}/.github/workflows/gotestsum.sh
--tags debugblock --run TestExperimental --timeout 60m --cover

# --------------------- ARCHIVE LOGS FOR ALL MODES ---------------------

- name: Archive detailed run log
Expand Down
7 changes: 7 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ COPY ./contracts/package.json ./contracts/yarn.lock ./contracts/
COPY ./safe-smart-account ./safe-smart-account
COPY ./solgen/gen.go ./solgen/
COPY ./go-ethereum ./go-ethereum
COPY ./experimental/debugblock ./experimental/debugblock
COPY scripts/remove_reference_types.sh scripts/
COPY --from=brotli-wasm-export / target/
COPY --from=contracts-builder workspace/contracts-local/out/precompiles/ contracts-local/out/precompiles/
Expand Down Expand Up @@ -387,5 +388,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \

USER user

FROM nitro-node AS nitro-node-experimental
USER root
COPY --from=node-builder /workspace/target/bin/nitro-experimental /usr/local/bin/
ENTRYPOINT [ "/usr/local/bin/nitro-experimental" , "--validation.wasm.allowed-wasm-module-roots", "/home/user/nitro-legacy/machines,/home/user/target/machines"]
USER user

FROM nitro-node AS nitro-node-default
# Just to ensure nitro-node-dist is default
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ all: build build-replay-env test-gen-proofs
@touch .make/all

.PHONY: build
build: $(patsubst %,$(output_root)/bin/%, nitro deploy relay daprovider daserver autonomous-auctioneer bidder-client datool el-proxy mockexternalsigner seq-coordinator-invalidate nitro-val seq-coordinator-manager dbconv genesis-generator)
build: $(patsubst %,$(output_root)/bin/%, nitro deploy relay daprovider daserver autonomous-auctioneer bidder-client datool el-proxy mockexternalsigner seq-coordinator-invalidate nitro-val seq-coordinator-manager dbconv genesis-generator nitro-experimental)
@printf $(done)

.PHONY: build-node-deps
Expand Down Expand Up @@ -348,6 +348,10 @@ $(output_root)/bin/seq-coordinator-manager: $(DEP_PREDICATE) build-node-deps
$(output_root)/bin/dbconv: $(DEP_PREDICATE) build-node-deps
go build $(GOLANG_PARAMS) -o $@ "$(CURDIR)/cmd/dbconv"

# nitro built with experimental tooling enabled
$(output_root)/bin/nitro-experimental: $(DEP_PREDICATE) build-node-deps
go build $(GOLANG_PARAMS) --tags debugblock -o $@ "$(CURDIR)/cmd/nitro"

# recompile wasm, but don't change timestamp unless files differ
$(replay_wasm): $(DEP_PREDICATE) $(go_source) .make/solgen
mkdir -p `dirname $(replay_wasm)`
Expand Down
5 changes: 5 additions & 0 deletions arbos/block_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/arbos/l2pricing"
"github.com/offchainlabs/nitro/arbos/util"
"github.com/offchainlabs/nitro/experimental/debugblock"
"github.com/offchainlabs/nitro/util/arbmath"
)

Expand Down Expand Up @@ -254,6 +255,10 @@ func ProduceBlockAdvanced(

firstTx := types.NewTx(startTx)

if chainConfig.DebugMode() && header.Number.Uint64() == chainConfig.ArbitrumChainParams.DebugBlock {
debugblock.DebugBlockStateUpdate(statedb, expectedBalanceDelta, chainConfig)
}

for {
// repeatedly process the next tx, doing redeems created along the way in FIFO order

Expand Down
5 changes: 4 additions & 1 deletion cmd/nitro/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import (
"github.com/offchainlabs/nitro/arbnode"
"github.com/offchainlabs/nitro/arbos/arbosState"
"github.com/offchainlabs/nitro/arbos/arbostypes"
"github.com/offchainlabs/nitro/bold/chain-abstraction"
protocol "github.com/offchainlabs/nitro/bold/chain-abstraction"
"github.com/offchainlabs/nitro/cmd/chaininfo"
"github.com/offchainlabs/nitro/cmd/conf"
"github.com/offchainlabs/nitro/cmd/pruning"
Expand Down Expand Up @@ -621,6 +621,9 @@ func openInitializeChainDb(ctx context.Context, stack *node.Node, config *NodeCo
if err := dbutil.UnfinishedConversionCheck(chainData); err != nil {
return nil, nil, fmt.Errorf("l2chaindata unfinished database conversion check error: %w", err)
}
if config.Execution.Dangerous.DebugBlock.OverwriteChainConfig {
config.Execution.Dangerous.DebugBlock.Apply(chainConfig)
}
wasmDb, err := stack.OpenDatabaseWithOptions("wasm", node.DatabaseOptions{Cache: config.Execution.Caching.DatabaseCache, Handles: config.Persistent.Handles, MetricsNamespace: "wasm/", PebbleExtraOptions: persistentConfig.Pebble.ExtraOptions("wasm")})
if err != nil {
return nil, nil, err
Expand Down
22 changes: 22 additions & 0 deletions execution/gethexec/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"github.com/offchainlabs/nitro/arbos/programs"
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/execution"
"github.com/offchainlabs/nitro/experimental/debugblock"
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
"github.com/offchainlabs/nitro/util"
"github.com/offchainlabs/nitro/util/arbmath"
Expand Down Expand Up @@ -127,6 +128,7 @@ type Config struct {
BlockMetadataApiBlocksLimit uint64 `koanf:"block-metadata-api-blocks-limit"`
VmTrace LiveTracingConfig `koanf:"vmtrace"`
ExposeMultiGas bool `koanf:"expose-multi-gas"`
Dangerous DangerousConfig `koanf:"dangerous"`

forwardingTarget string
}
Expand Down Expand Up @@ -155,6 +157,9 @@ func (c *Config) Validate() error {
if err := c.RPC.Validate(); err != nil {
return err
}
if err := c.Dangerous.Validate(); err != nil {
return err
}
return nil
}

Expand All @@ -176,6 +181,7 @@ func ConfigAddOptions(prefix string, f *pflag.FlagSet) {
f.Uint64(prefix+".block-metadata-api-blocks-limit", ConfigDefault.BlockMetadataApiBlocksLimit, "maximum number of blocks allowed to be queried for blockMetadata per arb_getRawBlockMetadata query. Enabled by default, set 0 to disable the limit")
f.Bool(prefix+".expose-multi-gas", false, "experimental: expose multi-dimensional gas in transaction receipts")
LiveTracingConfigAddOptions(prefix+".vmtrace", f)
DangerousConfigAddOptions(prefix+".dangerous", f)
}

type LiveTracingConfig struct {
Expand All @@ -193,6 +199,22 @@ func LiveTracingConfigAddOptions(prefix string, f *pflag.FlagSet) {
f.String(prefix+".json-config", DefaultLiveTracingConfig.JSONConfig, "(experimental) Tracer configuration in JSON format")
}

type DangerousConfig struct {
DebugBlock debugblock.Config `koanf:"debug-block"`
}

var DefaultDangerousConfig = DangerousConfig{
DebugBlock: debugblock.ConfigDefault,
}

func DangerousConfigAddOptions(prefix string, f *pflag.FlagSet) {
debugblock.ConfigAddOptions(prefix+".debug-block", f)
}

func (c *DangerousConfig) Validate() error {
return c.DebugBlock.Validate()
}

var ConfigDefault = Config{
RPC: arbitrum.DefaultConfig,
TxIndexer: DefaultTxIndexerConfig,
Expand Down
69 changes: 43 additions & 26 deletions execution/gethexec/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"github.com/offchainlabs/nitro/arbos/l1pricing"
"github.com/offchainlabs/nitro/arbutil"
"github.com/offchainlabs/nitro/execution"
"github.com/offchainlabs/nitro/experimental/debugblock"
"github.com/offchainlabs/nitro/timeboost"
"github.com/offchainlabs/nitro/util/arbmath"
"github.com/offchainlabs/nitro/util/containers"
Expand All @@ -62,30 +63,30 @@ var (
)

type SequencerConfig struct {
Enable bool `koanf:"enable"`
MaxBlockSpeed time.Duration `koanf:"max-block-speed" reload:"hot"`
ReadFromTxQueueTimeout time.Duration `koanf:"read-from-tx-queue-timeout" reload:"hot"`
MaxRevertGasReject uint64 `koanf:"max-revert-gas-reject" reload:"hot"`
MaxAcceptableTimestampDelta time.Duration `koanf:"max-acceptable-timestamp-delta" reload:"hot"`
SenderWhitelist []string `koanf:"sender-whitelist"`
Forwarder ForwarderConfig `koanf:"forwarder"`
QueueSize int `koanf:"queue-size"`
QueueTimeout time.Duration `koanf:"queue-timeout" reload:"hot"`
NonceCacheSize int `koanf:"nonce-cache-size" reload:"hot"`
MaxTxDataSize int `koanf:"max-tx-data-size" reload:"hot"`
NonceFailureCacheSize int `koanf:"nonce-failure-cache-size" reload:"hot"`
NonceFailureCacheExpiry time.Duration `koanf:"nonce-failure-cache-expiry" reload:"hot"`
ExpectedSurplusGasPriceMode string `koanf:"expected-surplus-gas-price-mode"`
ExpectedSurplusSoftThreshold string `koanf:"expected-surplus-soft-threshold" reload:"hot"`
ExpectedSurplusHardThreshold string `koanf:"expected-surplus-hard-threshold" reload:"hot"`
EnableProfiling bool `koanf:"enable-profiling" reload:"hot"`
Timeboost TimeboostConfig `koanf:"timeboost"`
Dangerous DangerousConfig `koanf:"dangerous"`
Enable bool `koanf:"enable"`
MaxBlockSpeed time.Duration `koanf:"max-block-speed" reload:"hot"`
ReadFromTxQueueTimeout time.Duration `koanf:"read-from-tx-queue-timeout" reload:"hot"`
MaxRevertGasReject uint64 `koanf:"max-revert-gas-reject" reload:"hot"`
MaxAcceptableTimestampDelta time.Duration `koanf:"max-acceptable-timestamp-delta" reload:"hot"`
SenderWhitelist []string `koanf:"sender-whitelist"`
Forwarder ForwarderConfig `koanf:"forwarder"`
QueueSize int `koanf:"queue-size"`
QueueTimeout time.Duration `koanf:"queue-timeout" reload:"hot"`
NonceCacheSize int `koanf:"nonce-cache-size" reload:"hot"`
MaxTxDataSize int `koanf:"max-tx-data-size" reload:"hot"`
NonceFailureCacheSize int `koanf:"nonce-failure-cache-size" reload:"hot"`
NonceFailureCacheExpiry time.Duration `koanf:"nonce-failure-cache-expiry" reload:"hot"`
ExpectedSurplusGasPriceMode string `koanf:"expected-surplus-gas-price-mode"`
ExpectedSurplusSoftThreshold string `koanf:"expected-surplus-soft-threshold" reload:"hot"`
ExpectedSurplusHardThreshold string `koanf:"expected-surplus-hard-threshold" reload:"hot"`
EnableProfiling bool `koanf:"enable-profiling" reload:"hot"`
Timeboost TimeboostConfig `koanf:"timeboost"`
Dangerous SequencerDangerousConfig `koanf:"dangerous"`
expectedSurplusSoftThreshold int
expectedSurplusHardThreshold int
}

type DangerousConfig struct {
type SequencerDangerousConfig struct {
DisableSeqInboxMaxDataSizeCheck bool `koanf:"disable-seq-inbox-max-data-size-check"`
DisableBlobBaseFeeCheck bool `koanf:"disable-blob-base-fee-check"`
}
Expand Down Expand Up @@ -193,10 +194,10 @@ var DefaultSequencerConfig = SequencerConfig{
ExpectedSurplusHardThreshold: "default",
EnableProfiling: false,
Timeboost: DefaultTimeboostConfig,
Dangerous: DefaultDangerousConfig,
Dangerous: DefaultSequencerDangerousConfig,
}

var DefaultDangerousConfig = DangerousConfig{
var DefaultSequencerDangerousConfig = SequencerDangerousConfig{
DisableSeqInboxMaxDataSizeCheck: false,
}

Expand All @@ -210,7 +211,7 @@ func SequencerConfigAddOptions(prefix string, f *pflag.FlagSet) {
AddOptionsForSequencerForwarderConfig(prefix+".forwarder", f)
TimeboostAddOptions(prefix+".timeboost", f)

DangerousAddOptions(prefix+".dangerous", f)
SequencerDangerousAddOptions(prefix+".dangerous", f)
f.Int(prefix+".queue-size", DefaultSequencerConfig.QueueSize, "size of the pending tx queue")
f.Duration(prefix+".queue-timeout", DefaultSequencerConfig.QueueTimeout, "maximum amount of time transaction can wait in queue")
f.Int(prefix+".nonce-cache-size", DefaultSequencerConfig.NonceCacheSize, "size of the tx sender nonce cache")
Expand All @@ -236,9 +237,9 @@ func TimeboostAddOptions(prefix string, f *pflag.FlagSet) {
f.Uint64(prefix+".queue-timeout-in-blocks", DefaultTimeboostConfig.QueueTimeoutInBlocks, "maximum amount of time (measured in blocks) that Express Lane transactions can wait in the sequencer's queue")
}

func DangerousAddOptions(prefix string, f *pflag.FlagSet) {
f.Bool(prefix+".disable-seq-inbox-max-data-size-check", DefaultDangerousConfig.DisableSeqInboxMaxDataSizeCheck, "DANGEROUS! disables nitro checks on sequencer MaxTxDataSize against the sequencer inbox MaxDataSize")
f.Bool(prefix+".disable-blob-base-fee-check", DefaultDangerousConfig.DisableBlobBaseFeeCheck, "DANGEROUS! disables nitro checks on sequencer for blob base fee")
func SequencerDangerousAddOptions(prefix string, f *pflag.FlagSet) {
f.Bool(prefix+".disable-seq-inbox-max-data-size-check", DefaultSequencerDangerousConfig.DisableSeqInboxMaxDataSizeCheck, "DANGEROUS! disables nitro checks on sequencer MaxTxDataSize against the sequencer inbox MaxDataSize")
f.Bool(prefix+".disable-blob-base-fee-check", DefaultSequencerDangerousConfig.DisableBlobBaseFeeCheck, "DANGEROUS! disables nitro checks on sequencer for blob base fee")
}

type txQueueItem struct {
Expand Down Expand Up @@ -1112,6 +1113,22 @@ func (s *Sequencer) createBlock(ctx context.Context) (returnValue bool) {

var startOfReadingFromTxQueue time.Time

if s.execEngine.bc.Config().DebugMode() {
chainConfig := s.execEngine.bc.Config()
if lastBlock.Number.Uint64()+1 == chainConfig.ArbitrumChainParams.DebugBlock {
// publish transaction to trigger next block
tx := debugblock.PrepareDebugTransaction(chainConfig, lastBlock)
if tx != nil {
go func() {
if err := s.PublishTransaction(ctx, tx, nil); err != nil {
log.Error("debug block: failed to publish tx", "err", err)
} else {
log.Warn("published tx", "txHash", tx.Hash())
}
}()
}
}
}
for {
if len(queueItems) == 1 {
startOfReadingFromTxQueue = time.Now()
Expand Down
16 changes: 16 additions & 0 deletions experimental/debugblock/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// DANGER! this file is included in all builds
// DANGER! do not place any of the experimental logic and features here

package debugblock

type Config struct {
OverwriteChainConfig bool `koanf:"overwrite-chain-config"`
DebugAddress string `koanf:"debug-address"`
DebugBlockNum uint64 `koanf:"debug-blocknum"`
}

var ConfigDefault = Config{
OverwriteChainConfig: false,
DebugAddress: "",
DebugBlockNum: 0,
}
Loading
Loading