Commit 34e8e691 authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

op-e2e: Parallelize CGT tests (#12464)

* op-e2e: Parallelize CGT tests

Parallelizes the custom gas token tests. This reduces runtime from ~120s to ~60s on my Macbook.

* code review updates
parent 6ae28f56
......@@ -27,6 +27,14 @@ import (
"github.com/stretchr/testify/require"
)
// setup expectations using custom gas token
type cgtTestExpectations struct {
tokenAddress common.Address
tokenName string
tokenSymbol string
tokenDecimals uint8
}
func TestMain(m *testing.M) {
op_e2e.RunMain(m)
}
......@@ -41,6 +49,15 @@ func TestCustomGasToken_Standard(t *testing.T) {
func testCustomGasToken(t *testing.T, allocType config.AllocType) {
op_e2e.InitParallel(t)
disabledExpectations := cgtTestExpectations{
common.HexToAddress("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"),
"Ether",
"ETH",
uint8(18),
}
setup := func() gasTokenTestOpts {
cfg := e2esys.DefaultSystemConfig(t, e2esys.WithAllocType(allocType))
offset := hexutil.Uint64(0)
cfg.DeployConfig.L2GenesisRegolithTimeOffset = &offset
......@@ -53,8 +70,6 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
require.NoError(t, err, "Error starting up system")
l1Client := sys.NodeClient("l1")
l2Client := sys.NodeClient("sequencer")
aliceOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.Alice, cfg.L1ChainIDBig())
require.NoError(t, err)
......@@ -64,20 +79,7 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
_, err = wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err)
// setup expectations using custom gas token
type Expectations struct {
tokenAddress common.Address
tokenName string
tokenSymbol string
tokenDecimals uint8
}
disabledExpectations := Expectations{
common.HexToAddress("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"),
"Ether",
"ETH",
uint8(18),
}
enabledExpectations := Expectations{}
enabledExpectations := cgtTestExpectations{}
enabledExpectations.tokenAddress = weth9Address
enabledExpectations.tokenName, err = weth9.Name(&bind.CallOpts{})
require.NoError(t, err)
......@@ -95,15 +97,206 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
require.NoError(t, err)
require.Equal(t, newBalance, big.NewInt(10_000_000))
// Function to prepare and make call to depositERC20Transaction and make
// appropriate assertions dependent on whether custom gas tokens have been enabled or not.
checkDeposit := func(t *testing.T, enabled bool) {
return gasTokenTestOpts{
aliceOpts: aliceOpts,
cfg: cfg,
weth9: weth9,
weth9Address: weth9Address,
allocType: allocType,
sys: sys,
enabledExpectations: enabledExpectations,
disabledExpectations: disabledExpectations,
}
}
t.Run("deposit", func(t *testing.T) {
op_e2e.InitParallel(t)
gto := setup()
checkDeposit(t, gto, false)
setCustomGasToken(t, gto.cfg, gto.sys, gto.weth9Address)
checkDeposit(t, gto, true)
})
t.Run("withdrawal", func(t *testing.T) {
op_e2e.InitParallel(t)
gto := setup()
setCustomGasToken(t, gto.cfg, gto.sys, gto.weth9Address)
checkDeposit(t, gto, true)
checkWithdrawal(t, gto)
})
t.Run("fee withdrawal", func(t *testing.T) {
op_e2e.InitParallel(t)
gto := setup()
setCustomGasToken(t, gto.cfg, gto.sys, gto.weth9Address)
checkDeposit(t, gto, true)
checkFeeWithdrawal(t, gto, true)
})
t.Run("token name and symbol", func(t *testing.T) {
op_e2e.InitParallel(t)
gto := setup()
checkL1TokenNameAndSymbol(t, gto, gto.disabledExpectations)
checkL2TokenNameAndSymbol(t, gto, gto.disabledExpectations)
checkWETHTokenNameAndSymbol(t, gto, gto.disabledExpectations)
setCustomGasToken(t, gto.cfg, gto.sys, gto.weth9Address)
checkL1TokenNameAndSymbol(t, gto, gto.enabledExpectations)
checkL2TokenNameAndSymbol(t, gto, gto.enabledExpectations)
checkWETHTokenNameAndSymbol(t, gto, gto.enabledExpectations)
})
}
// setCustomGasToken enables the Custom Gas Token feature on a chain where it wasn't enabled at genesis.
// It reads existing parameters from the SystemConfig contract, inserts the supplied cgtAddress and reinitializes that contract.
// To do this it uses the ProxyAdmin and StorageSetter from the supplied cfg.
func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System, cgtAddress common.Address) {
l1Client := sys.NodeClient("l1")
deployerOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.Deployer, cfg.L1ChainIDBig())
require.NoError(t, err)
// Bind a SystemConfig at the SystemConfigProxy address
systemConfig, err := bindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client)
require.NoError(t, err)
// Get existing parameters from SystemConfigProxy contract
owner, err := systemConfig.Owner(&bind.CallOpts{})
require.NoError(t, err)
basefeeScalar, err := systemConfig.BasefeeScalar(&bind.CallOpts{})
require.NoError(t, err)
blobbasefeeScalar, err := systemConfig.BlobbasefeeScalar(&bind.CallOpts{})
require.NoError(t, err)
batcherHash, err := systemConfig.BatcherHash(&bind.CallOpts{})
require.NoError(t, err)
gasLimit, err := systemConfig.GasLimit(&bind.CallOpts{})
require.NoError(t, err)
unsafeBlockSigner, err := systemConfig.UnsafeBlockSigner(&bind.CallOpts{})
require.NoError(t, err)
resourceConfig, err := systemConfig.ResourceConfig(&bind.CallOpts{})
require.NoError(t, err)
batchInbox, err := systemConfig.BatchInbox(&bind.CallOpts{})
require.NoError(t, err)
addresses := bindings.SystemConfigAddresses{}
addresses.L1CrossDomainMessenger, err = systemConfig.L1CrossDomainMessenger(&bind.CallOpts{})
require.NoError(t, err)
addresses.L1ERC721Bridge, err = systemConfig.L1ERC721Bridge(&bind.CallOpts{})
require.NoError(t, err)
addresses.L1StandardBridge, err = systemConfig.L1StandardBridge(&bind.CallOpts{})
require.NoError(t, err)
addresses.DisputeGameFactory, err = systemConfig.DisputeGameFactory(&bind.CallOpts{})
require.NoError(t, err)
addresses.OptimismPortal, err = systemConfig.OptimismPortal(&bind.CallOpts{})
require.NoError(t, err)
addresses.OptimismMintableERC20Factory, err = systemConfig.OptimismMintableERC20Factory(&bind.CallOpts{})
require.NoError(t, err)
// Queue up custom gas token address ready for reinitialization
addresses.GasPayingToken = cgtAddress
// Bind a ProxyAdmin to the ProxyAdmin address
proxyAdmin, err := bindings.NewProxyAdmin(cfg.L1Deployments.ProxyAdmin, l1Client)
require.NoError(t, err)
// Deploy a new StorageSetter contract
storageSetterAddr, tx, _, err := bindings.DeployStorageSetter(deployerOpts, l1Client)
waitForTx(t, tx, err, l1Client)
// Set up a signer which controls the Proxy Admin.
// The deploy config's finalSystemOwner is the owner of the ProxyAdmin as well as the SystemConfig,
// so we can use that address for the proxy admin owner.
proxyAdminOwnerOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig())
require.NoError(t, err)
// Execute the upgrade SystemConfigProxy -> StorageSetter via ProxyAdmin
tx, err = proxyAdmin.Upgrade(proxyAdminOwnerOpts, cfg.L1Deployments.SystemConfigProxy, storageSetterAddr)
waitForTx(t, tx, err, l1Client)
// Bind a StorageSetter to the SystemConfigProxy address
storageSetter, err := bindings.NewStorageSetter(cfg.L1Deployments.SystemConfigProxy, l1Client)
require.NoError(t, err)
// Use StorageSetter to clear out "initialize" slot
tx, err = storageSetter.SetBytes320(deployerOpts, [32]byte{0}, [32]byte{0})
waitForTx(t, tx, err, l1Client)
// Sanity check previous step worked
currentSlotValue, err := storageSetter.GetBytes32(&bind.CallOpts{}, [32]byte{0})
require.NoError(t, err)
require.Equal(t, currentSlotValue, [32]byte{0})
// Execute SystemConfigProxy -> SystemConfig upgrade
tx, err = proxyAdmin.Upgrade(proxyAdminOwnerOpts, cfg.L1Deployments.SystemConfigProxy, cfg.L1Deployments.SystemConfig)
waitForTx(t, tx, err, l1Client)
// Reinitialise with existing initializer values but with custom gas token set
tx, err = systemConfig.Initialize(deployerOpts, owner,
basefeeScalar,
blobbasefeeScalar,
batcherHash,
gasLimit,
unsafeBlockSigner,
resourceConfig,
batchInbox,
addresses)
require.NoError(t, err)
receipt, err := wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err)
// Read Custom Gas Token and check it has been set properly
gpt, err := systemConfig.GasPayingToken(&bind.CallOpts{})
require.NoError(t, err)
require.Equal(t, cgtAddress, gpt.Addr)
optimismPortal, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
depositEvent, err := receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")
depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
require.NoError(t, err)
l2Client := sys.NodeClient("sequencer")
receipt, err = wait.ForReceiptOK(context.Background(), l2Client, types.NewTx(depositTx).Hash())
require.NoError(t, err)
l1Block, err := bindings.NewL1Block(predeploys.L1BlockAddr, l2Client)
require.NoError(t, err)
_, err = receipts.FindLog(receipt.Logs, l1Block.ParseGasPayingTokenSet)
require.NoError(t, err)
}
// waitForTx is a thing wrapper around wait.ForReceiptOK which asserts on there being no errors.
func waitForTx(t *testing.T, tx *types.Transaction, err error, client *ethclient.Client) {
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), client, tx.Hash())
require.NoError(t, err)
}
type gasTokenTestOpts struct {
aliceOpts *bind.TransactOpts
cfg e2esys.SystemConfig
weth9 *bindings.WETH9
weth9Address common.Address
allocType config.AllocType
sys *e2esys.System
enabledExpectations cgtTestExpectations
disabledExpectations cgtTestExpectations
}
// Function to prepare and make call to depositERC20Transaction and make
// appropriate assertions dependent on whether custom gas tokens have been enabled or not.
func checkDeposit(t *testing.T, gto gasTokenTestOpts, enabled bool) {
aliceOpts := gto.aliceOpts
cfg := gto.cfg
l1Client := gto.sys.NodeClient("l1")
l2Client := gto.sys.NodeClient("sequencer")
weth9 := gto.weth9
// Set amount of WETH9 to bridge to the recipient on L2
amountToBridge := big.NewInt(10)
recipient := common.HexToAddress("0xbeefdead")
// Approve OptimismPortal
tx, err = weth9.Approve(aliceOpts, cfg.L1Deployments.OptimismPortalProxy, amountToBridge)
tx, err := weth9.Approve(aliceOpts, cfg.L1Deployments.OptimismPortalProxy, amountToBridge)
waitForTx(t, tx, err, l1Client)
// Get recipient L2 balance before bridging
......@@ -144,13 +337,18 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
} else {
require.Error(t, err)
}
}
}
// Function to prepare and execute withdrawal flow for CGTs
// and assert token balance is increased on L1.
checkWithdrawal := func(t *testing.T) {
l2Seq := l2Client
l2Verif := sys.NodeClient("verifier")
// Function to prepare and execute withdrawal flow for CGTs
// and assert token balance is increased on L1.
func checkWithdrawal(t *testing.T, gto gasTokenTestOpts) {
aliceOpts := gto.aliceOpts
cfg := gto.cfg
weth9 := gto.weth9
allocType := gto.allocType
l1Client := gto.sys.NodeClient("l1")
l2Seq := gto.sys.NodeClient("sequencer")
l2Verif := gto.sys.NodeClient("verifier")
fromAddr := aliceOpts.From
ethPrivKey := cfg.Secrets.Alice
......@@ -185,7 +383,7 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
startETHBalanceBeforeFinalize, err := l1Client.BalanceAt(context.Background(), fromAddr, nil)
require.NoError(t, err)
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", ethPrivKey, receipt)
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, gto.sys, "verifier", ethPrivKey, receipt)
// Verify L1 ETH balance change
proveFee := new(big.Int).Mul(new(big.Int).SetUint64(proveReceipt.GasUsed), proveReceipt.EffectiveGasPrice)
......@@ -214,10 +412,16 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
require.NoError(t, err)
diff = new(big.Int).Sub(endTokenBalanceAfterFinalize, startTokenBalanceBeforeFinalize)
require.Equal(t, withdrawAmount, diff)
}
}
// checkFeeWithdrawal ensures that the FeeVault can be withdrawn from
func checkFeeWithdrawal(t *testing.T, gto gasTokenTestOpts, enabled bool) {
cfg := gto.cfg
weth9 := gto.weth9
allocType := gto.allocType
l1Client := gto.sys.NodeClient("l1")
l2Client := gto.sys.NodeClient("sequencer")
// checkFeeWithdrawal ensures that the FeeVault can be withdrawn from
checkFeeWithdrawal := func(t *testing.T, enabled bool) {
feeVault, err := bindings.NewSequencerFeeVault(predeploys.SequencerFeeVaultAddr, l2Client)
require.NoError(t, err)
......@@ -334,7 +538,7 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
withdrawnAmount := it.Event.Value
// Finalize the withdrawal
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, sys, "verifier", cfg.Secrets.Alice, receipt)
proveReceipt, finalizeReceipt, resolveClaimReceipt, resolveReceipt := helpers.ProveAndFinalizeWithdrawal(t, cfg, gto.sys, "verifier", cfg.Secrets.Alice, receipt)
require.Equal(t, types.ReceiptStatusSuccessful, proveReceipt.Status)
require.Equal(t, types.ReceiptStatusSuccessful, finalizeReceipt.Status)
if allocType.UsesProofs() {
......@@ -352,9 +556,12 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
require.NoError(t, err)
require.Equal(t, recipientBalanceAfter, new(big.Int).Add(recipientBalanceBefore, withdrawnAmount))
}
}
func checkL1TokenNameAndSymbol(t *testing.T, gto gasTokenTestOpts, expectations cgtTestExpectations) {
l1Client := gto.sys.NodeClient("l1")
cfg := gto.cfg
checkL1TokenNameAndSymbol := func(t *testing.T, enabled bool) {
systemConfig, err := bindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client)
require.NoError(t, err)
......@@ -367,20 +574,15 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
symbol, err := systemConfig.GasPayingTokenSymbol(&bind.CallOpts{})
require.NoError(t, err)
if enabled {
require.Equal(t, enabledExpectations.tokenAddress, token.Addr)
require.Equal(t, enabledExpectations.tokenDecimals, token.Decimals)
require.Equal(t, enabledExpectations.tokenName, name)
require.Equal(t, enabledExpectations.tokenSymbol, symbol)
} else {
require.Equal(t, disabledExpectations.tokenAddress, token.Addr)
require.Equal(t, disabledExpectations.tokenDecimals, token.Decimals)
require.Equal(t, disabledExpectations.tokenName, name)
require.Equal(t, disabledExpectations.tokenSymbol, symbol)
}
}
require.Equal(t, expectations.tokenAddress, token.Addr)
require.Equal(t, expectations.tokenDecimals, token.Decimals)
require.Equal(t, expectations.tokenName, name)
require.Equal(t, expectations.tokenSymbol, symbol)
}
func checkL2TokenNameAndSymbol(t *testing.T, gto gasTokenTestOpts, enabledExpectations cgtTestExpectations) {
l2Client := gto.sys.NodeClient("sequencer")
checkL2TokenNameAndSymbol := func(t *testing.T, enabled bool) {
l1Block, err := bindings.NewL1Block(predeploys.L1BlockAddr, l2Client)
require.NoError(t, err)
......@@ -393,20 +595,15 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
symbol, err := l1Block.GasPayingTokenSymbol(&bind.CallOpts{})
require.NoError(t, err)
if enabled {
require.Equal(t, enabledExpectations.tokenAddress, token.Addr)
require.Equal(t, enabledExpectations.tokenDecimals, token.Decimals)
require.Equal(t, enabledExpectations.tokenName, name)
require.Equal(t, enabledExpectations.tokenSymbol, symbol)
} else {
require.Equal(t, disabledExpectations.tokenAddress, token.Addr)
require.Equal(t, disabledExpectations.tokenDecimals, token.Decimals)
require.Equal(t, disabledExpectations.tokenName, name)
require.Equal(t, disabledExpectations.tokenSymbol, symbol)
}
}
}
func checkWETHTokenNameAndSymbol(t *testing.T, gto gasTokenTestOpts, expectations cgtTestExpectations) {
l2Client := gto.sys.NodeClient("sequencer")
checkWETHTokenNameAndSymbol := func(t *testing.T, enabled bool) {
// Check name and symbol in WETH predeploy
weth, err := bindings.NewWETH(predeploys.WETHAddr, l2Client)
require.NoError(t, err)
......@@ -417,157 +614,6 @@ func testCustomGasToken(t *testing.T, allocType config.AllocType) {
symbol, err := weth.Symbol(&bind.CallOpts{})
require.NoError(t, err)
if enabled {
require.Equal(t, "Wrapped "+enabledExpectations.tokenName, name)
require.Equal(t, "W"+enabledExpectations.tokenSymbol, symbol)
} else {
require.Equal(t, "Wrapped "+disabledExpectations.tokenName, name)
require.Equal(t, "W"+disabledExpectations.tokenSymbol, symbol)
}
}
// Begin by testing behaviour when CGT feature is not enabled
enabled := false
checkDeposit(t, enabled)
checkL1TokenNameAndSymbol(t, enabled)
checkL2TokenNameAndSymbol(t, enabled)
checkWETHTokenNameAndSymbol(t, enabled)
checkFeeWithdrawal(t, enabled)
// Activate custom gas token feature (devnet does not have this activated at genesis)
setCustomGasToken(t, cfg, sys, weth9Address)
// Now test behaviour given CGT feature is enabled
enabled = true
checkDeposit(t, enabled)
checkWithdrawal(t)
checkL1TokenNameAndSymbol(t, enabled)
checkL2TokenNameAndSymbol(t, enabled)
checkWETHTokenNameAndSymbol(t, enabled)
checkFeeWithdrawal(t, enabled)
}
// setCustomGasToeken enables the Custom Gas Token feature on a chain where it wasn't enabled at genesis.
// It reads existing parameters from the SystemConfig contract, inserts the supplied cgtAddress and reinitializes that contract.
// To do this it uses the ProxyAdmin and StorageSetter from the supplied cfg.
func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System, cgtAddress common.Address) {
l1Client := sys.NodeClient("l1")
deployerOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.Deployer, cfg.L1ChainIDBig())
require.NoError(t, err)
// Bind a SystemConfig at the SystemConfigProxy address
systemConfig, err := bindings.NewSystemConfig(cfg.L1Deployments.SystemConfigProxy, l1Client)
require.NoError(t, err)
// Get existing parameters from SystemConfigProxy contract
owner, err := systemConfig.Owner(&bind.CallOpts{})
require.NoError(t, err)
basefeeScalar, err := systemConfig.BasefeeScalar(&bind.CallOpts{})
require.NoError(t, err)
blobbasefeeScalar, err := systemConfig.BlobbasefeeScalar(&bind.CallOpts{})
require.NoError(t, err)
batcherHash, err := systemConfig.BatcherHash(&bind.CallOpts{})
require.NoError(t, err)
gasLimit, err := systemConfig.GasLimit(&bind.CallOpts{})
require.NoError(t, err)
unsafeBlockSigner, err := systemConfig.UnsafeBlockSigner(&bind.CallOpts{})
require.NoError(t, err)
resourceConfig, err := systemConfig.ResourceConfig(&bind.CallOpts{})
require.NoError(t, err)
batchInbox, err := systemConfig.BatchInbox(&bind.CallOpts{})
require.NoError(t, err)
addresses := bindings.SystemConfigAddresses{}
addresses.L1CrossDomainMessenger, err = systemConfig.L1CrossDomainMessenger(&bind.CallOpts{})
require.NoError(t, err)
addresses.L1ERC721Bridge, err = systemConfig.L1ERC721Bridge(&bind.CallOpts{})
require.NoError(t, err)
addresses.L1StandardBridge, err = systemConfig.L1StandardBridge(&bind.CallOpts{})
require.NoError(t, err)
addresses.DisputeGameFactory, err = systemConfig.DisputeGameFactory(&bind.CallOpts{})
require.NoError(t, err)
addresses.OptimismPortal, err = systemConfig.OptimismPortal(&bind.CallOpts{})
require.NoError(t, err)
addresses.OptimismMintableERC20Factory, err = systemConfig.OptimismMintableERC20Factory(&bind.CallOpts{})
require.NoError(t, err)
// Queue up custom gas token address ready for reinitialization
addresses.GasPayingToken = cgtAddress
// Bind a ProxyAdmin to the ProxyAdmin address
proxyAdmin, err := bindings.NewProxyAdmin(cfg.L1Deployments.ProxyAdmin, l1Client)
require.NoError(t, err)
// Deploy a new StorageSetter contract
storageSetterAddr, tx, _, err := bindings.DeployStorageSetter(deployerOpts, l1Client)
waitForTx(t, tx, err, l1Client)
// Set up a signer which controls the Proxy Admin.
// The deploy config's finalSystemOwner is the owner of the ProxyAdmin as well as the SystemConfig,
// so we can use that address for the proxy admin owner.
proxyAdminOwnerOpts, err := bind.NewKeyedTransactorWithChainID(cfg.Secrets.SysCfgOwner, cfg.L1ChainIDBig())
require.NoError(t, err)
// Execute the upgrade SystemConfigProxy -> StorageSetter via ProxyAdmin
tx, err = proxyAdmin.Upgrade(proxyAdminOwnerOpts, cfg.L1Deployments.SystemConfigProxy, storageSetterAddr)
waitForTx(t, tx, err, l1Client)
// Bind a StorageSetter to the SystemConfigProxy address
storageSetter, err := bindings.NewStorageSetter(cfg.L1Deployments.SystemConfigProxy, l1Client)
require.NoError(t, err)
// Use StorageSetter to clear out "initialize" slot
tx, err = storageSetter.SetBytes320(deployerOpts, [32]byte{0}, [32]byte{0})
waitForTx(t, tx, err, l1Client)
// Sanity check previous step worked
currentSlotValue, err := storageSetter.GetBytes32(&bind.CallOpts{}, [32]byte{0})
require.NoError(t, err)
require.Equal(t, currentSlotValue, [32]byte{0})
// Execute SystemConfigProxy -> SystemConfig upgrade
tx, err = proxyAdmin.Upgrade(proxyAdminOwnerOpts, cfg.L1Deployments.SystemConfigProxy, cfg.L1Deployments.SystemConfig)
waitForTx(t, tx, err, l1Client)
// Reinitialise with existing initializer values but with custom gas token set
tx, err = systemConfig.Initialize(deployerOpts, owner,
basefeeScalar,
blobbasefeeScalar,
batcherHash,
gasLimit,
unsafeBlockSigner,
resourceConfig,
batchInbox,
addresses)
require.NoError(t, err)
receipt, err := wait.ForReceiptOK(context.Background(), l1Client, tx.Hash())
require.NoError(t, err)
// Read Custom Gas Token and check it has been set properly
gpt, err := systemConfig.GasPayingToken(&bind.CallOpts{})
require.NoError(t, err)
require.Equal(t, cgtAddress, gpt.Addr)
optimismPortal, err := bindings.NewOptimismPortal(cfg.L1Deployments.OptimismPortalProxy, l1Client)
require.NoError(t, err)
depositEvent, err := receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")
depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
require.NoError(t, err)
l2Client := sys.NodeClient("sequencer")
receipt, err = wait.ForReceiptOK(context.Background(), l2Client, types.NewTx(depositTx).Hash())
require.NoError(t, err)
l1Block, err := bindings.NewL1Block(predeploys.L1BlockAddr, l2Client)
require.NoError(t, err)
_, err = receipts.FindLog(receipt.Logs, l1Block.ParseGasPayingTokenSet)
require.NoError(t, err)
}
// waitForTx is a thing wrapper around wait.ForReceiptOK which asserts on there being no errors.
func waitForTx(t *testing.T, tx *types.Transaction, err error, client *ethclient.Client) {
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), client, tx.Hash())
require.NoError(t, err)
require.Equal(t, "Wrapped "+expectations.tokenName, name)
require.Equal(t, "W"+expectations.tokenSymbol, symbol)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment