Commit b096e724 authored by Joshua Gutow's avatar Joshua Gutow Committed by GitHub

Update withdrawal params for two step withdrawals (#4275)

This renames the L2 block field to the L2 Index. This more accurately
matches what the L2 output oracle contract expects.
parent 633ff747
......@@ -201,14 +201,10 @@ func TestBedrockIndexer(t *testing.T) {
require.NoError(t, err)
proofCl := gethclient.New(rpcClient)
receiptCl := ethclient.NewClient(rpcClient)
wParams, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, wdTx.Hash(), finHeader)
require.NoError(t, err)
oracle, err := bindings.NewL2OutputOracleCaller(predeploys.DevL2OutputOracleAddr, l1Client)
require.Nil(t, err)
l2OutputIndex, err := oracle.GetL2OutputIndexAfter(&bind.CallOpts{}, wParams.BlockNumber)
require.Nil(t, err)
wParams, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, wdTx.Hash(), finHeader, oracle)
require.NoError(t, err)
l1Opts.Value = big.NewInt(0)
// Prove our withdrawal
......@@ -222,7 +218,7 @@ func TestBedrockIndexer(t *testing.T) {
GasLimit: wParams.GasLimit,
Data: wParams.Data,
},
l2OutputIndex,
wParams.L2OutputIndex,
wParams.OutputRootProof,
wParams.WithdrawalProof,
)
......@@ -236,7 +232,7 @@ func TestBedrockIndexer(t *testing.T) {
e2eutils.TimeoutCtx(t, time.Minute),
l1Client,
predeploys.DevOptimismPortalAddr,
wParams.BlockNumber,
finHeader.Number,
)
require.NoError(t, err)
......
......@@ -409,7 +409,7 @@ func (s *CrossLayerUser) ProveWithdrawal(t Testing, l2TxHash common.Hash) common
// We generate a proof for the latest L2 output, which shouldn't require archive-node data if it's recent enough.
header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr)
require.NoError(t, err)
params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header)
params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller)
require.NoError(t, err)
// Create the prove tx
......@@ -480,7 +480,7 @@ func (s *CrossLayerUser) CompleteWithdrawal(t Testing, l2TxHash common.Hash) com
// params for the `WithdrawalTransaction` type generated in the bindings.
header, err := s.L2.env.EthCl.HeaderByNumber(t.Ctx(), l2OutputBlockNr)
require.NoError(t, err)
params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header)
params, err := withdrawals.ProveWithdrawalParameters(t.Ctx(), s.L2.env.Bindings.ProofClient, s.L2.env.EthCl, s.lastL2WithdrawalTxHash, header, &s.L1.env.Bindings.L2OutputOracle.L2OutputOracleCaller)
require.NoError(t, err)
// Create the withdrawal tx
......
......@@ -836,16 +836,13 @@ func TestWithdrawals(t *testing.T) {
receiptCl := ethclient.NewClient(rpcClient)
// Now create withdrawal
params, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, tx.Hash(), header)
require.Nil(t, err)
portal, err := bindings.NewOptimismPortal(predeploys.DevOptimismPortalAddr, l1Client)
oracle, err := bindings.NewL2OutputOracleCaller(predeploys.DevL2OutputOracleAddr, l1Client)
require.Nil(t, err)
oracle, err := bindings.NewL2OutputOracleCaller(predeploys.DevL2OutputOracleAddr, l1Client)
params, err := withdrawals.ProveWithdrawalParameters(context.Background(), proofCl, receiptCl, tx.Hash(), header, oracle)
require.Nil(t, err)
l2OutputIndex, err := oracle.GetL2OutputIndexAfter(&bind.CallOpts{}, params.BlockNumber)
portal, err := bindings.NewOptimismPortal(predeploys.DevOptimismPortalAddr, l1Client)
require.Nil(t, err)
opts.Value = nil
......@@ -861,7 +858,7 @@ func TestWithdrawals(t *testing.T) {
GasLimit: params.GasLimit,
Data: params.Data,
},
l2OutputIndex,
params.L2OutputIndex,
params.OutputRootProof,
params.WithdrawalProof,
)
......@@ -875,7 +872,7 @@ func TestWithdrawals(t *testing.T) {
// Wait for finalization and then create the Finalized Withdrawal Transaction
ctx, cancel = context.WithTimeout(context.Background(), 20*time.Duration(cfg.DeployConfig.L1BlockTime)*time.Second)
defer cancel()
_, err = withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, params.BlockNumber)
_, err = withdrawals.WaitForFinalizationPeriod(ctx, l1Client, predeploys.DevOptimismPortalAddr, header.Number)
require.Nil(t, err)
// Finalize withdrawal
......
......@@ -137,16 +137,16 @@ type ProvenWithdrawalParameters struct {
Target common.Address
Value *big.Int
GasLimit *big.Int
BlockNumber *big.Int
L2OutputIndex *big.Int
Data []byte
OutputRootProof bindings.TypesOutputRootProof
WithdrawalProof [][]byte // List of trie nodes to prove L2 storage
}
// ProveWithdrawalParameters queries L2 to generate all withdrawal parameters and proof necessary to prove a withdrawal on L1.
// ProveWithdrawalParameters queries L1 & L2 to generate all withdrawal parameters and proof necessary to prove a withdrawal on L1.
// The header provided is very important. It should be a block (timestamp) for which there is a submitted output in the L2 Output Oracle
// contract. If not, the withdrawal will fail as it the storage proof cannot be verified if there is no submitted state root.
func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, txHash common.Hash, header *types.Header) (ProvenWithdrawalParameters, error) {
func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2ReceiptCl ReceiptClient, txHash common.Hash, header *types.Header, l2OutputOracleContract *bindings.L2OutputOracleCaller) (ProvenWithdrawalParameters, error) {
// Transaction receipt
receipt, err := l2ReceiptCl.TransactionReceipt(ctx, txHash)
if err != nil {
......@@ -170,6 +170,12 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2Recei
if err != nil {
return ProvenWithdrawalParameters{}, err
}
// Fetch the L2OutputIndex from the L2 Output Oracle caller (on L1)
l2OutputIndex, err := l2OutputOracleContract.GetL2OutputIndexAfter(&bind.CallOpts{}, header.Number)
if err != nil {
return ProvenWithdrawalParameters{}, fmt.Errorf("failed to get l2OutputIndex: %w", err)
}
// TODO: Could skip this step, but it's nice to double check it
err = VerifyProof(header.Root, p)
if err != nil {
......@@ -186,13 +192,13 @@ func ProveWithdrawalParameters(ctx context.Context, proofCl ProofClient, l2Recei
}
return ProvenWithdrawalParameters{
Nonce: ev.Nonce,
Sender: ev.Sender,
Target: ev.Target,
Value: ev.Value,
GasLimit: ev.GasLimit,
BlockNumber: new(big.Int).Set(header.Number),
Data: ev.Data,
Nonce: ev.Nonce,
Sender: ev.Sender,
Target: ev.Target,
Value: ev.Value,
GasLimit: ev.GasLimit,
L2OutputIndex: l2OutputIndex,
Data: ev.Data,
OutputRootProof: bindings.TypesOutputRootProof{
Version: [32]byte{}, // Empty for version 1
StateRoot: header.Root,
......
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