-
Notifications
You must be signed in to change notification settings - Fork 3.9k
draft: ban-deposits-interop first RFC draft #11362
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
3d3e767
0d78e5a
37f17de
4f9621a
65b6804
70b7db0
24deb1c
2e322c9
f463e8a
e90db39
771b319
2838d6e
e40d49f
c89ffa4
ebc225d
198d683
1434e89
8e93fcc
abe646b
13096e8
057fc5b
5e0d64c
2c370f7
da494fd
09c549c
bc562de
a8fd430
0a803e5
78aa2c4
5eaf39d
d5ba5d1
f2d8fb8
ccf505d
a17e357
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,14 +20,19 @@ import ( | |
| const ( | ||
| L1InfoFuncBedrockSignature = "setL1BlockValues(uint64,uint64,uint256,bytes32,uint64,bytes32,uint256,uint256)" | ||
| L1InfoFuncEcotoneSignature = "setL1BlockValuesEcotone()" | ||
|
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") | ||
|
|
@@ -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 | ||
|
skeletor-spaceman marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| // Bedrock Binary Format | ||
|
|
@@ -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 { | ||
|
|
@@ -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 | ||
| } | ||
|
|
||
|
|
@@ -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") | ||
| } | ||
|
|
@@ -259,16 +270,40 @@ func L1BlockInfoFromBytes(rollupCfg *rollup.Config, l2BlockTime uint64, data []b | |
| return &info, info.unmarshalBinaryBedrock(data) | ||
| } | ||
|
|
||
| func (info *L1BlockInfo) marshalDepositsComplete() ([]byte, error) { | ||
|
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) { | ||
|
|
@@ -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) | ||
|
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) { | ||
|
skeletor-spaceman marked this conversation as resolved.
Outdated
|
||
| var data []byte | ||
| source := L1InfoDepositSource{ | ||
| L1BlockHash: block.Hash(), | ||
| SeqNumber: seqNumber, | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
| // 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, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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, | ||
|
skeletor-spaceman marked this conversation as resolved.
Outdated
|
||
| Data: data, | ||
|
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) { | ||
|
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) | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.