From b3918e5db50952a5a32ac093edbc66304110e5dc Mon Sep 17 00:00:00 2001 From: Joshua Colvin Date: Fri, 6 Sep 2024 12:42:20 -0700 Subject: [PATCH 01/82] Add buildspec.yml Move buildspec for AWS codebuild into nitro repo --- .github/buildspec.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/buildspec.yml diff --git a/.github/buildspec.yml b/.github/buildspec.yml new file mode 100644 index 0000000000..9b6503bb5d --- /dev/null +++ b/.github/buildspec.yml @@ -0,0 +1,36 @@ +version: 0.2 + +phases: + pre_build: + commands: + - git submodule update --init + - echo Logging in to Dockerhub.... + - docker login --username $DOCKERHUB_USERNAME --password $DOCKERHUB_PASSWORD + - aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin $REPOSITORY_URI + - COMMIT_HASH=$(git rev-parse --short=7 HEAD || echo "latest") + - VERSION_TAG=$(git tag --points-at HEAD | sed '/-/!s/$/_/' | sort -rV | sed 's/_$//' | head -n 1 | grep ^ || git show -s --pretty=%D | sed 's/, /\n/g' | grep -v '^origin/' |grep -v '^grafted\|HEAD\|master\|main$' || echo "dev") + - NITRO_VERSION=${VERSION_TAG}-${COMMIT_HASH} + - IMAGE_TAG=${NITRO_VERSION} + - NITRO_DATETIME=$(git show -s --date=iso-strict --format=%cd) + - NITRO_MODIFIED="false" + - echo ${NITRO_VERSION} > ./.nitro-tag.txt + build: + commands: + - echo Build started on `date` + - echo Building the Docker image ${NITRO_VERSION}... + - DOCKER_BUILDKIT=1 docker build . -t nitro-node-slim --target nitro-node-slim --build-arg version=$NITRO_VERSION --build-arg datetime=$NITRO_DATETIME --build-arg modified=$NITRO_MODIFIED + - DOCKER_BUILDKIT=1 docker build . -t nitro-node --target nitro-node --build-arg version=$NITRO_VERSION --build-arg datetime=$NITRO_DATETIME --build-arg modified=$NITRO_MODIFIED + - DOCKER_BUILDKIT=1 docker build . -t nitro-node-dev --target nitro-node-dev --build-arg version=$NITRO_VERSION --build-arg datetime=$NITRO_DATETIME --build-arg modified=$NITRO_MODIFIED + - DOCKER_BUILDKIT=1 docker build . -t nitro-node-validator --target nitro-node-validator --build-arg version=$NITRO_VERSION --build-arg datetime=$NITRO_DATETIME --build-arg modified=$NITRO_MODIFIED + - docker tag nitro-node:latest $REPOSITORY_URI:$IMAGE_TAG-$ARCH_TAG + - docker tag nitro-node-slim:latest $REPOSITORY_URI:$IMAGE_TAG-slim-$ARCH_TAG + - docker tag nitro-node-dev:latest $REPOSITORY_URI:$IMAGE_TAG-dev-$ARCH_TAG + - docker tag nitro-node-validator:latest $REPOSITORY_URI:$IMAGE_TAG-validator-$ARCH_TAG + post_build: + commands: + - echo Build completed on `date` + - echo pushing to repo + - docker push $REPOSITORY_URI:$IMAGE_TAG-$ARCH_TAG + - docker push $REPOSITORY_URI:$IMAGE_TAG-slim-$ARCH_TAG + - docker push $REPOSITORY_URI:$IMAGE_TAG-dev-$ARCH_TAG + - docker push $REPOSITORY_URI:$IMAGE_TAG-validator-$ARCH_TAG From af974b8048399fd70b14c502df54ddc7191a81ac Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 10 Sep 2024 11:39:46 -0300 Subject: [PATCH 02/82] AllowPostingBatchWithOnlyBatchPostingReport config --- arbnode/batch_poster.go | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index 44b360e76e..b022566846 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -154,24 +154,25 @@ type BatchPosterConfig struct { // Batch post polling interval. PollInterval time.Duration `koanf:"poll-interval" reload:"hot"` // Batch posting error delay. - ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` - CompressionLevel int `koanf:"compression-level" reload:"hot"` - DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` - GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` - DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` - RedisUrl string `koanf:"redis-url"` - RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` - ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` - Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` - IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` - ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` - L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` - L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` - UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` - GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` - Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` - ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` - CheckBatchCorrectness bool `koanf:"check-batch-correctness"` + ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` + CompressionLevel int `koanf:"compression-level" reload:"hot"` + DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` + GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` + DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` + RedisUrl string `koanf:"redis-url"` + RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` + ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` + Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` + IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` + ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` + L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` + L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` + UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` + GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` + Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` + ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` + CheckBatchCorrectness bool `koanf:"check-batch-correctness"` + AllowPostingBatchWithOnlyBatchPostingReport bool `koanf:"allow-posting-batch-with-only-batch-posting-report"` gasRefunder common.Address l1BlockBound l1BlockBound @@ -225,6 +226,7 @@ func BatchPosterConfigAddOptions(prefix string, f *pflag.FlagSet) { f.Uint64(prefix+".gas-estimate-base-fee-multiple-bips", uint64(DefaultBatchPosterConfig.GasEstimateBaseFeeMultipleBips), "for gas estimation, use this multiple of the basefee (measured in basis points) as the max fee per gas") f.Duration(prefix+".reorg-resistance-margin", DefaultBatchPosterConfig.ReorgResistanceMargin, "do not post batch if its within this duration from layer 1 minimum bounds. Requires l1-block-bound option not be set to \"ignore\"") f.Bool(prefix+".check-batch-correctness", DefaultBatchPosterConfig.CheckBatchCorrectness, "setting this to true will run the batch against an inbox multiplexer and verifies that it produces the correct set of messages") + f.Bool(prefix+".allow-posting-batch-with-only-batch-posting-report", DefaultBatchPosterConfig.AllowPostingBatchWithOnlyBatchPostingReport, "setting this to true will enable batch poster to post batches that only have a batch posting report message") redislock.AddConfigOptions(prefix+".redis-lock", f) dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfig) genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultBatchPosterConfig.ParentChainWallet.Pathname) @@ -256,6 +258,7 @@ var DefaultBatchPosterConfig = BatchPosterConfig{ GasEstimateBaseFeeMultipleBips: arbmath.OneInUBips * 3 / 2, ReorgResistanceMargin: 10 * time.Minute, CheckBatchCorrectness: true, + AllowPostingBatchWithOnlyBatchPostingReport: false, } var DefaultBatchPosterL1WalletConfig = genericconf.WalletConfig{ @@ -1309,7 +1312,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error) b.building.muxBackend.delayedInbox = append(b.building.muxBackend.delayedInbox, msg) } } - if msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport { + if config.AllowPostingBatchWithOnlyBatchPostingReport || (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) { b.building.haveUsefulMessage = true } b.building.msgCount++ From 52f6a6c59ef971471c7d4f66d43f62d66d7d7207 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 10 Oct 2024 11:36:31 -0300 Subject: [PATCH 03/82] PeriodToAllowPostingBatchWithOnlyBatchPostingReport config --- arbnode/batch_poster.go | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index b022566846..63175d48ac 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -154,25 +154,25 @@ type BatchPosterConfig struct { // Batch post polling interval. PollInterval time.Duration `koanf:"poll-interval" reload:"hot"` // Batch posting error delay. - ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` - CompressionLevel int `koanf:"compression-level" reload:"hot"` - DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` - GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` - DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` - RedisUrl string `koanf:"redis-url"` - RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` - ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` - Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` - IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` - ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` - L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` - L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` - UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` - GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` - Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` - ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` - CheckBatchCorrectness bool `koanf:"check-batch-correctness"` - AllowPostingBatchWithOnlyBatchPostingReport bool `koanf:"allow-posting-batch-with-only-batch-posting-report"` + ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` + CompressionLevel int `koanf:"compression-level" reload:"hot"` + DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` + GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` + DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` + RedisUrl string `koanf:"redis-url"` + RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` + ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` + Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` + IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` + ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` + L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` + L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` + UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` + GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` + Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` + ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` + CheckBatchCorrectness bool `koanf:"check-batch-correctness"` + PeriodToAllowPostingBatchWithOnlyBatchPostingReport time.Duration `koanf:"period-to-allow-posting-batch-with-only-batch-posting-report"` gasRefunder common.Address l1BlockBound l1BlockBound @@ -226,7 +226,7 @@ func BatchPosterConfigAddOptions(prefix string, f *pflag.FlagSet) { f.Uint64(prefix+".gas-estimate-base-fee-multiple-bips", uint64(DefaultBatchPosterConfig.GasEstimateBaseFeeMultipleBips), "for gas estimation, use this multiple of the basefee (measured in basis points) as the max fee per gas") f.Duration(prefix+".reorg-resistance-margin", DefaultBatchPosterConfig.ReorgResistanceMargin, "do not post batch if its within this duration from layer 1 minimum bounds. Requires l1-block-bound option not be set to \"ignore\"") f.Bool(prefix+".check-batch-correctness", DefaultBatchPosterConfig.CheckBatchCorrectness, "setting this to true will run the batch against an inbox multiplexer and verifies that it produces the correct set of messages") - f.Bool(prefix+".allow-posting-batch-with-only-batch-posting-report", DefaultBatchPosterConfig.AllowPostingBatchWithOnlyBatchPostingReport, "setting this to true will enable batch poster to post batches that only have a batch posting report message") + f.Duration(prefix+".period-to-allow-posting-batch-with-only-batch-posting-report", DefaultBatchPosterConfig.PeriodToAllowPostingBatchWithOnlyBatchPostingReport, "batch poster will only be able to post a batch with only batch posting report messages if this time period building a batch has passed") redislock.AddConfigOptions(prefix+".redis-lock", f) dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfig) genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultBatchPosterConfig.ParentChainWallet.Pathname) @@ -258,7 +258,7 @@ var DefaultBatchPosterConfig = BatchPosterConfig{ GasEstimateBaseFeeMultipleBips: arbmath.OneInUBips * 3 / 2, ReorgResistanceMargin: 10 * time.Minute, CheckBatchCorrectness: true, - AllowPostingBatchWithOnlyBatchPostingReport: false, + PeriodToAllowPostingBatchWithOnlyBatchPostingReport: 3 * 24 * time.Hour, } var DefaultBatchPosterL1WalletConfig = genericconf.WalletConfig{ @@ -1312,7 +1312,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error) b.building.muxBackend.delayedInbox = append(b.building.muxBackend.delayedInbox, msg) } } - if config.AllowPostingBatchWithOnlyBatchPostingReport || (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) { + if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (time.Since(firstMsgTime) >= config.PeriodToAllowPostingBatchWithOnlyBatchPostingReport) { b.building.haveUsefulMessage = true } b.building.msgCount++ From c33f09fd00767143fe46f5ce57e828f917480f20 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 08:48:43 -0300 Subject: [PATCH 04/82] Rename PeriodToAllowPostingBatchWithOnlyBatchPostingReport to MaxEmptyBatchDelay --- arbnode/batch_poster.go | 44 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index 63175d48ac..6a3340d7af 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -154,25 +154,25 @@ type BatchPosterConfig struct { // Batch post polling interval. PollInterval time.Duration `koanf:"poll-interval" reload:"hot"` // Batch posting error delay. - ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` - CompressionLevel int `koanf:"compression-level" reload:"hot"` - DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` - GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` - DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` - RedisUrl string `koanf:"redis-url"` - RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` - ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` - Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` - IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` - ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` - L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` - L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` - UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` - GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` - Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` - ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` - CheckBatchCorrectness bool `koanf:"check-batch-correctness"` - PeriodToAllowPostingBatchWithOnlyBatchPostingReport time.Duration `koanf:"period-to-allow-posting-batch-with-only-batch-posting-report"` + ErrorDelay time.Duration `koanf:"error-delay" reload:"hot"` + CompressionLevel int `koanf:"compression-level" reload:"hot"` + DASRetentionPeriod time.Duration `koanf:"das-retention-period" reload:"hot"` + GasRefunderAddress string `koanf:"gas-refunder-address" reload:"hot"` + DataPoster dataposter.DataPosterConfig `koanf:"data-poster" reload:"hot"` + RedisUrl string `koanf:"redis-url"` + RedisLock redislock.SimpleCfg `koanf:"redis-lock" reload:"hot"` + ExtraBatchGas uint64 `koanf:"extra-batch-gas" reload:"hot"` + Post4844Blobs bool `koanf:"post-4844-blobs" reload:"hot"` + IgnoreBlobPrice bool `koanf:"ignore-blob-price" reload:"hot"` + ParentChainWallet genericconf.WalletConfig `koanf:"parent-chain-wallet"` + L1BlockBound string `koanf:"l1-block-bound" reload:"hot"` + L1BlockBoundBypass time.Duration `koanf:"l1-block-bound-bypass" reload:"hot"` + UseAccessLists bool `koanf:"use-access-lists" reload:"hot"` + GasEstimateBaseFeeMultipleBips arbmath.UBips `koanf:"gas-estimate-base-fee-multiple-bips"` + Dangerous BatchPosterDangerousConfig `koanf:"dangerous"` + ReorgResistanceMargin time.Duration `koanf:"reorg-resistance-margin" reload:"hot"` + CheckBatchCorrectness bool `koanf:"check-batch-correctness"` + MaxEmptyBatchDelay time.Duration `koanf:"max-empty-batch-delay"` gasRefunder common.Address l1BlockBound l1BlockBound @@ -226,7 +226,7 @@ func BatchPosterConfigAddOptions(prefix string, f *pflag.FlagSet) { f.Uint64(prefix+".gas-estimate-base-fee-multiple-bips", uint64(DefaultBatchPosterConfig.GasEstimateBaseFeeMultipleBips), "for gas estimation, use this multiple of the basefee (measured in basis points) as the max fee per gas") f.Duration(prefix+".reorg-resistance-margin", DefaultBatchPosterConfig.ReorgResistanceMargin, "do not post batch if its within this duration from layer 1 minimum bounds. Requires l1-block-bound option not be set to \"ignore\"") f.Bool(prefix+".check-batch-correctness", DefaultBatchPosterConfig.CheckBatchCorrectness, "setting this to true will run the batch against an inbox multiplexer and verifies that it produces the correct set of messages") - f.Duration(prefix+".period-to-allow-posting-batch-with-only-batch-posting-report", DefaultBatchPosterConfig.PeriodToAllowPostingBatchWithOnlyBatchPostingReport, "batch poster will only be able to post a batch with only batch posting report messages if this time period building a batch has passed") + f.Duration(prefix+".max-empty-batch-delay", DefaultBatchPosterConfig.MaxEmptyBatchDelay, "maximum empty batch posting delay, batch poster will only be able to post an empty batch if this time period building a batch has passed") redislock.AddConfigOptions(prefix+".redis-lock", f) dataposter.DataPosterConfigAddOptions(prefix+".data-poster", f, dataposter.DefaultDataPosterConfig) genericconf.WalletConfigAddOptions(prefix+".parent-chain-wallet", f, DefaultBatchPosterConfig.ParentChainWallet.Pathname) @@ -258,7 +258,7 @@ var DefaultBatchPosterConfig = BatchPosterConfig{ GasEstimateBaseFeeMultipleBips: arbmath.OneInUBips * 3 / 2, ReorgResistanceMargin: 10 * time.Minute, CheckBatchCorrectness: true, - PeriodToAllowPostingBatchWithOnlyBatchPostingReport: 3 * 24 * time.Hour, + MaxEmptyBatchDelay: 3 * 24 * time.Hour, } var DefaultBatchPosterL1WalletConfig = genericconf.WalletConfig{ @@ -1312,7 +1312,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error) b.building.muxBackend.delayedInbox = append(b.building.muxBackend.delayedInbox, msg) } } - if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (time.Since(firstMsgTime) >= config.PeriodToAllowPostingBatchWithOnlyBatchPostingReport) { + if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (time.Since(firstMsgTime) >= config.MaxEmptyBatchDelay) { b.building.haveUsefulMessage = true } b.building.msgCount++ From af4c7b53ade34583190961649d1922db8607497f Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Tue, 15 Oct 2024 11:31:33 +0530 Subject: [PATCH 05/82] Test precompile methods related to stylus --- system_tests/program_test.go | 128 +++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index 4755096b26..61a157e5f8 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -1242,6 +1242,134 @@ func testSdkStorage(t *testing.T, jit bool) { check() } +func TestStylusPrecompileMethodsSimple(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, true) + cleanup := builder.Build(t) + defer cleanup() + + arbOwner, err := pgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + arbDebug, err := pgen.NewArbDebug(types.ArbDebugAddress, builder.L2.Client) + Require(t, err) + arbWasm, err := pgen.NewArbWasm(types.ArbWasmAddress, builder.L2.Client) + Require(t, err) + + ensure := func(tx *types.Transaction, err error) *types.Receipt { + t.Helper() + Require(t, err) + receipt, err := EnsureTxSucceeded(ctx, builder.L2.Client, tx) + Require(t, err) + return receipt + } + + ownerAuth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + ensure(arbDebug.BecomeChainOwner(&ownerAuth)) + + // ArbOwner precompile methods + testConst := uint16(10) + ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(testConst))) + ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(testConst))) + ensure(arbOwner.SetWasmFreePages(&ownerAuth, testConst)) + ensure(arbOwner.SetWasmPageGas(&ownerAuth, testConst)) + ensure(arbOwner.SetWasmPageLimit(&ownerAuth, testConst)) + // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, + // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits + ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) + ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(testConst))) + expectedExpiryDays := uint16(1) + ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) + ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) + ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, testConst)) + + // ArbWasm precompile methods + wasm, _ := readWasmFile(t, rustFile("keccak")) + codehash := crypto.Keccak256Hash(wasm) + programAddress := deployContract(t, ctx, ownerAuth, builder.L2.Client, wasm) + + activateAuth := ownerAuth + activateAuth.Value = oneEth + ensure(arbWasm.ActivateProgram(&activateAuth, programAddress)) + + bcs, err := arbWasm.BlockCacheSize(nil) + Require(t, err) + if bcs != testConst { + t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, testConst) + } + ed, err := arbWasm.ExpiryDays(nil) + Require(t, err) + if ed != expectedExpiryDays { + t.Errorf("ExpiryDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ed, expectedExpiryDays) + } + fp, err := arbWasm.FreePages(nil) + Require(t, err) + if fp != testConst { + t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, testConst) + } + ics, err := arbWasm.InitCostScalar(nil) + Require(t, err) + if ics != uint64(testConst) { + t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, testConst) + } + ip, err := arbWasm.InkPrice(nil) + Require(t, err) + if ip != uint32(testConst) { + t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, testConst) + } + kad, err := arbWasm.KeepaliveDays(nil) + Require(t, err) + if kad != 0 { + t.Errorf("KeepaliveDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: 0", kad) + } + msd, err := arbWasm.MaxStackDepth(nil) + Require(t, err) + if msd != uint32(testConst) { + t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, testConst) + } + mig, err := arbWasm.MinInitGas(nil) + Require(t, err) + if mig.Gas != programs.MinInitGasUnits { + t.Errorf("MinInitGas from arbWasm precompile didnt match the Gas value set by arbowner. have: %d, want: %d", mig.Gas, programs.MinInitGasUnits) + } + if mig.Cached != programs.MinCachedGasUnits { + t.Errorf("MinInitGas from arbWasm precompile didnt match the Cached value set by arbowner. have: %d, want: %d", mig.Cached, programs.MinCachedGasUnits) + } + pg, err := arbWasm.PageGas(nil) + Require(t, err) + if pg != testConst { + t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, testConst) + } + pl, err := arbWasm.PageLimit(nil) + Require(t, err) + if pl != testConst { + t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, testConst) + } + // pageramp currently is initialPageRamp = 620674314 value in programs package + _, err = arbWasm.PageRamp(nil) + Require(t, err) + + cas, err := arbWasm.CodehashAsmSize(nil, codehash) + Require(t, err) + if cas == 0 { + t.Error("CodehashAsmSize from arbWasm precompile returned 0 value") + } + ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) + Require(t, err) + expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) + // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day + // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that + // rounds down (the current time since ArbitrumStartTime in hours)/3600 + if expectedExpirySeconds-ptl > 3600 { + t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) + } + // Since ArbOwner has set wasm KeepaliveDays to 0, it enables us to do this, though this shouldn't have any effect + codehashKeepaliveAuth := ownerAuth + codehashKeepaliveAuth.Value = oneEth + ensure(arbWasm.CodehashKeepalive(&codehashKeepaliveAuth, codehash)) +} + func TestProgramActivationLogs(t *testing.T) { t.Parallel() builder, auth, cleanup := setupProgramTest(t, true) From 654efa95629ca83a1fc7441e5f761348a1cb3140 Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Tue, 15 Oct 2024 16:19:45 -0400 Subject: [PATCH 06/82] remove docker process --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 88bbd8dabe..4c5550d199 100644 --- a/Makefile +++ b/Makefile @@ -579,9 +579,9 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w -d - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w -d - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w -d + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w @touch $@ .make/wasm-lib: $(DEP_PREDICATE) arbitrator/wasm-libraries/soft-float/SoftFloat/build/Wasm-Clang/softfloat.a $(ORDER_ONLY_PREDICATE) .make From 79af5b4b04ad8eb41bad634473770b67a2468e67 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 24 Sep 2024 09:57:30 -0300 Subject: [PATCH 07/82] Adds comments on precompile methods without tests --- precompiles/ArbAddressTable.go | 1 + precompiles/ArbAggregator.go | 2 ++ precompiles/ArbDebug.go | 5 +++++ precompiles/ArbFunctionTable.go | 4 ++++ precompiles/ArbGasInfo.go | 25 +++++++++++++++++++++++++ precompiles/ArbInfo.go | 2 ++ precompiles/ArbOwner.go | 29 +++++++++++++++++++++++++++++ precompiles/ArbOwnerPublic.go | 4 ++++ precompiles/ArbRetryableTx.go | 8 ++++++++ precompiles/ArbStatistics.go | 1 + precompiles/ArbSys.go | 13 +++++++++++++ precompiles/ArbWasm.go | 20 ++++++++++++++++++++ precompiles/ArbWasmCache.go | 5 +++++ precompiles/ArbosActs.go | 2 ++ precompiles/ArbosTest.go | 1 + precompiles/context.go | 9 +++++++++ 16 files changed, 131 insertions(+) diff --git a/precompiles/ArbAddressTable.go b/precompiles/ArbAddressTable.go index 102fd55c3b..5ded229be6 100644 --- a/precompiles/ArbAddressTable.go +++ b/precompiles/ArbAddressTable.go @@ -13,6 +13,7 @@ type ArbAddressTable struct { Address addr // 0x66 } +// TODO: add test // AddressExists checks if an address exists in the table func (con ArbAddressTable) AddressExists(c ctx, evm mech, addr addr) (bool, error) { return c.State.AddressTable().AddressExists(addr) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index b74e280fe8..438707d969 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -19,12 +19,14 @@ type ArbAggregator struct { var ErrNotOwner = errors.New("must be called by chain owner") +// TODO: add test // GetPreferredAggregator returns the preferred aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetPreferredAggregator(c ctx, evm mech, address addr) (prefAgg addr, isDefault bool, err error) { return l1pricing.BatchPosterAddress, true, err } +// TODO: add test // GetDefaultAggregator returns the default aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetDefaultAggregator(c ctx, evm mech) (addr, error) { diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index bf85d5e18f..3004e76447 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -24,6 +24,7 @@ type ArbDebug struct { UnusedError func() error } +// TODO: add test func (con ArbDebug) Events(c ctx, evm mech, paid huge, flag bool, value bytes32) (addr, huge, error) { // Emits 2 events that cover each case // Basic tests an index'd value & a normal value @@ -42,11 +43,13 @@ func (con ArbDebug) Events(c ctx, evm mech, paid huge, flag bool, value bytes32) return c.caller, paid, nil } +// TODO: add test func (con ArbDebug) EventsView(c ctx, evm mech) error { _, _, err := con.Events(c, evm, common.Big0, true, bytes32{}) return err } +// TODO: add test func (con ArbDebug) CustomRevert(c ctx, number uint64) error { return con.CustomError(number, "This spider family wards off bugs: /\\oo/\\ //\\(oo)//\\ /\\oo/\\", true) } @@ -56,11 +59,13 @@ func (con ArbDebug) BecomeChainOwner(c ctx, evm mech) error { return c.State.ChainOwners().Add(c.caller) } +// TODO: add test // Halts the chain by panicking in the STF func (con ArbDebug) Panic(c ctx, evm mech) error { panic("called ArbDebug's debug-only Panic method") } +// TODO: add test func (con ArbDebug) LegacyError(c ctx) error { return errors.New("example legacy error") } diff --git a/precompiles/ArbFunctionTable.go b/precompiles/ArbFunctionTable.go index a870995e0f..084d4d532b 100644 --- a/precompiles/ArbFunctionTable.go +++ b/precompiles/ArbFunctionTable.go @@ -8,6 +8,7 @@ import ( "math/big" ) +// TODO: add test // ArbFunctionTable precompile provided aggregator's the ability to manage function tables. // Aggregation works differently in Nitro, so these methods have been stubbed and their effects disabled. // They are kept for backwards compatibility. @@ -15,16 +16,19 @@ type ArbFunctionTable struct { Address addr // 0x68 } +// TODO: add test // Upload does nothing func (con ArbFunctionTable) Upload(c ctx, evm mech, buf []byte) error { return nil } +// TODO: add test // Size returns the empty table's size, which is 0 func (con ArbFunctionTable) Size(c ctx, evm mech, addr addr) (huge, error) { return big.NewInt(0), nil } +// TODO: add test // Get reverts since the table is empty func (con ArbFunctionTable) Get(c ctx, evm mech, addr addr, index huge) (huge, bool, huge, error) { return nil, false, nil, errors.New("table is empty") diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index b41dfda8a2..909ccb52b8 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -22,6 +22,7 @@ var storageArbGas = big.NewInt(int64(storage.StorageWriteCost)) const AssumedSimpleTxSize = 140 +// TODO: add test // GetPricesInWeiWithAggregator gets prices in wei when using the provided aggregator func (con ArbGasInfo) GetPricesInWeiWithAggregator( c ctx, @@ -65,6 +66,7 @@ func (con ArbGasInfo) GetPricesInWeiWithAggregator( return perL2Tx, weiForL1Calldata, weiForL2Storage, perArbGasBase, perArbGasCongestion, perArbGasTotal, nil } +// TODO: add test func (con ArbGasInfo) _preVersion4_GetPricesInWeiWithAggregator( c ctx, evm mech, @@ -97,11 +99,13 @@ func (con ArbGasInfo) _preVersion4_GetPricesInWeiWithAggregator( return perL2Tx, weiForL1Calldata, weiForL2Storage, perArbGasBase, perArbGasCongestion, perArbGasTotal, nil } +// TODO: add test // GetPricesInWei gets prices in wei when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInWei(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { return con.GetPricesInWeiWithAggregator(c, evm, addr{}) } +// TODO: add test // GetPricesInArbGasWithAggregator gets prices in ArbGas when using the provided aggregator func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { if c.State.ArbOSVersion() < 4 { @@ -131,6 +135,7 @@ func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregato return gasPerL2Tx, gasForL1Calldata, storageArbGas, nil } +// TODO: add test func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { l1GasPrice, err := c.State.L1PricingState().PricePerUnit() if err != nil { @@ -154,11 +159,13 @@ func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm me return perL2Tx, gasForL1Calldata, storageArbGas, nil } +// TODO: add test // GetPricesInArbGas gets prices in ArbGas when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInArbGas(c ctx, evm mech) (huge, huge, huge, error) { return con.GetPricesInArbGasWithAggregator(c, evm, addr{}) } +// TODO: add test // GetGasAccountingParams gets the rollup's speed limit, pool size, and tx gas limit func (con ArbGasInfo) GetGasAccountingParams(c ctx, evm mech) (huge, huge, huge, error) { l2pricing := c.State.L2PricingState() @@ -167,56 +174,67 @@ func (con ArbGasInfo) GetGasAccountingParams(c ctx, evm mech) (huge, huge, huge, return arbmath.UintToBig(speedLimit), arbmath.UintToBig(maxTxGasLimit), arbmath.UintToBig(maxTxGasLimit), err } +// TODO: add test // GetMinimumGasPrice gets the minimum gas price needed for a transaction to succeed func (con ArbGasInfo) GetMinimumGasPrice(c ctx, evm mech) (huge, error) { return c.State.L2PricingState().MinBaseFeeWei() } +// TODO: add test // GetL1BaseFeeEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1BaseFeeEstimate(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().PricePerUnit() } +// TODO: add test // GetL1BaseFeeEstimateInertia gets how slowly ArbOS updates its estimate of the L1 basefee func (con ArbGasInfo) GetL1BaseFeeEstimateInertia(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().Inertia() } +// TODO: add test // GetL1RewardRate gets the L1 pricer reward rate func (con ArbGasInfo) GetL1RewardRate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().PerUnitReward() } +// TODO: add test // GetL1RewardRecipient gets the L1 pricer reward recipient func (con ArbGasInfo) GetL1RewardRecipient(c ctx, evm mech) (common.Address, error) { return c.State.L1PricingState().PayRewardsTo() } +// TODO: add test // GetL1GasPriceEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1GasPriceEstimate(c ctx, evm mech) (huge, error) { return con.GetL1BaseFeeEstimate(c, evm) } +// TODO: add test // GetCurrentTxL1GasFees gets the fee paid to the aggregator for posting this tx func (con ArbGasInfo) GetCurrentTxL1GasFees(c ctx, evm mech) (huge, error) { return c.txProcessor.PosterFee, nil } +// TODO: add test // GetGasBacklog gets the backlogged amount of gas burnt in excess of the speed limit func (con ArbGasInfo) GetGasBacklog(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().GasBacklog() } +// TODO: add test // GetPricingInertia gets how slowly ArbOS updates the L2 basefee in response to backlogged gas func (con ArbGasInfo) GetPricingInertia(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().PricingInertia() } +// TODO: add test // GetGasBacklogTolerance gets the forgivable amount of backlogged gas ArbOS will ignore when raising the basefee func (con ArbGasInfo) GetGasBacklogTolerance(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().BacklogTolerance() } +// TODO: add test // GetL1PricingSurplus gets the surplus of funds for L1 batch posting payments (may be negative) func (con ArbGasInfo) GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { if c.State.ArbOSVersion() < 10 { @@ -226,6 +244,7 @@ func (con ArbGasInfo) GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return ps.GetL1PricingSurplus() } +// TODO: add test func (con ArbGasInfo) _preversion10_GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { ps := c.State.L1PricingState() fundsDueForRefunds, err := ps.BatchPosterTable().TotalFundsDue() @@ -241,6 +260,7 @@ func (con ArbGasInfo) _preversion10_GetL1PricingSurplus(c ctx, evm mech) (*big.I return arbmath.BigSub(haveFunds.ToBig(), needFunds), nil } +// TODO: add test // GetPerBatchGasCharge gets the base charge (in L1 gas) attributed to each data batch in the calldata pricer func (con ArbGasInfo) GetPerBatchGasCharge(c ctx, evm mech) (int64, error) { return c.State.L1PricingState().PerBatchGasCost() @@ -256,26 +276,31 @@ func (con ArbGasInfo) GetL1FeesAvailable(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().L1FeesAvailable() } +// TODO: add test // GetL1PricingEquilibrationUnits gets the equilibration units parameter for L1 price adjustment algorithm func (con ArbGasInfo) GetL1PricingEquilibrationUnits(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().EquilibrationUnits() } +// TODO: add test // GetLastL1PricingUpdateTime gets the last time the L1 calldata pricer was updated func (con ArbGasInfo) GetLastL1PricingUpdateTime(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().LastUpdateTime() } +// TODO: add test // GetL1PricingFundsDueForRewards gets the amount of L1 calldata payments due for rewards (per the L1 reward rate) func (con ArbGasInfo) GetL1PricingFundsDueForRewards(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().FundsDueForRewards() } +// TODO: add test // GetL1PricingUnitsSinceUpdate gets the amount of L1 calldata posted since the last update func (con ArbGasInfo) GetL1PricingUnitsSinceUpdate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().UnitsSinceUpdate() } +// TODO: add test // GetLastL1PricingSurplus gets the L1 pricing surplus as of the last update (may be negative) func (con ArbGasInfo) GetLastL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().LastSurplus() diff --git a/precompiles/ArbInfo.go b/precompiles/ArbInfo.go index 9f8cf34532..c78dd84889 100644 --- a/precompiles/ArbInfo.go +++ b/precompiles/ArbInfo.go @@ -13,6 +13,7 @@ type ArbInfo struct { Address addr // 0x65 } +// TODO: add test // GetBalance retrieves an account's balance func (con ArbInfo) GetBalance(c ctx, evm mech, account addr) (huge, error) { if err := c.Burn(params.BalanceGasEIP1884); err != nil { @@ -21,6 +22,7 @@ func (con ArbInfo) GetBalance(c ctx, evm mech, account addr) (huge, error) { return evm.StateDB.GetBalance(account).ToBig(), nil } +// TODO: add test // GetCode retrieves a contract's deployed code func (con ArbInfo) GetCode(c ctx, evm mech, account addr) ([]byte, error) { if err := c.Burn(params.ColdSloadCostEIP2929); err != nil { diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 8b87445e0e..8bb69fff0a 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -57,16 +57,19 @@ func (con ArbOwner) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) return c.State.ChainOwners().AllMembers(65536) } +// TODO: add test // SetL1BaseFeeEstimateInertia sets how slowly ArbOS updates its estimate of the L1 basefee func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } +// TODO: add test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) } +// TODO: add test // SetMinimumL2BaseFee sets the minimum base fee needed for a transaction to succeed func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error { if c.txProcessor.MsgIsNonMutating() && priceInWei.Sign() == 0 { @@ -75,26 +78,31 @@ func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error return c.State.L2PricingState().SetMinBaseFeeWei(priceInWei) } +// TODO: add test // SetSpeedLimit sets the computational speed limit for the chain func (con ArbOwner) SetSpeedLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetSpeedLimitPerSecond(limit) } +// TODO: add test // SetMaxTxGasLimit sets the maximum size a tx (and block) can be func (con ArbOwner) SetMaxTxGasLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetMaxPerBlockGasLimit(limit) } +// TODO: add test // SetL2GasPricingInertia sets the L2 gas pricing inertia func (con ArbOwner) SetL2GasPricingInertia(c ctx, evm mech, sec uint64) error { return c.State.L2PricingState().SetPricingInertia(sec) } +// TODO: add test // SetL2GasBacklogTolerance sets the L2 gas backlog tolerance func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error { return c.State.L2PricingState().SetBacklogTolerance(sec) } +// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() @@ -105,6 +113,7 @@ func (con ArbOwner) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() } +// TODO: add test // SetNetworkFeeAccount sets the network fee collector to the new network fee account func (con ArbOwner) SetNetworkFeeAccount(c ctx, evm mech, newNetworkFeeAccount addr) error { return c.State.SetNetworkFeeAccount(newNetworkFeeAccount) @@ -115,31 +124,38 @@ func (con ArbOwner) SetInfraFeeAccount(c ctx, evm mech, newNetworkFeeAccount add return c.State.SetInfraFeeAccount(newNetworkFeeAccount) } +// TODO: add test // ScheduleArbOSUpgrade to the requested version at the requested timestamp func (con ArbOwner) ScheduleArbOSUpgrade(c ctx, evm mech, newVersion uint64, timestamp uint64) error { return c.State.ScheduleArbOSUpgrade(newVersion, timestamp) } +// TODO: add test func (con ArbOwner) SetL1PricingEquilibrationUnits(c ctx, evm mech, equilibrationUnits huge) error { return c.State.L1PricingState().SetEquilibrationUnits(equilibrationUnits) } +// TODO: add test func (con ArbOwner) SetL1PricingInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } +// TODO: add test func (con ArbOwner) SetL1PricingRewardRecipient(c ctx, evm mech, recipient addr) error { return c.State.L1PricingState().SetPayRewardsTo(recipient) } +// TODO: add test func (con ArbOwner) SetL1PricingRewardRate(c ctx, evm mech, weiPerUnit uint64) error { return c.State.L1PricingState().SetPerUnitReward(weiPerUnit) } +// TODO: add test func (con ArbOwner) SetL1PricePerUnit(c ctx, evm mech, pricePerUnit *big.Int) error { return c.State.L1PricingState().SetPricePerUnit(pricePerUnit) } +// TODO: add test func (con ArbOwner) SetPerBatchGasCharge(c ctx, evm mech, cost int64) error { return c.State.L1PricingState().SetPerBatchGasCost(cost) } @@ -148,6 +164,7 @@ func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error { return c.State.L1PricingState().SetAmortizedCostCapBips(cap) } +// TODO: add test func (con ArbOwner) SetBrotliCompressionLevel(c ctx, evm mech, level uint64) error { return c.State.SetBrotliCompressionLevel(level) } @@ -172,6 +189,7 @@ func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease return weiToTransfer, nil } +// TODO: add test // Sets the amount of ink 1 gas buys func (con ArbOwner) SetInkPrice(c ctx, evm mech, inkPrice uint32) error { params, err := c.State.Programs().Params() @@ -186,6 +204,7 @@ func (con ArbOwner) SetInkPrice(c ctx, evm mech, inkPrice uint32) error { return params.Save() } +// TODO: add test // Sets the maximum depth (in wasm words) a wasm stack may grow func (con ArbOwner) SetWasmMaxStackDepth(c ctx, evm mech, depth uint32) error { params, err := c.State.Programs().Params() @@ -196,6 +215,7 @@ func (con ArbOwner) SetWasmMaxStackDepth(c ctx, evm mech, depth uint32) error { return params.Save() } +// TODO: add test // Gets the number of free wasm pages a tx gets func (con ArbOwner) SetWasmFreePages(c ctx, evm mech, pages uint16) error { params, err := c.State.Programs().Params() @@ -206,6 +226,7 @@ func (con ArbOwner) SetWasmFreePages(c ctx, evm mech, pages uint16) error { return params.Save() } +// TODO: add test // Sets the base cost of each additional wasm page func (con ArbOwner) SetWasmPageGas(c ctx, evm mech, gas uint16) error { params, err := c.State.Programs().Params() @@ -216,6 +237,7 @@ func (con ArbOwner) SetWasmPageGas(c ctx, evm mech, gas uint16) error { return params.Save() } +// TODO: add test // Sets the initial number of pages a wasm may allocate func (con ArbOwner) SetWasmPageLimit(c ctx, evm mech, limit uint16) error { params, err := c.State.Programs().Params() @@ -226,6 +248,7 @@ func (con ArbOwner) SetWasmPageLimit(c ctx, evm mech, limit uint16) error { return params.Save() } +// TODO: add test // Sets the minimum costs to invoke a program func (con ArbOwner) SetWasmMinInitGas(c ctx, _ mech, gas, cached uint64) error { params, err := c.State.Programs().Params() @@ -237,6 +260,7 @@ func (con ArbOwner) SetWasmMinInitGas(c ctx, _ mech, gas, cached uint64) error { return params.Save() } +// TODO: add test // Sets the linear adjustment made to program init costs func (con ArbOwner) SetWasmInitCostScalar(c ctx, _ mech, percent uint64) error { params, err := c.State.Programs().Params() @@ -247,6 +271,7 @@ func (con ArbOwner) SetWasmInitCostScalar(c ctx, _ mech, percent uint64) error { return params.Save() } +// TODO: add test // Sets the number of days after which programs deactivate func (con ArbOwner) SetWasmExpiryDays(c ctx, _ mech, days uint16) error { params, err := c.State.Programs().Params() @@ -257,6 +282,7 @@ func (con ArbOwner) SetWasmExpiryDays(c ctx, _ mech, days uint16) error { return params.Save() } +// TODO: add test // Sets the age a program must be to perform a keepalive func (con ArbOwner) SetWasmKeepaliveDays(c ctx, _ mech, days uint16) error { params, err := c.State.Programs().Params() @@ -267,6 +293,7 @@ func (con ArbOwner) SetWasmKeepaliveDays(c ctx, _ mech, days uint16) error { return params.Save() } +// TODO: add test // Sets the number of extra programs ArbOS caches during a given block func (con ArbOwner) SetWasmBlockCacheSize(c ctx, _ mech, count uint16) error { params, err := c.State.Programs().Params() @@ -277,11 +304,13 @@ func (con ArbOwner) SetWasmBlockCacheSize(c ctx, _ mech, count uint16) error { return params.Save() } +// TODO: add test // Adds account as a wasm cache manager func (con ArbOwner) AddWasmCacheManager(c ctx, _ mech, manager addr) error { return c.State.Programs().CacheManagers().Add(manager) } +// TODO: add test // Removes account from the list of wasm cache managers func (con ArbOwner) RemoveWasmCacheManager(c ctx, _ mech, manager addr) error { managers := c.State.Programs().CacheManagers() diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index 451e18e1cc..2356c855ee 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -21,6 +21,7 @@ func (con ArbOwnerPublic) GetAllChainOwners(c ctx, evm mech) ([]common.Address, return c.State.ChainOwners().AllMembers(65536) } +// TODO: add test // RectifyChainOwner checks if the account is a chain owner func (con ArbOwnerPublic) RectifyChainOwner(c ctx, evm mech, addr addr) error { err := c.State.ChainOwners().RectifyMapping(addr) @@ -35,6 +36,7 @@ func (con ArbOwnerPublic) IsChainOwner(c ctx, evm mech, addr addr) (bool, error) return c.State.ChainOwners().IsMember(addr) } +// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwnerPublic) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() @@ -48,11 +50,13 @@ func (con ArbOwnerPublic) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() } +// TODO: add test // GetBrotliCompressionLevel gets the current brotli compression level used for fast compression func (con ArbOwnerPublic) GetBrotliCompressionLevel(c ctx, evm mech) (uint64, error) { return c.State.BrotliCompressionLevel() } +// TODO: add test // GetScheduledUpgrade gets the next scheduled ArbOS version upgrade and its activation timestamp. // Returns (0, 0, nil) if no ArbOS upgrade is scheduled. func (con ArbOwnerPublic) GetScheduledUpgrade(c ctx, evm mech) (uint64, uint64, error) { diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index 93e8023603..abfdc94807 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -45,6 +45,7 @@ func (con ArbRetryableTx) oldNotFoundError(c ctx) error { return errors.New("ticketId not found") } +// TODO: add test // Redeem schedules an attempt to redeem the retryable, donating all of the call's gas to the redeem attempt func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, error) { if c.txProcessor.CurrentRetryable != nil && ticketId == *c.txProcessor.CurrentRetryable { @@ -130,11 +131,13 @@ func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, er return retryTxHash, c.State.L2PricingState().AddToGasPool(arbmath.SaturatingCast[int64](gasToDonate)) } +// TODO: add test // GetLifetime gets the default lifetime period a retryable has at creation func (con ArbRetryableTx) GetLifetime(c ctx, evm mech) (huge, error) { return big.NewInt(retryables.RetryableLifetimeSeconds), nil } +// TODO: add test // GetTimeout gets the timestamp for when ticket will expire func (con ArbRetryableTx) GetTimeout(c ctx, evm mech, ticketId bytes32) (huge, error) { retryableState := c.State.RetryableState() @@ -152,6 +155,7 @@ func (con ArbRetryableTx) GetTimeout(c ctx, evm mech, ticketId bytes32) (huge, e return new(big.Int).SetUint64(timeout), nil } +// TODO: add test // Keepalive adds one lifetime period to the ticket's expiry func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, error) { @@ -181,6 +185,7 @@ func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, er return bigNewTimeout, err } +// TODO: add test // GetBeneficiary gets the beneficiary of the ticket func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (addr, error) { retryableState := c.State.RetryableState() @@ -194,6 +199,7 @@ func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (add return retryable.Beneficiary() } +// TODO: add test // Cancel the ticket and refund its callvalue to its beneficiary func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { if c.txProcessor.CurrentRetryable != nil && ticketId == *c.txProcessor.CurrentRetryable { @@ -223,6 +229,7 @@ func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { return con.Canceled(c, evm, ticketId) } +// TODO: add test func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, error) { if c.txProcessor.CurrentRefundTo != nil { return *c.txProcessor.CurrentRefundTo, nil @@ -230,6 +237,7 @@ func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, e return common.Address{}, nil } +// TODO: add test func (con ArbRetryableTx) SubmitRetryable( c ctx, evm mech, requestId bytes32, l1BaseFee, deposit, callvalue, gasFeeCap huge, gasLimit uint64, maxSubmissionFee huge, diff --git a/precompiles/ArbStatistics.go b/precompiles/ArbStatistics.go index 83f867d09d..74d1c2dd15 100644 --- a/precompiles/ArbStatistics.go +++ b/precompiles/ArbStatistics.go @@ -14,6 +14,7 @@ type ArbStatistics struct { Address addr // 0x6e } +// TODO: add test // GetStats returns the current block number and some statistics about the rollup's pre-Nitro state func (con ArbStatistics) GetStats(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { blockNum := evm.Context.BlockNumber diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index d55067a09c..295085a3c5 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -28,11 +28,13 @@ type ArbSys struct { L2ToL1TransactionGasCost func(addr, addr, huge, huge, huge, huge, huge, huge, huge, []byte) (uint64, error) } +// TODO: add test // ArbBlockNumber gets the current L2 block number func (con *ArbSys) ArbBlockNumber(c ctx, evm mech) (huge, error) { return evm.Context.BlockNumber, nil } +// TODO: add test // ArbBlockHash gets the L2 block hash, if sufficiently recent func (con *ArbSys) ArbBlockHash(c ctx, evm mech, arbBlockNumber *big.Int) (bytes32, error) { if !arbBlockNumber.IsUint64() { @@ -54,32 +56,38 @@ func (con *ArbSys) ArbBlockHash(c ctx, evm mech, arbBlockNumber *big.Int) (bytes return evm.Context.GetHash(requestedBlockNum), nil } +// TODO: add test // ArbChainID gets the rollup's unique chain identifier func (con *ArbSys) ArbChainID(c ctx, evm mech) (huge, error) { return evm.ChainConfig().ChainID, nil } +// TODO: add test // ArbOSVersion gets the current ArbOS version func (con *ArbSys) ArbOSVersion(c ctx, evm mech) (huge, error) { version := new(big.Int).SetUint64(55 + c.State.ArbOSVersion()) // Nitro starts at version 56 return version, nil } +// TODO: add test // GetStorageGasAvailable returns 0 since Nitro has no concept of storage gas func (con *ArbSys) GetStorageGasAvailable(c ctx, evm mech) (huge, error) { return big.NewInt(0), nil } +// TODO: add test // IsTopLevelCall checks if the call is top-level (deprecated) func (con *ArbSys) IsTopLevelCall(c ctx, evm mech) (bool, error) { return evm.Depth() <= 2, nil } +// TODO: add test // MapL1SenderContractAddressToL2Alias gets the contract's L2 alias func (con *ArbSys) MapL1SenderContractAddressToL2Alias(c ctx, sender addr, dest addr) (addr, error) { return util.RemapL1Address(sender), nil } +// TODO: add test // WasMyCallersAddressAliased checks if the caller's caller was aliased func (con *ArbSys) WasMyCallersAddressAliased(c ctx, evm mech) (bool, error) { topLevel := con.isTopLevel(c, evm) @@ -90,6 +98,7 @@ func (con *ArbSys) WasMyCallersAddressAliased(c ctx, evm mech) (bool, error) { return aliased, nil } +// TODO: add test // MyCallersAddressWithoutAliasing gets the caller's caller without any potential aliasing func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error) { @@ -106,6 +115,7 @@ func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error return address, err } +// TODO: add test // SendTxToL1 sends a transaction to L1, adding it to the outbox func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, calldataForL1 []byte) (huge, error) { l1BlockNum, err := c.txProcessor.L1BlockNumber(vm.BlockContext{}) @@ -186,6 +196,7 @@ func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, cal return sendHash.Big(), err } +// TODO: add test // SendMerkleTreeState gets the root, size, and partials of the outbox Merkle tree state (caller must be the 0 address) func (con ArbSys) SendMerkleTreeState(c ctx, evm mech) (huge, bytes32, []bytes32, error) { if c.caller != (addr{}) { @@ -202,11 +213,13 @@ func (con ArbSys) SendMerkleTreeState(c ctx, evm mech) (huge, bytes32, []bytes32 return new(big.Int).SetUint64(size), rootHash, partials, nil } +// TODO: add test // WithdrawEth send paid eth to the destination on L1 func (con ArbSys) WithdrawEth(c ctx, evm mech, value huge, destination addr) (huge, error) { return con.SendTxToL1(c, evm, value, destination, []byte{}) } +// TODO: add test func (con ArbSys) isTopLevel(c ctx, evm mech) bool { depth := evm.Depth() return depth < 2 || evm.Origin == c.txProcessor.Contracts[depth-2].Caller() diff --git a/precompiles/ArbWasm.go b/precompiles/ArbWasm.go index bc24c8a6e8..f8ece25600 100644 --- a/precompiles/ArbWasm.go +++ b/precompiles/ArbWasm.go @@ -29,6 +29,7 @@ type ArbWasm struct { ProgramInsufficientValueError func(have, want huge) error } +// TODO: add test // Compile a wasm program with the latest instrumentation func (con ArbWasm) ActivateProgram(c ctx, evm mech, value huge, program addr) (uint16, huge, error) { debug := evm.ChainConfig().DebugMode() @@ -53,6 +54,7 @@ func (con ArbWasm) ActivateProgram(c ctx, evm mech, value huge, program addr) (u return version, dataFee, con.ProgramActivated(c, evm, codeHash, moduleHash, program, dataFee, version) } +// TODO: add test // Extends a program's expiration date (reverts if too soon) func (con ArbWasm) CodehashKeepalive(c ctx, evm mech, value huge, codehash bytes32) error { params, err := c.State.Programs().Params() @@ -89,48 +91,56 @@ func (con ArbWasm) payActivationDataFee(c ctx, evm mech, value, dataFee huge) er return util.TransferBalance(&con.Address, &c.caller, repay, evm, scenario, "reimburse") } +// TODO: add test // Gets the latest stylus version func (con ArbWasm) StylusVersion(c ctx, evm mech) (uint16, error) { params, err := c.State.Programs().Params() return params.Version, err } +// TODO: add test // Gets the amount of ink 1 gas buys func (con ArbWasm) InkPrice(c ctx, _ mech) (uint32, error) { params, err := c.State.Programs().Params() return params.InkPrice.ToUint32(), err } +// TODO: add test // Gets the wasm stack size limit func (con ArbWasm) MaxStackDepth(c ctx, _ mech) (uint32, error) { params, err := c.State.Programs().Params() return params.MaxStackDepth, err } +// TODO: add test // Gets the number of free wasm pages a tx gets func (con ArbWasm) FreePages(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.FreePages, err } +// TODO: add test // Gets the base cost of each additional wasm page func (con ArbWasm) PageGas(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.PageGas, err } +// TODO: add test // Gets the ramp that drives exponential memory costs func (con ArbWasm) PageRamp(c ctx, _ mech) (uint64, error) { params, err := c.State.Programs().Params() return params.PageRamp, err } +// TODO: add test // Gets the maximum initial number of pages a wasm may allocate func (con ArbWasm) PageLimit(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.PageLimit, err } +// TODO: add test // Gets the minimum costs to invoke a program func (con ArbWasm) MinInitGas(c ctx, _ mech) (uint64, uint64, error) { params, err := c.State.Programs().Params() @@ -142,30 +152,35 @@ func (con ArbWasm) MinInitGas(c ctx, _ mech) (uint64, uint64, error) { return init, cached, err } +// TODO: add test // Gets the linear adjustment made to program init costs func (con ArbWasm) InitCostScalar(c ctx, _ mech) (uint64, error) { params, err := c.State.Programs().Params() return uint64(params.InitCostScalar) * programs.CostScalarPercent, err } +// TODO: add test // Gets the number of days after which programs deactivate func (con ArbWasm) ExpiryDays(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.ExpiryDays, err } +// TODO: add test // Gets the age a program must be to perform a keepalive func (con ArbWasm) KeepaliveDays(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.KeepaliveDays, err } +// TODO: add test // Gets the number of extra programs ArbOS caches during a given block. func (con ArbWasm) BlockCacheSize(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.BlockCacheSize, err } +// TODO: add test // Gets the stylus version that program with codehash was most recently compiled with func (con ArbWasm) CodehashVersion(c ctx, evm mech, codehash bytes32) (uint16, error) { params, err := c.State.Programs().Params() @@ -175,6 +190,7 @@ func (con ArbWasm) CodehashVersion(c ctx, evm mech, codehash bytes32) (uint16, e return c.State.Programs().CodehashVersion(codehash, evm.Context.Time, params) } +// TODO: add test // Gets a program's asm size in bytes func (con ArbWasm) CodehashAsmSize(c ctx, evm mech, codehash bytes32) (uint32, error) { params, err := c.State.Programs().Params() @@ -184,6 +200,7 @@ func (con ArbWasm) CodehashAsmSize(c ctx, evm mech, codehash bytes32) (uint32, e return c.State.Programs().ProgramAsmSize(codehash, evm.Context.Time, params) } +// TODO: add test // Gets the stylus version that program at addr was most recently compiled with func (con ArbWasm) ProgramVersion(c ctx, evm mech, program addr) (uint16, error) { codehash, err := c.GetCodeHash(program) @@ -193,6 +210,7 @@ func (con ArbWasm) ProgramVersion(c ctx, evm mech, program addr) (uint16, error) return con.CodehashVersion(c, evm, codehash) } +// TODO: add test // Gets the cost to invoke the program func (con ArbWasm) ProgramInitGas(c ctx, evm mech, program addr) (uint64, uint64, error) { codehash, params, err := con.getCodeHash(c, program) @@ -202,6 +220,7 @@ func (con ArbWasm) ProgramInitGas(c ctx, evm mech, program addr) (uint64, uint64 return c.State.Programs().ProgramInitGas(codehash, evm.Context.Time, params) } +// TODO: add test // Gets the footprint of program at addr func (con ArbWasm) ProgramMemoryFootprint(c ctx, evm mech, program addr) (uint16, error) { codehash, params, err := con.getCodeHash(c, program) @@ -211,6 +230,7 @@ func (con ArbWasm) ProgramMemoryFootprint(c ctx, evm mech, program addr) (uint16 return c.State.Programs().ProgramMemoryFootprint(codehash, evm.Context.Time, params) } +// TODO: add test // Gets returns the amount of time remaining until the program expires func (con ArbWasm) ProgramTimeLeft(c ctx, evm mech, program addr) (uint64, error) { codehash, params, err := con.getCodeHash(c, program) diff --git a/precompiles/ArbWasmCache.go b/precompiles/ArbWasmCache.go index 3cada9dd70..053cfb3792 100644 --- a/precompiles/ArbWasmCache.go +++ b/precompiles/ArbWasmCache.go @@ -12,21 +12,25 @@ type ArbWasmCache struct { UpdateProgramCacheGasCost func(addr, bytes32, bool) (uint64, error) } +// TODO: add test // See if the user is a cache manager owner. func (con ArbWasmCache) IsCacheManager(c ctx, _ mech, addr addr) (bool, error) { return c.State.Programs().CacheManagers().IsMember(addr) } +// TODO: add test // Retrieve all authorized address managers. func (con ArbWasmCache) AllCacheManagers(c ctx, _ mech) ([]addr, error) { return c.State.Programs().CacheManagers().AllMembers(65536) } +// TODO: add test // Deprecated: replaced with CacheProgram. func (con ArbWasmCache) CacheCodehash(c ctx, evm mech, codehash hash) error { return con.setProgramCached(c, evm, common.Address{}, codehash, true) } +// TODO: add test // Caches all programs with a codehash equal to the given address. Caller must be a cache manager or chain owner. func (con ArbWasmCache) CacheProgram(c ctx, evm mech, address addr) error { codehash, err := c.GetCodeHash(address) @@ -36,6 +40,7 @@ func (con ArbWasmCache) CacheProgram(c ctx, evm mech, address addr) error { return con.setProgramCached(c, evm, address, codehash, true) } +// TODO: add test // Evicts all programs with the given codehash. Caller must be a cache manager or chain owner. func (con ArbWasmCache) EvictCodehash(c ctx, evm mech, codehash hash) error { return con.setProgramCached(c, evm, common.Address{}, codehash, false) diff --git a/precompiles/ArbosActs.go b/precompiles/ArbosActs.go index e18aa43efb..475faf0e85 100644 --- a/precompiles/ArbosActs.go +++ b/precompiles/ArbosActs.go @@ -11,10 +11,12 @@ type ArbosActs struct { CallerNotArbOSError func() error } +// TODO: add test func (con ArbosActs) StartBlock(c ctx, evm mech, l1BaseFee huge, l1BlockNumber, l2BlockNumber, timeLastBlock uint64) error { return con.CallerNotArbOSError() } +// TODO: add test func (con ArbosActs) BatchPostingReport(c ctx, evm mech, batchTimestamp huge, batchPosterAddress addr, batchNumber uint64, batchDataGas uint64, l1BaseFeeWei huge) error { return con.CallerNotArbOSError() } diff --git a/precompiles/ArbosTest.go b/precompiles/ArbosTest.go index 6e988f533a..d34bc740c7 100644 --- a/precompiles/ArbosTest.go +++ b/precompiles/ArbosTest.go @@ -12,6 +12,7 @@ type ArbosTest struct { Address addr // 0x69 } +// TODO: add test // BurnArbGas unproductively burns the amount of L2 ArbGas func (con ArbosTest) BurnArbGas(c ctx, gasAmount huge) error { if !gasAmount.IsUint64() { diff --git a/precompiles/context.go b/precompiles/context.go index 670ffa7443..25aceba8ec 100644 --- a/precompiles/context.go +++ b/precompiles/context.go @@ -35,6 +35,7 @@ type Context struct { readOnly bool } +// TODO: add test func (c *Context) Burn(amount uint64) error { if c.gasLeft < amount { return c.BurnOut() @@ -43,36 +44,44 @@ func (c *Context) Burn(amount uint64) error { return nil } +// TODO: add test //nolint:unused func (c *Context) Burned() uint64 { return c.gasSupplied - c.gasLeft } +// TODO: add test func (c *Context) BurnOut() error { c.gasLeft = 0 return vm.ErrOutOfGas } +// TODO: add test func (c *Context) GasLeft() *uint64 { return &c.gasLeft } +// TODO: add test func (c *Context) Restrict(err error) { log.Crit("A metered burner was used for access-controlled work", "error", err) } +// TODO: add test func (c *Context) HandleError(err error) error { return err } +// TODO: add test func (c *Context) ReadOnly() bool { return c.readOnly } +// TODO: add test func (c *Context) TracingInfo() *util.TracingInfo { return c.tracingInfo } +// TODO: add test func (c *Context) GetCodeHash(address common.Address) (common.Hash, error) { return c.State.BackingStorage().GetCodeHash(address) } From bcb464d77e1d280be5fa0c8c9a7e7ebe55214c23 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 24 Sep 2024 15:19:08 -0300 Subject: [PATCH 08/82] Updates comments on precompile methods without tests --- precompiles/ArbDebug.go | 3 --- precompiles/ArbFunctionTable.go | 1 - precompiles/ArbGasInfo.go | 4 ---- precompiles/ArbOwner.go | 29 ----------------------------- precompiles/ArbOwnerPublic.go | 2 -- precompiles/ArbSys.go | 9 --------- precompiles/ArbosTest.go | 1 - precompiles/context.go | 9 --------- 8 files changed, 58 deletions(-) diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index 3004e76447..f20532f6e6 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -24,7 +24,6 @@ type ArbDebug struct { UnusedError func() error } -// TODO: add test func (con ArbDebug) Events(c ctx, evm mech, paid huge, flag bool, value bytes32) (addr, huge, error) { // Emits 2 events that cover each case // Basic tests an index'd value & a normal value @@ -43,13 +42,11 @@ func (con ArbDebug) Events(c ctx, evm mech, paid huge, flag bool, value bytes32) return c.caller, paid, nil } -// TODO: add test func (con ArbDebug) EventsView(c ctx, evm mech) error { _, _, err := con.Events(c, evm, common.Big0, true, bytes32{}) return err } -// TODO: add test func (con ArbDebug) CustomRevert(c ctx, number uint64) error { return con.CustomError(number, "This spider family wards off bugs: /\\oo/\\ //\\(oo)//\\ /\\oo/\\", true) } diff --git a/precompiles/ArbFunctionTable.go b/precompiles/ArbFunctionTable.go index 084d4d532b..c3a545136a 100644 --- a/precompiles/ArbFunctionTable.go +++ b/precompiles/ArbFunctionTable.go @@ -8,7 +8,6 @@ import ( "math/big" ) -// TODO: add test // ArbFunctionTable precompile provided aggregator's the ability to manage function tables. // Aggregation works differently in Nitro, so these methods have been stubbed and their effects disabled. // They are kept for backwards compatibility. diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index 909ccb52b8..e3e0029d9e 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -99,7 +99,6 @@ func (con ArbGasInfo) _preVersion4_GetPricesInWeiWithAggregator( return perL2Tx, weiForL1Calldata, weiForL2Storage, perArbGasBase, perArbGasCongestion, perArbGasTotal, nil } -// TODO: add test // GetPricesInWei gets prices in wei when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInWei(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { return con.GetPricesInWeiWithAggregator(c, evm, addr{}) @@ -174,13 +173,11 @@ func (con ArbGasInfo) GetGasAccountingParams(c ctx, evm mech) (huge, huge, huge, return arbmath.UintToBig(speedLimit), arbmath.UintToBig(maxTxGasLimit), arbmath.UintToBig(maxTxGasLimit), err } -// TODO: add test // GetMinimumGasPrice gets the minimum gas price needed for a transaction to succeed func (con ArbGasInfo) GetMinimumGasPrice(c ctx, evm mech) (huge, error) { return c.State.L2PricingState().MinBaseFeeWei() } -// TODO: add test // GetL1BaseFeeEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1BaseFeeEstimate(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().PricePerUnit() @@ -234,7 +231,6 @@ func (con ArbGasInfo) GetGasBacklogTolerance(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().BacklogTolerance() } -// TODO: add test // GetL1PricingSurplus gets the surplus of funds for L1 batch posting payments (may be negative) func (con ArbGasInfo) GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { if c.State.ArbOSVersion() < 10 { diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 8bb69fff0a..8b87445e0e 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -57,19 +57,16 @@ func (con ArbOwner) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) return c.State.ChainOwners().AllMembers(65536) } -// TODO: add test // SetL1BaseFeeEstimateInertia sets how slowly ArbOS updates its estimate of the L1 basefee func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } -// TODO: add test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) } -// TODO: add test // SetMinimumL2BaseFee sets the minimum base fee needed for a transaction to succeed func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error { if c.txProcessor.MsgIsNonMutating() && priceInWei.Sign() == 0 { @@ -78,31 +75,26 @@ func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error return c.State.L2PricingState().SetMinBaseFeeWei(priceInWei) } -// TODO: add test // SetSpeedLimit sets the computational speed limit for the chain func (con ArbOwner) SetSpeedLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetSpeedLimitPerSecond(limit) } -// TODO: add test // SetMaxTxGasLimit sets the maximum size a tx (and block) can be func (con ArbOwner) SetMaxTxGasLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetMaxPerBlockGasLimit(limit) } -// TODO: add test // SetL2GasPricingInertia sets the L2 gas pricing inertia func (con ArbOwner) SetL2GasPricingInertia(c ctx, evm mech, sec uint64) error { return c.State.L2PricingState().SetPricingInertia(sec) } -// TODO: add test // SetL2GasBacklogTolerance sets the L2 gas backlog tolerance func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error { return c.State.L2PricingState().SetBacklogTolerance(sec) } -// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() @@ -113,7 +105,6 @@ func (con ArbOwner) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() } -// TODO: add test // SetNetworkFeeAccount sets the network fee collector to the new network fee account func (con ArbOwner) SetNetworkFeeAccount(c ctx, evm mech, newNetworkFeeAccount addr) error { return c.State.SetNetworkFeeAccount(newNetworkFeeAccount) @@ -124,38 +115,31 @@ func (con ArbOwner) SetInfraFeeAccount(c ctx, evm mech, newNetworkFeeAccount add return c.State.SetInfraFeeAccount(newNetworkFeeAccount) } -// TODO: add test // ScheduleArbOSUpgrade to the requested version at the requested timestamp func (con ArbOwner) ScheduleArbOSUpgrade(c ctx, evm mech, newVersion uint64, timestamp uint64) error { return c.State.ScheduleArbOSUpgrade(newVersion, timestamp) } -// TODO: add test func (con ArbOwner) SetL1PricingEquilibrationUnits(c ctx, evm mech, equilibrationUnits huge) error { return c.State.L1PricingState().SetEquilibrationUnits(equilibrationUnits) } -// TODO: add test func (con ArbOwner) SetL1PricingInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } -// TODO: add test func (con ArbOwner) SetL1PricingRewardRecipient(c ctx, evm mech, recipient addr) error { return c.State.L1PricingState().SetPayRewardsTo(recipient) } -// TODO: add test func (con ArbOwner) SetL1PricingRewardRate(c ctx, evm mech, weiPerUnit uint64) error { return c.State.L1PricingState().SetPerUnitReward(weiPerUnit) } -// TODO: add test func (con ArbOwner) SetL1PricePerUnit(c ctx, evm mech, pricePerUnit *big.Int) error { return c.State.L1PricingState().SetPricePerUnit(pricePerUnit) } -// TODO: add test func (con ArbOwner) SetPerBatchGasCharge(c ctx, evm mech, cost int64) error { return c.State.L1PricingState().SetPerBatchGasCost(cost) } @@ -164,7 +148,6 @@ func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error { return c.State.L1PricingState().SetAmortizedCostCapBips(cap) } -// TODO: add test func (con ArbOwner) SetBrotliCompressionLevel(c ctx, evm mech, level uint64) error { return c.State.SetBrotliCompressionLevel(level) } @@ -189,7 +172,6 @@ func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease return weiToTransfer, nil } -// TODO: add test // Sets the amount of ink 1 gas buys func (con ArbOwner) SetInkPrice(c ctx, evm mech, inkPrice uint32) error { params, err := c.State.Programs().Params() @@ -204,7 +186,6 @@ func (con ArbOwner) SetInkPrice(c ctx, evm mech, inkPrice uint32) error { return params.Save() } -// TODO: add test // Sets the maximum depth (in wasm words) a wasm stack may grow func (con ArbOwner) SetWasmMaxStackDepth(c ctx, evm mech, depth uint32) error { params, err := c.State.Programs().Params() @@ -215,7 +196,6 @@ func (con ArbOwner) SetWasmMaxStackDepth(c ctx, evm mech, depth uint32) error { return params.Save() } -// TODO: add test // Gets the number of free wasm pages a tx gets func (con ArbOwner) SetWasmFreePages(c ctx, evm mech, pages uint16) error { params, err := c.State.Programs().Params() @@ -226,7 +206,6 @@ func (con ArbOwner) SetWasmFreePages(c ctx, evm mech, pages uint16) error { return params.Save() } -// TODO: add test // Sets the base cost of each additional wasm page func (con ArbOwner) SetWasmPageGas(c ctx, evm mech, gas uint16) error { params, err := c.State.Programs().Params() @@ -237,7 +216,6 @@ func (con ArbOwner) SetWasmPageGas(c ctx, evm mech, gas uint16) error { return params.Save() } -// TODO: add test // Sets the initial number of pages a wasm may allocate func (con ArbOwner) SetWasmPageLimit(c ctx, evm mech, limit uint16) error { params, err := c.State.Programs().Params() @@ -248,7 +226,6 @@ func (con ArbOwner) SetWasmPageLimit(c ctx, evm mech, limit uint16) error { return params.Save() } -// TODO: add test // Sets the minimum costs to invoke a program func (con ArbOwner) SetWasmMinInitGas(c ctx, _ mech, gas, cached uint64) error { params, err := c.State.Programs().Params() @@ -260,7 +237,6 @@ func (con ArbOwner) SetWasmMinInitGas(c ctx, _ mech, gas, cached uint64) error { return params.Save() } -// TODO: add test // Sets the linear adjustment made to program init costs func (con ArbOwner) SetWasmInitCostScalar(c ctx, _ mech, percent uint64) error { params, err := c.State.Programs().Params() @@ -271,7 +247,6 @@ func (con ArbOwner) SetWasmInitCostScalar(c ctx, _ mech, percent uint64) error { return params.Save() } -// TODO: add test // Sets the number of days after which programs deactivate func (con ArbOwner) SetWasmExpiryDays(c ctx, _ mech, days uint16) error { params, err := c.State.Programs().Params() @@ -282,7 +257,6 @@ func (con ArbOwner) SetWasmExpiryDays(c ctx, _ mech, days uint16) error { return params.Save() } -// TODO: add test // Sets the age a program must be to perform a keepalive func (con ArbOwner) SetWasmKeepaliveDays(c ctx, _ mech, days uint16) error { params, err := c.State.Programs().Params() @@ -293,7 +267,6 @@ func (con ArbOwner) SetWasmKeepaliveDays(c ctx, _ mech, days uint16) error { return params.Save() } -// TODO: add test // Sets the number of extra programs ArbOS caches during a given block func (con ArbOwner) SetWasmBlockCacheSize(c ctx, _ mech, count uint16) error { params, err := c.State.Programs().Params() @@ -304,13 +277,11 @@ func (con ArbOwner) SetWasmBlockCacheSize(c ctx, _ mech, count uint16) error { return params.Save() } -// TODO: add test // Adds account as a wasm cache manager func (con ArbOwner) AddWasmCacheManager(c ctx, _ mech, manager addr) error { return c.State.Programs().CacheManagers().Add(manager) } -// TODO: add test // Removes account from the list of wasm cache managers func (con ArbOwner) RemoveWasmCacheManager(c ctx, _ mech, manager addr) error { managers := c.State.Programs().CacheManagers() diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index 2356c855ee..4c83646aa9 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -36,7 +36,6 @@ func (con ArbOwnerPublic) IsChainOwner(c ctx, evm mech, addr addr) (bool, error) return c.State.ChainOwners().IsMember(addr) } -// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwnerPublic) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() @@ -56,7 +55,6 @@ func (con ArbOwnerPublic) GetBrotliCompressionLevel(c ctx, evm mech) (uint64, er return c.State.BrotliCompressionLevel() } -// TODO: add test // GetScheduledUpgrade gets the next scheduled ArbOS version upgrade and its activation timestamp. // Returns (0, 0, nil) if no ArbOS upgrade is scheduled. func (con ArbOwnerPublic) GetScheduledUpgrade(c ctx, evm mech) (uint64, uint64, error) { diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index 295085a3c5..a609f55dcd 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -28,13 +28,11 @@ type ArbSys struct { L2ToL1TransactionGasCost func(addr, addr, huge, huge, huge, huge, huge, huge, huge, []byte) (uint64, error) } -// TODO: add test // ArbBlockNumber gets the current L2 block number func (con *ArbSys) ArbBlockNumber(c ctx, evm mech) (huge, error) { return evm.Context.BlockNumber, nil } -// TODO: add test // ArbBlockHash gets the L2 block hash, if sufficiently recent func (con *ArbSys) ArbBlockHash(c ctx, evm mech, arbBlockNumber *big.Int) (bytes32, error) { if !arbBlockNumber.IsUint64() { @@ -56,7 +54,6 @@ func (con *ArbSys) ArbBlockHash(c ctx, evm mech, arbBlockNumber *big.Int) (bytes return evm.Context.GetHash(requestedBlockNum), nil } -// TODO: add test // ArbChainID gets the rollup's unique chain identifier func (con *ArbSys) ArbChainID(c ctx, evm mech) (huge, error) { return evm.ChainConfig().ChainID, nil @@ -75,7 +72,6 @@ func (con *ArbSys) GetStorageGasAvailable(c ctx, evm mech) (huge, error) { return big.NewInt(0), nil } -// TODO: add test // IsTopLevelCall checks if the call is top-level (deprecated) func (con *ArbSys) IsTopLevelCall(c ctx, evm mech) (bool, error) { return evm.Depth() <= 2, nil @@ -87,7 +83,6 @@ func (con *ArbSys) MapL1SenderContractAddressToL2Alias(c ctx, sender addr, dest return util.RemapL1Address(sender), nil } -// TODO: add test // WasMyCallersAddressAliased checks if the caller's caller was aliased func (con *ArbSys) WasMyCallersAddressAliased(c ctx, evm mech) (bool, error) { topLevel := con.isTopLevel(c, evm) @@ -98,7 +93,6 @@ func (con *ArbSys) WasMyCallersAddressAliased(c ctx, evm mech) (bool, error) { return aliased, nil } -// TODO: add test // MyCallersAddressWithoutAliasing gets the caller's caller without any potential aliasing func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error) { @@ -196,7 +190,6 @@ func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, cal return sendHash.Big(), err } -// TODO: add test // SendMerkleTreeState gets the root, size, and partials of the outbox Merkle tree state (caller must be the 0 address) func (con ArbSys) SendMerkleTreeState(c ctx, evm mech) (huge, bytes32, []bytes32, error) { if c.caller != (addr{}) { @@ -213,13 +206,11 @@ func (con ArbSys) SendMerkleTreeState(c ctx, evm mech) (huge, bytes32, []bytes32 return new(big.Int).SetUint64(size), rootHash, partials, nil } -// TODO: add test // WithdrawEth send paid eth to the destination on L1 func (con ArbSys) WithdrawEth(c ctx, evm mech, value huge, destination addr) (huge, error) { return con.SendTxToL1(c, evm, value, destination, []byte{}) } -// TODO: add test func (con ArbSys) isTopLevel(c ctx, evm mech) bool { depth := evm.Depth() return depth < 2 || evm.Origin == c.txProcessor.Contracts[depth-2].Caller() diff --git a/precompiles/ArbosTest.go b/precompiles/ArbosTest.go index d34bc740c7..6e988f533a 100644 --- a/precompiles/ArbosTest.go +++ b/precompiles/ArbosTest.go @@ -12,7 +12,6 @@ type ArbosTest struct { Address addr // 0x69 } -// TODO: add test // BurnArbGas unproductively burns the amount of L2 ArbGas func (con ArbosTest) BurnArbGas(c ctx, gasAmount huge) error { if !gasAmount.IsUint64() { diff --git a/precompiles/context.go b/precompiles/context.go index 25aceba8ec..670ffa7443 100644 --- a/precompiles/context.go +++ b/precompiles/context.go @@ -35,7 +35,6 @@ type Context struct { readOnly bool } -// TODO: add test func (c *Context) Burn(amount uint64) error { if c.gasLeft < amount { return c.BurnOut() @@ -44,44 +43,36 @@ func (c *Context) Burn(amount uint64) error { return nil } -// TODO: add test //nolint:unused func (c *Context) Burned() uint64 { return c.gasSupplied - c.gasLeft } -// TODO: add test func (c *Context) BurnOut() error { c.gasLeft = 0 return vm.ErrOutOfGas } -// TODO: add test func (c *Context) GasLeft() *uint64 { return &c.gasLeft } -// TODO: add test func (c *Context) Restrict(err error) { log.Crit("A metered burner was used for access-controlled work", "error", err) } -// TODO: add test func (c *Context) HandleError(err error) error { return err } -// TODO: add test func (c *Context) ReadOnly() bool { return c.readOnly } -// TODO: add test func (c *Context) TracingInfo() *util.TracingInfo { return c.tracingInfo } -// TODO: add test func (c *Context) GetCodeHash(address common.Address) (common.Hash, error) { return c.State.BackingStorage().GetCodeHash(address) } From c3b011ea25c94412eaf6ec1d326739323c5eee26 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 24 Sep 2024 16:08:45 -0300 Subject: [PATCH 09/82] Test for ArbAddressTable.AddressExists --- precompiles/ArbAddressTable.go | 1 - precompiles/ArbAddressTable_test.go | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbAddressTable.go b/precompiles/ArbAddressTable.go index 5ded229be6..102fd55c3b 100644 --- a/precompiles/ArbAddressTable.go +++ b/precompiles/ArbAddressTable.go @@ -13,7 +13,6 @@ type ArbAddressTable struct { Address addr // 0x66 } -// TODO: add test // AddressExists checks if an address exists in the table func (con ArbAddressTable) AddressExists(c ctx, evm mech, addr addr) (bool, error) { return c.State.AddressTable().AddressExists(addr) diff --git a/precompiles/ArbAddressTable_test.go b/precompiles/ArbAddressTable_test.go index b01a460636..62ce177480 100644 --- a/precompiles/ArbAddressTable_test.go +++ b/precompiles/ArbAddressTable_test.go @@ -47,6 +47,12 @@ func TestAddressTable1(t *testing.T) { addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + exists, err := atab.AddressExists(context, evm, addr) + Require(t, err) + if exists { + t.Fatal("Address shouldn't exist") + } + // register addr slot, err := atab.Register(context, evm, addr) Require(t, err) @@ -61,6 +67,12 @@ func TestAddressTable1(t *testing.T) { t.Fatal() } + exists, err = atab.AddressExists(context, evm, addr) + Require(t, err) + if !exists { + t.Fatal("Address should exist") + } + // verify Lookup of addr returns 0 index, err := atab.Lookup(context, evm, addr) Require(t, err) From 32975b921ecf3faa3f1fc7f01e9598926ae95f92 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 07:16:28 -0300 Subject: [PATCH 10/82] Do not test deprecated methods in ArbAggregator --- precompiles/ArbAggregator.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index 438707d969..b74e280fe8 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -19,14 +19,12 @@ type ArbAggregator struct { var ErrNotOwner = errors.New("must be called by chain owner") -// TODO: add test // GetPreferredAggregator returns the preferred aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetPreferredAggregator(c ctx, evm mech, address addr) (prefAgg addr, isDefault bool, err error) { return l1pricing.BatchPosterAddress, true, err } -// TODO: add test // GetDefaultAggregator returns the default aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetDefaultAggregator(c ctx, evm mech) (addr, error) { From 6615fac1110de6739cea1c220f8f77fbb0636579 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 08:18:56 -0300 Subject: [PATCH 11/82] Do not test simple ArbDebug methods --- precompiles/ArbDebug.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index f20532f6e6..bf85d5e18f 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -56,13 +56,11 @@ func (con ArbDebug) BecomeChainOwner(c ctx, evm mech) error { return c.State.ChainOwners().Add(c.caller) } -// TODO: add test // Halts the chain by panicking in the STF func (con ArbDebug) Panic(c ctx, evm mech) error { panic("called ArbDebug's debug-only Panic method") } -// TODO: add test func (con ArbDebug) LegacyError(c ctx) error { return errors.New("example legacy error") } From 94243c8b71553a12c45d300bfdfc33e2ab7bbeba Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 08:41:50 -0300 Subject: [PATCH 12/82] Tests for ArbFunctionTable --- precompiles/ArbFunctionTable.go | 3 --- precompiles/ArbFunctionTable_test.go | 35 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 precompiles/ArbFunctionTable_test.go diff --git a/precompiles/ArbFunctionTable.go b/precompiles/ArbFunctionTable.go index c3a545136a..a870995e0f 100644 --- a/precompiles/ArbFunctionTable.go +++ b/precompiles/ArbFunctionTable.go @@ -15,19 +15,16 @@ type ArbFunctionTable struct { Address addr // 0x68 } -// TODO: add test // Upload does nothing func (con ArbFunctionTable) Upload(c ctx, evm mech, buf []byte) error { return nil } -// TODO: add test // Size returns the empty table's size, which is 0 func (con ArbFunctionTable) Size(c ctx, evm mech, addr addr) (huge, error) { return big.NewInt(0), nil } -// TODO: add test // Get reverts since the table is empty func (con ArbFunctionTable) Get(c ctx, evm mech, addr addr, index huge) (huge, bool, huge, error) { return nil, false, nil, errors.New("table is empty") diff --git a/precompiles/ArbFunctionTable_test.go b/precompiles/ArbFunctionTable_test.go new file mode 100644 index 0000000000..6a68bffd22 --- /dev/null +++ b/precompiles/ArbFunctionTable_test.go @@ -0,0 +1,35 @@ +// Copyright 2021-2024, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package precompiles + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" +) + +func TestArbFunctionTable(t *testing.T) { + evm := newMockEVMForTesting() + ftab := ArbFunctionTable{} + context := testContext(common.Address{}, evm) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + // should be a noop + err := ftab.Upload(context, evm, []byte{0, 0, 0, 0}) + Require(t, err) + + size, err := ftab.Size(context, evm, addr) + Require(t, err) + if size.Cmp(big.NewInt(0)) != 0 { + t.Fatal("Size should be 0") + } + + _, _, _, err = ftab.Get(context, evm, addr, big.NewInt(10)) + if err == nil { + t.Fatal("Should error") + } +} From ac7f18e97c8b2be14632ae0f1c4dece1b903fada Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 09:32:11 -0300 Subject: [PATCH 13/82] Tests for ArbInfo --- precompiles/ArbInfo.go | 2 -- system_tests/program_test.go | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbInfo.go b/precompiles/ArbInfo.go index c78dd84889..9f8cf34532 100644 --- a/precompiles/ArbInfo.go +++ b/precompiles/ArbInfo.go @@ -13,7 +13,6 @@ type ArbInfo struct { Address addr // 0x65 } -// TODO: add test // GetBalance retrieves an account's balance func (con ArbInfo) GetBalance(c ctx, evm mech, account addr) (huge, error) { if err := c.Burn(params.BalanceGasEIP1884); err != nil { @@ -22,7 +21,6 @@ func (con ArbInfo) GetBalance(c ctx, evm mech, account addr) (huge, error) { return evm.StateDB.GetBalance(account).ToBig(), nil } -// TODO: add test // GetCode retrieves a contract's deployed code func (con ArbInfo) GetCode(c ctx, evm mech, account addr) ([]byte, error) { if err := c.Burn(params.ColdSloadCostEIP2929); err != nil { diff --git a/system_tests/program_test.go b/system_tests/program_test.go index 4c896d1791..cda592ee06 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -535,6 +535,16 @@ func testCalls(t *testing.T, jit bool) { defer cleanup() callsAddr := deployWasm(t, ctx, auth, l2client, rustFile("multicall")) + // checks ArbInfo.GetCode works properly + codeFromFile, _ := readWasmFile(t, rustFile("multicall")) + arbInfo, err := pgen.NewArbInfo(types.ArbInfoAddress, l2client) + Require(t, err) + codeFromArbInfo, err := arbInfo.GetCode(nil, callsAddr) + Require(t, err) + if !bytes.Equal(codeFromFile, codeFromArbInfo) { + t.Fatal("ArbInfo.GetCode returned wrong code") + } + ensure := func(tx *types.Transaction, err error) *types.Receipt { t.Helper() Require(t, err) @@ -716,6 +726,13 @@ func testCalls(t *testing.T, jit bool) { Fatal(t, balance, value) } + // checks ArbInfo.GetBalance works properly + balance, err = arbInfo.GetBalance(nil, eoa) + Require(t, err) + if !arbmath.BigEquals(balance, value) { + Fatal(t, balance, value) + } + blocks := []uint64{10} validateBlockRange(t, blocks, jit, builder) } From 18c3336d7fc211cf6a1fcffb5212ae98837dc234 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 09:44:05 -0300 Subject: [PATCH 14/82] Removes TODOs from ArbWasmCache --- precompiles/ArbWasmCache.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/precompiles/ArbWasmCache.go b/precompiles/ArbWasmCache.go index 053cfb3792..3cada9dd70 100644 --- a/precompiles/ArbWasmCache.go +++ b/precompiles/ArbWasmCache.go @@ -12,25 +12,21 @@ type ArbWasmCache struct { UpdateProgramCacheGasCost func(addr, bytes32, bool) (uint64, error) } -// TODO: add test // See if the user is a cache manager owner. func (con ArbWasmCache) IsCacheManager(c ctx, _ mech, addr addr) (bool, error) { return c.State.Programs().CacheManagers().IsMember(addr) } -// TODO: add test // Retrieve all authorized address managers. func (con ArbWasmCache) AllCacheManagers(c ctx, _ mech) ([]addr, error) { return c.State.Programs().CacheManagers().AllMembers(65536) } -// TODO: add test // Deprecated: replaced with CacheProgram. func (con ArbWasmCache) CacheCodehash(c ctx, evm mech, codehash hash) error { return con.setProgramCached(c, evm, common.Address{}, codehash, true) } -// TODO: add test // Caches all programs with a codehash equal to the given address. Caller must be a cache manager or chain owner. func (con ArbWasmCache) CacheProgram(c ctx, evm mech, address addr) error { codehash, err := c.GetCodeHash(address) @@ -40,7 +36,6 @@ func (con ArbWasmCache) CacheProgram(c ctx, evm mech, address addr) error { return con.setProgramCached(c, evm, address, codehash, true) } -// TODO: add test // Evicts all programs with the given codehash. Caller must be a cache manager or chain owner. func (con ArbWasmCache) EvictCodehash(c ctx, evm mech, codehash hash) error { return con.setProgramCached(c, evm, common.Address{}, codehash, false) From 844b5ea0a4f0d73c0f27c69cea7ffa19909da7ca Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 09:44:53 -0300 Subject: [PATCH 15/82] Removes TODOs from ArbWasm --- precompiles/ArbWasm.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/precompiles/ArbWasm.go b/precompiles/ArbWasm.go index f8ece25600..bc24c8a6e8 100644 --- a/precompiles/ArbWasm.go +++ b/precompiles/ArbWasm.go @@ -29,7 +29,6 @@ type ArbWasm struct { ProgramInsufficientValueError func(have, want huge) error } -// TODO: add test // Compile a wasm program with the latest instrumentation func (con ArbWasm) ActivateProgram(c ctx, evm mech, value huge, program addr) (uint16, huge, error) { debug := evm.ChainConfig().DebugMode() @@ -54,7 +53,6 @@ func (con ArbWasm) ActivateProgram(c ctx, evm mech, value huge, program addr) (u return version, dataFee, con.ProgramActivated(c, evm, codeHash, moduleHash, program, dataFee, version) } -// TODO: add test // Extends a program's expiration date (reverts if too soon) func (con ArbWasm) CodehashKeepalive(c ctx, evm mech, value huge, codehash bytes32) error { params, err := c.State.Programs().Params() @@ -91,56 +89,48 @@ func (con ArbWasm) payActivationDataFee(c ctx, evm mech, value, dataFee huge) er return util.TransferBalance(&con.Address, &c.caller, repay, evm, scenario, "reimburse") } -// TODO: add test // Gets the latest stylus version func (con ArbWasm) StylusVersion(c ctx, evm mech) (uint16, error) { params, err := c.State.Programs().Params() return params.Version, err } -// TODO: add test // Gets the amount of ink 1 gas buys func (con ArbWasm) InkPrice(c ctx, _ mech) (uint32, error) { params, err := c.State.Programs().Params() return params.InkPrice.ToUint32(), err } -// TODO: add test // Gets the wasm stack size limit func (con ArbWasm) MaxStackDepth(c ctx, _ mech) (uint32, error) { params, err := c.State.Programs().Params() return params.MaxStackDepth, err } -// TODO: add test // Gets the number of free wasm pages a tx gets func (con ArbWasm) FreePages(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.FreePages, err } -// TODO: add test // Gets the base cost of each additional wasm page func (con ArbWasm) PageGas(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.PageGas, err } -// TODO: add test // Gets the ramp that drives exponential memory costs func (con ArbWasm) PageRamp(c ctx, _ mech) (uint64, error) { params, err := c.State.Programs().Params() return params.PageRamp, err } -// TODO: add test // Gets the maximum initial number of pages a wasm may allocate func (con ArbWasm) PageLimit(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.PageLimit, err } -// TODO: add test // Gets the minimum costs to invoke a program func (con ArbWasm) MinInitGas(c ctx, _ mech) (uint64, uint64, error) { params, err := c.State.Programs().Params() @@ -152,35 +142,30 @@ func (con ArbWasm) MinInitGas(c ctx, _ mech) (uint64, uint64, error) { return init, cached, err } -// TODO: add test // Gets the linear adjustment made to program init costs func (con ArbWasm) InitCostScalar(c ctx, _ mech) (uint64, error) { params, err := c.State.Programs().Params() return uint64(params.InitCostScalar) * programs.CostScalarPercent, err } -// TODO: add test // Gets the number of days after which programs deactivate func (con ArbWasm) ExpiryDays(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.ExpiryDays, err } -// TODO: add test // Gets the age a program must be to perform a keepalive func (con ArbWasm) KeepaliveDays(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.KeepaliveDays, err } -// TODO: add test // Gets the number of extra programs ArbOS caches during a given block. func (con ArbWasm) BlockCacheSize(c ctx, _ mech) (uint16, error) { params, err := c.State.Programs().Params() return params.BlockCacheSize, err } -// TODO: add test // Gets the stylus version that program with codehash was most recently compiled with func (con ArbWasm) CodehashVersion(c ctx, evm mech, codehash bytes32) (uint16, error) { params, err := c.State.Programs().Params() @@ -190,7 +175,6 @@ func (con ArbWasm) CodehashVersion(c ctx, evm mech, codehash bytes32) (uint16, e return c.State.Programs().CodehashVersion(codehash, evm.Context.Time, params) } -// TODO: add test // Gets a program's asm size in bytes func (con ArbWasm) CodehashAsmSize(c ctx, evm mech, codehash bytes32) (uint32, error) { params, err := c.State.Programs().Params() @@ -200,7 +184,6 @@ func (con ArbWasm) CodehashAsmSize(c ctx, evm mech, codehash bytes32) (uint32, e return c.State.Programs().ProgramAsmSize(codehash, evm.Context.Time, params) } -// TODO: add test // Gets the stylus version that program at addr was most recently compiled with func (con ArbWasm) ProgramVersion(c ctx, evm mech, program addr) (uint16, error) { codehash, err := c.GetCodeHash(program) @@ -210,7 +193,6 @@ func (con ArbWasm) ProgramVersion(c ctx, evm mech, program addr) (uint16, error) return con.CodehashVersion(c, evm, codehash) } -// TODO: add test // Gets the cost to invoke the program func (con ArbWasm) ProgramInitGas(c ctx, evm mech, program addr) (uint64, uint64, error) { codehash, params, err := con.getCodeHash(c, program) @@ -220,7 +202,6 @@ func (con ArbWasm) ProgramInitGas(c ctx, evm mech, program addr) (uint64, uint64 return c.State.Programs().ProgramInitGas(codehash, evm.Context.Time, params) } -// TODO: add test // Gets the footprint of program at addr func (con ArbWasm) ProgramMemoryFootprint(c ctx, evm mech, program addr) (uint16, error) { codehash, params, err := con.getCodeHash(c, program) @@ -230,7 +211,6 @@ func (con ArbWasm) ProgramMemoryFootprint(c ctx, evm mech, program addr) (uint16 return c.State.Programs().ProgramMemoryFootprint(codehash, evm.Context.Time, params) } -// TODO: add test // Gets returns the amount of time remaining until the program expires func (con ArbWasm) ProgramTimeLeft(c ctx, evm mech, program addr) (uint64, error) { codehash, params, err := con.getCodeHash(c, program) From a06b470abc5373ee330415d5c89adb6118eb8fe9 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 09:56:02 -0300 Subject: [PATCH 16/82] Tests for ArbStatistics --- precompiles/ArbStatistics.go | 1 - precompiles/ArbStatistics_test.go | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 precompiles/ArbStatistics_test.go diff --git a/precompiles/ArbStatistics.go b/precompiles/ArbStatistics.go index 74d1c2dd15..83f867d09d 100644 --- a/precompiles/ArbStatistics.go +++ b/precompiles/ArbStatistics.go @@ -14,7 +14,6 @@ type ArbStatistics struct { Address addr // 0x6e } -// TODO: add test // GetStats returns the current block number and some statistics about the rollup's pre-Nitro state func (con ArbStatistics) GetStats(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { blockNum := evm.Context.BlockNumber diff --git a/precompiles/ArbStatistics_test.go b/precompiles/ArbStatistics_test.go new file mode 100644 index 0000000000..9787752906 --- /dev/null +++ b/precompiles/ArbStatistics_test.go @@ -0,0 +1,22 @@ +// Copyright 2021-2024, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package precompiles + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestArbStatistics(t *testing.T) { + evm := newMockEVMForTesting() + stats := ArbStatistics{} + context := testContext(common.Address{}, evm) + + blockNum, _, _, _, _, _, err := stats.GetStats(context, evm) + Require(t, err) + if blockNum.Cmp(evm.Context.BlockNumber) != 0 { + t.Error("Unexpected block number") + } +} From da7d145cdc370475f91d37a029808c7f88b2d64a Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 09:58:23 -0300 Subject: [PATCH 17/82] Do not test simple ArbosActs methods --- precompiles/ArbosActs.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/precompiles/ArbosActs.go b/precompiles/ArbosActs.go index 475faf0e85..e18aa43efb 100644 --- a/precompiles/ArbosActs.go +++ b/precompiles/ArbosActs.go @@ -11,12 +11,10 @@ type ArbosActs struct { CallerNotArbOSError func() error } -// TODO: add test func (con ArbosActs) StartBlock(c ctx, evm mech, l1BaseFee huge, l1BlockNumber, l2BlockNumber, timeLastBlock uint64) error { return con.CallerNotArbOSError() } -// TODO: add test func (con ArbosActs) BatchPostingReport(c ctx, evm mech, batchTimestamp huge, batchPosterAddress addr, batchNumber uint64, batchDataGas uint64, l1BaseFeeWei huge) error { return con.CallerNotArbOSError() } From 90ab8d0ac24f548b57f8d0b7c1de80459e68c697 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 10:40:58 -0300 Subject: [PATCH 18/82] Tests for ArbSys.GetStorageGasAvailable and ArbSys.ArbOSVersion --- precompiles/ArbSys.go | 3 --- system_tests/precompile_test.go | 17 ++++++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index a609f55dcd..bdbf9066f9 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -59,14 +59,12 @@ func (con *ArbSys) ArbChainID(c ctx, evm mech) (huge, error) { return evm.ChainConfig().ChainID, nil } -// TODO: add test // ArbOSVersion gets the current ArbOS version func (con *ArbSys) ArbOSVersion(c ctx, evm mech) (huge, error) { version := new(big.Int).SetUint64(55 + c.State.ArbOSVersion()) // Nitro starts at version 56 return version, nil } -// TODO: add test // GetStorageGasAvailable returns 0 since Nitro has no concept of storage gas func (con *ArbSys) GetStorageGasAvailable(c ctx, evm mech) (huge, error) { return big.NewInt(0), nil @@ -109,7 +107,6 @@ func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error return address, err } -// TODO: add test // SendTxToL1 sends a transaction to L1, adding it to the outbox func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, calldataForL1 []byte) (huge, error) { l1BlockNum, err := c.txProcessor.L1BlockNumber(vm.BlockContext{}) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 9e829124ee..68c630ff33 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -22,7 +22,10 @@ func TestPurePrecompileMethodCalls(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + arbosVersion := uint64(31) + builder := NewNodeBuilder(ctx). + DefaultConfig(t, false). + WithArbOSVersion(arbosVersion) cleanup := builder.Build(t) defer cleanup() @@ -33,6 +36,18 @@ func TestPurePrecompileMethodCalls(t *testing.T) { if chainId.Uint64() != params.ArbitrumDevTestChainConfig().ChainID.Uint64() { Fatal(t, "Wrong ChainID", chainId.Uint64()) } + + arbSysArbosVersion, err := arbSys.ArbOSVersion(&bind.CallOpts{}) + Require(t, err) + if arbSysArbosVersion.Uint64() != 55+arbosVersion { // Nitro versios start at 56 + Fatal(t, "Expected ArbOSVersion 86, got", arbosVersion) + } + + storageGasAvailable, err := arbSys.GetStorageGasAvailable(&bind.CallOpts{}) + Require(t, err) + if storageGasAvailable.Cmp(big.NewInt(0)) != 0 { + Fatal(t, "Expected 0 storage gas available, got", storageGasAvailable) + } } func TestViewLogReverts(t *testing.T) { From 8e742746fa19fad560669288d7cd574f6dce6c64 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 10:41:32 -0300 Subject: [PATCH 19/82] Do not test ArbSys.MapL1SenderContractAddressToL2Alias It only calls util.RemapL1Address, that is covered in other test flows --- precompiles/ArbSys.go | 1 - 1 file changed, 1 deletion(-) diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index bdbf9066f9..d55067a09c 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -75,7 +75,6 @@ func (con *ArbSys) IsTopLevelCall(c ctx, evm mech) (bool, error) { return evm.Depth() <= 2, nil } -// TODO: add test // MapL1SenderContractAddressToL2Alias gets the contract's L2 alias func (con *ArbSys) MapL1SenderContractAddressToL2Alias(c ctx, sender addr, dest addr) (addr, error) { return util.RemapL1Address(sender), nil From d712416b20518928dab40892c119ac61ae43e1d3 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 11:24:34 -0300 Subject: [PATCH 20/82] Test for ArbOwnerPublic.GetBrotliCompressionLevel --- precompiles/ArbOwnerPublic.go | 1 - system_tests/precompile_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index 4c83646aa9..177268d9bb 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -49,7 +49,6 @@ func (con ArbOwnerPublic) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() } -// TODO: add test // GetBrotliCompressionLevel gets the current brotli compression level used for fast compression func (con ArbOwnerPublic) GetBrotliCompressionLevel(c ctx, evm mech) (uint64, error) { return c.State.BrotliCompressionLevel() diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 68c630ff33..0b63d72e4d 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -140,6 +140,39 @@ func TestPrecompileErrorGasLeft(t *testing.T) { assertNotAllGasConsumed(common.HexToAddress("0xff"), arbDebug.Methods["legacyError"].ID) } +func TestGetBrotliCompressionLevel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), builder.L2.Client) + Require(t, err, "could not bind ArbOwner contract") + + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), builder.L2.Client) + Require(t, err, "could not bind ArbOwner contract") + + brotliCompressionLevel := uint64(11) + + // sets brotli compression level + tx, err := arbOwner.SetBrotliCompressionLevel(&auth, brotliCompressionLevel) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + // retrieves brotli compression level + callOpts := &bind.CallOpts{Context: ctx} + retrievedBrotliCompressionLevel, err := arbOwnerPublic.GetBrotliCompressionLevel(callOpts) + Require(t, err, "failed to call GetBrotliCompressionLevel") + if retrievedBrotliCompressionLevel != brotliCompressionLevel { + Fatal(t, "expected brotli compression level to be", brotliCompressionLevel, "got", retrievedBrotliCompressionLevel) + } +} + func TestScheduleArbosUpgrade(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 115bda4eff1780ee075fa03dd18f475c2254eb02 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 11:25:14 -0300 Subject: [PATCH 21/82] Do not test ArbOwnerPublic.RectifyChainOwner It basically uses AddressSet.RectifyMapping that is already covered in other tests --- precompiles/ArbOwnerPublic.go | 1 - 1 file changed, 1 deletion(-) diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index 177268d9bb..451e18e1cc 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -21,7 +21,6 @@ func (con ArbOwnerPublic) GetAllChainOwners(c ctx, evm mech) ([]common.Address, return c.State.ChainOwners().AllMembers(65536) } -// TODO: add test // RectifyChainOwner checks if the account is a chain owner func (con ArbOwnerPublic) RectifyChainOwner(c ctx, evm mech, addr addr) error { err := c.State.ChainOwners().RectifyMapping(addr) From 3f32c0f99031342797b5bcb60935359866118523 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 11:42:18 -0300 Subject: [PATCH 22/82] Comment to check ArbOwner later --- precompiles/ArbOwner.go | 1 + 1 file changed, 1 insertion(+) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 8b87445e0e..040ce7054b 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -1,3 +1,4 @@ +// TODO: check // Copyright 2021-2024, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE From 5a7ca32045e753540faf5e0e08c4f0cabaa4170f Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Wed, 25 Sep 2024 12:44:40 -0300 Subject: [PATCH 23/82] TestGetLifetime --- precompiles/ArbRetryableTx.go | 3 --- precompiles/ArbRetryableTx_test.go | 13 +++++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index abfdc94807..3410754b63 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -45,7 +45,6 @@ func (con ArbRetryableTx) oldNotFoundError(c ctx) error { return errors.New("ticketId not found") } -// TODO: add test // Redeem schedules an attempt to redeem the retryable, donating all of the call's gas to the redeem attempt func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, error) { if c.txProcessor.CurrentRetryable != nil && ticketId == *c.txProcessor.CurrentRetryable { @@ -131,13 +130,11 @@ func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, er return retryTxHash, c.State.L2PricingState().AddToGasPool(arbmath.SaturatingCast[int64](gasToDonate)) } -// TODO: add test // GetLifetime gets the default lifetime period a retryable has at creation func (con ArbRetryableTx) GetLifetime(c ctx, evm mech) (huge, error) { return big.NewInt(retryables.RetryableLifetimeSeconds), nil } -// TODO: add test // GetTimeout gets the timestamp for when ticket will expire func (con ArbRetryableTx) GetTimeout(c ctx, evm mech, ticketId bytes32) (huge, error) { retryableState := c.State.RetryableState() diff --git a/precompiles/ArbRetryableTx_test.go b/precompiles/ArbRetryableTx_test.go index 9ccb437abc..af52926e75 100644 --- a/precompiles/ArbRetryableTx_test.go +++ b/precompiles/ArbRetryableTx_test.go @@ -7,12 +7,25 @@ import ( "math/big" "testing" + "github.com/offchainlabs/nitro/arbos/retryables" "github.com/offchainlabs/nitro/arbos/storage" "github.com/ethereum/go-ethereum/common" templates "github.com/offchainlabs/nitro/solgen/go/precompilesgen" ) +func TestGetLifetime(t *testing.T) { + evm := newMockEVMForTesting() + retryableTx := ArbRetryableTx{} + context := testContext(common.Address{}, evm) + + lifetime, err := retryableTx.GetLifetime(context, evm) + Require(t, err) + if lifetime.Cmp(big.NewInt(retryables.RetryableLifetimeSeconds)) != 0 { + t.Fatal("Expected to be ", retryables.RetryableLifetimeSeconds, " but got ", lifetime) + } +} + func TestRetryableRedeem(t *testing.T) { evm := newMockEVMForTesting() precompileCtx := testContext(common.Address{}, evm) From 4b6d4a033b514bf30c7f1ad523280d0dbb205b3a Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 08:33:29 -0300 Subject: [PATCH 24/82] TestArbGasInfoAndArbOwner --- precompiles/ArbGasInfo.go | 11 ---- precompiles/ArbOwner.go | 5 +- system_tests/precompile_test.go | 101 ++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 12 deletions(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index e3e0029d9e..cd3ca6458d 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -22,7 +22,6 @@ var storageArbGas = big.NewInt(int64(storage.StorageWriteCost)) const AssumedSimpleTxSize = 140 -// TODO: add test // GetPricesInWeiWithAggregator gets prices in wei when using the provided aggregator func (con ArbGasInfo) GetPricesInWeiWithAggregator( c ctx, @@ -66,7 +65,6 @@ func (con ArbGasInfo) GetPricesInWeiWithAggregator( return perL2Tx, weiForL1Calldata, weiForL2Storage, perArbGasBase, perArbGasCongestion, perArbGasTotal, nil } -// TODO: add test func (con ArbGasInfo) _preVersion4_GetPricesInWeiWithAggregator( c ctx, evm mech, @@ -134,7 +132,6 @@ func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregato return gasPerL2Tx, gasForL1Calldata, storageArbGas, nil } -// TODO: add test func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { l1GasPrice, err := c.State.L1PricingState().PricePerUnit() if err != nil { @@ -183,19 +180,16 @@ func (con ArbGasInfo) GetL1BaseFeeEstimate(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().PricePerUnit() } -// TODO: add test // GetL1BaseFeeEstimateInertia gets how slowly ArbOS updates its estimate of the L1 basefee func (con ArbGasInfo) GetL1BaseFeeEstimateInertia(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().Inertia() } -// TODO: add test // GetL1RewardRate gets the L1 pricer reward rate func (con ArbGasInfo) GetL1RewardRate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().PerUnitReward() } -// TODO: add test // GetL1RewardRecipient gets the L1 pricer reward recipient func (con ArbGasInfo) GetL1RewardRecipient(c ctx, evm mech) (common.Address, error) { return c.State.L1PricingState().PayRewardsTo() @@ -219,13 +213,11 @@ func (con ArbGasInfo) GetGasBacklog(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().GasBacklog() } -// TODO: add test // GetPricingInertia gets how slowly ArbOS updates the L2 basefee in response to backlogged gas func (con ArbGasInfo) GetPricingInertia(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().PricingInertia() } -// TODO: add test // GetGasBacklogTolerance gets the forgivable amount of backlogged gas ArbOS will ignore when raising the basefee func (con ArbGasInfo) GetGasBacklogTolerance(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().BacklogTolerance() @@ -240,7 +232,6 @@ func (con ArbGasInfo) GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return ps.GetL1PricingSurplus() } -// TODO: add test func (con ArbGasInfo) _preversion10_GetL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { ps := c.State.L1PricingState() fundsDueForRefunds, err := ps.BatchPosterTable().TotalFundsDue() @@ -256,7 +247,6 @@ func (con ArbGasInfo) _preversion10_GetL1PricingSurplus(c ctx, evm mech) (*big.I return arbmath.BigSub(haveFunds.ToBig(), needFunds), nil } -// TODO: add test // GetPerBatchGasCharge gets the base charge (in L1 gas) attributed to each data batch in the calldata pricer func (con ArbGasInfo) GetPerBatchGasCharge(c ctx, evm mech) (int64, error) { return c.State.L1PricingState().PerBatchGasCost() @@ -272,7 +262,6 @@ func (con ArbGasInfo) GetL1FeesAvailable(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().L1FeesAvailable() } -// TODO: add test // GetL1PricingEquilibrationUnits gets the equilibration units parameter for L1 price adjustment algorithm func (con ArbGasInfo) GetL1PricingEquilibrationUnits(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().EquilibrationUnits() diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 040ce7054b..52096c1f26 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -1,4 +1,3 @@ -// TODO: check // Copyright 2021-2024, Offchain Labs, Inc. // For license information, see https://github.com/nitro/blob/master/LICENSE @@ -63,6 +62,7 @@ func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) return c.State.L1PricingState().SetInertia(inertia) } +// TODO: add test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) @@ -76,6 +76,7 @@ func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error return c.State.L2PricingState().SetMinBaseFeeWei(priceInWei) } +// TODO: add test // SetSpeedLimit sets the computational speed limit for the chain func (con ArbOwner) SetSpeedLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetSpeedLimitPerSecond(limit) @@ -96,6 +97,7 @@ func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error return c.State.L2PricingState().SetBacklogTolerance(sec) } +// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() @@ -125,6 +127,7 @@ func (con ArbOwner) SetL1PricingEquilibrationUnits(c ctx, evm mech, equilibratio return c.State.L1PricingState().SetEquilibrationUnits(equilibrationUnits) } +// TODO: add test func (con ArbOwner) SetL1PricingInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 0b63d72e4d..9f47013133 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -11,6 +11,7 @@ import ( "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/arbos" "github.com/offchainlabs/nitro/solgen/go/mocksgen" @@ -140,6 +141,106 @@ func TestPrecompileErrorGasLeft(t *testing.T) { assertNotAllGasConsumed(common.HexToAddress("0xff"), arbDebug.Methods["legacyError"].ID) } +func TestArbGasInfoAndArbOwner(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), builder.L2.Client) + Require(t, err) + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), builder.L2.Client) + Require(t, err) + + // GetL1BaseFeeEstimateInertia test + inertia := uint64(11) + tx, err := arbOwner.SetL1BaseFeeEstimateInertia(&auth, inertia) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoInertia, err := arbGasInfo.GetL1BaseFeeEstimateInertia(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoInertia != inertia { + Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) + } + + // GetL1RewardRate test + perUnitReward := uint64(11) + tx, err = arbOwner.SetL1PricingRewardRate(&auth, perUnitReward) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoPerUnitReward, err := arbGasInfo.GetL1RewardRate(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoPerUnitReward != perUnitReward { + Fatal(t, "expected per unit reward to be", perUnitReward, "got", arbGasInfoPerUnitReward) + } + + // GetL1RewardRecipient test + rewardRecipient := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + tx, err = arbOwner.SetL1PricingRewardRecipient(&auth, rewardRecipient) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoRewardRecipient, err := arbGasInfo.GetL1RewardRecipient(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoRewardRecipient.Cmp(rewardRecipient) != 0 { + Fatal(t, "expected reward recipient to be", rewardRecipient, "got", arbGasInfoRewardRecipient) + } + + // GetPricingInertia + inertia = uint64(11) + tx, err = arbOwner.SetL2GasPricingInertia(&auth, inertia) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoInertia, err = arbGasInfo.GetPricingInertia(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoInertia != inertia { + Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) + } + + // GetGasBacklogTolerance + gasTolerance := uint64(11) + tx, err = arbOwner.SetL2GasBacklogTolerance(&auth, inertia) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoGasTolerance, err := arbGasInfo.GetGasBacklogTolerance(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoGasTolerance != gasTolerance { + Fatal(t, "expected gas tolerance to be", gasTolerance, "got", arbGasInfoGasTolerance) + } + + // GetPerBatchGasCharge + perBatchGasCharge := int64(11) + tx, err = arbOwner.SetPerBatchGasCharge(&auth, perBatchGasCharge) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoPerBatchGasCharge, err := arbGasInfo.GetPerBatchGasCharge(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoPerBatchGasCharge != perBatchGasCharge { + Fatal(t, "expected per batch gas charge to be", perBatchGasCharge, "got", arbGasInfoPerBatchGasCharge) + } + + // GetL1PricingEquilibrationUnits + equilUnits := big.NewInt(11) + tx, err = arbOwner.SetL1PricingEquilibrationUnits(&auth, equilUnits) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoEquilUnits, err := arbGasInfo.GetL1PricingEquilibrationUnits(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoEquilUnits.Cmp(equilUnits) != 0 { + Fatal(t, "expected equilibration units to be", equilUnits, "got", arbGasInfoEquilUnits) + } +} + func TestGetBrotliCompressionLevel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 7ce998e2cb1bdd3a1dd61cea15c2714c18bfda23 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 10:09:59 -0300 Subject: [PATCH 25/82] Test for GetNetworkFeeAccount --- precompiles/ArbGasInfo.go | 1 - precompiles/ArbOwner.go | 1 - precompiles/ArbOwner_test.go | 8 ++++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index cd3ca6458d..133e1cb6e1 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -195,7 +195,6 @@ func (con ArbGasInfo) GetL1RewardRecipient(c ctx, evm mech) (common.Address, err return c.State.L1PricingState().PayRewardsTo() } -// TODO: add test // GetL1GasPriceEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1GasPriceEstimate(c ctx, evm mech) (huge, error) { return con.GetL1BaseFeeEstimate(c, evm) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 52096c1f26..98c874fc17 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -97,7 +97,6 @@ func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error return c.State.L2PricingState().SetBacklogTolerance(sec) } -// TODO: add test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() diff --git a/precompiles/ArbOwner_test.go b/precompiles/ArbOwner_test.go index 1f8c7ae4cd..b2ee1b5029 100644 --- a/precompiles/ArbOwner_test.go +++ b/precompiles/ArbOwner_test.go @@ -151,6 +151,14 @@ func TestArbOwner(t *testing.T) { if avail.Cmp(deposited) != 0 { Fail(t, avail, deposited) } + + err = prec.SetNetworkFeeAccount(callCtx, evm, addr1) + Require(t, err) + retrievedNetworkFeeAccount, err := prec.GetNetworkFeeAccount(callCtx, evm) + Require(t, err) + if retrievedNetworkFeeAccount != addr1 { + Fail(t, "Expected", addr1, "got", retrievedNetworkFeeAccount) + } } func TestArbOwnerSetChainConfig(t *testing.T) { From 136ad43d099a3559d7c962884ee037900af7abc7 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 10:13:17 -0300 Subject: [PATCH 26/82] Test for SetL1PricingInertia --- precompiles/ArbOwner.go | 1 - system_tests/precompile_test.go | 12 ++++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 98c874fc17..b98a4e31e7 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -126,7 +126,6 @@ func (con ArbOwner) SetL1PricingEquilibrationUnits(c ctx, evm mech, equilibratio return c.State.L1PricingState().SetEquilibrationUnits(equilibrationUnits) } -// TODO: add test func (con ArbOwner) SetL1PricingInertia(c ctx, evm mech, inertia uint64) error { return c.State.L1PricingState().SetInertia(inertia) } diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 9f47013133..ecd3125c6a 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -168,6 +168,18 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } + // GetL1BaseFeeEstimateInertia test, but using a different setter from ArbOwner + inertia = uint64(11) + tx, err = arbOwner.SetL1PricingInertia(&auth, inertia) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoInertia, err = arbGasInfo.GetL1BaseFeeEstimateInertia(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoInertia != inertia { + Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) + } + // GetL1RewardRate test perUnitReward := uint64(11) tx, err = arbOwner.SetL1PricingRewardRate(&auth, perUnitReward) From fd75c88bf6e581198aca525fe2e7fc538a0af3b5 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 10:40:45 -0300 Subject: [PATCH 27/82] Test for GetGasAccountingParams. Fixes GetGasBacklogTolerance test --- precompiles/ArbGasInfo.go | 1 - precompiles/ArbOwner.go | 1 - system_tests/precompile_test.go | 37 ++++++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index 133e1cb6e1..48d95f0a91 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -161,7 +161,6 @@ func (con ArbGasInfo) GetPricesInArbGas(c ctx, evm mech) (huge, huge, huge, erro return con.GetPricesInArbGasWithAggregator(c, evm, addr{}) } -// TODO: add test // GetGasAccountingParams gets the rollup's speed limit, pool size, and tx gas limit func (con ArbGasInfo) GetGasAccountingParams(c ctx, evm mech) (huge, huge, huge, error) { l2pricing := c.State.L2PricingState() diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index b98a4e31e7..5310254ead 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -76,7 +76,6 @@ func (con ArbOwner) SetMinimumL2BaseFee(c ctx, evm mech, priceInWei huge) error return c.State.L2PricingState().SetMinBaseFeeWei(priceInWei) } -// TODO: add test // SetSpeedLimit sets the computational speed limit for the chain func (con ArbOwner) SetSpeedLimit(c ctx, evm mech, limit uint64) error { return c.State.L2PricingState().SetSpeedLimitPerSecond(limit) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index ecd3125c6a..0d8a14f9b1 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -169,7 +169,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetL1BaseFeeEstimateInertia test, but using a different setter from ArbOwner - inertia = uint64(11) + inertia = uint64(12) tx, err = arbOwner.SetL1PricingInertia(&auth, inertia) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) @@ -181,7 +181,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetL1RewardRate test - perUnitReward := uint64(11) + perUnitReward := uint64(13) tx, err = arbOwner.SetL1PricingRewardRate(&auth, perUnitReward) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) @@ -205,7 +205,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetPricingInertia - inertia = uint64(11) + inertia = uint64(14) tx, err = arbOwner.SetL2GasPricingInertia(&auth, inertia) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) @@ -217,8 +217,8 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetGasBacklogTolerance - gasTolerance := uint64(11) - tx, err = arbOwner.SetL2GasBacklogTolerance(&auth, inertia) + gasTolerance := uint64(15) + tx, err = arbOwner.SetL2GasBacklogTolerance(&auth, gasTolerance) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -229,7 +229,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetPerBatchGasCharge - perBatchGasCharge := int64(11) + perBatchGasCharge := int64(16) tx, err = arbOwner.SetPerBatchGasCharge(&auth, perBatchGasCharge) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) @@ -241,7 +241,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { } // GetL1PricingEquilibrationUnits - equilUnits := big.NewInt(11) + equilUnits := big.NewInt(17) tx, err = arbOwner.SetL1PricingEquilibrationUnits(&auth, equilUnits) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) @@ -251,6 +251,29 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoEquilUnits.Cmp(equilUnits) != 0 { Fatal(t, "expected equilibration units to be", equilUnits, "got", arbGasInfoEquilUnits) } + + // GetGasAccountingParams + speedLimit := uint64(18) + txGasLimit := uint64(19) + tx, err = arbOwner.SetSpeedLimit(&auth, speedLimit) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + tx, err = arbOwner.SetMaxTxGasLimit(&auth, txGasLimit) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + arbGasInfoSpeedLimit, arbGasInfoPoolSize, arbGasInfoTxGasLimit, err := arbGasInfo.GetGasAccountingParams(&bind.CallOpts{Context: ctx}) + Require(t, err) + if arbGasInfoSpeedLimit.Cmp(big.NewInt(int64(speedLimit))) != 0 { + Fatal(t, "expected speed limit to be", speedLimit, "got", arbGasInfoSpeedLimit) + } + if arbGasInfoPoolSize.Cmp(big.NewInt(int64(txGasLimit))) != 0 { + Fatal(t, "expected pool size to be", txGasLimit, "got", arbGasInfoPoolSize) + } + if arbGasInfoTxGasLimit.Cmp(big.NewInt(int64(txGasLimit))) != 0 { + Fatal(t, "expected tx gas limit to be", txGasLimit, "got", arbGasInfoTxGasLimit) + } } func TestGetBrotliCompressionLevel(t *testing.T) { From 99e989bd2b118fa0ab9a028f824ac7d1f4189453 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 10:51:43 -0300 Subject: [PATCH 28/82] Test for ArbOwner.SetL2BaseFee --- precompiles/ArbOwner.go | 1 - precompiles/ArbOwner_test.go | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 5310254ead..8b87445e0e 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -62,7 +62,6 @@ func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) return c.State.L1PricingState().SetInertia(inertia) } -// TODO: add test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) diff --git a/precompiles/ArbOwner_test.go b/precompiles/ArbOwner_test.go index b2ee1b5029..2a2005b705 100644 --- a/precompiles/ArbOwner_test.go +++ b/precompiles/ArbOwner_test.go @@ -159,6 +159,16 @@ func TestArbOwner(t *testing.T) { if retrievedNetworkFeeAccount != addr1 { Fail(t, "Expected", addr1, "got", retrievedNetworkFeeAccount) } + + l2BaseFee := big.NewInt(123) + err = prec.SetL2BaseFee(callCtx, evm, l2BaseFee) + Require(t, err) + retrievedL2BaseFee, err := state.L2PricingState().BaseFeeWei() + Require(t, err) + if l2BaseFee.Cmp(retrievedL2BaseFee) != 0 { + Fail(t, "Expected", l2BaseFee, "got", retrievedL2BaseFee) + } + } func TestArbOwnerSetChainConfig(t *testing.T) { From 13092f7093a752d3b111d29fc3ee5609e9ca9c62 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 11:10:17 -0300 Subject: [PATCH 29/82] More ArbGasInfo tests --- precompiles/ArbGasInfo.go | 5 --- precompiles/ArbGasInfo_test.go | 81 ++++++++++++++++++++++++++++++++++ precompiles/ArbOwner_test.go | 1 - 3 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 precompiles/ArbGasInfo_test.go diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index 48d95f0a91..c476f9ec94 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -205,7 +205,6 @@ func (con ArbGasInfo) GetCurrentTxL1GasFees(c ctx, evm mech) (huge, error) { return c.txProcessor.PosterFee, nil } -// TODO: add test // GetGasBacklog gets the backlogged amount of gas burnt in excess of the speed limit func (con ArbGasInfo) GetGasBacklog(c ctx, evm mech) (uint64, error) { return c.State.L2PricingState().GasBacklog() @@ -265,25 +264,21 @@ func (con ArbGasInfo) GetL1PricingEquilibrationUnits(c ctx, evm mech) (*big.Int, return c.State.L1PricingState().EquilibrationUnits() } -// TODO: add test // GetLastL1PricingUpdateTime gets the last time the L1 calldata pricer was updated func (con ArbGasInfo) GetLastL1PricingUpdateTime(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().LastUpdateTime() } -// TODO: add test // GetL1PricingFundsDueForRewards gets the amount of L1 calldata payments due for rewards (per the L1 reward rate) func (con ArbGasInfo) GetL1PricingFundsDueForRewards(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().FundsDueForRewards() } -// TODO: add test // GetL1PricingUnitsSinceUpdate gets the amount of L1 calldata posted since the last update func (con ArbGasInfo) GetL1PricingUnitsSinceUpdate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().UnitsSinceUpdate() } -// TODO: add test // GetLastL1PricingSurplus gets the L1 pricing surplus as of the last update (may be negative) func (con ArbGasInfo) GetLastL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().LastSurplus() diff --git a/precompiles/ArbGasInfo_test.go b/precompiles/ArbGasInfo_test.go new file mode 100644 index 0000000000..dc893abe61 --- /dev/null +++ b/precompiles/ArbGasInfo_test.go @@ -0,0 +1,81 @@ +// Copyright 2021-2024, Offchain Labs, Inc. +// For license information, see https://github.com/nitro/blob/master/LICENSE + +package precompiles + +import ( + "math/big" + "testing" + + "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/nitro/arbos/arbosState" + "github.com/offchainlabs/nitro/arbos/burn" + "github.com/offchainlabs/nitro/arbos/util" + "github.com/offchainlabs/nitro/util/testhelpers" +) + +func TestArbGasInfo(t *testing.T) { + t.Parallel() + + evm := newMockEVMForTesting() + caller := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + tracer := util.NewTracingInfo(evm, testhelpers.RandomAddress(), types.ArbosAddress, util.TracingDuringEVM) + state, err := arbosState.OpenArbosState(evm.StateDB, burn.NewSystemBurner(tracer, false)) + Require(t, err) + + arbGasInfo := &ArbGasInfo{} + callCtx := testContext(caller, evm) + + // GetGasBacklog test + backlog := uint64(1000) + err = state.L2PricingState().SetGasBacklog(backlog) + Require(t, err) + retrievedBacklog, err := arbGasInfo.GetGasBacklog(callCtx, evm) + Require(t, err) + if retrievedBacklog != backlog { + t.Fatal("expected backlog to be", backlog, "but got", retrievedBacklog) + } + + // GetLastL1PricingUpdateTime test + lastUpdateTime := uint64(1001) + err = state.L1PricingState().SetLastUpdateTime(lastUpdateTime) + Require(t, err) + retrievedLastUpdateTime, err := arbGasInfo.GetLastL1PricingUpdateTime(callCtx, evm) + Require(t, err) + if retrievedLastUpdateTime != lastUpdateTime { + t.Fatal("expected last update time to be", lastUpdateTime, "but got", retrievedLastUpdateTime) + } + + // GetL1PricingFundsDueForRewards test + fundsDueForRewards := big.NewInt(1002) + err = state.L1PricingState().SetFundsDueForRewards(fundsDueForRewards) + Require(t, err) + retrievedFundsDueForRewards, err := arbGasInfo.GetL1PricingFundsDueForRewards(callCtx, evm) + Require(t, err) + if retrievedFundsDueForRewards.Cmp(fundsDueForRewards) != 0 { + t.Fatal("expected funds due for rewards to be", fundsDueForRewards, "but got", retrievedFundsDueForRewards) + } + + // GetL1PricingUnitsSinceUpdate test + pricingUnitsSinceUpdate := uint64(1003) + err = state.L1PricingState().SetUnitsSinceUpdate(pricingUnitsSinceUpdate) + Require(t, err) + retrievedPricingUnitsSinceUpdate, err := arbGasInfo.GetL1PricingUnitsSinceUpdate(callCtx, evm) + Require(t, err) + if retrievedPricingUnitsSinceUpdate != pricingUnitsSinceUpdate { + t.Fatal("expected pricing units since update to be", pricingUnitsSinceUpdate, "but got", retrievedPricingUnitsSinceUpdate) + } + + // GetLastL1PricingSurplus test + lastSurplus := big.NewInt(1004) + err = state.L1PricingState().SetLastSurplus(lastSurplus, params.ArbosVersion_Stylus) + Require(t, err) + retrievedLastSurplus, err := arbGasInfo.GetLastL1PricingSurplus(callCtx, evm) + Require(t, err) + if retrievedLastSurplus.Cmp(lastSurplus) != 0 { + t.Fatal("expected last surplus to be", lastSurplus, "but got", retrievedLastSurplus) + } +} diff --git a/precompiles/ArbOwner_test.go b/precompiles/ArbOwner_test.go index 2a2005b705..6d3256ca65 100644 --- a/precompiles/ArbOwner_test.go +++ b/precompiles/ArbOwner_test.go @@ -168,7 +168,6 @@ func TestArbOwner(t *testing.T) { if l2BaseFee.Cmp(retrievedL2BaseFee) != 0 { Fail(t, "Expected", l2BaseFee, "got", retrievedL2BaseFee) } - } func TestArbOwnerSetChainConfig(t *testing.T) { From 5fbfd672abf01825d56f5dd43f1309c90cfa542c Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 11:39:15 -0300 Subject: [PATCH 30/82] ArbRetryableTx.GetBeneficiary test --- precompiles/ArbRetryableTx.go | 1 - precompiles/ArbRetryableTx_test.go | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index 3410754b63..94b7172516 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -182,7 +182,6 @@ func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, er return bigNewTimeout, err } -// TODO: add test // GetBeneficiary gets the beneficiary of the ticket func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (addr, error) { retryableState := c.State.RetryableState() diff --git a/precompiles/ArbRetryableTx_test.go b/precompiles/ArbRetryableTx_test.go index af52926e75..03433dab15 100644 --- a/precompiles/ArbRetryableTx_test.go +++ b/precompiles/ArbRetryableTx_test.go @@ -26,7 +26,7 @@ func TestGetLifetime(t *testing.T) { } } -func TestRetryableRedeem(t *testing.T) { +func TestRetryableRedeemAndGetBeneficiary(t *testing.T) { evm := newMockEVMForTesting() precompileCtx := testContext(common.Address{}, evm) @@ -75,4 +75,21 @@ func TestRetryableRedeem(t *testing.T) { // to handle both cases, and some will be left over in this test's use case. Fail(t, "didn't consume all the expected gas") } + + getBeneficiaryCallData, err := retryABI.Pack("getBeneficiary", id) + Require(t, err) + retrievedBeneficiary, _, err := Precompiles()[retryAddress].Call( + getBeneficiaryCallData, + retryAddress, + retryAddress, + common.Address{}, + big.NewInt(0), + false, + 1000000, + evm, + ) + Require(t, err) + if common.BytesToAddress(retrievedBeneficiary).Cmp(beneficiary) != 0 { + Fail(t, "expected beneficiary to be ", beneficiary, " but got ", common.BytesToAddress(retrievedBeneficiary)) + } } From e8734333fe1284ab4975fe64d0f1a2537b4398c9 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 26 Sep 2024 13:31:11 -0300 Subject: [PATCH 31/82] GetPricesInArbGas test --- precompiles/ArbGasInfo.go | 2 -- precompiles/ArbGasInfo_test.go | 18 ++++++++++++++++++ precompiles/ArbRetryableTx.go | 1 - 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index c476f9ec94..b18945447d 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -102,7 +102,6 @@ func (con ArbGasInfo) GetPricesInWei(c ctx, evm mech) (huge, huge, huge, huge, h return con.GetPricesInWeiWithAggregator(c, evm, addr{}) } -// TODO: add test // GetPricesInArbGasWithAggregator gets prices in ArbGas when using the provided aggregator func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { if c.State.ArbOSVersion() < 4 { @@ -155,7 +154,6 @@ func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm me return perL2Tx, gasForL1Calldata, storageArbGas, nil } -// TODO: add test // GetPricesInArbGas gets prices in ArbGas when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInArbGas(c ctx, evm mech) (huge, huge, huge, error) { return con.GetPricesInArbGasWithAggregator(c, evm, addr{}) diff --git a/precompiles/ArbGasInfo_test.go b/precompiles/ArbGasInfo_test.go index dc893abe61..72bc13d71e 100644 --- a/precompiles/ArbGasInfo_test.go +++ b/precompiles/ArbGasInfo_test.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbos/arbosState" "github.com/offchainlabs/nitro/arbos/burn" + "github.com/offchainlabs/nitro/arbos/storage" "github.com/offchainlabs/nitro/arbos/util" "github.com/offchainlabs/nitro/util/testhelpers" ) @@ -78,4 +79,21 @@ func TestArbGasInfo(t *testing.T) { if retrievedLastSurplus.Cmp(lastSurplus) != 0 { t.Fatal("expected last surplus to be", lastSurplus, "but got", retrievedLastSurplus) } + + // GetPricesInArbGas test + evm.Context.BaseFee = big.NewInt(1005) + expectedGasPerL2Tx := big.NewInt(111442786069) + expectedGasForL1Calldata := big.NewInt(796019900) + expectedStorageArgGas := big.NewInt(int64(storage.StorageWriteCost)) + gasPerL2Tx, gasForL1Calldata, storageArgGas, err := arbGasInfo.GetPricesInArbGas(callCtx, evm) + Require(t, err) + if gasPerL2Tx.Cmp(expectedGasPerL2Tx) != 0 { + t.Fatal("expected gas per L2 tx to be", expectedGasPerL2Tx, "but got", gasPerL2Tx) + } + if gasForL1Calldata.Cmp(expectedGasForL1Calldata) != 0 { + t.Fatal("expected gas for L1 calldata to be", expectedGasForL1Calldata, "but got", gasForL1Calldata) + } + if storageArgGas.Cmp(expectedStorageArgGas) != 0 { + t.Fatal("expected storage arg gas to be", expectedStorageArgGas, "but got", storageArgGas) + } } diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index 94b7172516..ed7919c7dd 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -233,7 +233,6 @@ func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, e return common.Address{}, nil } -// TODO: add test func (con ArbRetryableTx) SubmitRetryable( c ctx, evm mech, requestId bytes32, l1BaseFee, deposit, callvalue, gasFeeCap huge, gasLimit uint64, maxSubmissionFee huge, From 4ce2fb88ef146c82275b3d53b3e411b2d7159220 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 07:50:10 -0300 Subject: [PATCH 32/82] GetCurrentTxL1GasFees test --- precompiles/ArbGasInfo.go | 1 - system_tests/precompile_test.go | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index b18945447d..b41dfda8a2 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -197,7 +197,6 @@ func (con ArbGasInfo) GetL1GasPriceEstimate(c ctx, evm mech) (huge, error) { return con.GetL1BaseFeeEstimate(c, evm) } -// TODO: add test // GetCurrentTxL1GasFees gets the fee paid to the aggregator for posting this tx func (con ArbGasInfo) GetCurrentTxL1GasFees(c ctx, evm mech) (huge, error) { return c.txProcessor.PosterFee, nil diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 0d8a14f9b1..780373a0cd 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -274,6 +274,15 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoTxGasLimit.Cmp(big.NewInt(int64(txGasLimit))) != 0 { Fatal(t, "expected tx gas limit to be", txGasLimit, "got", arbGasInfoTxGasLimit) } + + currTxL1GasFees, err := arbGasInfo.GetCurrentTxL1GasFees(&bind.CallOpts{Context: ctx}) + Require(t, err) + if currTxL1GasFees == nil { + Fatal(t, "currTxL1GasFees is nil") + } + if currTxL1GasFees.Cmp(big.NewInt(0)) != 1 { + Fatal(t, "expected currTxL1GasFees to be greater than 0, got", currTxL1GasFees) + } } func TestGetBrotliCompressionLevel(t *testing.T) { From b2a42d75a5ead89ece84e71a745062a48369b54c Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 11:51:37 -0300 Subject: [PATCH 33/82] GetCurrentRedeemer test --- precompiles/ArbRetryableTx.go | 1 - precompiles/ArbRetryableTx_test.go | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index ed7919c7dd..eab459af42 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -225,7 +225,6 @@ func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { return con.Canceled(c, evm, ticketId) } -// TODO: add test func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, error) { if c.txProcessor.CurrentRefundTo != nil { return *c.txProcessor.CurrentRefundTo, nil diff --git a/precompiles/ArbRetryableTx_test.go b/precompiles/ArbRetryableTx_test.go index 03433dab15..58eed5ad77 100644 --- a/precompiles/ArbRetryableTx_test.go +++ b/precompiles/ArbRetryableTx_test.go @@ -7,15 +7,28 @@ import ( "math/big" "testing" + "github.com/offchainlabs/nitro/arbos" "github.com/offchainlabs/nitro/arbos/retryables" "github.com/offchainlabs/nitro/arbos/storage" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/vm" templates "github.com/offchainlabs/nitro/solgen/go/precompilesgen" ) -func TestGetLifetime(t *testing.T) { +func newMockEVMForTestingWithCurrentRefundTo(currentRefundTo *common.Address) *vm.EVM { evm := newMockEVMForTesting() + txProcessor := arbos.NewTxProcessor(evm, &core.Message{}) + txProcessor.CurrentRefundTo = currentRefundTo + evm.ProcessingHook = txProcessor + return evm +} + +func TestGetLifetimeAndCurrentRedeemer(t *testing.T) { + currentRefundTo := common.HexToAddress("0x030405") + + evm := newMockEVMForTestingWithCurrentRefundTo(¤tRefundTo) retryableTx := ArbRetryableTx{} context := testContext(common.Address{}, evm) @@ -24,6 +37,12 @@ func TestGetLifetime(t *testing.T) { if lifetime.Cmp(big.NewInt(retryables.RetryableLifetimeSeconds)) != 0 { t.Fatal("Expected to be ", retryables.RetryableLifetimeSeconds, " but got ", lifetime) } + + currentRedeemer, err := retryableTx.GetCurrentRedeemer(context, evm) + Require(t, err) + if currentRefundTo.Cmp(currentRedeemer) != 0 { + t.Fatal("Expected to be ", currentRefundTo, " but got ", currentRedeemer) + } } func TestRetryableRedeemAndGetBeneficiary(t *testing.T) { From 98537b59cd7eeeb820127ba3851c2b0c0c05d104 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 12:45:36 -0300 Subject: [PATCH 34/82] ArbRetryableTx.Cancel test --- precompiles/ArbRetryableTx.go | 1 - system_tests/retryable_test.go | 72 ++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index eab459af42..b4696d5b78 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -195,7 +195,6 @@ func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (add return retryable.Beneficiary() } -// TODO: add test // Cancel the ticket and refund its callvalue to its beneficiary func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { if c.txProcessor.CurrentRetryable != nil && ticketId == *c.txProcessor.CurrentRetryable { diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index aa9fbfd72e..b3038716d7 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -423,6 +423,78 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { } } +func TestCancelRetryable(t *testing.T) { + t.Parallel() + builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) + defer teardown() + + ownerTxOpts := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + usertxopts := builder.L1Info.GetDefaultTransactOpts("Faucet", ctx) + usertxopts.Value = arbmath.BigMul(big.NewInt(1e12), big.NewInt(1e12)) + + simpleAddr, _ := builder.L2.DeploySimple(t, ownerTxOpts) + simpleABI, err := mocksgen.SimpleMetaData.GetAbi() + Require(t, err) + + beneficiaryAddress := builder.L2Info.GetAddress("Beneficiary") + l1tx, err := delayedInbox.CreateRetryableTicket( + &usertxopts, + simpleAddr, + common.Big0, + big.NewInt(1e16), + beneficiaryAddress, + beneficiaryAddress, + // send enough L2 gas for intrinsic but not compute + big.NewInt(int64(params.TxGas+params.TxDataNonZeroGasEIP2028*4)), + big.NewInt(l2pricing.InitialBaseFeeWei*2), + simpleABI.Methods["incrementRedeem"].ID, + ) + Require(t, err) + + l1Receipt, err := builder.L1.EnsureTxSucceeded(l1tx) + Require(t, err) + if l1Receipt.Status != types.ReceiptStatusSuccessful { + Fatal(t, "l1Receipt indicated failure") + } + + waitForL1DelayBlocks(t, builder) + + receipt, err := builder.L2.EnsureTxSucceeded(lookupL2Tx(l1Receipt)) + Require(t, err) + if len(receipt.Logs) != 2 { + Fatal(t, len(receipt.Logs)) + } + ticketId := receipt.Logs[0].Topics[1] + firstRetryTxId := receipt.Logs[1].Topics[2] + + // make sure it failed + receipt, err = WaitForTx(ctx, builder.L2.Client, firstRetryTxId, time.Second*5) + Require(t, err) + if receipt.Status != types.ReceiptStatusFailed { + Fatal(t, receipt.GasUsed) + } + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + + // checks that the ticket exists + _, err = arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) + Require(t, err) + + // cancel the ticket + beneficiaryTxOpts := builder.L2Info.GetDefaultTransactOpts("Beneficiary", ctx) + tx, err := arbRetryableTx.Cancel(&beneficiaryTxOpts, ticketId) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + // checks that the ticket no longer exists + _, err = arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) + if (err == nil) || (err.Error() != "execution reverted: error NoTicketWithID(): NoTicketWithID()") { + Fatal(t, "didn't get expected NoTicketWithID error") + } +} + func TestSubmissionGasCosts(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From 96bd892a1041c11676dd1bb3c07b9dbe4be41e88 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 13:19:03 -0300 Subject: [PATCH 35/82] ArbRetryableTx.Keepalive test --- precompiles/ArbRetryableTx.go | 2 -- system_tests/retryable_test.go | 16 +++++++++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index b4696d5b78..d925499180 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -152,10 +152,8 @@ func (con ArbRetryableTx) GetTimeout(c ctx, evm mech, ticketId bytes32) (huge, e return new(big.Int).SetUint64(timeout), nil } -// TODO: add test // Keepalive adds one lifetime period to the ticket's expiry func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, error) { - // charge for the expiry update retryableState := c.State.RetryableState() nbytes, err := retryableState.RetryableSizeBytes(ticketId, evm.Context.Time) diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index b3038716d7..6651c8ca74 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -423,7 +423,7 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { } } -func TestCancelRetryable(t *testing.T) { +func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) defer teardown() @@ -477,9 +477,19 @@ func TestCancelRetryable(t *testing.T) { arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) Require(t, err) - // checks that the ticket exists - _, err = arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) + // checks that the ticket exists and gets current timeout + timeoutBeforeKeepalive, err := arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) + Require(t, err) + // checks that keepalive increases the timeout as expected + _, err = arbRetryableTx.Keepalive(&ownerTxOpts, ticketId) Require(t, err) + timeoutAfterKeepalive, err := arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) + Require(t, err) + expectedTimeoutAfterKeepAlive := timeoutBeforeKeepalive + expectedTimeoutAfterKeepAlive.Add(expectedTimeoutAfterKeepAlive, big.NewInt(retryables.RetryableLifetimeSeconds)) + if timeoutAfterKeepalive.Cmp(expectedTimeoutAfterKeepAlive) != 0 { + Fatal(t, "expected timeout after keepalive to be", expectedTimeoutAfterKeepAlive, "but got", timeoutAfterKeepalive) + } // cancel the ticket beneficiaryTxOpts := builder.L2Info.GetDefaultTransactOpts("Beneficiary", ctx) From 7993502d0902bd58b2c975f95c20a0b20398b3c8 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 14:46:58 -0300 Subject: [PATCH 36/82] Fixes address comparison --- precompiles/ArbOwner_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/precompiles/ArbOwner_test.go b/precompiles/ArbOwner_test.go index 6d3256ca65..1fc6e679cb 100644 --- a/precompiles/ArbOwner_test.go +++ b/precompiles/ArbOwner_test.go @@ -156,7 +156,7 @@ func TestArbOwner(t *testing.T) { Require(t, err) retrievedNetworkFeeAccount, err := prec.GetNetworkFeeAccount(callCtx, evm) Require(t, err) - if retrievedNetworkFeeAccount != addr1 { + if retrievedNetworkFeeAccount.Cmp(addr1) != 0 { Fail(t, "Expected", addr1, "got", retrievedNetworkFeeAccount) } From bdb8010611f0cba91080f52a36a9c1e18c24f10e Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 14:49:13 -0300 Subject: [PATCH 37/82] Adds missing t.Parallel() --- precompiles/ArbFunctionTable_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/precompiles/ArbFunctionTable_test.go b/precompiles/ArbFunctionTable_test.go index 6a68bffd22..f3c6d97bbf 100644 --- a/precompiles/ArbFunctionTable_test.go +++ b/precompiles/ArbFunctionTable_test.go @@ -12,6 +12,8 @@ import ( ) func TestArbFunctionTable(t *testing.T) { + t.Parallel() + evm := newMockEVMForTesting() ftab := ArbFunctionTable{} context := testContext(common.Address{}, evm) From 9b78b42447ecefc7964b6bcdda926e0e77fa478b Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 14:53:15 -0300 Subject: [PATCH 38/82] Fixes comments --- system_tests/program_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index cda592ee06..dcdd7da60e 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -535,7 +535,7 @@ func testCalls(t *testing.T, jit bool) { defer cleanup() callsAddr := deployWasm(t, ctx, auth, l2client, rustFile("multicall")) - // checks ArbInfo.GetCode works properly + // checks that ArbInfo.GetCode works properly codeFromFile, _ := readWasmFile(t, rustFile("multicall")) arbInfo, err := pgen.NewArbInfo(types.ArbInfoAddress, l2client) Require(t, err) @@ -726,7 +726,7 @@ func testCalls(t *testing.T, jit bool) { Fatal(t, balance, value) } - // checks ArbInfo.GetBalance works properly + // checks that ArbInfo.GetBalance works properly balance, err = arbInfo.GetBalance(nil, eoa) Require(t, err) if !arbmath.BigEquals(balance, value) { From 2a9fe74f415e01a5d3056f08e846d69c58faf8b7 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 15:02:35 -0300 Subject: [PATCH 39/82] Improves arbSys.ArbOSVersion test --- system_tests/precompile_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 780373a0cd..d6382b89cd 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -38,10 +38,11 @@ func TestPurePrecompileMethodCalls(t *testing.T) { Fatal(t, "Wrong ChainID", chainId.Uint64()) } + expectedArbosVersion := 55 + arbosVersion // Nitro versions start at 56 arbSysArbosVersion, err := arbSys.ArbOSVersion(&bind.CallOpts{}) Require(t, err) - if arbSysArbosVersion.Uint64() != 55+arbosVersion { // Nitro versios start at 56 - Fatal(t, "Expected ArbOSVersion 86, got", arbosVersion) + if arbSysArbosVersion.Uint64() != expectedArbosVersion { + Fatal(t, "Expected ArbOS version", expectedArbosVersion, "got", arbSysArbosVersion) } storageGasAvailable, err := arbSys.GetStorageGasAvailable(&bind.CallOpts{}) From 8e8bece8bf5a9e994c397ae3ad780643dae32b8e Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 15:04:10 -0300 Subject: [PATCH 40/82] Fixes comment --- system_tests/precompile_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index d6382b89cd..a8ec863ce0 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -169,7 +169,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } - // GetL1BaseFeeEstimateInertia test, but using a different setter from ArbOwner + // GetL1BaseFeeEstimateInertia test, but now using a different setter from ArbOwner inertia = uint64(12) tx, err = arbOwner.SetL1PricingInertia(&auth, inertia) Require(t, err) From cbf2dc046d5b3b503558534ec67cc33c04a4c74b Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 27 Sep 2024 15:06:21 -0300 Subject: [PATCH 41/82] Fixes comment --- system_tests/precompile_test.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index a8ec863ce0..88df3e0beb 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -205,7 +205,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected reward recipient to be", rewardRecipient, "got", arbGasInfoRewardRecipient) } - // GetPricingInertia + // GetPricingInertia test inertia = uint64(14) tx, err = arbOwner.SetL2GasPricingInertia(&auth, inertia) Require(t, err) @@ -217,7 +217,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } - // GetGasBacklogTolerance + // GetGasBacklogTolerance test gasTolerance := uint64(15) tx, err = arbOwner.SetL2GasBacklogTolerance(&auth, gasTolerance) Require(t, err) @@ -229,7 +229,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected gas tolerance to be", gasTolerance, "got", arbGasInfoGasTolerance) } - // GetPerBatchGasCharge + // GetPerBatchGasCharge test perBatchGasCharge := int64(16) tx, err = arbOwner.SetPerBatchGasCharge(&auth, perBatchGasCharge) Require(t, err) @@ -241,7 +241,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected per batch gas charge to be", perBatchGasCharge, "got", arbGasInfoPerBatchGasCharge) } - // GetL1PricingEquilibrationUnits + // GetL1PricingEquilibrationUnits test equilUnits := big.NewInt(17) tx, err = arbOwner.SetL1PricingEquilibrationUnits(&auth, equilUnits) Require(t, err) @@ -253,7 +253,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected equilibration units to be", equilUnits, "got", arbGasInfoEquilUnits) } - // GetGasAccountingParams + // GetGasAccountingParams test speedLimit := uint64(18) txGasLimit := uint64(19) tx, err = arbOwner.SetSpeedLimit(&auth, speedLimit) @@ -276,6 +276,7 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { Fatal(t, "expected tx gas limit to be", txGasLimit, "got", arbGasInfoTxGasLimit) } + // GetCurrentTxL1GasFees test currTxL1GasFees, err := arbGasInfo.GetCurrentTxL1GasFees(&bind.CallOpts{Context: ctx}) Require(t, err) if currTxL1GasFees == nil { From e891a5444fb6f858151005bd514aa9454e06e950 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 1 Oct 2024 09:18:14 -0300 Subject: [PATCH 42/82] Separate long setter/getter test in multiple test functions --- precompiles/ArbGasInfo_test.go | 77 +++++++++++++---- system_tests/precompile_test.go | 142 ++++++++++++++++++++++++++------ 2 files changed, 175 insertions(+), 44 deletions(-) diff --git a/precompiles/ArbGasInfo_test.go b/precompiles/ArbGasInfo_test.go index 72bc13d71e..260d7b3cef 100644 --- a/precompiles/ArbGasInfo_test.go +++ b/precompiles/ArbGasInfo_test.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbos/arbosState" @@ -18,9 +19,14 @@ import ( "github.com/offchainlabs/nitro/util/testhelpers" ) -func TestArbGasInfo(t *testing.T) { - t.Parallel() - +func setupArbGasInfo( + t *testing.T, +) ( + *vm.EVM, + *arbosState.ArbosState, + *Context, + *ArbGasInfo, +) { evm := newMockEVMForTesting() caller := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) tracer := util.NewTracingInfo(evm, testhelpers.RandomAddress(), types.ArbosAddress, util.TracingDuringEVM) @@ -30,62 +36,97 @@ func TestArbGasInfo(t *testing.T) { arbGasInfo := &ArbGasInfo{} callCtx := testContext(caller, evm) - // GetGasBacklog test + return evm, state, callCtx, arbGasInfo +} + +func TestGetGasBacklog(t *testing.T) { + t.Parallel() + + evm, state, callCtx, arbGasInfo := setupArbGasInfo(t) + backlog := uint64(1000) - err = state.L2PricingState().SetGasBacklog(backlog) + err := state.L2PricingState().SetGasBacklog(backlog) Require(t, err) retrievedBacklog, err := arbGasInfo.GetGasBacklog(callCtx, evm) Require(t, err) if retrievedBacklog != backlog { t.Fatal("expected backlog to be", backlog, "but got", retrievedBacklog) } +} + +func TestGetL1PricingUpdateTime(t *testing.T) { + t.Parallel() + + evm, state, callCtx, arbGasInfo := setupArbGasInfo(t) - // GetLastL1PricingUpdateTime test lastUpdateTime := uint64(1001) - err = state.L1PricingState().SetLastUpdateTime(lastUpdateTime) + err := state.L1PricingState().SetLastUpdateTime(lastUpdateTime) Require(t, err) retrievedLastUpdateTime, err := arbGasInfo.GetLastL1PricingUpdateTime(callCtx, evm) Require(t, err) if retrievedLastUpdateTime != lastUpdateTime { t.Fatal("expected last update time to be", lastUpdateTime, "but got", retrievedLastUpdateTime) } +} + +func TestGetL1PricingFundsDueForRewards(t *testing.T) { + t.Parallel() + + evm, state, callCtx, arbGasInfo := setupArbGasInfo(t) - // GetL1PricingFundsDueForRewards test fundsDueForRewards := big.NewInt(1002) - err = state.L1PricingState().SetFundsDueForRewards(fundsDueForRewards) + err := state.L1PricingState().SetFundsDueForRewards(fundsDueForRewards) Require(t, err) retrievedFundsDueForRewards, err := arbGasInfo.GetL1PricingFundsDueForRewards(callCtx, evm) Require(t, err) if retrievedFundsDueForRewards.Cmp(fundsDueForRewards) != 0 { t.Fatal("expected funds due for rewards to be", fundsDueForRewards, "but got", retrievedFundsDueForRewards) } +} + +func TestGetL1PricingUnitsSinceUpdate(t *testing.T) { + t.Parallel() + + evm, state, callCtx, arbGasInfo := setupArbGasInfo(t) - // GetL1PricingUnitsSinceUpdate test pricingUnitsSinceUpdate := uint64(1003) - err = state.L1PricingState().SetUnitsSinceUpdate(pricingUnitsSinceUpdate) + err := state.L1PricingState().SetUnitsSinceUpdate(pricingUnitsSinceUpdate) Require(t, err) retrievedPricingUnitsSinceUpdate, err := arbGasInfo.GetL1PricingUnitsSinceUpdate(callCtx, evm) Require(t, err) if retrievedPricingUnitsSinceUpdate != pricingUnitsSinceUpdate { t.Fatal("expected pricing units since update to be", pricingUnitsSinceUpdate, "but got", retrievedPricingUnitsSinceUpdate) } +} + +func TestGetLastL1PricingSurplus(t *testing.T) { + t.Parallel() + + evm, state, callCtx, arbGasInfo := setupArbGasInfo(t) - // GetLastL1PricingSurplus test lastSurplus := big.NewInt(1004) - err = state.L1PricingState().SetLastSurplus(lastSurplus, params.ArbosVersion_Stylus) + err := state.L1PricingState().SetLastSurplus(lastSurplus, params.ArbosVersion_Stylus) Require(t, err) retrievedLastSurplus, err := arbGasInfo.GetLastL1PricingSurplus(callCtx, evm) Require(t, err) if retrievedLastSurplus.Cmp(lastSurplus) != 0 { t.Fatal("expected last surplus to be", lastSurplus, "but got", retrievedLastSurplus) } +} + +func TestGetPricesInArbGas(t *testing.T) { + t.Parallel() + + evm := newMockEVMForTesting() + caller := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + arbGasInfo := &ArbGasInfo{} + callCtx := testContext(caller, evm) - // GetPricesInArbGas test evm.Context.BaseFee = big.NewInt(1005) expectedGasPerL2Tx := big.NewInt(111442786069) expectedGasForL1Calldata := big.NewInt(796019900) - expectedStorageArgGas := big.NewInt(int64(storage.StorageWriteCost)) - gasPerL2Tx, gasForL1Calldata, storageArgGas, err := arbGasInfo.GetPricesInArbGas(callCtx, evm) + expectedStorageArbGas := big.NewInt(int64(storage.StorageWriteCost)) + gasPerL2Tx, gasForL1Calldata, storageArbGas, err := arbGasInfo.GetPricesInArbGas(callCtx, evm) Require(t, err) if gasPerL2Tx.Cmp(expectedGasPerL2Tx) != 0 { t.Fatal("expected gas per L2 tx to be", expectedGasPerL2Tx, "but got", gasPerL2Tx) @@ -93,7 +134,7 @@ func TestArbGasInfo(t *testing.T) { if gasForL1Calldata.Cmp(expectedGasForL1Calldata) != 0 { t.Fatal("expected gas for L1 calldata to be", expectedGasForL1Calldata, "but got", gasForL1Calldata) } - if storageArgGas.Cmp(expectedStorageArgGas) != 0 { - t.Fatal("expected storage arg gas to be", expectedStorageArgGas, "but got", storageArgGas) + if storageArbGas.Cmp(expectedStorageArbGas) != 0 { + t.Fatal("expected storage arb gas to be", expectedStorageArbGas, "but got", storageArbGas) } } diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 88df3e0beb..2b979f0dfd 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -142,13 +142,24 @@ func TestPrecompileErrorGasLeft(t *testing.T) { assertNotAllGasConsumed(common.HexToAddress("0xff"), arbDebug.Methods["legacyError"].ID) } -func TestArbGasInfoAndArbOwner(t *testing.T) { +func setupArbOwnerAndArbGasInfo( + t *testing.T, +) ( + *NodeBuilder, + func(), + bind.TransactOpts, + *precompilesgen.ArbOwner, + *precompilesgen.ArbGasInfo, +) { ctx, cancel := context.WithCancel(context.Background()) - defer cancel() builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() + builderCleanup := builder.Build(t) + + cleanup := func() { + builderCleanup() + cancel() + } auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) @@ -157,7 +168,16 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), builder.L2.Client) Require(t, err) - // GetL1BaseFeeEstimateInertia test + return builder, cleanup, auth, arbOwner, arbGasInfo +} + +func TestL1BaseFeeEstimateInertia(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx + inertia := uint64(11) tx, err := arbOwner.SetL1BaseFeeEstimateInertia(&auth, inertia) Require(t, err) @@ -168,22 +188,37 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoInertia != inertia { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } +} + +// Similar to TestL1BaseFeeEstimateInertia, but now using a different setter from ArbOwner +func TestL1PricingInertia(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetL1BaseFeeEstimateInertia test, but now using a different setter from ArbOwner - inertia = uint64(12) - tx, err = arbOwner.SetL1PricingInertia(&auth, inertia) + inertia := uint64(12) + tx, err := arbOwner.SetL1PricingInertia(&auth, inertia) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) - arbGasInfoInertia, err = arbGasInfo.GetL1BaseFeeEstimateInertia(&bind.CallOpts{Context: ctx}) + arbGasInfoInertia, err := arbGasInfo.GetL1BaseFeeEstimateInertia(&bind.CallOpts{Context: ctx}) Require(t, err) if arbGasInfoInertia != inertia { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } +} + +func TestL1PricingRewardRate(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetL1RewardRate test perUnitReward := uint64(13) - tx, err = arbOwner.SetL1PricingRewardRate(&auth, perUnitReward) + tx, err := arbOwner.SetL1PricingRewardRate(&auth, perUnitReward) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -192,10 +227,17 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoPerUnitReward != perUnitReward { Fatal(t, "expected per unit reward to be", perUnitReward, "got", arbGasInfoPerUnitReward) } +} + +func TestL1PricingRewardRecipient(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetL1RewardRecipient test rewardRecipient := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - tx, err = arbOwner.SetL1PricingRewardRecipient(&auth, rewardRecipient) + tx, err := arbOwner.SetL1PricingRewardRecipient(&auth, rewardRecipient) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -204,22 +246,36 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoRewardRecipient.Cmp(rewardRecipient) != 0 { Fatal(t, "expected reward recipient to be", rewardRecipient, "got", arbGasInfoRewardRecipient) } +} + +func TestL2GasPricingInertia(t *testing.T) { + t.Parallel() - // GetPricingInertia test - inertia = uint64(14) - tx, err = arbOwner.SetL2GasPricingInertia(&auth, inertia) + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx + + inertia := uint64(14) + tx, err := arbOwner.SetL2GasPricingInertia(&auth, inertia) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) - arbGasInfoInertia, err = arbGasInfo.GetPricingInertia(&bind.CallOpts{Context: ctx}) + arbGasInfoInertia, err := arbGasInfo.GetPricingInertia(&bind.CallOpts{Context: ctx}) Require(t, err) if arbGasInfoInertia != inertia { Fatal(t, "expected inertia to be", inertia, "got", arbGasInfoInertia) } +} + +func TestL2GasBacklogTolerance(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetGasBacklogTolerance test gasTolerance := uint64(15) - tx, err = arbOwner.SetL2GasBacklogTolerance(&auth, gasTolerance) + tx, err := arbOwner.SetL2GasBacklogTolerance(&auth, gasTolerance) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -228,10 +284,17 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoGasTolerance != gasTolerance { Fatal(t, "expected gas tolerance to be", gasTolerance, "got", arbGasInfoGasTolerance) } +} + +func TestPerBatchGasCharge(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetPerBatchGasCharge test perBatchGasCharge := int64(16) - tx, err = arbOwner.SetPerBatchGasCharge(&auth, perBatchGasCharge) + tx, err := arbOwner.SetPerBatchGasCharge(&auth, perBatchGasCharge) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -240,10 +303,17 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoPerBatchGasCharge != perBatchGasCharge { Fatal(t, "expected per batch gas charge to be", perBatchGasCharge, "got", arbGasInfoPerBatchGasCharge) } +} + +func TestL1PricingEquilibrationUnits(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetL1PricingEquilibrationUnits test equilUnits := big.NewInt(17) - tx, err = arbOwner.SetL1PricingEquilibrationUnits(&auth, equilUnits) + tx, err := arbOwner.SetL1PricingEquilibrationUnits(&auth, equilUnits) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -252,11 +322,18 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoEquilUnits.Cmp(equilUnits) != 0 { Fatal(t, "expected equilibration units to be", equilUnits, "got", arbGasInfoEquilUnits) } +} + +func TestGasAccountingParams(t *testing.T) { + t.Parallel() + + builder, cleanup, auth, arbOwner, arbGasInfo := setupArbOwnerAndArbGasInfo(t) + defer cleanup() + ctx := builder.ctx - // GetGasAccountingParams test speedLimit := uint64(18) txGasLimit := uint64(19) - tx, err = arbOwner.SetSpeedLimit(&auth, speedLimit) + tx, err := arbOwner.SetSpeedLimit(&auth, speedLimit) Require(t, err) _, err = builder.L2.EnsureTxSucceeded(tx) Require(t, err) @@ -275,8 +352,21 @@ func TestArbGasInfoAndArbOwner(t *testing.T) { if arbGasInfoTxGasLimit.Cmp(big.NewInt(int64(txGasLimit))) != 0 { Fatal(t, "expected tx gas limit to be", txGasLimit, "got", arbGasInfoTxGasLimit) } +} + +func TestCurrentTxL1GasFees(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), builder.L2.Client) + Require(t, err) - // GetCurrentTxL1GasFees test currTxL1GasFees, err := arbGasInfo.GetCurrentTxL1GasFees(&bind.CallOpts{Context: ctx}) Require(t, err) if currTxL1GasFees == nil { From 38e2180c58e66b32a2d96abc79feb750d1dae993 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 11 Oct 2024 10:24:49 -0300 Subject: [PATCH 43/82] Comments to precompile functions that needs to be tested as system tests --- precompiles/ArbAddressTable.go | 7 +++++++ precompiles/ArbAggregator.go | 7 +++++++ precompiles/ArbDebug.go | 2 ++ precompiles/ArbFunctionTable.go | 3 +++ precompiles/ArbGasInfo.go | 10 ++++++++++ precompiles/ArbOwner.go | 9 +++++++++ precompiles/ArbOwnerPublic.go | 2 ++ precompiles/ArbRetryableTx.go | 4 ++++ precompiles/ArbStatistics.go | 1 + precompiles/ArbSys.go | 3 ++- precompiles/ArbosActs.go | 2 ++ precompiles/ArbosTest.go | 1 + 12 files changed, 50 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbAddressTable.go b/precompiles/ArbAddressTable.go index 102fd55c3b..45b708bd7d 100644 --- a/precompiles/ArbAddressTable.go +++ b/precompiles/ArbAddressTable.go @@ -13,16 +13,19 @@ type ArbAddressTable struct { Address addr // 0x66 } +// TODO: add system test // AddressExists checks if an address exists in the table func (con ArbAddressTable) AddressExists(c ctx, evm mech, addr addr) (bool, error) { return c.State.AddressTable().AddressExists(addr) } +// TODO: add system test // Compress and returns the bytes that represent the address func (con ArbAddressTable) Compress(c ctx, evm mech, addr addr) ([]uint8, error) { return c.State.AddressTable().Compress(addr) } +// TODO: add system test // Decompress the compressed bytes at the given offset with those of the corresponding account func (con ArbAddressTable) Decompress(c ctx, evm mech, buf []uint8, offset huge) (addr, huge, error) { if !offset.IsInt64() { @@ -36,6 +39,7 @@ func (con ArbAddressTable) Decompress(c ctx, evm mech, buf []uint8, offset huge) return result, new(big.Int).SetUint64(nbytes), err } +// TODO: add system test // Lookup the index of an address in the table func (con ArbAddressTable) Lookup(c ctx, evm mech, addr addr) (huge, error) { result, exists, err := c.State.AddressTable().Lookup(addr) @@ -48,6 +52,7 @@ func (con ArbAddressTable) Lookup(c ctx, evm mech, addr addr) (huge, error) { return new(big.Int).SetUint64(result), nil } +// TODO: add system test // LookupIndex for an address in the table by index func (con ArbAddressTable) LookupIndex(c ctx, evm mech, index huge) (addr, error) { if !index.IsUint64() { @@ -63,12 +68,14 @@ func (con ArbAddressTable) LookupIndex(c ctx, evm mech, index huge) (addr, error return result, nil } +// TODO: add system test // Register adds an account to the table, shrinking its compressed representation func (con ArbAddressTable) Register(c ctx, evm mech, addr addr) (huge, error) { slot, err := c.State.AddressTable().Register(addr) return new(big.Int).SetUint64(slot), err } +// TODO: add system test // Size gets the number of addresses in the table func (con ArbAddressTable) Size(c ctx, evm mech) (huge, error) { size, err := c.State.AddressTable().Size() diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index b74e280fe8..c3ee19c12c 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -19,12 +19,14 @@ type ArbAggregator struct { var ErrNotOwner = errors.New("must be called by chain owner") +// TODO: add system test // GetPreferredAggregator returns the preferred aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetPreferredAggregator(c ctx, evm mech, address addr) (prefAgg addr, isDefault bool, err error) { return l1pricing.BatchPosterAddress, true, err } +// TODO: add system test // GetDefaultAggregator returns the default aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetDefaultAggregator(c ctx, evm mech) (addr, error) { @@ -36,6 +38,7 @@ func (con ArbAggregator) GetBatchPosters(c ctx, evm mech) ([]addr, error) { return c.State.L1PricingState().BatchPosterTable().AllPosters(65536) } +// TODO: add system test func (con ArbAggregator) AddBatchPoster(c ctx, evm mech, newBatchPoster addr) error { isOwner, err := c.State.ChainOwners().IsMember(c.caller) if err != nil { @@ -58,6 +61,7 @@ func (con ArbAggregator) AddBatchPoster(c ctx, evm mech, newBatchPoster addr) er return nil } +// TODO: add system test // GetFeeCollector gets a batch poster's fee collector func (con ArbAggregator) GetFeeCollector(c ctx, evm mech, batchPoster addr) (addr, error) { posterInfo, err := c.State.L1PricingState().BatchPosterTable().OpenPoster(batchPoster, false) @@ -67,6 +71,7 @@ func (con ArbAggregator) GetFeeCollector(c ctx, evm mech, batchPoster addr) (add return posterInfo.PayTo() } +// TODO: add system test // SetFeeCollector sets a batch poster's fee collector (caller must be the batch poster, its fee collector, or an owner) func (con ArbAggregator) SetFeeCollector(c ctx, evm mech, batchPoster addr, newFeeCollector addr) error { posterInfo, err := c.State.L1PricingState().BatchPosterTable().OpenPoster(batchPoster, false) @@ -89,12 +94,14 @@ func (con ArbAggregator) SetFeeCollector(c ctx, evm mech, batchPoster addr, newF return posterInfo.SetPayTo(newFeeCollector) } +// TODO: add system test // GetTxBaseFee gets an aggregator's current fixed fee to submit a tx func (con ArbAggregator) GetTxBaseFee(c ctx, evm mech, aggregator addr) (huge, error) { // This is deprecated and now always returns zero. return big.NewInt(0), nil } +// TODO: add system test // SetTxBaseFee sets an aggregator's fixed fee (caller must be the aggregator, its fee collector, or an owner) func (con ArbAggregator) SetTxBaseFee(c ctx, evm mech, aggregator addr, feeInL1Gas huge) error { // This is deprecated and is now a no-op. diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index bf85d5e18f..9bfc8c9815 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -56,11 +56,13 @@ func (con ArbDebug) BecomeChainOwner(c ctx, evm mech) error { return c.State.ChainOwners().Add(c.caller) } +// TODO: add system test // Halts the chain by panicking in the STF func (con ArbDebug) Panic(c ctx, evm mech) error { panic("called ArbDebug's debug-only Panic method") } +// TODO: add system test func (con ArbDebug) LegacyError(c ctx) error { return errors.New("example legacy error") } diff --git a/precompiles/ArbFunctionTable.go b/precompiles/ArbFunctionTable.go index a870995e0f..e7091813db 100644 --- a/precompiles/ArbFunctionTable.go +++ b/precompiles/ArbFunctionTable.go @@ -15,16 +15,19 @@ type ArbFunctionTable struct { Address addr // 0x68 } +// TODO: add system test // Upload does nothing func (con ArbFunctionTable) Upload(c ctx, evm mech, buf []byte) error { return nil } +// TODO: add system test // Size returns the empty table's size, which is 0 func (con ArbFunctionTable) Size(c ctx, evm mech, addr addr) (huge, error) { return big.NewInt(0), nil } +// TODO: add system test // Get reverts since the table is empty func (con ArbFunctionTable) Get(c ctx, evm mech, addr addr, index huge) (huge, bool, huge, error) { return nil, false, nil, errors.New("table is empty") diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index b41dfda8a2..c738f0fa37 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -22,6 +22,7 @@ var storageArbGas = big.NewInt(int64(storage.StorageWriteCost)) const AssumedSimpleTxSize = 140 +// TODO: add system test // GetPricesInWeiWithAggregator gets prices in wei when using the provided aggregator func (con ArbGasInfo) GetPricesInWeiWithAggregator( c ctx, @@ -102,6 +103,7 @@ func (con ArbGasInfo) GetPricesInWei(c ctx, evm mech) (huge, huge, huge, huge, h return con.GetPricesInWeiWithAggregator(c, evm, addr{}) } +// TODO: add system test // GetPricesInArbGasWithAggregator gets prices in ArbGas when using the provided aggregator func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { if c.State.ArbOSVersion() < 4 { @@ -154,6 +156,7 @@ func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm me return perL2Tx, gasForL1Calldata, storageArbGas, nil } +// TODO: add system test // GetPricesInArbGas gets prices in ArbGas when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInArbGas(c ctx, evm mech) (huge, huge, huge, error) { return con.GetPricesInArbGasWithAggregator(c, evm, addr{}) @@ -192,6 +195,7 @@ func (con ArbGasInfo) GetL1RewardRecipient(c ctx, evm mech) (common.Address, err return c.State.L1PricingState().PayRewardsTo() } +// TODO: add system test // GetL1GasPriceEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1GasPriceEstimate(c ctx, evm mech) (huge, error) { return con.GetL1BaseFeeEstimate(c, evm) @@ -246,11 +250,13 @@ func (con ArbGasInfo) GetPerBatchGasCharge(c ctx, evm mech) (int64, error) { return c.State.L1PricingState().PerBatchGasCost() } +// TODO: add system test // GetAmortizedCostCapBips gets the cost amortization cap in basis points func (con ArbGasInfo) GetAmortizedCostCapBips(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().AmortizedCostCapBips() } +// TODO: add system test // GetL1FeesAvailable gets the available funds from L1 fees func (con ArbGasInfo) GetL1FeesAvailable(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().L1FeesAvailable() @@ -261,21 +267,25 @@ func (con ArbGasInfo) GetL1PricingEquilibrationUnits(c ctx, evm mech) (*big.Int, return c.State.L1PricingState().EquilibrationUnits() } +// TODO: add system test // GetLastL1PricingUpdateTime gets the last time the L1 calldata pricer was updated func (con ArbGasInfo) GetLastL1PricingUpdateTime(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().LastUpdateTime() } +// TODO: add system test // GetL1PricingFundsDueForRewards gets the amount of L1 calldata payments due for rewards (per the L1 reward rate) func (con ArbGasInfo) GetL1PricingFundsDueForRewards(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().FundsDueForRewards() } +// TODO: add system test // GetL1PricingUnitsSinceUpdate gets the amount of L1 calldata posted since the last update func (con ArbGasInfo) GetL1PricingUnitsSinceUpdate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().UnitsSinceUpdate() } +// TODO: add system test // GetLastL1PricingSurplus gets the L1 pricing surplus as of the last update (may be negative) func (con ArbGasInfo) GetLastL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().LastSurplus() diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 8b87445e0e..7387b62a62 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -33,11 +33,13 @@ var ( ErrOutOfBounds = errors.New("value out of bounds") ) +// TODO: add system test // AddChainOwner adds account as a chain owner func (con ArbOwner) AddChainOwner(c ctx, evm mech, newOwner addr) error { return c.State.ChainOwners().Add(newOwner) } +// TODO: add system test // RemoveChainOwner removes account from the list of chain owners func (con ArbOwner) RemoveChainOwner(c ctx, evm mech, addr addr) error { member, _ := con.IsChainOwner(c, evm, addr) @@ -52,6 +54,7 @@ func (con ArbOwner) IsChainOwner(c ctx, evm mech, addr addr) (bool, error) { return c.State.ChainOwners().IsMember(addr) } +// TODO: add system test // GetAllChainOwners retrieves the list of chain owners func (con ArbOwner) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) { return c.State.ChainOwners().AllMembers(65536) @@ -62,6 +65,7 @@ func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) return c.State.L1PricingState().SetInertia(inertia) } +// TODO: add system test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) @@ -95,11 +99,13 @@ func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error return c.State.L2PricingState().SetBacklogTolerance(sec) } +// TODO: add system test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() } +// TODO: add system test // GetInfraFeeAccount gets the infrastructure fee collector func (con ArbOwner) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() @@ -144,6 +150,7 @@ func (con ArbOwner) SetPerBatchGasCharge(c ctx, evm mech, cost int64) error { return c.State.L1PricingState().SetPerBatchGasCost(cost) } +// TODO: add system test func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error { return c.State.L1PricingState().SetAmortizedCostCapBips(cap) } @@ -152,6 +159,7 @@ func (con ArbOwner) SetBrotliCompressionLevel(c ctx, evm mech, level uint64) err return c.State.SetBrotliCompressionLevel(level) } +// TODO: add system test func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease huge) (huge, error) { balance := evm.StateDB.GetBalance(l1pricing.L1PricerFundsPoolAddress) l1p := c.State.L1PricingState() @@ -295,6 +303,7 @@ func (con ArbOwner) RemoveWasmCacheManager(c ctx, _ mech, manager addr) error { return managers.Remove(manager, c.State.ArbOSVersion()) } +// TODO: add system test func (con ArbOwner) SetChainConfig(c ctx, evm mech, serializedChainConfig []byte) error { if c == nil { return errors.New("nil context") diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index 451e18e1cc..d901c77f12 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -16,11 +16,13 @@ type ArbOwnerPublic struct { ChainOwnerRectifiedGasCost func(addr) (uint64, error) } +// TODO: add system test // GetAllChainOwners retrieves the list of chain owners func (con ArbOwnerPublic) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) { return c.State.ChainOwners().AllMembers(65536) } +// TODO: add system test // RectifyChainOwner checks if the account is a chain owner func (con ArbOwnerPublic) RectifyChainOwner(c ctx, evm mech, addr addr) error { err := c.State.ChainOwners().RectifyMapping(addr) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index d925499180..dac112e1bd 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -130,6 +130,7 @@ func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, er return retryTxHash, c.State.L2PricingState().AddToGasPool(arbmath.SaturatingCast[int64](gasToDonate)) } +// TODO: add system test // GetLifetime gets the default lifetime period a retryable has at creation func (con ArbRetryableTx) GetLifetime(c ctx, evm mech) (huge, error) { return big.NewInt(retryables.RetryableLifetimeSeconds), nil @@ -180,6 +181,7 @@ func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, er return bigNewTimeout, err } +// TODO: add system test // GetBeneficiary gets the beneficiary of the ticket func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (addr, error) { retryableState := c.State.RetryableState() @@ -222,6 +224,7 @@ func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { return con.Canceled(c, evm, ticketId) } +// TODO: add system test func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, error) { if c.txProcessor.CurrentRefundTo != nil { return *c.txProcessor.CurrentRefundTo, nil @@ -229,6 +232,7 @@ func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, e return common.Address{}, nil } +// TODO: add system test func (con ArbRetryableTx) SubmitRetryable( c ctx, evm mech, requestId bytes32, l1BaseFee, deposit, callvalue, gasFeeCap huge, gasLimit uint64, maxSubmissionFee huge, diff --git a/precompiles/ArbStatistics.go b/precompiles/ArbStatistics.go index 83f867d09d..c4b6a39344 100644 --- a/precompiles/ArbStatistics.go +++ b/precompiles/ArbStatistics.go @@ -14,6 +14,7 @@ type ArbStatistics struct { Address addr // 0x6e } +// TODO: add system test // GetStats returns the current block number and some statistics about the rollup's pre-Nitro state func (con ArbStatistics) GetStats(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { blockNum := evm.Context.BlockNumber diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index d55067a09c..f48573fafe 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -75,6 +75,7 @@ func (con *ArbSys) IsTopLevelCall(c ctx, evm mech) (bool, error) { return evm.Depth() <= 2, nil } +// TODO: add system test // MapL1SenderContractAddressToL2Alias gets the contract's L2 alias func (con *ArbSys) MapL1SenderContractAddressToL2Alias(c ctx, sender addr, dest addr) (addr, error) { return util.RemapL1Address(sender), nil @@ -92,7 +93,6 @@ func (con *ArbSys) WasMyCallersAddressAliased(c ctx, evm mech) (bool, error) { // MyCallersAddressWithoutAliasing gets the caller's caller without any potential aliasing func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error) { - address := addr{} if evm.Depth() > 1 { @@ -106,6 +106,7 @@ func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error return address, err } +// TODO: add system test // SendTxToL1 sends a transaction to L1, adding it to the outbox func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, calldataForL1 []byte) (huge, error) { l1BlockNum, err := c.txProcessor.L1BlockNumber(vm.BlockContext{}) diff --git a/precompiles/ArbosActs.go b/precompiles/ArbosActs.go index e18aa43efb..45808f35a8 100644 --- a/precompiles/ArbosActs.go +++ b/precompiles/ArbosActs.go @@ -11,10 +11,12 @@ type ArbosActs struct { CallerNotArbOSError func() error } +// TODO: add system test func (con ArbosActs) StartBlock(c ctx, evm mech, l1BaseFee huge, l1BlockNumber, l2BlockNumber, timeLastBlock uint64) error { return con.CallerNotArbOSError() } +// TODO: add system test func (con ArbosActs) BatchPostingReport(c ctx, evm mech, batchTimestamp huge, batchPosterAddress addr, batchNumber uint64, batchDataGas uint64, l1BaseFeeWei huge) error { return con.CallerNotArbOSError() } diff --git a/precompiles/ArbosTest.go b/precompiles/ArbosTest.go index 6e988f533a..8a770ea339 100644 --- a/precompiles/ArbosTest.go +++ b/precompiles/ArbosTest.go @@ -12,6 +12,7 @@ type ArbosTest struct { Address addr // 0x69 } +// TODO: add system test // BurnArbGas unproductively burns the amount of L2 ArbGas func (con ArbosTest) BurnArbGas(c ctx, gasAmount huge) error { if !gasAmount.IsUint64() { From f9d877df0ac2397b878397aec4e559f9cbe89b30 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 11 Oct 2024 11:31:16 -0300 Subject: [PATCH 44/82] Moves TestArbStatistics to system_tests --- precompiles/ArbStatistics.go | 1 - precompiles/ArbStatistics_test.go | 22 ---------------------- system_tests/precompile_test.go | 24 ++++++++++++++++++++++++ 3 files changed, 24 insertions(+), 23 deletions(-) delete mode 100644 precompiles/ArbStatistics_test.go diff --git a/precompiles/ArbStatistics.go b/precompiles/ArbStatistics.go index c4b6a39344..83f867d09d 100644 --- a/precompiles/ArbStatistics.go +++ b/precompiles/ArbStatistics.go @@ -14,7 +14,6 @@ type ArbStatistics struct { Address addr // 0x6e } -// TODO: add system test // GetStats returns the current block number and some statistics about the rollup's pre-Nitro state func (con ArbStatistics) GetStats(c ctx, evm mech) (huge, huge, huge, huge, huge, huge, error) { blockNum := evm.Context.BlockNumber diff --git a/precompiles/ArbStatistics_test.go b/precompiles/ArbStatistics_test.go deleted file mode 100644 index 9787752906..0000000000 --- a/precompiles/ArbStatistics_test.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2021-2024, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE - -package precompiles - -import ( - "testing" - - "github.com/ethereum/go-ethereum/common" -) - -func TestArbStatistics(t *testing.T) { - evm := newMockEVMForTesting() - stats := ArbStatistics{} - context := testContext(common.Address{}, evm) - - blockNum, _, _, _, _, _, err := stats.GetStats(context, evm) - Require(t, err) - if blockNum.Cmp(evm.Context.BlockNumber) != 0 { - t.Error("Unexpected block number") - } -} diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 2b979f0dfd..5b9b89a91b 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -11,6 +11,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "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/nitro/arbos" @@ -460,3 +461,26 @@ func TestScheduleArbosUpgrade(t *testing.T) { t.Errorf("expected upgrade to be scheduled for version %v timestamp %v, got version %v timestamp %v", testVersion, testTimestamp, scheduled.ArbosVersion, scheduled.ScheduledForTimestamp) } } + +func TestArbStatistics(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + arbStatistics, err := precompilesgen.NewArbStatistics(types.ArbStatisticsAddress, builder.L2.Client) + Require(t, err) + + callOpts := &bind.CallOpts{Context: ctx} + blockNum, _, _, _, _, _, err := arbStatistics.GetStats(callOpts) + Require(t, err) + + expectedBlockNum, err := builder.L2.Client.BlockNumber(ctx) + Require(t, err) + + if blockNum.Uint64() != expectedBlockNum { + Fatal(t, "expected block number to be", expectedBlockNum, "got", blockNum) + } +} From 0b524822c93f577dff5fef270ea1f460ae478e2a Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 11 Oct 2024 13:10:43 -0300 Subject: [PATCH 45/82] Moves TestArbFunctionTable to system_tests --- precompiles/ArbFunctionTable.go | 3 --- precompiles/ArbFunctionTable_test.go | 37 --------------------------- system_tests/precompile_test.go | 38 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 40 deletions(-) delete mode 100644 precompiles/ArbFunctionTable_test.go diff --git a/precompiles/ArbFunctionTable.go b/precompiles/ArbFunctionTable.go index e7091813db..a870995e0f 100644 --- a/precompiles/ArbFunctionTable.go +++ b/precompiles/ArbFunctionTable.go @@ -15,19 +15,16 @@ type ArbFunctionTable struct { Address addr // 0x68 } -// TODO: add system test // Upload does nothing func (con ArbFunctionTable) Upload(c ctx, evm mech, buf []byte) error { return nil } -// TODO: add system test // Size returns the empty table's size, which is 0 func (con ArbFunctionTable) Size(c ctx, evm mech, addr addr) (huge, error) { return big.NewInt(0), nil } -// TODO: add system test // Get reverts since the table is empty func (con ArbFunctionTable) Get(c ctx, evm mech, addr addr, index huge) (huge, bool, huge, error) { return nil, false, nil, errors.New("table is empty") diff --git a/precompiles/ArbFunctionTable_test.go b/precompiles/ArbFunctionTable_test.go deleted file mode 100644 index f3c6d97bbf..0000000000 --- a/precompiles/ArbFunctionTable_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2021-2024, Offchain Labs, Inc. -// For license information, see https://github.com/nitro/blob/master/LICENSE - -package precompiles - -import ( - "math/big" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -func TestArbFunctionTable(t *testing.T) { - t.Parallel() - - evm := newMockEVMForTesting() - ftab := ArbFunctionTable{} - context := testContext(common.Address{}, evm) - - addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - - // should be a noop - err := ftab.Upload(context, evm, []byte{0, 0, 0, 0}) - Require(t, err) - - size, err := ftab.Size(context, evm, addr) - Require(t, err) - if size.Cmp(big.NewInt(0)) != 0 { - t.Fatal("Size should be 0") - } - - _, _, _, err = ftab.Get(context, evm, addr, big.NewInt(10)) - if err == nil { - t.Fatal("Should error") - } -} diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 5b9b89a91b..ea07427221 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -463,6 +463,8 @@ func TestScheduleArbosUpgrade(t *testing.T) { } func TestArbStatistics(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -484,3 +486,39 @@ func TestArbStatistics(t *testing.T) { Fatal(t, "expected block number to be", expectedBlockNum, "got", blockNum) } } + +func TestArbFunctionTable(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbFunctionTable, err := precompilesgen.NewArbFunctionTable(types.ArbFunctionTableAddress, builder.L2.Client) + Require(t, err) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + // should be a noop + tx, err := arbFunctionTable.Upload(&auth, []byte{0, 0, 0, 0}) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + size, err := arbFunctionTable.Size(callOpts, addr) + Require(t, err) + if size.Cmp(big.NewInt(0)) != 0 { + t.Fatal("Size should be 0") + } + + _, _, _, err = arbFunctionTable.Get(callOpts, addr, big.NewInt(10)) + if err == nil { + t.Fatal("Should error") + } +} From da7958e08b7d346a93925bee8c5120bd60bbfef1 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 10:05:30 -0300 Subject: [PATCH 46/82] ArbGasInfo.GetL1GasPriceEstimate test --- precompiles/ArbGasInfo.go | 1 - system_tests/fees_test.go | 6 ++++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index c738f0fa37..abe0f53588 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -195,7 +195,6 @@ func (con ArbGasInfo) GetL1RewardRecipient(c ctx, evm mech) (common.Address, err return c.State.L1PricingState().PayRewardsTo() } -// TODO: add system test // GetL1GasPriceEstimate gets the current estimate of the L1 basefee func (con ArbGasInfo) GetL1GasPriceEstimate(c ctx, evm mech) (huge, error) { return con.GetL1BaseFeeEstimate(c, evm) diff --git a/system_tests/fees_test.go b/system_tests/fees_test.go index ccca82e009..76de23e2cb 100644 --- a/system_tests/fees_test.go +++ b/system_tests/fees_test.go @@ -55,6 +55,12 @@ func TestSequencerFeePaid(t *testing.T) { l1Estimate, err := arbGasInfo.GetL1BaseFeeEstimate(callOpts) Require(t, err) + l1EstimateThroughGetL1GasPriceEstimate, err := arbGasInfo.GetL1GasPriceEstimate(callOpts) + Require(t, err) + if !arbmath.BigEquals(l1Estimate, l1EstimateThroughGetL1GasPriceEstimate) { + Fatal(t, "GetL1BaseFeeEstimate and GetL1GasPriceEstimate should return the same value") + } + baseFee := builder.L2.GetBaseFee(t) builder.L2Info.GasPrice = baseFee From 4e109349a5aee4b1568889e26d6d183d7ccdf6f1 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 10:13:53 -0300 Subject: [PATCH 47/82] TestArbGasInfoDoesntRevert --- precompiles/ArbGasInfo.go | 9 ------- system_tests/precompile_test.go | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/precompiles/ArbGasInfo.go b/precompiles/ArbGasInfo.go index abe0f53588..b41dfda8a2 100644 --- a/precompiles/ArbGasInfo.go +++ b/precompiles/ArbGasInfo.go @@ -22,7 +22,6 @@ var storageArbGas = big.NewInt(int64(storage.StorageWriteCost)) const AssumedSimpleTxSize = 140 -// TODO: add system test // GetPricesInWeiWithAggregator gets prices in wei when using the provided aggregator func (con ArbGasInfo) GetPricesInWeiWithAggregator( c ctx, @@ -103,7 +102,6 @@ func (con ArbGasInfo) GetPricesInWei(c ctx, evm mech) (huge, huge, huge, huge, h return con.GetPricesInWeiWithAggregator(c, evm, addr{}) } -// TODO: add system test // GetPricesInArbGasWithAggregator gets prices in ArbGas when using the provided aggregator func (con ArbGasInfo) GetPricesInArbGasWithAggregator(c ctx, evm mech, aggregator addr) (huge, huge, huge, error) { if c.State.ArbOSVersion() < 4 { @@ -156,7 +154,6 @@ func (con ArbGasInfo) _preVersion4_GetPricesInArbGasWithAggregator(c ctx, evm me return perL2Tx, gasForL1Calldata, storageArbGas, nil } -// TODO: add system test // GetPricesInArbGas gets prices in ArbGas when using the caller's preferred aggregator func (con ArbGasInfo) GetPricesInArbGas(c ctx, evm mech) (huge, huge, huge, error) { return con.GetPricesInArbGasWithAggregator(c, evm, addr{}) @@ -249,13 +246,11 @@ func (con ArbGasInfo) GetPerBatchGasCharge(c ctx, evm mech) (int64, error) { return c.State.L1PricingState().PerBatchGasCost() } -// TODO: add system test // GetAmortizedCostCapBips gets the cost amortization cap in basis points func (con ArbGasInfo) GetAmortizedCostCapBips(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().AmortizedCostCapBips() } -// TODO: add system test // GetL1FeesAvailable gets the available funds from L1 fees func (con ArbGasInfo) GetL1FeesAvailable(c ctx, evm mech) (huge, error) { return c.State.L1PricingState().L1FeesAvailable() @@ -266,25 +261,21 @@ func (con ArbGasInfo) GetL1PricingEquilibrationUnits(c ctx, evm mech) (*big.Int, return c.State.L1PricingState().EquilibrationUnits() } -// TODO: add system test // GetLastL1PricingUpdateTime gets the last time the L1 calldata pricer was updated func (con ArbGasInfo) GetLastL1PricingUpdateTime(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().LastUpdateTime() } -// TODO: add system test // GetL1PricingFundsDueForRewards gets the amount of L1 calldata payments due for rewards (per the L1 reward rate) func (con ArbGasInfo) GetL1PricingFundsDueForRewards(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().FundsDueForRewards() } -// TODO: add system test // GetL1PricingUnitsSinceUpdate gets the amount of L1 calldata posted since the last update func (con ArbGasInfo) GetL1PricingUnitsSinceUpdate(c ctx, evm mech) (uint64, error) { return c.State.L1PricingState().UnitsSinceUpdate() } -// TODO: add system test // GetLastL1PricingSurplus gets the L1 pricing surplus as of the last update (may be negative) func (con ArbGasInfo) GetLastL1PricingSurplus(c ctx, evm mech) (*big.Int, error) { return c.State.L1PricingState().LastSurplus() diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index ea07427221..f354fdd8c3 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -522,3 +522,48 @@ func TestArbFunctionTable(t *testing.T) { t.Fatal("Should error") } } + +func TestArbGasInfoDoesntRevert(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + arbGasInfo, err := precompilesgen.NewArbGasInfo(types.ArbGasInfoAddress, builder.L2.Client) + Require(t, err) + + _, err = arbGasInfo.GetGasBacklog(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetLastL1PricingUpdateTime(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1PricingFundsDueForRewards(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1PricingUnitsSinceUpdate(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetLastL1PricingSurplus(callOpts) + Require(t, err) + + _, _, _, err = arbGasInfo.GetPricesInArbGas(callOpts) + Require(t, err) + + _, _, _, err = arbGasInfo.GetPricesInArbGasWithAggregator(callOpts, addr) + Require(t, err) + + _, err = arbGasInfo.GetAmortizedCostCapBips(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1FeesAvailable(callOpts) + Require(t, err) + + _, _, _, _, _, _, err = arbGasInfo.GetPricesInWeiWithAggregator(callOpts, addr) + Require(t, err) +} From 1ac9018e03e88159059242f2c56f325dddd23daa Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 10:50:29 -0300 Subject: [PATCH 48/82] System test for ArbRetryableTx.GetLifetime --- precompiles/ArbRetryableTx.go | 1 - precompiles/ArbRetryableTx_test.go | 9 +-------- system_tests/precompile_test.go | 2 ++ system_tests/retryable_test.go | 22 ++++++++++++++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index dac112e1bd..b2d58b9dfd 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -130,7 +130,6 @@ func (con ArbRetryableTx) Redeem(c ctx, evm mech, ticketId bytes32) (bytes32, er return retryTxHash, c.State.L2PricingState().AddToGasPool(arbmath.SaturatingCast[int64](gasToDonate)) } -// TODO: add system test // GetLifetime gets the default lifetime period a retryable has at creation func (con ArbRetryableTx) GetLifetime(c ctx, evm mech) (huge, error) { return big.NewInt(retryables.RetryableLifetimeSeconds), nil diff --git a/precompiles/ArbRetryableTx_test.go b/precompiles/ArbRetryableTx_test.go index 58eed5ad77..ced3208d27 100644 --- a/precompiles/ArbRetryableTx_test.go +++ b/precompiles/ArbRetryableTx_test.go @@ -8,7 +8,6 @@ import ( "testing" "github.com/offchainlabs/nitro/arbos" - "github.com/offchainlabs/nitro/arbos/retryables" "github.com/offchainlabs/nitro/arbos/storage" "github.com/ethereum/go-ethereum/common" @@ -25,19 +24,13 @@ func newMockEVMForTestingWithCurrentRefundTo(currentRefundTo *common.Address) *v return evm } -func TestGetLifetimeAndCurrentRedeemer(t *testing.T) { +func TestGetCurrentRedeemer(t *testing.T) { currentRefundTo := common.HexToAddress("0x030405") evm := newMockEVMForTestingWithCurrentRefundTo(¤tRefundTo) retryableTx := ArbRetryableTx{} context := testContext(common.Address{}, evm) - lifetime, err := retryableTx.GetLifetime(context, evm) - Require(t, err) - if lifetime.Cmp(big.NewInt(retryables.RetryableLifetimeSeconds)) != 0 { - t.Fatal("Expected to be ", retryables.RetryableLifetimeSeconds, " but got ", lifetime) - } - currentRedeemer, err := retryableTx.GetCurrentRedeemer(context, evm) Require(t, err) if currentRefundTo.Cmp(currentRedeemer) != 0 { diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index f354fdd8c3..69ed699dc8 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -524,6 +524,8 @@ func TestArbFunctionTable(t *testing.T) { } func TestArbGasInfoDoesntRevert(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithCancel(context.Background()) defer cancel() diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 6651c8ca74..01519cc2c0 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -423,6 +423,28 @@ func TestSubmitRetryableFailThenRetry(t *testing.T) { } } +func TestGetLifetime(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + + lifetime, err := arbRetryableTx.GetLifetime(callOpts) + Require(t, err) + if lifetime.Cmp(big.NewInt(retryables.RetryableLifetimeSeconds)) != 0 { + t.Fatal("Expected to be ", retryables.RetryableLifetimeSeconds, " but got ", lifetime) + } +} + func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From 01d154b5fbb579f55d05f517f7c27c611b9835a1 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 10:59:35 -0300 Subject: [PATCH 49/82] Moves ArbRetryableTx.GetBeneficiary to system test --- precompiles/ArbRetryableTx.go | 1 - precompiles/ArbRetryableTx_test.go | 19 +------------------ system_tests/retryable_test.go | 8 ++++++++ 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index b2d58b9dfd..58342fd825 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -180,7 +180,6 @@ func (con ArbRetryableTx) Keepalive(c ctx, evm mech, ticketId bytes32) (huge, er return bigNewTimeout, err } -// TODO: add system test // GetBeneficiary gets the beneficiary of the ticket func (con ArbRetryableTx) GetBeneficiary(c ctx, evm mech, ticketId bytes32) (addr, error) { retryableState := c.State.RetryableState() diff --git a/precompiles/ArbRetryableTx_test.go b/precompiles/ArbRetryableTx_test.go index ced3208d27..47450299ce 100644 --- a/precompiles/ArbRetryableTx_test.go +++ b/precompiles/ArbRetryableTx_test.go @@ -38,7 +38,7 @@ func TestGetCurrentRedeemer(t *testing.T) { } } -func TestRetryableRedeemAndGetBeneficiary(t *testing.T) { +func TestRetryableRedeem(t *testing.T) { evm := newMockEVMForTesting() precompileCtx := testContext(common.Address{}, evm) @@ -87,21 +87,4 @@ func TestRetryableRedeemAndGetBeneficiary(t *testing.T) { // to handle both cases, and some will be left over in this test's use case. Fail(t, "didn't consume all the expected gas") } - - getBeneficiaryCallData, err := retryABI.Pack("getBeneficiary", id) - Require(t, err) - retrievedBeneficiary, _, err := Precompiles()[retryAddress].Call( - getBeneficiaryCallData, - retryAddress, - retryAddress, - common.Address{}, - big.NewInt(0), - false, - 1000000, - evm, - ) - Require(t, err) - if common.BytesToAddress(retrievedBeneficiary).Cmp(beneficiary) != 0 { - Fail(t, "expected beneficiary to be ", beneficiary, " but got ", common.BytesToAddress(retrievedBeneficiary)) - } } diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 01519cc2c0..89446e3c4b 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -502,6 +502,14 @@ func TestKeepaliveAndCancelRetryable(t *testing.T) { // checks that the ticket exists and gets current timeout timeoutBeforeKeepalive, err := arbRetryableTx.GetTimeout(&bind.CallOpts{}, ticketId) Require(t, err) + + // checks beneficiary + retrievedBeneficiaryAddress, err := arbRetryableTx.GetBeneficiary(&bind.CallOpts{}, ticketId) + Require(t, err) + if retrievedBeneficiaryAddress != beneficiaryAddress { + Fatal(t, "expected beneficiary to be", beneficiaryAddress, "but got", retrievedBeneficiaryAddress) + } + // checks that keepalive increases the timeout as expected _, err = arbRetryableTx.Keepalive(&ownerTxOpts, ticketId) Require(t, err) From acd3ab87b8ebb45329ad292153235e6b6ead9b06 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:14:47 -0300 Subject: [PATCH 50/82] TestArbRetryableTxDoesntRevert --- precompiles/ArbRetryableTx.go | 1 - system_tests/retryable_test.go | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index 58342fd825..0ca32e487a 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -222,7 +222,6 @@ func (con ArbRetryableTx) Cancel(c ctx, evm mech, ticketId bytes32) error { return con.Canceled(c, evm, ticketId) } -// TODO: add system test func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, error) { if c.txProcessor.CurrentRefundTo != nil { return *c.txProcessor.CurrentRefundTo, nil diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 89446e3c4b..070902c155 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -445,6 +445,25 @@ func TestGetLifetime(t *testing.T) { } } +func TestArbRetryableTxDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + + _, err = arbRetryableTx.GetCurrentRedeemer(callOpts) + Require(t, err) +} + func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From 6aa5b4e6463a8199ade646e6560049217d21bdb0 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:15:03 -0300 Subject: [PATCH 51/82] TestSubmitRetryable --- precompiles/ArbRetryableTx.go | 1 - system_tests/retryable_test.go | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbRetryableTx.go b/precompiles/ArbRetryableTx.go index 0ca32e487a..d925499180 100644 --- a/precompiles/ArbRetryableTx.go +++ b/precompiles/ArbRetryableTx.go @@ -229,7 +229,6 @@ func (con ArbRetryableTx) GetCurrentRedeemer(c ctx, evm mech) (common.Address, e return common.Address{}, nil } -// TODO: add system test func (con ArbRetryableTx) SubmitRetryable( c ctx, evm mech, requestId bytes32, l1BaseFee, deposit, callvalue, gasFeeCap huge, gasLimit uint64, maxSubmissionFee huge, diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 070902c155..d7a7b08337 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -5,6 +5,7 @@ package arbtest import ( "context" + "fmt" "math/big" "strings" "testing" @@ -464,6 +465,46 @@ func TestArbRetryableTxDoesntRevert(t *testing.T) { Require(t, err) } +func TestSubmitRetryable(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + + _, err = arbRetryableTx.SubmitRetryable( + &auth, + [32]byte{}, + big.NewInt(0), + big.NewInt(0), + big.NewInt(0), + big.NewInt(0), + 0, + big.NewInt(0), + common.Address{}, + common.Address{}, + common.Address{}, + []byte{}, + ) + if err == nil { + t.Fatal("expected error") + } + observedMessage := err.Error() + expectedError := "NotCallable()" + expectedMessage := fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) + if observedMessage != expectedMessage { + Fatal(t, observedMessage) + } +} + func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From a2551a8e21eaa5122109073687210128c77f298e Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:21:13 -0300 Subject: [PATCH 52/82] Moves TestSubmitRetryable to TestCustomSolidityErrors --- system_tests/precompile_test.go | 28 ++++++++++++++++++++++ system_tests/retryable_test.go | 41 --------------------------------- 2 files changed, 28 insertions(+), 41 deletions(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 69ed699dc8..430b4b4eab 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -79,6 +79,8 @@ func TestCustomSolidityErrors(t *testing.T) { defer cleanup() callOpts := &bind.CallOpts{Context: ctx} + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) Require(t, err, "could not bind ArbDebug contract") customError := arbDebug.CustomRevert(callOpts, 1024) @@ -105,6 +107,32 @@ func TestCustomSolidityErrors(t *testing.T) { if observedMessage != expectedMessage { Fatal(t, observedMessage) } + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + _, err = arbRetryableTx.SubmitRetryable( + &auth, + [32]byte{}, + big.NewInt(0), + big.NewInt(0), + big.NewInt(0), + big.NewInt(0), + 0, + big.NewInt(0), + common.Address{}, + common.Address{}, + common.Address{}, + []byte{}, + ) + if err == nil { + Fatal(t, "SubmitRetryable call should have errored") + } + observedMessage = err.Error() + expectedError = "NotCallable()" + expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) + if observedMessage != expectedMessage { + Fatal(t, observedMessage) + } } func TestPrecompileErrorGasLeft(t *testing.T) { diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index d7a7b08337..070902c155 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -5,7 +5,6 @@ package arbtest import ( "context" - "fmt" "math/big" "strings" "testing" @@ -465,46 +464,6 @@ func TestArbRetryableTxDoesntRevert(t *testing.T) { Require(t, err) } -func TestSubmitRetryable(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) - Require(t, err) - - _, err = arbRetryableTx.SubmitRetryable( - &auth, - [32]byte{}, - big.NewInt(0), - big.NewInt(0), - big.NewInt(0), - big.NewInt(0), - 0, - big.NewInt(0), - common.Address{}, - common.Address{}, - common.Address{}, - []byte{}, - ) - if err == nil { - t.Fatal("expected error") - } - observedMessage := err.Error() - expectedError := "NotCallable()" - expectedMessage := fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } -} - func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From 2f7fcfcfdc08cc38f464e2a7d4929faefa744cde Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:27:17 -0300 Subject: [PATCH 53/82] ArbosActs system tests --- precompiles/ArbosActs.go | 2 -- system_tests/precompile_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbosActs.go b/precompiles/ArbosActs.go index 45808f35a8..e18aa43efb 100644 --- a/precompiles/ArbosActs.go +++ b/precompiles/ArbosActs.go @@ -11,12 +11,10 @@ type ArbosActs struct { CallerNotArbOSError func() error } -// TODO: add system test func (con ArbosActs) StartBlock(c ctx, evm mech, l1BaseFee huge, l1BlockNumber, l2BlockNumber, timeLastBlock uint64) error { return con.CallerNotArbOSError() } -// TODO: add system test func (con ArbosActs) BatchPostingReport(c ctx, evm mech, batchTimestamp huge, batchPosterAddress addr, batchNumber uint64, batchDataGas uint64, l1BaseFeeWei huge) error { return con.CallerNotArbOSError() } diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 430b4b4eab..1e3c1adcee 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -133,6 +133,30 @@ func TestCustomSolidityErrors(t *testing.T) { if observedMessage != expectedMessage { Fatal(t, observedMessage) } + + arbosActs, err := precompilesgen.NewArbosActs(types.ArbosAddress, builder.L2.Client) + Require(t, err) + _, err = arbosActs.StartBlock(&auth, big.NewInt(0), 0, 0, 0) + if err == nil { + Fatal(t, "StartBlock call should have errored") + } + observedMessage = err.Error() + expectedError = "CallerNotArbOS()" + expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) + if observedMessage != expectedMessage { + Fatal(t, observedMessage) + } + + _, err = arbosActs.BatchPostingReport(&auth, big.NewInt(0), common.Address{}, 0, 0, big.NewInt(0)) + if err == nil { + Fatal(t, "BatchPostingReport call should have errored") + } + observedMessage = err.Error() + expectedError = "CallerNotArbOS()" + expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) + if observedMessage != expectedMessage { + Fatal(t, observedMessage) + } } func TestPrecompileErrorGasLeft(t *testing.T) { From 4ff5480fcd1b519b41f0ce097abf8aed58148a3a Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:33:57 -0300 Subject: [PATCH 54/82] Refactors TestCustomSolidityErrors --- system_tests/precompile_test.go | 96 ++++++++++++++++----------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 1e3c1adcee..eabbb60216 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -81,36 +81,42 @@ func TestCustomSolidityErrors(t *testing.T) { callOpts := &bind.CallOpts{Context: ctx} auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + ensure := func( + customError error, + expectedError string, + scenario string, + ) { + if customError == nil { + Fatal(t, "should have errored", "scenario", scenario) + } + observedMessage := customError.Error() + // The first error is server side. The second error is client side ABI decoding. + expectedMessage := fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) + if observedMessage != expectedMessage { + Fatal(t, observedMessage, "scenario", scenario) + } + } + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) Require(t, err, "could not bind ArbDebug contract") - customError := arbDebug.CustomRevert(callOpts, 1024) - if customError == nil { - Fatal(t, "customRevert call should have errored") - } - observedMessage := customError.Error() - expectedError := "Custom(1024, This spider family wards off bugs: /\\oo/\\ //\\(oo)//\\ /\\oo/\\, true)" - // The first error is server side. The second error is client side ABI decoding. - expectedMessage := fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } + ensure( + arbDebug.CustomRevert(callOpts, 1024), + "Custom(1024, This spider family wards off bugs: /\\oo/\\ //\\(oo)//\\ /\\oo/\\, true)", + "arbDebug.CustomRevert", + ) arbSys, err := precompilesgen.NewArbSys(arbos.ArbSysAddress, builder.L2.Client) Require(t, err, "could not bind ArbSys contract") - _, customError = arbSys.ArbBlockHash(callOpts, big.NewInt(1e9)) - if customError == nil { - Fatal(t, "out of range ArbBlockHash call should have errored") - } - observedMessage = customError.Error() - expectedError = "InvalidBlockNumber(1000000000, 1)" - expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } + _, customError := arbSys.ArbBlockHash(callOpts, big.NewInt(1e9)) + ensure( + customError, + "InvalidBlockNumber(1000000000, 1)", + "arbSys.ArbBlockHash", + ) arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) Require(t, err) - _, err = arbRetryableTx.SubmitRetryable( + _, customError = arbRetryableTx.SubmitRetryable( &auth, [32]byte{}, big.NewInt(0), @@ -124,39 +130,27 @@ func TestCustomSolidityErrors(t *testing.T) { common.Address{}, []byte{}, ) - if err == nil { - Fatal(t, "SubmitRetryable call should have errored") - } - observedMessage = err.Error() - expectedError = "NotCallable()" - expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } + ensure( + customError, + "NotCallable()", + "arbRetryableTx.SubmitRetryable", + ) arbosActs, err := precompilesgen.NewArbosActs(types.ArbosAddress, builder.L2.Client) Require(t, err) - _, err = arbosActs.StartBlock(&auth, big.NewInt(0), 0, 0, 0) - if err == nil { - Fatal(t, "StartBlock call should have errored") - } - observedMessage = err.Error() - expectedError = "CallerNotArbOS()" - expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } + _, customError = arbosActs.StartBlock(&auth, big.NewInt(0), 0, 0, 0) + ensure( + customError, + "CallerNotArbOS()", + "arbosActs.StartBlock", + ) - _, err = arbosActs.BatchPostingReport(&auth, big.NewInt(0), common.Address{}, 0, 0, big.NewInt(0)) - if err == nil { - Fatal(t, "BatchPostingReport call should have errored") - } - observedMessage = err.Error() - expectedError = "CallerNotArbOS()" - expectedMessage = fmt.Sprintf("execution reverted: error %v: %v", expectedError, expectedError) - if observedMessage != expectedMessage { - Fatal(t, observedMessage) - } + _, customError = arbosActs.BatchPostingReport(&auth, big.NewInt(0), common.Address{}, 0, 0, big.NewInt(0)) + ensure( + customError, + "CallerNotArbOS()", + "arbosActs.BatchPostingReport", + ) } func TestPrecompileErrorGasLeft(t *testing.T) { From 54283080f2ee010927c5dafa433c5ee0d8f1814c Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 11:44:41 -0300 Subject: [PATCH 55/82] TestArbDebugLegacyError --- precompiles/ArbDebug.go | 1 - system_tests/precompile_test.go | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index 9bfc8c9815..d8b4ad0f8e 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -62,7 +62,6 @@ func (con ArbDebug) Panic(c ctx, evm mech) error { panic("called ArbDebug's debug-only Panic method") } -// TODO: add system test func (con ArbDebug) LegacyError(c ctx) error { return errors.New("example legacy error") } diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index eabbb60216..b4074171cb 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -70,6 +70,25 @@ func TestViewLogReverts(t *testing.T) { } } +func TestArbDebugLegacyError(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) + Require(t, err) + + err = arbDebug.LegacyError(callOpts) + if err == nil { + Fatal(t, "unexpected success") + } +} + func TestCustomSolidityErrors(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() From bfd0d0d2dd40c5655e9e5e8962c64864afd4fa90 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 12:10:45 -0300 Subject: [PATCH 56/82] TestArbDebugPanic --- precompiles/ArbDebug.go | 1 - system_tests/precompile_test.go | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbDebug.go b/precompiles/ArbDebug.go index d8b4ad0f8e..bf85d5e18f 100644 --- a/precompiles/ArbDebug.go +++ b/precompiles/ArbDebug.go @@ -56,7 +56,6 @@ func (con ArbDebug) BecomeChainOwner(c ctx, evm mech) error { return c.State.ChainOwners().Add(c.caller) } -// TODO: add system test // Halts the chain by panicking in the STF func (con ArbDebug) Panic(c ctx, evm mech) error { panic("called ArbDebug's debug-only Panic method") diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index b4074171cb..426915c7d9 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -70,6 +70,28 @@ func TestViewLogReverts(t *testing.T) { } } +func TestArbDebugPanic(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) + Require(t, err) + + _, err = arbDebug.Panic(&auth) + if err == nil { + Fatal(t, "unexpected success") + } + if err.Error() != "method handler crashed" { + Fatal(t, "expected method handler to crash") + } +} + func TestArbDebugLegacyError(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() From 11996aa5c94cbd295675239eb030be4ee4a2923d Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 13:15:12 -0300 Subject: [PATCH 57/82] TestArbSysDoesntRevert --- precompiles/ArbSys.go | 1 - system_tests/precompile_test.go | 21 +++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index f48573fafe..149a95ec1f 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -75,7 +75,6 @@ func (con *ArbSys) IsTopLevelCall(c ctx, evm mech) (bool, error) { return evm.Depth() <= 2, nil } -// TODO: add system test // MapL1SenderContractAddressToL2Alias gets the contract's L2 alias func (con *ArbSys) MapL1SenderContractAddressToL2Alias(c ctx, sender addr, dest addr) (addr, error) { return util.RemapL1Address(sender), nil diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 426915c7d9..8b90836635 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -610,6 +610,27 @@ func TestArbFunctionTable(t *testing.T) { } } +func TestArbSysDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, builder.L2.Client) + Require(t, err) + + addr1 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + addr2 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + _, err = arbSys.MapL1SenderContractAddressToL2Alias(callOpts, addr1, addr2) + Require(t, err) +} + func TestArbGasInfoDoesntRevert(t *testing.T) { t.Parallel() From 4e2be7ec130f8bd9c906ba348953b10d08b49613 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 13:18:32 -0300 Subject: [PATCH 58/82] Uses ArbSys.SendTxToL1 in a system test --- precompiles/ArbSys.go | 1 - system_tests/debugapi_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/precompiles/ArbSys.go b/precompiles/ArbSys.go index 149a95ec1f..689d3b18de 100644 --- a/precompiles/ArbSys.go +++ b/precompiles/ArbSys.go @@ -105,7 +105,6 @@ func (con *ArbSys) MyCallersAddressWithoutAliasing(c ctx, evm mech) (addr, error return address, err } -// TODO: add system test // SendTxToL1 sends a transaction to L1, adding it to the outbox func (con *ArbSys) SendTxToL1(c ctx, evm mech, value huge, destination addr, calldataForL1 []byte) (huge, error) { l1BlockNum, err := c.txProcessor.L1BlockNumber(vm.BlockContext{}) diff --git a/system_tests/debugapi_test.go b/system_tests/debugapi_test.go index 30a2bee03e..eb2bcd095d 100644 --- a/system_tests/debugapi_test.go +++ b/system_tests/debugapi_test.go @@ -43,7 +43,7 @@ func TestDebugAPI(t *testing.T) { arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, builder.L2.Client) Require(t, err) auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - tx, err := arbSys.WithdrawEth(&auth, common.Address{}) + tx, err := arbSys.SendTxToL1(&auth, common.Address{}, []byte{}) Require(t, err) receipt, err := builder.L2.EnsureTxSucceeded(tx) Require(t, err) From 3927b8f8bb26e012bc6222c98f6dc6425621d37c Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 13:22:33 -0300 Subject: [PATCH 59/82] Test for ArbosTest --- precompiles/ArbosTest.go | 1 - system_tests/precompile_test.go | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/precompiles/ArbosTest.go b/precompiles/ArbosTest.go index 8a770ea339..6e988f533a 100644 --- a/precompiles/ArbosTest.go +++ b/precompiles/ArbosTest.go @@ -12,7 +12,6 @@ type ArbosTest struct { Address addr // 0x69 } -// TODO: add system test // BurnArbGas unproductively burns the amount of L2 ArbGas func (con ArbosTest) BurnArbGas(c ctx, gasAmount huge) error { if !gasAmount.IsUint64() { diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 8b90836635..7ea0cdbf4c 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -610,6 +610,25 @@ func TestArbFunctionTable(t *testing.T) { } } +func TestArbosTestDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbosTest, err := precompilesgen.NewArbosTest(types.ArbosTestAddress, builder.L2.Client) + Require(t, err) + + err = arbosTest.BurnArbGas(callOpts, big.NewInt(1)) + Require(t, err) +} + func TestArbSysDoesntRevert(t *testing.T) { t.Parallel() From 5bd7a50b5a83f3f9a49e259f14bac90003717ae2 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 15:28:22 -0300 Subject: [PATCH 60/82] TestArbAggregatorBatchPosters as a system test --- precompiles/ArbAggregator.go | 1 - precompiles/ArbAggregator_test.go | 28 ------------------ system_tests/precompile_test.go | 49 +++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index c3ee19c12c..9ed9c94cf4 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -38,7 +38,6 @@ func (con ArbAggregator) GetBatchPosters(c ctx, evm mech) ([]addr, error) { return c.State.L1PricingState().BatchPosterTable().AllPosters(65536) } -// TODO: add system test func (con ArbAggregator) AddBatchPoster(c ctx, evm mech, newBatchPoster addr) error { isOwner, err := c.State.ChainOwners().IsMember(c.caller) if err != nil { diff --git a/precompiles/ArbAggregator_test.go b/precompiles/ArbAggregator_test.go index ce1cebde5d..879fc737e4 100644 --- a/precompiles/ArbAggregator_test.go +++ b/precompiles/ArbAggregator_test.go @@ -12,34 +12,6 @@ import ( "github.com/offchainlabs/nitro/arbos/l1pricing" ) -func TestArbAggregatorBatchPosters(t *testing.T) { - evm := newMockEVMForTesting() - context := testContext(common.Address{}, evm) - - addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - - // initially should have one batch poster - bps, err := ArbAggregator{}.GetBatchPosters(context, evm) - Require(t, err) - if len(bps) != 1 { - Fail(t) - } - - // add addr as a batch poster - Require(t, ArbDebug{}.BecomeChainOwner(context, evm)) - Require(t, ArbAggregator{}.AddBatchPoster(context, evm, addr)) - - // there should now be two batch posters, and addr should be one of them - bps, err = ArbAggregator{}.GetBatchPosters(context, evm) - Require(t, err) - if len(bps) != 2 { - Fail(t) - } - if bps[0] != addr && bps[1] != addr { - Fail(t) - } -} - func TestFeeCollector(t *testing.T) { evm := newMockEVMForTesting() agg := ArbAggregator{} diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 7ea0cdbf4c..3406637ed5 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -696,3 +696,52 @@ func TestArbGasInfoDoesntRevert(t *testing.T) { _, _, _, _, _, _, err = arbGasInfo.GetPricesInWeiWithAggregator(callOpts, addr) Require(t, err) } + +func TestArbAggregatorBatchPosters(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) + Require(t, err) + + arbDebug, err := precompilesgen.NewArbDebug(types.ArbDebugAddress, builder.L2.Client) + Require(t, err) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + // initially should have one batch poster + bps, err := arbAggregator.GetBatchPosters(callOpts) + Require(t, err) + if len(bps) != 1 { + Fatal(t, "expected one batch poster") + } + + // add addr as a batch poster + tx, err := arbDebug.BecomeChainOwner(&auth) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + tx, err = arbAggregator.AddBatchPoster(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + // there should now be two batch posters, and addr should be one of them + bps, err = arbAggregator.GetBatchPosters(callOpts) + Require(t, err) + if len(bps) != 2 { + Fatal(t, "expected two batch posters") + } + if bps[0] != addr && bps[1] != addr { + Fatal(t, "expected addr to be a batch poster") + } +} From 5927380d6f90fc13d38f06cb0fa1cbcbc5791571 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 15:32:14 -0300 Subject: [PATCH 61/82] TestArbAggregatorGetPreferredAggregator --- precompiles/ArbAggregator.go | 2 -- system_tests/precompile_test.go | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index 9ed9c94cf4..9591c001d9 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -19,14 +19,12 @@ type ArbAggregator struct { var ErrNotOwner = errors.New("must be called by chain owner") -// TODO: add system test // GetPreferredAggregator returns the preferred aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetPreferredAggregator(c ctx, evm mech, address addr) (prefAgg addr, isDefault bool, err error) { return l1pricing.BatchPosterAddress, true, err } -// TODO: add system test // GetDefaultAggregator returns the default aggregator address. // Deprecated: Do not use this method. func (con ArbAggregator) GetDefaultAggregator(c ctx, evm mech) (addr, error) { diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 3406637ed5..bd61fa3982 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -15,6 +15,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/offchainlabs/nitro/arbos" + "github.com/offchainlabs/nitro/arbos/l1pricing" "github.com/offchainlabs/nitro/solgen/go/mocksgen" "github.com/offchainlabs/nitro/solgen/go/precompilesgen" "github.com/offchainlabs/nitro/util/arbmath" @@ -745,3 +746,36 @@ func TestArbAggregatorBatchPosters(t *testing.T) { Fatal(t, "expected addr to be a batch poster") } } + +func TestArbAggregatorGetPreferredAggregator(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) + Require(t, err) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + prefAgg, isDefault, err := arbAggregator.GetPreferredAggregator(callOpts, addr) + Require(t, err) + if !isDefault { + Fatal(t, "expected default preferred aggregator") + } + if prefAgg != l1pricing.BatchPosterAddress { + Fatal(t, "expected default preferred aggregator to be", l1pricing.BatchPosterAddress, "got", prefAgg) + } + + prefAgg, err = arbAggregator.GetDefaultAggregator(callOpts) + Require(t, err) + if prefAgg != l1pricing.BatchPosterAddress { + Fatal(t, "expected default preferred aggregator to be", l1pricing.BatchPosterAddress, "got", prefAgg) + } +} From 82f21dea10f68156e89a5c9ca85b5599c8b06cef Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 15:45:52 -0300 Subject: [PATCH 62/82] TestArbAggregatorBaseFee --- precompiles/ArbAggregator.go | 2 -- system_tests/precompile_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index 9591c001d9..d515eb375a 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -91,14 +91,12 @@ func (con ArbAggregator) SetFeeCollector(c ctx, evm mech, batchPoster addr, newF return posterInfo.SetPayTo(newFeeCollector) } -// TODO: add system test // GetTxBaseFee gets an aggregator's current fixed fee to submit a tx func (con ArbAggregator) GetTxBaseFee(c ctx, evm mech, aggregator addr) (huge, error) { // This is deprecated and now always returns zero. return big.NewInt(0), nil } -// TODO: add system test // SetTxBaseFee sets an aggregator's fixed fee (caller must be the aggregator, its fee collector, or an owner) func (con ArbAggregator) SetTxBaseFee(c ctx, evm mech, aggregator addr, feeInL1Gas huge) error { // This is deprecated and is now a no-op. diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index bd61fa3982..80bc2abdc4 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -611,6 +611,34 @@ func TestArbFunctionTable(t *testing.T) { } } +func TestArbAggregatorBaseFee(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) + Require(t, err) + + tx, err := arbAggregator.SetTxBaseFee(&auth, common.Address{}, big.NewInt(1)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + fee, err := arbAggregator.GetTxBaseFee(callOpts, common.Address{}) + Require(t, err) + if fee.Cmp(big.NewInt(0)) != 0 { + Fatal(t, "expected fee to be 0, got", fee) + } +} + func TestArbosTestDoesntRevert(t *testing.T) { t.Parallel() From ba50c008ec54503f2630d08aaffa113b2459020d Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 15:51:03 -0300 Subject: [PATCH 63/82] TestArbAggregatorDoesntRevert --- precompiles/ArbAggregator.go | 2 -- system_tests/precompile_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbAggregator.go b/precompiles/ArbAggregator.go index d515eb375a..b74e280fe8 100644 --- a/precompiles/ArbAggregator.go +++ b/precompiles/ArbAggregator.go @@ -58,7 +58,6 @@ func (con ArbAggregator) AddBatchPoster(c ctx, evm mech, newBatchPoster addr) er return nil } -// TODO: add system test // GetFeeCollector gets a batch poster's fee collector func (con ArbAggregator) GetFeeCollector(c ctx, evm mech, batchPoster addr) (addr, error) { posterInfo, err := c.State.L1PricingState().BatchPosterTable().OpenPoster(batchPoster, false) @@ -68,7 +67,6 @@ func (con ArbAggregator) GetFeeCollector(c ctx, evm mech, batchPoster addr) (add return posterInfo.PayTo() } -// TODO: add system test // SetFeeCollector sets a batch poster's fee collector (caller must be the batch poster, its fee collector, or an owner) func (con ArbAggregator) SetFeeCollector(c ctx, evm mech, batchPoster addr, newFeeCollector addr) error { posterInfo, err := c.State.L1PricingState().BatchPosterTable().OpenPoster(batchPoster, false) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 80bc2abdc4..cc4cf4195f 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -639,6 +639,31 @@ func TestArbAggregatorBaseFee(t *testing.T) { } } +func TestArbAggregatorDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) + Require(t, err) + + tx, err := arbAggregator.SetFeeCollector(&auth, l1pricing.BatchPosterAddress, common.Address{}) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + _, err = arbAggregator.GetFeeCollector(callOpts, l1pricing.BatchPosterAddress) + Require(t, err) +} + func TestArbosTestDoesntRevert(t *testing.T) { t.Parallel() From 3a75847a6954aea1445be7cda2288dc4296c15d7 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Mon, 14 Oct 2024 16:15:50 -0300 Subject: [PATCH 64/82] TestArbOwnerPublicGetAllChainOwners --- precompiles/ArbOwnerPublic.go | 2 -- system_tests/precompile_test.go | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbOwnerPublic.go b/precompiles/ArbOwnerPublic.go index d901c77f12..451e18e1cc 100644 --- a/precompiles/ArbOwnerPublic.go +++ b/precompiles/ArbOwnerPublic.go @@ -16,13 +16,11 @@ type ArbOwnerPublic struct { ChainOwnerRectifiedGasCost func(addr) (uint64, error) } -// TODO: add system test // GetAllChainOwners retrieves the list of chain owners func (con ArbOwnerPublic) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) { return c.State.ChainOwners().AllMembers(65536) } -// TODO: add system test // RectifyChainOwner checks if the account is a chain owner func (con ArbOwnerPublic) RectifyChainOwner(c ctx, evm mech, addr addr) error { err := c.State.ChainOwners().RectifyMapping(addr) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index cc4cf4195f..dc8cb842a3 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -704,6 +704,41 @@ func TestArbSysDoesntRevert(t *testing.T) { Require(t, err) } +func TestArbOwnerPublicGetAllChainOwners(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(types.ArbOwnerPublicAddress, builder.L2.Client) + Require(t, err) + + ownerAddr := builder.L2Info.GetAddress("Owner") + chainOwners, err := arbOwnerPublic.GetAllChainOwners(callOpts) + Require(t, err) + chainOwnerInChainOwners := false + for _, chainOwner := range chainOwners { + if chainOwner.Cmp(ownerAddr) == 0 { + chainOwnerInChainOwners = true + } + } + if !chainOwnerInChainOwners { + Fatal(t, "expected owner to be in chain owners") + } + + _, err = arbOwnerPublic.RectifyChainOwner(&auth, ownerAddr) + if (err == nil) || (err.Error() != "execution reverted") { + Fatal(t, "expected rectify chain owner to revert since it is already an owner") + } +} + func TestArbGasInfoDoesntRevert(t *testing.T) { t.Parallel() From b1d81100cd382c34cf17fb2c49ae6d080799b117 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 10:16:35 -0300 Subject: [PATCH 65/82] TestArbAddressTableDoesntRevert --- precompiles/ArbAddressTable.go | 7 ----- system_tests/precompile_test.go | 54 +++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/precompiles/ArbAddressTable.go b/precompiles/ArbAddressTable.go index 45b708bd7d..102fd55c3b 100644 --- a/precompiles/ArbAddressTable.go +++ b/precompiles/ArbAddressTable.go @@ -13,19 +13,16 @@ type ArbAddressTable struct { Address addr // 0x66 } -// TODO: add system test // AddressExists checks if an address exists in the table func (con ArbAddressTable) AddressExists(c ctx, evm mech, addr addr) (bool, error) { return c.State.AddressTable().AddressExists(addr) } -// TODO: add system test // Compress and returns the bytes that represent the address func (con ArbAddressTable) Compress(c ctx, evm mech, addr addr) ([]uint8, error) { return c.State.AddressTable().Compress(addr) } -// TODO: add system test // Decompress the compressed bytes at the given offset with those of the corresponding account func (con ArbAddressTable) Decompress(c ctx, evm mech, buf []uint8, offset huge) (addr, huge, error) { if !offset.IsInt64() { @@ -39,7 +36,6 @@ func (con ArbAddressTable) Decompress(c ctx, evm mech, buf []uint8, offset huge) return result, new(big.Int).SetUint64(nbytes), err } -// TODO: add system test // Lookup the index of an address in the table func (con ArbAddressTable) Lookup(c ctx, evm mech, addr addr) (huge, error) { result, exists, err := c.State.AddressTable().Lookup(addr) @@ -52,7 +48,6 @@ func (con ArbAddressTable) Lookup(c ctx, evm mech, addr addr) (huge, error) { return new(big.Int).SetUint64(result), nil } -// TODO: add system test // LookupIndex for an address in the table by index func (con ArbAddressTable) LookupIndex(c ctx, evm mech, index huge) (addr, error) { if !index.IsUint64() { @@ -68,14 +63,12 @@ func (con ArbAddressTable) LookupIndex(c ctx, evm mech, index huge) (addr, error return result, nil } -// TODO: add system test // Register adds an account to the table, shrinking its compressed representation func (con ArbAddressTable) Register(c ctx, evm mech, addr addr) (huge, error) { slot, err := c.State.AddressTable().Register(addr) return new(big.Int).SetUint64(slot), err } -// TODO: add system test // Size gets the number of addresses in the table func (con ArbAddressTable) Size(c ctx, evm mech) (huge, error) { size, err := c.State.AddressTable().Size() diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index dc8cb842a3..5d5cfe69db 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -639,6 +639,60 @@ func TestArbAggregatorBaseFee(t *testing.T) { } } +func TestArbAddressTableDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAddressTable, err := precompilesgen.NewArbAddressTable(types.ArbAddressTableAddress, builder.L2.Client) + Require(t, err) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + exists, err := arbAddressTable.AddressExists(callOpts, addr) + Require(t, err) + if exists { + Fatal(t, "expected address to not exist") + } + + tx, err := arbAddressTable.Register(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + idx, err := arbAddressTable.Lookup(callOpts, addr) + Require(t, err) + + retrievedAddr, err := arbAddressTable.LookupIndex(callOpts, idx) + Require(t, err) + if retrievedAddr.Cmp(addr) != 0 { + Fatal(t, "expected retrieved address to be", addr, "got", retrievedAddr) + } + + size, err := arbAddressTable.Size(callOpts) + Require(t, err) + if size.Cmp(big.NewInt(1)) != 0 { + Fatal(t, "expected size to be 1, got", size) + } + + tx, err = arbAddressTable.Compress(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + res := []uint8{128} + _, _, err = arbAddressTable.Decompress(callOpts, res, big.NewInt(0)) + Require(t, err) +} + func TestArbAggregatorDoesntRevert(t *testing.T) { t.Parallel() From a5435b225843368584da0106f1e6b81e2e71e3ec Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 10:37:00 -0300 Subject: [PATCH 66/82] System test for ArbOwner.GetAllChainOwners --- precompiles/ArbOwner.go | 1 - system_tests/precompile_test.go | 27 +++++++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 7387b62a62..4f4f01d45c 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -54,7 +54,6 @@ func (con ArbOwner) IsChainOwner(c ctx, evm mech, addr addr) (bool, error) { return c.State.ChainOwners().IsMember(addr) } -// TODO: add system test // GetAllChainOwners retrieves the list of chain owners func (con ArbOwner) GetAllChainOwners(c ctx, evm mech) ([]common.Address, error) { return c.State.ChainOwners().AllMembers(65536) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 5d5cfe69db..5aa648cc21 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "math/big" + "sort" "testing" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -758,7 +759,7 @@ func TestArbSysDoesntRevert(t *testing.T) { Require(t, err) } -func TestArbOwnerPublicGetAllChainOwners(t *testing.T) { +func TestGetAllChainOwners(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) @@ -774,11 +775,29 @@ func TestArbOwnerPublicGetAllChainOwners(t *testing.T) { arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(types.ArbOwnerPublicAddress, builder.L2.Client) Require(t, err) - ownerAddr := builder.L2Info.GetAddress("Owner") - chainOwners, err := arbOwnerPublic.GetAllChainOwners(callOpts) + arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + + chainOwnersArbOwnerPublic, err := arbOwnerPublic.GetAllChainOwners(callOpts) Require(t, err) + chainOwnersArbOwner, err := arbOwner.GetAllChainOwners(callOpts) + Require(t, err) + if len(chainOwnersArbOwnerPublic) != len(chainOwnersArbOwner) { + Fatal(t, "expected chain owners to be the same length") + } + // sort the chain owners to ensure they are in the same order + sort.Slice(chainOwnersArbOwnerPublic, func(i, j int) bool { + return chainOwnersArbOwnerPublic[i].Cmp(chainOwnersArbOwnerPublic[j]) < 0 + }) + for i := 0; i < len(chainOwnersArbOwnerPublic); i += 1 { + if chainOwnersArbOwnerPublic[i].Cmp(chainOwnersArbOwner[i]) != 0 { + Fatal(t, "expected chain owners to be the same") + } + } + + ownerAddr := builder.L2Info.GetAddress("Owner") chainOwnerInChainOwners := false - for _, chainOwner := range chainOwners { + for _, chainOwner := range chainOwnersArbOwner { if chainOwner.Cmp(ownerAddr) == 0 { chainOwnerInChainOwners = true } From 3fd92d33f1c0cd71b540c947f401545d8d439c9a Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 10:47:05 -0300 Subject: [PATCH 67/82] TestChainOwners --- precompiles/ArbOwner.go | 2 -- system_tests/precompile_test.go | 34 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 4f4f01d45c..487f93b049 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -33,13 +33,11 @@ var ( ErrOutOfBounds = errors.New("value out of bounds") ) -// TODO: add system test // AddChainOwner adds account as a chain owner func (con ArbOwner) AddChainOwner(c ctx, evm mech, newOwner addr) error { return c.State.ChainOwners().Add(newOwner) } -// TODO: add system test // RemoveChainOwner removes account from the list of chain owners func (con ArbOwner) RemoveChainOwner(c ctx, evm mech, addr addr) error { member, _ := con.IsChainOwner(c, evm, addr) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 5aa648cc21..1ac52c1883 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -759,7 +759,7 @@ func TestArbSysDoesntRevert(t *testing.T) { Require(t, err) } -func TestGetAllChainOwners(t *testing.T) { +func TestChainOwners(t *testing.T) { t.Parallel() ctx, cancel := context.WithCancel(context.Background()) @@ -774,10 +774,22 @@ func TestGetAllChainOwners(t *testing.T) { arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(types.ArbOwnerPublicAddress, builder.L2.Client) Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) Require(t, err) + builder.L2Info.GenerateAccount("Owner2") + chainOwnerAddr2 := builder.L2Info.GetAddress("Owner2") + tx, err := arbOwner.AddChainOwner(&auth, chainOwnerAddr2) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + isChainOwner, err := arbOwnerPublic.IsChainOwner(callOpts, chainOwnerAddr2) + Require(t, err) + if !isChainOwner { + Fatal(t, "expected owner2 to be a chain owner") + } + + // check that the chain owners retrieved from arbOwnerPublic and arbOwner are the same chainOwnersArbOwnerPublic, err := arbOwnerPublic.GetAllChainOwners(callOpts) Require(t, err) chainOwnersArbOwner, err := arbOwner.GetAllChainOwners(callOpts) @@ -794,11 +806,10 @@ func TestGetAllChainOwners(t *testing.T) { Fatal(t, "expected chain owners to be the same") } } - - ownerAddr := builder.L2Info.GetAddress("Owner") + chainOwnerAddr := builder.L2Info.GetAddress("Owner") chainOwnerInChainOwners := false for _, chainOwner := range chainOwnersArbOwner { - if chainOwner.Cmp(ownerAddr) == 0 { + if chainOwner.Cmp(chainOwnerAddr) == 0 { chainOwnerInChainOwners = true } } @@ -806,7 +817,18 @@ func TestGetAllChainOwners(t *testing.T) { Fatal(t, "expected owner to be in chain owners") } - _, err = arbOwnerPublic.RectifyChainOwner(&auth, ownerAddr) + // remove chain owner 2 + tx, err = arbOwner.RemoveChainOwner(&auth, chainOwnerAddr2) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + isChainOwner, err = arbOwnerPublic.IsChainOwner(callOpts, chainOwnerAddr2) + Require(t, err) + if isChainOwner { + Fatal(t, "expected owner2 to not be a chain owner") + } + + _, err = arbOwnerPublic.RectifyChainOwner(&auth, chainOwnerAddr) if (err == nil) || (err.Error() != "execution reverted") { Fatal(t, "expected rectify chain owner to revert since it is already an owner") } From d3e08616c1ea280b49a07d66dcc7a1c868b1e126 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 11:32:25 -0300 Subject: [PATCH 68/82] TestFeeAccounts --- precompiles/ArbOwner.go | 2 -- system_tests/precompile_test.go | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index 487f93b049..de67bca045 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -96,13 +96,11 @@ func (con ArbOwner) SetL2GasBacklogTolerance(c ctx, evm mech, sec uint64) error return c.State.L2PricingState().SetBacklogTolerance(sec) } -// TODO: add system test // GetNetworkFeeAccount gets the network fee collector func (con ArbOwner) GetNetworkFeeAccount(c ctx, evm mech) (addr, error) { return c.State.NetworkFeeAccount() } -// TODO: add system test // GetInfraFeeAccount gets the infrastructure fee collector func (con ArbOwner) GetInfraFeeAccount(c ctx, evm mech) (addr, error) { return c.State.InfraFeeAccount() diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 1ac52c1883..a775b21e2c 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -640,6 +640,48 @@ func TestArbAggregatorBaseFee(t *testing.T) { } } +func TestFeeAccounts(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + + builder.L2Info.GenerateAccount("User2") + addr := builder.L2Info.GetAddress("User2") + + tx, err := arbOwner.SetNetworkFeeAccount(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + feeAccount, err := arbOwner.GetNetworkFeeAccount(callOpts) + Require(t, err) + if feeAccount.Cmp(addr) != 0 { + Fatal(t, "expected fee account to be", addr, "got", feeAccount) + } + + tx, err = arbOwner.SetInfraFeeAccount(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + feeAccount, err = arbOwner.GetInfraFeeAccount(callOpts) + Require(t, err) + if feeAccount.Cmp(addr) != 0 { + Fatal(t, "expected fee account to be", addr, "got", feeAccount) + } +} + func TestArbAddressTableDoesntRevert(t *testing.T) { t.Parallel() From 0fd636c929777bb1b2d0bc45e6cdab284a1a5da3 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 11:47:00 -0300 Subject: [PATCH 69/82] TestArbOwnerDoesntRevert --- precompiles/ArbOwner.go | 4 ---- system_tests/precompile_test.go | 41 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/precompiles/ArbOwner.go b/precompiles/ArbOwner.go index de67bca045..8b87445e0e 100644 --- a/precompiles/ArbOwner.go +++ b/precompiles/ArbOwner.go @@ -62,7 +62,6 @@ func (con ArbOwner) SetL1BaseFeeEstimateInertia(c ctx, evm mech, inertia uint64) return c.State.L1PricingState().SetInertia(inertia) } -// TODO: add system test // SetL2BaseFee sets the L2 gas price directly, bypassing the pool calculus func (con ArbOwner) SetL2BaseFee(c ctx, evm mech, priceInWei huge) error { return c.State.L2PricingState().SetBaseFeeWei(priceInWei) @@ -145,7 +144,6 @@ func (con ArbOwner) SetPerBatchGasCharge(c ctx, evm mech, cost int64) error { return c.State.L1PricingState().SetPerBatchGasCost(cost) } -// TODO: add system test func (con ArbOwner) SetAmortizedCostCapBips(c ctx, evm mech, cap uint64) error { return c.State.L1PricingState().SetAmortizedCostCapBips(cap) } @@ -154,7 +152,6 @@ func (con ArbOwner) SetBrotliCompressionLevel(c ctx, evm mech, level uint64) err return c.State.SetBrotliCompressionLevel(level) } -// TODO: add system test func (con ArbOwner) ReleaseL1PricerSurplusFunds(c ctx, evm mech, maxWeiToRelease huge) (huge, error) { balance := evm.StateDB.GetBalance(l1pricing.L1PricerFundsPoolAddress) l1p := c.State.L1PricingState() @@ -298,7 +295,6 @@ func (con ArbOwner) RemoveWasmCacheManager(c ctx, _ mech, manager addr) error { return managers.Remove(manager, c.State.ArbOSVersion()) } -// TODO: add system test func (con ArbOwner) SetChainConfig(c ctx, evm mech, serializedChainConfig []byte) error { if c == nil { return errors.New("nil context") diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index a775b21e2c..acdaa88af7 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -5,6 +5,7 @@ package arbtest import ( "context" + "encoding/json" "fmt" "math/big" "sort" @@ -876,6 +877,46 @@ func TestChainOwners(t *testing.T) { } } +func TestArbOwnerDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + + chainConfig := params.ArbitrumDevTestChainConfig() + chainConfig.ArbitrumChainParams.MaxCodeSize = 100 + serializedChainConfig, err := json.Marshal(chainConfig) + Require(t, err) + tx, err := arbOwner.SetChainConfig(&auth, string(serializedChainConfig)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.SetAmortizedCostCapBips(&auth, 77734) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.ReleaseL1PricerSurplusFunds(&auth, big.NewInt(1)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.SetL2BaseFee(&auth, big.NewInt(1)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) +} + func TestArbGasInfoDoesntRevert(t *testing.T) { t.Parallel() From 3e2fdfc6031d11744d9da1536f504507896681bb Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 15:37:25 -0300 Subject: [PATCH 70/82] Commet about DoesntRevert tests --- system_tests/precompile_test.go | 18 ++++++++++++++++++ system_tests/retryable_test.go | 3 +++ 2 files changed, 21 insertions(+) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index acdaa88af7..379d939835 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -683,6 +683,9 @@ func TestFeeAccounts(t *testing.T) { } } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbAddressTableDoesntRevert(t *testing.T) { t.Parallel() @@ -737,6 +740,9 @@ func TestArbAddressTableDoesntRevert(t *testing.T) { Require(t, err) } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbAggregatorDoesntRevert(t *testing.T) { t.Parallel() @@ -762,6 +768,9 @@ func TestArbAggregatorDoesntRevert(t *testing.T) { Require(t, err) } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbosTestDoesntRevert(t *testing.T) { t.Parallel() @@ -781,6 +790,9 @@ func TestArbosTestDoesntRevert(t *testing.T) { Require(t, err) } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbSysDoesntRevert(t *testing.T) { t.Parallel() @@ -877,6 +889,9 @@ func TestChainOwners(t *testing.T) { } } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbOwnerDoesntRevert(t *testing.T) { t.Parallel() @@ -917,6 +932,9 @@ func TestArbOwnerDoesntRevert(t *testing.T) { Require(t, err) } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbGasInfoDoesntRevert(t *testing.T) { t.Parallel() diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 070902c155..5c90d3c7d5 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -445,6 +445,9 @@ func TestGetLifetime(t *testing.T) { } } +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. func TestArbRetryableTxDoesntRevert(t *testing.T) { t.Parallel() From c3b667735468027063b841144a9b5d3ba90f23f2 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Tue, 15 Oct 2024 15:56:36 -0300 Subject: [PATCH 71/82] Reuse precompile addresses defined in types --- system_tests/precompile_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index 379d939835..cdf63ffc98 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -83,7 +83,7 @@ func TestArbDebugPanic(t *testing.T) { auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) + arbDebug, err := precompilesgen.NewArbDebug(types.ArbDebugAddress, builder.L2.Client) Require(t, err) _, err = arbDebug.Panic(&auth) @@ -141,7 +141,7 @@ func TestCustomSolidityErrors(t *testing.T) { } } - arbDebug, err := precompilesgen.NewArbDebug(common.HexToAddress("0xff"), builder.L2.Client) + arbDebug, err := precompilesgen.NewArbDebug(types.ArbDebugAddress, builder.L2.Client) Require(t, err, "could not bind ArbDebug contract") ensure( arbDebug.CustomRevert(callOpts, 1024), @@ -158,7 +158,7 @@ func TestCustomSolidityErrors(t *testing.T) { "arbSys.ArbBlockHash", ) - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(types.ArbRetryableTxAddress, builder.L2.Client) Require(t, err) _, customError = arbRetryableTx.SubmitRetryable( &auth, @@ -455,7 +455,7 @@ func TestCurrentTxL1GasFees(t *testing.T) { cleanup := builder.Build(t) defer cleanup() - arbGasInfo, err := precompilesgen.NewArbGasInfo(common.HexToAddress("0x6c"), builder.L2.Client) + arbGasInfo, err := precompilesgen.NewArbGasInfo(types.ArbGasInfoAddress, builder.L2.Client) Require(t, err) currTxL1GasFees, err := arbGasInfo.GetCurrentTxL1GasFees(&bind.CallOpts{Context: ctx}) @@ -478,11 +478,11 @@ func TestGetBrotliCompressionLevel(t *testing.T) { auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(common.HexToAddress("0x6b"), builder.L2.Client) - Require(t, err, "could not bind ArbOwner contract") + arbOwnerPublic, err := precompilesgen.NewArbOwnerPublic(types.ArbOwnerPublicAddress, builder.L2.Client) + Require(t, err) - arbOwner, err := precompilesgen.NewArbOwner(common.HexToAddress("0x70"), builder.L2.Client) - Require(t, err, "could not bind ArbOwner contract") + arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) brotliCompressionLevel := uint64(11) @@ -495,7 +495,7 @@ func TestGetBrotliCompressionLevel(t *testing.T) { // retrieves brotli compression level callOpts := &bind.CallOpts{Context: ctx} retrievedBrotliCompressionLevel, err := arbOwnerPublic.GetBrotliCompressionLevel(callOpts) - Require(t, err, "failed to call GetBrotliCompressionLevel") + Require(t, err) if retrievedBrotliCompressionLevel != brotliCompressionLevel { Fatal(t, "expected brotli compression level to be", brotliCompressionLevel, "got", retrievedBrotliCompressionLevel) } From c4a6548f2afadeba3afdd49e5fb0983a6ff85631 Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Thu, 17 Oct 2024 09:47:31 -0300 Subject: [PATCH 72/82] Moves precompile DoesntRevert tests to its own file --- system_tests/precompile_doesnt_revert_test.go | 248 ++++++++++++++++++ system_tests/precompile_test.go | 225 ---------------- system_tests/retryable_test.go | 22 -- 3 files changed, 248 insertions(+), 247 deletions(-) create mode 100644 system_tests/precompile_doesnt_revert_test.go diff --git a/system_tests/precompile_doesnt_revert_test.go b/system_tests/precompile_doesnt_revert_test.go new file mode 100644 index 0000000000..e6751d347d --- /dev/null +++ b/system_tests/precompile_doesnt_revert_test.go @@ -0,0 +1,248 @@ +// Copyright 2021-2024, Offchain Labs, Inc. +// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE + +package arbtest + +import ( + "context" + "encoding/json" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "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/nitro/arbos/l1pricing" + "github.com/offchainlabs/nitro/solgen/go/precompilesgen" +) + +// DoesntRevert tests are useful to check if precompile calls revert due to differences in the +// return types of a contract between go and solidity. +// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. + +func TestArbAddressTableDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAddressTable, err := precompilesgen.NewArbAddressTable(types.ArbAddressTableAddress, builder.L2.Client) + Require(t, err) + + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + exists, err := arbAddressTable.AddressExists(callOpts, addr) + Require(t, err) + if exists { + Fatal(t, "expected address to not exist") + } + + tx, err := arbAddressTable.Register(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + idx, err := arbAddressTable.Lookup(callOpts, addr) + Require(t, err) + + retrievedAddr, err := arbAddressTable.LookupIndex(callOpts, idx) + Require(t, err) + if retrievedAddr.Cmp(addr) != 0 { + Fatal(t, "expected retrieved address to be", addr, "got", retrievedAddr) + } + + size, err := arbAddressTable.Size(callOpts) + Require(t, err) + if size.Cmp(big.NewInt(1)) != 0 { + Fatal(t, "expected size to be 1, got", size) + } + + tx, err = arbAddressTable.Compress(&auth, addr) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + res := []uint8{128} + _, _, err = arbAddressTable.Decompress(callOpts, res, big.NewInt(0)) + Require(t, err) +} + +func TestArbAggregatorDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + callOpts := &bind.CallOpts{Context: ctx} + + arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) + Require(t, err) + + tx, err := arbAggregator.SetFeeCollector(&auth, l1pricing.BatchPosterAddress, common.Address{}) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + _, err = arbAggregator.GetFeeCollector(callOpts, l1pricing.BatchPosterAddress) + Require(t, err) +} + +func TestArbosTestDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbosTest, err := precompilesgen.NewArbosTest(types.ArbosTestAddress, builder.L2.Client) + Require(t, err) + + err = arbosTest.BurnArbGas(callOpts, big.NewInt(1)) + Require(t, err) +} + +func TestArbSysDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, builder.L2.Client) + Require(t, err) + + addr1 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + addr2 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + _, err = arbSys.MapL1SenderContractAddressToL2Alias(callOpts, addr1, addr2) + Require(t, err) +} + +func TestArbOwnerDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) + + arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) + Require(t, err) + + chainConfig := params.ArbitrumDevTestChainConfig() + chainConfig.ArbitrumChainParams.MaxCodeSize = 100 + serializedChainConfig, err := json.Marshal(chainConfig) + Require(t, err) + tx, err := arbOwner.SetChainConfig(&auth, string(serializedChainConfig)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.SetAmortizedCostCapBips(&auth, 77734) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.ReleaseL1PricerSurplusFunds(&auth, big.NewInt(1)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) + + tx, err = arbOwner.SetL2BaseFee(&auth, big.NewInt(1)) + Require(t, err) + _, err = builder.L2.EnsureTxSucceeded(tx) + Require(t, err) +} + +func TestArbGasInfoDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) + + arbGasInfo, err := precompilesgen.NewArbGasInfo(types.ArbGasInfoAddress, builder.L2.Client) + Require(t, err) + + _, err = arbGasInfo.GetGasBacklog(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetLastL1PricingUpdateTime(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1PricingFundsDueForRewards(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1PricingUnitsSinceUpdate(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetLastL1PricingSurplus(callOpts) + Require(t, err) + + _, _, _, err = arbGasInfo.GetPricesInArbGas(callOpts) + Require(t, err) + + _, _, _, err = arbGasInfo.GetPricesInArbGasWithAggregator(callOpts, addr) + Require(t, err) + + _, err = arbGasInfo.GetAmortizedCostCapBips(callOpts) + Require(t, err) + + _, err = arbGasInfo.GetL1FeesAvailable(callOpts) + Require(t, err) + + _, _, _, _, _, _, err = arbGasInfo.GetPricesInWeiWithAggregator(callOpts, addr) + Require(t, err) +} + +func TestArbRetryableTxDoesntRevert(t *testing.T) { + t.Parallel() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + builder := NewNodeBuilder(ctx).DefaultConfig(t, false) + cleanup := builder.Build(t) + defer cleanup() + + callOpts := &bind.CallOpts{Context: ctx} + + arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) + Require(t, err) + + _, err = arbRetryableTx.GetCurrentRedeemer(callOpts) + Require(t, err) +} diff --git a/system_tests/precompile_test.go b/system_tests/precompile_test.go index cdf63ffc98..9d5737c249 100644 --- a/system_tests/precompile_test.go +++ b/system_tests/precompile_test.go @@ -5,7 +5,6 @@ package arbtest import ( "context" - "encoding/json" "fmt" "math/big" "sort" @@ -683,137 +682,6 @@ func TestFeeAccounts(t *testing.T) { } } -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbAddressTableDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - callOpts := &bind.CallOpts{Context: ctx} - - arbAddressTable, err := precompilesgen.NewArbAddressTable(types.ArbAddressTableAddress, builder.L2.Client) - Require(t, err) - - addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - - exists, err := arbAddressTable.AddressExists(callOpts, addr) - Require(t, err) - if exists { - Fatal(t, "expected address to not exist") - } - - tx, err := arbAddressTable.Register(&auth, addr) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - idx, err := arbAddressTable.Lookup(callOpts, addr) - Require(t, err) - - retrievedAddr, err := arbAddressTable.LookupIndex(callOpts, idx) - Require(t, err) - if retrievedAddr.Cmp(addr) != 0 { - Fatal(t, "expected retrieved address to be", addr, "got", retrievedAddr) - } - - size, err := arbAddressTable.Size(callOpts) - Require(t, err) - if size.Cmp(big.NewInt(1)) != 0 { - Fatal(t, "expected size to be 1, got", size) - } - - tx, err = arbAddressTable.Compress(&auth, addr) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - res := []uint8{128} - _, _, err = arbAddressTable.Decompress(callOpts, res, big.NewInt(0)) - Require(t, err) -} - -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbAggregatorDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - callOpts := &bind.CallOpts{Context: ctx} - - arbAggregator, err := precompilesgen.NewArbAggregator(types.ArbAggregatorAddress, builder.L2.Client) - Require(t, err) - - tx, err := arbAggregator.SetFeeCollector(&auth, l1pricing.BatchPosterAddress, common.Address{}) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - _, err = arbAggregator.GetFeeCollector(callOpts, l1pricing.BatchPosterAddress) - Require(t, err) -} - -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbosTestDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - callOpts := &bind.CallOpts{Context: ctx} - - arbosTest, err := precompilesgen.NewArbosTest(types.ArbosTestAddress, builder.L2.Client) - Require(t, err) - - err = arbosTest.BurnArbGas(callOpts, big.NewInt(1)) - Require(t, err) -} - -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbSysDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - callOpts := &bind.CallOpts{Context: ctx} - - arbSys, err := precompilesgen.NewArbSys(types.ArbSysAddress, builder.L2.Client) - Require(t, err) - - addr1 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - addr2 := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - _, err = arbSys.MapL1SenderContractAddressToL2Alias(callOpts, addr1, addr2) - Require(t, err) -} - func TestChainOwners(t *testing.T) { t.Parallel() @@ -889,99 +757,6 @@ func TestChainOwners(t *testing.T) { } } -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbOwnerDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) - - arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, builder.L2.Client) - Require(t, err) - - chainConfig := params.ArbitrumDevTestChainConfig() - chainConfig.ArbitrumChainParams.MaxCodeSize = 100 - serializedChainConfig, err := json.Marshal(chainConfig) - Require(t, err) - tx, err := arbOwner.SetChainConfig(&auth, string(serializedChainConfig)) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - tx, err = arbOwner.SetAmortizedCostCapBips(&auth, 77734) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - tx, err = arbOwner.ReleaseL1PricerSurplusFunds(&auth, big.NewInt(1)) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) - - tx, err = arbOwner.SetL2BaseFee(&auth, big.NewInt(1)) - Require(t, err) - _, err = builder.L2.EnsureTxSucceeded(tx) - Require(t, err) -} - -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbGasInfoDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - callOpts := &bind.CallOpts{Context: ctx} - addr := common.BytesToAddress(crypto.Keccak256([]byte{})[:20]) - - arbGasInfo, err := precompilesgen.NewArbGasInfo(types.ArbGasInfoAddress, builder.L2.Client) - Require(t, err) - - _, err = arbGasInfo.GetGasBacklog(callOpts) - Require(t, err) - - _, err = arbGasInfo.GetLastL1PricingUpdateTime(callOpts) - Require(t, err) - - _, err = arbGasInfo.GetL1PricingFundsDueForRewards(callOpts) - Require(t, err) - - _, err = arbGasInfo.GetL1PricingUnitsSinceUpdate(callOpts) - Require(t, err) - - _, err = arbGasInfo.GetLastL1PricingSurplus(callOpts) - Require(t, err) - - _, _, _, err = arbGasInfo.GetPricesInArbGas(callOpts) - Require(t, err) - - _, _, _, err = arbGasInfo.GetPricesInArbGasWithAggregator(callOpts, addr) - Require(t, err) - - _, err = arbGasInfo.GetAmortizedCostCapBips(callOpts) - Require(t, err) - - _, err = arbGasInfo.GetL1FeesAvailable(callOpts) - Require(t, err) - - _, _, _, _, _, _, err = arbGasInfo.GetPricesInWeiWithAggregator(callOpts, addr) - Require(t, err) -} - func TestArbAggregatorBatchPosters(t *testing.T) { t.Parallel() diff --git a/system_tests/retryable_test.go b/system_tests/retryable_test.go index 5c90d3c7d5..89446e3c4b 100644 --- a/system_tests/retryable_test.go +++ b/system_tests/retryable_test.go @@ -445,28 +445,6 @@ func TestGetLifetime(t *testing.T) { } } -// DoesntRevert tests are useful to check if precompile calls revert due to differences in the -// return types of a contract between go and solidity. -// They are not a substitute for unit tests, as they don't test the actual functionality of the precompile. -func TestArbRetryableTxDoesntRevert(t *testing.T) { - t.Parallel() - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - builder := NewNodeBuilder(ctx).DefaultConfig(t, false) - cleanup := builder.Build(t) - defer cleanup() - - callOpts := &bind.CallOpts{Context: ctx} - - arbRetryableTx, err := precompilesgen.NewArbRetryableTx(common.HexToAddress("6e"), builder.L2.Client) - Require(t, err) - - _, err = arbRetryableTx.GetCurrentRedeemer(callOpts) - Require(t, err) -} - func TestKeepaliveAndCancelRetryable(t *testing.T) { t.Parallel() builder, delayedInbox, lookupL2Tx, ctx, teardown := retryableSetup(t) From 1a1e179c737dc41424ab634fd481ead15c6485e4 Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Mon, 21 Oct 2024 16:58:28 +0530 Subject: [PATCH 73/82] Log from batch poster for which das backends are using chunked vs legacy store --- das/dasRpcClient.go | 1 + 1 file changed, 1 insertion(+) diff --git a/das/dasRpcClient.go b/das/dasRpcClient.go index 241f2196b1..d6e2c389c9 100644 --- a/das/dasRpcClient.go +++ b/das/dasRpcClient.go @@ -101,6 +101,7 @@ func (c *DASRPCClient) Store(ctx context.Context, message []byte, timeout uint64 var startChunkedStoreResult StartChunkedStoreResult if err := c.clnt.CallContext(ctx, &startChunkedStoreResult, "das_startChunkedStore", hexutil.Uint64(timestamp), hexutil.Uint64(nChunks), hexutil.Uint64(c.chunkSize), hexutil.Uint64(totalSize), hexutil.Uint64(timeout), hexutil.Bytes(startReqSig)); err != nil { if strings.Contains(err.Error(), "the method das_startChunkedStore does not exist") { + log.Info("Legacy store is used by the DAS client", "url", c.url) return c.legacyStore(ctx, message, timeout) } return nil, err From 044f70bd6312d0e71fe1dff386d9325db71f02db Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Tue, 22 Oct 2024 12:52:24 +0530 Subject: [PATCH 74/82] address PR comments --- system_tests/program_test.go | 94 +++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 44 deletions(-) diff --git a/system_tests/program_test.go b/system_tests/program_test.go index 9c8fe949ab..c240aaad6b 100644 --- a/system_tests/program_test.go +++ b/system_tests/program_test.go @@ -1268,66 +1268,75 @@ func TestStylusPrecompileMethodsSimple(t *testing.T) { ownerAuth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx) ensure(arbDebug.BecomeChainOwner(&ownerAuth)) - // ArbOwner precompile methods - testConst := uint16(10) - ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(testConst))) - ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(testConst))) - ensure(arbOwner.SetWasmFreePages(&ownerAuth, testConst)) - ensure(arbOwner.SetWasmPageGas(&ownerAuth, testConst)) - ensure(arbOwner.SetWasmPageLimit(&ownerAuth, testConst)) - // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, - // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits - ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) - ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(testConst))) - expectedExpiryDays := uint16(1) - ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) - ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) - ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, testConst)) - - // ArbWasm precompile methods wasm, _ := readWasmFile(t, rustFile("keccak")) - codehash := crypto.Keccak256Hash(wasm) programAddress := deployContract(t, ctx, ownerAuth, builder.L2.Client, wasm) activateAuth := ownerAuth activateAuth.Value = oneEth ensure(arbWasm.ActivateProgram(&activateAuth, programAddress)) - bcs, err := arbWasm.BlockCacheSize(nil) - Require(t, err) - if bcs != testConst { - t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, testConst) - } + expectedExpiryDays := uint16(1) + ensure(arbOwner.SetWasmExpiryDays(&ownerAuth, expectedExpiryDays)) ed, err := arbWasm.ExpiryDays(nil) Require(t, err) if ed != expectedExpiryDays { t.Errorf("ExpiryDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ed, expectedExpiryDays) } + ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) + Require(t, err) + expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) + // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day + // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that + // rounds down (the current time since ArbitrumStartTime in hours)/3600 + if expectedExpirySeconds-ptl > 3600 { + t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) + } + + ensure(arbOwner.SetWasmBlockCacheSize(&ownerAuth, 100)) + bcs, err := arbWasm.BlockCacheSize(nil) + Require(t, err) + if bcs != 100 { + t.Errorf("BlockCacheSize from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", bcs, 100) + } + + ensure(arbOwner.SetWasmFreePages(&ownerAuth, 3)) fp, err := arbWasm.FreePages(nil) Require(t, err) - if fp != testConst { - t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, testConst) + if fp != 3 { + t.Errorf("FreePages from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", fp, 3) } + + ensure(arbOwner.SetWasmInitCostScalar(&ownerAuth, uint64(4))) ics, err := arbWasm.InitCostScalar(nil) Require(t, err) - if ics != uint64(testConst) { - t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, testConst) + if ics != uint64(4) { + t.Errorf("InitCostScalar from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ics, 4) } + + ensure(arbOwner.SetInkPrice(&ownerAuth, uint32(5))) ip, err := arbWasm.InkPrice(nil) Require(t, err) - if ip != uint32(testConst) { - t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, testConst) + if ip != uint32(5) { + t.Errorf("InkPrice from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", ip, 5) } + + ensure(arbOwner.SetWasmKeepaliveDays(&ownerAuth, 0)) kad, err := arbWasm.KeepaliveDays(nil) Require(t, err) if kad != 0 { t.Errorf("KeepaliveDays from arbWasm precompile didnt match the value set by arbowner. have: %d, want: 0", kad) } + + ensure(arbOwner.SetWasmMaxStackDepth(&ownerAuth, uint32(6))) msd, err := arbWasm.MaxStackDepth(nil) Require(t, err) - if msd != uint32(testConst) { - t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, testConst) + if msd != uint32(6) { + t.Errorf("MaxStackDepth from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", msd, 6) } + + // Setting low values of gas and cached parameters ensures when MinInitGas is called on ArbWasm precompile, + // the returned values would be programs.MinInitGasUnits and programs.MinCachedGasUnits + ensure(arbOwner.SetWasmMinInitGas(&ownerAuth, 1, 1)) mig, err := arbWasm.MinInitGas(nil) Require(t, err) if mig.Gas != programs.MinInitGasUnits { @@ -1336,34 +1345,31 @@ func TestStylusPrecompileMethodsSimple(t *testing.T) { if mig.Cached != programs.MinCachedGasUnits { t.Errorf("MinInitGas from arbWasm precompile didnt match the Cached value set by arbowner. have: %d, want: %d", mig.Cached, programs.MinCachedGasUnits) } + + ensure(arbOwner.SetWasmPageGas(&ownerAuth, 7)) pg, err := arbWasm.PageGas(nil) Require(t, err) - if pg != testConst { - t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, testConst) + if pg != 7 { + t.Errorf("PageGas from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pg, 7) } + + ensure(arbOwner.SetWasmPageLimit(&ownerAuth, 8)) pl, err := arbWasm.PageLimit(nil) Require(t, err) - if pl != testConst { - t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, testConst) + if pl != 8 { + t.Errorf("PageLimit from arbWasm precompile didnt match the value set by arbowner. have: %d, want: %d", pl, 8) } + // pageramp currently is initialPageRamp = 620674314 value in programs package _, err = arbWasm.PageRamp(nil) Require(t, err) + codehash := crypto.Keccak256Hash(wasm) cas, err := arbWasm.CodehashAsmSize(nil, codehash) Require(t, err) if cas == 0 { t.Error("CodehashAsmSize from arbWasm precompile returned 0 value") } - ptl, err := arbWasm.ProgramTimeLeft(nil, programAddress) - Require(t, err) - expectedExpirySeconds := (uint64(expectedExpiryDays) * 24 * 3600) - // ProgramTimeLeft returns time in seconds to expiry and the current ExpiryDays is set to 1 day - // We expect the lag of 3600 seconds to exist because program.activatedAt uses hoursSinceArbitrum that - // rounds down (the current time since ArbitrumStartTime in hours)/3600 - if expectedExpirySeconds-ptl > 3600 { - t.Errorf("ProgramTimeLeft from arbWasm precompile returned value lesser than expected. %d <= want <= %d, have: %d", expectedExpirySeconds-3600, expectedExpirySeconds, ptl) - } // Since ArbOwner has set wasm KeepaliveDays to 0, it enables us to do this, though this shouldn't have any effect codehashKeepaliveAuth := ownerAuth codehashKeepaliveAuth.Value = oneEth From 94e252aa24d8f7587f6faf9583a19769d742fed5 Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Tue, 22 Oct 2024 11:01:26 -0400 Subject: [PATCH 75/82] add flag to remove docker in docker --- Makefile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4c5550d199..64d5acfd08 100644 --- a/Makefile +++ b/Makefile @@ -579,9 +579,15 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w +ifdef NODOCKERINDOCKER + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w +else + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w -d + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w -d + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w -d +endif @touch $@ .make/wasm-lib: $(DEP_PREDICATE) arbitrator/wasm-libraries/soft-float/SoftFloat/build/Wasm-Clang/softfloat.a $(ORDER_ONLY_PREDICATE) .make From 6680d818dbeaadf8f56729ba1bcc919d861a05ee Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Tue, 22 Oct 2024 12:30:59 -0400 Subject: [PATCH 76/82] update flags --- Dockerfile | 2 +- Makefile | 12 +++--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index aba5432254..aec8e831f3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -115,7 +115,7 @@ COPY --from=brotli-wasm-export / target/ COPY scripts/build-brotli.sh scripts/ COPY brotli brotli RUN apt-get update && apt-get install -y cmake -RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-header +RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-header ARGS="-w -d" FROM scratch AS prover-header-export COPY --from=prover-header-builder /workspace/target/ / diff --git a/Makefile b/Makefile index 64d5acfd08..2eb6ea54be 100644 --- a/Makefile +++ b/Makefile @@ -579,15 +579,9 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make -ifdef NODOCKERINDOCKER - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w -else - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w -d - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w -d - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w -d -endif + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh $(ARGS) + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh $(ARGS) + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh $(ARGS) @touch $@ .make/wasm-lib: $(DEP_PREDICATE) arbitrator/wasm-libraries/soft-float/SoftFloat/build/Wasm-Clang/softfloat.a $(ORDER_ONLY_PREDICATE) .make From 08618e2bd61f221b950efc3e74ac6c6eea41406d Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Tue, 22 Oct 2024 14:08:14 -0400 Subject: [PATCH 77/82] update names and defaults --- Dockerfile | 2 +- Makefile | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index aec8e831f3..aba5432254 100644 --- a/Dockerfile +++ b/Dockerfile @@ -115,7 +115,7 @@ COPY --from=brotli-wasm-export / target/ COPY scripts/build-brotli.sh scripts/ COPY brotli brotli RUN apt-get update && apt-get install -y cmake -RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-header ARGS="-w -d" +RUN NITRO_BUILD_IGNORE_TIMESTAMPS=1 make build-prover-header FROM scratch AS prover-header-export COPY --from=prover-header-builder /workspace/target/ / diff --git a/Makefile b/Makefile index 2eb6ea54be..5a7227ab86 100644 --- a/Makefile +++ b/Makefile @@ -579,9 +579,10 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh $(ARGS) - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh $(ARGS) - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh $(ARGS) + CBROTLI_WASM_BUILD_ARGS ?= -w -d + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) @touch $@ .make/wasm-lib: $(DEP_PREDICATE) arbitrator/wasm-libraries/soft-float/SoftFloat/build/Wasm-Clang/softfloat.a $(ORDER_ONLY_PREDICATE) .make From 82c01951094e84de8f0115765465d4c43ddf079c Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Wed, 23 Oct 2024 10:40:15 -0400 Subject: [PATCH 78/82] move var --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5a7227ab86..ff285ba0fb 100644 --- a/Makefile +++ b/Makefile @@ -155,6 +155,8 @@ stylus_test_hostio-test_src = $(call get_stylus_test_rust,hostio-test) stylus_test_wasms = $(stylus_test_keccak_wasm) $(stylus_test_keccak-100_wasm) $(stylus_test_fallible_wasm) $(stylus_test_storage_wasm) $(stylus_test_multicall_wasm) $(stylus_test_log_wasm) $(stylus_test_create_wasm) $(stylus_test_math_wasm) $(stylus_test_sdk-storage_wasm) $(stylus_test_erc20_wasm) $(stylus_test_read-return-data_wasm) $(stylus_test_evm-data_wasm) $(stylus_test_hostio-test_wasm) $(stylus_test_bfs:.b=.wasm) stylus_benchmarks = $(wildcard $(stylus_dir)/*.toml $(stylus_dir)/src/*.rs) $(stylus_test_wasms) +CBROTLI_WASM_BUILD_ARGS ?= -w -d + # user targets .PHONY: push @@ -579,7 +581,6 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make - CBROTLI_WASM_BUILD_ARGS ?= -w -d test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) From 0790c9d0d4a747a5b5d8e91cac9986804d0d3a05 Mon Sep 17 00:00:00 2001 From: Nick Hovsmith Date: Wed, 23 Oct 2024 12:25:37 -0400 Subject: [PATCH 79/82] always include -w --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index ff285ba0fb..12dfb07cf8 100644 --- a/Makefile +++ b/Makefile @@ -155,7 +155,7 @@ stylus_test_hostio-test_src = $(call get_stylus_test_rust,hostio-test) stylus_test_wasms = $(stylus_test_keccak_wasm) $(stylus_test_keccak-100_wasm) $(stylus_test_fallible_wasm) $(stylus_test_storage_wasm) $(stylus_test_multicall_wasm) $(stylus_test_log_wasm) $(stylus_test_create_wasm) $(stylus_test_math_wasm) $(stylus_test_sdk-storage_wasm) $(stylus_test_erc20_wasm) $(stylus_test_read-return-data_wasm) $(stylus_test_evm-data_wasm) $(stylus_test_hostio-test_wasm) $(stylus_test_bfs:.b=.wasm) stylus_benchmarks = $(wildcard $(stylus_dir)/*.toml $(stylus_dir)/src/*.rs) $(stylus_test_wasms) -CBROTLI_WASM_BUILD_ARGS ?= -w -d +CBROTLI_WASM_BUILD_ARGS ?=-d # user targets @@ -581,9 +581,9 @@ contracts/test/prover/proofs/%.json: $(arbitrator_cases)/%.wasm $(prover_bin) @touch $@ .make/cbrotli-wasm: $(DEP_PREDICATE) $(ORDER_ONLY_PREDICATE) .make - test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) - test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) - test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh $(CBROTLI_WASM_BUILD_ARGS) + test -f target/lib-wasm/libbrotlicommon-static.a || ./scripts/build-brotli.sh -w $(CBROTLI_WASM_BUILD_ARGS) + test -f target/lib-wasm/libbrotlienc-static.a || ./scripts/build-brotli.sh -w $(CBROTLI_WASM_BUILD_ARGS) + test -f target/lib-wasm/libbrotlidec-static.a || ./scripts/build-brotli.sh -w $(CBROTLI_WASM_BUILD_ARGS) @touch $@ .make/wasm-lib: $(DEP_PREDICATE) arbitrator/wasm-libraries/soft-float/SoftFloat/build/Wasm-Clang/softfloat.a $(ORDER_ONLY_PREDICATE) .make From dccdae1306a4695f92f80872851722a4fa6b8f80 Mon Sep 17 00:00:00 2001 From: Ganesh Vanahalli Date: Fri, 25 Oct 2024 09:46:01 +0530 Subject: [PATCH 80/82] Attempt to clear from PEL again after successfull deletion of Lower --- pubsub/producer.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pubsub/producer.go b/pubsub/producer.go index dacaeba7d0..722c145a09 100644 --- a/pubsub/producer.go +++ b/pubsub/producer.go @@ -201,8 +201,9 @@ func (p *Producer[Request, Response]) clearMessages(ctx context.Context) time.Du } if _, err := p.client.XDel(ctx, p.redisStream, pelData.Lower).Result(); err != nil { log.Error("error deleting PEL's lower message thats past its TTL", "msgID", pelData.Lower, "err", err) - return 0 + return 5 * p.cfg.CheckResultInterval } + return 0 } } return 5 * p.cfg.CheckResultInterval From 7c595e2ddfc059d6d7e130b2937af4d49679142b Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 25 Oct 2024 10:14:25 -0300 Subject: [PATCH 81/82] Fix check that verifies if enough time has passed to allow posting a batch with only batch posting report --- arbnode/batch_poster.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index dcca27e1c6..a928aa6ba4 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -1306,7 +1306,8 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error) b.building.muxBackend.delayedInbox = append(b.building.muxBackend.delayedInbox, msg) } } - if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (time.Since(firstMsgTime) >= config.MaxEmptyBatchDelay) { + timeSinceMsg := time.Since(time.Unix(int64(msg.Message.Header.Timestamp), 0)) + if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (timeSinceMsg >= config.MaxEmptyBatchDelay) { b.building.haveUsefulMessage = true if b.building.firstUsefulMsg == nil { b.building.firstUsefulMsg = msg From 489e1529f8e13164b03777f8850bfa1999581f2e Mon Sep 17 00:00:00 2001 From: Diego Ximenes Date: Fri, 25 Oct 2024 11:58:53 -0300 Subject: [PATCH 82/82] Adds missing nosec G115 --- arbnode/batch_poster.go | 1 + 1 file changed, 1 insertion(+) diff --git a/arbnode/batch_poster.go b/arbnode/batch_poster.go index a928aa6ba4..46a0160b71 100644 --- a/arbnode/batch_poster.go +++ b/arbnode/batch_poster.go @@ -1306,6 +1306,7 @@ func (b *BatchPoster) maybePostSequencerBatch(ctx context.Context) (bool, error) b.building.muxBackend.delayedInbox = append(b.building.muxBackend.delayedInbox, msg) } } + // #nosec G115 timeSinceMsg := time.Since(time.Unix(int64(msg.Message.Header.Timestamp), 0)) if (msg.Message.Header.Kind != arbostypes.L1MessageType_BatchPostingReport) || (timeSinceMsg >= config.MaxEmptyBatchDelay) { b.building.haveUsefulMessage = true