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
a145e096
Unverified
Commit
a145e096
authored
Aug 23, 2023
by
mergify[bot]
Committed by
GitHub
Aug 23, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into dependabot/npm_and_yarn/eslint-plugin-prettier-4.2.1
parents
fd71b159
2963dd94
Changes
41
Hide whitespace changes
Inline
Side-by-side
Showing
41 changed files
with
776 additions
and
459 deletions
+776
-459
deposits.go
indexer/api/routes/deposits.go
+1
-1
withdrawals.go
indexer/api/routes/withdrawals.go
+1
-1
blocks.go
indexer/database/blocks.go
+5
-5
bridge_messages.go
indexer/database/bridge_messages.go
+3
-2
bridge_transactions.go
indexer/database/bridge_transactions.go
+6
-5
u256.go
indexer/database/serializers/u256.go
+60
-0
types.go
indexer/database/types.go
+5
-59
bridge_messages_e2e_test.go
indexer/e2e_tests/bridge_messages_e2e_test.go
+6
-6
bridge_transactions_e2e_test.go
indexer/e2e_tests/bridge_transactions_e2e_test.go
+5
-5
bridge_transfers_e2e_test.go
indexer/e2e_tests/bridge_transfers_e2e_test.go
+4
-4
etl_e2e_test.go
indexer/e2e_tests/etl_e2e_test.go
+5
-5
l1_etl.go
indexer/etl/l1_etl.go
+1
-1
l2_etl.go
indexer/etl/l2_etl.go
+1
-1
bridge.go
indexer/processors/bridge.go
+1
-1
cross_domain_messenger.go
indexer/processors/contracts/cross_domain_messenger.go
+3
-3
l2_to_l1_message_passer.go
indexer/processors/contracts/l2_to_l1_message_passer.go
+5
-5
optimism_portal.go
indexer/processors/contracts/optimism_portal.go
+3
-3
standard_bridge.go
indexer/processors/contracts/standard_bridge.go
+2
-2
main_test.go
op-challenger/cmd/main_test.go
+18
-0
config.go
op-challenger/config/config.go
+12
-3
abi_test.go
op-challenger/fault/abi_test.go
+3
-3
agent.go
op-challenger/fault/agent.go
+19
-2
agent_test.go
op-challenger/fault/agent_test.go
+31
-0
caller.go
op-challenger/fault/caller.go
+1
-2
provider.go
op-challenger/fault/cannon/provider.go
+4
-0
provider_test.go
op-challenger/fault/cannon/provider_test.go
+8
-0
factory.go
op-challenger/fault/factory.go
+11
-6
factory_test.go
op-challenger/fault/factory_test.go
+11
-8
monitor.go
op-challenger/fault/monitor.go
+37
-4
monitor_test.go
op-challenger/fault/monitor_test.go
+102
-5
player.go
op-challenger/fault/player.go
+22
-4
player_test.go
op-challenger/fault/player_test.go
+60
-28
responder.go
op-challenger/fault/responder.go
+13
-6
responder_test.go
op-challenger/fault/responder_test.go
+135
-137
service.go
op-challenger/fault/service.go
+1
-1
types.go
op-challenger/fault/types/types.go
+9
-0
types_test.go
op-challenger/fault/types/types_test.go
+23
-0
flags.go
op-challenger/flags/flags.go
+8
-0
package.json
package.json
+1
-1
package.json
packages/contracts-bedrock/package.json
+1
-1
pnpm-lock.yaml
pnpm-lock.yaml
+129
-139
No files found.
indexer/api/routes/deposits.go
View file @
a145e096
...
...
@@ -46,7 +46,7 @@ func newDepositResponse(deposits *database.L1BridgeDepositsResponse) DepositResp
},
From
:
deposit
.
L1BridgeDeposit
.
Tx
.
FromAddress
.
String
(),
To
:
deposit
.
L1BridgeDeposit
.
Tx
.
ToAddress
.
String
(),
Amount
:
deposit
.
L1BridgeDeposit
.
Tx
.
Amount
.
Int
.
String
(),
Amount
:
deposit
.
L1BridgeDeposit
.
Tx
.
Amount
.
String
(),
L1Token
:
TokenInfo
{
ChainId
:
1
,
Address
:
deposit
.
L1BridgeDeposit
.
TokenPair
.
LocalTokenAddress
.
String
(),
...
...
indexer/api/routes/withdrawals.go
View file @
a145e096
...
...
@@ -60,7 +60,7 @@ func newWithdrawalResponse(withdrawals *database.L2BridgeWithdrawalsResponse) Wi
From
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
FromAddress
.
String
(),
To
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
ToAddress
.
String
(),
TransactionHash
:
withdrawal
.
L2TransactionHash
.
String
(),
Amount
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Amount
.
Int
.
String
(),
Amount
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Amount
.
String
(),
Proof
:
Proof
{
TransactionHash
:
withdrawal
.
ProvenL1TransactionHash
.
String
(),
BlockTimestamp
:
withdrawal
.
L2BridgeWithdrawal
.
Tx
.
Timestamp
,
...
...
indexer/database/blocks.go
View file @
a145e096
...
...
@@ -20,7 +20,7 @@ import (
type
BlockHeader
struct
{
Hash
common
.
Hash
`gorm:"primaryKey;serializer:bytes"`
ParentHash
common
.
Hash
`gorm:"serializer:bytes"`
Number
U256
Number
*
big
.
Int
`gorm:"serializer:u256"`
Timestamp
uint64
RLPHeader
*
RLPHeader
`gorm:"serializer:rlp;column:rlp_bytes"`
...
...
@@ -30,7 +30,7 @@ func BlockHeaderFromHeader(header *types.Header) BlockHeader {
return
BlockHeader
{
Hash
:
header
.
Hash
(),
ParentHash
:
header
.
ParentHash
,
Number
:
U256
{
Int
:
header
.
Number
}
,
Number
:
header
.
Number
,
Timestamp
:
header
.
Time
,
RLPHeader
:
(
*
RLPHeader
)(
header
),
...
...
@@ -58,8 +58,8 @@ type LegacyStateBatch struct {
type
OutputProposal
struct
{
OutputRoot
common
.
Hash
`gorm:"primaryKey;serializer:bytes"`
L2OutputIndex
U256
L2BlockNumber
U256
L2OutputIndex
*
big
.
Int
`gorm:"serializer:u256"`
L2BlockNumber
*
big
.
Int
`gorm:"serializer:u256"`
L1ContractEventGUID
uuid
.
UUID
}
...
...
@@ -165,7 +165,7 @@ func (db *blocksDB) LatestCheckpointedOutput() (*OutputProposal, error) {
func
(
db
*
blocksDB
)
OutputProposal
(
index
*
big
.
Int
)
(
*
OutputProposal
,
error
)
{
var
outputProposal
OutputProposal
result
:=
db
.
gorm
.
Where
(
&
OutputProposal
{
L2OutputIndex
:
U256
{
Int
:
index
}
})
.
Take
(
&
outputProposal
)
result
:=
db
.
gorm
.
Where
(
&
OutputProposal
{
L2OutputIndex
:
index
})
.
Take
(
&
outputProposal
)
if
result
.
Error
!=
nil
{
if
errors
.
Is
(
result
.
Error
,
gorm
.
ErrRecordNotFound
)
{
return
nil
,
nil
...
...
indexer/database/bridge_messages.go
View file @
a145e096
...
...
@@ -3,6 +3,7 @@ package database
import
(
"errors"
"fmt"
"math/big"
"gorm.io/gorm"
...
...
@@ -17,13 +18,13 @@ import (
type
BridgeMessage
struct
{
MessageHash
common
.
Hash
`gorm:"primaryKey;serializer:bytes"`
Nonce
U256
Nonce
*
big
.
Int
`gorm:"serializer:u256"`
SentMessageEventGUID
uuid
.
UUID
RelayedMessageEventGUID
*
uuid
.
UUID
Tx
Transaction
`gorm:"embedded"`
GasLimit
U256
GasLimit
*
big
.
Int
`gorm:"serializer:u256"`
}
type
L1BridgeMessage
struct
{
...
...
indexer/database/bridge_transactions.go
View file @
a145e096
...
...
@@ -3,6 +3,7 @@ package database
import
(
"errors"
"fmt"
"math/big"
"github.com/google/uuid"
"gorm.io/gorm"
...
...
@@ -17,8 +18,8 @@ import (
type
Transaction
struct
{
FromAddress
common
.
Address
`gorm:"serializer:bytes"`
ToAddress
common
.
Address
`gorm:"serializer:bytes"`
Amount
U256
Data
Bytes
`gorm:"serializer:bytes"`
Amount
*
big
.
Int
`gorm:"serializer:u256"`
Data
Bytes
`gorm:"serializer:bytes"`
Timestamp
uint64
}
...
...
@@ -28,12 +29,12 @@ type L1TransactionDeposit struct {
InitiatedL1EventGUID
uuid
.
UUID
Tx
Transaction
`gorm:"embedded"`
GasLimit
U256
GasLimit
*
big
.
Int
`gorm:"serializer:u256"`
}
type
L2TransactionWithdrawal
struct
{
WithdrawalHash
common
.
Hash
`gorm:"serializer:bytes;primaryKey"`
Nonce
U256
Nonce
*
big
.
Int
`gorm:"serializer:u256"`
InitiatedL2EventGUID
uuid
.
UUID
ProvenL1EventGUID
*
uuid
.
UUID
...
...
@@ -41,7 +42,7 @@ type L2TransactionWithdrawal struct {
Succeeded
*
bool
Tx
Transaction
`gorm:"embedded"`
GasLimit
U256
GasLimit
*
big
.
Int
`gorm:"serializer:u256"`
}
type
BridgeTransactionsView
interface
{
...
...
indexer/database/serializers/u256.go
0 → 100644
View file @
a145e096
package
serializers
import
(
"context"
"fmt"
"math/big"
"reflect"
"github.com/jackc/pgtype"
"gorm.io/gorm/schema"
)
var
(
big10
=
big
.
NewInt
(
10
)
u256BigIntOverflow
=
new
(
big
.
Int
)
.
Exp
(
big
.
NewInt
(
2
),
big
.
NewInt
(
256
),
nil
)
)
type
U256Serializer
struct
{}
func
init
()
{
schema
.
RegisterSerializer
(
"u256"
,
U256Serializer
{})
}
func
(
U256Serializer
)
Scan
(
ctx
context
.
Context
,
field
*
schema
.
Field
,
dst
reflect
.
Value
,
dbValue
interface
{})
error
{
if
dbValue
==
nil
{
return
nil
}
else
if
field
.
FieldType
!=
reflect
.
TypeOf
((
*
big
.
Int
)(
nil
))
{
return
fmt
.
Errorf
(
"can only deserialize into a *big.Int: %T"
,
field
.
FieldType
)
}
numeric
:=
new
(
pgtype
.
Numeric
)
err
:=
numeric
.
Scan
(
dbValue
)
if
err
!=
nil
{
return
err
}
bigInt
:=
numeric
.
Int
if
numeric
.
Exp
>
0
{
factor
:=
new
(
big
.
Int
)
.
Exp
(
big10
,
big
.
NewInt
(
int64
(
numeric
.
Exp
)),
nil
)
bigInt
.
Mul
(
bigInt
,
factor
)
}
if
bigInt
.
Cmp
(
u256BigIntOverflow
)
>=
0
{
return
fmt
.
Errorf
(
"deserialized number larger than u256 can hold: %s"
,
bigInt
)
}
field
.
ReflectValueOf
(
ctx
,
dst
)
.
Set
(
reflect
.
ValueOf
(
bigInt
))
return
nil
}
func
(
U256Serializer
)
Value
(
ctx
context
.
Context
,
field
*
schema
.
Field
,
dst
reflect
.
Value
,
fieldValue
interface
{})
(
interface
{},
error
)
{
if
fieldValue
==
nil
||
(
field
.
FieldType
.
Kind
()
==
reflect
.
Pointer
&&
reflect
.
ValueOf
(
fieldValue
)
.
IsNil
())
{
return
nil
,
nil
}
else
if
field
.
FieldType
!=
reflect
.
TypeOf
((
*
big
.
Int
)(
nil
))
{
return
nil
,
fmt
.
Errorf
(
"can only serialize a *big.Int: %T"
,
field
.
FieldType
)
}
numeric
:=
pgtype
.
Numeric
{
Int
:
fieldValue
.
(
*
big
.
Int
),
Status
:
pgtype
.
Present
}
return
numeric
.
Value
()
}
indexer/database/types.go
View file @
a145e096
package
database
import
(
"database/sql/driver"
"errors"
"io"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
"github.com/jackc/pgtype"
)
var
u256BigIntOverflow
=
new
(
big
.
Int
)
.
Exp
(
big
.
NewInt
(
2
),
big
.
NewInt
(
256
),
nil
)
var
big10
=
big
.
NewInt
(
10
)
var
ErrU256Overflow
=
errors
.
New
(
"number exceeds u256"
)
var
ErrU256ContainsDecimal
=
errors
.
New
(
"number contains fractional digits"
)
var
ErrU256Null
=
errors
.
New
(
"number cannot be null"
)
// U256 is a wrapper over big.Int that conforms to the database U256 numeric domain type
type
U256
struct
{
Int
*
big
.
Int
}
// Scan implements the database/sql Scanner interface.
func
(
u256
*
U256
)
Scan
(
src
interface
{})
error
{
// deserialize as a numeric
var
numeric
pgtype
.
Numeric
err
:=
numeric
.
Scan
(
src
)
if
err
!=
nil
{
return
err
}
else
if
numeric
.
Exp
<
0
{
return
ErrU256ContainsDecimal
}
else
if
numeric
.
Status
==
pgtype
.
Null
{
return
ErrU256Null
}
// factor in the powers of 10
num
:=
numeric
.
Int
if
numeric
.
Exp
>
0
{
factor
:=
new
(
big
.
Int
)
.
Exp
(
big10
,
big
.
NewInt
(
int64
(
numeric
.
Exp
)),
nil
)
num
.
Mul
(
num
,
factor
)
}
// check bounds before setting the u256
if
num
.
Cmp
(
u256BigIntOverflow
)
>=
0
{
return
ErrU256Overflow
}
else
{
u256
.
Int
=
num
}
return
nil
}
// Value implements the database/sql/driver Valuer interface.
func
(
u256
U256
)
Value
()
(
driver
.
Value
,
error
)
{
// check bounds
if
u256
.
Int
==
nil
{
return
nil
,
ErrU256Null
}
else
if
u256
.
Int
.
Cmp
(
u256BigIntOverflow
)
>=
0
{
return
nil
,
ErrU256Overflow
}
// simply encode as a numeric with no Exp set (non-decimal)
numeric
:=
pgtype
.
Numeric
{
Int
:
u256
.
Int
,
Status
:
pgtype
.
Present
}
return
numeric
.
Value
()
}
// Wrapper over types.Header such that we can get an RLP
// encoder over it via a `types.Block` wrapper
type
RLPHeader
types
.
Header
...
...
@@ -94,6 +37,9 @@ func (h *RLPHeader) Hash() common.Hash {
return
h
.
Header
()
.
Hash
()
}
// Type definition for []byte to conform to the
// interface expected by the `bytes` serializer
type
Bytes
[]
byte
func
(
b
Bytes
)
Bytes
()
[]
byte
{
...
...
indexer/e2e_tests/bridge_messages_e2e_test.go
View file @
a145e096
...
...
@@ -59,9 +59,9 @@ func TestE2EBridgeL1CrossDomainMessenger(t *testing.T) {
require
.
NotNil
(
t
,
sentMessage
)
require
.
NotNil
(
t
,
sentMessage
.
SentMessageEventGUID
)
require
.
Equal
(
t
,
depositInfo
.
DepositTx
.
SourceHash
,
sentMessage
.
TransactionSourceHash
)
require
.
Equal
(
t
,
nonce
.
Uint64
(),
sentMessage
.
Nonce
.
Int
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
100
_000
),
sentMessage
.
GasLimit
.
Int
.
Uint64
())
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
sentMessage
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
nonce
.
Uint64
(),
sentMessage
.
Nonce
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
100
_000
),
sentMessage
.
GasLimit
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
sentMessage
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
sentMessage
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
sentMessage
.
Tx
.
ToAddress
)
require
.
ElementsMatch
(
t
,
calldata
,
sentMessage
.
Tx
.
Data
)
...
...
@@ -146,9 +146,9 @@ func TestE2EBridgeL2CrossDomainMessenger(t *testing.T) {
require
.
NotNil
(
t
,
sentMessage
)
require
.
NotNil
(
t
,
sentMessage
.
SentMessageEventGUID
)
require
.
Equal
(
t
,
withdrawalHash
,
sentMessage
.
TransactionWithdrawalHash
)
require
.
Equal
(
t
,
nonce
.
Uint64
(),
sentMessage
.
Nonce
.
Int
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
100
_000
),
sentMessage
.
GasLimit
.
Int
.
Uint64
())
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
sentMessage
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
nonce
.
Uint64
(),
sentMessage
.
Nonce
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
100
_000
),
sentMessage
.
GasLimit
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
sentMessage
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
sentMessage
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
sentMessage
.
Tx
.
ToAddress
)
require
.
ElementsMatch
(
t
,
calldata
,
sentMessage
.
Tx
.
Data
)
...
...
indexer/e2e_tests/bridge_transactions_e2e_test.go
View file @
a145e096
...
...
@@ -54,8 +54,8 @@ func TestE2EBridgeTransactionsOptimismPortalDeposits(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
deposit
)
require
.
Equal
(
t
,
depositL2TxHash
,
deposit
.
L2TransactionHash
)
require
.
Equal
(
t
,
big
.
NewInt
(
100
_000
),
deposit
.
GasLimit
.
Int
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
uint64
(
100
_000
),
deposit
.
GasLimit
.
Uint64
()
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
ToAddress
)
require
.
ElementsMatch
(
t
,
calldata
,
deposit
.
Tx
.
Data
)
...
...
@@ -113,9 +113,9 @@ func TestE2EBridgeTransactionsL2ToL1MessagePasserWithdrawal(t *testing.T) {
withdraw
,
err
:=
testSuite
.
DB
.
BridgeTransactions
.
L2TransactionWithdrawal
(
withdrawalHash
)
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
withdraw
)
require
.
Equal
(
t
,
msgPassed
.
Nonce
.
Uint64
(),
withdraw
.
Nonce
.
Int
.
Uint64
())
require
.
Equal
(
t
,
big
.
NewInt
(
100
_000
),
withdraw
.
GasLimit
.
Int
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
withdraw
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
msgPassed
.
Nonce
.
Uint64
(),
withdraw
.
Nonce
.
Uint64
())
require
.
Equal
(
t
,
uint64
(
100
_000
),
withdraw
.
GasLimit
.
Uint64
()
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
withdraw
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
withdraw
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
withdraw
.
Tx
.
ToAddress
)
require
.
ElementsMatch
(
t
,
calldata
,
withdraw
.
Tx
.
Data
)
...
...
indexer/e2e_tests/bridge_transfers_e2e_test.go
View file @
a145e096
...
...
@@ -63,7 +63,7 @@ func TestE2EBridgeTransfersStandardBridgeETHDeposit(t *testing.T) {
require
.
Equal
(
t
,
depositInfo
.
DepositTx
.
SourceHash
,
deposit
.
TransactionSourceHash
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
LocalTokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
RemoteTokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
deposit
.
Tx
.
Data
[
0
])
...
...
@@ -235,7 +235,7 @@ func TestE2EBridgeTransfersOptimismPortalETHReceive(t *testing.T) {
require
.
Equal
(
t
,
depositInfo
.
DepositTx
.
SourceHash
,
deposit
.
TransactionSourceHash
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
LocalTokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
deposit
.
TokenPair
.
RemoteTokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
deposit
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
deposit
.
Tx
.
ToAddress
)
require
.
Len
(
t
,
deposit
.
Tx
.
Data
,
0
)
...
...
@@ -306,7 +306,7 @@ func TestE2EBridgeTransfersStandardBridgeETHWithdrawal(t *testing.T) {
require
.
Equal
(
t
,
withdrawalHash
,
withdrawal
.
TransactionWithdrawalHash
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
LocalTokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
RemoteTokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
ToAddress
)
require
.
Equal
(
t
,
byte
(
1
),
withdrawal
.
Tx
.
Data
[
0
])
...
...
@@ -390,7 +390,7 @@ func TestE2EBridgeTransfersL2ToL1MessagePasserETHReceive(t *testing.T) {
require
.
Equal
(
t
,
withdrawalHash
,
withdrawal
.
TransactionWithdrawalHash
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
LocalTokenAddress
)
require
.
Equal
(
t
,
predeploys
.
LegacyERC20ETHAddr
,
withdrawal
.
TokenPair
.
RemoteTokenAddress
)
require
.
Equal
(
t
,
big
.
NewInt
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Int
)
require
.
Equal
(
t
,
uint64
(
params
.
Ether
),
withdrawal
.
Tx
.
Amount
.
Uint64
()
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
FromAddress
)
require
.
Equal
(
t
,
aliceAddr
,
withdrawal
.
Tx
.
ToAddress
)
require
.
Len
(
t
,
withdrawal
.
Tx
.
Data
,
0
)
...
...
indexer/e2e_tests/etl_e2e_test.go
View file @
a145e096
...
...
@@ -40,19 +40,19 @@ func TestE2EETL(t *testing.T) {
l2Header
,
err
:=
testSuite
.
DB
.
Blocks
.
L2LatestBlockHeader
()
require
.
NoError
(
t
,
err
)
return
(
l1Header
!=
nil
&&
l1Header
.
Number
.
Int
.
Uint64
()
>=
l1Height
)
&&
(
l2Header
!=
nil
&&
l2Header
.
Number
.
Int
.
Uint64
()
>=
9
),
nil
return
(
l1Header
!=
nil
&&
l1Header
.
Number
.
Uint64
()
>=
l1Height
)
&&
(
l2Header
!=
nil
&&
l2Header
.
Number
.
Uint64
()
>=
9
),
nil
}))
t
.
Run
(
"indexes all L2 blocks"
,
func
(
t
*
testing
.
T
)
{
latestL2Header
,
err
:=
testSuite
.
DB
.
Blocks
.
L2LatestBlockHeader
()
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
latestL2Header
)
require
.
True
(
t
,
latestL2Header
.
Number
.
Int
.
Uint64
()
>=
9
)
require
.
True
(
t
,
latestL2Header
.
Number
.
Uint64
()
>=
9
)
for
i
:=
int64
(
0
);
i
<
10
;
i
++
{
height
:=
big
.
NewInt
(
i
)
indexedHeader
,
err
:=
testSuite
.
DB
.
Blocks
.
L2BlockHeaderWithFilter
(
database
.
BlockHeader
{
Number
:
database
.
U256
{
Int
:
height
}
})
indexedHeader
,
err
:=
testSuite
.
DB
.
Blocks
.
L2BlockHeaderWithFilter
(
database
.
BlockHeader
{
Number
:
height
})
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
indexedHeader
)
...
...
@@ -60,7 +60,7 @@ func TestE2EETL(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NotNil
(
t
,
indexedHeader
)
require
.
Equal
(
t
,
header
.
Number
.
Int64
(),
indexedHeader
.
Number
.
Int
.
Int
64
())
require
.
Equal
(
t
,
header
.
Number
.
Int64
(),
indexedHeader
.
Number
.
Int64
())
require
.
Equal
(
t
,
header
.
Hash
(),
indexedHeader
.
Hash
)
require
.
Equal
(
t
,
header
.
ParentHash
,
indexedHeader
.
ParentHash
)
require
.
Equal
(
t
,
header
.
Time
,
indexedHeader
.
Timestamp
)
...
...
@@ -144,7 +144,7 @@ func TestE2EETL(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
block
.
Hash
(),
l1BlockHeader
.
Hash
)
require
.
Equal
(
t
,
block
.
ParentHash
(),
l1BlockHeader
.
ParentHash
)
require
.
Equal
(
t
,
block
.
Number
()
,
l1BlockHeader
.
Number
.
Int
)
require
.
Equal
(
t
,
block
.
Number
()
.
Uint64
(),
l1BlockHeader
.
Number
.
Uint64
()
)
require
.
Equal
(
t
,
block
.
Time
(),
l1BlockHeader
.
Timestamp
)
// ensure the right rlp encoding is stored. checking the hashes
...
...
indexer/etl/l1_etl.go
View file @
a145e096
...
...
@@ -38,7 +38,7 @@ func NewL1ETL(log log.Logger, db *database.DB, client node.EthClient, startHeigh
// Determine the starting height for traversal
var
fromHeader
*
types
.
Header
if
latestHeader
!=
nil
{
log
.
Info
(
"detected last indexed block"
,
"number"
,
latestHeader
.
Number
.
Int
,
"hash"
,
latestHeader
.
Hash
)
log
.
Info
(
"detected last indexed block"
,
"number"
,
latestHeader
.
Number
,
"hash"
,
latestHeader
.
Hash
)
fromHeader
=
latestHeader
.
RLPHeader
.
Header
()
}
else
if
startHeight
.
BitLen
()
>
0
{
...
...
indexer/etl/l2_etl.go
View file @
a145e096
...
...
@@ -35,7 +35,7 @@ func NewL2ETL(log log.Logger, db *database.DB, client node.EthClient) (*L2ETL, e
var
fromHeader
*
types
.
Header
if
latestHeader
!=
nil
{
log
.
Info
(
"detected last indexed block"
,
"number"
,
latestHeader
.
Number
.
Int
,
"hash"
,
latestHeader
.
Hash
)
log
.
Info
(
"detected last indexed block"
,
"number"
,
latestHeader
.
Number
,
"hash"
,
latestHeader
.
Hash
)
fromHeader
=
latestHeader
.
RLPHeader
.
Header
()
}
else
{
log
.
Info
(
"no indexed state, starting from genesis"
)
...
...
indexer/processors/bridge.go
View file @
a145e096
...
...
@@ -107,7 +107,7 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
continue
}
toL1Height
,
toL2Height
:=
latestEpoch
.
L1BlockHeader
.
Number
.
Int
,
latestEpoch
.
L2BlockHeader
.
Number
.
Int
toL1Height
,
toL2Height
:=
latestEpoch
.
L1BlockHeader
.
Number
,
latestEpoch
.
L2BlockHeader
.
Number
fromL1Height
,
fromL2Height
:=
big
.
NewInt
(
0
),
big
.
NewInt
(
0
)
if
b
.
LatestL1Header
!=
nil
{
// `NewBridgeProcessor` ensures that LatestL2Header must not be nil if LatestL1Header is set
...
...
indexer/processors/contracts/cross_domain_messenger.go
View file @
a145e096
...
...
@@ -94,13 +94,13 @@ func CrossDomainMessengerSentMessageEvents(chainSelector string, contractAddress
Event
:
&
sentMessageEvents
[
i
],
BridgeMessage
:
database
.
BridgeMessage
{
MessageHash
:
messageHash
,
Nonce
:
database
.
U256
{
Int
:
sentMessage
.
MessageNonce
}
,
Nonce
:
sentMessage
.
MessageNonce
,
SentMessageEventGUID
:
sentMessageEvents
[
i
]
.
GUID
,
GasLimit
:
database
.
U256
{
Int
:
sentMessage
.
GasLimit
}
,
GasLimit
:
sentMessage
.
GasLimit
,
Tx
:
database
.
Transaction
{
FromAddress
:
sentMessage
.
Sender
,
ToAddress
:
sentMessage
.
Target
,
Amount
:
database
.
U256
{
Int
:
sentMessageExtension
.
Value
}
,
Amount
:
sentMessageExtension
.
Value
,
Data
:
sentMessage
.
Message
,
Timestamp
:
sentMessageEvents
[
i
]
.
Timestamp
,
},
...
...
indexer/processors/contracts/l2_to_l1_message_passer.go
View file @
a145e096
...
...
@@ -11,8 +11,8 @@ import (
type
L2ToL1MessagePasserMessagePassed
struct
{
Event
*
database
.
ContractEvent
WithdrawalHash
common
.
Hash
GasLimit
database
.
U256
Nonce
database
.
U256
GasLimit
*
big
.
Int
Nonce
*
big
.
Int
Tx
database
.
Transaction
}
...
...
@@ -40,12 +40,12 @@ func L2ToL1MessagePasserMessagePassedEvents(contractAddress common.Address, db *
messagesPassed
[
i
]
=
L2ToL1MessagePasserMessagePassed
{
Event
:
&
messagePassedEvents
[
i
]
.
ContractEvent
,
WithdrawalHash
:
messagePassed
.
WithdrawalHash
,
Nonce
:
database
.
U256
{
Int
:
messagePassed
.
Nonce
}
,
GasLimit
:
database
.
U256
{
Int
:
messagePassed
.
GasLimit
}
,
Nonce
:
messagePassed
.
Nonce
,
GasLimit
:
messagePassed
.
GasLimit
,
Tx
:
database
.
Transaction
{
FromAddress
:
messagePassed
.
Sender
,
ToAddress
:
messagePassed
.
Target
,
Amount
:
database
.
U256
{
Int
:
messagePassed
.
Value
}
,
Amount
:
messagePassed
.
Value
,
Data
:
messagePassed
.
Data
,
Timestamp
:
messagePassedEvents
[
i
]
.
Timestamp
,
},
...
...
indexer/processors/contracts/optimism_portal.go
View file @
a145e096
...
...
@@ -16,7 +16,7 @@ type OptimismPortalTransactionDepositEvent struct {
Event
*
database
.
ContractEvent
DepositTx
*
types
.
DepositTx
Tx
database
.
Transaction
GasLimit
database
.
U256
GasLimit
*
big
.
Int
}
type
OptimismPortalWithdrawalProvenEvent
struct
{
...
...
@@ -67,11 +67,11 @@ func OptimismPortalTransactionDepositEvents(contractAddress common.Address, db *
optimismPortalTxDeposits
[
i
]
=
OptimismPortalTransactionDepositEvent
{
Event
:
&
transactionDepositEvents
[
i
]
.
ContractEvent
,
DepositTx
:
depositTx
,
GasLimit
:
database
.
U256
{
Int
:
new
(
big
.
Int
)
.
SetUint64
(
depositTx
.
Gas
)}
,
GasLimit
:
new
(
big
.
Int
)
.
SetUint64
(
depositTx
.
Gas
)
,
Tx
:
database
.
Transaction
{
FromAddress
:
txDeposit
.
From
,
ToAddress
:
txDeposit
.
To
,
Amount
:
d
atabase
.
U256
{
Int
:
depositTx
.
Value
}
,
Amount
:
d
epositTx
.
Value
,
Data
:
depositTx
.
Data
,
Timestamp
:
transactionDepositEvents
[
i
]
.
Timestamp
,
},
...
...
indexer/processors/contracts/standard_bridge.go
View file @
a145e096
...
...
@@ -101,7 +101,7 @@ func _standardBridgeInitiatedEvents[BridgeEventType bindings.StandardBridgeETHBr
Tx
:
database
.
Transaction
{
FromAddress
:
erc20Bridge
.
From
,
ToAddress
:
erc20Bridge
.
To
,
Amount
:
database
.
U256
{
Int
:
erc20Bridge
.
Amount
}
,
Amount
:
erc20Bridge
.
Amount
,
Data
:
erc20Bridge
.
ExtraData
,
Timestamp
:
initiatedBridgeEvents
[
i
]
.
Timestamp
,
},
...
...
@@ -161,7 +161,7 @@ func _standardBridgeFinalizedEvents[BridgeEventType bindings.StandardBridgeETHBr
Tx
:
database
.
Transaction
{
FromAddress
:
erc20Bridge
.
From
,
ToAddress
:
erc20Bridge
.
To
,
Amount
:
database
.
U256
{
Int
:
erc20Bridge
.
Amount
}
,
Amount
:
erc20Bridge
.
Amount
,
Data
:
erc20Bridge
.
ExtraData
,
Timestamp
:
bridgeFinalizedEvents
[
i
]
.
Timestamp
,
},
...
...
op-challenger/cmd/main_test.go
View file @
a145e096
...
...
@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-challenger/config"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
...
...
@@ -233,6 +234,23 @@ func TestCannonSnapshotFreq(t *testing.T) {
})
}
func
TestGameWindow
(
t
*
testing
.
T
)
{
t
.
Run
(
"UsesDefault"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
))
require
.
Equal
(
t
,
config
.
DefaultGameWindow
,
cfg
.
GameWindow
)
})
t
.
Run
(
"Valid"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
,
"--game-window=1m"
))
require
.
Equal
(
t
,
time
.
Duration
(
time
.
Minute
),
cfg
.
GameWindow
)
})
t
.
Run
(
"ParsesDefault"
,
func
(
t
*
testing
.
T
)
{
cfg
:=
configForArgs
(
t
,
addRequiredArgs
(
config
.
TraceTypeAlphabet
,
"--game-window=264h"
))
require
.
Equal
(
t
,
config
.
DefaultGameWindow
,
cfg
.
GameWindow
)
})
}
func
TestRequireEitherCannonNetworkOrRollupAndGenesis
(
t
*
testing
.
T
)
{
verifyArgsInvalid
(
t
,
...
...
op-challenger/config/config.go
View file @
a145e096
...
...
@@ -3,6 +3,7 @@ package config
import
(
"errors"
"fmt"
"time"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -73,7 +74,14 @@ func ValidTraceType(value TraceType) bool {
return
false
}
const
DefaultCannonSnapshotFreq
=
uint
(
1
_000_000_000
)
const
(
DefaultCannonSnapshotFreq
=
uint
(
1
_000_000_000
)
// DefaultGameWindow is the default maximum time duration in the past
// that the challenger will look for games to progress.
// The default value is 11 days, which is a 4 day resolution buffer
// plus the 7 day game finalization window.
DefaultGameWindow
=
time
.
Duration
(
11
*
24
*
time
.
Hour
)
)
// Config is a well typed config that is parsed from the CLI params.
// This also contains config options for auxiliary services.
...
...
@@ -82,9 +90,9 @@ type Config struct {
L1EthRpc
string
// L1 RPC Url
GameFactoryAddress
common
.
Address
// Address of the dispute game factory
GameAllowlist
[]
common
.
Address
// Allowlist of fault game addresses
GameWindow
time
.
Duration
// Maximum time duration to look for games to progress
AgreeWithProposedOutput
bool
// Temporary config if we agree or disagree with the posted output
TraceType
TraceType
// Type of trace
TraceType
TraceType
// Type of trace
// Specific to the alphabet trace provider
AlphabetTrace
string
// String for the AlphabetTraceProvider
...
...
@@ -124,6 +132,7 @@ func NewConfig(
PprofConfig
:
oppprof
.
DefaultCLIConfig
(),
CannonSnapshotFreq
:
DefaultCannonSnapshotFreq
,
GameWindow
:
DefaultGameWindow
,
}
}
...
...
op-challenger/fault/abi_test.go
View file @
a145e096
...
...
@@ -55,7 +55,7 @@ func TestBuildFaultDefendData(t *testing.T) {
_
,
opts
,
_
,
contract
,
err
:=
setupFaultDisputeGame
()
require
.
NoError
(
t
,
err
)
responder
,
_
:=
newTestFaultResponder
(
t
,
false
)
responder
,
_
:=
newTestFaultResponder
(
t
)
data
,
err
:=
responder
.
buildFaultDefendData
(
1
,
[
32
]
byte
{
0x02
,
0x03
})
require
.
NoError
(
t
,
err
)
...
...
@@ -72,7 +72,7 @@ func TestBuildFaultAttackData(t *testing.T) {
_
,
opts
,
_
,
contract
,
err
:=
setupFaultDisputeGame
()
require
.
NoError
(
t
,
err
)
responder
,
_
:=
newTestFaultResponder
(
t
,
false
)
responder
,
_
:=
newTestFaultResponder
(
t
)
data
,
err
:=
responder
.
buildFaultAttackData
(
1
,
[
32
]
byte
{
0x02
,
0x03
})
require
.
NoError
(
t
,
err
)
...
...
@@ -89,7 +89,7 @@ func TestBuildFaultStepData(t *testing.T) {
_
,
opts
,
_
,
contract
,
err
:=
setupFaultDisputeGame
()
require
.
NoError
(
t
,
err
)
responder
,
_
:=
newTestFaultResponder
(
t
,
false
)
responder
,
_
:=
newTestFaultResponder
(
t
)
data
,
err
:=
responder
.
buildStepTxData
(
types
.
StepCallData
{
ClaimIndex
:
2
,
...
...
op-challenger/fault/agent.go
View file @
a145e096
...
...
@@ -13,7 +13,7 @@ import (
// Responder takes a response action & executes.
// For full op-challenger this means executing the transaction on chain.
type
Responder
interface
{
Ca
nResolve
(
ctx
context
.
Context
)
bool
Ca
llResolve
(
ctx
context
.
Context
)
(
types
.
GameStatus
,
error
)
Resolve
(
ctx
context
.
Context
)
error
Respond
(
ctx
context
.
Context
,
response
types
.
Claim
)
error
Step
(
ctx
context
.
Context
,
stepData
types
.
StepCallData
)
error
...
...
@@ -65,10 +65,27 @@ func (a *Agent) Act(ctx context.Context) error {
return
nil
}
// shouldResolve returns true if the agent should resolve the game.
// This method will return false if the game is still in progress.
func
(
a
*
Agent
)
shouldResolve
(
ctx
context
.
Context
,
status
types
.
GameStatus
)
bool
{
expected
:=
types
.
GameStatusDefenderWon
if
a
.
agreeWithProposedOutput
{
expected
=
types
.
GameStatusChallengerWon
}
if
expected
!=
status
{
a
.
log
.
Warn
(
"Game will be lost"
,
"expected"
,
expected
,
"actual"
,
status
)
}
return
expected
==
status
}
// tryResolve resolves the game if it is in a terminal state
// and returns true if the game resolves successfully.
func
(
a
*
Agent
)
tryResolve
(
ctx
context
.
Context
)
bool
{
if
!
a
.
responder
.
CanResolve
(
ctx
)
{
status
,
err
:=
a
.
responder
.
CallResolve
(
ctx
)
if
err
!=
nil
{
return
false
}
if
!
a
.
shouldResolve
(
ctx
,
status
)
{
return
false
}
a
.
log
.
Info
(
"Resolving game"
)
...
...
op-challenger/fault/agent_test.go
0 → 100644
View file @
a145e096
package
fault
import
(
"context"
"testing"
"github.com/ethereum/go-ethereum/log"
"github.com/stretchr/testify/require"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-node/testlog"
)
// TestShouldResolve tests the resolution logic.
func
TestShouldResolve
(
t
*
testing
.
T
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlCrit
)
t
.
Run
(
"AgreeWithProposedOutput"
,
func
(
t
*
testing
.
T
)
{
agent
:=
NewAgent
(
nil
,
0
,
nil
,
nil
,
nil
,
true
,
log
)
require
.
False
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusDefenderWon
))
require
.
True
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusChallengerWon
))
require
.
False
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusInProgress
))
})
t
.
Run
(
"DisagreeWithProposedOutput"
,
func
(
t
*
testing
.
T
)
{
agent
:=
NewAgent
(
nil
,
0
,
nil
,
nil
,
nil
,
false
,
log
)
require
.
True
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusDefenderWon
))
require
.
False
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusChallengerWon
))
require
.
False
(
t
,
agent
.
shouldResolve
(
context
.
Background
(),
types
.
GameStatusInProgress
))
})
}
op-challenger/fault/caller.go
View file @
a145e096
...
...
@@ -8,7 +8,6 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
)
type
FaultDisputeGameCaller
interface
{
...
...
@@ -26,7 +25,7 @@ func NewFaultCaller(caller FaultDisputeGameCaller) *FaultCaller {
}
}
func
NewFaultCallerFromBindings
(
fdgAddr
common
.
Address
,
client
*
ethclient
.
Client
)
(
*
FaultCaller
,
error
)
{
func
NewFaultCallerFromBindings
(
fdgAddr
common
.
Address
,
client
bind
.
ContractCaller
)
(
*
FaultCaller
,
error
)
{
caller
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
fdgAddr
,
client
)
if
err
!=
nil
{
return
nil
,
err
...
...
op-challenger/fault/cannon/provider.go
View file @
a145e096
...
...
@@ -118,6 +118,10 @@ func (p *CannonTraceProvider) AbsolutePreState(ctx context.Context) ([]byte, err
return
state
.
EncodeWitness
(),
nil
}
func
(
p
*
CannonTraceProvider
)
Cleanup
()
error
{
return
os
.
RemoveAll
(
p
.
dir
)
}
// loadProof will attempt to load or generate the proof data at the specified index
// If the requested index is beyond the end of the actual trace it is extended with no-op instructions.
func
(
p
*
CannonTraceProvider
)
loadProof
(
ctx
context
.
Context
,
i
uint64
)
(
*
proofData
,
error
)
{
...
...
op-challenger/fault/cannon/provider_test.go
View file @
a145e096
...
...
@@ -204,6 +204,14 @@ func TestUseGameSpecificSubdir(t *testing.T) {
require
.
Equal
(
t
,
filepath
.
Join
(
dataDir
,
gameDirName
),
provider
.
dir
,
"should use game specific subdir"
)
}
func
TestCleanup
(
t
*
testing
.
T
)
{
dataDir
,
prestate
:=
setupTestData
(
t
)
provider
,
_
:=
setupWithTestData
(
t
,
dataDir
,
prestate
)
require
.
NoError
(
t
,
provider
.
Cleanup
())
_
,
err
:=
os
.
Stat
(
dataDir
)
require
.
ErrorIs
(
t
,
err
,
os
.
ErrNotExist
)
}
func
setupPreState
(
t
*
testing
.
T
,
dataDir
string
,
filename
string
)
{
srcDir
:=
filepath
.
Join
(
"test_data"
)
path
:=
filepath
.
Join
(
srcDir
,
filename
)
...
...
op-challenger/fault/factory.go
View file @
a145e096
...
...
@@ -43,7 +43,7 @@ func NewGameLoader(caller MinimalDisputeGameFactoryCaller) *gameLoader {
}
// FetchAllGamesAtBlock fetches all dispute games from the factory at a given block number.
func
(
l
*
gameLoader
)
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
{
func
(
l
*
gameLoader
)
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
earliestTimestamp
uint64
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
{
if
blockNumber
==
nil
{
return
nil
,
ErrMissingBlockNumber
}
...
...
@@ -56,14 +56,19 @@ func (l *gameLoader) FetchAllGamesAtBlock(ctx context.Context, blockNumber *big.
return
nil
,
fmt
.
Errorf
(
"failed to fetch game count: %w"
,
err
)
}
games
:=
make
([]
FaultDisputeGame
,
gameCount
.
Uint64
())
for
i
:=
uint64
(
0
);
i
<
gameCount
.
Uint64
();
i
++
{
game
,
err
:=
l
.
caller
.
GameAtIndex
(
callOpts
,
big
.
NewInt
(
int64
(
i
)))
games
:=
make
([]
FaultDisputeGame
,
0
)
if
gameCount
.
Uint64
()
==
0
{
return
games
,
nil
}
for
i
:=
gameCount
.
Uint64
();
i
>
0
;
i
--
{
game
,
err
:=
l
.
caller
.
GameAtIndex
(
callOpts
,
big
.
NewInt
(
int64
(
i
-
1
)))
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to fetch game at index %d: %w"
,
i
,
err
)
}
games
[
i
]
=
game
if
game
.
Timestamp
<
earliestTimestamp
{
break
}
games
=
append
(
games
,
game
)
}
return
games
,
nil
...
...
op-challenger/fault/factory_test.go
View file @
a145e096
...
...
@@ -25,6 +25,7 @@ func TestGameLoader_FetchAllGames(t *testing.T) {
tests
:=
[]
struct
{
name
string
caller
*
mockMinimalDisputeGameFactoryCaller
earliest
uint64
blockNumber
*
big
.
Int
expectedErr
error
expectedLen
int
...
...
@@ -33,35 +34,36 @@ func TestGameLoader_FetchAllGames(t *testing.T) {
name
:
"success"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
10
,
false
,
false
),
blockNumber
:
big
.
NewInt
(
1
),
expectedErr
:
nil
,
expectedLen
:
10
,
},
{
name
:
"expired game ignored"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
10
,
false
,
false
),
earliest
:
500
,
blockNumber
:
big
.
NewInt
(
1
),
expectedLen
:
5
,
},
{
name
:
"game count error"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
10
,
true
,
false
),
blockNumber
:
big
.
NewInt
(
1
),
expectedErr
:
gameCountErr
,
expectedLen
:
0
,
},
{
name
:
"game index error"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
10
,
false
,
true
),
blockNumber
:
big
.
NewInt
(
1
),
expectedErr
:
gameIndexErr
,
expectedLen
:
0
,
},
{
name
:
"no games"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
0
,
false
,
false
),
blockNumber
:
big
.
NewInt
(
1
),
expectedErr
:
nil
,
expectedLen
:
0
,
},
{
name
:
"missing block number"
,
caller
:
newMockMinimalDisputeGameFactoryCaller
(
0
,
false
,
false
),
expectedErr
:
ErrMissingBlockNumber
,
expectedLen
:
0
,
},
}
...
...
@@ -72,10 +74,11 @@ func TestGameLoader_FetchAllGames(t *testing.T) {
t
.
Parallel
()
loader
:=
NewGameLoader
(
test
.
caller
)
games
,
err
:=
loader
.
FetchAllGamesAtBlock
(
context
.
Background
(),
test
.
blockNumber
)
games
,
err
:=
loader
.
FetchAllGamesAtBlock
(
context
.
Background
(),
test
.
earliest
,
test
.
blockNumber
)
require
.
ErrorIs
(
t
,
err
,
test
.
expectedErr
)
require
.
Len
(
t
,
games
,
test
.
expectedLen
)
expectedGames
:=
test
.
caller
.
games
expectedGames
=
expectedGames
[
len
(
expectedGames
)
-
test
.
expectedLen
:
]
if
test
.
expectedErr
!=
nil
{
expectedGames
=
make
([]
FaultDisputeGame
,
0
)
}
...
...
@@ -90,7 +93,7 @@ func generateMockGames(count uint64) []FaultDisputeGame {
for
i
:=
uint64
(
0
);
i
<
count
;
i
++
{
games
[
i
]
=
FaultDisputeGame
{
Proxy
:
common
.
BigToAddress
(
big
.
NewInt
(
int64
(
i
))),
Timestamp
:
i
,
Timestamp
:
i
*
100
,
}
}
...
...
op-challenger/fault/monitor.go
View file @
a145e096
...
...
@@ -13,6 +13,7 @@ import (
type
gamePlayer
interface
{
ProgressGame
(
ctx
context
.
Context
)
bool
Cleanup
()
error
}
type
playerCreator
func
(
address
common
.
Address
)
(
gamePlayer
,
error
)
...
...
@@ -20,24 +21,26 @@ type blockNumberFetcher func(ctx context.Context) (uint64, error)
// gameSource loads information about the games available to play
type
gameSource
interface
{
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
earliest
uint64
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
}
type
gameMonitor
struct
{
logger
log
.
Logger
clock
clock
.
Clock
source
gameSource
gameWindow
time
.
Duration
createPlayer
playerCreator
fetchBlockNumber
blockNumberFetcher
allowedGames
[]
common
.
Address
players
map
[
common
.
Address
]
gamePlayer
}
func
newGameMonitor
(
logger
log
.
Logger
,
cl
clock
.
Clock
,
fetchBlockNumber
blockNumberFetcher
,
allowedGames
[]
common
.
Address
,
source
gameSource
,
createGame
playerCreator
)
*
gameMonitor
{
func
newGameMonitor
(
logger
log
.
Logger
,
gameWindow
time
.
Duration
,
cl
clock
.
Clock
,
fetchBlockNumber
blockNumberFetcher
,
allowedGames
[]
common
.
Address
,
source
gameSource
,
createGame
playerCreator
)
*
gameMonitor
{
return
&
gameMonitor
{
logger
:
logger
,
clock
:
cl
,
source
:
source
,
gameWindow
:
gameWindow
,
createPlayer
:
createGame
,
fetchBlockNumber
:
fetchBlockNumber
,
allowedGames
:
allowedGames
,
...
...
@@ -57,26 +60,56 @@ func (m *gameMonitor) allowedGame(game common.Address) bool {
return
false
}
func
(
m
*
gameMonitor
)
minGameTimestamp
()
uint64
{
if
m
.
gameWindow
.
Seconds
()
==
0
{
return
0
}
// time: "To compute t-d for a duration d, use t.Add(-d)."
// https://pkg.go.dev/time#Time.Sub
if
m
.
clock
.
Now
()
.
Unix
()
>
int64
(
m
.
gameWindow
.
Seconds
())
{
return
uint64
(
m
.
clock
.
Now
()
.
Add
(
-
m
.
gameWindow
)
.
Unix
())
}
return
0
}
func
(
m
*
gameMonitor
)
progressGames
(
ctx
context
.
Context
)
error
{
blockNum
,
err
:=
m
.
fetchBlockNumber
(
ctx
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to load current block number: %w"
,
err
)
}
games
,
err
:=
m
.
source
.
FetchAllGamesAtBlock
(
ctx
,
new
(
big
.
Int
)
.
SetUint64
(
blockNum
))
games
,
err
:=
m
.
source
.
FetchAllGamesAtBlock
(
ctx
,
m
.
minGameTimestamp
(),
new
(
big
.
Int
)
.
SetUint64
(
blockNum
))
if
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to load games: %w"
,
err
)
}
requiredGames
:=
make
(
map
[
common
.
Address
]
bool
)
for
_
,
game
:=
range
games
{
if
!
m
.
allowedGame
(
game
.
Proxy
)
{
m
.
logger
.
Debug
(
"Skipping game not on allow list"
,
"game"
,
game
.
Proxy
)
continue
}
requiredGames
[
game
.
Proxy
]
=
true
player
,
err
:=
m
.
fetchOrCreateGamePlayer
(
game
)
if
err
!=
nil
{
m
.
logger
.
Error
(
"Error while progressing game"
,
"game"
,
game
.
Proxy
,
"err"
,
err
)
continue
}
player
.
ProgressGame
(
ctx
)
done
:=
player
.
ProgressGame
(
ctx
)
if
done
{
// Remove resources on disk as soon as the game is complete to save disk space.
// We keep the player in memory to avoid recreating it on every update but will no longer
// need the resources on disk because there are no further actions required on the game.
if
err
:=
player
.
Cleanup
();
err
!=
nil
{
m
.
logger
.
Error
(
"Unable to cleanup player data"
,
"err"
,
err
)
}
}
}
// Remove the player for any game that's no longer being returned from the list of active games
for
addr
:=
range
m
.
players
{
if
_
,
ok
:=
requiredGames
[
addr
];
ok
{
// Game still required
continue
}
delete
(
m
.
players
,
addr
)
}
return
nil
}
...
...
op-challenger/fault/monitor_test.go
View file @
a145e096
...
...
@@ -4,6 +4,7 @@ import (
"context"
"math/big"
"testing"
"time"
"github.com/ethereum-optimism/optimism/op-service/clock"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -13,6 +14,32 @@ import (
"github.com/ethereum-optimism/optimism/op-node/testlog"
)
func
TestMonitorMinGameTimestamp
(
t
*
testing
.
T
)
{
t
.
Parallel
()
t
.
Run
(
"zero game window returns zero"
,
func
(
t
*
testing
.
T
)
{
monitor
,
_
,
_
:=
setupMonitorTest
(
t
,
[]
common
.
Address
{})
monitor
.
gameWindow
=
time
.
Duration
(
0
)
require
.
Equal
(
t
,
monitor
.
minGameTimestamp
(),
uint64
(
0
))
})
t
.
Run
(
"non-zero game window with zero clock"
,
func
(
t
*
testing
.
T
)
{
monitor
,
_
,
_
:=
setupMonitorTest
(
t
,
[]
common
.
Address
{})
monitor
.
gameWindow
=
time
.
Minute
monitor
.
clock
=
clock
.
NewDeterministicClock
(
time
.
Unix
(
0
,
0
))
require
.
Equal
(
t
,
monitor
.
minGameTimestamp
(),
uint64
(
0
))
})
t
.
Run
(
"minimum computed correctly"
,
func
(
t
*
testing
.
T
)
{
monitor
,
_
,
_
:=
setupMonitorTest
(
t
,
[]
common
.
Address
{})
monitor
.
gameWindow
=
time
.
Minute
frozen
:=
time
.
Unix
(
int64
(
time
.
Hour
.
Seconds
()),
0
)
monitor
.
clock
=
clock
.
NewDeterministicClock
(
frozen
)
expected
:=
uint64
(
frozen
.
Add
(
-
time
.
Minute
)
.
Unix
())
require
.
Equal
(
t
,
monitor
.
minGameTimestamp
(),
expected
)
})
}
func
TestMonitorExitsWhenContextDone
(
t
*
testing
.
T
)
{
monitor
,
_
,
_
:=
setupMonitorTest
(
t
,
[]
common
.
Address
{
common
.
Address
{}})
ctx
,
cancel
:=
context
.
WithCancel
(
context
.
Background
())
...
...
@@ -77,6 +104,69 @@ func TestMonitorOnlyCreateSpecifiedGame(t *testing.T) {
require
.
Equal
(
t
,
1
,
games
.
created
[
addr2
]
.
progressCount
)
}
func
TestDeletePlayersWhenNoLongerInListOfGames
(
t
*
testing
.
T
)
{
addr1
:=
common
.
Address
{
0xaa
}
addr2
:=
common
.
Address
{
0xbb
}
monitor
,
source
,
games
:=
setupMonitorTest
(
t
,
nil
)
allGames
:=
[]
FaultDisputeGame
{
{
Proxy
:
addr1
,
Timestamp
:
9999
,
},
{
Proxy
:
addr2
,
Timestamp
:
9999
,
},
}
source
.
games
=
allGames
require
.
NoError
(
t
,
monitor
.
progressGames
(
context
.
Background
()))
require
.
Len
(
t
,
games
.
created
,
2
)
require
.
Contains
(
t
,
games
.
created
,
addr1
)
require
.
Contains
(
t
,
games
.
created
,
addr2
)
// First game is now old enough it's not returned in the list of active games
source
.
games
=
source
.
games
[
1
:
]
require
.
NoError
(
t
,
monitor
.
progressGames
(
context
.
Background
()))
require
.
Len
(
t
,
games
.
created
,
2
)
require
.
Contains
(
t
,
games
.
created
,
addr1
)
require
.
Contains
(
t
,
games
.
created
,
addr2
)
// Forget that we created the first game so it can be recreated if needed
delete
(
games
.
created
,
addr1
)
// First game now reappears (inexplicably but usefully for our testing)
source
.
games
=
allGames
require
.
NoError
(
t
,
monitor
.
progressGames
(
context
.
Background
()))
// A new player is created for it because the original was deleted
require
.
Len
(
t
,
games
.
created
,
2
)
require
.
Contains
(
t
,
games
.
created
,
addr1
)
require
.
Contains
(
t
,
games
.
created
,
addr2
)
require
.
Equal
(
t
,
1
,
games
.
created
[
addr1
]
.
progressCount
)
}
func
TestCleanupResourcesOfCompletedGames
(
t
*
testing
.
T
)
{
monitor
,
source
,
games
:=
setupMonitorTest
(
t
,
[]
common
.
Address
{})
games
.
createCompleted
=
true
addr1
:=
common
.
Address
{
0xaa
}
source
.
games
=
[]
FaultDisputeGame
{
{
Proxy
:
addr1
,
Timestamp
:
9999
,
},
}
err
:=
monitor
.
progressGames
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Len
(
t
,
games
.
created
,
1
,
"should create game agents"
)
require
.
Contains
(
t
,
games
.
created
,
addr1
)
require
.
Equal
(
t
,
1
,
games
.
created
[
addr1
]
.
progressCount
)
require
.
Equal
(
t
,
1
,
games
.
created
[
addr1
]
.
cleanupCount
,
"should clean up once game is done"
)
}
func
setupMonitorTest
(
t
*
testing
.
T
,
allowedGames
[]
common
.
Address
)
(
*
gameMonitor
,
*
stubGameSource
,
*
createdGames
)
{
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlDebug
)
source
:=
&
stubGameSource
{}
...
...
@@ -87,7 +177,7 @@ func setupMonitorTest(t *testing.T, allowedGames []common.Address) (*gameMonitor
fetchBlockNum
:=
func
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
return
1234
,
nil
}
monitor
:=
newGameMonitor
(
logger
,
clock
.
SystemClock
,
fetchBlockNum
,
allowedGames
,
source
,
games
.
CreateGame
)
monitor
:=
newGameMonitor
(
logger
,
time
.
Duration
(
0
),
clock
.
SystemClock
,
fetchBlockNum
,
allowedGames
,
source
,
games
.
CreateGame
)
return
monitor
,
source
,
games
}
...
...
@@ -95,13 +185,14 @@ type stubGameSource struct {
games
[]
FaultDisputeGame
}
func
(
s
*
stubGameSource
)
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
{
func
(
s
*
stubGameSource
)
FetchAllGamesAtBlock
(
ctx
context
.
Context
,
earliest
uint64
,
blockNumber
*
big
.
Int
)
([]
FaultDisputeGame
,
error
)
{
return
s
.
games
,
nil
}
type
stubGame
struct
{
addr
common
.
Address
progressCount
int
cleanupCount
int
done
bool
}
...
...
@@ -110,16 +201,22 @@ func (g *stubGame) ProgressGame(ctx context.Context) bool {
return
g
.
done
}
func
(
g
*
stubGame
)
Cleanup
()
error
{
g
.
cleanupCount
++
return
nil
}
type
createdGames
struct
{
t
*
testing
.
T
created
map
[
common
.
Address
]
*
stubGame
t
*
testing
.
T
createCompleted
bool
created
map
[
common
.
Address
]
*
stubGame
}
func
(
c
*
createdGames
)
CreateGame
(
addr
common
.
Address
)
(
gamePlayer
,
error
)
{
if
_
,
exists
:=
c
.
created
[
addr
];
exists
{
c
.
t
.
Fatalf
(
"game %v already exists"
,
addr
)
}
game
:=
&
stubGame
{
addr
:
addr
}
game
:=
&
stubGame
{
addr
:
addr
,
done
:
c
.
createCompleted
}
c
.
created
[
addr
]
=
game
return
game
,
nil
}
op-challenger/fault/player.go
View file @
a145e096
...
...
@@ -10,8 +10,8 @@ import (
"github.com/ethereum-optimism/optimism/op-challenger/fault/cannon"
"github.com/ethereum-optimism/optimism/op-challenger/fault/types"
"github.com/ethereum-optimism/optimism/op-service/txmgr"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
)
...
...
@@ -29,6 +29,9 @@ type GamePlayer struct {
agreeWithProposedOutput
bool
caller
GameInfo
logger
log
.
Logger
cleanup
func
()
error
completed
bool
}
func
NewGamePlayer
(
...
...
@@ -37,7 +40,7 @@ func NewGamePlayer(
cfg
*
config
.
Config
,
addr
common
.
Address
,
txMgr
txmgr
.
TxManager
,
client
*
ethclient
.
Client
,
client
bind
.
ContractCaller
,
)
(
*
GamePlayer
,
error
)
{
logger
=
logger
.
New
(
"game"
,
addr
)
contract
,
err
:=
bindings
.
NewFaultDisputeGameCaller
(
addr
,
client
)
...
...
@@ -54,18 +57,22 @@ func NewGamePlayer(
var
provider
types
.
TraceProvider
var
updater
types
.
OracleUpdater
var
cleanup
func
()
error
switch
cfg
.
TraceType
{
case
config
.
TraceTypeCannon
:
provider
,
err
=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
cfg
,
client
,
addr
)
cannonProvider
,
err
:
=
cannon
.
NewTraceProvider
(
ctx
,
logger
,
cfg
,
client
,
addr
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"create cannon trace provider: %w"
,
err
)
}
cleanup
=
cannonProvider
.
Cleanup
provider
=
cannonProvider
updater
,
err
=
cannon
.
NewOracleUpdater
(
ctx
,
logger
,
txMgr
,
addr
,
client
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"failed to create the cannon updater: %w"
,
err
)
}
case
config
.
TraceTypeAlphabet
:
provider
=
alphabet
.
NewTraceProvider
(
cfg
.
AlphabetTrace
,
gameDepth
)
cleanup
=
func
()
error
{
return
nil
}
updater
=
alphabet
.
NewOracleUpdater
(
logger
)
default
:
return
nil
,
fmt
.
Errorf
(
"unsupported trace type: %v"
,
cfg
.
TraceType
)
...
...
@@ -90,10 +97,16 @@ func NewGamePlayer(
agreeWithProposedOutput
:
cfg
.
AgreeWithProposedOutput
,
caller
:
caller
,
logger
:
logger
,
cleanup
:
cleanup
,
},
nil
}
func
(
g
*
GamePlayer
)
ProgressGame
(
ctx
context
.
Context
)
bool
{
if
g
.
completed
{
// Game is already complete so don't try to perform further actions.
g
.
logger
.
Trace
(
"Skipping completed game"
)
return
true
}
g
.
logger
.
Trace
(
"Checking if actions are required"
)
if
err
:=
g
.
agent
.
Act
(
ctx
);
err
!=
nil
{
g
.
logger
.
Error
(
"Error when acting on game"
,
"err"
,
err
)
...
...
@@ -102,7 +115,8 @@ func (g *GamePlayer) ProgressGame(ctx context.Context) bool {
g
.
logger
.
Warn
(
"Unable to retrieve game status"
,
"err"
,
err
)
}
else
{
g
.
logGameStatus
(
ctx
,
status
)
return
status
!=
types
.
GameStatusInProgress
g
.
completed
=
status
!=
types
.
GameStatusInProgress
return
g
.
completed
}
return
false
}
...
...
@@ -129,3 +143,7 @@ func (g *GamePlayer) logGameStatus(ctx context.Context, status types.GameStatus)
g
.
logger
.
Error
(
"Game lost"
,
"status"
,
status
)
}
}
func
(
g
*
GamePlayer
)
Cleanup
()
error
{
return
g
.
cleanup
()
}
op-challenger/fault/player_test.go
View file @
a145e096
...
...
@@ -12,14 +12,14 @@ import (
)
func
TestProgressGame_LogErrorFromAct
(
t
*
testing
.
T
)
{
handler
,
game
,
actor
,
_
:=
setupProgressGameTest
(
t
,
true
)
actor
.
e
rr
=
errors
.
New
(
"boom"
)
handler
,
game
,
actor
:=
setupProgressGameTest
(
t
,
true
)
actor
.
actE
rr
=
errors
.
New
(
"boom"
)
done
:=
game
.
ProgressGame
(
context
.
Background
())
require
.
False
(
t
,
done
,
"should not be done"
)
require
.
Equal
(
t
,
1
,
actor
.
callCount
,
"should perform next actions"
)
errLog
:=
handler
.
FindLog
(
log
.
LvlError
,
"Error when acting on game"
)
require
.
NotNil
(
t
,
errLog
,
"should log error"
)
require
.
Equal
(
t
,
actor
.
e
rr
,
errLog
.
GetContextValue
(
"err"
))
require
.
Equal
(
t
,
actor
.
actE
rr
,
errLog
.
GetContextValue
(
"err"
))
// Should still log game status
msg
:=
handler
.
FindLog
(
log
.
LvlInfo
,
"Game info"
)
...
...
@@ -27,6 +27,24 @@ func TestProgressGame_LogErrorFromAct(t *testing.T) {
require
.
Equal
(
t
,
uint64
(
1
),
msg
.
GetContextValue
(
"claims"
))
}
func
TestCleanup
(
t
*
testing
.
T
)
{
t
.
Run
(
"default cleanup"
,
func
(
t
*
testing
.
T
)
{
game
:=
&
GamePlayer
{
cleanup
:
func
()
error
{
return
nil
},
}
require
.
NoError
(
t
,
game
.
Cleanup
())
})
t
.
Run
(
"cleanup bubbles up error"
,
func
(
t
*
testing
.
T
)
{
err
:=
errors
.
New
(
"wassie"
)
game
:=
&
GamePlayer
{
cleanup
:
func
()
error
{
return
err
},
}
require
.
Error
(
t
,
err
,
game
.
Cleanup
())
})
}
func
TestProgressGame_LogGameStatus
(
t
*
testing
.
T
)
{
tests
:=
[]
struct
{
name
string
...
...
@@ -74,11 +92,11 @@ func TestProgressGame_LogGameStatus(t *testing.T) {
for
_
,
test
:=
range
tests
{
test
:=
test
t
.
Run
(
test
.
name
,
func
(
t
*
testing
.
T
)
{
handler
,
game
,
actor
,
gameInfo
:=
setupProgressGameTest
(
t
,
test
.
agreeWithOutput
)
game
Info
.
status
=
test
.
status
handler
,
game
,
gameState
:=
setupProgressGameTest
(
t
,
test
.
agreeWithOutput
)
game
State
.
status
=
test
.
status
done
:=
game
.
ProgressGame
(
context
.
Background
())
require
.
Equal
(
t
,
1
,
actor
.
callCount
,
"should perform next actions"
)
require
.
Equal
(
t
,
1
,
gameState
.
callCount
,
"should perform next actions"
)
require
.
Equal
(
t
,
test
.
status
!=
types
.
GameStatusInProgress
,
done
,
"should be done when not in progress"
)
errLog
:=
handler
.
FindLog
(
test
.
logLevel
,
test
.
logMsg
)
require
.
NotNil
(
t
,
errLog
,
"should log game result"
)
...
...
@@ -87,43 +105,57 @@ func TestProgressGame_LogGameStatus(t *testing.T) {
}
}
func
setupProgressGameTest
(
t
*
testing
.
T
,
agreeWithProposedRoot
bool
)
(
*
testlog
.
CapturingHandler
,
*
GamePlayer
,
*
stubActor
,
*
stubGameInfo
)
{
func
TestDoNotActOnCompleteGame
(
t
*
testing
.
T
)
{
for
_
,
status
:=
range
[]
types
.
GameStatus
{
types
.
GameStatusChallengerWon
,
types
.
GameStatusDefenderWon
}
{
t
.
Run
(
status
.
String
(),
func
(
t
*
testing
.
T
)
{
_
,
game
,
gameState
:=
setupProgressGameTest
(
t
,
true
)
gameState
.
status
=
status
done
:=
game
.
ProgressGame
(
context
.
Background
())
require
.
Equal
(
t
,
1
,
gameState
.
callCount
,
"acts the first time"
)
require
.
True
(
t
,
done
,
"should be done"
)
// Should not act when it knows the game is already complete
done
=
game
.
ProgressGame
(
context
.
Background
())
require
.
Equal
(
t
,
1
,
gameState
.
callCount
,
"does not act after game is complete"
)
require
.
True
(
t
,
done
,
"should still be done"
)
})
}
}
func
setupProgressGameTest
(
t
*
testing
.
T
,
agreeWithProposedRoot
bool
)
(
*
testlog
.
CapturingHandler
,
*
GamePlayer
,
*
stubGameState
)
{
logger
:=
testlog
.
Logger
(
t
,
log
.
LvlDebug
)
handler
:=
&
testlog
.
CapturingHandler
{
Delegate
:
logger
.
GetHandler
(),
}
logger
.
SetHandler
(
handler
)
actor
:=
&
stubActor
{}
gameInfo
:=
&
stubGameInfo
{
claimCount
:
1
}
gameState
:=
&
stubGameState
{
claimCount
:
1
}
game
:=
&
GamePlayer
{
agent
:
actor
,
agent
:
gameState
,
agreeWithProposedOutput
:
agreeWithProposedRoot
,
caller
:
game
Info
,
caller
:
game
State
,
logger
:
logger
,
}
return
handler
,
game
,
actor
,
gameInfo
}
type
stubActor
struct
{
callCount
int
err
error
return
handler
,
game
,
gameState
}
func
(
a
*
stubActor
)
Act
(
ctx
context
.
Context
)
error
{
a
.
callCount
++
return
a
.
err
}
type
stubGameInfo
struct
{
type
stubGameState
struct
{
status
types
.
GameStatus
claimCount
uint64
err
error
callCount
int
actErr
error
Err
error
}
func
(
s
*
stubGameState
)
Act
(
ctx
context
.
Context
)
error
{
s
.
callCount
++
return
s
.
actErr
}
func
(
s
*
stubGame
Info
)
GetGameStatus
(
ctx
context
.
Context
)
(
types
.
GameStatus
,
error
)
{
return
s
.
status
,
s
.
err
func
(
s
*
stubGame
State
)
GetGameStatus
(
ctx
context
.
Context
)
(
types
.
GameStatus
,
error
)
{
return
s
.
status
,
nil
}
func
(
s
*
stubGame
Info
)
GetClaimCount
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
return
s
.
claimCount
,
s
.
err
func
(
s
*
stubGame
State
)
GetClaimCount
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
return
s
.
claimCount
,
nil
}
op-challenger/fault/responder.go
View file @
a145e096
...
...
@@ -79,18 +79,25 @@ func (r *faultResponder) BuildTx(ctx context.Context, response types.Claim) ([]b
}
}
// Ca
n
Resolve determines if the resolve function on the fault dispute game contract
// would succeed. Returns t
rue if the game can be resolved, otherwise fal
se.
func
(
r
*
faultResponder
)
Ca
nResolve
(
ctx
context
.
Context
)
bool
{
// Ca
ll
Resolve determines if the resolve function on the fault dispute game contract
// would succeed. Returns t
he game status if the call would succeed, errors otherwi
se.
func
(
r
*
faultResponder
)
Ca
llResolve
(
ctx
context
.
Context
)
(
types
.
GameStatus
,
error
)
{
txData
,
err
:=
r
.
buildResolveData
()
if
err
!=
nil
{
return
false
return
types
.
GameStatusInProgress
,
err
}
_
,
err
=
r
.
txMgr
.
Call
(
ctx
,
ethereum
.
CallMsg
{
res
,
err
:
=
r
.
txMgr
.
Call
(
ctx
,
ethereum
.
CallMsg
{
To
:
&
r
.
fdgAddr
,
Data
:
txData
,
},
nil
)
return
err
==
nil
if
err
!=
nil
{
return
types
.
GameStatusInProgress
,
err
}
var
status
uint8
if
err
=
r
.
fdgAbi
.
UnpackIntoInterface
(
&
status
,
"resolve"
,
res
);
err
!=
nil
{
return
types
.
GameStatusInProgress
,
err
}
return
types
.
GameStatusFromUint8
(
status
)
}
// Resolve executes a resolve transaction to resolve a fault dispute game.
...
...
op-challenger/fault/responder_test.go
View file @
a145e096
...
...
@@ -22,13 +22,138 @@ import (
var
(
mockFdgAddress
=
common
.
HexToAddress
(
"0x1234"
)
mockSendError
=
errors
.
New
(
"mock send error"
)
mockCallError
=
errors
.
New
(
"mock call error"
)
)
// TestCallResolve tests the [Responder.CallResolve].
func
TestCallResolve
(
t
*
testing
.
T
)
{
t
.
Run
(
"SendFails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
callFails
=
true
status
,
err
:=
responder
.
CallResolve
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
mockCallError
)
require
.
Equal
(
t
,
types
.
GameStatusInProgress
,
status
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
calls
)
})
t
.
Run
(
"UnpackFails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
callBytes
=
[]
byte
{
0x00
,
0x01
}
status
,
err
:=
responder
.
CallResolve
(
context
.
Background
())
require
.
Error
(
t
,
err
)
require
.
Equal
(
t
,
types
.
GameStatusInProgress
,
status
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
calls
)
})
t
.
Run
(
"Success"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
status
,
err
:=
responder
.
CallResolve
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
types
.
GameStatusInProgress
,
status
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
calls
)
})
}
// TestResolve tests the [Responder.Resolve] method.
func
TestResolve
(
t
*
testing
.
T
)
{
t
.
Run
(
"SendFails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
sendFails
=
true
err
:=
responder
.
Resolve
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
mockSendError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
})
t
.
Run
(
"Success"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
err
:=
responder
.
Resolve
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
sends
)
})
}
// TestRespond tests the [Responder.Respond] method.
func
TestRespond
(
t
*
testing
.
T
)
{
t
.
Run
(
"send fails"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
mockTxMgr
.
sendFails
=
true
err
:=
responder
.
Respond
(
context
.
Background
(),
generateMockResponseClaim
())
require
.
ErrorIs
(
t
,
err
,
mockSendError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
})
t
.
Run
(
"sends response"
,
func
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
)
err
:=
responder
.
Respond
(
context
.
Background
(),
generateMockResponseClaim
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
sends
)
})
}
// TestBuildTx tests the [Responder.BuildTx] method.
func
TestBuildTx
(
t
*
testing
.
T
)
{
t
.
Run
(
"attack"
,
func
(
t
*
testing
.
T
)
{
responder
,
_
:=
newTestFaultResponder
(
t
)
responseClaim
:=
generateMockResponseClaim
()
responseClaim
.
ParentContractIndex
=
7
tx
,
err
:=
responder
.
BuildTx
(
context
.
Background
(),
responseClaim
)
require
.
NoError
(
t
,
err
)
// Pack the tx data manually.
fdgAbi
,
err
:=
bindings
.
FaultDisputeGameMetaData
.
GetAbi
()
require
.
NoError
(
t
,
err
)
parent
:=
big
.
NewInt
(
int64
(
7
))
claim
:=
responseClaim
.
ValueBytes
()
expected
,
err
:=
fdgAbi
.
Pack
(
"attack"
,
parent
,
claim
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
tx
)
})
t
.
Run
(
"defend"
,
func
(
t
*
testing
.
T
)
{
responder
,
_
:=
newTestFaultResponder
(
t
)
responseClaim
:=
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x01
},
Position
:
types
.
NewPositionFromGIndex
(
3
),
},
Parent
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x02
},
Position
:
types
.
NewPositionFromGIndex
(
6
),
},
ContractIndex
:
0
,
ParentContractIndex
:
7
,
}
tx
,
err
:=
responder
.
BuildTx
(
context
.
Background
(),
responseClaim
)
require
.
NoError
(
t
,
err
)
// Pack the tx data manually.
fdgAbi
,
err
:=
bindings
.
FaultDisputeGameMetaData
.
GetAbi
()
require
.
NoError
(
t
,
err
)
parent
:=
big
.
NewInt
(
int64
(
7
))
claim
:=
responseClaim
.
ValueBytes
()
expected
,
err
:=
fdgAbi
.
Pack
(
"defend"
,
parent
,
claim
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
tx
)
})
}
func
newTestFaultResponder
(
t
*
testing
.
T
)
(
*
faultResponder
,
*
mockTxManager
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
mockTxMgr
:=
&
mockTxManager
{}
responder
,
err
:=
NewFaultResponder
(
log
,
mockTxMgr
,
mockFdgAddress
)
require
.
NoError
(
t
,
err
)
return
responder
,
mockTxMgr
}
type
mockTxManager
struct
{
from
common
.
Address
sends
int
calls
int
sendFails
bool
callFails
bool
callBytes
[]
byte
}
func
(
m
*
mockTxManager
)
Send
(
ctx
context
.
Context
,
candidate
txmgr
.
TxCandidate
)
(
*
ethtypes
.
Receipt
,
error
)
{
...
...
@@ -44,11 +169,16 @@ func (m *mockTxManager) Send(ctx context.Context, candidate txmgr.TxCandidate) (
}
func
(
m
*
mockTxManager
)
Call
(
_
context
.
Context
,
_
ethereum
.
CallMsg
,
_
*
big
.
Int
)
([]
byte
,
error
)
{
if
m
.
send
Fails
{
return
nil
,
mock
Send
Error
if
m
.
call
Fails
{
return
nil
,
mock
Call
Error
}
m
.
calls
++
return
[]
byte
{},
nil
if
m
.
callBytes
!=
nil
{
return
m
.
callBytes
,
nil
}
return
common
.
Hex2Bytes
(
"0000000000000000000000000000000000000000000000000000000000000000"
,
),
nil
}
func
(
m
*
mockTxManager
)
BlockNumber
(
ctx
context
.
Context
)
(
uint64
,
error
)
{
...
...
@@ -59,56 +189,8 @@ func (m *mockTxManager) From() common.Address {
return
m
.
from
}
func
newTestFaultResponder
(
t
*
testing
.
T
,
sendFails
bool
)
(
*
faultResponder
,
*
mockTxManager
)
{
log
:=
testlog
.
Logger
(
t
,
log
.
LvlError
)
mockTxMgr
:=
&
mockTxManager
{}
mockTxMgr
.
sendFails
=
sendFails
responder
,
err
:=
NewFaultResponder
(
log
,
mockTxMgr
,
mockFdgAddress
)
require
.
NoError
(
t
,
err
)
return
responder
,
mockTxMgr
}
// TestResponder_CanResolve_CallFails tests the [Responder.CanResolve] method
// bubbles up the error returned by the [txmgr.Call] method.
func
TestResponder_CanResolve_CallFails
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
true
)
resolved
:=
responder
.
CanResolve
(
context
.
Background
())
require
.
False
(
t
,
resolved
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
}
// TestResponder_CanResolve_Success tests the [Responder.CanResolve] method
// succeeds when the call message is successfully sent through the txmgr.
func
TestResponder_CanResolve_Success
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
false
)
resolved
:=
responder
.
CanResolve
(
context
.
Background
())
require
.
True
(
t
,
resolved
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
calls
)
}
// TestResponder_Resolve_SendFails tests the [Responder.Resolve] method
// bubbles up the error returned by the [txmgr.Send] method.
func
TestResponder_Resolve_SendFails
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
true
)
err
:=
responder
.
Resolve
(
context
.
Background
())
require
.
ErrorIs
(
t
,
err
,
mockSendError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
}
// TestResponder_Resolve_Success tests the [Responder.Resolve] method
// succeeds when the tx candidate is successfully sent through the txmgr.
func
TestResponder_Resolve_Success
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
false
)
err
:=
responder
.
Resolve
(
context
.
Background
())
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
sends
)
}
// TestResponder_Respond_SendFails tests the [Responder.Respond] method
// bubbles up the error returned by the [txmgr.Send] method.
func
TestResponder_Respond_SendFails
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
true
)
err
:=
responder
.
Respond
(
context
.
Background
(),
types
.
Claim
{
func
generateMockResponseClaim
()
types
.
Claim
{
return
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x01
},
Position
:
types
.
NewPositionFromGIndex
(
2
),
...
...
@@ -119,89 +201,5 @@ func TestResponder_Respond_SendFails(t *testing.T) {
},
ContractIndex
:
0
,
ParentContractIndex
:
0
,
})
require
.
ErrorIs
(
t
,
err
,
mockSendError
)
require
.
Equal
(
t
,
0
,
mockTxMgr
.
sends
)
}
// TestResponder_Respond_Success tests the [Responder.Respond] method
// succeeds when the tx candidate is successfully sent through the txmgr.
func
TestResponder_Respond_Success
(
t
*
testing
.
T
)
{
responder
,
mockTxMgr
:=
newTestFaultResponder
(
t
,
false
)
err
:=
responder
.
Respond
(
context
.
Background
(),
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x01
},
Position
:
types
.
NewPositionFromGIndex
(
2
),
},
Parent
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x02
},
Position
:
types
.
NewPositionFromGIndex
(
1
),
},
ContractIndex
:
0
,
ParentContractIndex
:
0
,
})
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
1
,
mockTxMgr
.
sends
)
}
// TestResponder_BuildTx_Attack tests the [Responder.BuildTx] method
// returns a tx candidate with the correct data for an attack tx.
func
TestResponder_BuildTx_Attack
(
t
*
testing
.
T
)
{
responder
,
_
:=
newTestFaultResponder
(
t
,
false
)
responseClaim
:=
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x01
},
Position
:
types
.
NewPositionFromGIndex
(
2
),
},
Parent
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x02
},
Position
:
types
.
NewPositionFromGIndex
(
1
),
},
ContractIndex
:
0
,
ParentContractIndex
:
7
,
}
tx
,
err
:=
responder
.
BuildTx
(
context
.
Background
(),
responseClaim
)
require
.
NoError
(
t
,
err
)
// Pack the tx data manually.
fdgAbi
,
err
:=
bindings
.
FaultDisputeGameMetaData
.
GetAbi
()
require
.
NoError
(
t
,
err
)
expected
,
err
:=
fdgAbi
.
Pack
(
"attack"
,
big
.
NewInt
(
int64
(
7
)),
responseClaim
.
ValueBytes
(),
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
tx
)
}
// TestResponder_BuildTx_Defend tests the [Responder.BuildTx] method
// returns a tx candidate with the correct data for a defend tx.
func
TestResponder_BuildTx_Defend
(
t
*
testing
.
T
)
{
responder
,
_
:=
newTestFaultResponder
(
t
,
false
)
responseClaim
:=
types
.
Claim
{
ClaimData
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x01
},
Position
:
types
.
NewPositionFromGIndex
(
3
),
},
Parent
:
types
.
ClaimData
{
Value
:
common
.
Hash
{
0x02
},
Position
:
types
.
NewPositionFromGIndex
(
6
),
},
ContractIndex
:
0
,
ParentContractIndex
:
7
,
}
tx
,
err
:=
responder
.
BuildTx
(
context
.
Background
(),
responseClaim
)
require
.
NoError
(
t
,
err
)
// Pack the tx data manually.
fdgAbi
,
err
:=
bindings
.
FaultDisputeGameMetaData
.
GetAbi
()
require
.
NoError
(
t
,
err
)
expected
,
err
:=
fdgAbi
.
Pack
(
"defend"
,
big
.
NewInt
(
int64
(
7
)),
responseClaim
.
ValueBytes
(),
)
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
expected
,
tx
)
}
op-challenger/fault/service.go
View file @
a145e096
...
...
@@ -73,7 +73,7 @@ func NewService(ctx context.Context, logger log.Logger, cfg *config.Config) (*se
}
loader
:=
NewGameLoader
(
factory
)
monitor
:=
newGameMonitor
(
logger
,
cl
,
client
.
BlockNumber
,
cfg
.
GameAllowlist
,
loader
,
func
(
addr
common
.
Address
)
(
gamePlayer
,
error
)
{
monitor
:=
newGameMonitor
(
logger
,
c
fg
.
GameWindow
,
c
l
,
client
.
BlockNumber
,
cfg
.
GameAllowlist
,
loader
,
func
(
addr
common
.
Address
)
(
gamePlayer
,
error
)
{
return
NewGamePlayer
(
ctx
,
logger
,
cfg
,
addr
,
txMgr
,
client
)
})
...
...
op-challenger/fault/types/types.go
View file @
a145e096
...
...
@@ -3,6 +3,7 @@ package types
import
(
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
...
...
@@ -34,6 +35,14 @@ func (s GameStatus) String() string {
}
}
// GameStatusFromUint8 returns a game status from the uint8 representation.
func
GameStatusFromUint8
(
i
uint8
)
(
GameStatus
,
error
)
{
if
i
>
2
{
return
GameStatus
(
i
),
fmt
.
Errorf
(
"invalid game status: %d"
,
i
)
}
return
GameStatus
(
i
),
nil
}
// PreimageOracleData encapsulates the preimage oracle data
// to load into the onchain oracle.
type
PreimageOracleData
struct
{
...
...
op-challenger/fault/types/types_test.go
View file @
a145e096
package
types
import
(
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
var
validGameStatuses
=
[]
GameStatus
{
GameStatusInProgress
,
GameStatusChallengerWon
,
GameStatusDefenderWon
,
}
func
TestGameStatusFromUint8
(
t
*
testing
.
T
)
{
for
_
,
status
:=
range
validGameStatuses
{
t
.
Run
(
fmt
.
Sprintf
(
"Valid Game Status %v"
,
status
),
func
(
t
*
testing
.
T
)
{
parsed
,
err
:=
GameStatusFromUint8
(
uint8
(
status
))
require
.
NoError
(
t
,
err
)
require
.
Equal
(
t
,
status
,
parsed
)
})
}
t
.
Run
(
"Invalid"
,
func
(
t
*
testing
.
T
)
{
status
,
err
:=
GameStatusFromUint8
(
3
)
require
.
Error
(
t
,
err
)
require
.
Equal
(
t
,
GameStatus
(
3
),
status
)
})
}
func
TestNewPreimageOracleData
(
t
*
testing
.
T
)
{
t
.
Run
(
"LocalData"
,
func
(
t
*
testing
.
T
)
{
data
:=
NewPreimageOracleData
([]
byte
{
1
,
2
,
3
},
[]
byte
{
4
,
5
,
6
},
7
)
...
...
op-challenger/flags/flags.go
View file @
a145e096
...
...
@@ -109,6 +109,12 @@ var (
EnvVars
:
prefixEnvVars
(
"CANNON_SNAPSHOT_FREQ"
),
Value
:
config
.
DefaultCannonSnapshotFreq
,
}
GameWindowFlag
=
&
cli
.
DurationFlag
{
Name
:
"game-window"
,
Usage
:
"The time window which the challenger will look for games to progress."
,
EnvVars
:
prefixEnvVars
(
"GAME_WINDOW"
),
Value
:
config
.
DefaultGameWindow
,
}
)
// requiredFlags are checked by [CheckRequired]
...
...
@@ -132,6 +138,7 @@ var optionalFlags = []cli.Flag{
CannonDatadirFlag
,
CannonL2Flag
,
CannonSnapshotFreqFlag
,
GameWindowFlag
,
}
func
init
()
{
...
...
@@ -222,6 +229,7 @@ func NewConfigFromCLI(ctx *cli.Context) (*config.Config, error) {
TraceType
:
traceTypeFlag
,
GameFactoryAddress
:
gameFactoryAddress
,
GameAllowlist
:
allowedGames
,
GameWindow
:
ctx
.
Duration
(
GameWindowFlag
.
Name
),
AlphabetTrace
:
ctx
.
String
(
AlphabetFlag
.
Name
),
CannonNetwork
:
ctx
.
String
(
CannonNetworkFlag
.
Name
),
CannonRollupConfigPath
:
ctx
.
String
(
CannonRollupConfigFlag
.
Name
),
...
...
package.json
View file @
a145e096
...
...
@@ -68,7 +68,7 @@
"
markdownlint-cli2
"
:
"
0.4.0
"
,
"
mkdirp
"
:
"
^1.0.4
"
,
"
mocha
"
:
"
^10.2.0
"
,
"
nx
"
:
"
16.7.
2
"
,
"
nx
"
:
"
16.7.
3
"
,
"
nyc
"
:
"
^15.1.0
"
,
"
patch-package
"
:
"
^8.0.0
"
,
"
prettier
"
:
"
^2.8.0
"
,
...
...
packages/contracts-bedrock/package.json
View file @
a145e096
...
...
@@ -41,7 +41,7 @@
"lint"
:
"pnpm lint:fix && pnpm lint:check"
},
"devDependencies"
:
{
"@typescript-eslint/eslint-plugin"
:
"^
6.4
.0"
,
"@typescript-eslint/eslint-plugin"
:
"^
5.62
.0"
,
"@typescript-eslint/parser"
:
"^6.4.0"
,
"tsx"
:
"^3.12.7"
,
"typescript"
:
"^5.1.6"
...
...
pnpm-lock.yaml
View file @
a145e096
...
...
@@ -38,7 +38,7 @@ importers:
version
:
12.20.20
'
@typescript-eslint/eslint-plugin'
:
specifier
:
^5.60.1
version
:
5.6
0.1
(@typescript-eslint/parser@5.60.1)(eslint@8.47.0)(typescript@5.1.6)
version
:
5.6
2.0
(@typescript-eslint/parser@5.60.1)(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/parser'
:
specifier
:
^5.60.1
version
:
5.60.1(eslint@8.47.0)(typescript@5.1.6)
...
...
@@ -109,8 +109,8 @@ importers:
specifier
:
^10.2.0
version
:
10.2.0
nx
:
specifier
:
16.7.
2
version
:
16.7.
2
specifier
:
16.7.
3
version
:
16.7.
3
nyc
:
specifier
:
^15.1.0
version
:
15.1.0
...
...
@@ -268,8 +268,8 @@ importers:
packages/contracts-bedrock
:
devDependencies
:
'
@typescript-eslint/eslint-plugin'
:
specifier
:
^
6.4
.0
version
:
6.4
.0(@typescript-eslint/parser@6.4.0)(eslint@8.47.0)(typescript@5.1.6)
specifier
:
^
5.62
.0
version
:
5.62
.0(@typescript-eslint/parser@6.4.0)(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/parser'
:
specifier
:
^6.4.0
version
:
6.4.0(eslint@8.47.0)(typescript@5.1.6)
...
...
@@ -1005,7 +1005,7 @@ packages:
/@changesets/apply-release-plan@6.1.3
:
resolution
:
{
integrity
:
sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/config'
:
2.3.0
'
@changesets/get-version-range-type'
:
0.3.2
'
@changesets/git'
:
2.0.0
...
...
@@ -1023,7 +1023,7 @@ packages:
/@changesets/assemble-release-plan@5.2.3
:
resolution
:
{
integrity
:
sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/errors'
:
0.1.4
'
@changesets/get-dependents-graph'
:
1.3.5
'
@changesets/types'
:
5.2.1
...
...
@@ -1126,7 +1126,7 @@ packages:
/@changesets/get-release-plan@3.0.16
:
resolution
:
{
integrity
:
sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/assemble-release-plan'
:
5.2.3
'
@changesets/config'
:
2.3.0
'
@changesets/pre'
:
1.0.14
...
...
@@ -1142,7 +1142,7 @@ packages:
/@changesets/git@2.0.0
:
resolution
:
{
integrity
:
sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/errors'
:
0.1.4
'
@changesets/types'
:
5.2.1
'
@manypkg/get-packages'
:
1.1.3
...
...
@@ -1167,7 +1167,7 @@ packages:
/@changesets/pre@1.0.14
:
resolution
:
{
integrity
:
sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/errors'
:
0.1.4
'
@changesets/types'
:
5.2.1
'
@manypkg/get-packages'
:
1.1.3
...
...
@@ -1177,7 +1177,7 @@ packages:
/@changesets/read@0.5.9
:
resolution
:
{
integrity
:
sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/git'
:
2.0.0
'
@changesets/logger'
:
0.0.5
'
@changesets/parse'
:
0.3.16
...
...
@@ -1197,7 +1197,7 @@ packages:
/@changesets/write@0.2.3
:
resolution
:
{
integrity
:
sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/types'
:
5.2.1
fs-extra
:
7.0.1
human-id
:
1.0.2
...
...
@@ -1738,11 +1738,6 @@ packages:
eslint-visitor-keys
:
3.4.3
dev
:
true
/@eslint-community/regexpp@4.5.1
:
resolution
:
{
integrity
:
sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==
}
engines
:
{
node
:
^12.0.0 || ^14.0.0 || >=16.0.0
}
dev
:
true
/@eslint-community/regexpp@4.6.2
:
resolution
:
{
integrity
:
sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==
}
engines
:
{
node
:
^12.0.0 || ^14.0.0 || >=16.0.0
}
...
...
@@ -2517,7 +2512,7 @@ packages:
dependencies
:
'
@lerna/child-process'
:
7.1.5
'
@npmcli/run-script'
:
6.0.2
'
@nx/devkit'
:
16.7.1(nx@16.7.
2
)
'
@nx/devkit'
:
16.7.1(nx@16.7.
3
)
'
@octokit/plugin-enterprise-rest'
:
6.0.1
'
@octokit/rest'
:
19.0.11
byte-size
:
8.1.1
...
...
@@ -2553,7 +2548,7 @@ packages:
npm-packlist
:
5.1.1
npm-registry-fetch
:
14.0.5
npmlog
:
6.0.2
nx
:
16.7.
2
nx
:
16.7.
3
p-map
:
4.0.0
p-map-series
:
2.1.0
p-queue
:
6.6.2
...
...
@@ -2608,7 +2603,7 @@ packages:
/@manypkg/get-packages@1.1.3
:
resolution
:
{
integrity
:
sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==
}
dependencies
:
'
@babel/runtime'
:
7.2
0.7
'
@babel/runtime'
:
7.2
2.6
'
@changesets/types'
:
4.1.0
'
@manypkg/find-root'
:
1.1.0
fs-extra
:
8.1.0
...
...
@@ -2838,10 +2833,10 @@ packages:
-
supports-color
dev
:
true
/@nrwl/devkit@16.7.1(nx@16.7.
2
)
:
/@nrwl/devkit@16.7.1(nx@16.7.
3
)
:
resolution
:
{
integrity
:
sha512-ysAgNju6o7QjG/ZHW0wIRJ8yWxjhErjqQ8GZ2Smqsb1myrr6UbYsuxaXjoOHI56fMmGyNPK04zzyNXXWQw/UAA==
}
dependencies
:
'
@nx/devkit'
:
16.7.1(nx@16.7.
2
)
'
@nx/devkit'
:
16.7.1(nx@16.7.
3
)
transitivePeerDependencies
:
-
nx
dev
:
true
...
...
@@ -2854,11 +2849,11 @@ packages:
-
debug
dev
:
true
/@nrwl/tao@16.7.
2
:
resolution
:
{
integrity
:
sha512-
4Wc3ic5VtZL3t4qqCMJlEad/wWuFxNUX78U5ohEStN3UFFJIjwJJpKZYZDtxhaOLWUdXbk6CI3KfSIpWgwPdbQ
==
}
/@nrwl/tao@16.7.
3
:
resolution
:
{
integrity
:
sha512-
kaH0i7ZuncSW8hGXg6DVlUBG319lUG/ene6aJUeV1spOxEsEqlckCm9HfJPfcVntvh9m1LauW+yk64cw/biVwg
==
}
hasBin
:
true
dependencies
:
nx
:
16.7.
2
nx
:
16.7.
3
tslib
:
2.6.0
transitivePeerDependencies
:
-
'
@swc-node/register'
...
...
@@ -2866,23 +2861,23 @@ packages:
-
debug
dev
:
true
/@nx/devkit@16.7.1(nx@16.7.
2
)
:
/@nx/devkit@16.7.1(nx@16.7.
3
)
:
resolution
:
{
integrity
:
sha512-PASQGd1YhcAA/hpupCsSakP71Qh1pYle4dtF+wh3KDe2kdeM6BgccClapiGcXAI46JKLUGAbNYJ8pg7GEPY5Nw==
}
peerDependencies
:
nx
:
'
>=
15
<=
17'
dependencies
:
'
@nrwl/devkit'
:
16.7.1(nx@16.7.
2
)
'
@nrwl/devkit'
:
16.7.1(nx@16.7.
3
)
ejs
:
3.1.9
enquirer
:
2.3.6
ignore
:
5.2.4
nx
:
16.7.
2
nx
:
16.7.
3
semver
:
7.5.3
tmp
:
0.2.1
tslib
:
2.6.0
dev
:
true
/@nx/nx-darwin-arm64@16.7.
2
:
resolution
:
{
integrity
:
sha512-
dkTHAzOTbqRHUQtnw7knEJq4ll6hew11u+9B0fThs9gC/X0iPK0eDXD4TqbIKEbcWAsxpuGiWPzGoNPo7Gwl9
A==
}
/@nx/nx-darwin-arm64@16.7.
3
:
resolution
:
{
integrity
:
sha512-
s1woGSGbNEzDSzNoSIIpaYkVwJmM0D89/1QmccVZIv7jvGGcqx4ONQPsBylWpDco3IeTDhNsOMzMhF3fvqhtg
A==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
arm64
]
os
:
[
darwin
]
...
...
@@ -2890,8 +2885,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-darwin-x64@16.7.
2
:
resolution
:
{
integrity
:
sha512-
EKhjX7DCRIA5U8yAxIgGXeIFaq1dhgLJy8OAG4n1Ud8c21px+bBSrcZvv0ww5VoEulhggQ+c6fW1cjKtGgLkn
Q==
}
/@nx/nx-darwin-x64@16.7.
3
:
resolution
:
{
integrity
:
sha512-
J9lE+T7Hm3hD+s33xidxa6Jkq2CCKZwwTrLO+Ff1/A2d4T13d16O/Rf3Y/nuveUjCVEYwwYkk4G5v2FPJ4i3S
Q==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
x64
]
os
:
[
darwin
]
...
...
@@ -2899,8 +2894,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-freebsd-x64@16.7.
2
:
resolution
:
{
integrity
:
sha512-
3QhXZq0wxvi4lg1MJqwq72F7PE/d0Hcl3uwheenYQtwUvAFAmijC/Z4AVPSqbKJ+QaoqASnXRim9z3EIfeD+DQ
==
}
/@nx/nx-freebsd-x64@16.7.
3
:
resolution
:
{
integrity
:
sha512-
/1WrplEyxTkoARsCUcI2FjMVy2AFuaH2oS1vFuGtBchWoKbgFZd3Aek8+oYt0wiQ7cfBxs2y92UqvTOhLygxOw
==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
x64
]
os
:
[
freebsd
]
...
...
@@ -2908,8 +2903,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-linux-arm-gnueabihf@16.7.
2
:
resolution
:
{
integrity
:
sha512-
7bny8NvE9iyfwRfq9/mOZjzMNWthT70Ce1N9suB2zdbgbLUEDPQQhBNbg969yT6/LbWMWuWZXeIbz/Fwndf9z
A==
}
/@nx/nx-linux-arm-gnueabihf@16.7.
3
:
resolution
:
{
integrity
:
sha512-
Z3CLZcxBnpra8nlizK97eyohI9x+JPh4wp+87x9WvIiLGd+k3hO42nth/q0xXJs2G5emQN8cSLPscGzbZodVp
A==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
arm
]
os
:
[
linux
]
...
...
@@ -2917,8 +2912,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-linux-arm64-gnu@16.7.
2
:
resolution
:
{
integrity
:
sha512-
+UdeFB1HY/3GU2+mflydFWpztghFRQiVzJV6MTcjtOzE3jfgXzz9TP580pDxozTvNSRPlblH07X+iB8DhVcB9w
==
}
/@nx/nx-linux-arm64-gnu@16.7.
3
:
resolution
:
{
integrity
:
sha512-
a4E4psBgU0b7ZT99630mylxcrlLObgy4bA6JrT+4XIFAcaHkfCmWLupPyXgBCmSqQN01jsuXSYm/t7EWjKL98Q
==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
arm64
]
os
:
[
linux
]
...
...
@@ -2926,8 +2921,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-linux-arm64-musl@16.7.
2
:
resolution
:
{
integrity
:
sha512-
YfkWu+4GKXageuYiH5a77gIDAXnit5SIyfI+RWe/j04uFy171KnUt167DC417fv/fTGxeXY1tzOu112Y+x5ix
w==
}
/@nx/nx-linux-arm64-musl@16.7.
3
:
resolution
:
{
integrity
:
sha512-
vl+WONX6uOS8uGwtcAlb4yiAh2ws/gZSLaIURJaDnf509FrYTb/RsBca5BskOQUYkKSI//6oQu653TRDKYxyW
w==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
arm64
]
os
:
[
linux
]
...
...
@@ -2935,8 +2930,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-linux-x64-gnu@16.7.
2
:
resolution
:
{
integrity
:
sha512-
/TtSa2rHR+1gNuALR1yafl4fzBK2/GAhosf+skn00OgwsJ0c8ie9tuuftlMo+2n3LcXY/IaPDaD7t6fln4qsQg
==
}
/@nx/nx-linux-x64-gnu@16.7.
3
:
resolution
:
{
integrity
:
sha512-
udZ+6IOYv0Ra0MRpbAW8TSFdcUxtfuIryRsGVF2767HeWqHzOhLynmJyJPatJ7gXMVFaL7+zfcAoV6fm7My1FQ
==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
x64
]
os
:
[
linux
]
...
...
@@ -2944,8 +2939,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-linux-x64-musl@16.7.
2
:
resolution
:
{
integrity
:
sha512-
VC638hxdWSA8VTDU9rAXjr60mmMP3ZyCUbSkJ+8ydEe83StMDY3PAXS5Hw3n/ouxDfCF9r1kWIGFe4g+emvfB
w==
}
/@nx/nx-linux-x64-musl@16.7.
3
:
resolution
:
{
integrity
:
sha512-
LQW1ttQWNekHoJTrzXMumaMxfYRcjsuGQP8Ki2pWuw43TFTQyI6Cfgk8/wjKv8ATc772cF9Tadyz4+JEIQlcN
w==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
x64
]
os
:
[
linux
]
...
...
@@ -2953,8 +2948,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-win32-arm64-msvc@16.7.
2
:
resolution
:
{
integrity
:
sha512-
sSUqgANLgQFFzKTvyMczh5D6xiqTQnB8daJTLX+QUCv5vO5+ZSwuVDyNfr6g/HV2+ak0M9/wVQUae11TgUIPYw
==
}
/@nx/nx-win32-arm64-msvc@16.7.
3
:
resolution
:
{
integrity
:
sha512-
wCrpGqh5fPrlkhHZXVSPBDs9E3L5vIJHtdPrc1QP1uCQiV41mpauey31p6rjvQUWYCC0BGTWJGF+hAY7wYUHdg
==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
arm64
]
os
:
[
win32
]
...
...
@@ -2962,8 +2957,8 @@ packages:
dev
:
true
optional
:
true
/@nx/nx-win32-x64-msvc@16.7.
2
:
resolution
:
{
integrity
:
sha512-
+n01cT9/P3o95x+FlRWYf9sFZ29ooxYD/WLcmxACeXN0V1bdbnZxKVSuJqrXZhmpHe7P+/+IRmniv9cdpkxz7g
==
}
/@nx/nx-win32-x64-msvc@16.7.
3
:
resolution
:
{
integrity
:
sha512-
Ja2+VhMFWiVsZt3mkdsU1MCotQlAxG94zFiJYbXufsERJItWuN4i0mZjeZITiRBosEmkn4SeAUkg+xuiH+q4GA
==
}
engines
:
{
node
:
'
>=
10'
}
cpu
:
[
x64
]
os
:
[
win32
]
...
...
@@ -3980,10 +3975,6 @@ packages:
pretty-format
:
29.6.1
dev
:
true
/@types/json-schema@7.0.11
:
resolution
:
{
integrity
:
sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
}
dev
:
true
/@types/json-schema@7.0.12
:
resolution
:
{
integrity
:
sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
}
dev
:
true
...
...
@@ -4165,10 +4156,6 @@ packages:
resolution
:
{
integrity
:
sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==
}
dev
:
false
/@types/semver@7.3.13
:
resolution
:
{
integrity
:
sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==
}
dev
:
true
/@types/semver@7.5.0
:
resolution
:
{
integrity
:
sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==
}
dev
:
true
...
...
@@ -4255,8 +4242,8 @@ packages:
'
@types/yargs-parser'
:
21.0.0
dev
:
true
/@typescript-eslint/eslint-plugin@5.6
0.1
(@typescript-eslint/parser@5.60.1)(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw
==
}
/@typescript-eslint/eslint-plugin@5.6
2.0
(@typescript-eslint/parser@5.60.1)(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag
==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
peerDependencies
:
'
@typescript-eslint/parser'
:
^5.0.0
...
...
@@ -4266,29 +4253,29 @@ packages:
typescript
:
optional
:
true
dependencies
:
'
@eslint-community/regexpp'
:
4.
5.1
'
@eslint-community/regexpp'
:
4.
6.2
'
@typescript-eslint/parser'
:
5.60.1(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/scope-manager'
:
5.6
0.1
'
@typescript-eslint/type-utils'
:
5.6
0.1
(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/utils'
:
5.6
0.1
(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/scope-manager'
:
5.6
2.0
'
@typescript-eslint/type-utils'
:
5.6
2.0
(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/utils'
:
5.6
2.0
(eslint@8.47.0)(typescript@5.1.6)
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.47.0
grapheme
-splitter
:
1.0.4
grapheme
r
:
1.4.0
ignore
:
5.2.4
natural-compare-lite
:
1.4.0
semver
:
7.5.
3
semver
:
7.5.
4
tsutils
:
3.21.0(typescript@5.1.6)
typescript
:
5.1.6
transitivePeerDependencies
:
-
supports-color
dev
:
true
/@typescript-eslint/eslint-plugin@
6.4
.0(@typescript-eslint/parser@6.4.0)(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
62o2Hmc7Gs3p8SLfbXcipjWAa6qk2wZGChXG2JbBtYpwSRmti/9KHLqfbLs9uDigOexG+3PaQ9G2g3201FWLK
g==
}
engines
:
{
node
:
^1
6.0.0 || >=18
.0.0
}
/@typescript-eslint/eslint-plugin@
5.62
.0(@typescript-eslint/parser@6.4.0)(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXa
g==
}
engines
:
{
node
:
^1
2.22.0 || ^14.17.0 || >=16
.0.0
}
peerDependencies
:
'
@typescript-eslint/parser'
:
^
6.0.0 || ^6.0.0-alpha
eslint
:
^7.0.0 || ^8.0.0
'
@typescript-eslint/parser'
:
^
5.0.0
eslint
:
^
6.0.0 || ^
7.0.0 || ^8.0.0
typescript
:
'
*'
peerDependenciesMeta
:
typescript
:
...
...
@@ -4296,17 +4283,16 @@ packages:
dependencies
:
'
@eslint-community/regexpp'
:
4.6.2
'
@typescript-eslint/parser'
:
6.4.0(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/scope-manager'
:
6.4.0
'
@typescript-eslint/type-utils'
:
6.4.0(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/utils'
:
6.4.0(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/visitor-keys'
:
6.4.0
'
@typescript-eslint/scope-manager'
:
5.62.0
'
@typescript-eslint/type-utils'
:
5.62.0(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/utils'
:
5.62.0(eslint@8.47.0)(typescript@5.1.6)
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.47.0
graphemer
:
1.4.0
ignore
:
5.2.4
natural-compare
:
1.4.0
natural-compare
-lite
:
1.4.0
semver
:
7.5.4
ts
-api-utils
:
1.0.1
(typescript@5.1.6)
ts
utils
:
3.21.0
(typescript@5.1.6)
typescript
:
5.1.6
transitivePeerDependencies
:
-
supports-color
...
...
@@ -4361,6 +4347,14 @@ packages:
'
@typescript-eslint/visitor-keys'
:
5.60.1
dev
:
true
/@typescript-eslint/scope-manager@5.62.0
:
resolution
:
{
integrity
:
sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dependencies
:
'
@typescript-eslint/types'
:
5.62.0
'
@typescript-eslint/visitor-keys'
:
5.62.0
dev
:
true
/@typescript-eslint/scope-manager@6.4.0
:
resolution
:
{
integrity
:
sha512-TUS7vaKkPWDVvl7GDNHFQMsMruD+zhkd3SdVW0d7b+7Zo+bd/hXJQ8nsiUZMi1jloWo6c9qt3B7Sqo+flC1nig==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -4369,8 +4363,8 @@ packages:
'
@typescript-eslint/visitor-keys'
:
6.4.0
dev
:
true
/@typescript-eslint/type-utils@5.6
0.1
(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A
==
}
/@typescript-eslint/type-utils@5.6
2.0
(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew
==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
peerDependencies
:
eslint
:
'
*'
...
...
@@ -4379,8 +4373,8 @@ packages:
typescript
:
optional
:
true
dependencies
:
'
@typescript-eslint/typescript-estree'
:
5.6
0.1
(typescript@5.1.6)
'
@typescript-eslint/utils'
:
5.6
0.1
(eslint@8.47.0)(typescript@5.1.6)
'
@typescript-eslint/typescript-estree'
:
5.6
2.0
(typescript@5.1.6)
'
@typescript-eslint/utils'
:
5.6
2.0
(eslint@8.47.0)(typescript@5.1.6)
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.47.0
tsutils
:
3.21.0(typescript@5.1.6)
...
...
@@ -4389,31 +4383,16 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/type-utils@6.4.0(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-TvqrUFFyGY0cX3WgDHcdl2/mMCWCDv/0thTtx/ODMY1QhEiyFtv/OlLaNIiYLwRpAxAtOLOY9SUf1H3Q3dlwAg==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
peerDependencies
:
eslint
:
^7.0.0 || ^8.0.0
typescript
:
'
*'
peerDependenciesMeta
:
typescript
:
optional
:
true
dependencies
:
'
@typescript-eslint/typescript-estree'
:
6.4.0(typescript@5.1.6)
'
@typescript-eslint/utils'
:
6.4.0(eslint@8.47.0)(typescript@5.1.6)
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.47.0
ts-api-utils
:
1.0.1(typescript@5.1.6)
typescript
:
5.1.6
transitivePeerDependencies
:
-
supports-color
dev
:
true
/@typescript-eslint/types@5.60.1
:
resolution
:
{
integrity
:
sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dev
:
true
/@typescript-eslint/types@5.62.0
:
resolution
:
{
integrity
:
sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dev
:
true
/@typescript-eslint/types@6.4.0
:
resolution
:
{
integrity
:
sha512-+FV9kVFrS7w78YtzkIsNSoYsnOtrYVnKWSTVXoL1761CsCRv5wpDOINgsXpxD67YCLZtVQekDDyaxfjVWUJmmg==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -4440,6 +4419,27 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/typescript-estree@5.62.0(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
peerDependencies
:
typescript
:
'
*'
peerDependenciesMeta
:
typescript
:
optional
:
true
dependencies
:
'
@typescript-eslint/types'
:
5.62.0
'
@typescript-eslint/visitor-keys'
:
5.62.0
debug
:
4.3.4(supports-color@8.1.1)
globby
:
11.1.0
is-glob
:
4.0.3
semver
:
7.5.4
tsutils
:
3.21.0(typescript@5.1.6)
typescript
:
5.1.6
transitivePeerDependencies
:
-
supports-color
dev
:
true
/@typescript-eslint/typescript-estree@6.4.0(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-iDPJArf/K2sxvjOR6skeUCNgHR/tCQXBsa+ee1/clRKr3olZjZ/dSkXPZjG6YkPtnW6p5D1egeEPMCW6Gn4yLA==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -4461,39 +4461,20 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/utils@5.6
0.1
(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvp
Q==
}
/@typescript-eslint/utils@5.6
2.0
(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-
n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWA
Q==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
peerDependencies
:
eslint
:
^6.0.0 || ^7.0.0 || ^8.0.0
dependencies
:
'
@eslint-community/eslint-utils'
:
4.4.0(eslint@8.47.0)
'
@types/json-schema'
:
7.0.11
'
@types/semver'
:
7.3.13
'
@typescript-eslint/scope-manager'
:
5.60.1
'
@typescript-eslint/types'
:
5.60.1
'
@typescript-eslint/typescript-estree'
:
5.60.1(typescript@5.1.6)
eslint
:
8.47.0
eslint-scope
:
5.1.1
semver
:
7.5.4
transitivePeerDependencies
:
-
supports-color
-
typescript
dev
:
true
/@typescript-eslint/utils@6.4.0(eslint@8.47.0)(typescript@5.1.6)
:
resolution
:
{
integrity
:
sha512-BvvwryBQpECPGo8PwF/y/q+yacg8Hn/2XS+DqL/oRsOPK+RPt29h5Ui5dqOKHDlbXrAeHUTnyG3wZA0KTDxRZw==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
peerDependencies
:
eslint
:
^7.0.0 || ^8.0.0
dependencies
:
'
@eslint-community/eslint-utils'
:
4.4.0(eslint@8.47.0)
'
@types/json-schema'
:
7.0.12
'
@types/semver'
:
7.5.0
'
@typescript-eslint/scope-manager'
:
6.4
.0
'
@typescript-eslint/types'
:
6.4
.0
'
@typescript-eslint/typescript-estree'
:
6.4
.0(typescript@5.1.6)
'
@typescript-eslint/scope-manager'
:
5.62
.0
'
@typescript-eslint/types'
:
5.62
.0
'
@typescript-eslint/typescript-estree'
:
5.62
.0(typescript@5.1.6)
eslint
:
8.47.0
eslint-scope
:
5.1.1
semver
:
7.5.4
transitivePeerDependencies
:
-
supports-color
...
...
@@ -4508,6 +4489,14 @@ packages:
eslint-visitor-keys
:
3.4.3
dev
:
true
/@typescript-eslint/visitor-keys@5.62.0
:
resolution
:
{
integrity
:
sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dependencies
:
'
@typescript-eslint/types'
:
5.62.0
eslint-visitor-keys
:
3.4.3
dev
:
true
/@typescript-eslint/visitor-keys@6.4.0
:
resolution
:
{
integrity
:
sha512-yJSfyT+uJm+JRDWYRYdCm2i+pmvXJSMtPR9Cq5/XQs4QIgNoLcoRtDdzsLbLsFM/c6um6ohQkg/MLxWvoIndJA==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -9493,6 +9482,7 @@ packages:
/grapheme-splitter@1.0.4
:
resolution
:
{
integrity
:
sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
}
dev
:
false
/graphemer@1.4.0
:
resolution
:
{
integrity
:
sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
}
...
...
@@ -10859,7 +10849,7 @@ packages:
'
@lerna/child-process'
:
7.1.5
'
@lerna/create'
:
7.1.5
'
@npmcli/run-script'
:
6.0.2
'
@nx/devkit'
:
16.7.1(nx@16.7.
2
)
'
@nx/devkit'
:
16.7.1(nx@16.7.
3
)
'
@octokit/plugin-enterprise-rest'
:
6.0.1
'
@octokit/rest'
:
19.0.11
byte-size
:
8.1.1
...
...
@@ -10902,7 +10892,7 @@ packages:
npm-packlist
:
5.1.1
npm-registry-fetch
:
14.0.5
npmlog
:
6.0.2
nx
:
16.7.
2
nx
:
16.7.
3
p-map
:
4.0.0
p-map-series
:
2.1.0
p-pipe
:
3.1.0
...
...
@@ -12529,8 +12519,8 @@ packages:
-
debug
dev
:
true
/nx@16.7.
2
:
resolution
:
{
integrity
:
sha512-
T7cRC97qJ4H9fg498ZGwFQaTzJdLQaRp6DFUwzFo1B9qzR56A2tA3HBvT/huo85THaDX+/pcgLyeixJKEE5RPg
==
}
/nx@16.7.
3
:
resolution
:
{
integrity
:
sha512-
aam+1ZesbCfV9xv5FktsAqHVBObcazrf1MG56SdBTYNuILBVgAztPj8NyIZ87ZHw8IE/JxWDDUtZo7lwaSOFzA
==
}
hasBin
:
true
requiresBuild
:
true
peerDependencies
:
...
...
@@ -12542,7 +12532,7 @@ packages:
'
@swc/core'
:
optional
:
true
dependencies
:
'
@nrwl/tao'
:
16.7.
2
'
@nrwl/tao'
:
16.7.
3
'
@parcel/watcher'
:
2.0.4
'
@yarnpkg/lockfile'
:
1.1.0
'
@yarnpkg/parsers'
:
3.0.0-rc.46
...
...
@@ -12578,16 +12568,16 @@ packages:
yargs
:
17.7.2
yargs-parser
:
21.1.1
optionalDependencies
:
'
@nx/nx-darwin-arm64'
:
16.7.
2
'
@nx/nx-darwin-x64'
:
16.7.
2
'
@nx/nx-freebsd-x64'
:
16.7.
2
'
@nx/nx-linux-arm-gnueabihf'
:
16.7.
2
'
@nx/nx-linux-arm64-gnu'
:
16.7.
2
'
@nx/nx-linux-arm64-musl'
:
16.7.
2
'
@nx/nx-linux-x64-gnu'
:
16.7.
2
'
@nx/nx-linux-x64-musl'
:
16.7.
2
'
@nx/nx-win32-arm64-msvc'
:
16.7.
2
'
@nx/nx-win32-x64-msvc'
:
16.7.
2
'
@nx/nx-darwin-arm64'
:
16.7.
3
'
@nx/nx-darwin-x64'
:
16.7.
3
'
@nx/nx-freebsd-x64'
:
16.7.
3
'
@nx/nx-linux-arm-gnueabihf'
:
16.7.
3
'
@nx/nx-linux-arm64-gnu'
:
16.7.
3
'
@nx/nx-linux-arm64-musl'
:
16.7.
3
'
@nx/nx-linux-x64-gnu'
:
16.7.
3
'
@nx/nx-linux-x64-musl'
:
16.7.
3
'
@nx/nx-win32-arm64-msvc'
:
16.7.
3
'
@nx/nx-win32-x64-msvc'
:
16.7.
3
transitivePeerDependencies
:
-
debug
dev
:
true
...
...
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