From b0d586cb4dcc13d414de86eb35958f5bb04be54a Mon Sep 17 00:00:00 2001 From: Gabriel de Quadros Ligneul Date: Mon, 28 Oct 2024 17:31:15 -0300 Subject: [PATCH] Use BoLD contracts to test delay buffer Rebase the delay buffer PR on top of BoLD's little merge. Then, use the BoLD version of the contracts when appropriate instead of using the delay-buffer development branch. --- arbnode/batch_poster.go | 3 +- arbnode/delay_buffer.go | 2 +- arbnode/node.go | 37 --- cmd/deploy/deploy.go | 12 +- deploy/deploy.go | 117 +++++++-- deploy/legacy.go | 321 +++++++++++++++++++++++ system_tests/batch_poster_test.go | 10 +- system_tests/common_test.go | 103 ++++++-- system_tests/full_challenge_impl_test.go | 1 - 9 files changed, 509 insertions(+), 97 deletions(-) create mode 100644 deploy/legacy.go diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index fc1a789db9..eb0a98240c 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "github.com/offchainlabs/bold/solgen/go/bridgegen" "github.com/offchainlabs/nitro/arbnode/dataposter" "github.com/offchainlabs/nitro/arbnode/dataposter/storage" "github.com/offchainlabs/nitro/arbnode/redislock" @@ -44,7 +45,6 @@ import ( "github.com/offchainlabs/nitro/cmd/chaininfo" "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/execution" - "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/util" "github.com/offchainlabs/nitro/util/arbmath" "github.com/offchainlabs/nitro/util/blobs" @@ -317,7 +317,6 @@ func NewBatchPoster(ctx context.Context, opts *BatchPosterOpts) (*BatchPoster, e if err = opts.Config().Validate(); err != nil { return nil, err } - // TODO(delaybuffer) use new bridgegen seqInboxABI, err := bridgegen.SequencerInboxMetaData.GetAbi() if err != nil { return nil, err diff --git a/arbnode/delay_buffer.go b/arbnode/delay_buffer.go index 508fec1b35..ffef7ee828 100644 --- a/arbnode/delay_buffer.go +++ b/arbnode/delay_buffer.go @@ -14,8 +14,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/offchainlabs/bold/solgen/go/bridgegen" "github.com/offchainlabs/nitro/arbos/arbostypes" - "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/util/headerreader" ) diff --git a/arbnode/node.go b/arbnode/node.go index d7d9465205..7445999fcd 100644 --- a/arbnode/node.go +++ b/arbnode/node.go @@ -39,7 +39,6 @@ import ( "github.com/offchainlabs/nitro/execution/gethexec" "github.com/offchainlabs/nitro/solgen/go/bridgegen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" - "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/staker" boldstaker "github.com/offchainlabs/nitro/staker/bold" legacystaker "github.com/offchainlabs/nitro/staker/legacy" @@ -53,42 +52,6 @@ import ( "github.com/offchainlabs/nitro/wsbroadcastserver" ) -func DefaultBufferConfig() rollupgen.BufferConfig { - return rollupgen.BufferConfig{ - Threshold: 600, // 1 hour of blocks - Max: 14400, // 2 days of blocks - ReplenishRateInBasis: 500, // 5% - } -} - -func GenerateRollupConfig(prod bool, wasmModuleRoot common.Hash, rollupOwner common.Address, chainConfig *params.ChainConfig, serializedChainConfig []byte, loserStakeEscrow common.Address, bufferConfig rollupgen.BufferConfig) rollupgen.Config { - var confirmPeriod uint64 - if prod { - confirmPeriod = 45818 - } else { - confirmPeriod = 20 - } - return rollupgen.Config{ - ConfirmPeriodBlocks: confirmPeriod, - ExtraChallengeTimeBlocks: 200, - StakeToken: common.Address{}, - BaseStake: big.NewInt(params.Ether), - WasmModuleRoot: wasmModuleRoot, - Owner: rollupOwner, - LoserStakeEscrow: loserStakeEscrow, - ChainId: chainConfig.ChainID, - // TODO could the ChainConfig be just []byte? - ChainConfig: string(serializedChainConfig), - SequencerInboxMaxTimeVariation: rollupgen.ISequencerInboxMaxTimeVariation{ - DelayBlocks: big.NewInt(60 * 60 * 24 / 15), - FutureBlocks: big.NewInt(12), - DelaySeconds: big.NewInt(60 * 60 * 24), - FutureSeconds: big.NewInt(60 * 60), - }, - BufferConfig: bufferConfig, - } -} - type Config struct { Sequencer bool `koanf:"sequencer"` ParentChainReader headerreader.Config `koanf:"parent-chain-reader" reload:"hot"` diff --git a/cmd/deploy/deploy.go b/cmd/deploy/deploy.go index 6060c55586..603539196f 100644 --- a/cmd/deploy/deploy.go +++ b/cmd/deploy/deploy.go @@ -17,7 +17,6 @@ import ( "github.com/offchainlabs/nitro/cmd/chaininfo" "github.com/offchainlabs/nitro/cmd/genericconf" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" - "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/util/headerreader" "github.com/offchainlabs/nitro/validator/server_common" @@ -26,7 +25,6 @@ import ( "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/offchainlabs/nitro/arbnode" "github.com/offchainlabs/nitro/cmd/util" deploycode "github.com/offchainlabs/nitro/deploy" ) @@ -62,7 +60,6 @@ func main() { authorizevalidators := flag.Uint64("authorizevalidators", 0, "Number of validators to preemptively authorize") txTimeout := flag.Duration("txtimeout", 10*time.Minute, "Timeout when waiting for a transaction to be included in a block") prod := flag.Bool("prod", false, "Whether to configure the rollup for production or testing") - isDelayBufferable := flag.Bool("delayBufferable", false, "Whether the sequencer-inbox delay buffer is enabled") flag.Parse() l1ChainId := new(big.Int).SetUint64(*l1ChainIdUint) maxDataSize := new(big.Int).SetUint64(*maxDataSizeUint) @@ -172,11 +169,6 @@ func main() { panic(fmt.Errorf("failed to deserialize chain config: %w", err)) } - var bufferConfig rollupgen.BufferConfig - if *isDelayBufferable { - bufferConfig = arbnode.DefaultBufferConfig() - } - arbSys, _ := precompilesgen.NewArbSys(types.ArbSysAddress, l1client) l1Reader, err := headerreader.New(ctx, l1client, func() *headerreader.Config { return &headerReaderConfig }, arbSys) if err != nil { @@ -186,14 +178,14 @@ func main() { defer l1Reader.StopAndWait() nativeToken := common.HexToAddress(*nativeTokenAddressString) - deployedAddresses, err := deploycode.DeployOnParentChain( + deployedAddresses, err := deploycode.DeployLegacyOnParentChain( ctx, l1Reader, l1TransactionOpts, batchPosters, batchPosterManagerAddress, *authorizevalidators, - arbnode.GenerateRollupConfig(*prod, moduleRoot, ownerAddress, &chainConfig, chainConfigJson, loserEscrowAddress, bufferConfig), + deploycode.GenerateLegacyRollupConfig(*prod, moduleRoot, ownerAddress, &chainConfig, chainConfigJson, loserEscrowAddress), nativeToken, maxDataSize, true, diff --git a/deploy/deploy.go b/deploy/deploy.go index 858d06db89..6a71dd9673 100644 --- a/deploy/deploy.go +++ b/deploy/deploy.go @@ -10,16 +10,89 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/offchainlabs/bold/solgen/go/bridgegen" + "github.com/offchainlabs/bold/solgen/go/challengeV2gen" + "github.com/offchainlabs/bold/solgen/go/ospgen" + "github.com/offchainlabs/bold/solgen/go/rollupgen" + "github.com/offchainlabs/bold/solgen/go/yulgen" "github.com/offchainlabs/nitro/cmd/chaininfo" - "github.com/offchainlabs/nitro/solgen/go/bridgegen" - "github.com/offchainlabs/nitro/solgen/go/challengegen" - "github.com/offchainlabs/nitro/solgen/go/ospgen" - "github.com/offchainlabs/nitro/solgen/go/rollupgen" "github.com/offchainlabs/nitro/solgen/go/upgrade_executorgen" - "github.com/offchainlabs/nitro/solgen/go/yulgen" "github.com/offchainlabs/nitro/util/headerreader" ) +// lint:require-exhaustive-initialization +type RollupConfigOpts struct { + Prod bool + WasmModuleRoot common.Hash + RollupOwner common.Address + ChainConfig *params.ChainConfig + SerializedChainConfig []byte + LoserStakeEscrow common.Address + MiniStakeValues []*big.Int + StakeToken common.Address + GenesisExecutionState rollupgen.AssertionState + GenesisInboxCount *big.Int + AnyTrustFastConfirmer common.Address + LayerZeroBlockEdgeHeight uint64 + LayerZeroBigStepEdgeHeight uint64 + LayerZeroSmallStepEdgeHeight uint64 + NumBigStepLevel uint8 + BufferConfig rollupgen.BufferConfig +} + +func DefaultBufferConfig() rollupgen.BufferConfig { + return rollupgen.BufferConfig{ + Threshold: 600, // 1 hour of blocks + Max: 14400, // 2 days of blocks + ReplenishRateInBasis: 500, // 5% + } +} + +func GenerateRollupConfig(opts *RollupConfigOpts) rollupgen.Config { + var confirmPeriod uint64 + if opts.Prod { + confirmPeriod = 45818 + } else { + confirmPeriod = 25 + } + + var gracePeriod uint64 + if opts.Prod { + gracePeriod = 14400 + } else { + gracePeriod = 3 + } + + cfg := rollupgen.Config{ + ConfirmPeriodBlocks: confirmPeriod, + StakeToken: opts.StakeToken, + BaseStake: big.NewInt(1), + WasmModuleRoot: opts.WasmModuleRoot, + Owner: opts.RollupOwner, + LoserStakeEscrow: opts.LoserStakeEscrow, + ChainId: opts.ChainConfig.ChainID, + ChainConfig: string(opts.SerializedChainConfig), + MiniStakeValues: opts.MiniStakeValues, + SequencerInboxMaxTimeVariation: rollupgen.ISequencerInboxMaxTimeVariation{ + DelayBlocks: big.NewInt(60 * 60 * 24 / 15), + FutureBlocks: big.NewInt(12), + DelaySeconds: big.NewInt(60 * 60 * 24), + FutureSeconds: big.NewInt(60 * 60), + }, + LayerZeroBlockEdgeHeight: new(big.Int).SetUint64(opts.LayerZeroBlockEdgeHeight), + LayerZeroBigStepEdgeHeight: new(big.Int).SetUint64(opts.LayerZeroBigStepEdgeHeight), + LayerZeroSmallStepEdgeHeight: new(big.Int).SetUint64(opts.LayerZeroSmallStepEdgeHeight), + GenesisAssertionState: opts.GenesisExecutionState, + GenesisInboxCount: opts.GenesisInboxCount, + AnyTrustFastConfirmer: opts.AnyTrustFastConfirmer, + NumBigStepLevel: opts.NumBigStepLevel, + ChallengeGracePeriodBlocks: gracePeriod, + BufferConfig: opts.BufferConfig, + } + return cfg +} + func andTxSucceeded(ctx context.Context, parentChainReader *headerreader.HeaderReader, tx *types.Transaction, err error) error { if err != nil { return fmt.Errorf("error submitting tx: %w", err) @@ -167,7 +240,7 @@ func deployChallengeFactory(ctx context.Context, parentChainReader *headerreader return common.Address{}, common.Address{}, fmt.Errorf("ospHostIo deploy error: %w", err) } - challengeManagerAddr, tx, _, err := challengegen.DeployChallengeManager(auth, client) + challengeManagerAddr, tx, _, err := challengeV2gen.DeployEdgeChallengeManager(auth, client) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { return common.Address{}, common.Address{}, fmt.Errorf("challenge manager deploy error: %w", err) @@ -182,57 +255,51 @@ func deployChallengeFactory(ctx context.Context, parentChainReader *headerreader return ospEntryAddr, challengeManagerAddr, nil } -func deployRollupCreator(ctx context.Context, parentChainReader *headerreader.HeaderReader, auth *bind.TransactOpts, maxDataSize *big.Int, chainSupportsBlobs bool) (*rollupgen.RollupCreator, common.Address, common.Address, common.Address, error) { +func deployRollupCreator(ctx context.Context, parentChainReader *headerreader.HeaderReader, auth *bind.TransactOpts, maxDataSize *big.Int, chainSupportsBlobs bool) (*rollupgen.RollupCreator, common.Address, common.Address, error) { bridgeCreator, err := deployBridgeCreator(ctx, parentChainReader, auth, maxDataSize, chainSupportsBlobs) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("bridge creator deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("bridge creator deploy error: %w", err) } ospEntryAddr, challengeManagerAddr, err := deployChallengeFactory(ctx, parentChainReader, auth) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, err + return nil, common.Address{}, common.Address{}, err } rollupAdminLogic, tx, _, err := rollupgen.DeployRollupAdminLogic(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup admin logic deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("rollup admin logic deploy error: %w", err) } rollupUserLogic, tx, _, err := rollupgen.DeployRollupUserLogic(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup user logic deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("rollup user logic deploy error: %w", err) } rollupCreatorAddress, tx, rollupCreator, err := rollupgen.DeployRollupCreator(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup creator deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("rollup creator deploy error: %w", err) } upgradeExecutor, tx, _, err := upgrade_executorgen.DeployUpgradeExecutor(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("upgrade executor deploy error: %w", err) - } - - validatorUtils, tx, _, err := rollupgen.DeployValidatorUtils(auth, parentChainReader.Client()) - err = andTxSucceeded(ctx, parentChainReader, tx, err) - if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("validator utils deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("upgrade executor deploy error: %w", err) } validatorWalletCreator, tx, _, err := rollupgen.DeployValidatorWalletCreator(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("validator wallet creator deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("validator wallet creator deploy error: %w", err) } l2FactoriesDeployHelper, tx, _, err := rollupgen.DeployDeployHelper(auth, parentChainReader.Client()) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("deploy helper creator deploy error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("deploy helper creator deploy error: %w", err) } tx, err = rollupCreator.SetTemplates( @@ -243,16 +310,15 @@ func deployRollupCreator(ctx context.Context, parentChainReader *headerreader.He rollupAdminLogic, rollupUserLogic, upgradeExecutor, - validatorUtils, validatorWalletCreator, l2FactoriesDeployHelper, ) err = andTxSucceeded(ctx, parentChainReader, tx, err) if err != nil { - return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup set template error: %w", err) + return nil, common.Address{}, common.Address{}, fmt.Errorf("rollup set template error: %w", err) } - return rollupCreator, rollupCreatorAddress, validatorUtils, validatorWalletCreator, nil + return rollupCreator, rollupCreatorAddress, validatorWalletCreator, nil } func DeployOnParentChain(ctx context.Context, parentChainReader *headerreader.HeaderReader, deployAuth *bind.TransactOpts, batchPosters []common.Address, batchPosterManager common.Address, authorizeValidators uint64, config rollupgen.Config, nativeToken common.Address, maxDataSize *big.Int, chainSupportsBlobs bool) (*chaininfo.RollupAddresses, error) { @@ -260,7 +326,7 @@ func DeployOnParentChain(ctx context.Context, parentChainReader *headerreader.He return nil, errors.New("no machine specified") } - rollupCreator, _, validatorUtils, validatorWalletCreator, err := deployRollupCreator(ctx, parentChainReader, deployAuth, maxDataSize, chainSupportsBlobs) + rollupCreator, _, validatorWalletCreator, err := deployRollupCreator(ctx, parentChainReader, deployAuth, maxDataSize, chainSupportsBlobs) if err != nil { return nil, fmt.Errorf("error deploying rollup creator: %w", err) } @@ -305,7 +371,6 @@ func DeployOnParentChain(ctx context.Context, parentChainReader *headerreader.He Rollup: info.RollupAddress, NativeToken: nativeToken, UpgradeExecutor: info.UpgradeExecutor, - ValidatorUtils: validatorUtils, ValidatorWalletCreator: validatorWalletCreator, }, nil } diff --git a/deploy/legacy.go b/deploy/legacy.go new file mode 100644 index 0000000000..908052ae08 --- /dev/null +++ b/deploy/legacy.go @@ -0,0 +1,321 @@ +package deploy + +import ( + "context" + "errors" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/offchainlabs/nitro/cmd/chaininfo" + "github.com/offchainlabs/nitro/solgen/go/bridgegen" + "github.com/offchainlabs/nitro/solgen/go/challengegen" + "github.com/offchainlabs/nitro/solgen/go/ospgen" + "github.com/offchainlabs/nitro/solgen/go/rollupgen" + "github.com/offchainlabs/nitro/solgen/go/upgrade_executorgen" + "github.com/offchainlabs/nitro/solgen/go/yulgen" + "github.com/offchainlabs/nitro/util/headerreader" +) + +func GenerateLegacyRollupConfig( + prod bool, + wasmModuleRoot common.Hash, + rollupOwner common.Address, + chainConfig *params.ChainConfig, + serializedChainConfig []byte, + loserStakeEscrow common.Address, +) rollupgen.Config { + var confirmPeriod uint64 + if prod { + confirmPeriod = 45818 + } else { + confirmPeriod = 20 + } + return rollupgen.Config{ + ConfirmPeriodBlocks: confirmPeriod, + ExtraChallengeTimeBlocks: 200, + StakeToken: common.Address{}, + BaseStake: big.NewInt(params.Ether), + WasmModuleRoot: wasmModuleRoot, + Owner: rollupOwner, + LoserStakeEscrow: loserStakeEscrow, + ChainId: chainConfig.ChainID, + // TODO could the ChainConfig be just []byte? + ChainConfig: string(serializedChainConfig), + SequencerInboxMaxTimeVariation: rollupgen.ISequencerInboxMaxTimeVariation{ + DelayBlocks: big.NewInt(60 * 60 * 24 / 15), + FutureBlocks: big.NewInt(12), + DelaySeconds: big.NewInt(60 * 60 * 24), + FutureSeconds: big.NewInt(60 * 60), + }, + } +} + +func deployLegacyBridgeCreator(ctx context.Context, parentChainReader *headerreader.HeaderReader, auth *bind.TransactOpts, maxDataSize *big.Int, chainSupportsBlobs bool) (common.Address, error) { + client := parentChainReader.Client() + + /// deploy eth based templates + bridgeTemplate, tx, _, err := bridgegen.DeployBridge(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("bridge deploy error: %w", err) + } + + var reader4844 common.Address + if chainSupportsBlobs { + reader4844, tx, _, err = yulgen.DeployReader4844(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("blob basefee reader deploy error: %w", err) + } + } + seqInboxTemplateEthBased, tx, _, err := bridgegen.DeploySequencerInbox(auth, client, maxDataSize, reader4844, false) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("sequencer inbox eth based deploy error: %w", err) + } + seqInboxTemplateERC20Based, tx, _, err := bridgegen.DeploySequencerInbox(auth, client, maxDataSize, reader4844, true) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("sequencer inbox erc20 based deploy error: %w", err) + } + + inboxTemplate, tx, _, err := bridgegen.DeployInbox(auth, client, maxDataSize) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("inbox deploy error: %w", err) + } + + rollupEventBridgeTemplate, tx, _, err := rollupgen.DeployRollupEventInbox(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("rollup event bridge deploy error: %w", err) + } + + outboxTemplate, tx, _, err := bridgegen.DeployOutbox(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("outbox deploy error: %w", err) + } + + ethBasedTemplates := rollupgen.BridgeCreatorBridgeContracts{ + Bridge: bridgeTemplate, + SequencerInbox: seqInboxTemplateEthBased, + Inbox: inboxTemplate, + RollupEventInbox: rollupEventBridgeTemplate, + Outbox: outboxTemplate, + } + + /// deploy ERC20 based templates + erc20BridgeTemplate, tx, _, err := bridgegen.DeployERC20Bridge(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("bridge deploy error: %w", err) + } + + erc20InboxTemplate, tx, _, err := bridgegen.DeployERC20Inbox(auth, client, maxDataSize) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("inbox deploy error: %w", err) + } + + erc20RollupEventBridgeTemplate, tx, _, err := rollupgen.DeployERC20RollupEventInbox(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("rollup event bridge deploy error: %w", err) + } + + erc20OutboxTemplate, tx, _, err := bridgegen.DeployERC20Outbox(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("outbox deploy error: %w", err) + } + + erc20BasedTemplates := rollupgen.BridgeCreatorBridgeContracts{ + Bridge: erc20BridgeTemplate, + SequencerInbox: seqInboxTemplateERC20Based, + Inbox: erc20InboxTemplate, + RollupEventInbox: erc20RollupEventBridgeTemplate, + Outbox: erc20OutboxTemplate, + } + + bridgeCreatorAddr, tx, _, err := rollupgen.DeployBridgeCreator(auth, client, ethBasedTemplates, erc20BasedTemplates) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, fmt.Errorf("bridge creator deploy error: %w", err) + } + + return bridgeCreatorAddr, nil +} + +func deployLegacyChallengeFactory(ctx context.Context, parentChainReader *headerreader.HeaderReader, auth *bind.TransactOpts) (common.Address, common.Address, error) { + client := parentChainReader.Client() + osp0, tx, _, err := ospgen.DeployOneStepProver0(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("osp0 deploy error: %w", err) + } + + ospMem, tx, _, err := ospgen.DeployOneStepProverMemory(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("ospMemory deploy error: %w", err) + } + + ospMath, tx, _, err := ospgen.DeployOneStepProverMath(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("ospMath deploy error: %w", err) + } + + ospHostIo, tx, _, err := ospgen.DeployOneStepProverHostIo(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("ospHostIo deploy error: %w", err) + } + + challengeManagerAddr, tx, _, err := challengegen.DeployChallengeManager(auth, client) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("challenge manager deploy error: %w", err) + } + + ospEntryAddr, tx, _, err := ospgen.DeployOneStepProofEntry(auth, client, osp0, ospMem, ospMath, ospHostIo) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return common.Address{}, common.Address{}, fmt.Errorf("ospEntry deploy error: %w", err) + } + + return ospEntryAddr, challengeManagerAddr, nil +} + +func deployLegacyRollupCreator(ctx context.Context, parentChainReader *headerreader.HeaderReader, auth *bind.TransactOpts, maxDataSize *big.Int, chainSupportsBlobs bool) (*rollupgen.RollupCreator, common.Address, common.Address, common.Address, error) { + bridgeCreator, err := deployLegacyBridgeCreator(ctx, parentChainReader, auth, maxDataSize, chainSupportsBlobs) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("bridge creator deploy error: %w", err) + } + + ospEntryAddr, challengeManagerAddr, err := deployLegacyChallengeFactory(ctx, parentChainReader, auth) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, err + } + + rollupAdminLogic, tx, _, err := rollupgen.DeployRollupAdminLogic(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup admin logic deploy error: %w", err) + } + + rollupUserLogic, tx, _, err := rollupgen.DeployRollupUserLogic(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup user logic deploy error: %w", err) + } + + rollupCreatorAddress, tx, rollupCreator, err := rollupgen.DeployRollupCreator(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup creator deploy error: %w", err) + } + + upgradeExecutor, tx, _, err := upgrade_executorgen.DeployUpgradeExecutor(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("upgrade executor deploy error: %w", err) + } + + validatorUtils, tx, _, err := rollupgen.DeployValidatorUtils(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("validator utils deploy error: %w", err) + } + + validatorWalletCreator, tx, _, err := rollupgen.DeployValidatorWalletCreator(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("validator wallet creator deploy error: %w", err) + } + + l2FactoriesDeployHelper, tx, _, err := rollupgen.DeployDeployHelper(auth, parentChainReader.Client()) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("deploy helper creator deploy error: %w", err) + } + + tx, err = rollupCreator.SetTemplates( + auth, + bridgeCreator, + ospEntryAddr, + challengeManagerAddr, + rollupAdminLogic, + rollupUserLogic, + upgradeExecutor, + validatorUtils, + validatorWalletCreator, + l2FactoriesDeployHelper, + ) + err = andTxSucceeded(ctx, parentChainReader, tx, err) + if err != nil { + return nil, common.Address{}, common.Address{}, common.Address{}, fmt.Errorf("rollup set template error: %w", err) + } + + return rollupCreator, rollupCreatorAddress, validatorUtils, validatorWalletCreator, nil +} + +func DeployLegacyOnParentChain(ctx context.Context, parentChainReader *headerreader.HeaderReader, deployAuth *bind.TransactOpts, batchPosters []common.Address, batchPosterManager common.Address, authorizeValidators uint64, config rollupgen.Config, nativeToken common.Address, maxDataSize *big.Int, chainSupportsBlobs bool) (*chaininfo.RollupAddresses, error) { + if config.WasmModuleRoot == (common.Hash{}) { + return nil, errors.New("no machine specified") + } + + rollupCreator, _, validatorUtils, validatorWalletCreator, err := deployLegacyRollupCreator(ctx, parentChainReader, deployAuth, maxDataSize, chainSupportsBlobs) + if err != nil { + return nil, fmt.Errorf("error deploying rollup creator: %w", err) + } + + var validatorAddrs []common.Address + for i := uint64(1); i <= authorizeValidators; i++ { + validatorAddrs = append(validatorAddrs, crypto.CreateAddress(validatorWalletCreator, i)) + } + deployParams := rollupgen.RollupCreatorRollupDeploymentParams{ + Config: config, + Validators: validatorAddrs, + MaxDataSize: maxDataSize, + NativeToken: nativeToken, + DeployFactoriesToL2: false, + MaxFeePerGasForRetryables: big.NewInt(0), // needed when utility factories are deployed + BatchPosters: batchPosters, + BatchPosterManager: batchPosterManager, + } + + tx, err := rollupCreator.CreateRollup( + deployAuth, + deployParams, + ) + + if err != nil { + return nil, fmt.Errorf("error submitting create rollup tx: %w", err) + } + receipt, err := parentChainReader.WaitForTxApproval(ctx, tx) + if err != nil { + return nil, fmt.Errorf("error executing create rollup tx: %w", err) + } + info, err := rollupCreator.ParseRollupCreated(*receipt.Logs[len(receipt.Logs)-1]) + if err != nil { + return nil, fmt.Errorf("error parsing rollup created log: %w", err) + } + + return &chaininfo.RollupAddresses{ + Bridge: info.Bridge, + Inbox: info.InboxAddress, + SequencerInbox: info.SequencerInbox, + DeployedAt: receipt.BlockNumber.Uint64(), + Rollup: info.RollupAddress, + NativeToken: nativeToken, + UpgradeExecutor: info.UpgradeExecutor, + ValidatorUtils: validatorUtils, + ValidatorWalletCreator: validatorWalletCreator, + }, nil +} diff --git a/system_tests/batch_poster_test.go b/system_tests/batch_poster_test.go index 2ba3da328e..ffcd6a02be 100644 --- a/system_tests/batch_poster_test.go +++ b/system_tests/batch_poster_test.go @@ -392,7 +392,10 @@ func testBatchPosterDelayBuffer(t *testing.T, delayBufferEnabled bool) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDelayBuffer(threshold) + builder := NewNodeBuilder(ctx). + DefaultConfig(t, true). + WithBoldContracts(). + WithDelayBufferThreshold(threshold) builder.L2Info.GenerateAccount("User2") builder.nodeConfig.BatchPoster.MaxDelay = time.Hour // set high max-delay so we can test the delay buffer cleanup := builder.Build(t) @@ -446,7 +449,10 @@ func TestBatchPosterDelayBufferDontForceNonDelayedMessages(t *testing.T) { defer cancel() const threshold = 100 - builder := NewNodeBuilder(ctx).DefaultConfig(t, true).WithDelayBuffer(threshold) + builder := NewNodeBuilder(ctx). + DefaultConfig(t, true). + WithBoldContracts(). + WithDelayBufferThreshold(threshold) builder.L2Info.GenerateAccount("User2") builder.nodeConfig.BatchPoster.MaxDelay = time.Hour // set high max-delay so we can test the delay buffer cleanup := builder.Build(t) diff --git a/system_tests/common_test.go b/system_tests/common_test.go index 4bbf7c473c..a08d60f470 100644 --- a/system_tests/common_test.go +++ b/system_tests/common_test.go @@ -71,10 +71,11 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/offchainlabs/bold/solgen/go/mocksgen" + "github.com/offchainlabs/bold/solgen/go/rollupgen" "github.com/offchainlabs/nitro/arbnode" _ "github.com/offchainlabs/nitro/execution/nodeInterface" "github.com/offchainlabs/nitro/solgen/go/bridgegen" - "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" "github.com/offchainlabs/nitro/solgen/go/upgrade_executorgen" "github.com/offchainlabs/nitro/statetransfer" @@ -252,6 +253,7 @@ type NodeBuilder struct { l3InitMessage *arbostypes.ParsedInitMessage withProdConfirmPeriodBlocks bool wasmCacheTag uint32 + deployBoldContracts bool delayBufferThreshold uint64 // Created nodes @@ -365,10 +367,15 @@ func (b *NodeBuilder) WithStylusLongTermCache(enabled bool) *NodeBuilder { return b } -// WithDelayBuffer sets the delay-buffer threshold, which is the number of blocks the batch-poster +func (b *NodeBuilder) WithBoldContracts() *NodeBuilder { + b.deployBoldContracts = true + return b +} + +// WithDelayBufferThreshold sets the delay-buffer threshold, which is the number of blocks the batch-poster // is allowed to delay a batch with a delayed message. // Setting the threshold to zero disabled the delay buffer (default behaviour). -func (b *NodeBuilder) WithDelayBuffer(threshold uint64) *NodeBuilder { +func (b *NodeBuilder) WithDelayBufferThreshold(threshold uint64) *NodeBuilder { b.delayBufferThreshold = threshold return b } @@ -422,6 +429,7 @@ func (b *NodeBuilder) BuildL1(t *testing.T) { locator.LatestWasmModuleRoot(), b.withProdConfirmPeriodBlocks, true, + b.deployBoldContracts, b.delayBufferThreshold, ) b.L1.cleanup = func() { requireClose(t, b.L1.Stack) } @@ -526,6 +534,7 @@ func (b *NodeBuilder) BuildL3OnL2(t *testing.T) func() { locator.LatestWasmModuleRoot(), b.l3Config.withProdConfirmPeriodBlocks, false, + false, 0, ) @@ -1270,6 +1279,7 @@ func deployOnParentChain( wasmModuleRoot common.Hash, prodConfirmPeriodBlocks bool, chainSupportsBlobs bool, + deployBoldContracts bool, delayBufferThreshold uint64, ) (*chaininfo.RollupAddresses, *arbostypes.ParsedInitMessage) { parentChainInfo.GenerateAccount("RollupOwner") @@ -1293,24 +1303,62 @@ func deployOnParentChain( parentChainReader.Start(ctx) defer parentChainReader.StopAndWait() - bufferConfig := arbnode.DefaultBufferConfig() - bufferConfig.Threshold = delayBufferThreshold - nativeToken := common.Address{} maxDataSize := big.NewInt(117964) - addresses, err := deploy.DeployOnParentChain( - ctx, - parentChainReader, - &parentChainTransactionOpts, - []common.Address{parentChainInfo.GetAddress("Sequencer")}, - parentChainInfo.GetAddress("RollupOwner"), - 0, - arbnode.GenerateRollupConfig(prodConfirmPeriodBlocks, wasmModuleRoot, parentChainInfo.GetAddress("RollupOwner"), chainConfig, serializedChainConfig, common.Address{}, bufferConfig), - nativeToken, - maxDataSize, - chainSupportsBlobs, - ) + var addresses *chaininfo.RollupAddresses + if deployBoldContracts { + miniStakeValues := []*big.Int{big.NewInt(5), big.NewInt(4), big.NewInt(3), big.NewInt(2), big.NewInt(1)} + opts := deploy.RollupConfigOpts{ + Prod: prodConfirmPeriodBlocks, + WasmModuleRoot: wasmModuleRoot, + RollupOwner: parentChainInfo.GetAddress("RollupOwner"), + ChainConfig: chainConfig, + SerializedChainConfig: serializedChainConfig, + LoserStakeEscrow: parentChainInfo.GetAddress("RollupOwner"), + MiniStakeValues: miniStakeValues, + StakeToken: deployStakeToken(t, ctx, parentChainInfo, parentChainClient), + GenesisExecutionState: rollupgen.AssertionState{ + GlobalState: rollupgen.GlobalState{}, + MachineStatus: 1, + EndHistoryRoot: [32]byte{}, + }, + GenesisInboxCount: big.NewInt(0), + AnyTrustFastConfirmer: common.Address{}, + LayerZeroBlockEdgeHeight: 1 << 5, + LayerZeroBigStepEdgeHeight: 1 << 10, + LayerZeroSmallStepEdgeHeight: 1 << 10, + NumBigStepLevel: 3, + BufferConfig: deploy.DefaultBufferConfig(), + } + opts.BufferConfig.Threshold = delayBufferThreshold + addresses, err = deploy.DeployOnParentChain( + ctx, + parentChainReader, + &parentChainTransactionOpts, + []common.Address{parentChainInfo.GetAddress("Sequencer")}, + parentChainInfo.GetAddress("RollupOwner"), + 0, + deploy.GenerateRollupConfig(&opts), + nativeToken, + maxDataSize, + chainSupportsBlobs, + ) + } else { + addresses, err = deploy.DeployLegacyOnParentChain( + ctx, + parentChainReader, + &parentChainTransactionOpts, + []common.Address{parentChainInfo.GetAddress("Sequencer")}, + parentChainInfo.GetAddress("RollupOwner"), + 0, + deploy.GenerateLegacyRollupConfig(prodConfirmPeriodBlocks, wasmModuleRoot, parentChainInfo.GetAddress("RollupOwner"), chainConfig, serializedChainConfig, common.Address{}), + nativeToken, + maxDataSize, + chainSupportsBlobs, + ) + } Require(t, err) + parentChainInfo.SetContract("Bridge", addresses.Bridge) parentChainInfo.SetContract("SequencerInbox", addresses.SequencerInbox) parentChainInfo.SetContract("Inbox", addresses.Inbox) @@ -1617,6 +1665,25 @@ func getDeadlineTimeout(t *testing.T, defaultTimeout time.Duration) time.Duratio return timeout } +func deployStakeToken(t *testing.T, ctx context.Context, info *BlockchainTestInfo, client *ethclient.Client) common.Address { + transactionOpts := info.GetDefaultTransactOpts("RollupOwner", ctx) + stakeToken, tx, tokenBindings, err := mocksgen.DeployTestWETH9( + &transactionOpts, + client, + "Weth", + "WETH", + ) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, client, tx) + Require(t, err) + transactionOpts.Value = big.NewInt(10000) + tx, err = tokenBindings.Deposit(&transactionOpts) + Require(t, err) + _, err = EnsureTxSucceeded(ctx, client, tx) + Require(t, err) + return stakeToken +} + func deploySimple( t *testing.T, ctx context.Context, auth bind.TransactOpts, client *ethclient.Client, ) (common.Address, *mocksgen.Simple) { diff --git a/system_tests/full_challenge_impl_test.go b/system_tests/full_challenge_impl_test.go index 30b7352892..4d902f87ba 100644 --- a/system_tests/full_challenge_impl_test.go +++ b/system_tests/full_challenge_impl_test.go @@ -215,7 +215,6 @@ func setupSequencerInboxStub(ctx context.Context, t *testing.T, l1Info *Blockcha big.NewInt(117964), reader4844, false, - false, ) Require(t, err) _, err = EnsureTxSucceeded(ctx, l1Client, tx)