Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestArbos11To32Upgrade #2837

Merged
merged 18 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are tons of other changes in the contracts. Maybe the branch you chose as a base wasn't the correct one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitro-contracts/pre-bold was branched off nitro-contracts/main.
There were some changes introduced in nitro-contracts/main that were not included in nitro's contracts submodule, these are the changes in the contracts that you are observing.

186 changes: 186 additions & 0 deletions system_tests/arbos_upgrade_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright 2021-2024, Offchain Labs, Inc.
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE

package arbtest

import (
"context"
"math/big"
"strings"
"testing"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"

"github.com/offchainlabs/nitro/arbnode"
"github.com/offchainlabs/nitro/arbos/arbosState"
"github.com/offchainlabs/nitro/solgen/go/mocksgen"
"github.com/offchainlabs/nitro/solgen/go/precompilesgen"
)

func TestScheduleArbosUpgrade(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")

callOpts := &bind.CallOpts{Context: ctx}
scheduled, err := arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade before scheduling upgrade")
if scheduled.ArbosVersion != 0 || scheduled.ScheduledForTimestamp != 0 {
t.Errorf("expected no upgrade to be scheduled, got version %v timestamp %v", scheduled.ArbosVersion, scheduled.ScheduledForTimestamp)
}

// Schedule a noop upgrade, which should test GetScheduledUpgrade in the same way an already completed upgrade would.
tx, err := arbOwner.ScheduleArbOSUpgrade(&auth, 1, 1)
Require(t, err)
_, err = builder.L2.EnsureTxSucceeded(tx)
Require(t, err)

scheduled, err = arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade after scheduling noop upgrade")
if scheduled.ArbosVersion != 0 || scheduled.ScheduledForTimestamp != 0 {
t.Errorf("expected completed scheduled upgrade to be ignored, got version %v timestamp %v", scheduled.ArbosVersion, scheduled.ScheduledForTimestamp)
}

// We can't test 11 -> 20 because 11 doesn't have the GetScheduledUpgrade method we want to test
var testVersion uint64 = 100
var testTimestamp uint64 = 1 << 62
tx, err = arbOwner.ScheduleArbOSUpgrade(&auth, 100, 1<<62)
Require(t, err)
_, err = builder.L2.EnsureTxSucceeded(tx)
Require(t, err)

scheduled, err = arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade after scheduling upgrade")
if scheduled.ArbosVersion != testVersion || scheduled.ScheduledForTimestamp != testTimestamp {
t.Errorf("expected upgrade to be scheduled for version %v timestamp %v, got version %v timestamp %v", testVersion, testTimestamp, scheduled.ArbosVersion, scheduled.ScheduledForTimestamp)
}
}

func checkArbOSVersion(t *testing.T, testClient *TestClient, expectedVersion uint64, scenario string) {
statedb, err := testClient.ExecNode.Backend.ArbInterface().BlockChain().State()
Require(t, err, "could not get statedb", scenario)
state, err := arbosState.OpenSystemArbosState(statedb, nil, true)
Require(t, err, "could not open ArbOS state", scenario)
if state.ArbOSVersion() != expectedVersion {
t.Errorf("%s: expected ArbOS version %v, got %v", scenario, expectedVersion, state.ArbOSVersion())
}

}

