Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
4acb9efa
Commit
4acb9efa
authored
Aug 05, 2023
by
Hamdi Allam
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
split tests. Bridge -> BridgeTransfers
parent
04248fb0
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
549 additions
and
278 deletions
+549
-278
bridge_transfers.go
indexer/database/bridge_transfers.go
+251
-0
db.go
indexer/database/db.go
+11
-11
bridge_e2e_test.go
indexer/e2e_test/bridge_e2e_test.go
+0
-180
blocks_e2e_test.go
indexer/e2e_tests/blocks_e2e_test.go
+9
-13
bridge_transfers_e2e_test.go
indexer/e2e_tests/bridge_transfers_e2e_test.go
+164
-0
setup.go
indexer/e2e_tests/setup.go
+20
-15
deposits.go
indexer/e2e_tests/utils/deposits.go
+40
-0
20230523_create_schema.sql
indexer/migrations/20230523_create_schema.sql
+6
-6
l1_processor.go
indexer/processor/l1_processor.go
+26
-34
l2_processor.go
indexer/processor/l2_processor.go
+22
-19
No files found.
indexer/database/bridge.go
→
indexer/database/bridge
_transfers
.go
View file @
4acb9efa
This diff is collapsed.
Click to expand it.
indexer/database/db.go
View file @
4acb9efa
...
@@ -10,9 +10,9 @@ import (
...
@@ -10,9 +10,9 @@ import (
type
DB
struct
{
type
DB
struct
{
gorm
*
gorm
.
DB
gorm
*
gorm
.
DB
Blocks
BlocksDB
Blocks
BlocksDB
ContractEvents
ContractEventsDB
ContractEvents
ContractEventsDB
Bridge
Bridge
DB
Bridge
Transfers
BridgeTransfers
DB
}
}
func
NewDB
(
dsn
string
)
(
*
DB
,
error
)
{
func
NewDB
(
dsn
string
)
(
*
DB
,
error
)
{
...
@@ -31,10 +31,10 @@ func NewDB(dsn string) (*DB, error) {
...
@@ -31,10 +31,10 @@ func NewDB(dsn string) (*DB, error) {
}
}
db
:=
&
DB
{
db
:=
&
DB
{
gorm
:
gorm
,
gorm
:
gorm
,
Blocks
:
newBlocksDB
(
gorm
),
Blocks
:
newBlocksDB
(
gorm
),
ContractEvents
:
newContractEventsDB
(
gorm
),
ContractEvents
:
newContractEventsDB
(
gorm
),
Bridge
:
newBridge
DB
(
gorm
),
Bridge
Transfers
:
newBridgeTransfers
DB
(
gorm
),
}
}
return
db
,
nil
return
db
,
nil
...
@@ -59,9 +59,9 @@ func (db *DB) Close() error {
...
@@ -59,9 +59,9 @@ func (db *DB) Close() error {
func
dbFromGormTx
(
tx
*
gorm
.
DB
)
*
DB
{
func
dbFromGormTx
(
tx
*
gorm
.
DB
)
*
DB
{
return
&
DB
{
return
&
DB
{
gorm
:
tx
,
gorm
:
tx
,
Blocks
:
newBlocksDB
(
tx
),
Blocks
:
newBlocksDB
(
tx
),
ContractEvents
:
newContractEventsDB
(
tx
),
ContractEvents
:
newContractEventsDB
(
tx
),
Bridge
:
newBridge
DB
(
tx
),
Bridge
Transfers
:
newBridgeTransfers
DB
(
tx
),
}
}
}
}
indexer/e2e_test/bridge_e2e_test.go
deleted
100644 → 0
View file @
04248fb0
package
e2e_tests
import
(
"context"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/indexer/processor"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
func
TestE2EBridge
(
t
*
testing
.
T
)
{
testSuite
:=
createE2ETestSuite
(
t
)
l1Client
:=
testSuite
.
OpSys
.
Clients
[
"l1"
]
l2Client
:=
testSuite
.
OpSys
.
Clients
[
"sequencer"
]
l1StandardBridge
,
err
:=
bindings
.
NewL1StandardBridge
(
testSuite
.
OpCfg
.
L1Deployments
.
L1StandardBridgeProxy
,
l1Client
)
require
.
NoError
(
t
,
err
)
l2StandardBridge
,
err
:=
bindings
.
NewL2StandardBridge
(
predeploys
.
L2StandardBridgeAddr
,
l2Client
)
require
.
NoError
(
t
,
err
)
// pre-emptively conduct a deposit & withdrawal to speed up the test
setupCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
30
*
time
.
Second
)
defer
cancel
()
aliceAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Alice
l1Opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
testSuite
.
OpCfg
.
Secrets
.
Alice
,
testSuite
.
OpCfg
.
L1ChainIDBig
())
require
.
NoError
(
t
,
err
)
l2Opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
testSuite
.
OpCfg
.
Secrets
.
Alice
,
testSuite
.
OpCfg
.
L2ChainIDBig
())
require
.
NoError
(
t
,
err
)
l1Opts
.
Value
=
big
.
NewInt
(
params
.
Ether
)
l2Opts
.
Value
=
big
.
NewInt
(
params
.
Ether
)
depositTx
,
err
:=
l1StandardBridge
.
DepositETH
(
l1Opts
,
200
_000
,
[]
byte
{
byte
(
1
)})
require
.
NoError
(
t
,
err
)
withdrawTx
,
err
:=
l2StandardBridge
.
Withdraw
(
l2Opts
,
processor
.
EthAddress
,
big
.
NewInt
(
params
.
Ether
),
200
_000
,
[]
byte
{
byte
(
1
)})
require
.
NoError
(
t
,
err
)
depositReceipt
,
err
:=
utils
.
WaitReceiptOK
(
setupCtx
,
l1Client
,
depositTx
.
Hash
())
require
.
NoError
(
t
,
err
)
withdrawalReceipt
,
err
:=
utils
.
WaitReceiptOK
(
setupCtx
,
l2Client
,
withdrawTx
.
Hash
())
require
.
NoError
(
t
,
err
)
t
.
Run
(
"indexes ETH deposits"
,
func
(
t
*
testing
.
T
)
{
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
20
*
time
.
Second
)
defer
cancel
()
// Pause the L2Processor so that we can test for finalization separately. A pause is
// required since deposit inclusion is apart of the L2 block derivation process
testSuite
.
Indexer
.
L2Processor
.
PauseForTest
()
// (1) Test Deposit Initiation
// wait for processor catchup
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
depositReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceDeposits
,
err
:=
testSuite
.
DB
.
Bridge
.
DepositsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
aliceDeposits
,
1
)
require
.
Equal
(
t
,
depositTx
.
Hash
(),
aliceDeposits
[
0
]
.
L1TransactionHash
)
require
.
Empty
(
t
,
aliceDeposits
[
0
]
.
FinalizedL2TransactionHash
)
deposit
:=
aliceDeposits
[
0
]
.
Deposit
require
.
Nil
(
t
,
deposit
.
FinalizedL2EventGUID
)
require
.
Equal
(
t
,
processor
.
EthAddress
,
deposit
.
TokenPair
.
L1TokenAddress
)
require
.
Equal
(
t
,
processor
.
EthAddress
,
deposit
.
TokenPair
.
L2TokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
deposit
.
Tx
.
Data
[
0
])
// (2) Test Deposit Finalization
testSuite
.
Indexer
.
L2Processor
.
ResumeForTest
()
// finalization hash can be deterministically derived from TransactionDeposited log
var
depositTxHash
common
.
Hash
for
_
,
log
:=
range
depositReceipt
.
Logs
{
if
log
.
Topics
[
0
]
==
derive
.
DepositEventABIHash
{
deposit
,
err
:=
derive
.
UnmarshalDepositLogEvent
(
log
)
require
.
NoError
(
t
,
err
)
depositTxHash
=
types
.
NewTx
(
deposit
)
.
Hash
()
break
}
}
// wait for the l2 processor to catch this deposit in the derivation process
_
,
err
=
utils
.
WaitReceiptOK
(
testCtx
,
l2Client
,
depositTxHash
)
require
.
NoError
(
t
,
err
)
l2Height
,
err
:=
l2Client
.
BlockNumber
(
testCtx
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
l2Height
,
nil
}))
aliceDeposits
,
err
=
testSuite
.
DB
.
Bridge
.
DepositsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
depositTxHash
,
aliceDeposits
[
0
]
.
FinalizedL2TransactionHash
)
require
.
NotNil
(
t
,
aliceDeposits
[
0
]
.
Deposit
.
FinalizedL2EventGUID
)
})
t
.
Run
(
"indexes ETH withdrawals"
,
func
(
t
*
testing
.
T
)
{
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Minute
)
defer
cancel
()
// (1) Test Withdrawal Initiation
// wait for processor catchup
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
withdrawalReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceWithdrawals
,
err
:=
testSuite
.
DB
.
Bridge
.
WithdrawalsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
aliceWithdrawals
,
1
)
require
.
Equal
(
t
,
withdrawTx
.
Hash
(),
aliceWithdrawals
[
0
]
.
L2TransactionHash
)
require
.
Empty
(
t
,
aliceWithdrawals
[
0
]
.
ProvenL1TransactionHash
)
require
.
Empty
(
t
,
aliceWithdrawals
[
0
]
.
FinalizedL1TransactionHash
)
withdrawal
:=
aliceWithdrawals
[
0
]
.
Withdrawal
require
.
Nil
(
t
,
withdrawal
.
ProvenL1EventGUID
)
require
.
Nil
(
t
,
withdrawal
.
FinalizedL1EventGUID
)
require
.
Equal
(
t
,
processor
.
EthAddress
,
withdrawal
.
TokenPair
.
L1TokenAddress
)
require
.
Equal
(
t
,
processor
.
EthAddress
,
withdrawal
.
TokenPair
.
L2TokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
withdrawal
.
Tx
.
Data
[
0
])
// (2) Test Withdrawal Proven
// prove & wait for processor catchup
withdrawParams
,
proveReceipt
:=
op_e2e
.
ProveWithdrawal
(
t
,
*
testSuite
.
OpCfg
,
l1Client
,
testSuite
.
OpSys
.
Nodes
[
"sequencer"
],
testSuite
.
OpCfg
.
Secrets
.
Alice
,
withdrawalReceipt
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
proveReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceWithdrawals
,
err
=
testSuite
.
DB
.
Bridge
.
WithdrawalsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Empty
(
t
,
aliceWithdrawals
[
0
]
.
FinalizedL1TransactionHash
)
require
.
Equal
(
t
,
proveReceipt
.
TxHash
,
aliceWithdrawals
[
0
]
.
ProvenL1TransactionHash
)
// (3) Test Withdrawal Finalization
// finalize & wait for processor catchup
finalizeReceipt
:=
op_e2e
.
FinalizeWithdrawal
(
t
,
*
testSuite
.
OpCfg
,
l1Client
,
testSuite
.
OpCfg
.
Secrets
.
Alice
,
proveReceipt
,
withdrawParams
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
finalizeReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceWithdrawals
,
err
=
testSuite
.
DB
.
Bridge
.
WithdrawalsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
finalizeReceipt
.
TxHash
,
aliceWithdrawals
[
0
]
.
FinalizedL1TransactionHash
)
})
}
indexer/e2e_test/blocks_e2e_test.go
→
indexer/e2e_test
s
/blocks_e2e_test.go
View file @
4acb9efa
...
@@ -23,9 +23,7 @@ import (
...
@@ -23,9 +23,7 @@ import (
func
TestE2EBlockHeaders
(
t
*
testing
.
T
)
{
func
TestE2EBlockHeaders
(
t
*
testing
.
T
)
{
testSuite
:=
createE2ETestSuite
(
t
)
testSuite
:=
createE2ETestSuite
(
t
)
l1Client
:=
testSuite
.
OpSys
.
Clients
[
"l1"
]
l2OutputOracle
,
err
:=
bindings
.
NewL2OutputOracle
(
testSuite
.
OpCfg
.
L1Deployments
.
L2OutputOracleProxy
,
testSuite
.
L1Client
)
l2Client
:=
testSuite
.
OpSys
.
Clients
[
"sequencer"
]
l2OutputOracle
,
err
:=
bindings
.
NewL2OutputOracleCaller
(
testSuite
.
OpCfg
.
L1Deployments
.
L2OutputOracleProxy
,
l1Client
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
// a minute for total setup to finish
// a minute for total setup to finish
...
@@ -39,7 +37,7 @@ func TestE2EBlockHeaders(t *testing.T) {
...
@@ -39,7 +37,7 @@ func TestE2EBlockHeaders(t *testing.T) {
}))
}))
// ensure the processors are caught up to this state
// ensure the processors are caught up to this state
l1Height
,
err
:=
l
1Client
.
BlockNumber
(
setupCtx
)
l1Height
,
err
:=
testSuite
.
L
1Client
.
BlockNumber
(
setupCtx
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
setupCtx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
setupCtx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
...
@@ -60,7 +58,7 @@ func TestE2EBlockHeaders(t *testing.T) {
...
@@ -60,7 +58,7 @@ func TestE2EBlockHeaders(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
indexedHeader
)
require
.
NotNil
(
t
,
indexedHeader
)
header
,
err
:=
l
2Client
.
HeaderByNumber
(
context
.
Background
(),
height
)
header
,
err
:=
testSuite
.
L
2Client
.
HeaderByNumber
(
context
.
Background
(),
height
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
indexedHeader
)
require
.
NotNil
(
t
,
indexedHeader
)
...
@@ -93,7 +91,7 @@ func TestE2EBlockHeaders(t *testing.T) {
...
@@ -93,7 +91,7 @@ func TestE2EBlockHeaders(t *testing.T) {
require
.
NotEmpty
(
t
,
output
.
L1ContractEventGUID
)
require
.
NotEmpty
(
t
,
output
.
L1ContractEventGUID
)
// we may as well check the integrity of the output root
// we may as well check the integrity of the output root
l2Block
,
err
:=
l
2Client
.
BlockByNumber
(
context
.
Background
(),
blockNumber
)
l2Block
,
err
:=
testSuite
.
L
2Client
.
BlockByNumber
(
context
.
Background
(),
blockNumber
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
messagePasserStorageHash
,
err
:=
l2EthClient
.
StorageHash
(
predeploys
.
L2ToL1MessagePasserAddr
,
blockNumber
)
messagePasserStorageHash
,
err
:=
l2EthClient
.
StorageHash
(
predeploys
.
L2ToL1MessagePasserAddr
,
blockNumber
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
...
@@ -111,12 +109,10 @@ func TestE2EBlockHeaders(t *testing.T) {
...
@@ -111,12 +109,10 @@ func TestE2EBlockHeaders(t *testing.T) {
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
10
*
time
.
Second
)
defer
cancel
()
defer
cancel
()
devContracts
:=
make
([]
common
.
Address
,
0
)
l1Contracts
:=
[]
common
.
Address
{}
testSuite
.
OpCfg
.
L1Deployments
.
ForEach
(
func
(
name
string
,
address
common
.
Address
)
{
testSuite
.
OpCfg
.
L1Deployments
.
ForEach
(
func
(
name
string
,
addr
common
.
Address
)
{
l1Contracts
=
append
(
l1Contracts
,
addr
)
})
devContracts
=
append
(
devContracts
,
address
)
logFilter
:=
ethereum
.
FilterQuery
{
FromBlock
:
big
.
NewInt
(
0
),
ToBlock
:
big
.
NewInt
(
int64
(
l1Height
)),
Addresses
:
l1Contracts
}
})
logs
,
err
:=
testSuite
.
L1Client
.
FilterLogs
(
testCtx
,
logFilter
)
// []types.Log
logFilter
:=
ethereum
.
FilterQuery
{
FromBlock
:
big
.
NewInt
(
0
),
ToBlock
:
big
.
NewInt
(
int64
(
l1Height
)),
Addresses
:
devContracts
}
logs
,
err
:=
l1Client
.
FilterLogs
(
testCtx
,
logFilter
)
// []types.Log
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
for
_
,
log
:=
range
logs
{
for
_
,
log
:=
range
logs
{
...
@@ -128,7 +124,7 @@ func TestE2EBlockHeaders(t *testing.T) {
...
@@ -128,7 +124,7 @@ func TestE2EBlockHeaders(t *testing.T) {
require
.
Equal
(
t
,
log
.
Index
,
uint
(
contractEvent
.
LogIndex
))
require
.
Equal
(
t
,
log
.
Index
,
uint
(
contractEvent
.
LogIndex
))
// ensure the block is also indexed
// ensure the block is also indexed
block
,
err
:=
l
1Client
.
BlockByNumber
(
testCtx
,
big
.
NewInt
(
int64
(
log
.
BlockNumber
)))
block
,
err
:=
testSuite
.
L
1Client
.
BlockByNumber
(
testCtx
,
big
.
NewInt
(
int64
(
log
.
BlockNumber
)))
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
block
.
Time
(),
contractEvent
.
Timestamp
)
require
.
Equal
(
t
,
block
.
Time
(),
contractEvent
.
Timestamp
)
...
...
indexer/e2e_tests/bridge_transfers_e2e_test.go
0 → 100644
View file @
4acb9efa
package
e2e_tests
import
(
"context"
"math/big"
"testing"
"time"
e2etest_utils
"github.com/ethereum-optimism/optimism/indexer/e2e_tests/utils"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-node/withdrawals"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-bindings/predeploys"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"github.com/stretchr/testify/require"
)
func
TestE2EBridgeTransfersStandardBridgeETHDeposit
(
t
*
testing
.
T
)
{
testSuite
:=
createE2ETestSuite
(
t
)
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
time
.
Minute
)
defer
cancel
()
l1StandardBridge
,
err
:=
bindings
.
NewL1StandardBridge
(
testSuite
.
OpCfg
.
L1Deployments
.
L1StandardBridgeProxy
,
testSuite
.
L1Client
)
require
.
NoError
(
t
,
err
)
// 1 ETH transfer
aliceAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Alice
l1Opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
testSuite
.
OpCfg
.
Secrets
.
Alice
,
testSuite
.
OpCfg
.
L1ChainIDBig
())
require
.
NoError
(
t
,
err
)
l1Opts
.
Value
=
big
.
NewInt
(
params
.
Ether
)
// Pause the L2Processor so that we can test for finalization separately. A pause is
// required since deposit inclusion is apart of the L2 block derivation process
testSuite
.
Indexer
.
L2Processor
.
PauseForTest
()
// (1) Test Deposit Initiation
depositTx
,
err
:=
l1StandardBridge
.
DepositETH
(
l1Opts
,
200
_000
,
[]
byte
{
byte
(
1
)})
require
.
NoError
(
t
,
err
)
depositReceipt
,
err
:=
utils
.
WaitReceiptOK
(
testCtx
,
testSuite
.
L1Client
,
depositTx
.
Hash
())
require
.
NoError
(
t
,
err
)
depositInfo
,
err
:=
e2etest_utils
.
ParseDepositInfo
(
depositReceipt
)
require
.
NoError
(
t
,
err
)
// wait for processor catchup
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
depositReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceDeposits
,
err
:=
testSuite
.
DB
.
BridgeTransfers
.
L1BridgeDepositsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
aliceDeposits
,
1
)
require
.
Equal
(
t
,
depositTx
.
Hash
(),
aliceDeposits
[
0
]
.
L1TransactionHash
)
require
.
Empty
(
t
,
aliceDeposits
[
0
]
.
FinalizedL2TransactionHash
)
deposit
:=
aliceDeposits
[
0
]
.
L1BridgeDeposit
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
L1TokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
L2TokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
deposit
.
Tx
.
Data
[
0
])
// (2) Test Deposit Finalization
require
.
Nil
(
t
,
deposit
.
FinalizedL2EventGUID
)
testSuite
.
Indexer
.
L2Processor
.
ResumeForTest
()
// wait for the l2 processor to catch this deposit in the derivation process
depositReceipt
,
err
=
utils
.
WaitReceiptOK
(
testCtx
,
testSuite
.
L2Client
,
types
.
NewTx
(
depositInfo
.
DepositTx
)
.
Hash
())
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
depositReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceDeposits
,
err
=
testSuite
.
DB
.
BridgeTransfers
.
L1BridgeDepositsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
aliceDeposits
[
0
]
.
L1BridgeDeposit
.
FinalizedL2EventGUID
)
require
.
Equal
(
t
,
types
.
NewTx
(
depositInfo
.
DepositTx
)
.
Hash
(),
aliceDeposits
[
0
]
.
FinalizedL2TransactionHash
)
}
func
TestE2EBridgeTransfersStandardBridgeETHWithdrawal
(
t
*
testing
.
T
)
{
testSuite
:=
createE2ETestSuite
(
t
)
testCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
2
*
time
.
Minute
)
defer
cancel
()
optimismPortal
,
err
:=
bindings
.
NewOptimismPortal
(
testSuite
.
OpCfg
.
L1Deployments
.
OptimismPortalProxy
,
testSuite
.
L1Client
)
require
.
NoError
(
t
,
err
)
l2StandardBridge
,
err
:=
bindings
.
NewL2StandardBridge
(
predeploys
.
L2StandardBridgeAddr
,
testSuite
.
L2Client
)
require
.
NoError
(
t
,
err
)
// 1 ETH transfer
aliceAddr
:=
testSuite
.
OpCfg
.
Secrets
.
Addresses
()
.
Alice
l2Opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
testSuite
.
OpCfg
.
Secrets
.
Alice
,
testSuite
.
OpCfg
.
L2ChainIDBig
())
require
.
NoError
(
t
,
err
)
l2Opts
.
Value
=
big
.
NewInt
(
params
.
Ether
)
// Ensure L1 has enough funds for the withdrawal by depositing an equal amount into the OptimismPortal
l1Opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
testSuite
.
OpCfg
.
Secrets
.
Alice
,
testSuite
.
OpCfg
.
L1ChainIDBig
())
require
.
NoError
(
t
,
err
)
l1Opts
.
Value
=
l2Opts
.
Value
depositTx
,
err
:=
optimismPortal
.
Receive
(
l1Opts
)
require
.
NoError
(
t
,
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
testCtx
,
testSuite
.
L1Client
,
depositTx
.
Hash
())
require
.
NoError
(
t
,
err
)
// (1) Test Withdrawal Initiation
withdrawTx
,
err
:=
l2StandardBridge
.
Withdraw
(
l2Opts
,
predeploys
.
LegacyERC20ETHAddr
,
l2Opts
.
Value
,
200
_000
,
[]
byte
{
byte
(
1
)})
require
.
NoError
(
t
,
err
)
withdrawReceipt
,
err
:=
utils
.
WaitReceiptOK
(
testCtx
,
testSuite
.
L2Client
,
withdrawTx
.
Hash
())
require
.
NoError
(
t
,
err
)
// wait for processor catchup
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
withdrawReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceWithdrawals
,
err
:=
testSuite
.
DB
.
BridgeTransfers
.
L2BridgeWithdrawalsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
aliceWithdrawals
,
1
)
require
.
Equal
(
t
,
withdrawTx
.
Hash
(),
aliceWithdrawals
[
0
]
.
L2TransactionHash
)
msgPassed
,
err
:=
withdrawals
.
ParseMessagePassed
(
withdrawReceipt
)
require
.
NoError
(
t
,
err
)
withdrawalHash
,
err
:=
withdrawals
.
WithdrawalHash
(
msgPassed
)
require
.
NoError
(
t
,
err
)
withdrawal
:=
aliceWithdrawals
[
0
]
.
L2BridgeWithdrawal
require
.
Equal
(
t
,
withdrawalHash
,
withdrawal
.
WithdrawalHash
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
L1TokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
L2TokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
withdrawal
.
Tx
.
Data
[
0
])
// (2) Test Withdrawal Proven/Finalized. Test the sql join queries to populate the right transaction
require
.
Nil
(
t
,
withdrawal
.
ProvenL1EventGUID
)
require
.
Nil
(
t
,
withdrawal
.
FinalizedL1EventGUID
)
require
.
Empty
(
t
,
aliceWithdrawals
[
0
]
.
ProvenL1TransactionHash
)
require
.
Empty
(
t
,
aliceWithdrawals
[
0
]
.
FinalizedL1TransactionHash
)
// wait for processor catchup
proveReceipt
,
finalizeReceipt
:=
op_e2e
.
ProveAndFinalizeWithdrawal
(
t
,
*
testSuite
.
OpCfg
,
testSuite
.
L1Client
,
testSuite
.
OpSys
.
Nodes
[
"sequencer"
],
testSuite
.
OpCfg
.
Secrets
.
Alice
,
withdrawReceipt
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
finalizeReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
aliceWithdrawals
,
err
=
testSuite
.
DB
.
BridgeTransfers
.
L2BridgeWithdrawalsByAddress
(
aliceAddr
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
aliceWithdrawals
[
0
]
.
L2BridgeWithdrawal
.
ProvenL1EventGUID
)
require
.
NotNil
(
t
,
aliceWithdrawals
[
0
]
.
L2BridgeWithdrawal
.
FinalizedL1EventGUID
)
require
.
Equal
(
t
,
proveReceipt
.
TxHash
,
aliceWithdrawals
[
0
]
.
ProvenL1TransactionHash
)
require
.
Equal
(
t
,
finalizeReceipt
.
TxHash
,
aliceWithdrawals
[
0
]
.
FinalizedL1TransactionHash
)
}
indexer/e2e_test/setup.go
→
indexer/e2e_test
s
/setup.go
View file @
4acb9efa
...
@@ -17,6 +17,7 @@ import (
...
@@ -17,6 +17,7 @@ import (
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
op_e2e
"github.com/ethereum-optimism/optimism/op-e2e"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum-optimism/optimism/op-node/testlog"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
_
"github.com/jackc/pgx/v5/stdlib"
_
"github.com/jackc/pgx/v5/stdlib"
...
@@ -33,6 +34,10 @@ type E2ETestSuite struct {
...
@@ -33,6 +34,10 @@ type E2ETestSuite struct {
// Rollup
// Rollup
OpCfg
*
op_e2e
.
SystemConfig
OpCfg
*
op_e2e
.
SystemConfig
OpSys
*
op_e2e
.
System
OpSys
*
op_e2e
.
System
// Clients
L1Client
*
ethclient
.
Client
L2Client
*
ethclient
.
Client
}
}
func
createE2ETestSuite
(
t
*
testing
.
T
)
E2ETestSuite
{
func
createE2ETestSuite
(
t
*
testing
.
T
)
E2ETestSuite
{
...
@@ -48,16 +53,9 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
...
@@ -48,16 +53,9 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
opSys
,
err
:=
opCfg
.
Start
()
opSys
,
err
:=
opCfg
.
Start
()
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
l1Contracts
:=
processor
.
L1Contracts
{
OptimismPortal
:
opCfg
.
L1Deployments
.
OptimismPortalProxy
,
L2OutputOracle
:
opCfg
.
L1Deployments
.
L2OutputOracleProxy
,
L1CrossDomainMessenger
:
opCfg
.
L1Deployments
.
L1CrossDomainMessengerProxy
,
L1StandardBridge
:
opCfg
.
L1Deployments
.
L1StandardBridgeProxy
,
L1ERC721Bridge
:
opCfg
.
L1Deployments
.
L1ERC721BridgeProxy
,
}
// Indexer Configuration and Start
// Indexer Configuration and Start
indexerCfg
:=
config
.
Config
{
indexerCfg
:=
config
.
Config
{
Logger
:
logger
,
DB
:
config
.
DBConfig
{
DB
:
config
.
DBConfig
{
Host
:
"127.0.0.1"
,
Host
:
"127.0.0.1"
,
Port
:
5432
,
Port
:
5432
,
...
@@ -68,9 +66,14 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
...
@@ -68,9 +66,14 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
L1RPC
:
opSys
.
Nodes
[
"l1"
]
.
HTTPEndpoint
(),
L1RPC
:
opSys
.
Nodes
[
"l1"
]
.
HTTPEndpoint
(),
L2RPC
:
opSys
.
Nodes
[
"sequencer"
]
.
HTTPEndpoint
(),
L2RPC
:
opSys
.
Nodes
[
"sequencer"
]
.
HTTPEndpoint
(),
},
},
Logger
:
logger
,
Chain
:
config
.
ChainConfig
{
Chain
:
config
.
ChainConfig
{
L1Contracts
:
l1Contracts
,
L1Contracts
:
processor
.
L1Contracts
{
OptimismPortal
:
opCfg
.
L1Deployments
.
OptimismPortalProxy
,
L2OutputOracle
:
opCfg
.
L1Deployments
.
L2OutputOracleProxy
,
L1CrossDomainMessenger
:
opCfg
.
L1Deployments
.
L1CrossDomainMessengerProxy
,
L1StandardBridge
:
opCfg
.
L1Deployments
.
L1StandardBridgeProxy
,
L1ERC721Bridge
:
opCfg
.
L1Deployments
.
L1ERC721BridgeProxy
,
},
},
},
}
}
...
@@ -99,11 +102,13 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
...
@@ -99,11 +102,13 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
})
})
return
E2ETestSuite
{
return
E2ETestSuite
{
t
:
t
,
t
:
t
,
DB
:
db
,
DB
:
db
,
Indexer
:
indexer
,
Indexer
:
indexer
,
OpCfg
:
&
opCfg
,
OpCfg
:
&
opCfg
,
OpSys
:
opSys
,
OpSys
:
opSys
,
L1Client
:
opSys
.
Clients
[
"l1"
],
L2Client
:
opSys
.
Clients
[
"sequencer"
],
}
}
}
}
...
...
indexer/e2e_tests/utils/deposits.go
0 → 100644
View file @
4acb9efa
package
utils
import
(
"errors"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
)
type
DepositInfo
struct
{
*
bindings
.
OptimismPortalTransactionDeposited
DepositTx
*
types
.
DepositTx
}
func
ParseDepositInfo
(
depositReceipt
*
types
.
Receipt
)
(
*
DepositInfo
,
error
)
{
optimismPortal
,
err
:=
bindings
.
NewOptimismPortal
(
common
.
Address
{},
nil
)
if
err
!=
nil
{
return
nil
,
err
}
for
_
,
log
:=
range
depositReceipt
.
Logs
{
if
log
.
Topics
[
0
]
==
derive
.
DepositEventABIHash
{
portalTxDeposited
,
err
:=
optimismPortal
.
ParseTransactionDeposited
(
*
log
)
if
err
!=
nil
{
return
nil
,
err
}
depositTx
,
err
:=
derive
.
UnmarshalDepositLogEvent
(
log
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
DepositInfo
{
portalTxDeposited
,
depositTx
},
nil
}
}
return
nil
,
errors
.
New
(
"cannot find deposit event in receipt"
)
}
indexer/migrations/20230523_create_schema.sql
View file @
4acb9efa
...
@@ -67,12 +67,12 @@ CREATE TABLE IF NOT EXISTS output_proposals (
...
@@ -67,12 +67,12 @@ CREATE TABLE IF NOT EXISTS output_proposals (
* BRIDGING DATA
* BRIDGING DATA
*/
*/
CREATE
TABLE
IF
NOT
EXISTS
deposits
(
CREATE
TABLE
IF
NOT
EXISTS
l1_bridge_
deposits
(
guid
VARCHAR
PRIMARY
KEY
NOT
NULL
,
guid
VARCHAR
PRIMARY
KEY
NOT
NULL
,
-- Event causing the deposit
-- Event causing the deposit
initiated_l1_event_guid
VARCHAR
NOT
NULL
REFERENCES
l1_contract_events
(
guid
),
initiated_l1_event_guid
VARCHAR
NOT
NULL
REFERENCES
l1_contract_events
(
guid
),
sent_message_nonce
UINT256
UNIQUE
,
cross_domain_messenger_nonce
UINT256
UNIQUE
,
-- Finalization marker for the deposit
-- Finalization marker for the deposit
finalized_l2_event_guid
VARCHAR
REFERENCES
l2_contract_events
(
guid
),
finalized_l2_event_guid
VARCHAR
REFERENCES
l2_contract_events
(
guid
),
...
@@ -88,12 +88,12 @@ CREATE TABLE IF NOT EXISTS deposits (
...
@@ -88,12 +88,12 @@ CREATE TABLE IF NOT EXISTS deposits (
timestamp
INTEGER
NOT
NULL
CHECK
(
timestamp
>
0
)
timestamp
INTEGER
NOT
NULL
CHECK
(
timestamp
>
0
)
);
);
CREATE
TABLE
IF
NOT
EXISTS
withdrawals
(
CREATE
TABLE
IF
NOT
EXISTS
l2_bridge_
withdrawals
(
guid
VARCHAR
PRIMARY
KEY
NOT
NULL
,
guid
VARCHAR
PRIMARY
KEY
NOT
NULL
,
-- Event causing this withdrawal
-- Event causing this withdrawal
initiated_l2_event_guid
VARCHAR
NOT
NULL
REFERENCES
l2_contract_events
(
guid
),
initiated_l2_event_guid
VARCHAR
NOT
NULL
REFERENCES
l2_contract_events
(
guid
),
sent_message_nonce
UINT256
UNIQUE
,
cross_domain_messenger_nonce
UINT256
UNIQUE
,
-- Multistep (bedrock) process of a withdrawal
-- Multistep (bedrock) process of a withdrawal
withdrawal_hash
VARCHAR
NOT
NULL
,
withdrawal_hash
VARCHAR
NOT
NULL
,
...
...
indexer/processor/l1_processor.go
View file @
4acb9efa
...
@@ -255,13 +255,13 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -255,13 +255,13 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
err
return
err
}
}
deposits
:=
make
([]
*
database
.
Deposit
,
len
(
initiatedDepositEvents
))
deposits
:=
make
([]
*
database
.
L1Bridge
Deposit
,
len
(
initiatedDepositEvents
))
for
i
,
initiatedBridgeEvent
:=
range
initiatedDepositEvents
{
for
i
,
initiatedBridgeEvent
:=
range
initiatedDepositEvents
{
deposits
[
i
]
=
&
database
.
Deposit
{
deposits
[
i
]
=
&
database
.
L1Bridge
Deposit
{
GUID
:
uuid
.
New
(),
GUID
:
uuid
.
New
(),
InitiatedL1EventGUID
:
initiatedBridgeEvent
.
RawEvent
.
GUID
,
InitiatedL1EventGUID
:
initiatedBridgeEvent
.
RawEvent
.
GUID
,
SentMessageNonce
:
database
.
U256
{
Int
:
initiatedBridgeEvent
.
CrossDomainMessengerNonce
},
CrossDomainMessengerNonce
:
database
.
U256
{
Int
:
initiatedBridgeEvent
.
CrossDomainMessengerNonce
},
TokenPair
:
database
.
TokenPair
{
L1TokenAddress
:
initiatedBridgeEvent
.
LocalToken
,
L2TokenAddress
:
initiatedBridgeEvent
.
RemoteToken
},
TokenPair
:
database
.
TokenPair
{
L1TokenAddress
:
initiatedBridgeEvent
.
LocalToken
,
L2TokenAddress
:
initiatedBridgeEvent
.
RemoteToken
},
Tx
:
database
.
Transaction
{
Tx
:
database
.
Transaction
{
FromAddress
:
initiatedBridgeEvent
.
From
,
FromAddress
:
initiatedBridgeEvent
.
From
,
ToAddress
:
initiatedBridgeEvent
.
To
,
ToAddress
:
initiatedBridgeEvent
.
To
,
...
@@ -274,7 +274,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -274,7 +274,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
if
len
(
deposits
)
>
0
{
if
len
(
deposits
)
>
0
{
processLog
.
Info
(
"detected L1StandardBridge deposits"
,
"num"
,
len
(
deposits
))
processLog
.
Info
(
"detected L1StandardBridge deposits"
,
"num"
,
len
(
deposits
))
err
:=
db
.
Bridge
.
Stor
eDeposits
(
deposits
)
err
:=
db
.
Bridge
Transfers
.
StoreL1Bridg
eDeposits
(
deposits
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -286,47 +286,39 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -286,47 +286,39 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
err
return
err
}
}
// we manually keep track since not every proven withdrawal is a standard bridge withdrawal
latestL2Header
,
err
:=
db
.
Blocks
.
LatestL2BlockHeader
()
if
err
!=
nil
{
return
err
}
else
if
len
(
provenWithdrawalEvents
)
>
0
&&
latestL2Header
==
nil
{
return
errors
.
New
(
"no indexed L2 state to process any proven L1 transactions"
)
}
numProvenWithdrawals
:=
0
numProvenWithdrawals
:=
0
for
_
,
provenWithdrawalEvent
:=
range
provenWithdrawalEvents
{
for
_
,
provenWithdrawalEvent
:=
range
provenWithdrawalEvents
{
withdrawalHash
:=
provenWithdrawalEvent
.
WithdrawalHash
withdrawalHash
:=
provenWithdrawalEvent
.
WithdrawalHash
withdrawal
,
err
:=
db
.
Bridge
.
WithdrawalBy
Hash
(
withdrawalHash
)
withdrawal
,
err
:=
db
.
Bridge
Transfers
.
L2BridgeWithdrawalByWithdrawal
Hash
(
withdrawalHash
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
else
if
withdrawal
==
nil
{
// NOTE: This needs to be updated to identify if this CrossDomainMessenger message is a StandardBridge message. This
// Check if the L2Processor is behind or really has missed an event. We can compare against the
// will be easier to do once we index cross domain messages and track its lifecyle separately
// OptimismPortal#ProvenWithdrawal on-chain mapping relative to the latest indexed L2 height
if
withdrawal
==
nil
{
// This needs to be updated to read from config as well as correctly identify if the CrossDomainMessenger message is a standard
// bridge message. This will easier to do once we index passed messages separately which will include the right To/From fields
if
provenWithdrawalEvent
.
From
!=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000007"
)
||
provenWithdrawalEvent
.
To
!=
l1Contracts
.
L1CrossDomainMessenger
{
if
provenWithdrawalEvent
.
From
!=
common
.
HexToAddress
(
"0x4200000000000000000000000000000000000007"
)
||
provenWithdrawalEvent
.
To
!=
l1Contracts
.
L1CrossDomainMessenger
{
// non-bridge withdrawal
// non-bridge withdrawal
continue
continue
}
}
// Query for the the proven withdrawal on-chain
// Check if the L2Processor is behind or really has missed an event. Since L2 timestamps
provenWithdrawal
,
err
:=
OptimismPortalQueryProvenWithdrawal
(
rawEthClient
,
l1Contracts
.
OptimismPortal
,
withdrawalHash
)
// are derived from L1, we can simply compare timestamps
if
err
!=
nil
{
if
provenWithdrawalEvent
.
RawEvent
.
Timestamp
>
latestL2Header
.
Timestamp
{
return
err
processLog
.
Warn
(
"behind on indexed L2StandardBridge withdrawals"
)
}
latestL2Header
,
err
:=
db
.
Blocks
.
LatestL2BlockHeader
()
if
err
!=
nil
{
return
err
}
if
latestL2Header
==
nil
||
provenWithdrawal
.
L2OutputIndex
.
Cmp
(
latestL2Header
.
Number
.
Int
)
>
0
{
processLog
.
Warn
(
"behind on indexed L2 withdrawals"
)
return
errors
.
New
(
"waiting for L2Processor to catch up"
)
return
errors
.
New
(
"waiting for L2Processor to catch up"
)
}
else
{
}
else
{
processLog
.
Crit
(
"missing indexed withdrawal for this proven event"
)
processLog
.
Crit
(
"missing indexed
L2StandardBridge
withdrawal for this proven event"
)
return
errors
.
New
(
"missing withdrawal message"
)
return
errors
.
New
(
"missing withdrawal message"
)
}
}
}
}
err
=
db
.
Bridge
.
MarkProven
WithdrawalEvent
(
withdrawal
.
GUID
,
provenWithdrawalEvent
.
RawEvent
.
GUID
)
err
=
db
.
Bridge
Transfers
.
MarkProvenL2Bridge
WithdrawalEvent
(
withdrawal
.
GUID
,
provenWithdrawalEvent
.
RawEvent
.
GUID
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -346,7 +338,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -346,7 +338,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
for
_
,
finalizedBridgeEvent
:=
range
finalizedWithdrawalEvents
{
for
_
,
finalizedBridgeEvent
:=
range
finalizedWithdrawalEvents
{
nonce
:=
finalizedBridgeEvent
.
CrossDomainMessengerNonce
nonce
:=
finalizedBridgeEvent
.
CrossDomainMessengerNonce
withdrawal
,
err
:=
db
.
Bridge
.
WithdrawalByMessage
Nonce
(
nonce
)
withdrawal
,
err
:=
db
.
Bridge
Transfers
.
L2BridgeWithdrawalByCrossDomainMessenger
Nonce
(
nonce
)
if
err
!=
nil
{
if
err
!=
nil
{
processLog
.
Error
(
"error querying associated withdrawal messsage using nonce"
,
"cross_domain_messenger_nonce"
,
nonce
)
processLog
.
Error
(
"error querying associated withdrawal messsage using nonce"
,
"cross_domain_messenger_nonce"
,
nonce
)
return
err
return
err
...
@@ -359,7 +351,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -359,7 +351,7 @@ func l1BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
errors
.
New
(
"missing withdrawal message"
)
return
errors
.
New
(
"missing withdrawal message"
)
}
}
err
=
db
.
Bridge
.
MarkFinalized
WithdrawalEvent
(
withdrawal
.
GUID
,
finalizedBridgeEvent
.
RawEvent
.
GUID
)
err
=
db
.
Bridge
Transfers
.
MarkFinalizedL2Bridge
WithdrawalEvent
(
withdrawal
.
GUID
,
finalizedBridgeEvent
.
RawEvent
.
GUID
)
if
err
!=
nil
{
if
err
!=
nil
{
processLog
.
Error
(
"error finalizing withdrawal"
,
"err"
,
err
)
processLog
.
Error
(
"error finalizing withdrawal"
,
"err"
,
err
)
return
err
return
err
...
...
indexer/processor/l2_processor.go
View file @
4acb9efa
...
@@ -183,7 +183,7 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -183,7 +183,7 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
err
return
err
}
}
withdrawals
:=
make
([]
*
database
.
Withdrawal
,
len
(
initiatedWithdrawalEvents
))
withdrawals
:=
make
([]
*
database
.
L2Bridge
Withdrawal
,
len
(
initiatedWithdrawalEvents
))
for
i
,
initiatedBridgeEvent
:=
range
initiatedWithdrawalEvents
{
for
i
,
initiatedBridgeEvent
:=
range
initiatedWithdrawalEvents
{
log
:=
events
.
eventLog
[
initiatedBridgeEvent
.
RawEvent
.
GUID
]
log
:=
events
.
eventLog
[
initiatedBridgeEvent
.
RawEvent
.
GUID
]
...
@@ -195,12 +195,12 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -195,12 +195,12 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
err
return
err
}
}
withdrawals
[
i
]
=
&
database
.
Withdrawal
{
withdrawals
[
i
]
=
&
database
.
L2Bridge
Withdrawal
{
GUID
:
uuid
.
New
(),
GUID
:
uuid
.
New
(),
InitiatedL2EventGUID
:
initiatedBridgeEvent
.
RawEvent
.
GUID
,
InitiatedL2EventGUID
:
initiatedBridgeEvent
.
RawEvent
.
GUID
,
SentMessageNonce
:
database
.
U256
{
Int
:
initiatedBridgeEvent
.
CrossDomainMessengerNonce
},
CrossDomainMessengerNonce
:
database
.
U256
{
Int
:
initiatedBridgeEvent
.
CrossDomainMessengerNonce
},
WithdrawalHash
:
msgPassedData
.
WithdrawalHash
,
WithdrawalHash
:
msgPassedData
.
WithdrawalHash
,
TokenPair
:
database
.
TokenPair
{
L1TokenAddress
:
initiatedBridgeEvent
.
LocalToken
,
L2TokenAddress
:
initiatedBridgeEvent
.
RemoteToken
},
TokenPair
:
database
.
TokenPair
{
L1TokenAddress
:
initiatedBridgeEvent
.
LocalToken
,
L2TokenAddress
:
initiatedBridgeEvent
.
RemoteToken
},
Tx
:
database
.
Transaction
{
Tx
:
database
.
Transaction
{
FromAddress
:
initiatedBridgeEvent
.
From
,
FromAddress
:
initiatedBridgeEvent
.
From
,
ToAddress
:
initiatedBridgeEvent
.
To
,
ToAddress
:
initiatedBridgeEvent
.
To
,
...
@@ -213,7 +213,7 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -213,7 +213,7 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
if
len
(
withdrawals
)
>
0
{
if
len
(
withdrawals
)
>
0
{
processLog
.
Info
(
"detected L2StandardBridge withdrawals"
,
"num"
,
len
(
withdrawals
))
processLog
.
Info
(
"detected L2StandardBridge withdrawals"
,
"num"
,
len
(
withdrawals
))
err
:=
db
.
Bridge
.
Stor
eWithdrawals
(
withdrawals
)
err
:=
db
.
Bridge
Transfers
.
StoreL2Bridg
eWithdrawals
(
withdrawals
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
...
@@ -225,30 +225,33 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
...
@@ -225,30 +225,33 @@ func l2BridgeProcessContractEvents(processLog log.Logger, db *database.DB, ethCl
return
err
return
err
}
}
latestL1Header
,
err
:=
db
.
Blocks
.
LatestL1BlockHeader
()
if
err
!=
nil
{
return
err
}
else
if
len
(
finalizationBridgeEvents
)
>
0
&&
latestL1Header
==
nil
{
return
errors
.
New
(
"no indexed L1 state to process any L2 bridge finalizations"
)
}
for
_
,
finalizedBridgeEvent
:=
range
finalizationBridgeEvents
{
for
_
,
finalizedBridgeEvent
:=
range
finalizationBridgeEvents
{
nonce
:=
finalizedBridgeEvent
.
CrossDomainMessengerNonce
nonce
:=
finalizedBridgeEvent
.
CrossDomainMessengerNonce
deposit
,
err
:=
db
.
Bridge
.
DepositByMessage
Nonce
(
nonce
)
deposit
,
err
:=
db
.
Bridge
Transfers
.
L1BridgeDepositByCrossDomainMessenger
Nonce
(
nonce
)
if
err
!=
nil
{
if
err
!=
nil
{
processLog
.
Error
(
"error querying associated deposit messsage using nonce"
,
"cross_domain_messenger_nonce"
,
nonce
)
processLog
.
Error
(
"error querying associated deposit messsage using nonce"
,
"cross_domain_messenger_nonce"
,
nonce
)
return
err
return
err
}
else
if
deposit
==
nil
{
}
else
if
deposit
==
nil
{
latestNonce
,
err
:=
db
.
Bridge
.
LatestDepositMessageNonce
()
// Check if the L1Processor is behind or really has missed an event. Since L2 timestamps
if
err
!=
nil
{
// are derived from L1, we can simply compare timestamps
return
err
if
finalizedBridgeEvent
.
RawEvent
.
Timestamp
>
latestL1Header
.
Timestamp
{
}
processLog
.
Warn
(
"behind on indexed L1StandardBridge deposits"
)
// Check if the L1Processor is behind or really has missed an event
if
latestNonce
==
nil
||
nonce
.
Cmp
(
latestNonce
)
>
0
{
processLog
.
Warn
(
"behind on indexed L1 deposits"
)
return
errors
.
New
(
"waiting for L1Processor to catch up"
)
return
errors
.
New
(
"waiting for L1Processor to catch up"
)
}
else
{
}
else
{
processLog
.
Crit
(
"missing indexed deposit for this finalization event"
)
processLog
.
Crit
(
"missing indexed
L1StandardBridge
deposit for this finalization event"
)
return
errors
.
New
(
"missing deposit message"
)
return
errors
.
New
(
"missing deposit message"
)
}
}
}
}
err
=
db
.
Bridge
.
MarkFinalized
DepositEvent
(
deposit
.
GUID
,
finalizedBridgeEvent
.
RawEvent
.
GUID
)
err
=
db
.
Bridge
Transfers
.
MarkFinalizedL1Bridge
DepositEvent
(
deposit
.
GUID
,
finalizedBridgeEvent
.
RawEvent
.
GUID
)
if
err
!=
nil
{
if
err
!=
nil
{
processLog
.
Error
(
"error finalizing deposit"
,
"err"
,
err
)
processLog
.
Error
(
"error finalizing deposit"
,
"err"
,
err
)
return
err
return
err
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment