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
2eeb5362
Commit
2eeb5362
authored
May 30, 2023
by
Andreas Bigger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement the Output Validation Function
parent
a48e53c1
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
226 additions
and
11 deletions
+226
-11
challenger.go
op-challenger/challenger/challenger.go
+14
-10
oracle_test.go
op-challenger/challenger/oracle_test.go
+1
-1
output.go
op-challenger/challenger/output.go
+52
-0
output_test.go
op-challenger/challenger/output_test.go
+159
-0
No files found.
op-challenger/challenger/challenger.go
View file @
2eeb5362
...
...
@@ -6,21 +6,25 @@ import (
"sync"
"time"
abi
"github.com/ethereum/go-ethereum/accounts/abi"
bind
"github.com/ethereum/go-ethereum/accounts/abi/bind"
common
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
ethclient
"github.com/ethereum/go-ethereum/ethclient"
log
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/log"
config
"github.com/ethereum-optimism/optimism/op-challenger/config"
metrics
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
bindings
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
sources
"github.com/ethereum-optimism/optimism/op-node/sources
"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-node/eth
"
opclient
"github.com/ethereum-optimism/optimism/op-service/client"
txmgr
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
)
type
OutputAPI
interface
{
OutputAtBlock
(
ctx
context
.
Context
,
blockNum
uint64
)
(
*
eth
.
OutputResponse
,
error
)
}
// Challenger contests invalid L2OutputOracle outputs
type
Challenger
struct
{
txMgr
txmgr
.
TxManager
...
...
@@ -35,7 +39,7 @@ type Challenger struct {
l1Client
*
ethclient
.
Client
rollupClient
*
sources
.
RollupClient
rollupClient
OutputAPI
// l2 Output Oracle contract
l2ooContract
*
bindings
.
L2OutputOracleCaller
...
...
op-challenger/challenger/oracle_test.go
View file @
2eeb5362
...
...
@@ -48,5 +48,5 @@ func TestBuildOutputLogFilter_Fails(t *testing.T) {
// Build the filter
_
,
err
:=
BuildOutputLogFilter
(
&
l2ooABI
)
require
.
Error
(
t
,
err
)
require
.
E
qual
(
t
,
ErrMissingEvent
,
err
)
require
.
E
rrorIs
(
t
,
err
,
ErrMissingEvent
)
}
op-challenger/challenger/output.go
0 → 100644
View file @
2eeb5362
package
challenger
import
(
"context"
"errors"
"math/big"
"github.com/ethereum-optimism/optimism/op-node/eth"
)
var
(
// supportedL2OutputVersion is the version of the L2 output that the challenger supports.
supportedL2OutputVersion
=
eth
.
Bytes32
{}
// ErrInvalidBlockNumber is returned when the block number of the output does not match the expected block number.
ErrInvalidBlockNumber
=
errors
.
New
(
"invalid block number"
)
// ErrUnsupportedL2OOVersion is returned when the output version is not supported.
ErrUnsupportedL2OOVersion
=
errors
.
New
(
"unsupported l2oo version"
)
)
// ValidateOutput checks that a given output is expected via a trusted rollup node rpc.
// It returns: if the output is correct, the fetched output, error
func
(
c
*
Challenger
)
ValidateOutput
(
ctx
context
.
Context
,
l2BlockNumber
*
big
.
Int
,
expected
eth
.
Bytes32
)
(
bool
,
*
eth
.
Bytes32
,
error
)
{
// Fetch the output from the rollup node
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
c
.
networkTimeout
)
defer
cancel
()
output
,
err
:=
c
.
rollupClient
.
OutputAtBlock
(
ctx
,
l2BlockNumber
.
Uint64
())
if
err
!=
nil
{
c
.
log
.
Error
(
"Failed to fetch output"
,
"blockNum"
,
l2BlockNumber
,
"err"
,
err
)
return
false
,
nil
,
err
}
// Compare the output root to the expected output root
equalRoots
,
err
:=
c
.
compareOutputRoots
(
output
,
expected
,
l2BlockNumber
)
if
err
!=
nil
{
return
false
,
nil
,
err
}
return
equalRoots
,
&
output
.
OutputRoot
,
nil
}
// compareOutputRoots compares the output root of the given block number to the expected output root.
func
(
c
*
Challenger
)
compareOutputRoots
(
received
*
eth
.
OutputResponse
,
expected
eth
.
Bytes32
,
blockNumber
*
big
.
Int
)
(
bool
,
error
)
{
if
received
.
Version
!=
supportedL2OutputVersion
{
c
.
log
.
Error
(
"Unsupported l2 output version"
,
"version"
,
received
.
Version
)
return
false
,
ErrUnsupportedL2OOVersion
}
if
received
.
BlockRef
.
Number
!=
blockNumber
.
Uint64
()
{
c
.
log
.
Error
(
"Invalid blockNumber"
,
"expected"
,
blockNumber
,
"actual"
,
received
.
BlockRef
.
Number
)
return
false
,
ErrInvalidBlockNumber
}
return
received
.
OutputRoot
==
expected
,
nil
}
op-challenger/challenger/output_test.go
0 → 100644
View file @
2eeb5362
package
challenger
import
(
"context"
"errors"
"math/big"
"testing"
"time"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum-optimism/optimism/op-challenger/metrics"
"github.com/ethereum-optimism/optimism/op-node/eth"
"github.com/ethereum-optimism/optimism/op-node/testlog"
)
func
TestChallenger_ValidateOutput_RollupClientErrors
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
supportedL2OutputVersion
,
OutputRoot
:
eth
.
Bytes32
{},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
true
)
valid
,
received
,
err
:=
challenger
.
ValidateOutput
(
context
.
Background
(),
big
.
NewInt
(
0
),
output
.
OutputRoot
)
require
.
False
(
t
,
valid
)
require
.
Nil
(
t
,
received
)
require
.
ErrorIs
(
t
,
err
,
mockOutputApiError
)
}
func
TestChallenger_ValidateOutput_ErrorsWithWrongVersion
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
eth
.
Bytes32
{
0x01
},
OutputRoot
:
eth
.
Bytes32
{
0x01
},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
received
,
err
:=
challenger
.
ValidateOutput
(
context
.
Background
(),
big
.
NewInt
(
0
),
eth
.
Bytes32
{})
require
.
False
(
t
,
valid
)
require
.
Nil
(
t
,
received
)
require
.
ErrorIs
(
t
,
err
,
ErrUnsupportedL2OOVersion
)
}
func
TestChallenger_ValidateOutput_ErrorsInvalidBlockNumber
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
supportedL2OutputVersion
,
OutputRoot
:
eth
.
Bytes32
{
0x01
},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
received
,
err
:=
challenger
.
ValidateOutput
(
context
.
Background
(),
big
.
NewInt
(
1
),
output
.
OutputRoot
)
require
.
False
(
t
,
valid
)
require
.
Nil
(
t
,
received
)
require
.
ErrorIs
(
t
,
err
,
ErrInvalidBlockNumber
)
}
func
TestOutput_ValidateOutput
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
eth
.
Bytes32
{},
OutputRoot
:
eth
.
Bytes32
{},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
expected
,
err
:=
challenger
.
ValidateOutput
(
context
.
Background
(),
big
.
NewInt
(
0
),
output
.
OutputRoot
)
require
.
Equal
(
t
,
*
expected
,
output
.
OutputRoot
)
require
.
True
(
t
,
valid
)
require
.
NoError
(
t
,
err
)
}
func
TestChallenger_CompareOutputRoots_ErrorsWithDifferentRoots
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
eth
.
Bytes32
{
0xFF
,
0xFF
,
0xFF
,
0xFF
},
OutputRoot
:
eth
.
Bytes32
{},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
err
:=
challenger
.
compareOutputRoots
(
&
output
,
output
.
OutputRoot
,
big
.
NewInt
(
0
))
require
.
False
(
t
,
valid
)
require
.
ErrorIs
(
t
,
err
,
ErrUnsupportedL2OOVersion
)
}
func
TestChallenger_CompareOutputRoots_ErrInvalidBlockNumber
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
supportedL2OutputVersion
,
OutputRoot
:
eth
.
Bytes32
{},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
err
:=
challenger
.
compareOutputRoots
(
&
output
,
output
.
OutputRoot
,
big
.
NewInt
(
1
))
require
.
False
(
t
,
valid
)
require
.
ErrorIs
(
t
,
err
,
ErrInvalidBlockNumber
)
}
func
TestChallenger_CompareOutputRoots_Succeeds
(
t
*
testing
.
T
)
{
output
:=
eth
.
OutputResponse
{
Version
:
supportedL2OutputVersion
,
OutputRoot
:
eth
.
Bytes32
{},
BlockRef
:
eth
.
L2BlockRef
{},
}
challenger
:=
newTestChallenger
(
t
,
output
,
false
)
valid
,
err
:=
challenger
.
compareOutputRoots
(
&
output
,
output
.
OutputRoot
,
big
.
NewInt
(
0
))
require
.
True
(
t
,
valid
)
require
.
NoError
(
t
,
err
)
valid
,
err
=
challenger
.
compareOutputRoots
(
&
output
,
eth
.
Bytes32
{
0x01
},
big
.
NewInt
(
0
))
require
.
False
(
t
,
valid
)
require
.
NoError
(
t
,
err
)
}
func
newTestChallenger
(
t
*
testing
.
T
,
output
eth
.
OutputResponse
,
errors
bool
)
*
Challenger
{
outputApi
:=
newMockOutputApi
(
output
,
errors
)
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
metr
:=
metrics
.
NewMetrics
(
"test"
)
challenger
:=
Challenger
{
rollupClient
:
outputApi
,
log
:
log
,
metr
:
metr
,
networkTimeout
:
time
.
Duration
(
5
)
*
time
.
Second
,
}
return
&
challenger
}
var
mockOutputApiError
=
errors
.
New
(
"mock output api error"
)
type
mockOutputApi
struct
{
mock
.
Mock
expected
eth
.
OutputResponse
errors
bool
}
func
newMockOutputApi
(
output
eth
.
OutputResponse
,
errors
bool
)
*
mockOutputApi
{
return
&
mockOutputApi
{
expected
:
output
,
errors
:
errors
,
}
}
func
(
m
*
mockOutputApi
)
OutputAtBlock
(
ctx
context
.
Context
,
blockNumber
uint64
)
(
*
eth
.
OutputResponse
,
error
)
{
if
m
.
errors
{
return
nil
,
mockOutputApiError
}
return
&
m
.
expected
,
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