func TestArbos11To32Upgrade(t *testing.T) {
t.Parallel()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

initialVersion := uint64(11)
finalVersion := uint64(32)

builder := NewNodeBuilder(ctx).
DefaultConfig(t, true).
WithArbOSVersion(initialVersion)
cleanup := builder.Build(t)
defer cleanup()
seqTestClient := builder.L2

auth := builder.L2Info.GetDefaultTransactOpts("Owner", ctx)
auth.GasLimit = 32000000

// makes Owner a chain owner
arbDebug, err := precompilesgen.NewArbDebug(types.ArbDebugAddress, seqTestClient.Client)
Require(t, err)
tx, err := arbDebug.BecomeChainOwner(&auth)
Require(t, err)
_, err = EnsureTxSucceeded(ctx, seqTestClient.Client, tx)
Require(t, err)

// deploys test contract
_, tx, contract, err := mocksgen.DeployArbOS11To32UpgradeTest(&auth, seqTestClient.Client)
Require(t, err)
_, err = EnsureTxSucceeded(ctx, seqTestClient.Client, tx)
Require(t, err)

// build replica node
replicaConfig := arbnode.ConfigDefaultL1Test()
replicaConfig.BatchPoster.Enable = false
replicaTestClient, replicaCleanup := builder.Build2ndNode(t, &SecondNodeParams{nodeConfig: replicaConfig})
defer replicaCleanup()

checkArbOSVersion(t, seqTestClient, initialVersion, "initial sequencer")
checkArbOSVersion(t, replicaTestClient, initialVersion, "initial replica")

// mcopy should fail since arbos 11 doesn't support it
tx, err = contract.Mcopy(&auth)
Require(t, err)
_, err = seqTestClient.EnsureTxSucceeded(tx)
if (err == nil) || !strings.Contains(err.Error(), "invalid opcode: MCOPY") {
t.Errorf("expected MCOPY to fail, got %v", err)
}
_, err = WaitForTx(ctx, replicaTestClient.Client, tx.Hash(), time.Second*15)
Require(t, err)

// upgrade arbos to final version
arbOwner, err := precompilesgen.NewArbOwner(types.ArbOwnerAddress, seqTestClient.Client)
Require(t, err)
tx, err = arbOwner.ScheduleArbOSUpgrade(&auth, finalVersion, 0)
Require(t, err)
_, err = seqTestClient.EnsureTxSucceeded(tx)
Require(t, err)
_, err = WaitForTx(ctx, replicaTestClient.Client, tx.Hash(), time.Second*15)
Require(t, err)

// checks upgrade worked
tx, err = contract.Mcopy(&auth)
Require(t, err)
_, err = seqTestClient.EnsureTxSucceeded(tx)
Require(t, err)
_, err = WaitForTx(ctx, replicaTestClient.Client, tx.Hash(), time.Second*15)
Require(t, err)

checkArbOSVersion(t, seqTestClient, finalVersion, "final sequencer")
checkArbOSVersion(t, replicaTestClient, finalVersion, "final replica")

// generates more blocks
builder.L2Info.GenerateAccount("User2")
for i := 0; i < 3; i++ {
tx = builder.L2Info.PrepareTx("Owner", "User2", builder.L2Info.TransferGas, big.NewInt(1e12), nil)
err = seqTestClient.Client.SendTransaction(ctx, tx)
Require(t, err)
_, err = seqTestClient.EnsureTxSucceeded(tx)
Require(t, err)
_, err = WaitForTx(ctx, replicaTestClient.Client, tx.Hash(), time.Second*15)
Require(t, err)
}

blockNumberSeq, err := seqTestClient.Client.BlockNumber(ctx)
Require(t, err)
blockNumberReplica, err := replicaTestClient.Client.BlockNumber(ctx)
Require(t, err)
if blockNumberSeq != blockNumberReplica {
t.Errorf("expected sequencer and replica to have same block number, got %v and %v", blockNumberSeq, blockNumberReplica)
}
// #nosec G115
blockNumber := big.NewInt(int64(blockNumberSeq))

blockSeq, err := seqTestClient.Client.BlockByNumber(ctx, blockNumber)
Require(t, err)
blockReplica, err := replicaTestClient.Client.BlockByNumber(ctx, blockNumber)
Require(t, err)
if blockSeq.Hash() != blockReplica.Hash() {
t.Errorf("expected sequencer and replica to have same block hash, got %v and %v", blockSeq.Hash(), blockReplica.Hash())
}
}
51 changes: 0 additions & 51 deletions system_tests/precompile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,57 +504,6 @@ func TestGetBrotliCompressionLevel(t *testing.T) {
}
}

func TestScheduleArbosUpgrade(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")

callOpts := &bind.CallOpts{Context: ctx}
scheduled, err := arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade before scheduling upgrade")
if scheduled.ArbosVersion != 0 || scheduled.ScheduledForTimestamp != 0 {
t.Errorf("expected no upgrade to be scheduled, got version %v timestamp %v", scheduled.ArbosVersion, scheduled.ScheduledForTimestamp)
}

// Schedule a noop upgrade, which should test GetScheduledUpgrade in the same way an already completed upgrade would.
tx, err := arbOwner.ScheduleArbOSUpgrade(&auth, 1, 1)
Require(t, err)
_, err = builder.L2.EnsureTxSucceeded(tx)
Require(t, err)

scheduled, err = arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade after scheduling noop upgrade")
if scheduled.ArbosVersion != 0 || scheduled.ScheduledForTimestamp != 0 {
t.Errorf("expected completed scheduled upgrade to be ignored, got version %v timestamp %v", scheduled.ArbosVersion, scheduled.ScheduledForTimestamp)
}

// TODO: Once we have an ArbOS 30, test a real upgrade with it
// We can't test 11 -> 20 because 11 doesn't have the GetScheduledUpgrade method we want to test
var testVersion uint64 = 100
var testTimestamp uint64 = 1 << 62
tx, err = arbOwner.ScheduleArbOSUpgrade(&auth, 100, 1<<62)
Require(t, err)
_, err = builder.L2.EnsureTxSucceeded(tx)
Require(t, err)

scheduled, err = arbOwnerPublic.GetScheduledUpgrade(callOpts)
Require(t, err, "failed to call GetScheduledUpgrade after scheduling upgrade")
if scheduled.ArbosVersion != testVersion || scheduled.ScheduledForTimestamp != testTimestamp {
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) {
t.Parallel()

Expand Down
Loading