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
fc64f875
Commit
fc64f875
authored
Jun 21, 2023
by
Kevin Chen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fault-detector: Remove pre-bedrock support.
parent
52eb1a26
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
258 deletions
+141
-258
helpers.ts
packages/fault-detector/src/helpers.ts
+9
-9
service.ts
packages/fault-detector/src/service.ts
+131
-248
helpers.spec.ts
packages/fault-detector/test/helpers.spec.ts
+1
-1
No files found.
packages/fault-detector/src/helpers.ts
View file @
fc64f875
import
{
Contract
,
BigNumber
}
from
'
ethers
'
import
{
Logger
}
from
'
@eth-optimism/common-ts
'
export
interface
OutputOracle
<
TSubmissionEventArgs
>
{
export
interface
OutputOracle
{
contract
:
Contract
filter
:
any
getTotalElements
:
()
=>
Promise
<
BigNumber
>
getEventIndex
:
(
args
:
TSubmissionEventArgs
)
=>
BigNumber
getEventIndex
:
(
args
:
any
)
=>
BigNumber
}
/**
...
...
@@ -54,8 +54,8 @@ const getCache = (
* @param contract Contract to update cache for.
* @param filter Event filter to use.
*/
export
const
updateOracleCache
=
async
<
TSubmissionEventArgs
>
(
oracle
:
OutputOracle
<
TSubmissionEventArgs
>
,
export
const
updateOracleCache
=
async
(
oracle
:
OutputOracle
,
logger
?:
Logger
):
Promise
<
void
>
=>
{
const
cache
=
getCache
(
oracle
.
contract
.
address
)
...
...
@@ -86,7 +86,7 @@ export const updateOracleCache = async <TSubmissionEventArgs>(
// Throw the events into the cache.
for
(
const
event
of
events
)
{
cache
.
eventCache
[
oracle
.
getEventIndex
(
event
.
args
as
TSubmissionEventArgs
).
toNumber
()
oracle
.
getEventIndex
(
event
.
args
).
toNumber
()
]
=
{
blockNumber
:
event
.
blockNumber
,
transactionHash
:
event
.
transactionHash
,
...
...
@@ -135,8 +135,8 @@ export const updateOracleCache = async <TSubmissionEventArgs>(
* @param index State batch index to search for.
* @returns Event corresponding to the batch.
*/
export
const
findEventForStateBatch
=
async
<
TSubmissionEventArgs
>
(
oracle
:
OutputOracle
<
TSubmissionEventArgs
>
,
export
const
findEventForStateBatch
=
async
(
oracle
:
OutputOracle
,
index
:
number
,
logger
?:
Logger
):
Promise
<
PartialEvent
>
=>
{
...
...
@@ -166,8 +166,8 @@ export const findEventForStateBatch = async <TSubmissionEventArgs>(
* @param oracle Output oracle contract.
* @returns Starting state root batch index.
*/
export
const
findFirstUnfinalizedStateBatchIndex
=
async
<
TSubmissionEventArgs
>
(
oracle
:
OutputOracle
<
TSubmissionEventArgs
>
,
export
const
findFirstUnfinalizedStateBatchIndex
=
async
(
oracle
:
OutputOracle
,
fpw
:
number
,
logger
?:
Logger
):
Promise
<
number
>
=>
{
...
...
packages/fault-detector/src/service.ts
View file @
fc64f875
...
...
@@ -32,8 +32,9 @@ type Options = {
l1RpcProvider
:
Provider
l2RpcProvider
:
Provider
startBatchIndex
:
number
bedrock
:
boolean
optimismPortalAddress
?:
string
// Deprecated. Bedrock is the only version we support.
bedrock
:
boolean
stateCommitmentChainAddress
?:
string
}
...
...
@@ -44,8 +45,8 @@ type Metrics = {
}
type
State
=
{
f
p
w
:
number
o
o
:
OutputOracle
<
any
>
f
aultProofWindo
w
:
number
o
utputOracle
:
OutputOracle
messenger
:
CrossChainMessenger
currentBatchIndex
:
number
diverged
:
boolean
...
...
@@ -76,22 +77,23 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
desc
:
'
Batch index to start checking from. For bedrock chains, this is the L2 height to start from
'
,
public
:
true
,
},
bedrock
:
{
validator
:
validators
.
bool
,
default
:
true
,
desc
:
'
Whether or not the service is running against a Bedrock chain
'
,
public
:
true
,
},
optimismPortalAddress
:
{
validator
:
validators
.
str
,
default
:
ethers
.
constants
.
AddressZero
,
desc
:
'
[Custom Bedrock Chains] Deployed OptimismPortal contract address. Used to retrieve necessary info for ouput verification
'
,
desc
:
'
Deployed OptimismPortal contract address. Used to retrieve necessary info for ouput verification
'
,
public
:
true
,
},
// Deprecated flags.
bedrock
:
{
validator
:
validators
.
bool
,
default
:
true
,
desc
:
'
[Deprecated, must be set to true] Whether or not the service is running against a Bedrock chain
'
,
public
:
true
,
},
stateCommitmentChainAddress
:
{
validator
:
validators
.
str
,
default
:
ethers
.
constants
.
AddressZero
,
desc
:
'
[
Custom Legacy Chains
] Deployed StateCommitmentChain contract address. Used to fetch necessary info for output verification.
'
,
desc
:
'
[
Deprecated, must be set to 0x0
] Deployed StateCommitmentChain contract address. Used to fetch necessary info for output verification.
'
,
public
:
true
,
},
},
...
...
@@ -119,10 +121,9 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
* will fallback to the pre-defined set of addresses from options, otherwise aborting if unset.
*
* Required Contracts
* -
Bedrock:
OptimismPortal (used to also fetch L2OutputOracle address variable). This is the preferred address
* - OptimismPortal (used to also fetch L2OutputOracle address variable). This is the preferred address
* since in early versions of bedrock, OptimismPortal holds the FINALIZATION_WINDOW variable instead of L2OutputOracle.
* The retrieved L2OutputOracle address from OptimismPortal is used to query for output roots.
* - Legacy: StateCommitmentChain to query for output roots.
*
* @param l2ChainId op chain id
* @returns OEL1ContractsLike set of L1 contracts with only the required addresses set
...
...
@@ -130,19 +131,17 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
async
getOEL1Contracts
(
l2ChainId
:
number
):
Promise
<
OEL1ContractsLike
>
{
// CrossChainMessenger requires all address to be defined. Default to `AddressZero` to ignore unused contracts
let
contracts
:
OEL1ContractsLike
=
{
OptimismPortal
:
ethers
.
constants
.
AddressZero
,
L2OutputOracle
:
ethers
.
constants
.
AddressZero
,
// Unused contracts
AddressManager
:
ethers
.
constants
.
AddressZero
,
BondManager
:
ethers
.
constants
.
AddressZero
,
CanonicalTransactionChain
:
ethers
.
constants
.
AddressZero
,
L1CrossDomainMessenger
:
ethers
.
constants
.
AddressZero
,
L1StandardBridge
:
ethers
.
constants
.
AddressZero
,
StateCommitmentChain
:
ethers
.
constants
.
AddressZero
,
CanonicalTransactionChain
:
ethers
.
constants
.
AddressZero
,
BondManager
:
ethers
.
constants
.
AddressZero
,
OptimismPortal
:
ethers
.
constants
.
AddressZero
,
L2OutputOracle
:
ethers
.
constants
.
AddressZero
,
}
const
chainType
=
this
.
options
.
bedrock
?
'
bedrock
'
:
'
legacy
'
this
.
logger
.
info
(
`Setting contracts for OP chain type:
${
chainType
}
`
)
const
knownChainId
=
L2ChainID
[
l2ChainId
]
!==
undefined
if
(
knownChainId
)
{
this
.
logger
.
info
(
`Recognized L2 chain id
${
L2ChainID
[
l2ChainId
]}
`
)
...
...
@@ -152,42 +151,26 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
}
this
.
logger
.
info
(
'
checking contract address options...
'
)
if
(
this
.
options
.
bedrock
)
{
const
address
=
this
.
options
.
optimismPortalAddress
if
(
!
knownChainId
&&
address
===
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
error
(
'
OptimismPortal contract unspecified
'
)
throw
new
Error
(
'
--optimismportalcontractaddress needs to set for custom bedrock op chains
'
)
}
if
(
address
!==
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
info
(
'
set OptimismPortal contract override
'
)
contracts
.
OptimismPortal
=
address
this
.
logger
.
info
(
'
fetching L2OutputOracle contract from OptimismPortal
'
)
const
opts
=
{
address
,
signerOrProvider
:
this
.
options
.
l1RpcProvider
}
const
portalContract
=
getOEContract
(
'
OptimismPortal
'
,
l2ChainId
,
opts
)
contracts
.
L2OutputOracle
=
await
portalContract
.
L2_ORACLE
()
}
const
portalAddress
=
this
.
options
.
optimismPortalAddress
if
(
!
knownChainId
&&
portalAddress
===
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
error
(
'
OptimismPortal contract unspecified
'
)
throw
new
Error
(
'
--optimismportalcontractaddress needs to set for custom bedrock op chains
'
)
}
// ... for a known chain ids without an override, the L2OutputOracle will already
// be set via the hardcoded default
}
else
{
const
address
=
this
.
options
.
stateCommitmentChainAddress
if
(
!
knownChainId
&&
address
===
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
error
(
'
StateCommitmentChain contract unspecified
'
)
throw
new
Error
(
'
--statecommitmentchainaddress needs to set for custom legacy op chains
'
)
}
if
(
portalAddress
!==
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
info
(
'
set OptimismPortal contract override
'
)
contracts
.
OptimismPortal
=
portalAddress
if
(
address
!==
ethers
.
constants
.
AddressZero
)
{
this
.
logger
.
info
(
'
set StateCommitmentChain contract override
'
)
contracts
.
StateCommitmentChain
=
address
}
this
.
logger
.
info
(
'
fetching L2OutputOracle contract from OptimismPortal
'
)
const
opts
=
{
portalAddress
,
signerOrProvider
:
this
.
options
.
l1RpcProvider
}
const
portalContract
=
getOEContract
(
'
OptimismPortal
'
,
l2ChainId
,
opts
)
contracts
.
L2OutputOracle
=
await
portalContract
.
L2_ORACLE
()
}
// ... for a known chain ids without an override, the L2OutputOracle will already
// be set via the hardcoded default
return
contracts
}
...
...
@@ -211,7 +194,7 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
l2SignerOrProvider
:
this
.
options
.
l2RpcProvider
,
l1ChainId
,
l2ChainId
,
bedrock
:
t
his
.
options
.
bedrock
,
bedrock
:
t
rue
,
contracts
:
{
l1
:
await
this
.
getOEL1Contracts
(
l2ChainId
)
},
})
...
...
@@ -219,46 +202,36 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
this
.
state
.
diverged
=
false
// We use this a lot, a bit cleaner to pull out to the top level of the state object.
this
.
state
.
fpw
=
await
this
.
state
.
messenger
.
getChallengePeriodSeconds
()
this
.
logger
.
info
(
`fault proof window is
${
this
.
state
.
fpw
}
seconds`
)
if
(
this
.
options
.
bedrock
)
{
const
oo
=
this
.
state
.
messenger
.
contracts
.
l1
.
L2OutputOracle
this
.
state
.
oo
=
{
contract
:
oo
,
filter
:
oo
.
filters
.
OutputProposed
(),
getTotalElements
:
async
()
=>
oo
.
nextOutputIndex
(),
getEventIndex
:
(
args
)
=>
args
.
l2OutputIndex
,
}
}
else
{
const
oo
=
this
.
state
.
messenger
.
contracts
.
l1
.
StateCommitmentChain
this
.
state
.
oo
=
{
contract
:
oo
,
filter
:
oo
.
filters
.
StateBatchAppended
(),
getTotalElements
:
async
()
=>
oo
.
getTotalBatches
(),
getEventIndex
:
(
args
)
=>
args
.
_batchIndex
,
}
this
.
state
.
faultProofWindow
=
await
this
.
state
.
messenger
.
getChallengePeriodSeconds
()
this
.
logger
.
info
(
`fault proof window is
${
this
.
state
.
faultProofWindow
}
seconds`
)
const
outputOracle
=
this
.
state
.
messenger
.
contracts
.
l1
.
L2OutputOracle
this
.
state
.
outputOracle
=
{
contract
:
outputOracle
,
filter
:
outputOracle
.
filters
.
OutputProposed
(),
getTotalElements
:
async
()
=>
outputOracle
.
nextOutputIndex
(),
getEventIndex
:
(
args
)
=>
args
.
l2OutputIndex
,
}
// Populate the event cache.
this
.
logger
.
info
(
'
warming event cache, this might take a while...
'
)
await
updateOracleCache
(
this
.
state
.
o
o
,
this
.
logger
)
await
updateOracleCache
(
this
.
state
.
o
utputOracle
,
this
.
logger
)
// Figure out where to start syncing from.
if
(
this
.
options
.
startBatchIndex
===
-
1
)
{
this
.
logger
.
info
(
'
finding appropriate starting unfinalized batch
'
)
const
firstUnfinalized
=
await
findFirstUnfinalizedStateBatchIndex
(
this
.
state
.
o
o
,
this
.
state
.
f
p
w
,
this
.
state
.
o
utputOracle
,
this
.
state
.
f
aultProofWindo
w
,
this
.
logger
)
// We may not have an unfinalized batches in the case where no batches have been submitted
// for the entire duration of the F
P
W. We generally do not expect this to happen on mainnet,
// but it happens often on testnets because the F
P
W is very short.
// for the entire duration of the F
AULTPROOFWINDO
W. We generally do not expect this to happen on mainnet,
// but it happens often on testnets because the F
AULTPROOFWINDO
W is very short.
if
(
firstUnfinalized
===
undefined
)
{
this
.
logger
.
info
(
'
no unfinalized batches found. skipping all batches.
'
)
const
totalBatches
=
await
this
.
state
.
o
o
.
getTotalElements
()
const
totalBatches
=
await
this
.
state
.
o
utputOracle
.
getTotalElements
()
this
.
state
.
currentBatchIndex
=
totalBatches
.
toNumber
()
-
1
}
else
{
this
.
state
.
currentBatchIndex
=
firstUnfinalized
...
...
@@ -288,7 +261,7 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
let
latestBatchIndex
:
number
try
{
const
totalBatches
=
await
this
.
state
.
o
o
.
getTotalElements
()
const
totalBatches
=
await
this
.
state
.
o
utputOracle
.
getTotalElements
()
latestBatchIndex
=
totalBatches
.
toNumber
()
-
1
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to query total # of batches
'
,
{
...
...
@@ -322,7 +295,7 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
let
event
:
PartialEvent
try
{
event
=
await
findEventForStateBatch
(
this
.
state
.
o
o
,
this
.
state
.
o
utputOracle
,
this
.
state
.
currentBatchIndex
,
this
.
logger
)
...
...
@@ -358,179 +331,89 @@ export class FaultDetector extends BaseServiceV2<Options, Metrics, State> {
return
}
if
(
this
.
options
.
bedrock
)
{
const
outputBlockNumber
=
event
.
args
.
l2BlockNumber
.
toNumber
()
if
(
latestBlock
<
outputBlockNumber
)
{
this
.
logger
.
info
(
'
L2 node is behind, waiting for sync...
'
,
{
l2BlockHeight
:
latestBlock
,
outputBlock
:
outputBlockNumber
,
})
return
}
const
outputBlockNumber
=
event
.
args
.
l2BlockNumber
.
toNumber
()
if
(
latestBlock
<
outputBlockNumber
)
{
this
.
logger
.
info
(
'
L2 node is behind, waiting for sync...
'
,
{
l2BlockHeight
:
latestBlock
,
outputBlock
:
outputBlockNumber
,
})
return
}
let
outputBlock
:
any
try
{
outputBlock
=
await
(
this
.
options
.
l2RpcProvider
as
ethers
.
providers
.
JsonRpcProvider
).
send
(
'
eth_getBlockByNumber
'
,
[
toRpcHexString
(
outputBlockNumber
),
false
,
])
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to fetch output block
'
,
{
error
:
err
,
node
:
'
l2
'
,
section
:
'
getBlock
'
,
block
:
outputBlockNumber
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l2
'
,
section
:
'
getBlock
'
,
})
await
sleep
(
15000
)
return
}
let
outputBlock
:
any
try
{
outputBlock
=
await
(
this
.
options
.
l2RpcProvider
as
ethers
.
providers
.
JsonRpcProvider
).
send
(
'
eth_getBlockByNumber
'
,
[
toRpcHexString
(
outputBlockNumber
),
false
,
])
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to fetch output block
'
,
{
error
:
err
,
node
:
'
l2
'
,
section
:
'
getBlock
'
,
block
:
outputBlockNumber
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l2
'
,
section
:
'
getBlock
'
,
})
await
sleep
(
15000
)
return
}
let
messagePasserProofResponse
:
any
try
{
messagePasserProofResponse
=
await
(
this
.
options
.
l2RpcProvider
as
ethers
.
providers
.
JsonRpcProvider
).
send
(
'
eth_getProof
'
,
[
this
.
state
.
messenger
.
contracts
.
l2
.
BedrockMessagePasser
.
address
,
[],
toRpcHexString
(
outputBlockNumber
),
])
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to fetch message passer proof
'
,
{
error
:
err
,
node
:
'
l2
'
,
section
:
'
getProof
'
,
block
:
outputBlockNumber
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l2
'
,
section
:
'
getProof
'
,
})
await
sleep
(
15000
)
return
}
let
messagePasserProofResponse
:
any
try
{
messagePasserProofResponse
=
await
(
this
.
options
.
l2RpcProvider
as
ethers
.
providers
.
JsonRpcProvider
).
send
(
'
eth_getProof
'
,
[
this
.
state
.
messenger
.
contracts
.
l2
.
BedrockMessagePasser
.
address
,
[],
toRpcHexString
(
outputBlockNumber
),
])
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to fetch message passer proof
'
,
{
error
:
err
,
node
:
'
l2
'
,
section
:
'
getProof
'
,
block
:
outputBlockNumber
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l2
'
,
section
:
'
getProof
'
,
})
await
sleep
(
15000
)
return
}
const
outputRoot
=
ethers
.
utils
.
solidityKeccak256
(
[
'
uint256
'
,
'
bytes32
'
,
'
bytes32
'
,
'
bytes32
'
],
[
0
,
outputBlock
.
stateRoot
,
messagePasserProofResponse
.
storageHash
,
outputBlock
.
hash
,
]
)
const
outputRoot
=
ethers
.
utils
.
solidityKeccak256
(
[
'
uint256
'
,
'
bytes32
'
,
'
bytes32
'
,
'
bytes32
'
],
[
0
,
outputBlock
.
stateRoot
,
messagePasserProofResponse
.
storageHash
,
outputBlock
.
hash
,
]
)
if
(
outputRoot
!==
event
.
args
.
outputRoot
)
{
this
.
state
.
diverged
=
true
this
.
metrics
.
isCurrentlyMismatched
.
set
(
1
)
this
.
logger
.
error
(
'
state root mismatch
'
,
{
blockNumber
:
outputBlock
.
number
,
expectedStateRoot
:
event
.
args
.
outputRoot
,
actualStateRoot
:
outputRoot
,
finalizationTime
:
dateformat
(
new
Date
(
(
ethers
.
BigNumber
.
from
(
outputBlock
.
timestamp
).
toNumber
()
+
this
.
state
.
fpw
)
*
1000
),
'
mmmm dS, yyyy, h:MM:ss TT
'
if
(
outputRoot
!==
event
.
args
.
outputRoot
)
{
this
.
state
.
diverged
=
true
this
.
metrics
.
isCurrentlyMismatched
.
set
(
1
)
this
.
logger
.
error
(
'
state root mismatch
'
,
{
blockNumber
:
outputBlock
.
number
,
expectedStateRoot
:
event
.
args
.
outputRoot
,
actualStateRoot
:
outputRoot
,
finalizationTime
:
dateformat
(
new
Date
(
(
ethers
.
BigNumber
.
from
(
outputBlock
.
timestamp
).
toNumber
()
+
this
.
state
.
faultProofWindow
)
*
1000
),
})
return
}
}
else
{
let
batchTransaction
:
Transaction
try
{
batchTransaction
=
await
this
.
options
.
l1RpcProvider
.
getTransaction
(
event
.
transactionHash
)
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to acquire batch transaction
'
,
{
error
:
err
,
node
:
'
l1
'
,
section
:
'
getTransaction
'
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l1
'
,
section
:
'
getTransaction
'
,
})
await
sleep
(
15000
)
return
}
const
[
stateRoots
]
=
this
.
state
.
oo
.
contract
.
interface
.
decodeFunctionData
(
'
appendStateBatch
'
,
batchTransaction
.
data
)
const
batchStart
=
event
.
args
.
_prevTotalElements
.
toNumber
()
+
1
const
batchSize
=
event
.
args
.
_batchSize
.
toNumber
()
const
batchEnd
=
batchStart
+
batchSize
if
(
latestBlock
<
batchEnd
)
{
this
.
logger
.
info
(
'
L2 node is behind. waiting for sync...
'
,
{
batchBlockStart
:
batchStart
,
batchBlockEnd
:
batchEnd
,
l2BlockHeight
:
latestBlock
,
})
return
}
// `getBlockRange` has a limit of 1000 blocks, so we have to break this request out into
// multiple requests of maximum 1000 blocks in the case that batchSize > 1000.
let
blocks
:
any
[]
=
[]
for
(
let
i
=
0
;
i
<
batchSize
;
i
+=
1000
)
{
let
newBlocks
:
any
[]
try
{
newBlocks
=
await
(
this
.
options
.
l2RpcProvider
as
ethers
.
providers
.
JsonRpcProvider
).
send
(
'
eth_getBlockRange
'
,
[
toRpcHexString
(
batchStart
+
i
),
toRpcHexString
(
batchStart
+
i
+
Math
.
min
(
batchSize
-
i
,
1000
)
-
1
),
false
,
])
}
catch
(
err
)
{
this
.
logger
.
error
(
'
failed to query for blocks in batch
'
,
{
error
:
err
,
node
:
'
l2
'
,
section
:
'
getBlockRange
'
,
})
this
.
metrics
.
nodeConnectionFailures
.
inc
({
layer
:
'
l2
'
,
section
:
'
getBlockRange
'
,
})
await
sleep
(
15000
)
return
}
blocks
=
blocks
.
concat
(
newBlocks
)
}
for
(
const
[
i
,
stateRoot
]
of
stateRoots
.
entries
())
{
if
(
blocks
[
i
].
stateRoot
!==
stateRoot
)
{
this
.
state
.
diverged
=
true
this
.
metrics
.
isCurrentlyMismatched
.
set
(
1
)
this
.
logger
.
error
(
'
state root mismatch
'
,
{
blockNumber
:
blocks
[
i
].
number
,
expectedStateRoot
:
blocks
[
i
].
stateRoot
,
actualStateRoot
:
stateRoot
,
finalizationTime
:
dateformat
(
new
Date
(
(
ethers
.
BigNumber
.
from
(
blocks
[
i
].
timestamp
).
toNumber
()
+
this
.
state
.
fpw
)
*
1000
),
'
mmmm dS, yyyy, h:MM:ss TT
'
),
})
return
}
}
'
mmmm dS, yyyy, h:MM:ss TT
'
),
})
return
}
const
elapsedMs
=
Date
.
now
()
-
startMs
...
...
packages/fault-detector/test/helpers.spec.ts
View file @
fc64f875
...
...
@@ -29,7 +29,7 @@ describe('helpers', () => {
let
AddressManager
:
Contract
let
ChainStorageContainer
:
Contract
let
StateCommitmentChain
:
Contract
let
oracle
:
OutputOracle
<
any
>
let
oracle
:
OutputOracle
beforeEach
(
async
()
=>
{
// Set up fakes
FakeBondManager
=
await
smock
.
fake
(
getContractInterface
(
'
BondManager
'
))
...
...
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