Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
3d3e767
feat: ban-deposits-interop first RFC draft
skeletor-spaceman Aug 5, 2024
0d78e5a
fix: missing marshalling of tx
skeletor-spaceman Aug 5, 2024
37f17de
feat: code cleanup and renaming
skeletor-spaceman Aug 6, 2024
4f9621a
feat: cleaner implementation, always set isDeposit on
skeletor-spaceman Aug 6, 2024
65b6804
feat: simplified deposits complete tx and added Isthmus L1Info tx
skeletor-spaceman Aug 6, 2024
70b7db0
feat: L1Block make ecotone a public function
skeletor-spaceman Aug 7, 2024
24deb1c
feat: re-organized shared functions
skeletor-spaceman Aug 7, 2024
2e322c9
Merge branch 'develop' of github.com:ethereum-optimism/optimism into …
skeletor-spaceman Aug 7, 2024
f463e8a
feat: revamp unmarshalBinaryIsthmusAndEcotone function
skeletor-spaceman Aug 7, 2024
e90db39
feat: ban deposits interop (#11396)
0xDiscotech Aug 8, 2024
771b319
Merge branch 'develop' into feat/ban-deposits-interop
skeletor-spaceman Aug 8, 2024
2838d6e
fix: removed duplicated function from bad merge
skeletor-spaceman Aug 8, 2024
e40d49f
fix: relevant comments added, optional bool removed
skeletor-spaceman Aug 8, 2024
c89ffa4
fix: sstore of isDeposit
skeletor-spaceman Aug 8, 2024
ebc225d
fix: sstore of isDeposit
skeletor-spaceman Aug 8, 2024
198d683
fix: is deposit relevant tests
skeletor-spaceman Aug 8, 2024
1434e89
fix: is deposit relevant tests
skeletor-spaceman Aug 8, 2024
8e93fcc
fix: reorder marshal funcs
skeletor-spaceman Aug 9, 2024
abe646b
feat: add DepositSource to avoid possible collitions
skeletor-spaceman Aug 9, 2024
13096e8
feat: renames and revert isDeposit on legacy L1 set
skeletor-spaceman Aug 12, 2024
057fc5b
feat: rename Deposit for AfterForceInclude
skeletor-spaceman Aug 12, 2024
5e0d64c
feat: ban deposits interop (#11451)
0xDiscotech Aug 12, 2024
2c370f7
fix: typo
skeletor-spaceman Aug 12, 2024
da494fd
feat: ban deposits interop (#11454)
0xDiscotech Aug 13, 2024
09c549c
feat: ban deposits interop (#11481)
0xDiscotech Aug 14, 2024
bc562de
chore: some renames
skeletor-spaceman Aug 14, 2024
a8fd430
chore: update gas limit of DepositsComplete
skeletor-spaceman Aug 15, 2024
0a803e5
chore: merged main
skeletor-spaceman Aug 15, 2024
78aa2c4
Merge branch 'develop' of github.com:ethereum-optimism/optimism into …
skeletor-spaceman Aug 16, 2024
5eaf39d
fix: deprecate Interop L1 block
skeletor-spaceman Aug 16, 2024
d5ba5d1
fix: missed interop filename changes
skeletor-spaceman Aug 16, 2024
f2d8fb8
feat: merged from upstream
skeletor-spaceman Aug 22, 2024
ccf505d
feat: ban deposits client tests (#11504)
skeletor-spaceman Aug 29, 2024
a17e357
feat: merged from develop
skeletor-spaceman Aug 29, 2024
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
17 changes: 15 additions & 2 deletions op-node/rollup/derive/attributes.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,27 @@ func (ba *FetchingAttributesBuilder) PreparePayloadAttributes(ctx context.Contex
upgradeTxs = append(upgradeTxs, fjord...)
}

l1InfoTx, err := L1InfoDepositBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2Time)
var hasDeposits = len(depositTxs) > 0
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
l1InfoTx, err := L1InfoDepositBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2Time, hasDeposits)
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create l1InfoTx: %w", err))
}

Comment thread
skeletor-spaceman marked this conversation as resolved.
txs := make([]hexutil.Bytes, 0, 1+len(depositTxs)+len(upgradeTxs))
var txsLen = 1 + len(depositTxs) + len(upgradeTxs)
if hasDeposits {
txsLen += 1 // for the isDeposit resetting tx
}
txs := make([]hexutil.Bytes, 0, txsLen)
txs = append(txs, l1InfoTx)
txs = append(txs, depositTxs...)
if hasDeposits {
depositsCompleteTx, err := DepositsCompleteBytes(ba.rollupCfg, sysConfig, seqNumber, l1Info, nextL2Time)
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
if err != nil {
return nil, NewCriticalError(fmt.Errorf("failed to create depositsCompleteTx: %w", err))
}
// after all the deposits have been processed, we need to include the isDeposit resetting tx
txs = append(txs, depositsCompleteTx)
}
txs = append(txs, upgradeTxs...)

var withdrawals *types.Withdrawals
Expand Down
80 changes: 77 additions & 3 deletions op-node/rollup/derive/l1_block_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,19 @@ import (
const (
L1InfoFuncBedrockSignature = "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)"
L1InfoFuncEcotoneSignature = "setL1BlockValuesEcotone()"
Comment thread
skeletor-spaceman marked this conversation as resolved.
DepositsCompleteSignature = "depositsComplete()"
L1InfoArguments = 8
L1InfoBedrockLen = 4 + 32*L1InfoArguments
L1InfoEcotoneLen = 4 + 32*5 // after Ecotone upgrade, args are packed into 5 32-byte slots
// TODO ^ we need to add space for the isDeposit flag here
// or should we create a new Len var for this?
DepositsCompleteLen = 4 // only the selector
)

var (
L1InfoFuncBedrockBytes4 = crypto.Keccak256([]byte(L1InfoFuncBedrockSignature))[:4]
L1InfoFuncEcotoneBytes4 = crypto.Keccak256([]byte(L1InfoFuncEcotoneSignature))[:4]
DepositsCompleteBytes4 = crypto.Keccak256([]byte(DepositsCompleteSignature))[:4]
L1InfoDepositerAddress = common.HexToAddress("0xdeaddeaddeaddeaddeaddeaddeaddeaddead0001")
L1BlockAddress = predeploys.L1BlockAddr
ErrInvalidFormat = errors.New("invalid ecotone l1 block info format")
Expand Down Expand Up @@ -55,6 +60,8 @@ type L1BlockInfo struct {
BlobBaseFee *big.Int // added by Ecotone upgrade
BaseFeeScalar uint32 // added by Ecotone upgrade
BlobBaseFeeScalar uint32 // added by Ecotone upgrade

IsDeposit bool // added by Interop upgrade
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
}

// Bedrock Binary Format
Expand Down Expand Up @@ -160,6 +167,8 @@ func (info *L1BlockInfo) unmarshalBinaryBedrock(data []byte) error {
// | 32 | BatcherHash |
// +---------+--------------------------+

// TODO: should we duplicate this function?
// or can we extend it somehow to only add the isDeposit flag at the end
func (info *L1BlockInfo) marshalBinaryEcotone() ([]byte, error) {
w := bytes.NewBuffer(make([]byte, 0, L1InfoEcotoneLen))
if err := solabi.WriteSignature(w, L1InfoFuncEcotoneBytes4); err != nil {
Expand Down Expand Up @@ -197,6 +206,7 @@ func (info *L1BlockInfo) marshalBinaryEcotone() ([]byte, error) {
if err := solabi.WriteAddress(w, info.BatcherAddr); err != nil {
return nil, err
}
// TODO: add isDeposit flag here
return w.Bytes(), nil
}

Expand Down Expand Up @@ -238,6 +248,7 @@ func (info *L1BlockInfo) unmarshalBinaryEcotone(data []byte) error {
if info.BatcherAddr, err = solabi.ReadAddress(r); err != nil {
return err
}
// TODO unmarshall isDeposit flag here
if !solabi.EmptyReader(r) {
return errors.New("too many bytes")
}
Expand All @@ -259,16 +270,40 @@ func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []b
return &info, info.unmarshalBinaryBedrock(data)
}

func (info *L1BlockInfo) marshalDepositsComplete() ([]byte, error) {
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
w := bytes.NewBuffer(make([]byte, 0, DepositsCompleteLen))
if err := solabi.WriteSignature(w, []byte(DepositsCompleteBytes4)); err != nil {
return nil, err
}
return w.Bytes(), nil
}

func (info *L1BlockInfo) unmarshalDepositsComplete(data []byte) error {
if len(data) != DepositsCompleteLen {
return fmt.Errorf("data is unexpected length: %d", len(data))
}
r := bytes.NewReader(data)

if _, err := solabi.ReadAndValidateSignature(r, DepositsCompleteBytes4); err != nil {
return err
}
if !solabi.EmptyReader(r) {
return errors.New("too many bytes")
}
return nil
}

// L1InfoDeposit creates a L1 Info deposit transaction based on the L1 block,
// and the L2 block-height difference with the start of the epoch.
func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64) (*types.DepositTx, error) {
func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64, isDeposit bool) (*types.DepositTx, error) {
l1BlockInfo := L1BlockInfo{
Number: block.NumberU64(),
Time: block.Time(),
BaseFee: block.BaseFee(),
BlockHash: block.Hash(),
SequenceNumber: seqNumber,
BatcherAddr: sysCfg.BatcherAddr,
IsDeposit: isDeposit,
}
var data []byte
if isEcotoneButNotFirstBlock(rollupCfg, l2BlockTime) {
Expand Down Expand Up @@ -323,8 +358,47 @@ func L1InfoDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber
}

// L1InfoDepositBytes returns a serialized L1-info attributes transaction.
func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64) ([]byte, error) {
dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime)
func L1InfoDepositBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64, isDeposit bool) ([]byte, error) {
dep, err := L1InfoDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime, isDeposit)
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
if err != nil {
return nil, fmt.Errorf("failed to create L1 info tx: %w", err)
}
l1Tx := types.NewTx(dep)
opaqueL1Tx, err := l1Tx.MarshalBinary()
if err != nil {
return nil, fmt.Errorf("failed to encode L1 info tx: %w", err)
}
return opaqueL1Tx, nil
}

func DepositsCompleteDeposit(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, block eth.BlockInfo, l2BlockTime uint64) (*types.DepositTx, error) {
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
var data []byte
source := L1InfoDepositSource{
L1BlockHash: block.Hash(),
SeqNumber: seqNumber,
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The idea of the "sourcehash" is that it helps uniquely identify deposit transactions, because they do not include a nonce.
While technically ok to reuse the same source-hash as the system L1Info deposit (since different tx contents are mixed in), I would prefer us to specify a new type of deposit-source, to really ensure the two deposits get a different tx-hash, and not surprise any users of the source-hash property.

// Set a normal gas limit with `IsSystemTransaction` to ensure
// that the DepositCompleted Transaction does not run out of gas.
out := &types.DepositTx{
SourceHash: source.SourceHash(),
From: L1InfoDepositerAddress,
To: &L1BlockAddress,
Mint: nil,
Value: big.NewInt(0),
Gas: 50_000,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Have we specified/checked how much gas this TX needs conservatively to run?

IsSystemTransaction: true,
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
Data: data,
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
}
// With the regolith fork we disable the IsSystemTx functionality, and allocate real gas
if rollupCfg.IsRegolith(l2BlockTime) {
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
out.IsSystemTransaction = false
out.Gas = RegolithSystemTxGas
}
return out, nil
}

func DepositsCompleteBytes(rollupCfg *rollup.Config, sysCfg eth.SystemConfig, seqNumber uint64, l1Info eth.BlockInfo, l2BlockTime uint64) ([]byte, error) {
dep, err := DepositsCompleteDeposit(rollupCfg, sysCfg, seqNumber, l1Info, l2BlockTime)
if err != nil {
return nil, fmt.Errorf("failed to create L1 info tx: %w", err)
}
Expand Down
6 changes: 6 additions & 0 deletions packages/contracts-bedrock/src/L2/CrossL2Inbox.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ error InvalidChainId();
/// @notice Thrown when trying to execute a cross chain message and the target call fails.
error TargetCallFailed();

/// @notice Thrown when trying to execute a cross chain message on a deposit transaction.
error NoExecutingDeposits();

/// @custom:proxied
/// @custom:predeploy 0x4200000000000000000000000000000000000022
/// @title CrossL2Inbox
Expand Down Expand Up @@ -114,6 +117,9 @@ contract CrossL2Inbox is ICrossL2Inbox, ISemver, TransientReentrancyAware {
payable
reentrantAware
{
// We need to know if this is being called on a depositTx
if (L1_BLOCK.isDeposit()) revert NoExecutingDeposits();

Comment thread
skeletor-spaceman marked this conversation as resolved.
if (_id.timestamp > block.timestamp) revert InvalidTimestamp();
if (!IDependencySet(Predeploys.L1_BLOCK_ATTRIBUTES).isInDependencySet(_id.chainId)) {
revert InvalidChainId();
Expand Down
23 changes: 21 additions & 2 deletions packages/contracts-bedrock/src/L2/L1Block.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ contract L1Block is ISemver, IGasToken {
/// @notice The latest L1 blob base fee.
uint256 public blobBaseFee;

/// @notice The isDeposit flag.
bool public isDeposit;
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated

/// @custom:semver 1.4.1-beta.1
function version() public pure virtual returns (string memory) {
return "1.4.1-beta.1";
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
Expand Down Expand Up @@ -87,6 +90,11 @@ contract L1Block is ISemver, IGasToken {
return token != Constants.ETHER;
}

function isDeposit() returns (bool _isDeposit) external view {
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
require(msg.sender == CROSS_L2_INBOX, "L1Block: only the CrossL2Inbox can check if it is a deposit");
returns isDeposit;
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
}

/// @custom:legacy
/// @notice Updates the L1 block values.
/// @param _number L1 blocknumber.
Expand All @@ -97,6 +105,7 @@ contract L1Block is ISemver, IGasToken {
/// @param _batcherHash Versioned hash to authenticate batcher by.
/// @param _l1FeeOverhead L1 fee overhead.
/// @param _l1FeeScalar L1 fee scalar.
/// @param _isDeposit isDeposit flag
function setL1BlockValues(
uint64 _number,
uint64 _timestamp,
Expand All @@ -105,7 +114,8 @@ contract L1Block is ISemver, IGasToken {
uint64 _sequenceNumber,
bytes32 _batcherHash,
uint256 _l1FeeOverhead,
uint256 _l1FeeScalar
uint256 _l1FeeScalar,
bool _isDeposit
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
)
external
{
Expand All @@ -119,6 +129,7 @@ contract L1Block is ISemver, IGasToken {
batcherHash = _batcherHash;
l1FeeOverhead = _l1FeeOverhead;
l1FeeScalar = _l1FeeScalar;
isDeposit = _isDeposit;
}

/// @notice Updates the L1 block values for an Ecotone upgraded chain.
Expand All @@ -133,7 +144,8 @@ contract L1Block is ISemver, IGasToken {
/// 7. _blobBaseFee L1 blob base fee.
/// 8. _hash L1 blockhash.
/// 9. _batcherHash Versioned hash to authenticate batcher by.
function setL1BlockValuesEcotone() external {
/// 10. _isDeposit isDeposit flag
function setL1BlockValuesInterop() external {
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
address depositor = DEPOSITOR_ACCOUNT();
assembly {
// Revert if the caller is not the depositor account.
Expand All @@ -149,6 +161,7 @@ contract L1Block is ISemver, IGasToken {
sstore(blobBaseFee.slot, calldataload(68)) // uint256
sstore(hash.slot, calldataload(100)) // bytes32
sstore(batcherHash.slot, calldataload(132)) // bytes32
sstore(isDeposit.slot, calldataload(133)) // boolean
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
}
}

Expand All @@ -162,4 +175,10 @@ contract L1Block is ISemver, IGasToken {

emit GasPayingTokenSet({ token: _token, decimals: _decimals, name: _name, symbol: _symbol });
}

/// @notice Resets the isDeposit flag.
function depositsComplete() external {
if (msg.sender != DEPOSITOR_ACCOUNT()) revert NotDepositor();
isDeposit = false;
}
Comment thread
skeletor-spaceman marked this conversation as resolved.
Outdated
}