Commit 22067e94 authored by Hamdi Allam's avatar Hamdi Allam

cursor e2e tests

parent 828f0d41
...@@ -137,12 +137,12 @@ func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, c ...@@ -137,12 +137,12 @@ func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, c
cursorClause := "" cursorClause := ""
if cursor != "" { if cursor != "" {
sourceHash := common.HexToHash(cursor) sourceHash := common.HexToHash(cursor)
var txDeposit L1TransactionDeposit txDeposit := new(L1TransactionDeposit)
result := db.gorm.Model(&L1TransactionDeposit{}).Where(&L1TransactionDeposit{SourceHash: sourceHash}).Take(&txDeposit) result := db.gorm.Model(&L1TransactionDeposit{}).Where(&L1TransactionDeposit{SourceHash: sourceHash}).Take(txDeposit)
if result.Error != nil || errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil || errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("unable to find transaction with supplied cursor source hash %s: %w", sourceHash, result.Error) return nil, fmt.Errorf("unable to find transaction with supplied cursor source hash %s: %w", sourceHash, result.Error)
} }
cursorClause = fmt.Sprintf("timestamp < %d", txDeposit.Tx.Timestamp) cursorClause = fmt.Sprintf("l1_transaction_deposits.timestamp <= %d", txDeposit.Tx.Timestamp)
} }
// TODO join with l1_bridged_tokens and l2_bridged_tokens // TODO join with l1_bridged_tokens and l2_bridged_tokens
...@@ -150,13 +150,13 @@ func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, c ...@@ -150,13 +150,13 @@ func (db *bridgeTransfersDB) L1BridgeDepositsByAddress(address common.Address, c
// Coalesce l1 transaction deposits that are simply ETH sends // Coalesce l1 transaction deposits that are simply ETH sends
ethTransactionDeposits := db.gorm.Model(&L1TransactionDeposit{}) ethTransactionDeposits := db.gorm.Model(&L1TransactionDeposit{})
ethTransactionDeposits = ethTransactionDeposits.Where(Transaction{FromAddress: address}).Where(`data = '0x' AND amount > 0`) ethTransactionDeposits = ethTransactionDeposits.Where(Transaction{FromAddress: address}).Where("data = '0x' AND amount > 0")
ethTransactionDeposits = ethTransactionDeposits.Joins("INNER JOIN l1_contract_events ON l1_contract_events.guid = initiated_l1_event_guid") ethTransactionDeposits = ethTransactionDeposits.Joins("INNER JOIN l1_contract_events ON l1_contract_events.guid = initiated_l1_event_guid")
ethTransactionDeposits = ethTransactionDeposits.Select(` ethTransactionDeposits = ethTransactionDeposits.Select(`
from_address, to_address, amount, data, source_hash AS transaction_source_hash, from_address, to_address, amount, data, source_hash AS transaction_source_hash,
l2_transaction_hash, l1_contract_events.transaction_hash AS l1_transaction_hash, l2_transaction_hash, l1_contract_events.transaction_hash AS l1_transaction_hash,
l1_transaction_deposits.timestamp, NULL AS cross_domain_message_hash, ? AS local_token_address, ? AS remote_token_address`, ethAddressString, ethAddressString) l1_transaction_deposits.timestamp, NULL AS cross_domain_message_hash, ? AS local_token_address, ? AS remote_token_address`, ethAddressString, ethAddressString)
ethTransactionDeposits = ethTransactionDeposits.Limit(limit + 1) ethTransactionDeposits = ethTransactionDeposits.Order("timestamp DESC").Limit(limit + 1)
if cursorClause != "" { if cursorClause != "" {
ethTransactionDeposits = ethTransactionDeposits.Where(cursorClause) ethTransactionDeposits = ethTransactionDeposits.Where(cursorClause)
} }
...@@ -168,7 +168,7 @@ l1_transaction_deposits.timestamp, NULL AS cross_domain_message_hash, ? AS local ...@@ -168,7 +168,7 @@ l1_transaction_deposits.timestamp, NULL AS cross_domain_message_hash, ? AS local
l1_bridge_deposits.from_address, l1_bridge_deposits.to_address, l1_bridge_deposits.amount, l1_bridge_deposits.data, transaction_source_hash, l1_bridge_deposits.from_address, l1_bridge_deposits.to_address, l1_bridge_deposits.amount, l1_bridge_deposits.data, transaction_source_hash,
l2_transaction_hash, l1_contract_events.transaction_hash AS l1_transaction_hash, l2_transaction_hash, l1_contract_events.transaction_hash AS l1_transaction_hash,
l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, remote_token_address`) l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, remote_token_address`)
depositsQuery = depositsQuery.Limit(limit + 1) depositsQuery = depositsQuery.Order("timestamp DESC").Limit(limit + 1)
if cursorClause != "" { if cursorClause != "" {
depositsQuery = depositsQuery.Where(cursorClause) depositsQuery = depositsQuery.Where(cursorClause)
} }
...@@ -189,16 +189,11 @@ l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, re ...@@ -189,16 +189,11 @@ l1_bridge_deposits.timestamp, cross_domain_message_hash, local_token_address, re
hasNextPage := false hasNextPage := false
if len(deposits) > limit { if len(deposits) > limit {
hasNextPage = true hasNextPage = true
deposits = deposits[:limit]
nextCursor = deposits[limit].L1BridgeDeposit.TransactionSourceHash.String() nextCursor = deposits[limit].L1BridgeDeposit.TransactionSourceHash.String()
deposits = deposits[:limit]
} }
response := &L1BridgeDepositsResponse{ response := &L1BridgeDepositsResponse{Deposits: deposits, Cursor: nextCursor, HasNextPage: hasNextPage}
Deposits: deposits,
Cursor: nextCursor,
HasNextPage: hasNextPage,
}
return response, nil return response, nil
} }
...@@ -260,7 +255,7 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawalsByAddress(address common.Address ...@@ -260,7 +255,7 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawalsByAddress(address common.Address
if result.Error != nil || errors.Is(result.Error, gorm.ErrRecordNotFound) { if result.Error != nil || errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, fmt.Errorf("unable to find transaction with supplied cursor withdrawal hash %s: %w", withdrawalHash, result.Error) return nil, fmt.Errorf("unable to find transaction with supplied cursor withdrawal hash %s: %w", withdrawalHash, result.Error)
} }
cursorClause = fmt.Sprintf("timestamp < %d", txWithdrawal.Tx.Timestamp) cursorClause = fmt.Sprintf("l2_transaction_withdrawals.timestamp <= %d", txWithdrawal.Tx.Timestamp)
} }
// TODO join with l1_bridged_tokens and l2_bridged_tokens // TODO join with l1_bridged_tokens and l2_bridged_tokens
...@@ -276,7 +271,7 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawalsByAddress(address common.Address ...@@ -276,7 +271,7 @@ func (db *bridgeTransfersDB) L2BridgeWithdrawalsByAddress(address common.Address
from_address, to_address, amount, data, withdrawal_hash AS transaction_withdrawal_hash, from_address, to_address, amount, data, withdrawal_hash AS transaction_withdrawal_hash,
l2_contract_events.transaction_hash AS l2_transaction_hash, proven_l1_events.transaction_hash AS proven_l1_transaction_hash, finalized_l1_events.transaction_hash AS finalized_l1_transaction_hash, l2_contract_events.transaction_hash AS l2_transaction_hash, proven_l1_events.transaction_hash AS proven_l1_transaction_hash, finalized_l1_events.transaction_hash AS finalized_l1_transaction_hash,
l2_transaction_withdrawals.timestamp, NULL AS cross_domain_message_hash, ? AS local_token_address, ? AS remote_token_address`, ethAddressString, ethAddressString) l2_transaction_withdrawals.timestamp, NULL AS cross_domain_message_hash, ? AS local_token_address, ? AS remote_token_address`, ethAddressString, ethAddressString)
ethTransactionWithdrawals = ethTransactionWithdrawals.Limit(limit + 1) ethTransactionWithdrawals = ethTransactionWithdrawals.Order("timestamp DESC").Limit(limit + 1)
if cursorClause != "" { if cursorClause != "" {
ethTransactionWithdrawals = ethTransactionWithdrawals.Where(cursorClause) ethTransactionWithdrawals = ethTransactionWithdrawals.Where(cursorClause)
} }
...@@ -290,7 +285,7 @@ l2_transaction_withdrawals.timestamp, NULL AS cross_domain_message_hash, ? AS lo ...@@ -290,7 +285,7 @@ l2_transaction_withdrawals.timestamp, NULL AS cross_domain_message_hash, ? AS lo
l2_bridge_withdrawals.from_address, l2_bridge_withdrawals.to_address, l2_bridge_withdrawals.amount, l2_bridge_withdrawals.data, transaction_withdrawal_hash, l2_bridge_withdrawals.from_address, l2_bridge_withdrawals.to_address, l2_bridge_withdrawals.amount, l2_bridge_withdrawals.data, transaction_withdrawal_hash,
l2_contract_events.transaction_hash AS l2_transaction_hash, proven_l1_events.transaction_hash AS proven_l1_transaction_hash, finalized_l1_events.transaction_hash AS finalized_l1_transaction_hash, l2_contract_events.transaction_hash AS l2_transaction_hash, proven_l1_events.transaction_hash AS proven_l1_transaction_hash, finalized_l1_events.transaction_hash AS finalized_l1_transaction_hash,
l2_bridge_withdrawals.timestamp, cross_domain_message_hash, local_token_address, remote_token_address`) l2_bridge_withdrawals.timestamp, cross_domain_message_hash, local_token_address, remote_token_address`)
withdrawalsQuery = withdrawalsQuery.Limit(limit + 1) withdrawalsQuery = withdrawalsQuery.Order("timestamp DESC").Limit(limit + 1)
if cursorClause != "" { if cursorClause != "" {
withdrawalsQuery = withdrawalsQuery.Where(cursorClause) withdrawalsQuery = withdrawalsQuery.Where(cursorClause)
} }
...@@ -311,21 +306,10 @@ l2_bridge_withdrawals.timestamp, cross_domain_message_hash, local_token_address, ...@@ -311,21 +306,10 @@ l2_bridge_withdrawals.timestamp, cross_domain_message_hash, local_token_address,
hasNextPage := false hasNextPage := false
if len(withdrawals) > limit { if len(withdrawals) > limit {
hasNextPage = true hasNextPage = true
withdrawals = withdrawals[:limit]
nextCursor = withdrawals[limit].L2BridgeWithdrawal.TransactionWithdrawalHash.String() nextCursor = withdrawals[limit].L2BridgeWithdrawal.TransactionWithdrawalHash.String()
withdrawals = withdrawals[:limit]
} }
if result.Error != nil { response := &L2BridgeWithdrawalsResponse{Withdrawals: withdrawals, Cursor: nextCursor, HasNextPage: hasNextPage}
if errors.Is(result.Error, gorm.ErrRecordNotFound) {
return nil, nil
}
return nil, result.Error
}
response := &L2BridgeWithdrawalsResponse{
Withdrawals: withdrawals,
Cursor: nextCursor,
HasNextPage: hasNextPage,
}
return response, nil return response, nil
} }
...@@ -2,12 +2,14 @@ package e2e_tests ...@@ -2,12 +2,14 @@ package e2e_tests
import ( import (
"context" "context"
"fmt"
"math/big" "math/big"
"testing" "testing"
"time" "time"
e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils" e2etest_utils "github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
op_e2e "github.com/ethereum-optimism/optimism/op-e2e" op_e2e "github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/transactions"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait" "github.com/ethereum-optimism/optimism/op-e2e/e2eutils/wait"
"github.com/ethereum-optimism/optimism/op-node/withdrawals" "github.com/ethereum-optimism/optimism/op-node/withdrawals"
...@@ -86,118 +88,6 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) { ...@@ -86,118 +88,6 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
require.NotNil(t, crossDomainBridgeMessage.RelayedMessageEventGUID) require.NotNil(t, crossDomainBridgeMessage.RelayedMessageEventGUID)
} }
/*
TODO make this test work:
Error Trace: /root/project/indexer/e2e_tests/bridge_transfers_e2e_test.go:116
Error: Received unexpected error:
expected status 1, but got 0
tx trace unavailable: websocket: read limit exceeded
Test: TestE2EBridgeTransfersPagination
func TestE2EBridgeTransfersPagination(t *testing.T) {
testSuite := createE2ETestSuite(t)
l1StandardBridge, err := bindings.NewL1StandardBridge(testSuite.OpCfg.L1Deployments.L1StandardBridgeProxy, testSuite.L1Client)
require.NoError(t, err)
// 1 ETH transfer
aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice
// (1) Test Deposit Initiation
var deposits []struct {
Tx *types.Transaction
Receipt *types.Receipt
Info *e2etest_utils.DepositInfo
}
for i := 0; i < 3; i++ {
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
l1Opts.Value = big.NewInt(params.Ether)
depositTx, err := l1StandardBridge.DepositETH(l1Opts, 200_000, []byte{byte(i)})
require.NoError(t, err)
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
depositInfo, err := e2etest_utils.ParseDepositInfo(depositReceipt)
require.NoError(t, err)
// wait for processor catchup
err = wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
l1Header := testSuite.Indexer.L1Processor.LatestProcessedHeader()
return l1Header != nil && l1Header.Number.Uint64() >= depositReceipt.BlockNumber.Uint64(), nil
})
require.NoError(t, err)
deposits = append(deposits, struct {
Tx *types.Transaction
Receipt *types.Receipt
Info *e2etest_utils.DepositInfo
}{
Tx: depositTx,
Receipt: depositReceipt,
Info: depositInfo,
})
// wait for processor catchup
require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
l1Header := testSuite.Indexer.L1Processor.LatestProcessedHeader()
return l1Header != nil && l1Header.Number.Uint64() >= deposits[i].Receipt.BlockNumber.Uint64(), nil
}))
}
// Test no cursor or limit
cursor := ""
limit := 0
aliceDeposits, err := testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 3)
require.Equal(t, deposits[0].Tx.Hash(), aliceDeposits.Deposits[0].L1TransactionHash)
require.Equal(t, deposits[1].Tx.Hash(), aliceDeposits.Deposits[1].L1TransactionHash)
require.Equal(t, deposits[2].Tx.Hash(), aliceDeposits.Deposits[2].L1TransactionHash)
require.Equal(t, "", aliceDeposits.Cursor)
require.Equal(t, false, aliceDeposits.HasNextPage)
// test cursor with no limit
cursor = deposits[1].Tx.Hash().String()
limit = 0
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 2)
require.Equal(t, deposits[1].Tx.Hash().String(), aliceDeposits.Deposits[0].L1TransactionHash)
require.Equal(t, deposits[2].Tx.Hash().String(), aliceDeposits.Deposits[1].L1TransactionHash)
require.Equal(t, "", aliceDeposits.Cursor)
require.Equal(t, false, aliceDeposits.HasNextPage)
// test no cursor with limit and hasNext page is true
cursor = ""
limit = 2
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, limit)
require.Equal(t, deposits[0].Tx.Hash().String(), aliceDeposits.Deposits[0].L1TransactionHash)
require.Equal(t, deposits[1].Tx.Hash().String(), aliceDeposits.Deposits[1].L1TransactionHash)
require.Equal(t, deposits[2].Tx.Hash().String(), aliceDeposits.Cursor)
require.Equal(t, true, aliceDeposits.HasNextPage)
// test cursor with limit and hasNext page is true
cursor = deposits[1].Tx.Hash().String()
limit = 1
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 1)
require.Equal(t, deposits[1].Tx.Hash().String(), aliceDeposits.Deposits[1].L1TransactionHash)
require.Equal(t, deposits[2].Tx.Hash().String(), aliceDeposits.Cursor)
require.Equal(t, true, aliceDeposits.HasNextPage)
// limit bigger than the total amount
cursor = ""
limit = 10
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 3)
}
*/
func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) { func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) {
testSuite := createE2ETestSuite(t) testSuite := createE2ETestSuite(t)
...@@ -257,6 +147,78 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) { ...@@ -257,6 +147,78 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) {
require.Nil(t, aliceDeposits.Deposits[0].L1BridgeDeposit.CrossDomainMessageHash) require.Nil(t, aliceDeposits.Deposits[0].L1BridgeDeposit.CrossDomainMessageHash)
} }
func TestE2EBridgeTransfersCursoredDeposits(t *testing.T) {
testSuite := createE2ETestSuite(t)
l1StandardBridge, err := bindings.NewL1StandardBridge(testSuite.OpCfg.L1Deployments.L1StandardBridgeProxy, testSuite.L1Client)
require.NoError(t, err)
optimismPortal, err := bindings.NewOptimismPortal(testSuite.OpCfg.L1Deployments.OptimismPortalProxy, testSuite.L1Client)
require.NoError(t, err)
aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
require.NoError(t, err)
// Deposit 1/2/3 ETH (second deposit via the optimism portal)
var depositReceipts [3]*types.Receipt
for i := 0; i < 3; i++ {
var depositTx *types.Transaction
l1Opts.Value = big.NewInt(int64((i + 1)) * params.Ether)
if i != 1 {
depositTx, err = transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l1StandardBridge.Receive(opts)
})
require.NoError(t, err)
} else {
depositTx, err = transactions.PadGasEstimate(l1Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return optimismPortal.Receive(opts)
})
require.NoError(t, err)
}
depositReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err, fmt.Sprintf("failed on deposit %d", i))
depositReceipts[i] = depositReceipt
}
// wait for processor catchup of the latest tx
require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
l1Header := testSuite.Indexer.BridgeProcessor.LatestL1Header
return l1Header != nil && l1Header.Number.Uint64() >= depositReceipts[2].BlockNumber.Uint64(), nil
}))
// Get All
aliceDeposits, err := testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, "", 0)
require.NotNil(t, aliceDeposits)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 3)
require.False(t, aliceDeposits.HasNextPage)
// Respects Limits & Supplied Cursors
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, "", 2)
require.NotNil(t, aliceDeposits)
require.NoError(t, err)
require.Len(t, aliceDeposits.Deposits, 2)
require.True(t, aliceDeposits.HasNextPage)
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, aliceDeposits.Cursor, 2)
require.NotNil(t, aliceDeposits)
require.Len(t, aliceDeposits.Deposits, 1)
require.False(t, aliceDeposits.HasNextPage)
// Returns the results in the right order
aliceDeposits, err = testSuite.DB.BridgeTransfers.L1BridgeDepositsByAddress(aliceAddr, "", 100)
require.NotNil(t, aliceDeposits)
require.NoError(t, err)
for i := 0; i < 3; i++ {
deposit := aliceDeposits.Deposits[i]
// DESCENDING order
require.Equal(t, depositReceipts[2-i].TxHash, deposit.L1TransactionHash)
require.Equal(t, int64(3-i)*params.Ether, deposit.L1BridgeDeposit.Tx.Amount.Int64())
}
}
func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) { func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
testSuite := createE2ETestSuite(t) testSuite := createE2ETestSuite(t)
...@@ -415,90 +377,88 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) { ...@@ -415,90 +377,88 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) {
require.Equal(t, finalizeReceipt.TxHash, aliceWithdrawals.Withdrawals[0].FinalizedL1TransactionHash) require.Equal(t, finalizeReceipt.TxHash, aliceWithdrawals.Withdrawals[0].FinalizedL1TransactionHash)
} }
/** func TestE2EBridgeTransfersCursoredWithdrawals(t *testing.T) {
THIS test will work after we order transactions correctly
func TestE2EBridgeTransfersPaginationWithdrawals(t *testing.T) {
testSuite := createE2ETestSuite(t) testSuite := createE2ETestSuite(t)
l2StandardBridge, err := bindings.NewL2StandardBridge(predeploys.L2StandardBridgeAddr, testSuite.L2Client) l2StandardBridge, err := bindings.NewL2StandardBridge(predeploys.L2StandardBridgeAddr, testSuite.L2Client)
require.NoError(t, err) require.NoError(t, err)
l2ToL1MP, err := bindings.NewOptimismPortal(predeploys.L2ToL1MessagePasserAddr, testSuite.L2Client)
require.NoError(t, err)
// 1 ETH transfer
aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice aliceAddr := testSuite.OpCfg.Secrets.Addresses().Alice
l2Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L2ChainIDBig()) l2Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L2ChainIDBig())
require.NoError(t, err) require.NoError(t, err)
l2Opts.Value = big.NewInt(params.Ether)
var withdrawals []struct { // Ensure L1 has enough funds for the withdrawal by depositing an equal amount into the OptimismPortal
Tx *types.Transaction func() {
Receipt *types.Receipt optimismPortal, err := bindings.NewOptimismPortal(testSuite.OpCfg.L1Deployments.OptimismPortalProxy, testSuite.L1Client)
}
for i := 0; i < 3; i++ {
withdrawTx, err := l2StandardBridge.Withdraw(l2Opts, predeploys.LegacyERC20ETHAddr, l2Opts.Value, 200_000, []byte{byte(i)})
require.NoError(t, err) require.NoError(t, err)
l1Opts, err := bind.NewKeyedTransactorWithChainID(testSuite.OpCfg.Secrets.Alice, testSuite.OpCfg.L1ChainIDBig())
withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash())
require.NoError(t, err) require.NoError(t, err)
l1Opts.Value = big.NewInt(6 * params.Ether)
depositTx, err := optimismPortal.Receive(l1Opts)
require.NoError(t, err)
_, err = wait.ForReceiptOK(context.Background(), testSuite.L1Client, depositTx.Hash())
require.NoError(t, err)
}()
err = wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) { // Withdraw 1/2/3 ETH (second deposit via the l2ToL1MP)
l2Header := testSuite.Indexer.L2Processor.LatestProcessedHeader() var withdrawReceipts [3]*types.Receipt
return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipt.BlockNumber.Uint64(), nil for i := 0; i < 3; i++ {
var withdrawTx *types.Transaction
l2Opts.Value = big.NewInt(int64((i + 1)) * params.Ether)
if i != 1 {
withdrawTx, err = transactions.PadGasEstimate(l2Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
return l2StandardBridge.Receive(opts)
}) })
require.NoError(t, err) require.NoError(t, err)
} else {
withdrawals = append(withdrawals, struct { withdrawTx, err = transactions.PadGasEstimate(l2Opts, 1.1, func(opts *bind.TransactOpts) (*types.Transaction, error) {
Tx *types.Transaction return l2ToL1MP.Receive(opts)
Receipt *types.Receipt
}{
Tx: withdrawTx,
Receipt: withdrawReceipt,
}) })
require.NoError(t, err)
} }
cursor := "" withdrawReceipt, err := wait.ForReceiptOK(context.Background(), testSuite.L2Client, withdrawTx.Hash())
limit := 0 require.NoError(t, err, fmt.Sprintf("failed on withdrawal %d", i))
aliceWithdrawals, err := testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, cursor, limit) withdrawReceipts[i] = withdrawReceipt
require.NoError(t, err) }
require.Len(t, aliceWithdrawals.Withdrawals, 3)
require.Equal(t, withdrawals[0].Tx.Hash().String(), aliceWithdrawals.Withdrawals[0].L2TransactionHash.String()) // wait for processor catchup of the latest tx
require.Equal(t, withdrawals[1].Tx.Hash().String(), aliceWithdrawals.Withdrawals[1].L2TransactionHash.String()) require.NoError(t, wait.For(context.Background(), 500*time.Millisecond, func() (bool, error) {
require.Equal(t, withdrawals[2].Tx.Hash().String(), aliceWithdrawals.Withdrawals[2].L2TransactionHash.String()) l2Header := testSuite.Indexer.BridgeProcessor.LatestL2Header
return l2Header != nil && l2Header.Number.Uint64() >= withdrawReceipts[2].BlockNumber.Uint64(), nil
}))
cursor = withdrawals[1].Tx.Hash().String() // Get All
limit = 0 aliceWithdrawals, err := testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, "", 0)
aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, cursor, limit) require.NotNil(t, aliceWithdrawals)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, aliceWithdrawals, 2) require.Len(t, aliceWithdrawals.Withdrawals, 3)
require.Equal(t, withdrawals[1].Tx.Hash().String(), aliceWithdrawals.Withdrawals[0].L2TransactionHash.String()) require.False(t, aliceWithdrawals.HasNextPage)
require.Equal(t, withdrawals[2].Tx.Hash().String(), aliceWithdrawals.Withdrawals[1].L2TransactionHash.String())
cursor = "" // Respects Limits & Supplied Cursors
limit = 2 aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, "", 2)
aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, cursor, limit) require.NotNil(t, aliceWithdrawals)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, aliceWithdrawals, limit) require.Len(t, aliceWithdrawals.Withdrawals, 2)
require.Equal(t, withdrawals[0].Tx.Hash().String(), aliceWithdrawals.Withdrawals[0].L2TransactionHash.String()) require.True(t, aliceWithdrawals.HasNextPage)
require.Equal(t, withdrawals[1].Tx.Hash().String(), aliceWithdrawals.Withdrawals[1].L2TransactionHash.String())
cursor = withdrawals[1].Tx.Hash().String() aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, aliceWithdrawals.Cursor, 2)
limit = 1 require.NotNil(t, aliceWithdrawals)
aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, cursor, limit)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, aliceWithdrawals, 1) require.Len(t, aliceWithdrawals.Withdrawals, 1)
require.Equal(t, withdrawals[1].Tx.Hash().String(), aliceWithdrawals.Withdrawals[0].L2TransactionHash.String()) require.False(t, aliceWithdrawals.HasNextPage)
require.Equal(t, true, aliceWithdrawals.HasNextPage)
require.Equal(t, withdrawals[2].Tx.Hash().String(), aliceWithdrawals.Cursor)
cursor = "" // Returns the results in the right order
limit = 10 aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, "", 100)
aliceWithdrawals, err = testSuite.DB.BridgeTransfers.L2BridgeWithdrawalsByAddress(aliceAddr, cursor, limit) require.NotNil(t, aliceWithdrawals)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, proveReceipt.TxHash, aliceWithdrawals.Withdrawals[0].ProvenL1TransactionHash) for i := 0; i < 3; i++ {
require.Equal(t, finalizeReceipt.TxHash, aliceWithdrawals.Withdrawals[0].FinalizedL1TransactionHash) withdrawal := aliceWithdrawals.Withdrawals[i]
// Still nil as the withdrawal did not occur through the standard bridge // DESCENDING order
require.Nil(t, aliceWithdrawals.Withdrawals[0].L2BridgeWithdrawal.CrossDomainMessageHash) require.Equal(t, withdrawReceipts[2-i].TxHash, withdrawal.L2TransactionHash)
require.Equal(t, int64(3-i)*params.Ether, withdrawal.L2BridgeWithdrawal.Tx.Amount.Int64())
}
} }
*/
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