Skip to content

Commit

Permalink
Deposit queue
Browse files Browse the repository at this point in the history
  • Loading branch information
mdehoog committed Dec 27, 2024
1 parent f3b9f0c commit 116598a
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 30 deletions.
27 changes: 23 additions & 4 deletions op-node/rollup/derive/deposit_log.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import (
var (
DepositEventABI = "TransactionDeposited(address,address,uint256,bytes)"
DepositEventABIHash = crypto.Keccak256Hash([]byte(DepositEventABI))
DepositEventVersion0 = common.Hash{}
DepositEventVersion0 = uint64(0)
DepositEventVersion1 = uint64(1)
)

// UnmarshalDepositLogEvent decodes an EVM log entry emitted by the deposit contract into typed deposit data.
Expand All @@ -27,7 +28,7 @@ var (
// event TransactionDeposited(
// address indexed from,
// address indexed to,
// uint256 indexed version,
// uint256 indexed nonceAndVersion,
// bytes opaqueData
// );
//
Expand All @@ -51,7 +52,7 @@ func UnmarshalDepositLogEvent(ev *types.Log) (*types.DepositTx, error) {
// indexed 1
to := common.BytesToAddress(ev.Topics[2][12:])
// indexed 2
version := ev.Topics[3]
nonceAndVersion := ev.Topics[3]
// unindexed data
// Solidity serializes the event's Data field as follows:
// abi.encode(abi.encodPacked(uint256 mint, uint256 value, uint64 gasLimit, uint8 isCreation, bytes data))
Expand Down Expand Up @@ -83,10 +84,15 @@ func UnmarshalDepositLogEvent(ev *types.Log) (*types.DepositTx, error) {
dep.From = from
dep.IsSystemTransaction = false

_, versionBig := unpackNonceAndVersion(nonceAndVersion)
version := versionBig.Uint64()

var err error
switch version {
case DepositEventVersion0:
err = unmarshalDepositVersion0(&dep, to, opaqueData)
case DepositEventVersion1:
err = unmarshalDepositVersion1(&dep, to, opaqueData)
default:
return nil, fmt.Errorf("invalid deposit version, got %s", version)
}
Expand All @@ -96,6 +102,14 @@ func UnmarshalDepositLogEvent(ev *types.Log) (*types.DepositTx, error) {
return &dep, nil
}

func unpackNonceAndVersion(nonceAndVersion common.Hash) (nonce *big.Int, version *big.Int) {
i := new(big.Int).SetBytes(nonceAndVersion[:])
mask128 := new(big.Int).SetBytes(common.Hex2Bytes("ffffffffffffffffffffffffffffffff"))
version = mask128.And(mask128, i)
nonce = i.Lsh(i, 128)
return
}

func unmarshalDepositVersion0(dep *types.DepositTx, to common.Address, opaqueData []byte) error {
if len(opaqueData) < 32+32+8+1 {
return fmt.Errorf("unexpected opaqueData length: %d", len(opaqueData))
Expand Down Expand Up @@ -140,6 +154,11 @@ func unmarshalDepositVersion0(dep *types.DepositTx, to common.Address, opaqueDat
return nil
}

func unmarshalDepositVersion1(dep *types.DepositTx, to common.Address, opaqueData []byte) error {
// version 1 simply adds a nonce; the rest is the same
return unmarshalDepositVersion0(dep, to, opaqueData)
}

// MarshalDepositLogEvent returns an EVM log entry that encodes a TransactionDeposited event from the deposit contract.
// This is the reverse of the deposit transaction derivation.
func MarshalDepositLogEvent(depositContractAddr common.Address, deposit *types.DepositTx) (*types.Log, error) {
Expand All @@ -151,7 +170,7 @@ func MarshalDepositLogEvent(depositContractAddr common.Address, deposit *types.D
DepositEventABIHash,
eth.AddressAsLeftPaddedHash(deposit.From),
toBytes,
DepositEventVersion0,
common.BytesToHash(new(big.Int).SetUint64(DepositEventVersion0).Bytes()),
}

data := make([]byte, 64, 64+3*32)
Expand Down
2 changes: 1 addition & 1 deletion op-node/rollup/derive/deposit_log_tob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ func FuzzDeriveDepositsBadVersion(f *testing.F) {
}

// Set our bad topic and update our state
log.Topics[3] = badTopic
log.Topics[3] = common.BytesToHash(new(big.Int).SetUint64(badTopic).Bytes())
hasBadDepositVersion = true
}
}
Expand Down
16 changes: 11 additions & 5 deletions op-node/rollup/derive/system_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ var (
var (
ConfigUpdateEventABI = "ConfigUpdate(uint256,uint8,bytes)"
ConfigUpdateEventABIHash = crypto.Keccak256Hash([]byte(ConfigUpdateEventABI))
ConfigUpdateEventVersion0 = common.Hash{}
ConfigUpdateEventVersion0 = uint64(0)
ConfigUpdateEventVersion1 = uint64(1)
)

// UpdateSystemConfigWithL1Receipts filters all L1 receipts to find config updates and applies the config updates to the given sysCfg
Expand All @@ -53,7 +54,7 @@ func UpdateSystemConfigWithL1Receipts(sysCfg *eth.SystemConfig, receipts []*type
// parse log data for:
//
// event ConfigUpdate(
// uint256 indexed version,
// uint256 indexed nonceAndVersion,
// UpdateType indexed updateType,
// bytes data
// );
Expand All @@ -66,10 +67,15 @@ func ProcessSystemConfigUpdateLogEvent(destSysCfg *eth.SystemConfig, ev *types.L
}

// indexed 0
version := ev.Topics[1]
if version != ConfigUpdateEventVersion0 {
return fmt.Errorf("unrecognized SystemConfig update event version: %s", version)
_, versionBig := unpackNonceAndVersion(ev.Topics[1])
version := versionBig.Uint64()
switch version {
case ConfigUpdateEventVersion0:
case ConfigUpdateEventVersion1:
default:
return fmt.Errorf("unrecognized SystemConfig update event version: %d", version)
}

// indexed 1
updateType := ev.Topics[2]

Expand Down
27 changes: 18 additions & 9 deletions packages/contracts-bedrock/src/L1/OptimismPortal2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
uint256 internal immutable DISPUTE_GAME_FINALITY_DELAY_SECONDS;

/// @notice Version of the deposit event.
uint256 internal constant DEPOSIT_VERSION = 0;
uint256 internal constant DEPOSIT_VERSION = 1;

/// @notice The L2 gas limit set when eth is deposited using the receive() function.
uint64 internal constant RECEIVE_DEFAULT_GAS_LIMIT = 100_000;
Expand Down Expand Up @@ -141,14 +141,17 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
/// It is not safe to trust `ERC20.balanceOf` as it may lie.
uint256 internal _balance;

/// @notice Nonce incremented for each TransactionDeposited event
uint256 public transactionDepositedNonce;

/// @notice Emitted when a transaction is deposited from L1 to L2.
/// The parameters of this event are read by the rollup node and used to derive deposit
/// transactions on L2.
/// @param from Address that triggered the deposit transaction.
/// @param to Address that the deposit transaction is directed to.
/// @param version Version of this deposit transaction event.
/// @param opaqueData ABI encoded deposit data to be parsed off-chain.
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData);
/// @param from Address that triggered the deposit transaction.
/// @param to Address that the deposit transaction is directed to.
/// @param nonceAndVersion Nonce (first 128-bits) and version (second 128-bits).
/// @param opaqueData ABI encoded deposit data to be parsed off-chain.
event TransactionDeposited(address indexed from, address indexed to, uint256 indexed nonceAndVersion, bytes opaqueData);

/// @notice Emitted when a withdrawal transaction is proven.
/// @param withdrawalHash Hash of the withdrawal transaction.
Expand Down Expand Up @@ -597,7 +600,7 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {

// Emit a TransactionDeposited event so that the rollup node can derive a deposit
// transaction for this deposit.
emit TransactionDeposited(from, _to, DEPOSIT_VERSION, opaqueData);
_emitTransactionDeposited(from, _to, opaqueData);
}

/// @notice Sets the gas paying token for the L2 system. This token is used as the
Expand All @@ -611,10 +614,9 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {

// Emit the special deposit transaction directly that sets the gas paying
// token in the L1Block predeploy contract.
emit TransactionDeposited(
_emitTransactionDeposited(
Constants.DEPOSITOR_ACCOUNT,
Predeploys.L1_BLOCK_ATTRIBUTES,
DEPOSIT_VERSION,
abi.encodePacked(
uint256(0), // mint
uint256(0), // value
Expand All @@ -625,6 +627,13 @@ contract OptimismPortal2 is Initializable, ResourceMetering, ISemver {
);
}

/// @notice Emit a TransactionDeposited event and increment the nonce.
function _emitTransactionDeposited(address from, address to, bytes memory opaqueData) internal {
uint256 _version = transactionDepositedNonce << 128 | DEPOSIT_VERSION;
transactionDepositedNonce++;
emit TransactionDeposited(from, to, _version, opaqueData);
}

/// @notice Blacklists a dispute game. Should only be used in the event that a dispute game resolves incorrectly.
/// @param _disputeGame Dispute game to blacklist.
function blacklistDisputeGame(IDisputeGame _disputeGame) external {
Expand Down
32 changes: 21 additions & 11 deletions packages/contracts-bedrock/src/L1/SystemConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
}

/// @notice Version identifier, used for upgrades.
uint256 public constant VERSION = 0;
uint256 public constant VERSION = 1;

/// @notice Storage slot that the unsafe block signer is stored at.
/// Storing it at this deterministic storage slot allows for decoupling the storage
Expand Down Expand Up @@ -130,11 +130,14 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
/// @notice The EIP-1559 elasticity multiplier.
uint32 public eip1559Elasticity;

/// @notice Nonce incremented for each ConfigUpdate event
uint256 public configUpdateNonce;

/// @notice Emitted when configuration is updated.
/// @param version SystemConfig version.
/// @param updateType Type of update.
/// @param data Encoded update data.
event ConfigUpdate(uint256 indexed version, UpdateType indexed updateType, bytes data);
/// @param nonceAndVersion Nonce (first 128-bits) and version (second 128-bits).
/// @param updateType Type of update.
/// @param data Encoded update data.
event ConfigUpdate(uint256 indexed nonceAndVersion, UpdateType indexed updateType, bytes data);

/// @notice Semantic version.
/// @custom:semver 2.3.0-beta.9
Expand Down Expand Up @@ -323,7 +326,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
Storage.setAddress(UNSAFE_BLOCK_SIGNER_SLOT, _unsafeBlockSigner);

bytes memory data = abi.encode(_unsafeBlockSigner);
emit ConfigUpdate(VERSION, UpdateType.UNSAFE_BLOCK_SIGNER, data);
_emitConfigUpdate(UpdateType.UNSAFE_BLOCK_SIGNER, data);
}

/// @notice Updates the batcher hash. Can only be called by the owner.
Expand All @@ -338,7 +341,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
batcherHash = _batcherHash;

bytes memory data = abi.encode(_batcherHash);
emit ConfigUpdate(VERSION, UpdateType.BATCHER, data);
_emitConfigUpdate(UpdateType.BATCHER, data);
}

/// @notice Updates gas config. Can only be called by the owner.
Expand All @@ -359,7 +362,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
scalar = _scalar;

bytes memory data = abi.encode(_overhead, _scalar);
emit ConfigUpdate(VERSION, UpdateType.FEE_SCALARS, data);
_emitConfigUpdate(UpdateType.FEE_SCALARS, data);
}

/// @notice Updates gas config as of the Ecotone upgrade. Can only be called by the owner.
Expand All @@ -379,7 +382,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
scalar = (uint256(0x01) << 248) | (uint256(_blobbasefeeScalar) << 32) | _basefeeScalar;

bytes memory data = abi.encode(overhead, scalar);
emit ConfigUpdate(VERSION, UpdateType.FEE_SCALARS, data);
_emitConfigUpdate(UpdateType.FEE_SCALARS, data);
}

/// @notice Updates the L2 gas limit. Can only be called by the owner.
Expand All @@ -396,7 +399,7 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
gasLimit = _gasLimit;

bytes memory data = abi.encode(_gasLimit);
emit ConfigUpdate(VERSION, UpdateType.GAS_LIMIT, data);
_emitConfigUpdate(UpdateType.GAS_LIMIT, data);
}

/// @notice Updates the EIP-1559 parameters of the chain. Can only be called by the owner.
Expand All @@ -415,7 +418,14 @@ contract SystemConfig is OwnableUpgradeable, ISemver, IGasToken {
eip1559Elasticity = _elasticity;

bytes memory data = abi.encode(uint256(_denominator) << 32 | uint64(_elasticity));
emit ConfigUpdate(VERSION, UpdateType.EIP_1559_PARAMS, data);
_emitConfigUpdate(UpdateType.EIP_1559_PARAMS, data);
}

/// @notice Emit a ConfigUpdate event and increment the nonce.
function _emitConfigUpdate(UpdateType updateType, bytes memory data) internal {
uint256 _version = configUpdateNonce << 128 | VERSION;
configUpdateNonce++;
emit ConfigUpdate(_version, updateType, data);
}

/// @notice Sets the start block in a backwards compatible way. Proxies
Expand Down

0 comments on commit 116598a

Please sign in to comment.