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
e85caec3
Commit
e85caec3
authored
Jul 05, 2023
by
Hamdi Allam
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bridge events
parent
256ab17b
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
279 additions
and
61 deletions
+279
-61
l1_processor.go
indexer/processor/l1_processor.go
+152
-51
l2_processor.go
indexer/processor/l2_processor.go
+127
-10
No files found.
indexer/processor/l1_processor.go
View file @
e85caec3
This diff is collapsed.
Click to expand it.
indexer/processor/l2_processor.go
View file @
e85caec3
package
processor
import
(
"bytes"
"context"
"errors"
"math/big"
"reflect"
"github.com/ethereum-optimism/optimism/indexer/database"
"github.com/ethereum-optimism/optimism/indexer/node"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/google/uuid"
"github.com/ethereum/go-ethereum"
...
...
@@ -125,7 +128,10 @@ func l2ProcessFn(processLog log.Logger, ethClient node.EthClient, l2Contracts L2
}
numLogs
:=
len
(
logs
)
logsByIndex
:=
make
(
map
[
uint
]
*
types
.
Log
,
numLogs
)
l2ContractEvents
:=
make
([]
*
database
.
L2ContractEvent
,
numLogs
)
l2ContractEventLogs
:=
make
(
map
[
uuid
.
UUID
]
*
types
.
Log
)
for
i
,
log
:=
range
logs
{
header
,
ok
:=
l2HeaderMap
[
log
.
BlockHash
]
if
!
ok
{
...
...
@@ -133,16 +139,11 @@ func l2ProcessFn(processLog log.Logger, ethClient node.EthClient, l2Contracts L2
return
errors
.
New
(
"parsed log with a block hash not in this batch"
)
}
l2ContractEvents
[
i
]
=
&
database
.
L2ContractEvent
{
ContractEvent
:
database
.
ContractEvent
{
GUID
:
uuid
.
New
(),
BlockHash
:
log
.
BlockHash
,
TransactionHash
:
log
.
TxHash
,
EventSignature
:
log
.
Topics
[
0
],
LogIndex
:
uint64
(
log
.
Index
),
Timestamp
:
header
.
Time
,
},
}
logsByIndex
[
log
.
Index
]
=
&
logs
[
i
]
contractEvent
:=
&
database
.
L2ContractEvent
{
ContractEvent
:
database
.
ContractEventFromLog
(
&
log
,
header
.
Time
)}
l2ContractEvents
[
i
]
=
contractEvent
l2ContractEventLogs
[
contractEvent
.
GUID
]
=
&
logs
[
i
]
}
/** Update Database **/
...
...
@@ -159,9 +160,125 @@ func l2ProcessFn(processLog log.Logger, ethClient node.EthClient, l2Contracts L2
if
err
!=
nil
{
return
err
}
// forward along contract events to the bridge processor
err
=
l2BridgeProcessContractEvents
(
processLog
,
db
,
ethClient
,
l2ContractEvents
,
l2ContractEventLogs
,
logsByIndex
)
if
err
!=
nil
{
return
err
}
}
// a-ok!
return
nil
}
}
func
l2BridgeProcessContractEvents
(
processLog
log
.
Logger
,
db
*
database
.
DB
,
ethClient
node
.
EthClient
,
events
[]
*
database
.
L2ContractEvent
,
eventLogs
map
[
uuid
.
UUID
]
*
types
.
Log
,
logsByIndex
map
[
uint
]
*
types
.
Log
,
)
error
{
rawEthClient
:=
ethclient
.
NewClient
(
ethClient
.
RawRpcClient
())
l2StandardBridgeABI
,
err
:=
bindings
.
L2StandardBridgeMetaData
.
GetAbi
()
if
err
!=
nil
{
return
err
}
l2CrossDomainMessengerABI
,
err
:=
bindings
.
L2CrossDomainMessengerMetaData
.
GetAbi
()
if
err
!=
nil
{
return
err
}
type
BridgeData
struct
{
From
common
.
Address
To
common
.
Address
Amount
*
big
.
Int
ExtraData
[]
byte
}
numFinalizedDeposits
:=
0
ethBridgeFinalizedEventSig
:=
l2StandardBridgeABI
.
Events
[
"ETHBridgeFinalized"
]
.
ID
relayedMessageEventSig
:=
l2CrossDomainMessengerABI
.
Events
[
"RelayedMessage"
]
.
ID
relayMessageMethod
:=
l2CrossDomainMessengerABI
.
Methods
[
"relayMessage"
]
for
_
,
contractEvent
:=
range
events
{
eventSig
:=
contractEvent
.
EventSignature
log
:=
eventLogs
[
contractEvent
.
GUID
]
if
eventSig
==
ethBridgeFinalizedEventSig
{
// (1) Ensure the RelayedMessage follows the log right after the bridge event
relayedMsgLog
:=
logsByIndex
[
log
.
Index
+
1
]
if
relayedMsgLog
.
Topics
[
0
]
!=
relayedMessageEventSig
{
processLog
.
Crit
(
"expected CrossDomainMessenger#RelayedMessage following StandardBridge#EthBridgeFinalized event"
,
"event_sig"
,
relayedMsgLog
.
Topics
[
0
],
"relayed_message_sig"
,
relayedMessageEventSig
)
return
errors
.
New
(
"unexpected bridge event ordering"
)
}
// unfortunately there's no way to extract the nonce on the relayed message event. we can
// extract the nonce by unpacking the transaction input for the `relayMessage` transaction
tx
,
isPending
,
err
:=
rawEthClient
.
TransactionByHash
(
context
.
Background
(),
relayedMsgLog
.
TxHash
)
if
err
!=
nil
||
isPending
{
processLog
.
Crit
(
"CrossDomainMessager#relayeMessage transaction query err or found pending"
,
err
,
"err"
,
"isPending"
,
isPending
)
return
errors
.
New
(
"unable to query relayMessage tx"
)
}
txData
:=
tx
.
Data
()
fnSelector
:=
txData
[
:
4
]
if
!
bytes
.
Equal
(
fnSelector
,
relayMessageMethod
.
ID
)
{
processLog
.
Crit
(
"expected relayMessage function selector"
)
return
errors
.
New
(
"RelayMessage log does not match relayMessage transaction"
)
}
fnData
:=
txData
[
4
:
]
inputsMap
:=
make
(
map
[
string
]
interface
{})
err
=
relayMessageMethod
.
Inputs
.
UnpackIntoMap
(
inputsMap
,
fnData
)
if
err
!=
nil
{
processLog
.
Crit
(
"unable to unpack CrossDomainMessenger#relayMessage function data"
,
"err"
,
err
)
return
err
}
nonce
,
ok
:=
inputsMap
[
"_nonce"
]
.
(
*
big
.
Int
)
if
!
ok
{
processLog
.
Crit
(
"unable to extract _nonce from CrossDomainMessenger#relayMessage function call"
)
return
errors
.
New
(
"unable to extract relayMessage nonce"
)
}
// (2) Mark initiated L1 deposit as finalized
deposit
,
err
:=
db
.
Bridge
.
DepositByMessageNonce
(
nonce
)
if
err
!=
nil
{
processLog
.
Error
(
"error querying initiated deposit messsage using nonce"
,
"nonce"
,
nonce
)
return
err
}
else
if
deposit
==
nil
{
latestNonce
,
err
:=
db
.
Bridge
.
LatestDepositMessageNonce
()
if
err
!=
nil
{
return
err
}
// check if the the L1Processor is behind or really has missed an event
if
latestNonce
==
nil
||
nonce
.
Cmp
(
latestNonce
)
>
0
{
processLog
.
Warn
(
"behind on indexed L1 deposits"
,
"deposit_message_nonce"
,
nonce
,
"latest_deposit_message_nonce"
,
latestNonce
)
return
errors
.
New
(
"waiting for L1Processor to catch up"
)
}
else
{
processLog
.
Crit
(
"missing indexed deposit for this finalization event"
,
"deposit_message_nonce"
,
nonce
,
"tx_hash"
,
log
.
TxHash
,
"log_index"
,
log
.
Index
)
return
errors
.
New
(
"missing deposit message"
)
}
}
err
=
db
.
Bridge
.
MarkFinalizedDepositEvent
(
deposit
.
GUID
,
contractEvent
.
GUID
)
if
err
!=
nil
{
processLog
.
Error
(
"error finalizing deposit"
,
"err"
,
err
)
return
err
}
numFinalizedDeposits
++
}
}
// a-ok!
if
numFinalizedDeposits
>
0
{
processLog
.
Info
(
"finalized deposits"
,
"num"
,
numFinalizedDeposits
)
}
return
nil
}
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