Commit b04f8c6c authored by mergify[bot]'s avatar mergify[bot] Committed by GitHub

Merge branch 'develop' into sc/ctb-move-initializers

parents 7d7d9ba8 9192f93f
...@@ -2,6 +2,48 @@ version: 2.1 ...@@ -2,6 +2,48 @@ version: 2.1
orbs: orbs:
go: circleci/go@1.5.0 go: circleci/go@1.5.0
gcp-cli: circleci/gcp-cli@2.4.1
commands:
gcp-oidc-authenticate:
description: "Authenticate with GCP using a CircleCI OIDC token."
parameters:
project_id:
type: env_var_name
default: GCP_PROJECT_ID
workload_identity_pool_id:
type: env_var_name
default: GCP_WIP_ID
workload_identity_pool_provider_id:
type: env_var_name
default: GCP_WIP_PROVIDER_ID
service_account_email:
type: env_var_name
default: GCP_SERVICE_ACCOUNT_EMAIL
gcp_cred_config_file_path:
type: string
default: /home/circleci/gcp_cred_config.json
oidc_token_file_path:
type: string
default: /home/circleci/oidc_token.json
steps:
- run:
name: "Create OIDC credential configuration"
command: |
# Store OIDC token in temp file
echo $CIRCLE_OIDC_TOKEN > << parameters.oidc_token_file_path >>
# Create a credential configuration for the generated OIDC ID Token
gcloud iam workload-identity-pools create-cred-config \
"projects/${<< parameters.project_id >>}/locations/global/workloadIdentityPools/${<< parameters.workload_identity_pool_id >>}/providers/${<< parameters.workload_identity_pool_provider_id >>}"\
--output-file="<< parameters.gcp_cred_config_file_path >>" \
--service-account="${<< parameters.service_account_email >>}" \
--credential-source-file=<< parameters.oidc_token_file_path >>
- run:
name: "Authenticate with GCP using OIDC"
command: |
# Configure gcloud to leverage the generated credential configuration
gcloud auth login --brief --cred-file "<< parameters.gcp_cred_config_file_path >>"
# Configure ADC
echo "export GOOGLE_APPLICATION_CREDENTIALS='<< parameters.gcp_cred_config_file_path >>'" | tee -a "$BASH_ENV"
jobs: jobs:
yarn-monorepo: yarn-monorepo:
docker: docker:
...@@ -67,6 +109,7 @@ jobs: ...@@ -67,6 +109,7 @@ jobs:
image: ubuntu-2204:2022.07.1 image: ubuntu-2204:2022.07.1
resource_class: xlarge resource_class: xlarge
steps: steps:
- gcp-oidc-authenticate
# Below is CircleCI recommended way of specifying nameservers on an Ubuntu box: # Below is CircleCI recommended way of specifying nameservers on an Ubuntu box:
# https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan # https://support.circleci.com/hc/en-us/articles/7323511028251-How-to-set-custom-DNS-on-Ubuntu-based-images-using-netplan
- run: sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml - run: sudo sed -i '13 i \ \ \ \ \ \ \ \ \ \ \ \ nameservers:' /etc/netplan/50-cloud-init.yaml
...@@ -101,7 +144,7 @@ jobs: ...@@ -101,7 +144,7 @@ jobs:
- run: - run:
name: Publish name: Publish
command: | command: |
echo "$DOCKER_PASS" | docker login -u "$DOCKER_USERNAME" --password-stdin "<<parameters.repo>>" gcloud auth configure-docker us-central1-docker.pkg.dev
docker push <<parameters.docker_tags>> docker push <<parameters.docker_tags>>
contracts-bedrock-tests: contracts-bedrock-tests:
...@@ -145,7 +188,7 @@ jobs: ...@@ -145,7 +188,7 @@ jobs:
working_directory: packages/contracts-bedrock working_directory: packages/contracts-bedrock
- run: - run:
name: upload coverage name: upload coverage
command: codecov --verbose --clean --flag contracts-bedrock-tests command: codecov --verbose --clean --flags contracts-bedrock-tests
environment: environment:
FOUNDRY_PROFILE: ci FOUNDRY_PROFILE: ci
- run: - run:
...@@ -217,7 +260,7 @@ jobs: ...@@ -217,7 +260,7 @@ jobs:
working_directory: packages/<<parameters.package_name>> working_directory: packages/<<parameters.package_name>>
- run: - run:
name: Upload coverage name: Upload coverage
command: codecov --verbose --clean --flag <<parameters.coverage_flag>> command: codecov --verbose --clean --flags <<parameters.coverage_flag>>
bedrock-go-tests: bedrock-go-tests:
docker: docker:
...@@ -308,7 +351,7 @@ jobs: ...@@ -308,7 +351,7 @@ jobs:
working_directory: op-chain-ops working_directory: op-chain-ops
- run: - run:
name: upload coverage name: upload coverage
command: codecov --verbose --clean --flag bedrock-go-tests command: codecov --verbose --clean --flags bedrock-go-tests
- store_test_results: - store_test_results:
path: /test-results path: /test-results
- run: - run:
......
...@@ -14,10 +14,10 @@ import ( ...@@ -14,10 +14,10 @@ import (
// LegacyWithdrawal represents a pre bedrock upgrade withdrawal. // LegacyWithdrawal represents a pre bedrock upgrade withdrawal.
type LegacyWithdrawal struct { type LegacyWithdrawal struct {
Target *common.Address Target *common.Address `json:"target"`
Sender *common.Address Sender *common.Address `json:"sender"`
Data []byte Data []byte `json:"data"`
Nonce *big.Int Nonce *big.Int `json:"nonce"`
} }
var _ WithdrawalMessage = (*LegacyWithdrawal)(nil) var _ WithdrawalMessage = (*LegacyWithdrawal)(nil)
......
package crossdomain
import (
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
var (
abiTrue = common.Hash{31: 0x01}
errLegacyStorageSlotNotFound = errors.New("cannot find storage slot")
)
// MigrateWithdrawals will migrate a list of pending withdrawals given a StateDB.
func MigrateWithdrawals(withdrawals []*PendingWithdrawal, db vm.StateDB, l1CrossDomainMessenger, l1StandardBridge *common.Address) error {
for _, legacy := range withdrawals {
legacySlot, err := legacy.StorageSlot()
if err != nil {
return err
}
legacyValue := db.GetState(predeploys.LegacyMessagePasserAddr, legacySlot)
if legacyValue != abiTrue {
return fmt.Errorf("%w: %s", errLegacyStorageSlotNotFound, legacyValue)
}
withdrawal, err := MigrateWithdrawal(&legacy.LegacyWithdrawal, l1CrossDomainMessenger, l1StandardBridge)
if err != nil {
return err
}
slot, err := withdrawal.StorageSlot()
if err != nil {
return err
}
db.SetState(predeploys.L2ToL1MessagePasserAddr, slot, abiTrue)
}
return nil
}
// MigrateWithdrawal will turn a LegacyWithdrawal into a bedrock
// style Withdrawal.
func MigrateWithdrawal(withdrawal *LegacyWithdrawal, l1CrossDomainMessenger, l1StandardBridge *common.Address) (*Withdrawal, error) {
value := new(big.Int)
isFromL2StandardBridge := *withdrawal.Sender == predeploys.L2StandardBridgeAddr
if withdrawal.Target == nil {
return nil, errors.New("withdrawal target cannot be nil")
}
isToL1StandardBridge := *withdrawal.Target == *l1StandardBridge
if isFromL2StandardBridge && isToL1StandardBridge {
abi, err := bindings.L1StandardBridgeMetaData.GetAbi()
if err != nil {
return nil, err
}
method, err := abi.MethodById(withdrawal.Data)
if err != nil {
return nil, err
}
if method.Name == "finalizeETHWithdrawal" {
data, err := method.Inputs.Unpack(withdrawal.Data[4:])
if err != nil {
return nil, err
}
// bounds check
if len(data) < 3 {
return nil, errors.New("not enough data")
}
var ok bool
value, ok = data[2].(*big.Int)
if !ok {
return nil, errors.New("not big.Int")
}
}
}
abi, err := bindings.L1CrossDomainMessengerMetaData.GetAbi()
if err != nil {
return nil, err
}
versionedNonce := EncodeVersionedNonce(withdrawal.Nonce, common.Big1)
data, err := abi.Pack(
"relayMessage",
versionedNonce,
withdrawal.Sender,
withdrawal.Target,
value,
new(big.Int),
withdrawal.Data,
)
if err != nil {
return nil, fmt.Errorf("cannot abi encode relayMessage: %w", err)
}
w := NewWithdrawal(
withdrawal.Nonce,
&predeploys.L2CrossDomainMessengerAddr,
l1CrossDomainMessenger,
value,
new(big.Int),
data,
)
return w, nil
}
package crossdomain_test
import (
"fmt"
"testing"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-chain-ops/crossdomain"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)
func TestMigrateWithdrawal(t *testing.T) {
withdrawals := make([]*crossdomain.LegacyWithdrawal, 0)
for _, receipt := range receipts {
msg, err := findCrossDomainMessage(receipt)
require.Nil(t, err)
withdrawal, err := msg.ToWithdrawal()
require.Nil(t, err)
legacyWithdrawal, ok := withdrawal.(*crossdomain.LegacyWithdrawal)
require.True(t, ok)
withdrawals = append(withdrawals, legacyWithdrawal)
}
l1CrossDomainMessenger := common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1")
l1StandardBridge := common.HexToAddress("0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1")
for i, legacy := range withdrawals {
t.Run(fmt.Sprintf("test%d", i), func(t *testing.T) {
withdrawal, err := crossdomain.MigrateWithdrawal(legacy, &l1CrossDomainMessenger, &l1StandardBridge)
require.Nil(t, err)
require.NotNil(t, withdrawal)
require.Equal(t, legacy.Nonce.Uint64(), withdrawal.Nonce.Uint64())
require.Equal(t, *withdrawal.Sender, predeploys.L2CrossDomainMessengerAddr)
require.Equal(t, *withdrawal.Target, l1CrossDomainMessenger)
})
}
}
...@@ -13,12 +13,12 @@ var _ WithdrawalMessage = (*Withdrawal)(nil) ...@@ -13,12 +13,12 @@ var _ WithdrawalMessage = (*Withdrawal)(nil)
// Withdrawal represents a withdrawal transaction on L2 // Withdrawal represents a withdrawal transaction on L2
type Withdrawal struct { type Withdrawal struct {
Nonce *big.Int Nonce *big.Int `json:"nonce"`
Sender *common.Address Sender *common.Address `json:"sender"`
Target *common.Address Target *common.Address `json:"target"`
Value *big.Int Value *big.Int `json:"value"`
GasLimit *big.Int GasLimit *big.Int `json:"gasLimit"`
Data []byte Data []byte `json:"data"`
} }
// NewWithdrawal will create a Withdrawal // NewWithdrawal will create a Withdrawal
......
...@@ -15,12 +15,8 @@ import ( ...@@ -15,12 +15,8 @@ import (
// A PendingWithdrawal represents a withdrawal that has // A PendingWithdrawal represents a withdrawal that has
// not been finalized on L1 // not been finalized on L1
type PendingWithdrawal struct { type PendingWithdrawal struct {
Target common.Address `json:"target"` LegacyWithdrawal `json:"withdrawal"`
Sender common.Address `json:"sender"` TransactionHash common.Hash `json:"transactionHash"`
Message []byte `json:"message"`
MessageNonce *big.Int `json:"nonce"`
GasLimit *big.Int `json:"gasLimit"`
TransactionHash common.Hash `json:"transactionHash"`
} }
// Backends represents a set of backends for L1 and L2. // Backends represents a set of backends for L1 and L2.
...@@ -119,11 +115,12 @@ func GetPendingWithdrawals(messengers *Messengers, version *big.Int, start, end ...@@ -119,11 +115,12 @@ func GetPendingWithdrawals(messengers *Messengers, version *big.Int, start, end
log.Info("%s not yet relayed", event.Raw.TxHash) log.Info("%s not yet relayed", event.Raw.TxHash)
withdrawal := PendingWithdrawal{ withdrawal := PendingWithdrawal{
Target: event.Target, LegacyWithdrawal: LegacyWithdrawal{
Sender: event.Sender, Target: &event.Target,
Message: event.Message, Sender: &event.Sender,
MessageNonce: event.MessageNonce, Data: event.Message,
GasLimit: event.GasLimit, Nonce: event.MessageNonce,
},
TransactionHash: event.Raw.TxHash, TransactionHash: event.Raw.TxHash,
} }
......
...@@ -272,8 +272,7 @@ func TestGetPendingWithdrawals(t *testing.T) { ...@@ -272,8 +272,7 @@ func TestGetPendingWithdrawals(t *testing.T) {
for i, msg := range msgs[3:] { for i, msg := range msgs[3:] {
withdrawal := withdrawals[i] withdrawal := withdrawals[i]
require.Equal(t, msg.Target, withdrawal.Target) require.Equal(t, msg.Target, *withdrawal.Target)
require.Equal(t, msg.Message, withdrawal.Message) require.Equal(t, msg.Message, withdrawal.Data)
require.Equal(t, uint64(msg.MinGasLimit), withdrawal.GasLimit.Uint64())
} }
} }
...@@ -7,7 +7,7 @@ import '@eth-optimism/hardhat-deploy-config' ...@@ -7,7 +7,7 @@ import '@eth-optimism/hardhat-deploy-config'
const upgradeABIs = { const upgradeABIs = {
L2OutputOracleProxy: async (deployConfig) => [ L2OutputOracleProxy: async (deployConfig) => [
'initialize(bytes32,uint256,address)', 'initialize(bytes32,address,address)',
[ [
deployConfig.l2OutputOracleGenesisL2Output, deployConfig.l2OutputOracleGenesisL2Output,
deployConfig.l2OutputOracleProposer, deployConfig.l2OutputOracleProposer,
......
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