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
179aea69
Unverified
Commit
179aea69
authored
Dec 04, 2023
by
protolambda
Committed by
GitHub
Dec 04, 2023
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8416 from testinprod-io/tip/batch-decoder-span-batch-support
op-node: batch_decoder: Support Span Batch
parents
372d13b8
a77ac64f
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
209 additions
and
106 deletions
+209
-106
README.md
op-node/cmd/batch_decoder/README.md
+6
-1
main.go
op-node/cmd/batch_decoder/main.go
+55
-10
reassemble.go
op-node/cmd/batch_decoder/reassemble/reassemble.go
+38
-14
batch_test.go
op-node/rollup/derive/batch_test.go
+2
-6
channel_in_reader.go
op-node/rollup/derive/channel_in_reader.go
+2
-16
singular_batch.go
op-node/rollup/derive/singular_batch.go
+10
-0
span_batch.go
op-node/rollup/derive/span_batch.go
+88
-51
span_batch_test.go
op-node/rollup/derive/span_batch_test.go
+8
-8
No files found.
op-node/cmd/batch_decoder/README.md
View file @
179aea69
...
@@ -24,7 +24,12 @@ the transaction hash.
...
@@ -24,7 +24,12 @@ the transaction hash.
`batch_decoder reassemble`
goes through all of the found frames in the cache & then turns them
`batch_decoder reassemble`
goes through all of the found frames in the cache & then turns them
into channels. It then stores the channels with metadata on disk where the file name is the Channel ID.
into channels. It then stores the channels with metadata on disk where the file name is the Channel ID.
Each channel can contain multiple batches.
If the batch is span batch,
`batch_decoder`
derives span batch using
`L2BlockTime`
,
`L2GenesisTime`
, and
`L2ChainID`
.
These arguments can be provided to the binary using flags.
If the batch is a singular batch,
`batch_decoder`
does not derive and stores the batch as is.
### Force Close
### Force Close
...
...
op-node/cmd/batch_decoder/main.go
View file @
179aea69
...
@@ -4,11 +4,13 @@ import (
...
@@ -4,11 +4,13 @@ import (
"context"
"context"
"fmt"
"fmt"
"log"
"log"
"math/big"
"os"
"os"
"time"
"time"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/reassemble"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/reassemble"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/ethclient"
...
@@ -77,7 +79,7 @@ func main() {
...
@@ -77,7 +79,7 @@ func main() {
End
:
uint64
(
cliCtx
.
Int
(
"end"
)),
End
:
uint64
(
cliCtx
.
Int
(
"end"
)),
ChainID
:
chainID
,
ChainID
:
chainID
,
BatchSenders
:
map
[
common
.
Address
]
struct
{}{
BatchSenders
:
map
[
common
.
Address
]
struct
{}{
common
.
HexToAddress
(
cliCtx
.
String
(
"sender"
))
:
struct
{}
{},
common
.
HexToAddress
(
cliCtx
.
String
(
"sender"
))
:
{},
},
},
BatchInbox
:
common
.
HexToAddress
(
cliCtx
.
String
(
"inbox"
)),
BatchInbox
:
common
.
HexToAddress
(
cliCtx
.
String
(
"inbox"
)),
OutDirectory
:
cliCtx
.
String
(
"out"
),
OutDirectory
:
cliCtx
.
String
(
"out"
),
...
@@ -92,13 +94,8 @@ func main() {
...
@@ -92,13 +94,8 @@ func main() {
},
},
{
{
Name
:
"reassemble"
,
Name
:
"reassemble"
,
Usage
:
"Reassembles channels from fetched batches"
,
Usage
:
"Reassembles channels from fetched batch
transactions and decode batch
es"
,
Flags
:
[]
cli
.
Flag
{
Flags
:
[]
cli
.
Flag
{
&
cli
.
StringFlag
{
Name
:
"inbox"
,
Value
:
"0xff00000000000000000000000000000000000420"
,
Usage
:
"Batch Inbox Address"
,
},
&
cli
.
StringFlag
{
&
cli
.
StringFlag
{
Name
:
"in"
,
Name
:
"in"
,
Value
:
"/tmp/batch_decoder/transactions_cache"
,
Value
:
"/tmp/batch_decoder/transactions_cache"
,
...
@@ -109,12 +106,60 @@ func main() {
...
@@ -109,12 +106,60 @@ func main() {
Value
:
"/tmp/batch_decoder/channel_cache"
,
Value
:
"/tmp/batch_decoder/channel_cache"
,
Usage
:
"Cache directory for the found channels"
,
Usage
:
"Cache directory for the found channels"
,
},
},
&
cli
.
Uint64Flag
{
Name
:
"l2-chain-id"
,
Value
:
10
,
Usage
:
"L2 chain id for span batch derivation. Default value from op-mainnet."
,
},
&
cli
.
Uint64Flag
{
Name
:
"l2-genesis-timestamp"
,
Value
:
1686068903
,
Usage
:
"L2 genesis time for span batch derivation. Default value from op-mainnet. "
+
"Superchain-registry prioritized when given value is inconsistent."
,
},
&
cli
.
Uint64Flag
{
Name
:
"l2-block-time"
,
Value
:
2
,
Usage
:
"L2 block time for span batch derivation. Default value from op-mainnet. "
+
"Superchain-registry prioritized when given value is inconsistent."
,
},
&
cli
.
StringFlag
{
Name
:
"inbox"
,
Value
:
"0xFF00000000000000000000000000000000000010"
,
Usage
:
"Batch Inbox Address. Default value from op-mainnet. "
+
"Superchain-registry prioritized when given value is inconsistent."
,
},
},
},
Action
:
func
(
cliCtx
*
cli
.
Context
)
error
{
Action
:
func
(
cliCtx
*
cli
.
Context
)
error
{
var
(
L2GenesisTime
uint64
=
cliCtx
.
Uint64
(
"l2-genesis-timestamp"
)
L2BlockTime
uint64
=
cliCtx
.
Uint64
(
"l2-block-time"
)
BatchInboxAddress
common
.
Address
=
common
.
HexToAddress
(
cliCtx
.
String
(
"inbox"
))
)
L2ChainID
:=
new
(
big
.
Int
)
.
SetUint64
(
cliCtx
.
Uint64
(
"l2-chain-id"
))
rollupCfg
,
err
:=
rollup
.
LoadOPStackRollupConfig
(
L2ChainID
.
Uint64
())
if
err
==
nil
{
// prioritize superchain config
if
L2GenesisTime
!=
rollupCfg
.
Genesis
.
L2Time
{
L2GenesisTime
=
rollupCfg
.
Genesis
.
L2Time
fmt
.
Printf
(
"L2GenesisTime overridden: %v
\n
"
,
L2GenesisTime
)
}
if
L2BlockTime
!=
rollupCfg
.
BlockTime
{
L2BlockTime
=
rollupCfg
.
BlockTime
fmt
.
Printf
(
"L2BlockTime overridden: %v
\n
"
,
L2BlockTime
)
}
if
BatchInboxAddress
!=
rollupCfg
.
BatchInboxAddress
{
BatchInboxAddress
=
rollupCfg
.
BatchInboxAddress
fmt
.
Printf
(
"BatchInboxAddress overridden: %v
\n
"
,
BatchInboxAddress
)
}
}
config
:=
reassemble
.
Config
{
config
:=
reassemble
.
Config
{
BatchInbox
:
common
.
HexToAddress
(
cliCtx
.
String
(
"inbox"
))
,
BatchInbox
:
BatchInboxAddress
,
InDirectory
:
cliCtx
.
String
(
"in"
),
InDirectory
:
cliCtx
.
String
(
"in"
),
OutDirectory
:
cliCtx
.
String
(
"out"
),
OutDirectory
:
cliCtx
.
String
(
"out"
),
L2ChainID
:
L2ChainID
,
L2GenesisTime
:
L2GenesisTime
,
L2BlockTime
:
L2BlockTime
,
}
}
reassemble
.
Channels
(
config
)
reassemble
.
Channels
(
config
)
return
nil
return
nil
...
...
op-node/cmd/batch_decoder/reassemble/reassemble.go
View file @
179aea69
...
@@ -5,13 +5,11 @@ import (
...
@@ -5,13 +5,11 @@ import (
"fmt"
"fmt"
"io"
"io"
"log"
"log"
"math/big"
"os"
"os"
"path"
"path"
"sort"
"sort"
"github.com/ethereum-optimism/optimism/op-node/chaincfg"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-service/eth"
"github.com/ethereum-optimism/optimism/op-service/eth"
...
@@ -24,7 +22,8 @@ type ChannelWithMetadata struct {
...
@@ -24,7 +22,8 @@ type ChannelWithMetadata struct {
InvalidFrames
bool
`json:"invalid_frames"`
InvalidFrames
bool
`json:"invalid_frames"`
InvalidBatches
bool
`json:"invalid_batches"`
InvalidBatches
bool
`json:"invalid_batches"`
Frames
[]
FrameWithMetadata
`json:"frames"`
Frames
[]
FrameWithMetadata
`json:"frames"`
Batches
[]
derive
.
BatchData
`json:"batches"`
Batches
[]
derive
.
Batch
`json:"batches"`
BatchTypes
[]
int
`json:"batch_types"`
}
}
type
FrameWithMetadata
struct
{
type
FrameWithMetadata
struct
{
...
@@ -39,6 +38,9 @@ type Config struct {
...
@@ -39,6 +38,9 @@ type Config struct {
BatchInbox
common
.
Address
BatchInbox
common
.
Address
InDirectory
string
InDirectory
string
OutDirectory
string
OutDirectory
string
L2ChainID
*
big
.
Int
L2GenesisTime
uint64
L2BlockTime
uint64
}
}
func
LoadFrames
(
directory
string
,
inbox
common
.
Address
)
[]
FrameWithMetadata
{
func
LoadFrames
(
directory
string
,
inbox
common
.
Address
)
[]
FrameWithMetadata
{
...
@@ -68,9 +70,8 @@ func Channels(config Config) {
...
@@ -68,9 +70,8 @@ func Channels(config Config) {
for
_
,
frame
:=
range
frames
{
for
_
,
frame
:=
range
frames
{
framesByChannel
[
frame
.
Frame
.
ID
]
=
append
(
framesByChannel
[
frame
.
Frame
.
ID
],
frame
)
framesByChannel
[
frame
.
Frame
.
ID
]
=
append
(
framesByChannel
[
frame
.
Frame
.
ID
],
frame
)
}
}
cfg
:=
chaincfg
.
Mainnet
for
id
,
frames
:=
range
framesByChannel
{
for
id
,
frames
:=
range
framesByChannel
{
ch
:=
processFrames
(
c
f
g
,
id
,
frames
)
ch
:=
processFrames
(
c
onfi
g
,
id
,
frames
)
filename
:=
path
.
Join
(
config
.
OutDirectory
,
fmt
.
Sprintf
(
"%s.json"
,
id
.
String
()))
filename
:=
path
.
Join
(
config
.
OutDirectory
,
fmt
.
Sprintf
(
"%s.json"
,
id
.
String
()))
if
err
:=
writeChannel
(
ch
,
filename
);
err
!=
nil
{
if
err
:=
writeChannel
(
ch
,
filename
);
err
!=
nil
{
log
.
Fatal
(
err
)
log
.
Fatal
(
err
)
...
@@ -88,7 +89,7 @@ func writeChannel(ch ChannelWithMetadata, filename string) error {
...
@@ -88,7 +89,7 @@ func writeChannel(ch ChannelWithMetadata, filename string) error {
return
enc
.
Encode
(
ch
)
return
enc
.
Encode
(
ch
)
}
}
func
processFrames
(
cfg
*
rollup
.
Config
,
id
derive
.
ChannelID
,
frames
[]
FrameWithMetadata
)
ChannelWithMetadata
{
func
processFrames
(
cfg
Config
,
id
derive
.
ChannelID
,
frames
[]
FrameWithMetadata
)
ChannelWithMetadata
{
ch
:=
derive
.
NewChannel
(
id
,
eth
.
L1BlockRef
{
Number
:
frames
[
0
]
.
InclusionBlock
})
ch
:=
derive
.
NewChannel
(
id
,
eth
.
L1BlockRef
{
Number
:
frames
[
0
]
.
InclusionBlock
})
invalidFrame
:=
false
invalidFrame
:=
false
...
@@ -104,17 +105,39 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe
...
@@ -104,17 +105,39 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe
}
}
}
}
var
batches
[]
derive
.
BatchData
var
batches
[]
derive
.
Batch
var
batchTypes
[]
int
invalidBatches
:=
false
invalidBatches
:=
false
if
ch
.
IsReady
()
{
if
ch
.
IsReady
()
{
br
,
err
:=
derive
.
BatchReader
(
ch
.
Reader
())
br
,
err
:=
derive
.
BatchReader
(
ch
.
Reader
())
if
err
==
nil
{
if
err
==
nil
{
for
batch
,
err
:=
br
();
err
!=
io
.
EOF
;
batch
,
err
=
br
()
{
for
batch
Data
,
err
:=
br
();
err
!=
io
.
EOF
;
batchData
,
err
=
br
()
{
if
err
!=
nil
{
if
err
!=
nil
{
fmt
.
Printf
(
"Error reading batch for channel %v. Err: %v
\n
"
,
id
.
String
(),
err
)
fmt
.
Printf
(
"Error reading batch
Data
for channel %v. Err: %v
\n
"
,
id
.
String
(),
err
)
invalidBatches
=
true
invalidBatches
=
true
}
else
{
}
else
{
batches
=
append
(
batches
,
*
batch
)
batchType
:=
batchData
.
GetBatchType
()
batchTypes
=
append
(
batchTypes
,
int
(
batchType
))
switch
batchType
{
case
derive
.
SingularBatchType
:
singularBatch
,
err
:=
derive
.
GetSingularBatch
(
batchData
)
if
err
!=
nil
{
invalidBatches
=
true
fmt
.
Printf
(
"Error converting singularBatch from batchData for channel %v. Err: %v
\n
"
,
id
.
String
(),
err
)
}
// singularBatch will be nil when errored
batches
=
append
(
batches
,
singularBatch
)
case
derive
.
SpanBatchType
:
spanBatch
,
err
:=
derive
.
DeriveSpanBatch
(
batchData
,
cfg
.
L2BlockTime
,
cfg
.
L2GenesisTime
,
cfg
.
L2ChainID
)
if
err
!=
nil
{
invalidBatches
=
true
fmt
.
Printf
(
"Error deriving spanBatch from batchData for channel %v. Err: %v
\n
"
,
id
.
String
(),
err
)
}
// spanBatch will be nil when errored
batches
=
append
(
batches
,
spanBatch
)
default
:
fmt
.
Printf
(
"unrecognized batch type: %d for channel %v.
\n
"
,
batchData
.
GetBatchType
(),
id
.
String
())
}
}
}
}
}
}
else
{
}
else
{
...
@@ -131,6 +154,7 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe
...
@@ -131,6 +154,7 @@ func processFrames(cfg *rollup.Config, id derive.ChannelID, frames []FrameWithMe
InvalidFrames
:
invalidFrame
,
InvalidFrames
:
invalidFrame
,
InvalidBatches
:
invalidBatches
,
InvalidBatches
:
invalidBatches
,
Batches
:
batches
,
Batches
:
batches
,
BatchTypes
:
batchTypes
,
}
}
}
}
...
...
op-node/rollup/derive/batch_test.go
View file @
179aea69
...
@@ -172,9 +172,7 @@ func TestBatchRoundTrip(t *testing.T) {
...
@@ -172,9 +172,7 @@ func TestBatchRoundTrip(t *testing.T) {
err
=
dec
.
UnmarshalBinary
(
enc
)
err
=
dec
.
UnmarshalBinary
(
enc
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
if
dec
.
GetBatchType
()
==
SpanBatchType
{
if
dec
.
GetBatchType
()
==
SpanBatchType
{
rawSpanBatch
,
ok
:=
dec
.
inner
.
(
*
RawSpanBatch
)
_
,
err
:=
DeriveSpanBatch
(
&
dec
,
blockTime
,
genesisTimestamp
,
chainID
)
require
.
True
(
t
,
ok
)
_
,
err
:=
rawSpanBatch
.
derive
(
blockTime
,
genesisTimestamp
,
chainID
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
}
}
require
.
Equal
(
t
,
batch
,
&
dec
,
"Batch not equal test case %v"
,
i
)
require
.
Equal
(
t
,
batch
,
&
dec
,
"Batch not equal test case %v"
,
i
)
...
@@ -222,9 +220,7 @@ func TestBatchRoundTripRLP(t *testing.T) {
...
@@ -222,9 +220,7 @@ func TestBatchRoundTripRLP(t *testing.T) {
err
=
dec
.
DecodeRLP
(
s
)
err
=
dec
.
DecodeRLP
(
s
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
if
dec
.
GetBatchType
()
==
SpanBatchType
{
if
dec
.
GetBatchType
()
==
SpanBatchType
{
rawSpanBatch
,
ok
:=
dec
.
inner
.
(
*
RawSpanBatch
)
_
,
err
=
DeriveSpanBatch
(
&
dec
,
blockTime
,
genesisTimestamp
,
chainID
)
require
.
True
(
t
,
ok
)
_
,
err
:=
rawSpanBatch
.
derive
(
blockTime
,
genesisTimestamp
,
chainID
)
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
}
}
require
.
Equal
(
t
,
batch
,
&
dec
,
"Batch not equal test case %v"
,
i
)
require
.
Equal
(
t
,
batch
,
&
dec
,
"Batch not equal test case %v"
,
i
)
...
...
op-node/rollup/derive/channel_in_reader.go
View file @
179aea69
...
@@ -3,7 +3,6 @@ package derive
...
@@ -3,7 +3,6 @@ package derive
import
(
import
(
"bytes"
"bytes"
"context"
"context"
"errors"
"fmt"
"fmt"
"io"
"io"
...
@@ -92,11 +91,7 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) {
...
@@ -92,11 +91,7 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) {
}
}
switch
batchData
.
GetBatchType
()
{
switch
batchData
.
GetBatchType
()
{
case
SingularBatchType
:
case
SingularBatchType
:
singularBatch
,
ok
:=
batchData
.
inner
.
(
*
SingularBatch
)
return
GetSingularBatch
(
batchData
)
if
!
ok
{
return
nil
,
NewCriticalError
(
errors
.
New
(
"failed type assertion to SingularBatch"
))
}
return
singularBatch
,
nil
case
SpanBatchType
:
case
SpanBatchType
:
if
origin
:=
cr
.
Origin
();
!
cr
.
cfg
.
IsDelta
(
origin
.
Time
)
{
if
origin
:=
cr
.
Origin
();
!
cr
.
cfg
.
IsDelta
(
origin
.
Time
)
{
// Check hard fork activation with the L1 inclusion block time instead of the L1 origin block time.
// Check hard fork activation with the L1 inclusion block time instead of the L1 origin block time.
...
@@ -104,16 +99,7 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) {
...
@@ -104,16 +99,7 @@ func (cr *ChannelInReader) NextBatch(ctx context.Context) (Batch, error) {
// This is just for early dropping invalid batches as soon as possible.
// This is just for early dropping invalid batches as soon as possible.
return
nil
,
NewTemporaryError
(
fmt
.
Errorf
(
"cannot accept span batch in L1 block %s at time %d"
,
origin
,
origin
.
Time
))
return
nil
,
NewTemporaryError
(
fmt
.
Errorf
(
"cannot accept span batch in L1 block %s at time %d"
,
origin
,
origin
.
Time
))
}
}
rawSpanBatch
,
ok
:=
batchData
.
inner
.
(
*
RawSpanBatch
)
return
DeriveSpanBatch
(
batchData
,
cr
.
cfg
.
BlockTime
,
cr
.
cfg
.
Genesis
.
L2Time
,
cr
.
cfg
.
L2ChainID
)
if
!
ok
{
return
nil
,
NewCriticalError
(
errors
.
New
(
"failed type assertion to SpanBatch"
))
}
// If the batch type is Span batch, derive block inputs from RawSpanBatch.
spanBatch
,
err
:=
rawSpanBatch
.
derive
(
cr
.
cfg
.
BlockTime
,
cr
.
cfg
.
Genesis
.
L2Time
,
cr
.
cfg
.
L2ChainID
)
if
err
!=
nil
{
return
nil
,
err
}
return
spanBatch
,
nil
default
:
default
:
// error is bubbled up to user, but pipeline can skip the batch and continue after.
// error is bubbled up to user, but pipeline can skip the batch and continue after.
return
nil
,
NewTemporaryError
(
fmt
.
Errorf
(
"unrecognized batch type: %d"
,
batchData
.
GetBatchType
()))
return
nil
,
NewTemporaryError
(
fmt
.
Errorf
(
"unrecognized batch type: %d"
,
batchData
.
GetBatchType
()))
...
...
op-node/rollup/derive/singular_batch.go
View file @
179aea69
...
@@ -2,6 +2,7 @@ package derive
...
@@ -2,6 +2,7 @@ package derive
import
(
import
(
"bytes"
"bytes"
"errors"
"io"
"io"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup"
...
@@ -65,3 +66,12 @@ func (b *SingularBatch) encode(w io.Writer) error {
...
@@ -65,3 +66,12 @@ func (b *SingularBatch) encode(w io.Writer) error {
func
(
b
*
SingularBatch
)
decode
(
r
*
bytes
.
Reader
)
error
{
func
(
b
*
SingularBatch
)
decode
(
r
*
bytes
.
Reader
)
error
{
return
rlp
.
Decode
(
r
,
b
)
return
rlp
.
Decode
(
r
,
b
)
}
}
// GetSingularBatch retrieves SingularBatch from batchData
func
GetSingularBatch
(
batchData
*
BatchData
)
(
*
SingularBatch
,
error
)
{
singularBatch
,
ok
:=
batchData
.
inner
.
(
*
SingularBatch
)
if
!
ok
{
return
nil
,
NewCriticalError
(
errors
.
New
(
"failed type assertion to SingularBatch"
))
}
return
singularBatch
,
nil
}
op-node/rollup/derive/span_batch.go
View file @
179aea69
...
@@ -3,6 +3,7 @@ package derive
...
@@ -3,6 +3,7 @@ package derive
import
(
import
(
"bytes"
"bytes"
"encoding/binary"
"encoding/binary"
"encoding/json"
"errors"
"errors"
"fmt"
"fmt"
"io"
"io"
...
@@ -377,7 +378,7 @@ func (b *RawSpanBatch) encode(w io.Writer) error {
...
@@ -377,7 +378,7 @@ func (b *RawSpanBatch) encode(w io.Writer) error {
return
nil
return
nil
}
}
// derive converts RawSpanBatch into SpanBatch, which has a list of
s
panBatchElement.
// derive converts RawSpanBatch into SpanBatch, which has a list of
S
panBatchElement.
// We need chain config constants to derive values for making payload attributes.
// We need chain config constants to derive values for making payload attributes.
func
(
b
*
RawSpanBatch
)
derive
(
blockTime
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
SpanBatch
,
error
)
{
func
(
b
*
RawSpanBatch
)
derive
(
blockTime
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
SpanBatch
,
error
)
{
if
b
.
blockCount
==
0
{
if
b
.
blockCount
==
0
{
...
@@ -401,35 +402,45 @@ func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.I
...
@@ -401,35 +402,45 @@ func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.I
}
}
spanBatch
:=
SpanBatch
{
spanBatch
:=
SpanBatch
{
p
arentCheck
:
b
.
parentCheck
,
P
arentCheck
:
b
.
parentCheck
,
l
1OriginCheck
:
b
.
l1OriginCheck
,
L
1OriginCheck
:
b
.
l1OriginCheck
,
}
}
txIdx
:=
0
txIdx
:=
0
for
i
:=
0
;
i
<
int
(
b
.
blockCount
);
i
++
{
for
i
:=
0
;
i
<
int
(
b
.
blockCount
);
i
++
{
batch
:=
s
panBatchElement
{}
batch
:=
S
panBatchElement
{}
batch
.
Timestamp
=
genesisTimestamp
+
b
.
relTimestamp
+
blockTime
*
uint64
(
i
)
batch
.
Timestamp
=
genesisTimestamp
+
b
.
relTimestamp
+
blockTime
*
uint64
(
i
)
batch
.
EpochNum
=
rollup
.
Epoch
(
blockOriginNums
[
i
])
batch
.
EpochNum
=
rollup
.
Epoch
(
blockOriginNums
[
i
])
for
j
:=
0
;
j
<
int
(
b
.
blockTxCounts
[
i
]);
j
++
{
for
j
:=
0
;
j
<
int
(
b
.
blockTxCounts
[
i
]);
j
++
{
batch
.
Transactions
=
append
(
batch
.
Transactions
,
fullTxs
[
txIdx
])
batch
.
Transactions
=
append
(
batch
.
Transactions
,
fullTxs
[
txIdx
])
txIdx
++
txIdx
++
}
}
spanBatch
.
batches
=
append
(
spanBatch
.
b
atches
,
&
batch
)
spanBatch
.
Batches
=
append
(
spanBatch
.
B
atches
,
&
batch
)
}
}
return
&
spanBatch
,
nil
return
&
spanBatch
,
nil
}
}
// spanBatchElement is a derived form of input to build a L2 block.
// ToSpanBatch converts RawSpanBatch to SpanBatch,
// which implements a wrapper of derive method of RawSpanBatch
func
(
b
*
RawSpanBatch
)
ToSpanBatch
(
blockTime
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
SpanBatch
,
error
)
{
spanBatch
,
err
:=
b
.
derive
(
blockTime
,
genesisTimestamp
,
chainID
)
if
err
!=
nil
{
return
nil
,
err
}
return
spanBatch
,
nil
}
// SpanBatchElement is a derived form of input to build a L2 block.
// similar to SingularBatch, but does not have ParentHash and EpochHash
// similar to SingularBatch, but does not have ParentHash and EpochHash
// because Span batch spec does not contain parent hash and epoch hash of every block in the span.
// because Span batch spec does not contain parent hash and epoch hash of every block in the span.
type
s
panBatchElement
struct
{
type
S
panBatchElement
struct
{
EpochNum
rollup
.
Epoch
// aka l1 num
EpochNum
rollup
.
Epoch
// aka l1 num
Timestamp
uint64
Timestamp
uint64
Transactions
[]
hexutil
.
Bytes
Transactions
[]
hexutil
.
Bytes
}
}
// singularBatchToElement converts a SingularBatch to a
s
panBatchElement
// singularBatchToElement converts a SingularBatch to a
S
panBatchElement
func
singularBatchToElement
(
singularBatch
*
SingularBatch
)
*
s
panBatchElement
{
func
singularBatchToElement
(
singularBatch
*
SingularBatch
)
*
S
panBatchElement
{
return
&
s
panBatchElement
{
return
&
S
panBatchElement
{
EpochNum
:
singularBatch
.
EpochNum
,
EpochNum
:
singularBatch
.
EpochNum
,
Timestamp
:
singularBatch
.
Timestamp
,
Timestamp
:
singularBatch
.
Timestamp
,
Transactions
:
singularBatch
.
Transactions
,
Transactions
:
singularBatch
.
Transactions
,
...
@@ -437,11 +448,27 @@ func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement {
...
@@ -437,11 +448,27 @@ func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement {
}
}
// SpanBatch is an implementation of Batch interface,
// SpanBatch is an implementation of Batch interface,
// containing the input to build a span of L2 blocks in derived form (
s
panBatchElement)
// containing the input to build a span of L2 blocks in derived form (
S
panBatchElement)
type
SpanBatch
struct
{
type
SpanBatch
struct
{
parentCheck
[
20
]
byte
// First 20 bytes of the first block's parent hash
ParentCheck
[
20
]
byte
// First 20 bytes of the first block's parent hash
l1OriginCheck
[
20
]
byte
// First 20 bytes of the last block's L1 origin hash
L1OriginCheck
[
20
]
byte
// First 20 bytes of the last block's L1 origin hash
batches
[]
*
spanBatchElement
// List of block input in derived form
Batches
[]
*
SpanBatchElement
// List of block input in derived form
}
// spanBatchMarshaling is a helper type used for JSON marshaling.
type
spanBatchMarshaling
struct
{
ParentCheck
[]
hexutil
.
Bytes
`json:"parent_check"`
L1OriginCheck
[]
hexutil
.
Bytes
`json:"l1_origin_check"`
Batches
[]
*
SpanBatchElement
`json:"span_batch_elements"`
}
func
(
b
*
SpanBatch
)
MarshalJSON
()
([]
byte
,
error
)
{
spanBatch
:=
spanBatchMarshaling
{
ParentCheck
:
[]
hexutil
.
Bytes
{
b
.
ParentCheck
[
:
]},
L1OriginCheck
:
[]
hexutil
.
Bytes
{
b
.
L1OriginCheck
[
:
]},
Batches
:
b
.
Batches
,
}
return
json
.
Marshal
(
spanBatch
)
}
}
// GetBatchType returns its batch type (batch_version)
// GetBatchType returns its batch type (batch_version)
...
@@ -451,100 +478,100 @@ func (b *SpanBatch) GetBatchType() int {
...
@@ -451,100 +478,100 @@ func (b *SpanBatch) GetBatchType() int {
// GetTimestamp returns timestamp of the first block in the span
// GetTimestamp returns timestamp of the first block in the span
func
(
b
*
SpanBatch
)
GetTimestamp
()
uint64
{
func
(
b
*
SpanBatch
)
GetTimestamp
()
uint64
{
return
b
.
b
atches
[
0
]
.
Timestamp
return
b
.
B
atches
[
0
]
.
Timestamp
}
}
// LogContext creates a new log context that contains information of the batch
// LogContext creates a new log context that contains information of the batch
func
(
b
*
SpanBatch
)
LogContext
(
log
log
.
Logger
)
log
.
Logger
{
func
(
b
*
SpanBatch
)
LogContext
(
log
log
.
Logger
)
log
.
Logger
{
if
len
(
b
.
b
atches
)
==
0
{
if
len
(
b
.
B
atches
)
==
0
{
return
log
.
New
(
"block_count"
,
0
)
return
log
.
New
(
"block_count"
,
0
)
}
}
return
log
.
New
(
return
log
.
New
(
"batch_timestamp"
,
b
.
b
atches
[
0
]
.
Timestamp
,
"batch_timestamp"
,
b
.
B
atches
[
0
]
.
Timestamp
,
"parent_check"
,
hexutil
.
Encode
(
b
.
p
arentCheck
[
:
]),
"parent_check"
,
hexutil
.
Encode
(
b
.
P
arentCheck
[
:
]),
"origin_check"
,
hexutil
.
Encode
(
b
.
l
1OriginCheck
[
:
]),
"origin_check"
,
hexutil
.
Encode
(
b
.
L
1OriginCheck
[
:
]),
"start_epoch_number"
,
b
.
GetStartEpochNum
(),
"start_epoch_number"
,
b
.
GetStartEpochNum
(),
"end_epoch_number"
,
b
.
GetBlockEpochNum
(
len
(
b
.
b
atches
)
-
1
),
"end_epoch_number"
,
b
.
GetBlockEpochNum
(
len
(
b
.
B
atches
)
-
1
),
"block_count"
,
len
(
b
.
b
atches
),
"block_count"
,
len
(
b
.
B
atches
),
)
)
}
}
// GetStartEpochNum returns epoch number(L1 origin block number) of the first block in the span
// GetStartEpochNum returns epoch number(L1 origin block number) of the first block in the span
func
(
b
*
SpanBatch
)
GetStartEpochNum
()
rollup
.
Epoch
{
func
(
b
*
SpanBatch
)
GetStartEpochNum
()
rollup
.
Epoch
{
return
b
.
b
atches
[
0
]
.
EpochNum
return
b
.
B
atches
[
0
]
.
EpochNum
}
}
// CheckOriginHash checks if the l1OriginCheck matches the first 20 bytes of given hash, probably L1 block hash from the current canonical L1 chain.
// CheckOriginHash checks if the l1OriginCheck matches the first 20 bytes of given hash, probably L1 block hash from the current canonical L1 chain.
func
(
b
*
SpanBatch
)
CheckOriginHash
(
hash
common
.
Hash
)
bool
{
func
(
b
*
SpanBatch
)
CheckOriginHash
(
hash
common
.
Hash
)
bool
{
return
bytes
.
Equal
(
b
.
l
1OriginCheck
[
:
],
hash
.
Bytes
()[
:
20
])
return
bytes
.
Equal
(
b
.
L
1OriginCheck
[
:
],
hash
.
Bytes
()[
:
20
])
}
}
// CheckParentHash checks if the parentCheck matches the first 20 bytes of given hash, probably the current L2 safe head.
// CheckParentHash checks if the parentCheck matches the first 20 bytes of given hash, probably the current L2 safe head.
func
(
b
*
SpanBatch
)
CheckParentHash
(
hash
common
.
Hash
)
bool
{
func
(
b
*
SpanBatch
)
CheckParentHash
(
hash
common
.
Hash
)
bool
{
return
bytes
.
Equal
(
b
.
p
arentCheck
[
:
],
hash
.
Bytes
()[
:
20
])
return
bytes
.
Equal
(
b
.
P
arentCheck
[
:
],
hash
.
Bytes
()[
:
20
])
}
}
// GetBlockEpochNum returns the epoch number(L1 origin block number) of the block at the given index in the span.
// GetBlockEpochNum returns the epoch number(L1 origin block number) of the block at the given index in the span.
func
(
b
*
SpanBatch
)
GetBlockEpochNum
(
i
int
)
uint64
{
func
(
b
*
SpanBatch
)
GetBlockEpochNum
(
i
int
)
uint64
{
return
uint64
(
b
.
b
atches
[
i
]
.
EpochNum
)
return
uint64
(
b
.
B
atches
[
i
]
.
EpochNum
)
}
}
// GetBlockTimestamp returns the timestamp of the block at the given index in the span.
// GetBlockTimestamp returns the timestamp of the block at the given index in the span.
func
(
b
*
SpanBatch
)
GetBlockTimestamp
(
i
int
)
uint64
{
func
(
b
*
SpanBatch
)
GetBlockTimestamp
(
i
int
)
uint64
{
return
b
.
b
atches
[
i
]
.
Timestamp
return
b
.
B
atches
[
i
]
.
Timestamp
}
}
// GetBlockTransactions returns the encoded transactions of the block at the given index in the span.
// GetBlockTransactions returns the encoded transactions of the block at the given index in the span.
func
(
b
*
SpanBatch
)
GetBlockTransactions
(
i
int
)
[]
hexutil
.
Bytes
{
func
(
b
*
SpanBatch
)
GetBlockTransactions
(
i
int
)
[]
hexutil
.
Bytes
{
return
b
.
b
atches
[
i
]
.
Transactions
return
b
.
B
atches
[
i
]
.
Transactions
}
}
// GetBlockCount returns the number of blocks in the span
// GetBlockCount returns the number of blocks in the span
func
(
b
*
SpanBatch
)
GetBlockCount
()
int
{
func
(
b
*
SpanBatch
)
GetBlockCount
()
int
{
return
len
(
b
.
b
atches
)
return
len
(
b
.
B
atches
)
}
}
// AppendSingularBatch appends a SingularBatch into the span batch
// AppendSingularBatch appends a SingularBatch into the span batch
// updates l1OriginCheck or parentCheck if needed.
// updates l1OriginCheck or parentCheck if needed.
func
(
b
*
SpanBatch
)
AppendSingularBatch
(
singularBatch
*
SingularBatch
)
{
func
(
b
*
SpanBatch
)
AppendSingularBatch
(
singularBatch
*
SingularBatch
)
{
if
len
(
b
.
b
atches
)
==
0
{
if
len
(
b
.
B
atches
)
==
0
{
copy
(
b
.
p
arentCheck
[
:
],
singularBatch
.
ParentHash
.
Bytes
()[
:
20
])
copy
(
b
.
P
arentCheck
[
:
],
singularBatch
.
ParentHash
.
Bytes
()[
:
20
])
}
}
b
.
batches
=
append
(
b
.
b
atches
,
singularBatchToElement
(
singularBatch
))
b
.
Batches
=
append
(
b
.
B
atches
,
singularBatchToElement
(
singularBatch
))
copy
(
b
.
l
1OriginCheck
[
:
],
singularBatch
.
EpochHash
.
Bytes
()[
:
20
])
copy
(
b
.
L
1OriginCheck
[
:
],
singularBatch
.
EpochHash
.
Bytes
()[
:
20
])
}
}
// ToRawSpanBatch merges SingularBatch List and initialize single RawSpanBatch
// ToRawSpanBatch merges SingularBatch List and initialize single RawSpanBatch
func
(
b
*
SpanBatch
)
ToRawSpanBatch
(
originChangedBit
uint
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
RawSpanBatch
,
error
)
{
func
(
b
*
SpanBatch
)
ToRawSpanBatch
(
originChangedBit
uint
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
RawSpanBatch
,
error
)
{
if
len
(
b
.
b
atches
)
==
0
{
if
len
(
b
.
B
atches
)
==
0
{
return
nil
,
errors
.
New
(
"cannot merge empty singularBatch list"
)
return
nil
,
errors
.
New
(
"cannot merge empty singularBatch list"
)
}
}
raw
:=
RawSpanBatch
{}
raw
:=
RawSpanBatch
{}
// Sort by timestamp of L2 block
// Sort by timestamp of L2 block
sort
.
Slice
(
b
.
b
atches
,
func
(
i
,
j
int
)
bool
{
sort
.
Slice
(
b
.
B
atches
,
func
(
i
,
j
int
)
bool
{
return
b
.
batches
[
i
]
.
Timestamp
<
b
.
b
atches
[
j
]
.
Timestamp
return
b
.
Batches
[
i
]
.
Timestamp
<
b
.
B
atches
[
j
]
.
Timestamp
})
})
// spanBatchPrefix
// spanBatchPrefix
span_start
:=
b
.
b
atches
[
0
]
span_start
:=
b
.
B
atches
[
0
]
span_end
:=
b
.
batches
[
len
(
b
.
b
atches
)
-
1
]
span_end
:=
b
.
Batches
[
len
(
b
.
B
atches
)
-
1
]
raw
.
relTimestamp
=
span_start
.
Timestamp
-
genesisTimestamp
raw
.
relTimestamp
=
span_start
.
Timestamp
-
genesisTimestamp
raw
.
l1OriginNum
=
uint64
(
span_end
.
EpochNum
)
raw
.
l1OriginNum
=
uint64
(
span_end
.
EpochNum
)
raw
.
parentCheck
=
b
.
p
arentCheck
raw
.
parentCheck
=
b
.
P
arentCheck
raw
.
l1OriginCheck
=
b
.
l
1OriginCheck
raw
.
l1OriginCheck
=
b
.
L
1OriginCheck
// spanBatchPayload
// spanBatchPayload
raw
.
blockCount
=
uint64
(
len
(
b
.
b
atches
))
raw
.
blockCount
=
uint64
(
len
(
b
.
B
atches
))
raw
.
originBits
=
new
(
big
.
Int
)
raw
.
originBits
=
new
(
big
.
Int
)
raw
.
originBits
.
SetBit
(
raw
.
originBits
,
0
,
originChangedBit
)
raw
.
originBits
.
SetBit
(
raw
.
originBits
,
0
,
originChangedBit
)
for
i
:=
1
;
i
<
len
(
b
.
b
atches
);
i
++
{
for
i
:=
1
;
i
<
len
(
b
.
B
atches
);
i
++
{
bit
:=
uint
(
0
)
bit
:=
uint
(
0
)
if
b
.
batches
[
i
-
1
]
.
EpochNum
<
b
.
b
atches
[
i
]
.
EpochNum
{
if
b
.
Batches
[
i
-
1
]
.
EpochNum
<
b
.
B
atches
[
i
]
.
EpochNum
{
bit
=
1
bit
=
1
}
}
raw
.
originBits
.
SetBit
(
raw
.
originBits
,
i
,
bit
)
raw
.
originBits
.
SetBit
(
raw
.
originBits
,
i
,
bit
)
}
}
var
blockTxCounts
[]
uint64
var
blockTxCounts
[]
uint64
var
txs
[][]
byte
var
txs
[][]
byte
for
_
,
batch
:=
range
b
.
b
atches
{
for
_
,
batch
:=
range
b
.
B
atches
{
blockTxCount
:=
uint64
(
len
(
batch
.
Transactions
))
blockTxCount
:=
uint64
(
len
(
batch
.
Transactions
))
blockTxCounts
=
append
(
blockTxCounts
,
blockTxCount
)
blockTxCounts
=
append
(
blockTxCounts
,
blockTxCount
)
for
_
,
rawTx
:=
range
batch
.
Transactions
{
for
_
,
rawTx
:=
range
batch
.
Transactions
{
...
@@ -560,13 +587,13 @@ func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint6
...
@@ -560,13 +587,13 @@ func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint6
return
&
raw
,
nil
return
&
raw
,
nil
}
}
// GetSingularBatches converts
s
panBatchElements after L2 safe head to SingularBatches.
// GetSingularBatches converts
S
panBatchElements after L2 safe head to SingularBatches.
// Since
s
panBatchElement does not contain EpochHash, set EpochHash from the given L1 blocks.
// Since
S
panBatchElement does not contain EpochHash, set EpochHash from the given L1 blocks.
// The result SingularBatches do not contain ParentHash yet. It must be set by BatchQueue.
// The result SingularBatches do not contain ParentHash yet. It must be set by BatchQueue.
func
(
b
*
SpanBatch
)
GetSingularBatches
(
l1Origins
[]
eth
.
L1BlockRef
,
l2SafeHead
eth
.
L2BlockRef
)
([]
*
SingularBatch
,
error
)
{
func
(
b
*
SpanBatch
)
GetSingularBatches
(
l1Origins
[]
eth
.
L1BlockRef
,
l2SafeHead
eth
.
L2BlockRef
)
([]
*
SingularBatch
,
error
)
{
var
singularBatches
[]
*
SingularBatch
var
singularBatches
[]
*
SingularBatch
originIdx
:=
0
originIdx
:=
0
for
_
,
batch
:=
range
b
.
b
atches
{
for
_
,
batch
:=
range
b
.
B
atches
{
if
batch
.
Timestamp
<=
l2SafeHead
.
Time
{
if
batch
.
Timestamp
<=
l2SafeHead
.
Time
{
continue
continue
}
}
...
@@ -592,20 +619,30 @@ func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead et
...
@@ -592,20 +619,30 @@ func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead et
return
singularBatches
,
nil
return
singularBatches
,
nil
}
}
// NewSpanBatch converts given singularBatches into
s
panBatchElements, and creates a new SpanBatch.
// NewSpanBatch converts given singularBatches into
S
panBatchElements, and creates a new SpanBatch.
func
NewSpanBatch
(
singularBatches
[]
*
SingularBatch
)
*
SpanBatch
{
func
NewSpanBatch
(
singularBatches
[]
*
SingularBatch
)
*
SpanBatch
{
spanBatch
:=
&
SpanBatch
{}
spanBatch
:=
&
SpanBatch
{}
if
len
(
singularBatches
)
==
0
{
if
len
(
singularBatches
)
==
0
{
return
spanBatch
return
spanBatch
}
}
copy
(
spanBatch
.
p
arentCheck
[
:
],
singularBatches
[
0
]
.
ParentHash
.
Bytes
()[
:
20
])
copy
(
spanBatch
.
P
arentCheck
[
:
],
singularBatches
[
0
]
.
ParentHash
.
Bytes
()[
:
20
])
copy
(
spanBatch
.
l
1OriginCheck
[
:
],
singularBatches
[
len
(
singularBatches
)
-
1
]
.
EpochHash
.
Bytes
()[
:
20
])
copy
(
spanBatch
.
L
1OriginCheck
[
:
],
singularBatches
[
len
(
singularBatches
)
-
1
]
.
EpochHash
.
Bytes
()[
:
20
])
for
_
,
singularBatch
:=
range
singularBatches
{
for
_
,
singularBatch
:=
range
singularBatches
{
spanBatch
.
batches
=
append
(
spanBatch
.
b
atches
,
singularBatchToElement
(
singularBatch
))
spanBatch
.
Batches
=
append
(
spanBatch
.
B
atches
,
singularBatchToElement
(
singularBatch
))
}
}
return
spanBatch
return
spanBatch
}
}
// DeriveSpanBatch derives SpanBatch from BatchData.
func
DeriveSpanBatch
(
batchData
*
BatchData
,
blockTime
,
genesisTimestamp
uint64
,
chainID
*
big
.
Int
)
(
*
SpanBatch
,
error
)
{
rawSpanBatch
,
ok
:=
batchData
.
inner
.
(
*
RawSpanBatch
)
if
!
ok
{
return
nil
,
NewCriticalError
(
errors
.
New
(
"failed type assertion to SpanBatch"
))
}
// If the batch type is Span batch, derive block inputs from RawSpanBatch.
return
rawSpanBatch
.
ToSpanBatch
(
blockTime
,
genesisTimestamp
,
chainID
)
}
// SpanBatchBuilder is a utility type to build a SpanBatch by adding a SingularBatch one by one.
// SpanBatchBuilder is a utility type to build a SpanBatch by adding a SingularBatch one by one.
// makes easier to stack SingularBatches and convert to RawSpanBatch for encoding.
// makes easier to stack SingularBatches and convert to RawSpanBatch for encoding.
type
SpanBatchBuilder
struct
{
type
SpanBatchBuilder
struct
{
...
@@ -642,7 +679,7 @@ func (b *SpanBatchBuilder) GetRawSpanBatch() (*RawSpanBatch, error) {
...
@@ -642,7 +679,7 @@ func (b *SpanBatchBuilder) GetRawSpanBatch() (*RawSpanBatch, error) {
}
}
func
(
b
*
SpanBatchBuilder
)
GetBlockCount
()
int
{
func
(
b
*
SpanBatchBuilder
)
GetBlockCount
()
int
{
return
len
(
b
.
spanBatch
.
b
atches
)
return
len
(
b
.
spanBatch
.
B
atches
)
}
}
func
(
b
*
SpanBatchBuilder
)
Reset
()
{
func
(
b
*
SpanBatchBuilder
)
Reset
()
{
...
...
op-node/rollup/derive/span_batch_test.go
View file @
179aea69
...
@@ -331,18 +331,18 @@ func TestSpanBatchDerive(t *testing.T) {
...
@@ -331,18 +331,18 @@ func TestSpanBatchDerive(t *testing.T) {
require
.
NoError
(
t
,
err
)
require
.
NoError
(
t
,
err
)
blockCount
:=
len
(
singularBatches
)
blockCount
:=
len
(
singularBatches
)
require
.
Equal
(
t
,
safeL2Head
.
Hash
.
Bytes
()[
:
20
],
spanBatchDerived
.
p
arentCheck
[
:
])
require
.
Equal
(
t
,
safeL2Head
.
Hash
.
Bytes
()[
:
20
],
spanBatchDerived
.
P
arentCheck
[
:
])
require
.
Equal
(
t
,
singularBatches
[
blockCount
-
1
]
.
Epoch
()
.
Hash
.
Bytes
()[
:
20
],
spanBatchDerived
.
l
1OriginCheck
[
:
])
require
.
Equal
(
t
,
singularBatches
[
blockCount
-
1
]
.
Epoch
()
.
Hash
.
Bytes
()[
:
20
],
spanBatchDerived
.
L
1OriginCheck
[
:
])
require
.
Equal
(
t
,
len
(
singularBatches
),
int
(
rawSpanBatch
.
blockCount
))
require
.
Equal
(
t
,
len
(
singularBatches
),
int
(
rawSpanBatch
.
blockCount
))
for
i
:=
1
;
i
<
len
(
singularBatches
);
i
++
{
for
i
:=
1
;
i
<
len
(
singularBatches
);
i
++
{
require
.
Equal
(
t
,
spanBatchDerived
.
batches
[
i
]
.
Timestamp
,
spanBatchDerived
.
b
atches
[
i
-
1
]
.
Timestamp
+
l2BlockTime
)
require
.
Equal
(
t
,
spanBatchDerived
.
Batches
[
i
]
.
Timestamp
,
spanBatchDerived
.
B
atches
[
i
-
1
]
.
Timestamp
+
l2BlockTime
)
}
}
for
i
:=
0
;
i
<
len
(
singularBatches
);
i
++
{
for
i
:=
0
;
i
<
len
(
singularBatches
);
i
++
{
require
.
Equal
(
t
,
singularBatches
[
i
]
.
EpochNum
,
spanBatchDerived
.
b
atches
[
i
]
.
EpochNum
)
require
.
Equal
(
t
,
singularBatches
[
i
]
.
EpochNum
,
spanBatchDerived
.
B
atches
[
i
]
.
EpochNum
)
require
.
Equal
(
t
,
singularBatches
[
i
]
.
Timestamp
,
spanBatchDerived
.
b
atches
[
i
]
.
Timestamp
)
require
.
Equal
(
t
,
singularBatches
[
i
]
.
Timestamp
,
spanBatchDerived
.
B
atches
[
i
]
.
Timestamp
)
require
.
Equal
(
t
,
singularBatches
[
i
]
.
Transactions
,
spanBatchDerived
.
b
atches
[
i
]
.
Transactions
)
require
.
Equal
(
t
,
singularBatches
[
i
]
.
Transactions
,
spanBatchDerived
.
B
atches
[
i
]
.
Transactions
)
}
}
}
}
}
}
...
@@ -511,8 +511,8 @@ func TestSpanBatchBuilder(t *testing.T) {
...
@@ -511,8 +511,8 @@ func TestSpanBatchBuilder(t *testing.T) {
for
i
:=
0
;
i
<
len
(
singularBatches
);
i
++
{
for
i
:=
0
;
i
<
len
(
singularBatches
);
i
++
{
spanBatchBuilder
.
AppendSingularBatch
(
singularBatches
[
i
],
seqNum
)
spanBatchBuilder
.
AppendSingularBatch
(
singularBatches
[
i
],
seqNum
)
require
.
Equal
(
t
,
i
+
1
,
spanBatchBuilder
.
GetBlockCount
())
require
.
Equal
(
t
,
i
+
1
,
spanBatchBuilder
.
GetBlockCount
())
require
.
Equal
(
t
,
singularBatches
[
0
]
.
ParentHash
.
Bytes
()[
:
20
],
spanBatchBuilder
.
spanBatch
.
p
arentCheck
[
:
])
require
.
Equal
(
t
,
singularBatches
[
0
]
.
ParentHash
.
Bytes
()[
:
20
],
spanBatchBuilder
.
spanBatch
.
P
arentCheck
[
:
])
require
.
Equal
(
t
,
singularBatches
[
i
]
.
EpochHash
.
Bytes
()[
:
20
],
spanBatchBuilder
.
spanBatch
.
l
1OriginCheck
[
:
])
require
.
Equal
(
t
,
singularBatches
[
i
]
.
EpochHash
.
Bytes
()[
:
20
],
spanBatchBuilder
.
spanBatch
.
L
1OriginCheck
[
:
])
}
}
rawSpanBatch
,
err
:=
spanBatchBuilder
.
GetRawSpanBatch
()
rawSpanBatch
,
err
:=
spanBatchBuilder
.
GetRawSpanBatch
()
...
...
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