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
1ca85526
Unverified
Commit
1ca85526
authored
Oct 28, 2024
by
Axel Kingsley
Committed by
GitHub
Oct 29, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Interop: Expanded E2E Tests (#12659)
* Expand Interop E2E Testing * fix test ; address comment
parent
b46bffed
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
242 additions
and
111 deletions
+242
-111
interop_test.go
op-e2e/interop/interop_test.go
+161
-62
supersystem.go
op-e2e/interop/supersystem.go
+9
-1
supervisor_client.go
op-service/sources/supervisor_client.go
+53
-15
backend.go
op-supervisor/supervisor/backend/backend.go
+2
-2
query.go
op-supervisor/supervisor/backend/db/query.go
+1
-1
l2inbox.go
...rvisor/supervisor/backend/processors/contracts/l2inbox.go
+1
-16
l2inbox_test.go
...r/supervisor/backend/processors/contracts/l2inbox_test.go
+1
-1
log_processor.go
op-supervisor/supervisor/backend/processors/log_processor.go
+1
-13
types.go
op-supervisor/supervisor/types/types.go
+13
-0
No files found.
op-e2e/interop/interop_test.go
View file @
1ca85526
...
@@ -3,22 +3,24 @@ package interop
...
@@ -3,22 +3,24 @@ package interop
import
(
import
(
"context"
"context"
"math/big"
"math/big"
"sync"
"testing"
"testing"
"time"
"time"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-chain-ops/interopgen"
"github.com/ethereum-optimism/optimism/op-chain-ops/interopgen"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
"github.com/ethereum-optimism/optimism/op-e2e/system/helpers"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
gethTypes
"github.com/ethereum/go-ethereum/core/types"
)
)
// TestInteropTrivial tests a simple interop scenario
// setupAndRun is a helper function that sets up a SuperSystem
// Chains A and B exist, but no messages are sent between them
// which contains two L2 Chains, and two users on each chain.
// and in fact no event-logs are emitted by either chain at all.
func
setupAndRun
(
t
*
testing
.
T
,
fn
func
(
*
testing
.
T
,
SuperSystem
))
{
// A transaction is sent from Alice to Bob on Chain A.
// The balance of Bob on Chain A is checked before and after the tx.
// The balance of Bob on Chain B is checked after the tx.
func
TestInteropTrivial
(
t
*
testing
.
T
)
{
recipe
:=
interopgen
.
InteropDevRecipe
{
recipe
:=
interopgen
.
InteropDevRecipe
{
L1ChainID
:
900100
,
L1ChainID
:
900100
,
L2ChainIDs
:
[]
uint64
{
900200
,
900201
},
L2ChainIDs
:
[]
uint64
{
900200
,
900201
},
...
@@ -32,66 +34,163 @@ func TestInteropTrivial(t *testing.T) {
...
@@ -32,66 +34,163 @@ func TestInteropTrivial(t *testing.T) {
// create a super system from the recipe
// create a super system from the recipe
// and get the L2 IDs for use in the test
// and get the L2 IDs for use in the test
s2
:=
NewSuperSystem
(
t
,
&
recipe
,
worldResources
)
s2
:=
NewSuperSystem
(
t
,
&
recipe
,
worldResources
)
ids
:=
s2
.
L2IDs
()
// chainA is the first L2 chain
chainA
:=
ids
[
0
]
// chainB is the second L2 chain
chainB
:=
ids
[
1
]
// create two users on all L2 chains
// create two users on all L2 chains
s2
.
AddUser
(
"Alice"
)
s2
.
AddUser
(
"Alice"
)
s2
.
AddUser
(
"Bob"
)
s2
.
AddUser
(
"Bob"
)
bobAddr
:=
s2
.
Address
(
chainA
,
"Bob"
)
// run the test
fn
(
t
,
s2
)
// check the balance of Bob
}
clientA
:=
s2
.
L2GethClient
(
chainA
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
:=
clientA
.
BalanceAt
(
ctx
,
bobAddr
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
:=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000000000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
// send a tx from Alice to Bob
s2
.
SendL2Tx
(
chainA
,
"Alice"
,
func
(
l2Opts
*
helpers
.
TxOpts
)
{
l2Opts
.
ToAddr
=
&
bobAddr
l2Opts
.
Value
=
big
.
NewInt
(
1000000
)
l2Opts
.
GasFeeCap
=
big
.
NewInt
(
1
_000_000_000
)
l2Opts
.
GasTipCap
=
big
.
NewInt
(
1
_000_000_000
)
},
)
// check the balance of Bob after the tx
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
=
clientA
.
BalanceAt
(
ctx
,
bobAddr
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000001000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
// check that the balance of Bob on ChainB hasn't changed
bobAddrB
:=
s2
.
Address
(
chainB
,
"Bob"
)
clientB
:=
s2
.
L2GethClient
(
chainB
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
=
clientB
.
BalanceAt
(
ctx
,
bobAddrB
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000000000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
s2
.
DeployEmitterContract
(
chainA
,
"Alice"
)
s2
.
DeployEmitterContract
(
chainB
,
"Alice"
)
for
i
:=
0
;
i
<
1
;
i
++
{
s2
.
EmitData
(
chainA
,
"Alice"
,
"0x1234567890abcdef"
)
s2
.
EmitData
(
chainB
,
"Alice"
,
"0x1234567890abcdef"
)
}
time
.
Sleep
(
60
*
time
.
Second
)
// TestInterop_IsolatedChains tests a simple interop scenario
// Chains A and B exist, but no messages are sent between them
// a transaction is sent from Alice to Bob on Chain A,
// and only Chain A is affected.
func
TestInterop_IsolatedChains
(
t
*
testing
.
T
)
{
test
:=
func
(
t
*
testing
.
T
,
s2
SuperSystem
)
{
ids
:=
s2
.
L2IDs
()
chainA
:=
ids
[
0
]
chainB
:=
ids
[
1
]
// check the balance of Bob
bobAddr
:=
s2
.
Address
(
chainA
,
"Bob"
)
clientA
:=
s2
.
L2GethClient
(
chainA
)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
:=
clientA
.
BalanceAt
(
ctx
,
bobAddr
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
:=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000000000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
// send a tx from Alice to Bob
s2
.
SendL2Tx
(
chainA
,
"Alice"
,
func
(
l2Opts
*
helpers
.
TxOpts
)
{
l2Opts
.
ToAddr
=
&
bobAddr
l2Opts
.
Value
=
big
.
NewInt
(
1000000
)
l2Opts
.
GasFeeCap
=
big
.
NewInt
(
1
_000_000_000
)
l2Opts
.
GasTipCap
=
big
.
NewInt
(
1
_000_000_000
)
},
)
// check the balance of Bob after the tx
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
=
clientA
.
BalanceAt
(
ctx
,
bobAddr
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000001000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
// check that the balance of Bob on ChainB hasn't changed
bobAddrB
:=
s2
.
Address
(
chainB
,
"Bob"
)
clientB
:=
s2
.
L2GethClient
(
chainB
)
ctx
,
cancel
=
context
.
WithTimeout
(
context
.
Background
(),
1
*
time
.
Second
)
defer
cancel
()
bobBalance
,
err
=
clientB
.
BalanceAt
(
ctx
,
bobAddrB
,
nil
)
require
.
NoError
(
t
,
err
)
expectedBalance
,
_
=
big
.
NewInt
(
0
)
.
SetString
(
"10000000000000000000000000"
,
10
)
require
.
Equal
(
t
,
expectedBalance
,
bobBalance
)
}
setupAndRun
(
t
,
test
)
}
// TestInteropTrivial_EmitLogs tests a simple interop scenario
// Chains A and B exist, but no messages are sent between them.
// A contract is deployed on each chain, and logs are emitted repeatedly.
func
TestInteropTrivial_EmitLogs
(
t
*
testing
.
T
)
{
test
:=
func
(
t
*
testing
.
T
,
s2
SuperSystem
)
{
ids
:=
s2
.
L2IDs
()
chainA
:=
ids
[
0
]
chainB
:=
ids
[
1
]
EmitterA
:=
s2
.
DeployEmitterContract
(
chainA
,
"Alice"
)
EmitterB
:=
s2
.
DeployEmitterContract
(
chainB
,
"Alice"
)
payload1
:=
"SUPER JACKPOT!"
numEmits
:=
10
// emit logs on both chains in parallel
var
emitParallel
sync
.
WaitGroup
emitOn
:=
func
(
chainID
string
)
{
for
i
:=
0
;
i
<
numEmits
;
i
++
{
s2
.
EmitData
(
chainID
,
"Alice"
,
payload1
)
}
emitParallel
.
Done
()
}
emitParallel
.
Add
(
2
)
go
emitOn
(
chainA
)
go
emitOn
(
chainB
)
emitParallel
.
Wait
()
clientA
:=
s2
.
L2GethClient
(
chainA
)
clientB
:=
s2
.
L2GethClient
(
chainB
)
// check that the logs are emitted on chain A
qA
:=
ethereum
.
FilterQuery
{
Addresses
:
[]
common
.
Address
{
EmitterA
},
}
logsA
,
err
:=
clientA
.
FilterLogs
(
context
.
Background
(),
qA
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
logsA
,
numEmits
)
// check that the logs are emitted on chain B
qB
:=
ethereum
.
FilterQuery
{
Addresses
:
[]
common
.
Address
{
EmitterB
},
}
logsB
,
err
:=
clientB
.
FilterLogs
(
context
.
Background
(),
qB
)
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
logsB
,
numEmits
)
// wait for cross-safety to settle
// I've tried 30s but not all logs are cross-safe by then
time
.
Sleep
(
60
*
time
.
Second
)
supervisor
:=
s2
.
SupervisorClient
()
// requireMessage checks the safety level of a log against the supervisor
// it also checks that the error is as expected
requireMessage
:=
func
(
chainID
string
,
log
gethTypes
.
Log
,
expectedSafety
types
.
SafetyLevel
,
expectedError
error
)
{
client
:=
s2
.
L2GethClient
(
chainID
)
// construct the expected hash of the log's payload
// (topics concatenated with data)
msgPayload
:=
make
([]
byte
,
0
)
for
_
,
topic
:=
range
log
.
Topics
{
msgPayload
=
append
(
msgPayload
,
topic
.
Bytes
()
...
)
}
msgPayload
=
append
(
msgPayload
,
log
.
Data
...
)
expectedHash
:=
common
.
BytesToHash
(
crypto
.
Keccak256
(
msgPayload
))
// convert payload hash to log hash
logHash
:=
types
.
PayloadHashToLogHash
(
expectedHash
,
log
.
Address
)
// get block for the log (for timestamp)
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
3
*
time
.
Second
)
defer
cancel
()
block
,
err
:=
client
.
BlockByHash
(
ctx
,
log
.
BlockHash
)
require
.
NoError
(
t
,
err
)
// make an identifier out of the sample log
identifier
:=
types
.
Identifier
{
Origin
:
log
.
Address
,
BlockNumber
:
log
.
BlockNumber
,
LogIndex
:
uint64
(
log
.
Index
),
Timestamp
:
block
.
Time
(),
ChainID
:
types
.
ChainIDFromBig
(
s2
.
ChainID
(
chainID
)),
}
safety
,
error
:=
supervisor
.
CheckMessage
(
context
.
Background
(),
identifier
,
logHash
,
)
require
.
ErrorIs
(
t
,
error
,
expectedError
)
// the supervisor could progress the safety level more quickly than we expect,
// which is why we check for a minimum safety level
require
.
True
(
t
,
safety
.
AtLeastAsSafe
(
expectedSafety
),
"log: %v should be at least %s, but is %s"
,
log
,
expectedSafety
.
String
(),
safety
.
String
())
}
// all logs should be cross-safe
for
_
,
log
:=
range
logsA
{
requireMessage
(
chainA
,
log
,
types
.
CrossSafe
,
nil
)
}
for
_
,
log
:=
range
logsB
{
requireMessage
(
chainB
,
log
,
types
.
CrossSafe
,
nil
)
}
}
setupAndRun
(
t
,
test
)
}
}
op-e2e/interop/supersystem.go
View file @
1ca85526
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"os"
"os"
"path"
"path"
"path/filepath"
"path/filepath"
"sort"
"testing"
"testing"
"time"
"time"
...
@@ -79,8 +80,10 @@ type SuperSystem interface {
...
@@ -79,8 +80,10 @@ type SuperSystem interface {
L2GethClient
(
network
string
)
*
ethclient
.
Client
L2GethClient
(
network
string
)
*
ethclient
.
Client
// get the secret for a network and role
// get the secret for a network and role
L2OperatorKey
(
network
string
,
role
devkeys
.
ChainOperatorRole
)
ecdsa
.
PrivateKey
L2OperatorKey
(
network
string
,
role
devkeys
.
ChainOperatorRole
)
ecdsa
.
PrivateKey
// get the list of network IDs
// get the list of network IDs
as key-strings
L2IDs
()
[]
string
L2IDs
()
[]
string
// get the chain ID for a network
ChainID
(
network
string
)
*
big
.
Int
// register a username to an account on all L2s
// register a username to an account on all L2s
AddUser
(
username
string
)
AddUser
(
username
string
)
// get the user key for a user on an L2
// get the user key for a user on an L2
...
@@ -415,6 +418,10 @@ func (s *interopE2ESystem) newL2(id string, l2Out *interopgen.L2Output) l2Set {
...
@@ -415,6 +418,10 @@ func (s *interopE2ESystem) newL2(id string, l2Out *interopgen.L2Output) l2Set {
}
}
}
}
func
(
s
*
interopE2ESystem
)
ChainID
(
network
string
)
*
big
.
Int
{
return
s
.
l2s
[
network
]
.
chainID
}
// prepareSupervisor creates a new supervisor for the system
// prepareSupervisor creates a new supervisor for the system
func
(
s
*
interopE2ESystem
)
prepareSupervisor
()
*
supervisor
.
SupervisorService
{
func
(
s
*
interopE2ESystem
)
prepareSupervisor
()
*
supervisor
.
SupervisorService
{
// Be verbose with op-supervisor, it's in early test phase
// Be verbose with op-supervisor, it's in early test phase
...
@@ -604,6 +611,7 @@ func (s *interopE2ESystem) L2IDs() []string {
...
@@ -604,6 +611,7 @@ func (s *interopE2ESystem) L2IDs() []string {
for
id
:=
range
s
.
l2s
{
for
id
:=
range
s
.
l2s
{
ids
=
append
(
ids
,
id
)
ids
=
append
(
ids
,
id
)
}
}
sort
.
Strings
(
ids
)
return
ids
return
ids
}
}
...
...
op-service/sources/supervisor_client.go
View file @
1ca85526
...
@@ -7,6 +7,7 @@ import (
...
@@ -7,6 +7,7 @@ import (
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/client"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum-optimism/optimism/op-supervisor/supervisor/types"
"github.com/ethereum/go-ethereum/common"
)
)
type
SupervisorClient
struct
{
type
SupervisorClient
struct
{
...
@@ -19,9 +20,7 @@ func NewSupervisorClient(client client.RPC) *SupervisorClient {
...
@@ -19,9 +20,7 @@ func NewSupervisorClient(client client.RPC) *SupervisorClient {
}
}
}
}
func
(
cl
*
SupervisorClient
)
Stop
(
func
(
cl
*
SupervisorClient
)
Stop
(
ctx
context
.
Context
)
error
{
ctx
context
.
Context
,
)
error
{
var
result
error
var
result
error
err
:=
cl
.
client
.
CallContext
(
err
:=
cl
.
client
.
CallContext
(
ctx
,
ctx
,
...
@@ -33,9 +32,7 @@ func (cl *SupervisorClient) Stop(
...
@@ -33,9 +32,7 @@ func (cl *SupervisorClient) Stop(
return
result
return
result
}
}
func
(
cl
*
SupervisorClient
)
Start
(
func
(
cl
*
SupervisorClient
)
Start
(
ctx
context
.
Context
)
error
{
ctx
context
.
Context
,
)
error
{
var
result
error
var
result
error
err
:=
cl
.
client
.
CallContext
(
err
:=
cl
.
client
.
CallContext
(
ctx
,
ctx
,
...
@@ -47,10 +44,7 @@ func (cl *SupervisorClient) Start(
...
@@ -47,10 +44,7 @@ func (cl *SupervisorClient) Start(
return
result
return
result
}
}
func
(
cl
*
SupervisorClient
)
AddL2RPC
(
func
(
cl
*
SupervisorClient
)
AddL2RPC
(
ctx
context
.
Context
,
rpc
string
)
error
{
ctx
context
.
Context
,
rpc
string
,
)
error
{
var
result
error
var
result
error
err
:=
cl
.
client
.
CallContext
(
err
:=
cl
.
client
.
CallContext
(
ctx
,
ctx
,
...
@@ -63,6 +57,25 @@ func (cl *SupervisorClient) AddL2RPC(
...
@@ -63,6 +57,25 @@ func (cl *SupervisorClient) AddL2RPC(
return
result
return
result
}
}
func
(
cl
*
SupervisorClient
)
CheckMessage
(
ctx
context
.
Context
,
identifier
types
.
Identifier
,
logHash
common
.
Hash
)
(
types
.
SafetyLevel
,
error
)
{
var
result
types
.
SafetyLevel
err
:=
cl
.
client
.
CallContext
(
ctx
,
&
result
,
"supervisor_checkMessage"
,
identifier
,
logHash
)
if
err
!=
nil
{
return
types
.
Invalid
,
fmt
.
Errorf
(
"failed to check message (chain %s), (block %v), (index %v), (logHash %s): %w"
,
identifier
.
ChainID
,
identifier
.
BlockNumber
,
identifier
.
LogIndex
,
logHash
,
err
)
}
return
result
,
nil
}
func
(
cl
*
SupervisorClient
)
UnsafeView
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
unsafe
types
.
ReferenceView
)
(
types
.
ReferenceView
,
error
)
{
func
(
cl
*
SupervisorClient
)
UnsafeView
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
unsafe
types
.
ReferenceView
)
(
types
.
ReferenceView
,
error
)
{
var
result
types
.
ReferenceView
var
result
types
.
ReferenceView
err
:=
cl
.
client
.
CallContext
(
err
:=
cl
.
client
.
CallContext
(
...
@@ -93,26 +106,51 @@ func (cl *SupervisorClient) SafeView(ctx context.Context, chainID types.ChainID,
...
@@ -93,26 +106,51 @@ func (cl *SupervisorClient) SafeView(ctx context.Context, chainID types.ChainID,
func
(
cl
*
SupervisorClient
)
Finalized
(
ctx
context
.
Context
,
chainID
types
.
ChainID
)
(
eth
.
BlockID
,
error
)
{
func
(
cl
*
SupervisorClient
)
Finalized
(
ctx
context
.
Context
,
chainID
types
.
ChainID
)
(
eth
.
BlockID
,
error
)
{
var
result
eth
.
BlockID
var
result
eth
.
BlockID
err
:=
cl
.
client
.
CallContext
(
ctx
,
&
result
,
"supervisor_finalized"
,
chainID
)
err
:=
cl
.
client
.
CallContext
(
ctx
,
&
result
,
"supervisor_finalized"
,
chainID
)
return
result
,
err
return
result
,
err
}
}
func
(
cl
*
SupervisorClient
)
DerivedFrom
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
derived
eth
.
BlockID
)
(
eth
.
BlockRef
,
error
)
{
func
(
cl
*
SupervisorClient
)
DerivedFrom
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
derived
eth
.
BlockID
)
(
eth
.
BlockRef
,
error
)
{
var
result
eth
.
BlockRef
var
result
eth
.
BlockRef
err
:=
cl
.
client
.
CallContext
(
ctx
,
&
result
,
"supervisor_derivedFrom"
,
chainID
,
derived
)
err
:=
cl
.
client
.
CallContext
(
ctx
,
&
result
,
"supervisor_derivedFrom"
,
chainID
,
derived
)
return
result
,
err
return
result
,
err
}
}
func
(
cl
*
SupervisorClient
)
UpdateLocalUnsafe
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
head
eth
.
BlockRef
)
error
{
func
(
cl
*
SupervisorClient
)
UpdateLocalUnsafe
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
head
eth
.
BlockRef
)
error
{
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateLocalUnsafe"
,
chainID
,
head
)
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateLocalUnsafe"
,
chainID
,
head
)
}
}
func
(
cl
*
SupervisorClient
)
UpdateLocalSafe
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
derivedFrom
eth
.
L1BlockRef
,
lastDerived
eth
.
BlockRef
)
error
{
func
(
cl
*
SupervisorClient
)
UpdateLocalSafe
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
derivedFrom
eth
.
L1BlockRef
,
lastDerived
eth
.
BlockRef
)
error
{
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateLocalSafe"
,
chainID
,
derivedFrom
,
lastDerived
)
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateLocalSafe"
,
chainID
,
derivedFrom
,
lastDerived
)
}
}
func
(
cl
*
SupervisorClient
)
UpdateFinalizedL1
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
finalizedL1
eth
.
L1BlockRef
)
error
{
func
(
cl
*
SupervisorClient
)
UpdateFinalizedL1
(
ctx
context
.
Context
,
chainID
types
.
ChainID
,
finalizedL1
eth
.
L1BlockRef
)
error
{
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateFinalizedL1"
,
chainID
,
finalizedL1
)
return
cl
.
client
.
CallContext
(
ctx
,
nil
,
"supervisor_updateFinalizedL1"
,
chainID
,
finalizedL1
)
}
}
func
(
cl
*
SupervisorClient
)
Close
()
{
func
(
cl
*
SupervisorClient
)
Close
()
{
...
...
op-supervisor/supervisor/backend/backend.go
View file @
1ca85526
...
@@ -308,14 +308,14 @@ func (su *SupervisorBackend) DependencySet() depset.DependencySet {
...
@@ -308,14 +308,14 @@ func (su *SupervisorBackend) DependencySet() depset.DependencySet {
// Query methods
// Query methods
// ----------------------------
// ----------------------------
func
(
su
*
SupervisorBackend
)
CheckMessage
(
identifier
types
.
Identifier
,
payload
Hash
common
.
Hash
)
(
types
.
SafetyLevel
,
error
)
{
func
(
su
*
SupervisorBackend
)
CheckMessage
(
identifier
types
.
Identifier
,
log
Hash
common
.
Hash
)
(
types
.
SafetyLevel
,
error
)
{
su
.
mu
.
RLock
()
su
.
mu
.
RLock
()
defer
su
.
mu
.
RUnlock
()
defer
su
.
mu
.
RUnlock
()
chainID
:=
identifier
.
ChainID
chainID
:=
identifier
.
ChainID
blockNum
:=
identifier
.
BlockNumber
blockNum
:=
identifier
.
BlockNumber
logIdx
:=
identifier
.
LogIndex
logIdx
:=
identifier
.
LogIndex
_
,
err
:=
su
.
chainDBs
.
Check
(
chainID
,
blockNum
,
uint32
(
logIdx
),
payload
Hash
)
_
,
err
:=
su
.
chainDBs
.
Check
(
chainID
,
blockNum
,
uint32
(
logIdx
),
log
Hash
)
if
errors
.
Is
(
err
,
types
.
ErrFuture
)
{
if
errors
.
Is
(
err
,
types
.
ErrFuture
)
{
return
types
.
LocalUnsafe
,
nil
return
types
.
LocalUnsafe
,
nil
}
}
...
...
op-supervisor/supervisor/backend/db/query.go
View file @
1ca85526
...
@@ -358,7 +358,7 @@ func (db *ChainsDB) NextDerivedFrom(chain types.ChainID, derivedFrom eth.BlockID
...
@@ -358,7 +358,7 @@ func (db *ChainsDB) NextDerivedFrom(chain types.ChainID, derivedFrom eth.BlockID
// Safest returns the strongest safety level that can be guaranteed for the given log entry.
// Safest returns the strongest safety level that can be guaranteed for the given log entry.
// it assumes the log entry has already been checked and is valid, this function only checks safety levels.
// it assumes the log entry has already been checked and is valid, this function only checks safety levels.
//
Cross-safety levels are all considered to be more safe than any form of local-safety
.
//
Safety levels are assumed to graduate from LocalUnsafe to LocalSafe to CrossUnsafe to CrossSafe, with Finalized as the strongest
.
func
(
db
*
ChainsDB
)
Safest
(
chainID
types
.
ChainID
,
blockNum
uint64
,
index
uint32
)
(
safest
types
.
SafetyLevel
,
err
error
)
{
func
(
db
*
ChainsDB
)
Safest
(
chainID
types
.
ChainID
,
blockNum
uint64
,
index
uint32
)
(
safest
types
.
SafetyLevel
,
err
error
)
{
db
.
mu
.
RLock
()
db
.
mu
.
RLock
()
defer
db
.
mu
.
RUnlock
()
defer
db
.
mu
.
RUnlock
()
...
...
op-supervisor/supervisor/backend/processors/contracts/l2inbox.go
View file @
1ca85526
...
@@ -14,7 +14,6 @@ import (
...
@@ -14,7 +14,6 @@ import (
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots"
"github.com/ethereum-optimism/optimism/packages/contracts-bedrock/snapshots"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
ethTypes
"github.com/ethereum/go-ethereum/core/types"
ethTypes
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
)
)
const
(
const
(
...
@@ -74,7 +73,7 @@ func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (types.Executi
...
@@ -74,7 +73,7 @@ func (i *CrossL2Inbox) DecodeExecutingMessageLog(l *ethTypes.Log) (types.Executi
if
err
!=
nil
{
if
err
!=
nil
{
return
types
.
ExecutingMessage
{},
fmt
.
Errorf
(
"failed to convert chain ID %v to uint32: %w"
,
identifier
.
ChainId
,
err
)
return
types
.
ExecutingMessage
{},
fmt
.
Errorf
(
"failed to convert chain ID %v to uint32: %w"
,
identifier
.
ChainId
,
err
)
}
}
hash
:=
p
ayloadHashToLogHash
(
msgHash
,
identifier
.
Origin
)
hash
:=
types
.
P
ayloadHashToLogHash
(
msgHash
,
identifier
.
Origin
)
return
types
.
ExecutingMessage
{
return
types
.
ExecutingMessage
{
Chain
:
types
.
ChainIndex
(
chainID
),
// TODO(#11105): translate chain ID to chain index
Chain
:
types
.
ChainIndex
(
chainID
),
// TODO(#11105): translate chain ID to chain index
Hash
:
hash
,
Hash
:
hash
,
...
@@ -117,17 +116,3 @@ func identifierFromBytes(identifierBytes io.Reader) (contractIdentifier, error)
...
@@ -117,17 +116,3 @@ func identifierFromBytes(identifierBytes io.Reader) (contractIdentifier, error)
ChainId
:
chainID
,
ChainId
:
chainID
,
},
nil
},
nil
}
}
// payloadHashToLogHash converts the payload hash to the log hash
// it is the concatenation of the log's address and the hash of the log's payload,
// which is then hashed again. This is the hash that is stored in the log storage.
// The logHash can then be used to traverse from the executing message
// to the log the referenced initiating message.
// TODO(#12424): this function is duplicated between contracts and backend/source/log_processor.go
// to avoid a circular dependency. It should be reorganized to avoid this duplication.
func
payloadHashToLogHash
(
payloadHash
common
.
Hash
,
addr
common
.
Address
)
common
.
Hash
{
msg
:=
make
([]
byte
,
0
,
2
*
common
.
HashLength
)
msg
=
append
(
msg
,
addr
.
Bytes
()
...
)
msg
=
append
(
msg
,
payloadHash
.
Bytes
()
...
)
return
crypto
.
Keccak256Hash
(
msg
)
}
op-supervisor/supervisor/backend/processors/contracts/l2inbox_test.go
View file @
1ca85526
...
@@ -32,7 +32,7 @@ func TestDecodeExecutingMessageEvent(t *testing.T) {
...
@@ -32,7 +32,7 @@ func TestDecodeExecutingMessageEvent(t *testing.T) {
Timestamp
:
new
(
big
.
Int
)
.
SetUint64
(
expected
.
Timestamp
),
Timestamp
:
new
(
big
.
Int
)
.
SetUint64
(
expected
.
Timestamp
),
LogIndex
:
new
(
big
.
Int
)
.
SetUint64
(
uint64
(
expected
.
LogIdx
)),
LogIndex
:
new
(
big
.
Int
)
.
SetUint64
(
uint64
(
expected
.
LogIdx
)),
}
}
expected
.
Hash
=
p
ayloadHashToLogHash
(
payloadHash
,
contractIdent
.
Origin
)
expected
.
Hash
=
types
.
P
ayloadHashToLogHash
(
payloadHash
,
contractIdent
.
Origin
)
abi
:=
snapshots
.
LoadCrossL2InboxABI
()
abi
:=
snapshots
.
LoadCrossL2InboxABI
()
validData
,
err
:=
abi
.
Events
[
eventExecutingMessage
]
.
Inputs
.
Pack
(
payloadHash
,
contractIdent
)
validData
,
err
:=
abi
.
Events
[
eventExecutingMessage
]
.
Inputs
.
Pack
(
payloadHash
,
contractIdent
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
...
...
op-supervisor/supervisor/backend/processors/log_processor.go
View file @
1ca85526
...
@@ -78,7 +78,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.BlockRef, rcpts
...
@@ -78,7 +78,7 @@ func (p *logProcessor) ProcessLogs(_ context.Context, block eth.BlockRef, rcpts
// and because they represent paired data.
// and because they represent paired data.
func
logToLogHash
(
l
*
ethTypes
.
Log
)
common
.
Hash
{
func
logToLogHash
(
l
*
ethTypes
.
Log
)
common
.
Hash
{
payloadHash
:=
crypto
.
Keccak256
(
logToMessagePayload
(
l
))
payloadHash
:=
crypto
.
Keccak256
(
logToMessagePayload
(
l
))
return
p
ayloadHashToLogHash
(
common
.
Hash
(
payloadHash
),
l
.
Address
)
return
types
.
P
ayloadHashToLogHash
(
common
.
Hash
(
payloadHash
),
l
.
Address
)
}
}
// logToMessagePayload is the data that is hashed to get the logHash
// logToMessagePayload is the data that is hashed to get the logHash
...
@@ -92,15 +92,3 @@ func logToMessagePayload(l *ethTypes.Log) []byte {
...
@@ -92,15 +92,3 @@ func logToMessagePayload(l *ethTypes.Log) []byte {
msg
=
append
(
msg
,
l
.
Data
...
)
msg
=
append
(
msg
,
l
.
Data
...
)
return
msg
return
msg
}
}
// payloadHashToLogHash converts the payload hash to the log hash
// it is the concatenation of the log's address and the hash of the log's payload,
// which is then hashed. This is the hash that is stored in the log storage.
// The logHash can then be used to traverse from the executing message
// to the log the referenced initiating message.
func
payloadHashToLogHash
(
payloadHash
common
.
Hash
,
addr
common
.
Address
)
common
.
Hash
{
msg
:=
make
([]
byte
,
0
,
2
*
common
.
HashLength
)
msg
=
append
(
msg
,
addr
.
Bytes
()
...
)
msg
=
append
(
msg
,
payloadHash
.
Bytes
()
...
)
return
crypto
.
Keccak256Hash
(
msg
)
}
op-supervisor/supervisor/types/types.go
View file @
1ca85526
...
@@ -12,6 +12,7 @@ import (
...
@@ -12,6 +12,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/eth"
)
)
...
@@ -251,3 +252,15 @@ func BlockSealFromRef(ref eth.BlockRef) BlockSeal {
...
@@ -251,3 +252,15 @@ func BlockSealFromRef(ref eth.BlockRef) BlockSeal {
Timestamp
:
ref
.
Time
,
Timestamp
:
ref
.
Time
,
}
}
}
}
// PayloadHashToLogHash converts the payload hash to the log hash
// it is the concatenation of the log's address and the hash of the log's payload,
// which is then hashed again. This is the hash that is stored in the log storage.
// The logHash can then be used to traverse from the executing message
// to the log the referenced initiating message.
func
PayloadHashToLogHash
(
payloadHash
common
.
Hash
,
addr
common
.
Address
)
common
.
Hash
{
msg
:=
make
([]
byte
,
0
,
2
*
common
.
HashLength
)
msg
=
append
(
msg
,
addr
.
Bytes
()
...
)
msg
=
append
(
msg
,
payloadHash
.
Bytes
()
...
)
return
crypto
.
Keccak256Hash
(
msg
)
}
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