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
67f19ecc
Unverified
Commit
67f19ecc
authored
Sep 28, 2023
by
mergify[bot]
Committed by
GitHub
Sep 28, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' into aj/resolve-log
parents
7614f8a5
39bee257
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
207 additions
and
349 deletions
+207
-349
bigint.go
indexer/bigint/bigint.go
+0
-32
bigint_test.go
indexer/bigint/bigint_test.go
+0
-43
blocks.go
indexer/database/blocks.go
+62
-22
mocks.go
indexer/database/mocks.go
+3
-1
setup.go
indexer/e2e_tests/setup.go
+20
-12
bridge.go
indexer/processors/bridge.go
+64
-81
package.json
package.json
+1
-1
pnpm-lock.yaml
pnpm-lock.yaml
+57
-157
No files found.
indexer/bigint/bigint.go
View file @
67f19ecc
...
...
@@ -25,35 +25,3 @@ func Clamp(start, end *big.Int, size uint64) *big.Int {
func
Matcher
(
num
int64
)
func
(
*
big
.
Int
)
bool
{
return
func
(
bi
*
big
.
Int
)
bool
{
return
bi
.
Int64
()
==
num
}
}
type
Range
struct
{
Start
*
big
.
Int
End
*
big
.
Int
}
// Grouped will return a slice of inclusive ranges from (start, end),
// capped to the supplied size from `(start, end)`.
func
Grouped
(
start
,
end
*
big
.
Int
,
size
uint64
)
[]
Range
{
if
end
.
Cmp
(
start
)
<
0
||
size
==
0
{
return
nil
}
bigMaxDiff
:=
big
.
NewInt
(
int64
(
size
-
1
))
groups
:=
[]
Range
{}
for
start
.
Cmp
(
end
)
<=
0
{
diff
:=
new
(
big
.
Int
)
.
Sub
(
end
,
start
)
switch
{
case
diff
.
Uint64
()
+
1
<=
size
:
// re-use allocated diff as the next start
groups
=
append
(
groups
,
Range
{
start
,
end
})
start
=
diff
.
Add
(
end
,
One
)
default
:
// re-use allocated diff as the next start
end
:=
new
(
big
.
Int
)
.
Add
(
start
,
bigMaxDiff
)
groups
=
append
(
groups
,
Range
{
start
,
end
})
start
=
diff
.
Add
(
end
,
One
)
}
}
return
groups
}
indexer/bigint/bigint_test.go
View file @
67f19ecc
...
...
@@ -27,46 +27,3 @@ func TestClamp(t *testing.T) {
require
.
False
(
t
,
end
==
result
)
require
.
Equal
(
t
,
uint64
(
5
),
result
.
Uint64
())
}
func
TestGrouped
(
t
*
testing
.
T
)
{
// base cases
require
.
Nil
(
t
,
Grouped
(
One
,
Zero
,
1
))
require
.
Nil
(
t
,
Grouped
(
Zero
,
One
,
0
))
// Same Start/End
group
:=
Grouped
(
One
,
One
,
1
)
require
.
Len
(
t
,
group
,
1
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
Start
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
End
)
Three
,
Five
:=
big
.
NewInt
(
3
),
big
.
NewInt
(
5
)
// One at a time
group
=
Grouped
(
One
,
Three
,
1
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
End
)
require
.
Equal
(
t
,
int64
(
1
),
group
[
0
]
.
End
.
Int64
())
require
.
Equal
(
t
,
int64
(
2
),
group
[
1
]
.
Start
.
Int64
())
require
.
Equal
(
t
,
int64
(
2
),
group
[
1
]
.
End
.
Int64
())
require
.
Equal
(
t
,
int64
(
3
),
group
[
2
]
.
Start
.
Int64
())
require
.
Equal
(
t
,
int64
(
3
),
group
[
2
]
.
End
.
Int64
())
// Split groups
group
=
Grouped
(
One
,
Five
,
3
)
require
.
Len
(
t
,
group
,
2
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
Start
)
require
.
Equal
(
t
,
int64
(
3
),
group
[
0
]
.
End
.
Int64
())
require
.
Equal
(
t
,
int64
(
4
),
group
[
1
]
.
Start
.
Int64
())
require
.
Equal
(
t
,
Five
,
group
[
1
]
.
End
)
// Encompasses the range
group
=
Grouped
(
One
,
Five
,
5
)
require
.
Len
(
t
,
group
,
1
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
Start
,
Zero
)
require
.
Equal
(
t
,
Five
,
group
[
0
]
.
End
)
// Size larger than the entire range
group
=
Grouped
(
One
,
Five
,
100
)
require
.
Len
(
t
,
group
,
1
)
require
.
Equal
(
t
,
One
,
group
[
0
]
.
Start
,
Zero
)
require
.
Equal
(
t
,
Five
,
group
[
0
]
.
End
)
}
indexer/database/blocks.go
View file @
67f19ecc
...
...
@@ -2,8 +2,10 @@ package database
import
(
"errors"
"fmt"
"math/big"
"github.com/ethereum-optimism/optimism/indexer/bigint"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
...
...
@@ -51,7 +53,7 @@ type BlocksView interface {
L2BlockHeaderWithFilter
(
BlockHeader
)
(
*
L2BlockHeader
,
error
)
L2LatestBlockHeader
()
(
*
L2BlockHeader
,
error
)
Latest
Epoch
(
)
(
*
Epoch
,
error
)
Latest
ObservedEpoch
(
*
big
.
Int
,
uint64
)
(
*
Epoch
,
error
)
}
type
BlocksDB
interface
{
...
...
@@ -155,36 +157,74 @@ type Epoch struct {
L2BlockHeader
L2BlockHeader
`gorm:"embedded"`
}
// LatestEpoch return the latest epoch, seen on L1 & L2. In other words
// this returns the latest indexed L1 block that has a corresponding
// indexed L2 block with a matching L1Origin (equal timestamps).
// LatestObservedEpoch return the marker for latest epoch, observed on L1 & L2, within
// the specified bounds. In other words this returns the latest indexed L1 block that has
// a corresponding indexed L2 block with a matching L1Origin (equal timestamps).
//
// If `fromL1Height` (inclusive) is not specified, the search will start from genesis and
// continue all the way to latest indexed heights if `maxL1Range == 0`.
//
// For more, see the protocol spec:
// - https://github.com/ethereum-optimism/optimism/blob/develop/specs/derivation.md
func
(
db
*
blocksDB
)
Latest
Epoch
(
)
(
*
Epoch
,
error
)
{
latestL1Header
,
err
:=
db
.
L1LatestBlockHeader
()
if
err
!=
nil
{
return
nil
,
err
}
else
if
latestL1Header
==
nil
{
return
nil
,
nil
func
(
db
*
blocksDB
)
Latest
ObservedEpoch
(
fromL1Height
*
big
.
Int
,
maxL1Range
uint64
)
(
*
Epoch
,
error
)
{
// We use timestamps since that translates to both L1 & L2
var
fromTimestamp
,
toTimestamp
uint64
if
fromL1Height
==
nil
{
fromL1Height
=
bigint
.
Zero
}
latestL2Header
,
err
:=
db
.
L2LatestBlockHeader
()
if
err
!=
nil
{
return
nil
,
err
}
else
if
latestL2Header
==
nil
{
return
nil
,
nil
// Lower Bound (the default `fromTimestamp = 0` suffices genesis representation)
if
fromL1Height
.
BitLen
()
>
0
{
var
header
L1BlockHeader
result
:=
db
.
gorm
.
Where
(
"number = ?"
,
fromL1Height
)
.
Take
(
&
header
)
if
result
.
Error
!=
nil
{
if
errors
.
Is
(
result
.
Error
,
gorm
.
ErrRecordNotFound
)
{
return
nil
,
nil
}
return
nil
,
result
.
Error
}
fromTimestamp
=
header
.
Timestamp
}
minTime
:=
latestL1Header
.
Timestamp
if
latestL2Header
.
Timestamp
<
minTime
{
minTime
=
latestL2Header
.
Timestamp
// Upper Bound (lowest timestamp indexed between L1/L2 bounded by `maxL1Range`)
{
l1QueryFilter
:=
fmt
.
Sprintf
(
"timestamp >= %d"
,
fromTimestamp
)
if
maxL1Range
>
0
{
maxHeight
:=
new
(
big
.
Int
)
.
Add
(
fromL1Height
,
big
.
NewInt
(
int64
(
maxL1Range
)))
l1QueryFilter
=
fmt
.
Sprintf
(
"%s AND number <= %d"
,
l1QueryFilter
,
maxHeight
)
}
var
l1Header
L1BlockHeader
result
:=
db
.
gorm
.
Where
(
l1QueryFilter
)
.
Order
(
"timestamp DESC"
)
.
Take
(
&
l1Header
)
if
result
.
Error
!=
nil
{
if
errors
.
Is
(
result
.
Error
,
gorm
.
ErrRecordNotFound
)
{
return
nil
,
nil
}
return
nil
,
result
.
Error
}
toTimestamp
=
l1Header
.
Timestamp
var
l2Header
L2BlockHeader
result
=
db
.
gorm
.
Where
(
"timestamp <= ?"
,
toTimestamp
)
.
Order
(
"timestamp DESC"
)
.
Take
(
&
l2Header
)
if
result
.
Error
!=
nil
{
if
errors
.
Is
(
result
.
Error
,
gorm
.
ErrRecordNotFound
)
{
return
nil
,
nil
}
return
nil
,
result
.
Error
}
if
l2Header
.
Timestamp
<
toTimestamp
{
toTimestamp
=
l2Header
.
Timestamp
}
}
//
This is a faster query than doing an INNER JOIN between l1_block_headers and l2_block_headers
// which requires a full table scan to compute the resulting table.
l1Query
:=
db
.
gorm
.
Table
(
"l1_block_headers"
)
.
Where
(
"timestamp
<= ?"
,
minTime
)
l2Query
:=
db
.
gorm
.
Table
(
"l2_block_headers"
)
.
Where
(
"timestamp
<= ?"
,
minTime
)
//
Search for the latest indexed epoch within range. This is a faster query than doing an INNER JOIN between
//
l1_block_headers and l2_block_headers
which requires a full table scan to compute the resulting table.
l1Query
:=
db
.
gorm
.
Table
(
"l1_block_headers"
)
.
Where
(
"timestamp
>= ? AND timestamp <= ?"
,
fromTimestamp
,
toTimestamp
)
l2Query
:=
db
.
gorm
.
Table
(
"l2_block_headers"
)
.
Where
(
"timestamp
>= ? AND timestamp <= ?"
,
fromTimestamp
,
toTimestamp
)
query
:=
db
.
gorm
.
Raw
(
`SELECT * FROM (?) AS l1_block_headers, (?) AS l2_block_headers
WHERE l1_block_headers.timestamp = l2_block_headers.timestamp
ORDER BY l2_block_headers.number DESC LIMIT 1`
,
l1Query
,
l2Query
)
...
...
indexer/database/mocks.go
View file @
67f19ecc
package
database
import
(
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/mock"
...
...
@@ -51,7 +53,7 @@ func (m *MockBlocksView) L2LatestBlockHeader() (*L2BlockHeader, error) {
return
args
.
Get
(
0
)
.
(
*
L2BlockHeader
),
args
.
Error
(
1
)
}
func
(
m
*
MockBlocksView
)
Latest
Epoch
(
)
(
*
Epoch
,
error
)
{
func
(
m
*
MockBlocksView
)
Latest
ObservedEpoch
(
*
big
.
Int
,
uint64
)
(
*
Epoch
,
error
)
{
args
:=
m
.
Called
()
return
args
.
Get
(
0
)
.
(
*
Epoch
),
args
.
Error
(
1
)
}
...
...
indexer/e2e_tests/setup.go
View file @
67f19ecc
...
...
@@ -41,21 +41,24 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
dbUser
:=
os
.
Getenv
(
"DB_USER"
)
dbName
:=
setupTestDatabase
(
t
)
// Discard the Global Logger as each component
// has its own configured logger
// Rollup System Configuration. Unless specified,
// omit logs emitted by the various components. Maybe
// we can eventually dump these logs to a temp file
log
.
Root
()
.
SetHandler
(
log
.
DiscardHandler
())
// Rollup System Configuration and Start
opCfg
:=
op_e2e
.
DefaultSystemConfig
(
t
)
opCfg
.
DeployConfig
.
FinalizationPeriodSeconds
=
2
if
len
(
os
.
Getenv
(
"ENABLE_ROLLUP_LOGS"
))
==
0
{
t
.
Log
(
"set env 'ENABLE_ROLLUP_LOGS' to show rollup logs"
)
for
name
,
logger
:=
range
opCfg
.
Loggers
{
t
.
Logf
(
"discarding logs for %s"
,
name
)
logger
.
SetHandler
(
log
.
DiscardHandler
())
}
}
// Rollup Start
opSys
,
err
:=
opCfg
.
Start
(
t
)
require
.
NoError
(
t
,
err
)
t
.
Cleanup
(
func
()
{
opSys
.
Close
()
})
// E2E tests can run on the order of magnitude of minutes. Once
// the system is running, mark this test for Parallel execution
t
.
Parallel
()
// Indexer Configuration and Start
indexerCfg
:=
config
.
Config
{
DB
:
config
.
DBConfig
{
...
...
@@ -86,8 +89,14 @@ func createE2ETestSuite(t *testing.T) E2ETestSuite {
MetricsServer
:
config
.
ServerConfig
{
Host
:
"127.0.0.1"
,
Port
:
0
},
}
// Emit debug log levels
db
,
err
:=
database
.
NewDB
(
testlog
.
Logger
(
t
,
log
.
LvlDebug
)
.
New
(
"role"
,
"db"
),
indexerCfg
.
DB
)
// E2E tests can run on the order of magnitude of minutes. Once
// the system is running, mark this test for Parallel execution
t
.
Parallel
()
// provide a DB for the unit test. disable logging
silentLog
:=
testlog
.
Logger
(
t
,
log
.
LvlInfo
)
silentLog
.
SetHandler
(
log
.
DiscardHandler
())
db
,
err
:=
database
.
NewDB
(
silentLog
,
indexerCfg
.
DB
)
require
.
NoError
(
t
,
err
)
t
.
Cleanup
(
func
()
{
db
.
Close
()
})
...
...
@@ -138,7 +147,6 @@ func setupTestDatabase(t *testing.T) string {
User
:
user
,
Password
:
""
,
}
// NewDB will create the database schema
silentLog
:=
log
.
New
()
silentLog
.
SetHandler
(
log
.
DiscardHandler
())
...
...
indexer/processors/bridge.go
View file @
67f19ecc
...
...
@@ -67,6 +67,8 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
// sequencing epoch and corresponding L1 origin that has also been indexed
// serves as this shared marker.
// Fire off independently on startup to check for
// new data or if we've indexed new L1 data.
l1EtlUpdates
:=
b
.
l1Etl
.
Notify
()
startup
:=
make
(
chan
interface
{},
1
)
startup
<-
nil
...
...
@@ -78,32 +80,45 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
b
.
log
.
Info
(
"stopping bridge processor"
)
return
nil
// Fire off independently on startup to check for any
// new data or if we've indexed new L1 data.
// Tickers
case
<-
startup
:
case
<-
l1EtlUpdates
:
}
latestEpoch
,
err
:=
b
.
db
.
Blocks
.
LatestEpoch
()
// In the event where we have a large number of un-observed epochs, we cap the search
// of epochs by 10k. If this turns out to be a bottleneck, we can parallelize the processing
// of epochs to significantly speed up sync times.
maxEpochRange
:=
uint64
(
10
_000
)
var
lastEpoch
*
big
.
Int
if
b
.
LatestL1Header
!=
nil
{
lastEpoch
=
b
.
LatestL1Header
.
Number
}
latestEpoch
,
err
:=
b
.
db
.
Blocks
.
LatestObservedEpoch
(
lastEpoch
,
maxEpochRange
)
if
err
!=
nil
{
return
err
}
else
if
latestEpoch
==
nil
{
if
b
.
LatestL1Header
!=
nil
||
b
.
LatestL2Header
!=
nil
{
// Once we have some indexed state `latestEpoch
` can never return nil
b
.
log
.
Error
(
"bridge events indexed, but no
index
ed epoch returned"
,
"latest_bridge_l1_block_number"
,
b
.
LatestL1Header
.
Number
)
return
errors
.
New
(
"bridge events indexed, but no
index
ed epoch returned"
)
// Once we have some indexed state `latestEpoch
!= nil` as `LatestObservedEpoch` is inclusive in its search with the last provided epoch.
b
.
log
.
Error
(
"bridge events indexed, but no
observ
ed epoch returned"
,
"latest_bridge_l1_block_number"
,
b
.
LatestL1Header
.
Number
)
return
errors
.
New
(
"bridge events indexed, but no
observ
ed epoch returned"
)
}
b
.
log
.
Warn
(
"no indexed epochs available. waiting..."
)
b
.
log
.
Warn
(
"no observed epochs available. waiting..."
)
continue
}
// Integrity Checks
if
b
.
LatestL1Header
!=
nil
&&
latestEpoch
.
L1BlockHeader
.
Hash
==
b
.
LatestL1Header
.
Hash
()
{
b
.
log
.
Warn
(
"all available epochs indexed"
,
"latest_bridge_l1_block_number"
,
b
.
LatestL1Header
.
Number
)
continue
}
// Integrity Checks
genesisL1Height
:=
big
.
NewInt
(
int64
(
b
.
chainConfig
.
L1StartingHeight
))
if
latestEpoch
.
L1BlockHeader
.
Number
.
Cmp
(
genesisL1Height
)
<
0
{
b
.
log
.
Error
(
"L1 epoch less than starting L1 height observed"
,
"l1_starting_number"
,
genesisL1Height
,
"latest_epoch_number"
,
latestEpoch
.
L1BlockHeader
.
Number
)
return
errors
.
New
(
"L1 epoch less than starting L1 height observed"
)
}
if
b
.
LatestL1Header
!=
nil
&&
latestEpoch
.
L1BlockHeader
.
Number
.
Cmp
(
b
.
LatestL1Header
.
Number
)
<=
0
{
b
.
log
.
Error
(
"decreasing l1 block height observed"
,
"latest_bridge_l1_block_number"
,
b
.
LatestL1Header
.
Number
,
"latest_epoch_number"
,
latestEpoch
.
L1BlockHeader
.
Number
)
return
errors
.
New
(
"decreasing l1 block heght observed"
)
...
...
@@ -116,7 +131,7 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
// Process Bridge Events
toL1Height
,
toL2Height
:=
latestEpoch
.
L1BlockHeader
.
Number
,
latestEpoch
.
L2BlockHeader
.
Number
fromL1Height
,
fromL2Height
:=
big
.
NewInt
(
int64
(
b
.
chainConfig
.
L1StartingHeight
))
,
bigint
.
Zero
fromL1Height
,
fromL2Height
:=
genesisL1Height
,
bigint
.
Zero
if
b
.
LatestL1Header
!=
nil
{
fromL1Height
=
new
(
big
.
Int
)
.
Add
(
b
.
LatestL1Header
.
Number
,
bigint
.
One
)
}
...
...
@@ -128,59 +143,40 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
l2BedrockStartingHeight
:=
big
.
NewInt
(
int64
(
b
.
chainConfig
.
L2BedrockStartingHeight
))
batchLog
:=
b
.
log
.
New
(
"epoch_start_number"
,
fromL1Height
,
"epoch_end_number"
,
toL1Height
)
batchLog
.
Info
(
"unobserved epochs"
)
err
=
b
.
db
.
Transaction
(
func
(
tx
*
database
.
DB
)
error
{
// In the event where we have a large number of un-observed blocks, group the block range
// on the order of 10k blocks at a time. If this turns out to be a bottleneck, we can
// parallelize these operations
maxBlockRange
:=
uint64
(
10
_000
)
batchLog
.
Info
(
"unobserved epochs"
,
"latest_l1_block_number"
,
fromL1Height
,
"latest_l2_block_number"
,
fromL2Height
)
if
err
:=
b
.
db
.
Transaction
(
func
(
tx
*
database
.
DB
)
error
{
l1BridgeLog
:=
b
.
log
.
New
(
"bridge"
,
"l1"
)
l2BridgeLog
:=
b
.
log
.
New
(
"bridge"
,
"l2"
)
// FOR OP-MAINNET, OP-GOERLI ONLY! Specially handle the existence of pre-bedrock blocks
if
l1BedrockStartingHeight
.
Cmp
(
fromL1Height
)
>
0
{
l1BridgeLog
:=
l1BridgeLog
.
New
(
"mode"
,
"legacy"
)
l2BridgeLog
:=
l2BridgeLog
.
New
(
"mode"
,
"legacy"
)
legacyFromL1Height
,
legacyToL1Height
:=
fromL1Height
,
toL1Height
legacyFromL2Height
,
legacyToL2Height
:=
fromL2Height
,
toL2Height
if
l1BedrockStartingHeight
.
Cmp
(
toL1Height
)
<=
0
{
legacyToL1Height
=
new
(
big
.
Int
)
.
Sub
(
l1BedrockStartingHeight
,
big
.
NewInt
(
1
)
)
legacyToL2Height
=
new
(
big
.
Int
)
.
Sub
(
l2BedrockStartingHeight
,
big
.
NewInt
(
1
)
)
legacyToL1Height
=
new
(
big
.
Int
)
.
Sub
(
l1BedrockStartingHeight
,
big
int
.
One
)
legacyToL2Height
=
new
(
big
.
Int
)
.
Sub
(
l2BedrockStartingHeight
,
big
int
.
One
)
}
l1BridgeLog
=
l1BridgeLog
.
New
(
"mode"
,
"legacy"
,
"from_l1_block_number"
,
legacyFromL1Height
,
"to_l1_block_number"
,
legacyToL1Height
)
l1BridgeLog
.
Info
(
"scanning for bridge events"
)
l2BridgeLog
=
l2BridgeLog
.
New
(
"mode"
,
"legacy"
,
"from_l2_block_number"
,
legacyFromL2Height
,
"to_l2_block_number"
,
legacyToL2Height
)
l2BridgeLog
.
Info
(
"scanning for bridge events"
)
// First, find all possible initiated bridge events
l1BlockGroups
:=
bigint
.
Grouped
(
legacyFromL1Height
,
legacyToL1Height
,
maxBlockRange
)
l2BlockGroups
:=
bigint
.
Grouped
(
legacyFromL2Height
,
legacyToL2Height
,
maxBlockRange
)
for
_
,
group
:=
range
l1BlockGroups
{
log
:=
l1BridgeLog
.
New
(
"from_l1_block_number"
,
group
.
Start
,
"to_l1_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for initiated bridge events"
)
if
err
:=
bridge
.
LegacyL1ProcessInitiatedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L1Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
LegacyL1ProcessInitiatedBridgeEvents
(
l1BridgeLog
,
tx
,
b
.
chainConfig
.
L1Contracts
,
legacyFromL1Height
,
legacyToL1Height
);
err
!=
nil
{
return
err
}
for
_
,
group
:=
range
l2BlockGroups
{
log
:=
l2BridgeLog
.
New
(
"from_l2_block_number"
,
group
.
Start
,
"to_l2_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for initiated bridge events"
)
if
err
:=
bridge
.
LegacyL2ProcessInitiatedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L2Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
LegacyL2ProcessInitiatedBridgeEvents
(
l2BridgeLog
,
tx
,
b
.
chainConfig
.
L2Contracts
,
legacyFromL2Height
,
legacyToL2Height
);
err
!=
nil
{
return
err
}
// Now that all initiated events have been indexed, it is ensured that all finalization can find their counterpart.
for
_
,
group
:=
range
l1BlockGroups
{
log
:=
l1BridgeLog
.
New
(
"from_l1_block_number"
,
group
.
Start
,
"to_l1_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for finalized bridge events"
)
if
err
:=
bridge
.
LegacyL1ProcessFinalizedBridgeEvents
(
log
,
tx
,
b
.
l1Etl
.
EthClient
,
b
.
chainConfig
.
L1Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
LegacyL1ProcessFinalizedBridgeEvents
(
l1BridgeLog
,
tx
,
b
.
l1Etl
.
EthClient
,
b
.
chainConfig
.
L1Contracts
,
legacyFromL1Height
,
legacyToL1Height
);
err
!=
nil
{
return
err
}
for
_
,
group
:=
range
l2BlockGroups
{
log
:=
l2BridgeLog
.
New
(
"from_l2_block_number"
,
group
.
Start
,
"to_l2_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for finalized bridge events"
)
if
err
:=
bridge
.
LegacyL2ProcessFinalizedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L2Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
LegacyL2ProcessFinalizedBridgeEvents
(
l2BridgeLog
,
tx
,
b
.
chainConfig
.
L2Contracts
,
legacyFromL2Height
,
legacyToL2Height
);
err
!=
nil
{
return
err
}
if
legacyToL1Height
.
Cmp
(
toL1Height
)
==
0
{
...
...
@@ -193,52 +189,39 @@ func (b *BridgeProcessor) Start(ctx context.Context) error {
fromL2Height
=
l2BedrockStartingHeight
}
l1BridgeLog
=
l1BridgeLog
.
New
(
"from_l1_block_number"
,
fromL1Height
,
"to_l1_block_number"
,
toL1Height
)
l1BridgeLog
.
Info
(
"scanning for bridge events"
)
l2BridgeLog
=
l2BridgeLog
.
New
(
"from_l2_block_number"
,
fromL2Height
,
"to_l2_block_number"
,
toL2Height
)
l2BridgeLog
.
Info
(
"scanning for bridge events"
)
// First, find all possible initiated bridge events
l1BlockGroups
:=
bigint
.
Grouped
(
fromL1Height
,
toL1Height
,
maxBlockRange
)
l2BlockGroups
:=
bigint
.
Grouped
(
fromL2Height
,
toL2Height
,
maxBlockRange
)
for
_
,
group
:=
range
l1BlockGroups
{
log
:=
l1BridgeLog
.
New
(
"from_block_number"
,
group
.
Start
,
"to_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for initiated bridge events"
)
if
err
:=
bridge
.
L1ProcessInitiatedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L1Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
L1ProcessInitiatedBridgeEvents
(
l1BridgeLog
,
tx
,
b
.
chainConfig
.
L1Contracts
,
fromL1Height
,
toL1Height
);
err
!=
nil
{
return
err
}
for
_
,
group
:=
range
l2BlockGroups
{
log
:=
l2BridgeLog
.
New
(
"from_block_number"
,
group
.
Start
,
"to_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for initiated bridge events"
)
if
err
:=
bridge
.
L2ProcessInitiatedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L2Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
L2ProcessInitiatedBridgeEvents
(
l2BridgeLog
,
tx
,
b
.
chainConfig
.
L2Contracts
,
fromL2Height
,
toL2Height
);
err
!=
nil
{
return
err
}
// Now all finalization events can find their counterpart.
for
_
,
group
:=
range
l1BlockGroups
{
log
:=
l1BridgeLog
.
New
(
"from_block_number"
,
group
.
Start
,
"to_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for finalized bridge events"
)
if
err
:=
bridge
.
L1ProcessFinalizedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L1Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
L1ProcessFinalizedBridgeEvents
(
l1BridgeLog
,
tx
,
b
.
chainConfig
.
L1Contracts
,
fromL1Height
,
toL1Height
);
err
!=
nil
{
return
err
}
for
_
,
group
:=
range
l2BlockGroups
{
log
:=
l2BridgeLog
.
New
(
"from_block_number"
,
group
.
Start
,
"to_block_number"
,
group
.
End
)
log
.
Info
(
"scanning for finalized bridge events"
)
if
err
:=
bridge
.
L2ProcessFinalizedBridgeEvents
(
log
,
tx
,
b
.
chainConfig
.
L2Contracts
,
group
.
Start
,
group
.
End
);
err
!=
nil
{
return
err
}
if
err
:=
bridge
.
L2ProcessFinalizedBridgeEvents
(
l2BridgeLog
,
tx
,
b
.
chainConfig
.
L2Contracts
,
fromL2Height
,
toL2Height
);
err
!=
nil
{
return
err
}
// a-ok
return
nil
})
if
err
!=
nil
{
});
err
!=
nil
{
// Try again on a subsequent interval
batchLog
.
Error
(
"failed to index bridge events"
,
"err"
,
err
)
}
else
{
batchLog
.
Info
(
"indexed bridge events"
,
"latest_l1_block_number"
,
toL1Height
,
"latest_l2_block_number"
,
toL2Height
)
b
.
LatestL1Header
=
latestEpoch
.
L1BlockHeader
.
RLPHeader
.
Header
()
b
.
LatestL2Header
=
latestEpoch
.
L2BlockHeader
.
RLPHeader
.
Header
()
return
err
}
batchLog
.
Info
(
"indexed bridge events"
,
"latest_l1_block_number"
,
toL1Height
,
"latest_l2_block_number"
,
toL2Height
)
b
.
LatestL1Header
=
latestEpoch
.
L1BlockHeader
.
RLPHeader
.
Header
()
b
.
LatestL2Header
=
latestEpoch
.
L2BlockHeader
.
RLPHeader
.
Header
()
}
}
package.json
View file @
67f19ecc
...
...
@@ -49,7 +49,7 @@
"
chai
"
:
"
^4.3.9
"
,
"
depcheck
"
:
"
^1.4.3
"
,
"
doctoc
"
:
"
^2.2.0
"
,
"
eslint
"
:
"
^8.
43
.0
"
,
"
eslint
"
:
"
^8.
50
.0
"
,
"
eslint-config-prettier
"
:
"
^8.3.0
"
,
"
eslint-config-standard
"
:
"
^16.0.3
"
,
"
eslint-plugin-import
"
:
"
^2.26.0
"
,
...
...
pnpm-lock.yaml
View file @
67f19ecc
...
...
@@ -17,7 +17,7 @@ importers:
devDependencies
:
'
@babel/eslint-parser'
:
specifier
:
^7.18.2
version
:
7.22.15(@babel/core@7.22.10)(eslint@8.
49
.0)
version
:
7.22.15(@babel/core@7.22.10)(eslint@8.
50
.0)
'
@changesets/changelog-github'
:
specifier
:
^0.4.8
version
:
0.4.8
...
...
@@ -38,10 +38,10 @@ importers:
version
:
20.6.3
'
@typescript-eslint/eslint-plugin'
:
specifier
:
^6.7.0
version
:
6.7.0(@typescript-eslint/parser@6.7.3)(eslint@8.
49
.0)(typescript@5.2.2)
version
:
6.7.0(@typescript-eslint/parser@6.7.3)(eslint@8.
50
.0)(typescript@5.2.2)
'
@typescript-eslint/parser'
:
specifier
:
^6.7.0
version
:
6.7.3(eslint@8.
49
.0)(typescript@5.2.2)
version
:
6.7.3(eslint@8.
50
.0)(typescript@5.2.2)
chai
:
specifier
:
^4.3.9
version
:
4.3.9
...
...
@@ -52,38 +52,38 @@ importers:
specifier
:
^2.2.0
version
:
2.2.1
eslint
:
specifier
:
^8.
43
.0
version
:
8.
49
.0
specifier
:
^8.
50
.0
version
:
8.
50
.0
eslint-config-prettier
:
specifier
:
^8.3.0
version
:
8.3.0(eslint@8.
49
.0)
version
:
8.3.0(eslint@8.
50
.0)
eslint-config-standard
:
specifier
:
^16.0.3
version
:
16.0.3(eslint-plugin-import@2.28.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.
49
.0)
version
:
16.0.3(eslint-plugin-import@2.28.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.
50
.0)
eslint-plugin-import
:
specifier
:
^2.26.0
version
:
2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
49
.0)
version
:
2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
50
.0)
eslint-plugin-jsdoc
:
specifier
:
^35.1.2
version
:
35.5.1(eslint@8.
49
.0)
version
:
35.5.1(eslint@8.
50
.0)
eslint-plugin-node
:
specifier
:
^11.1.0
version
:
11.1.0(eslint@8.
49
.0)
version
:
11.1.0(eslint@8.
50
.0)
eslint-plugin-prefer-arrow
:
specifier
:
^1.2.3
version
:
1.2.3(eslint@8.
49
.0)
version
:
1.2.3(eslint@8.
50
.0)
eslint-plugin-prettier
:
specifier
:
^4.0.0
version
:
4.2.1(eslint-config-prettier@8.3.0)(eslint@8.
49
.0)(prettier@2.8.8)
version
:
4.2.1(eslint-config-prettier@8.3.0)(eslint@8.
50
.0)(prettier@2.8.8)
eslint-plugin-promise
:
specifier
:
^5.1.0
version
:
5.2.0(eslint@8.
49
.0)
version
:
5.2.0(eslint@8.
50
.0)
eslint-plugin-react
:
specifier
:
^7.24.0
version
:
7.33.2(eslint@8.
49
.0)
version
:
7.33.2(eslint@8.
50
.0)
eslint-plugin-unicorn
:
specifier
:
^48.0.1
version
:
48.0.1(eslint@8.
49
.0)
version
:
48.0.1(eslint@8.
50
.0)
husky
:
specifier
:
^8.0.3
version
:
8.0.3
...
...
@@ -632,7 +632,7 @@ packages:
-
supports-color
dev
:
true
/@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.
49
.0)
:
/@babel/eslint-parser@7.22.15(@babel/core@7.22.10)(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-yc8OOBIQk1EcRrpizuARSQS0TWAcOMpEJ1aafhNznaeYkeL+OhqnDObGFylB8ka8VFF/sZc+S4RzHyO+3LjQxg==
}
engines
:
{
node
:
^10.13.0 || ^12.13.0 || >=14.0.0
}
peerDependencies
:
...
...
@@ -641,7 +641,7 @@ packages:
dependencies
:
'
@babel/core'
:
7.22.10
'
@nicolo-ribaudo/eslint-scope-5-internals'
:
5.1.1-v1
eslint
:
8.
49
.0
eslint
:
8.
50
.0
eslint-visitor-keys
:
2.1.0
semver
:
6.3.1
dev
:
true
...
...
@@ -1775,16 +1775,6 @@ packages:
dev
:
true
optional
:
true
/@eslint-community/eslint-utils@4.4.0(eslint@8.49.0)
:
resolution
:
{
integrity
:
sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
peerDependencies
:
eslint
:
^6.0.0 || ^7.0.0 || >=8.0.0
dependencies
:
eslint
:
8.49.0
eslint-visitor-keys
:
3.4.3
dev
:
true
/@eslint-community/eslint-utils@4.4.0(eslint@8.50.0)
:
resolution
:
{
integrity
:
sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
...
...
@@ -1817,11 +1807,6 @@ packages:
-
supports-color
dev
:
true
/@eslint/js@8.49.0
:
resolution
:
{
integrity
:
sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dev
:
true
/@eslint/js@8.50.0
:
resolution
:
{
integrity
:
sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
...
...
@@ -4227,7 +4212,7 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/eslint-plugin@6.7.0(@typescript-eslint/parser@6.7.3)(eslint@8.
49
.0)(typescript@5.2.2)
:
/@typescript-eslint/eslint-plugin@6.7.0(@typescript-eslint/parser@6.7.3)(eslint@8.
50
.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
peerDependencies
:
...
...
@@ -4239,13 +4224,13 @@ packages:
optional
:
true
dependencies
:
'
@eslint-community/regexpp'
:
4.6.2
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
49
.0)(typescript@5.2.2)
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
50
.0)(typescript@5.2.2)
'
@typescript-eslint/scope-manager'
:
6.7.0
'
@typescript-eslint/type-utils'
:
6.7.0(eslint@8.
49
.0)(typescript@5.2.2)
'
@typescript-eslint/utils'
:
6.7.0(eslint@8.
49
.0)(typescript@5.2.2)
'
@typescript-eslint/type-utils'
:
6.7.0(eslint@8.
50
.0)(typescript@5.2.2)
'
@typescript-eslint/utils'
:
6.7.0(eslint@8.
50
.0)(typescript@5.2.2)
'
@typescript-eslint/visitor-keys'
:
6.7.0
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.
49
.0
eslint
:
8.
50
.0
graphemer
:
1.4.0
ignore
:
5.2.4
natural-compare
:
1.4.0
...
...
@@ -4277,7 +4262,7 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/parser@6.7.3(eslint@8.
49
.0)(typescript@5.2.2)
:
/@typescript-eslint/parser@6.7.3(eslint@8.
50
.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
peerDependencies
:
...
...
@@ -4292,7 +4277,7 @@ packages:
'
@typescript-eslint/typescript-estree'
:
6.7.3(typescript@5.2.2)
'
@typescript-eslint/visitor-keys'
:
6.7.3
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.
49
.0
eslint
:
8.
50
.0
typescript
:
5.2.2
transitivePeerDependencies
:
-
supports-color
...
...
@@ -4322,26 +4307,6 @@ packages:
'
@typescript-eslint/visitor-keys'
:
6.7.3
dev
:
true
/@typescript-eslint/type-utils@6.7.0(eslint@8.49.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==
}
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.7.0(typescript@5.2.2)
'
@typescript-eslint/utils'
:
6.7.0(eslint@8.49.0)(typescript@5.2.2)
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.49.0
ts-api-utils
:
1.0.1(typescript@5.2.2)
typescript
:
5.2.2
transitivePeerDependencies
:
-
supports-color
dev
:
true
/@typescript-eslint/type-utils@6.7.0(eslint@8.50.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -4440,25 +4405,6 @@ packages:
-
supports-color
dev
:
true
/@typescript-eslint/utils@6.7.0(eslint@8.49.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==
}
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.49.0)
'
@types/json-schema'
:
7.0.12
'
@types/semver'
:
7.5.0
'
@typescript-eslint/scope-manager'
:
6.7.0
'
@typescript-eslint/types'
:
6.7.0
'
@typescript-eslint/typescript-estree'
:
6.7.0(typescript@5.2.2)
eslint
:
8.49.0
semver
:
7.5.4
transitivePeerDependencies
:
-
supports-color
-
typescript
dev
:
true
/@typescript-eslint/utils@6.7.0(eslint@8.50.0)(typescript@5.2.2)
:
resolution
:
{
integrity
:
sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==
}
engines
:
{
node
:
^16.0.0 || >=18.0.0
}
...
...
@@ -7603,16 +7549,16 @@ packages:
engines
:
{
node
:
'
>=10'
}
dev
:
true
/eslint-config-prettier@8.3.0(eslint@8.
49
.0)
:
/eslint-config-prettier@8.3.0(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==
}
hasBin
:
true
peerDependencies
:
eslint
:
'
>=7.0.0'
dependencies
:
eslint
:
8.
49
.0
eslint
:
8.
50
.0
dev
:
true
/eslint-config-standard@16.0.3(eslint-plugin-import@2.28.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.
49
.0)
:
/eslint-config-standard@16.0.3(eslint-plugin-import@2.28.1)(eslint-plugin-node@11.1.0)(eslint-plugin-promise@5.2.0)(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==
}
peerDependencies
:
eslint
:
^7.12.1
...
...
@@ -7620,10 +7566,10 @@ packages:
eslint-plugin-node
:
^11.1.0
eslint-plugin-promise
:
^4.2.1 || ^5.0.0
dependencies
:
eslint
:
8.
49
.0
eslint-plugin-import
:
2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
49
.0)
eslint-plugin-node
:
11.1.0(eslint@8.
49
.0)
eslint-plugin-promise
:
5.2.0(eslint@8.
49
.0)
eslint
:
8.
50
.0
eslint-plugin-import
:
2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
50
.0)
eslint-plugin-node
:
11.1.0(eslint@8.
50
.0)
eslint-plugin-promise
:
5.2.0(eslint@8.
50
.0)
dev
:
true
/eslint-import-resolver-node@0.3.9
:
...
...
@@ -7636,7 +7582,7 @@ packages:
-
supports-color
dev
:
true
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.
49
.0)
:
/eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==
}
engines
:
{
node
:
'
>=4'
}
peerDependencies
:
...
...
@@ -7657,26 +7603,26 @@ packages:
eslint-import-resolver-webpack
:
optional
:
true
dependencies
:
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
49
.0)(typescript@5.2.2)
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
50
.0)(typescript@5.2.2)
debug
:
3.2.7
eslint
:
8.
49
.0
eslint
:
8.
50
.0
eslint-import-resolver-node
:
0.3.9
transitivePeerDependencies
:
-
supports-color
dev
:
true
/eslint-plugin-es@3.0.1(eslint@8.
49
.0)
:
/eslint-plugin-es@3.0.1(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==
}
engines
:
{
node
:
'
>=8.10.0'
}
peerDependencies
:
eslint
:
'
>=4.19.1'
dependencies
:
eslint
:
8.
49
.0
eslint
:
8.
50
.0
eslint-utils
:
2.1.0
regexpp
:
3.2.0
dev
:
true
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
49
.0)
:
/eslint-plugin-import@2.28.1(@typescript-eslint/parser@6.7.3)(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A==
}
engines
:
{
node
:
'
>=4'
}
peerDependencies
:
...
...
@@ -7686,16 +7632,16 @@ packages:
'
@typescript-eslint/parser'
:
optional
:
true
dependencies
:
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
49
.0)(typescript@5.2.2)
'
@typescript-eslint/parser'
:
6.7.3(eslint@8.
50
.0)(typescript@5.2.2)
array-includes
:
3.1.6
array.prototype.findlastindex
:
1.2.2
array.prototype.flat
:
1.3.1
array.prototype.flatmap
:
1.3.1
debug
:
3.2.7
doctrine
:
2.1.0
eslint
:
8.
49
.0
eslint
:
8.
50
.0
eslint-import-resolver-node
:
0.3.9
eslint-module-utils
:
2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.
49
.0)
eslint-module-utils
:
2.8.0(@typescript-eslint/parser@6.7.3)(eslint-import-resolver-node@0.3.9)(eslint@8.
50
.0)
has
:
1.0.3
is-core-module
:
2.13.0
is-glob
:
4.0.3
...
...
@@ -7711,7 +7657,7 @@ packages:
-
supports-color
dev
:
true
/eslint-plugin-jsdoc@35.5.1(eslint@8.
49
.0)
:
/eslint-plugin-jsdoc@35.5.1(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-pPYPWtsykwVEue1tYEyoppBj4dgF7XicF67tLLLraY6RQYBq7qMKjUHji19+hfiTtYKKBD0YfeK8hgjPAE5viw==
}
engines
:
{
node
:
'
>=12'
}
peerDependencies
:
...
...
@@ -7720,7 +7666,7 @@ packages:
'
@es-joy/jsdoccomment'
:
0.9.0-alpha.1
comment-parser
:
1.1.6-beta.0
debug
:
4.3.4(supports-color@8.1.1)
eslint
:
8.
49
.0
eslint
:
8.
50
.0
esquery
:
1.4.0
jsdoc-type-pratt-parser
:
1.1.1
lodash
:
4.17.21
...
...
@@ -7731,14 +7677,14 @@ packages:
-
supports-color
dev
:
true
/eslint-plugin-node@11.1.0(eslint@8.
49
.0)
:
/eslint-plugin-node@11.1.0(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==
}
engines
:
{
node
:
'
>=8.10.0'
}
peerDependencies
:
eslint
:
'
>=5.16.0'
dependencies
:
eslint
:
8.
49
.0
eslint-plugin-es
:
3.0.1(eslint@8.
49
.0)
eslint
:
8.
50
.0
eslint-plugin-es
:
3.0.1(eslint@8.
50
.0)
eslint-utils
:
2.1.0
ignore
:
5.2.4
minimatch
:
3.1.2
...
...
@@ -7746,15 +7692,15 @@ packages:
semver
:
6.3.1
dev
:
true
/eslint-plugin-prefer-arrow@1.2.3(eslint@8.
49
.0)
:
/eslint-plugin-prefer-arrow@1.2.3(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-J9I5PKCOJretVuiZRGvPQxCbllxGAV/viI20JO3LYblAodofBxyMnZAJ+WGeClHgANnSJberTNoFWWjrWKBuXQ==
}
peerDependencies
:
eslint
:
'
>=2.0.0'
dependencies
:
eslint
:
8.
49
.0
eslint
:
8.
50
.0
dev
:
true
/eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.
49
.0)(prettier@2.8.8)
:
/eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.3.0)(eslint@8.
50
.0)(prettier@2.8.8)
:
resolution
:
{
integrity
:
sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==
}
engines
:
{
node
:
'
>=12.0.0'
}
peerDependencies
:
...
...
@@ -7765,22 +7711,22 @@ packages:
eslint-config-prettier
:
optional
:
true
dependencies
:
eslint
:
8.
49
.0
eslint-config-prettier
:
8.3.0(eslint@8.
49
.0)
eslint
:
8.
50
.0
eslint-config-prettier
:
8.3.0(eslint@8.
50
.0)
prettier
:
2.8.8
prettier-linter-helpers
:
1.0.0
dev
:
true
/eslint-plugin-promise@5.2.0(eslint@8.
49
.0)
:
/eslint-plugin-promise@5.2.0(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==
}
engines
:
{
node
:
^10.12.0 || >=12.0.0
}
peerDependencies
:
eslint
:
^7.0.0
dependencies
:
eslint
:
8.
49
.0
eslint
:
8.
50
.0
dev
:
true
/eslint-plugin-react@7.33.2(eslint@8.
49
.0)
:
/eslint-plugin-react@7.33.2(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==
}
engines
:
{
node
:
'
>=4'
}
peerDependencies
:
...
...
@@ -7791,7 +7737,7 @@ packages:
array.prototype.tosorted
:
1.1.1
doctrine
:
2.1.0
es-iterator-helpers
:
1.0.13
eslint
:
8.
49
.0
eslint
:
8.
50
.0
estraverse
:
5.3.0
jsx-ast-utils
:
3.2.0
minimatch
:
3.1.2
...
...
@@ -7805,17 +7751,17 @@ packages:
string.prototype.matchall
:
4.0.8
dev
:
true
/eslint-plugin-unicorn@48.0.1(eslint@8.
49
.0)
:
/eslint-plugin-unicorn@48.0.1(eslint@8.
50
.0)
:
resolution
:
{
integrity
:
sha512-FW+4r20myG/DqFcCSzoumaddKBicIPeFnTrifon2mWIzlfyvzwyqZjqVP7m4Cqr/ZYisS2aiLghkUWaPg6vtCw==
}
engines
:
{
node
:
'
>=16'
}
peerDependencies
:
eslint
:
'
>=8.44.0'
dependencies
:
'
@babel/helper-validator-identifier'
:
7.22.5
'
@eslint-community/eslint-utils'
:
4.4.0(eslint@8.
49
.0)
'
@eslint-community/eslint-utils'
:
4.4.0(eslint@8.
50
.0)
ci-info
:
3.8.0
clean-regexp
:
1.0.0
eslint
:
8.
49
.0
eslint
:
8.
50
.0
esquery
:
1.5.0
indent-string
:
4.0.0
is-builtin-module
:
3.2.1
...
...
@@ -7867,52 +7813,6 @@ packages:
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
dev
:
true
/eslint@8.49.0
:
resolution
:
{
integrity
:
sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
hasBin
:
true
dependencies
:
'
@eslint-community/eslint-utils'
:
4.4.0(eslint@8.49.0)
'
@eslint-community/regexpp'
:
4.6.2
'
@eslint/eslintrc'
:
2.1.2
'
@eslint/js'
:
8.49.0
'
@humanwhocodes/config-array'
:
0.11.11
'
@humanwhocodes/module-importer'
:
1.0.1
'
@nodelib/fs.walk'
:
1.2.8
ajv
:
6.12.6
chalk
:
4.1.2
cross-spawn
:
7.0.3
debug
:
4.3.4(supports-color@8.1.1)
doctrine
:
3.0.0
escape-string-regexp
:
4.0.0
eslint-scope
:
7.2.2
eslint-visitor-keys
:
3.4.3
espree
:
9.6.1
esquery
:
1.5.0
esutils
:
2.0.3
fast-deep-equal
:
3.1.3
file-entry-cache
:
6.0.1
find-up
:
5.0.0
glob-parent
:
6.0.2
globals
:
13.21.0
graphemer
:
1.4.0
ignore
:
5.2.4
imurmurhash
:
0.1.4
is-glob
:
4.0.3
is-path-inside
:
3.0.3
js-yaml
:
4.1.0
json-stable-stringify-without-jsonify
:
1.0.1
levn
:
0.4.1
lodash.merge
:
4.6.2
minimatch
:
3.1.2
natural-compare
:
1.4.0
optionator
:
0.9.3
strip-ansi
:
6.0.1
text-table
:
0.2.0
transitivePeerDependencies
:
-
supports-color
dev
:
true
/eslint@8.50.0
:
resolution
:
{
integrity
:
sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==
}
engines
:
{
node
:
^12.22.0 || ^14.17.0 || >=16.0.0
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment