Skip to content

Commit

Permalink
Introduce nonce for consensus events on L1
Browse files Browse the repository at this point in the history
  • Loading branch information
mdehoog committed Jan 1, 2025
1 parent f3b9f0c commit c083f5d
Show file tree
Hide file tree
Showing 73 changed files with 3,375 additions and 290 deletions.
2 changes: 2 additions & 0 deletions .semgrep/rules/sol-rules.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ rules:
}
paths:
exclude:
- packages/contracts-bedrock/src/L1/SystemConfigIsthmus.sol
- packages/contracts-bedrock/src/L1/SystemConfigInterop.sol
- packages/contracts-bedrock/src/L1/OptimismPortalIsthmus.sol
- packages/contracts-bedrock/src/L1/OptimismPortalInterop.sol

- id: sol-safety-proper-initializer
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require (
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20241213092551-33a63fce8214
github.com/ethereum/go-ethereum v1.14.11
github.com/fsnotify/fsnotify v1.8.0
github.com/golang-jwt/jwt/v4 v4.5.1
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb
github.com/google/go-cmp v0.6.0
github.com/google/gofuzz v1.2.1-0.20220503160820-4a35382e8fc8
Expand Down Expand Up @@ -113,7 +114,6 @@ require (
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gopacket v1.1.19 // indirect
github.com/google/pprof v0.0.0-20241009165004-a3522334989c // indirect
Expand Down Expand Up @@ -252,7 +252,7 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect
)

replace github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101411.5-rc.1
replace github.com/ethereum/go-ethereum => github.com/mdehoog/op-geth v0.0.0-20250101233126-2ae05da2c681

//replace github.com/ethereum/go-ethereum => ../go-ethereum

Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -189,8 +189,6 @@ github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/u
github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3 h1:RWHKLhCrQThMfch+QJ1Z8veEq5ZO3DfIhZ7xgRP9WTc=
github.com/ethereum-optimism/go-ethereum-hdwallet v0.1.3/go.mod h1:QziizLAiF0KqyLdNJYD7O5cpDlaFMNZzlxYNcWsJUxs=
github.com/ethereum-optimism/op-geth v1.101411.5-rc.1 h1:8fhtAycm/+xugWev5jInUxgF0Wdc29PxSODZXca6Qi8=
github.com/ethereum-optimism/op-geth v1.101411.5-rc.1/go.mod h1:n6VeI9cKFxmXCauD7Ji9lgTAg+2TYGLZu5AXgVJB4tk=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20241213092551-33a63fce8214 h1:94dIMFDCafAQ3FCC1pryuhgfZc1jPoDwK4xSMOPshN8=
github.com/ethereum-optimism/superchain-registry/superchain v0.0.0-20241213092551-33a63fce8214/go.mod h1:9feO8jcL5OZ1tvRjEfNAHz4Aggvd6373l+ZxmZZAyZs=
github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA=
Expand Down Expand Up @@ -514,6 +512,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdehoog/op-geth v0.0.0-20250101233126-2ae05da2c681 h1:KXbyO/Iqv+C+NaHxyd4Ob/iO2845X3VB72kQ0hVmgoE=
github.com/mdehoog/op-geth v0.0.0-20250101233126-2ae05da2c681/go.mod h1:n6VeI9cKFxmXCauD7Ji9lgTAg+2TYGLZu5AXgVJB4tk=
github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
Expand Down
3 changes: 1 addition & 2 deletions op-chain-ops/cmd/deposit-hash/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ func main() {

for _, ethLog := range l1Receipt.Logs {
if ethLog.Topics[0].String() == depositLogTopic.String() {

reconstructedDep, err := derive.UnmarshalDepositLogEvent(ethLog)
reconstructedDep, err := derive.UnmarshalDepositLogEventIgnoreNonce(ethLog)
if err != nil {
log.Crit("Failed to parse deposit event ", "err", err)
}
Expand Down
34 changes: 27 additions & 7 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -996,13 +996,8 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
Hash: l2GenesisBlockHash,
Number: l2GenesisBlockNumber,
},
L2Time: l1StartBlock.Time,
SystemConfig: eth.SystemConfig{
BatcherAddr: d.BatchSenderAddress,
Overhead: eth.Bytes32(common.BigToHash(new(big.Int).SetUint64(d.GasPriceOracleOverhead))),
Scalar: eth.Bytes32(d.FeeScalar()),
GasLimit: uint64(d.L2GenesisBlockGasLimit),
},
L2Time: l1StartBlock.Time,
SystemConfig: d.GenesisSystemConfig(),
},
BlockTime: d.L2BlockTime,
MaxSequencerDrift: d.MaxSequencerDrift,
Expand All @@ -1027,6 +1022,31 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Header, l2GenesisBlockHa
}, nil
}

// GenesisSystemConfig converts a DeployConfig to a eth.SystemConfig. If Ecotone is active at genesis, the
// Overhead value is considered a noop.
func (d *DeployConfig) GenesisSystemConfig() eth.SystemConfig {
depositNonce := uint64(0)
configUpdateNonce := uint64(0)
// if Isthmus is active at genesis, we must ensure the nonces are set correctly
if d.L2GenesisIsthmusTimeOffset != nil && *d.L2GenesisIsthmusTimeOffset == 0 {
// SystemConfig emits 3 ConfigUpdate events which increments the nonce by 3
configUpdateNonce += 3
// If a custom gas token is set, a TransactionDeposited event is emitted from
// the OptimismPortal, which increments the deposit nonce by 1
if d.UseCustomGasToken {
depositNonce += 1
}
}
return eth.SystemConfig{
BatcherAddr: d.BatchSenderAddress,
Overhead: eth.Bytes32(common.BigToHash(new(big.Int).SetUint64(d.GasPriceOracleOverhead))),
Scalar: d.FeeScalar(),
GasLimit: uint64(d.L2GenesisBlockGasLimit),
DepositNonce: depositNonce,
ConfigUpdateNonce: configUpdateNonce,
}
}

// NewDeployConfig reads a config file given a path on the filesystem.
func NewDeployConfig(path string) (*DeployConfig, error) {
file, err := os.ReadFile(path)
Expand Down
1 change: 1 addition & 0 deletions op-chain-ops/interopgen/recipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ func InteropL2DevConfig(l1ChainID, l2ChainID uint64, addrs devkeys.Addresses) (*
L2GenesisFjordTimeOffset: new(hexutil.Uint64),
L2GenesisGraniteTimeOffset: new(hexutil.Uint64),
L2GenesisHoloceneTimeOffset: new(hexutil.Uint64),
L2GenesisIsthmusTimeOffset: new(hexutil.Uint64),
L2GenesisInteropTimeOffset: new(hexutil.Uint64),
L1CancunTimeOffset: new(hexutil.Uint64),
UseInterop: true,
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/actions/helpers/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ func (s *CrossLayerUser) CheckDepositTx(t Testing, l1TxHash common.Hash, index i
require.False(t, l2Success)
} else {
require.Less(t, index, len(depositReceipt.Logs), "must have enough logs in receipt")
reconstructedDep, err := derive.UnmarshalDepositLogEvent(depositReceipt.Logs[index])
reconstructedDep, err := derive.UnmarshalDepositLogEventIgnoreNonce(depositReceipt.Logs[index])
require.NoError(t, err, "Could not reconstruct L2 Deposit")
l2Tx := types.NewTx(reconstructedDep)
s.L2.CheckReceipt(t, l2Success, l2Tx.Hash())
Expand Down
15 changes: 7 additions & 8 deletions op-e2e/e2eutils/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"path"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
Expand Down Expand Up @@ -205,6 +204,7 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
FjordTime: deployConf.FjordTime(uint64(deployConf.L1GenesisBlockTimestamp)),
GraniteTime: deployConf.GraniteTime(uint64(deployConf.L1GenesisBlockTimestamp)),
HoloceneTime: deployConf.HoloceneTime(uint64(deployConf.L1GenesisBlockTimestamp)),
IsthmusTime: deployConf.IsthmusTime(uint64(deployConf.L1GenesisBlockTimestamp)),
InteropTime: deployConf.InteropTime(uint64(deployConf.L1GenesisBlockTimestamp)),
AltDAConfig: pcfg,
}
Expand All @@ -226,16 +226,12 @@ func Setup(t require.TestingT, deployParams *DeployParams, alloc *AllocParams) *
}

func SystemConfigFromDeployConfig(deployConfig *genesis.DeployConfig) eth.SystemConfig {
return eth.SystemConfig{
BatcherAddr: deployConfig.BatchSenderAddress,
Overhead: eth.Bytes32(common.BigToHash(new(big.Int).SetUint64(deployConfig.GasPriceOracleOverhead))),
Scalar: eth.Bytes32(deployConfig.FeeScalar()),
GasLimit: uint64(deployConfig.L2GenesisBlockGasLimit),
}
return deployConfig.GenesisSystemConfig()
}

func ApplyDeployConfigForks(deployConfig *genesis.DeployConfig) {
isHolocene := os.Getenv("OP_E2E_USE_HOLOCENE") == "true"
isIsthmus := os.Getenv("OP_E2E_USE_ISTHMUS") == "true"
isHolocene := isIsthmus || os.Getenv("OP_E2E_USE_HOLOCENE") == "true"
isGranite := isHolocene || os.Getenv("OP_E2E_USE_GRANITE") == "true"
isFjord := isGranite || os.Getenv("OP_E2E_USE_FJORD") == "true"
isEcotone := isFjord || os.Getenv("OP_E2E_USE_ECOTONE") == "true"
Expand All @@ -255,6 +251,9 @@ func ApplyDeployConfigForks(deployConfig *genesis.DeployConfig) {
if isHolocene {
deployConfig.L2GenesisHoloceneTimeOffset = new(hexutil.Uint64)
}
if isIsthmus {
deployConfig.L2GenesisIsthmusTimeOffset = new(hexutil.Uint64)
}
// Canyon and lower is activated by default
deployConfig.L2GenesisCanyonTimeOffset = new(hexutil.Uint64)
deployConfig.L2GenesisRegolithTimeOffset = new(hexutil.Uint64)
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/system/bridge/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func TestERC20BridgeDeposits(t *testing.T) {
depositEvent, err := receipts.FindLog(depositReceipt.Logs, portal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")

depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
depositTx, err := derive.UnmarshalDepositLogEventIgnoreNonce(&depositEvent.Raw)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l2Client, types.NewTx(depositTx).Hash())
require.NoError(t, err)
Expand Down
1 change: 1 addition & 0 deletions op-e2e/system/e2esys/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ func (cfg SystemConfig) Start(t *testing.T, startOpts ...StartOption) (*System,
FjordTime: cfg.DeployConfig.FjordTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
GraniteTime: cfg.DeployConfig.GraniteTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
HoloceneTime: cfg.DeployConfig.HoloceneTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
IsthmusTime: cfg.DeployConfig.IsthmusTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
InteropTime: cfg.DeployConfig.InteropTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
ProtocolVersionsAddress: cfg.L1Deployments.ProtocolVersionsProxy,
AltDAConfig: rollupAltDAConfig,
Expand Down
6 changes: 3 additions & 3 deletions op-e2e/system/gastoken/gastoken_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ func setCustomGasToken(t *testing.T, cfg e2esys.SystemConfig, sys *e2esys.System

depositEvent, err := receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")
depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
depositTx, err := derive.UnmarshalDepositLogEventIgnoreNonce(&depositEvent.Raw)

require.NoError(t, err)
l2Client := sys.NodeClient("sequencer")
Expand Down Expand Up @@ -326,7 +326,7 @@ func checkDeposit(t *testing.T, gto gasTokenTestOpts, enabled bool) {
// compute the deposit transaction hash + poll for it
depositEvent, err := receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")
depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
depositTx, err := derive.UnmarshalDepositLogEventIgnoreNonce(&depositEvent.Raw)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l2Client, types.NewTx(depositTx).Hash())
require.NoError(t, err)
Expand Down Expand Up @@ -496,7 +496,7 @@ func checkFeeWithdrawal(t *testing.T, gto gasTokenTestOpts, enabled bool) {
// Compute the deposit transaction hash + poll for it
depositEvent, err := receipts.FindLog(receipt.Logs, optimismPortal.ParseTransactionDeposited)
require.NoError(t, err, "Should emit deposit event")
depositTx, err := derive.UnmarshalDepositLogEvent(&depositEvent.Raw)
depositTx, err := derive.UnmarshalDepositLogEventIgnoreNonce(&depositEvent.Raw)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), l2Client, types.NewTx(depositTx).Hash())
require.NoError(t, err)
Expand Down
2 changes: 1 addition & 1 deletion op-e2e/system/helpers/tx_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func SendDepositTx(t *testing.T, cfg e2esys.SystemConfig, l1Client *ethclient.Cl
t.Logf("SendDepositTx: included on L1")

// Wait for transaction to be included on L2
reconstructedDep, err := derive.UnmarshalDepositLogEvent(l1Receipt.Logs[0])
reconstructedDep, err := derive.UnmarshalDepositLogEventIgnoreNonce(l1Receipt.Logs[0])
require.NoError(t, err, "Could not reconstruct L2 Deposit")
tx = types.NewTx(reconstructedDep)
l2Receipt, err := wait.ForReceipt(ctx, l2Client, tx.Hash(), l2Opts.ExpectedStatus)
Expand Down
4 changes: 3 additions & 1 deletion op-node/rollup/attributes/engine_consolidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ func logL1InfoTxns(rollupCfg *rollup.Config, l log.Logger, l2Number, l2Timestamp
"unsafe_l1_time", unsafeInfo.Time, "unsafe_seq_num", unsafeInfo.SequenceNumber,
"unsafe_l1_basefee", unsafeInfo.BaseFee, "unsafe_batcher_addr", unsafeInfo.BatcherAddr,
)
if bytes.HasPrefix(safeTxValue.Data(), types.EcotoneL1AttributesSelector) {
if bytes.HasPrefix(safeTxValue.Data(), types.EcotoneL1AttributesSelector[:]) ||
bytes.HasPrefix(safeTxValue.Data(), types.IsthmusL1AttributesSelector[:]) ||
bytes.HasPrefix(safeTxValue.Data(), types.InteropL1AttributesSelector[:]) {
l.Error("L1 Info transaction differs",
"safe_l1_blob_basefee", safeInfo.BlobBaseFee,
"safe_l1_basefee_scalar", safeInfo.BaseFeeScalar,
Expand Down
19 changes: 8 additions & 11 deletions op-node/rollup/derive/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,38 +65,35 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
// case we need to fetch all transaction receipts from the L1 origin block so we can scan for
// user deposits.
if l2Parent.L1Origin.Number != epoch.Number {
info, receipts, err := ba.l1.FetchReceipts(ctx, epoch.Hash)
if err != nil {
var receipts types.Receipts
if l1Info, receipts, err = ba.l1.FetchReceipts(ctx, epoch.Hash); err != nil {
return nil, NewTemporaryError(fmt.Errorf("failed to fetch L1 block info and receipts: %w", err))
}
if l2Parent.L1Origin.Hash != info.ParentHash() {
if l2Parent.L1Origin.Hash != l1Info.ParentHash() {
return nil, NewResetError(
fmt.Errorf("cannot create new block with L1 origin %s (parent %s) on top of L1 origin %s",
epoch, info.ParentHash(), l2Parent.L1Origin))
epoch, l1Info.ParentHash(), l2Parent.L1Origin))
}

deposits, err := DeriveDeposits(receipts, ba.rollupCfg.DepositContractAddress)
if err != nil {
if depositTxs, sysConfig.DepositNonce, err = DeriveDeposits(receipts, ba.rollupCfg.DepositContractAddress, sysConfig.DepositNonce); err != nil {
// deposits may never be ignored. Failing to process them is a critical error.
return nil, NewCriticalError(fmt.Errorf("failed to derive some deposits: %w", err))
}

// apply sysCfg changes
if err := UpdateSystemConfigWithL1Receipts(&sysConfig, receipts, ba.rollupCfg, info.Time()); err != nil {
if err = UpdateSystemConfigWithL1Receipts(&sysConfig, receipts, ba.rollupCfg, l1Info.Time()); err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to apply derived L1 sysCfg updates: %w", err))
}

l1Info = info
depositTxs = deposits
seqNumber = 0
} else {
if l2Parent.L1Origin.Hash != epoch.Hash {
return nil, NewResetError(fmt.Errorf("cannot create new block with L1 origin %s in conflict with L1 origin %s", epoch, l2Parent.L1Origin))
}
info, err := ba.l1.InfoByHash(ctx, epoch.Hash)
l1Info, err = ba.l1.InfoByHash(ctx, epoch.Hash)
if err != nil {
return nil, NewTemporaryError(fmt.Errorf("failed to fetch L1 block info: %w", err))
}
l1Info = info
depositTxs = nil
seqNumber = l2Parent.SequenceNumber + 1
}
Expand Down
Loading

0 comments on commit c083f5d

Please sign in to comment.