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
7fd54307
Unverified
Commit
7fd54307
authored
Aug 07, 2023
by
mergify[bot]
Committed by
GitHub
Aug 07, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into dependabot/go_modules/github.com/jackc/pgx/v5-5.4.3
parents
82abb67e
a6bd6942
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
145 additions
and
195 deletions
+145
-195
cli.go
indexer/cli/cli.go
+13
-9
blocks_e2e_test.go
indexer/e2e_tests/blocks_e2e_test.go
+4
-8
bridge_transfers_e2e_test.go
indexer/e2e_tests/bridge_transfers_e2e_test.go
+8
-12
indexer.go
indexer/indexer.go
+13
-4
config.go
op-chain-ops/genesis/config.go
+2
-1
agent.go
op-challenger/fault/agent.go
+14
-1
service.go
op-challenger/fault/service.go
+2
-3
solver.go
op-challenger/fault/solver/solver.go
+6
-0
deploy.go
op-e2e/e2eutils/disputegame/deploy.go
+0
-121
helper.go
op-e2e/e2eutils/disputegame/helper.go
+71
-23
faultproof_test.go
op-e2e/faultproof_test.go
+10
-11
devnetL1.json
packages/contracts-bedrock/deploy-config/devnetL1.json
+2
-2
No files found.
indexer/cli/cli.go
View file @
7fd54307
...
...
@@ -23,15 +23,16 @@ type Cli struct {
}
func
runIndexer
(
ctx
*
cli
.
Context
)
error
{
logger
:=
log
.
NewLogger
(
log
.
ReadCLIConfig
(
ctx
))
configPath
:=
ctx
.
String
(
ConfigFlag
.
Name
)
cfg
,
err
:=
config
.
LoadConfig
(
configPath
)
if
err
!=
nil
{
logger
.
Error
(
"failed to load config"
,
"err"
,
err
)
return
err
}
// setup logger
cfg
.
Logger
=
log
.
NewLogger
(
log
.
ReadCLIConfig
(
ctx
))
cfg
.
Logger
=
logger
indexer
,
err
:=
indexer
.
NewIndexer
(
cfg
)
if
err
!=
nil
{
return
err
...
...
@@ -47,17 +48,20 @@ func runIndexer(ctx *cli.Context) error {
}
func
runApi
(
ctx
*
cli
.
Context
)
error
{
configPath
:=
ctx
.
String
(
ConfigFlag
.
Name
)
conf
,
err
:=
config
.
LoadConfig
(
configPath
)
fmt
.
Println
(
conf
)
logger
:=
log
.
NewLogger
(
log
.
ReadCLIConfig
(
ctx
))
configPath
:=
ctx
.
String
(
ConfigFlag
.
Name
)
cfg
,
err
:=
config
.
LoadConfig
(
configPath
)
if
err
!=
nil
{
panic
(
err
)
logger
.
Error
(
"failed to load config"
,
"err"
,
err
)
return
err
}
cfg
.
Logger
=
logger
fmt
.
Println
(
cfg
)
// finish me
return
nil
return
err
}
var
(
...
...
indexer/e2e_tests/blocks_e2e_test.go
View file @
7fd54307
...
...
@@ -26,20 +26,16 @@ func TestE2EBlockHeaders(t *testing.T) {
l2OutputOracle
,
err
:=
bindings
.
NewL2OutputOracle
(
testSuite
.
OpCfg
.
L1Deployments
.
L2OutputOracleProxy
,
testSuite
.
L1Client
)
require
.
NoError
(
t
,
err
)
// a minute for total setup to finish
setupCtx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
time
.
Minute
)
defer
cancel
()
// wait for at least 10 L2 blocks to be created & posted on L1
require
.
NoError
(
t
,
utils
.
WaitFor
(
setupCtx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
l2Height
,
err
:=
l2OutputOracle
.
LatestBlockNumber
(
&
bind
.
CallOpts
{
Context
:
setupCtx
})
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
time
.
Second
,
func
()
(
bool
,
error
)
{
l2Height
,
err
:=
l2OutputOracle
.
LatestBlockNumber
(
&
bind
.
CallOpts
{
Context
:
context
.
Background
()
})
return
l2Height
!=
nil
&&
l2Height
.
Uint64
()
>=
9
,
err
}))
// ensure the processors are caught up to this state
l1Height
,
err
:=
testSuite
.
L1Client
.
BlockNumber
(
setupCtx
)
l1Height
,
err
:=
testSuite
.
L1Client
.
BlockNumber
(
context
.
Background
()
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
setupCtx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
time
.
Second
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
(
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
l1Height
)
&&
(
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
9
),
nil
...
...
indexer/e2e_tests/bridge_transfers_e2e_test.go
View file @
7fd54307
...
...
@@ -23,8 +23,6 @@ import (
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
)
...
...
@@ -42,14 +40,14 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
// (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
())
depositReceipt
,
err
:=
utils
.
WaitReceiptOK
(
context
.
Background
()
,
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
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
depositReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
...
...
@@ -73,9 +71,9 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
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
())
depositReceipt
,
err
=
utils
.
WaitReceiptOK
(
context
.
Background
()
,
testSuite
.
L2Client
,
types
.
NewTx
(
depositInfo
.
DepositTx
)
.
Hash
())
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
depositReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
...
...
@@ -88,8 +86,6 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
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
)
...
...
@@ -108,17 +104,17 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
l1Opts
.
Value
=
l2Opts
.
Value
depositTx
,
err
:=
optimismPortal
.
Receive
(
l1Opts
)
require
.
NoError
(
t
,
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
testCtx
,
testSuite
.
L1Client
,
depositTx
.
Hash
())
_
,
err
=
utils
.
WaitReceiptOK
(
context
.
Background
()
,
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
())
withdrawReceipt
,
err
:=
utils
.
WaitReceiptOK
(
context
.
Background
()
,
testSuite
.
L2Client
,
withdrawTx
.
Hash
())
require
.
NoError
(
t
,
err
)
// wait for processor catchup
require
.
NoError
(
t
,
utils
.
WaitFor
(
testCtx
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l2Header
:=
testSuite
.
Indexer
.
L2Processor
.
LatestProcessedHeader
()
return
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
withdrawReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
...
...
@@ -150,7 +146,7 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
// 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
)
{
require
.
NoError
(
t
,
utils
.
WaitFor
(
context
.
Background
()
,
500
*
time
.
Millisecond
,
func
()
(
bool
,
error
)
{
l1Header
:=
testSuite
.
Indexer
.
L1Processor
.
LatestProcessedHeader
()
return
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
finalizeReceipt
.
BlockNumber
.
Uint64
(),
nil
}))
...
...
indexer/indexer.go
View file @
7fd54307
...
...
@@ -72,21 +72,30 @@ func NewIndexer(cfg config.Config) (*Indexer, error) {
// Start starts the indexing service on L1 and L2 chains
func
(
i
*
Indexer
)
Run
(
ctx
context
.
Context
)
error
{
var
wg
sync
.
WaitGroup
errCh
:=
make
(
chan
error
)
errCh
:=
make
(
chan
error
,
1
)
// If either processor errors out, we stop
processorCtx
,
cancel
:=
context
.
WithCancel
(
ctx
)
run
:=
func
(
start
func
(
ctx
context
.
Context
)
error
)
{
wg
.
Add
(
1
)
defer
wg
.
Done
()
defer
func
()
{
if
err
:=
recover
();
err
!=
nil
{
i
.
log
.
Error
(
"halting indexer on panic"
,
"err"
,
err
)
errCh
<-
fmt
.
Errorf
(
"panic: %v"
,
err
)
}
wg
.
Done
()
}()
err
:=
start
(
processorCtx
)
if
err
!=
nil
{
i
.
log
.
Error
(
"halting indexer on error"
,
"err"
,
err
)
cancel
()
errCh
<-
err
}
// Send a value down regardless if we've received an error or halted
// via cancellation where err == nil
errCh
<-
err
}
// Kick off the processors
...
...
op-chain-ops/genesis/config.go
View file @
7fd54307
...
...
@@ -470,6 +470,7 @@ func NewDeployConfigWithNetwork(network, path string) (*DeployConfig, error) {
// L1Deployments represents a set of L1 contracts that are deployed.
type
L1Deployments
struct
{
AddressManager
common
.
Address
`json:"AddressManager"`
BlockOracle
common
.
Address
`json:"BlockOracle"`
DisputeGameFactory
common
.
Address
`json:"DisputeGameFactory"`
DisputeGameFactoryProxy
common
.
Address
`json:"DisputeGameFactoryProxy"`
L1CrossDomainMessenger
common
.
Address
`json:"L1CrossDomainMessenger"`
...
...
@@ -512,7 +513,7 @@ func (d *L1Deployments) Check() error {
for
i
:=
0
;
i
<
val
.
NumField
();
i
++
{
name
:=
val
.
Type
()
.
Field
(
i
)
.
Name
// Skip the non production ready contracts
if
name
==
"DisputeGameFactory"
||
name
==
"DisputeGameFactoryProxy"
{
if
name
==
"DisputeGameFactory"
||
name
==
"DisputeGameFactoryProxy"
||
name
==
"BlockOracle"
{
continue
}
if
val
.
Field
(
i
)
.
Interface
()
.
(
common
.
Address
)
==
(
common
.
Address
{})
{
...
...
op-challenger/fault/agent.go
View file @
7fd54307
...
...
@@ -23,16 +23,18 @@ type Agent struct {
solver
*
solver
.
Solver
loader
Loader
responder
Responder
updater
types
.
OracleUpdater
maxDepth
int
agreeWithProposedOutput
bool
log
log
.
Logger
}
func
NewAgent
(
loader
Loader
,
maxDepth
int
,
trace
types
.
TraceProvider
,
responder
Responder
,
agreeWithProposedOutput
bool
,
log
log
.
Logger
)
*
Agent
{
func
NewAgent
(
loader
Loader
,
maxDepth
int
,
trace
types
.
TraceProvider
,
responder
Responder
,
updater
types
.
OracleUpdater
,
agreeWithProposedOutput
bool
,
log
log
.
Logger
)
*
Agent
{
return
&
Agent
{
solver
:
solver
.
NewSolver
(
maxDepth
,
trace
),
loader
:
loader
,
responder
:
responder
,
updater
:
updater
,
maxDepth
:
maxDepth
,
agreeWithProposedOutput
:
agreeWithProposedOutput
,
log
:
log
,
...
...
@@ -132,6 +134,17 @@ func (a *Agent) step(ctx context.Context, claim types.Claim, game types.Game) er
return
nil
}
oracleData
,
err
:=
a
.
solver
.
GetOracleData
(
ctx
,
claim
)
if
err
!=
nil
{
a
.
log
.
Debug
(
"Failed to get oracle data"
,
"err"
,
err
)
return
nil
}
a
.
log
.
Info
(
"Updating oracle data"
,
"oracleKey"
,
oracleData
.
OracleKey
,
"oracleData"
,
oracleData
.
OracleData
)
if
err
:=
a
.
updater
.
UpdateOracle
(
ctx
,
*
oracleData
);
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to load oracle data: %w"
,
err
)
}
a
.
log
.
Info
(
"Attempting step"
,
"claim_depth"
,
claim
.
Depth
(),
"maxDepth"
,
a
.
maxDepth
)
step
,
err
:=
a
.
solver
.
AttemptStep
(
ctx
,
claim
,
agreeWithClaimLevel
)
if
err
!=
nil
{
...
...
op-challenger/fault/service.go
View file @
7fd54307
...
...
@@ -64,8 +64,7 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
}
// newTypedService creates a new Service from a provided trace provider.
func
newTypedService
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
,
client
*
ethclient
.
Client
,
provider
types
.
TraceProvider
,
uploader
types
.
OracleUpdater
,
txMgr
txmgr
.
TxManager
)
(
*
service
,
error
)
{
func
newTypedService
(
ctx
context
.
Context
,
logger
log
.
Logger
,
cfg
*
config
.
Config
,
client
*
ethclient
.
Client
,
provider
types
.
TraceProvider
,
updater
types
.
OracleUpdater
,
txMgr
txmgr
.
TxManager
)
(
*
service
,
error
)
{
contract
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
cfg
.
GameAddress
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault dispute game contract: %w"
,
err
)
...
...
@@ -83,7 +82,7 @@ func newTypedService(ctx context.Context, logger log.Logger, cfg *config.Config,
return
nil
,
fmt
.
Errorf
(
"failed to bind the fault contract: %w"
,
err
)
}
agent
:=
NewAgent
(
loader
,
cfg
.
GameDepth
,
provider
,
responder
,
cfg
.
AgreeWithProposedOutput
,
gameLogger
)
agent
:=
NewAgent
(
loader
,
cfg
.
GameDepth
,
provider
,
responder
,
updater
,
cfg
.
AgreeWithProposedOutput
,
gameLogger
)
return
&
service
{
agent
:
agent
,
...
...
op-challenger/fault/solver/solver.go
View file @
7fd54307
...
...
@@ -28,6 +28,12 @@ func NewSolver(gameDepth int, traceProvider types.TraceProvider) *Solver {
}
}
// GetOracleData returns the oracle data for the provided claim.
// It passes through to the [TraceProvider] by finding the trace index for the claim.
func
(
s
*
Solver
)
GetOracleData
(
ctx
context
.
Context
,
claim
types
.
Claim
)
(
*
types
.
PreimageOracleData
,
error
)
{
return
s
.
trace
.
GetOracleData
(
ctx
,
claim
.
TraceIndex
(
s
.
gameDepth
))
}
// NextMove returns the next move to make given the current state of the game.
func
(
s
*
Solver
)
NextMove
(
ctx
context
.
Context
,
claim
types
.
Claim
,
agreeWithClaimLevel
bool
)
(
*
types
.
Claim
,
error
)
{
if
agreeWithClaimLevel
{
...
...
op-e2e/e2eutils/disputegame/deploy.go
deleted
100644 → 0
View file @
82abb67e
package
disputegame
import
(
"context"
"math/big"
"time"
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-e2e/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
// deployDisputeGameContracts deploys the DisputeGameFactory, AlphabetVM and FaultDisputeGame contracts
// It configures the alphabet fault game as game type 0 (faultGameType)
// If/when the dispute game factory becomes a predeployed contract this can be removed and just use the
// predeployed version
func
deployDisputeGameContracts
(
require
*
require
.
Assertions
,
ctx
context
.
Context
,
clock
*
clock
.
AdvancingClock
,
client
*
ethclient
.
Client
,
opts
*
bind
.
TransactOpts
,
gameDuration
uint64
)
(
*
bindings
.
DisputeGameFactory
,
*
big
.
Int
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
5
*
time
.
Minute
)
defer
cancel
()
// Deploy the proxy
_
,
tx
,
proxy
,
err
:=
bindings
.
DeployProxy
(
opts
,
client
,
deployer
.
TestAddress
)
require
.
NoError
(
err
)
proxyAddr
,
err
:=
bind
.
WaitDeployed
(
ctx
,
client
,
tx
)
require
.
NoError
(
err
)
// Deploy the dispute game factory implementation
_
,
tx
,
_
,
err
=
bindings
.
DeployDisputeGameFactory
(
opts
,
client
)
require
.
NoError
(
err
)
factoryAddr
,
err
:=
bind
.
WaitDeployed
(
ctx
,
client
,
tx
)
require
.
NoError
(
err
)
// Point the proxy at the implementation and create bindings going via the proxy
disputeGameFactoryAbi
,
err
:=
bindings
.
DisputeGameFactoryMetaData
.
GetAbi
()
require
.
NoError
(
err
)
data
,
err
:=
disputeGameFactoryAbi
.
Pack
(
"initialize"
,
deployer
.
TestAddress
)
require
.
NoError
(
err
)
tx
,
err
=
proxy
.
UpgradeToAndCall
(
opts
,
factoryAddr
,
data
)
require
.
NoError
(
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
ctx
,
client
,
tx
.
Hash
())
require
.
NoError
(
err
)
factory
,
err
:=
bindings
.
NewDisputeGameFactory
(
proxyAddr
,
client
)
require
.
NoError
(
err
)
// Now setup the fault dispute game type
// Start by deploying the AlphabetVM
_
,
tx
,
_
,
err
=
bindings
.
DeployAlphabetVM
(
opts
,
client
,
alphabetVMAbsolutePrestateClaim
)
require
.
NoError
(
err
)
alphaVMAddr
,
err
:=
bind
.
WaitDeployed
(
ctx
,
client
,
tx
)
require
.
NoError
(
err
)
l2OutputOracle
,
err
:=
bindings
.
NewL2OutputOracle
(
config
.
L1Deployments
.
L2OutputOracleProxy
,
client
)
require
.
NoError
(
err
)
// Deploy the block hash oracle
_
,
tx
,
_
,
err
=
bindings
.
DeployBlockOracle
(
opts
,
client
)
require
.
NoError
(
err
)
blockHashOracleAddr
,
err
:=
bind
.
WaitDeployed
(
ctx
,
client
,
tx
)
require
.
NoError
(
err
)
blockHashOracle
,
err
:=
bindings
.
NewBlockOracle
(
blockHashOracleAddr
,
client
)
require
.
NoError
(
err
)
// Deploy the fault dispute game implementation
_
,
tx
,
_
,
err
=
bindings
.
DeployFaultDisputeGame
(
opts
,
client
,
uint8
(
0
),
alphabetVMAbsolutePrestateClaim
,
big
.
NewInt
(
alphabetGameDepth
),
gameDuration
,
alphaVMAddr
,
config
.
L1Deployments
.
L2OutputOracleProxy
,
blockHashOracleAddr
,
)
require
.
NoError
(
err
)
faultDisputeGameAddr
,
err
:=
bind
.
WaitDeployed
(
ctx
,
client
,
tx
)
require
.
NoError
(
err
)
// Create a proposer transactor
secrets
,
err
:=
e2eutils
.
DefaultMnemonicConfig
.
Secrets
()
require
.
NoError
(
err
)
chainId
,
err
:=
client
.
ChainID
(
ctx
)
require
.
NoError
(
err
)
proposerOpts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
secrets
.
Proposer
,
chainId
)
require
.
NoError
(
err
)
// Propose 2 outputs
for
i
:=
uint8
(
0
);
i
<
2
;
i
++
{
nextBlockNumber
,
err
:=
l2OutputOracle
.
NextBlockNumber
(
&
bind
.
CallOpts
{
Pending
:
true
,
Context
:
ctx
})
require
.
NoError
(
err
)
block
,
err
:=
client
.
BlockByNumber
(
ctx
,
big
.
NewInt
(
int64
(
i
)))
require
.
NoError
(
err
)
tx
,
err
=
l2OutputOracle
.
ProposeL2Output
(
proposerOpts
,
[
32
]
byte
{
i
+
1
},
nextBlockNumber
,
block
.
Hash
(),
block
.
Number
())
require
.
NoError
(
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
ctx
,
client
,
tx
.
Hash
())
require
.
NoError
(
err
)
}
// Set the fault game type implementation
tx
,
err
=
factory
.
SetImplementation
(
opts
,
faultGameType
,
faultDisputeGameAddr
)
require
.
NoError
(
err
)
_
,
err
=
utils
.
WaitReceiptOK
(
ctx
,
client
,
tx
.
Hash
())
require
.
NoError
(
err
,
"wait for final transaction to be included and OK"
)
// Warp 15 seconds ahead for a diff in the timestamp.
clock
.
AdvanceTime
(
15
*
time
.
Second
)
// Store the current block in the oracle
tx
,
err
=
blockHashOracle
.
Checkpoint
(
opts
)
require
.
NoError
(
err
)
r
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
client
,
tx
.
Hash
())
require
.
NoError
(
err
,
"failed to store block in blockoracle"
)
return
factory
,
new
(
big
.
Int
)
.
Sub
(
r
.
BlockNumber
,
big
.
NewInt
(
1
))
}
op-e2e/e2eutils/disputegame/helper.go
View file @
7fd54307
...
...
@@ -10,15 +10,14 @@ import (
"github.com/ethereum-optimism/optimism/op-bindings/bindings"
"github.com/ethereum-optimism/optimism/op-chain-ops/deployer"
"github.com/ethereum-optimism/optimism/op-chain-ops/genesis"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-challenger/fault/alphabet"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils/challenger"
"github.com/ethereum-optimism/optimism/op-service/client/utils"
"github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/stretchr/testify/require"
)
...
...
@@ -35,48 +34,90 @@ const (
StatusDefenderWins
)
var
alphabetVMAbsolutePrestate
=
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000060"
)
var
alphabetVMAbsolutePrestateClaim
=
crypto
.
Keccak256Hash
(
alphabetVMAbsolutePrestate
)
func
(
s
Status
)
String
()
string
{
switch
s
{
case
StatusInProgress
:
return
"In Progress"
case
StatusChallengerWins
:
return
"Challenger Wins"
case
StatusDefenderWins
:
return
"Defender Wins"
default
:
return
fmt
.
Sprintf
(
"Unknown status: %v"
,
int
(
s
))
}
}
var
CorrectAlphabet
=
"abcdefghijklmnop"
type
FactoryHelper
struct
{
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
factory
*
bindings
.
DisputeGameFactory
l1Head
*
big
.
Int
t
*
testing
.
T
require
*
require
.
Assertions
client
*
ethclient
.
Client
opts
*
bind
.
TransactOpts
factory
*
bindings
.
DisputeGameFactory
blockOracle
*
bindings
.
BlockOracle
l2oo
*
bindings
.
L2OutputOracleCaller
}
func
NewFactoryHelper
(
t
*
testing
.
T
,
ctx
context
.
Context
,
clock
*
clock
.
AdvancingClock
,
client
*
ethclient
.
Client
,
gameDuration
uint64
)
*
FactoryHelper
{
func
NewFactoryHelper
(
t
*
testing
.
T
,
ctx
context
.
Context
,
deployments
*
genesis
.
L1Deployments
,
client
*
ethclient
.
Client
)
*
FactoryHelper
{
require
:=
require
.
New
(
t
)
chainID
,
err
:=
client
.
ChainID
(
ctx
)
require
.
NoError
(
err
)
opts
,
err
:=
bind
.
NewKeyedTransactorWithChainID
(
deployer
.
TestKey
,
chainID
)
require
.
NoError
(
err
)
factory
,
l1Head
:=
deployDisputeGameContracts
(
require
,
ctx
,
clock
,
client
,
opts
,
gameDuration
)
require
.
NotNil
(
deployments
,
"No deployments"
)
factory
,
err
:=
bindings
.
NewDisputeGameFactory
(
deployments
.
DisputeGameFactoryProxy
,
client
)
require
.
NoError
(
err
)
blockOracle
,
err
:=
bindings
.
NewBlockOracle
(
deployments
.
BlockOracle
,
client
)
require
.
NoError
(
err
)
l2oo
,
err
:=
bindings
.
NewL2OutputOracleCaller
(
deployments
.
L2OutputOracleProxy
,
client
)
require
.
NoError
(
err
,
"Error creating l2oo caller"
)
//factory, l1Head := deployDisputeGameContracts(require, ctx, clock, client, opts, gameDuration)
return
&
FactoryHelper
{
t
:
t
,
require
:
require
,
client
:
client
,
opts
:
opts
,
factory
:
factory
,
l1Head
:
l1Head
,
t
:
t
,
require
:
require
,
client
:
client
,
opts
:
opts
,
factory
:
factory
,
blockOracle
:
blockOracle
,
l2oo
:
l2oo
,
}
}
func
(
h
*
FactoryHelper
)
StartAlphabetGame
(
ctx
context
.
Context
,
claimedAlphabet
string
)
*
FaultGameHelper
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
// Wait for two output proposals to be published
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
2
*
time
.
Minute
)
defer
cancel
()
trace
:=
alphabet
.
NewTraceProvider
(
claimedAlphabet
,
4
)
err
:=
utils
.
WaitFor
(
ctx
,
time
.
Second
,
func
()
(
bool
,
error
)
{
index
,
err
:=
h
.
l2oo
.
LatestOutputIndex
(
&
bind
.
CallOpts
{
Context
:
ctx
})
if
err
!=
nil
{
h
.
t
.
Logf
(
"Could not get latest output index: %v"
,
err
.
Error
())
return
false
,
nil
}
h
.
t
.
Logf
(
"Latest output index: %v"
,
index
)
return
index
.
Cmp
(
big
.
NewInt
(
1
))
>=
0
,
nil
})
h
.
require
.
NoError
(
err
,
"Did not get two output roots"
)
ctx
,
cancel
=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
// Store the current block in the oracle
tx
,
err
:=
h
.
blockOracle
.
Checkpoint
(
h
.
opts
)
h
.
require
.
NoError
(
err
)
r
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"failed to store block in blockoracle"
)
l1Head
:=
new
(
big
.
Int
)
.
Sub
(
r
.
BlockNumber
,
big
.
NewInt
(
1
))
trace
:=
alphabet
.
NewTraceProvider
(
claimedAlphabet
,
alphabetGameDepth
)
rootClaim
,
err
:=
trace
.
Get
(
ctx
,
lastAlphabetTraceIndex
)
h
.
require
.
NoError
(
err
,
"get root claim"
)
extraData
:=
make
([]
byte
,
64
)
binary
.
BigEndian
.
PutUint64
(
extraData
[
24
:
],
uint64
(
8
))
binary
.
BigEndian
.
PutUint64
(
extraData
[
56
:
],
h
.
l1Head
.
Uint64
())
tx
,
err
:
=
h
.
factory
.
Create
(
h
.
opts
,
faultGameType
,
rootClaim
,
extraData
)
binary
.
BigEndian
.
PutUint64
(
extraData
[
56
:
],
l1Head
.
Uint64
())
tx
,
err
=
h
.
factory
.
Create
(
h
.
opts
,
faultGameType
,
rootClaim
,
extraData
)
h
.
require
.
NoError
(
err
,
"create fault dispute game"
)
rcpt
,
err
:=
utils
.
WaitReceiptOK
(
ctx
,
h
.
client
,
tx
.
Hash
())
h
.
require
.
NoError
(
err
,
"wait for create fault dispute game receipt to be OK"
)
...
...
@@ -128,6 +169,12 @@ func (g *FaultGameHelper) StartChallenger(ctx context.Context, l1Endpoint string
return
c
}
func
(
g
*
FaultGameHelper
)
GameDuration
(
ctx
context
.
Context
)
time
.
Duration
{
duration
,
err
:=
g
.
game
.
GAMEDURATION
(
&
bind
.
CallOpts
{
Context
:
ctx
})
g
.
require
.
NoError
(
err
,
"failed to get game duration"
)
return
time
.
Duration
(
duration
)
*
time
.
Second
}
func
(
g
*
FaultGameHelper
)
WaitForClaimCount
(
ctx
context
.
Context
,
count
int64
)
{
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
...
...
@@ -190,6 +237,7 @@ func (g *FaultGameHelper) Resolve(ctx context.Context) {
}
func
(
g
*
FaultGameHelper
)
WaitForGameStatus
(
ctx
context
.
Context
,
expected
Status
)
{
g
.
t
.
Logf
(
"Waiting for game %v to have status %v"
,
g
.
addr
,
expected
)
ctx
,
cancel
:=
context
.
WithTimeout
(
ctx
,
1
*
time
.
Minute
)
defer
cancel
()
err
:=
utils
.
WaitFor
(
ctx
,
1
*
time
.
Second
,
func
()
(
bool
,
error
)
{
...
...
@@ -199,7 +247,7 @@ func (g *FaultGameHelper) WaitForGameStatus(ctx context.Context, expected Status
if
err
!=
nil
{
return
false
,
fmt
.
Errorf
(
"game status unavailable: %w"
,
err
)
}
g
.
t
.
Logf
(
"Game %v has state %v, waiting for state %v"
,
g
.
addr
,
Status
(
status
),
expected
)
return
expected
==
Status
(
status
),
nil
})
g
.
require
.
NoError
(
err
,
"wait for game status"
)
...
...
op-e2e/faultproof_test.go
View file @
7fd54307
...
...
@@ -3,7 +3,6 @@ package op_e2e
import
(
"context"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-e2e/e2eutils"
...
...
@@ -17,13 +16,13 @@ func TestResolveDisputeGame(t *testing.T) {
InitParallel
(
t
)
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
start
L1Only
System
(
t
)
sys
,
l1Client
:=
start
FaultDispute
System
(
t
)
t
.
Cleanup
(
sys
.
Close
)
gameDuration
:=
24
*
time
.
Hour
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
TimeTravelClock
,
l1Client
,
uint64
(
gameDuration
.
Seconds
()))
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
game
:=
disputeGameFactory
.
StartAlphabetGame
(
ctx
,
"zyxwvut"
)
require
.
NotNil
(
t
,
game
)
gameDuration
:=
game
.
GameDuration
(
ctx
)
game
.
WaitForGameStatus
(
ctx
,
disputegame
.
StatusInProgress
)
...
...
@@ -115,13 +114,13 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
InitParallel
(
t
)
ctx
:=
context
.
Background
()
sys
,
l1Client
:=
start
L1Only
System
(
t
)
sys
,
l1Client
:=
start
FaultDispute
System
(
t
)
t
.
Cleanup
(
sys
.
Close
)
gameDuration
:=
24
*
time
.
Hour
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
TimeTravelClock
,
l1Client
,
uint64
(
gameDuration
.
Seconds
()))
disputeGameFactory
:=
disputegame
.
NewFactoryHelper
(
t
,
ctx
,
sys
.
cfg
.
L1Deployments
,
l1Client
)
game
:=
disputeGameFactory
.
StartAlphabetGame
(
ctx
,
test
.
rootClaimAlphabet
)
require
.
NotNil
(
t
,
game
)
gameDuration
:=
game
.
GameDuration
(
ctx
)
game
.
StartChallenger
(
ctx
,
sys
.
NodeEndpoint
(
"l1"
),
"Defender"
,
func
(
c
*
config
.
Config
)
{
c
.
TxMgrConfig
.
PrivateKey
=
e2eutils
.
EncodePrivKeyToString
(
sys
.
cfg
.
Secrets
.
Mallory
)
...
...
@@ -144,13 +143,13 @@ func TestChallengerCompleteDisputeGame(t *testing.T) {
}
}
func
start
L1Only
System
(
t
*
testing
.
T
)
(
*
System
,
*
ethclient
.
Client
)
{
func
start
FaultDispute
System
(
t
*
testing
.
T
)
(
*
System
,
*
ethclient
.
Client
)
{
cfg
:=
DefaultSystemConfig
(
t
)
cfg
.
DeployConfig
.
L1BlockTime
=
1
delete
(
cfg
.
Nodes
,
"verifier"
)
delete
(
cfg
.
Nodes
,
"sequencer"
)
cfg
.
SupportL1TimeTravel
=
true
cfg
.
DeployConfig
.
L2OutputOracleSubmissionInterval
=
2
cfg
.
NonFinalizedProposals
=
true
// Submit output proposals asap
sys
,
err
:=
cfg
.
Start
()
require
.
N
il
(
t
,
err
,
"Error starting up system"
)
require
.
N
oError
(
t
,
err
,
"Error starting up system"
)
return
sys
,
sys
.
Clients
[
"l1"
]
}
packages/contracts-bedrock/deploy-config/devnetL1.json
View file @
7fd54307
...
...
@@ -43,7 +43,7 @@
"eip1559Elasticity"
:
6
,
"l1GenesisBlockTimestamp"
:
"0x64c811bf"
,
"l2GenesisRegolithTimeOffset"
:
"0x0"
,
"faultGameAbsolutePrestate"
:
96
,
"faultGameAbsolutePrestate"
:
"0x41c7ae758795765c6664a5d39bf63841c71ff191e9189522bad8ebff5d4eca98"
,
"faultGameMaxDepth"
:
4
,
"faultGameMaxDuration"
:
12
0
"faultGameMaxDuration"
:
30
0
}
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