Commit 06c495e0 authored by pcw109550's avatar pcw109550

op-node: Public scope for span batch structs and elements

parent efddff2d
......@@ -377,7 +377,7 @@ func (b *RawSpanBatch) encode(w io.Writer) error {
return nil
}
// derive converts RawSpanBatch into SpanBatch, which has a list of spanBatchElement.
// derive converts RawSpanBatch into SpanBatch, which has a list of SpanBatchElement.
// We need chain config constants to derive values for making payload attributes.
func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.Int) (*SpanBatch, error) {
if b.blockCount == 0 {
......@@ -399,19 +399,19 @@ func (b *RawSpanBatch) derive(blockTime, genesisTimestamp uint64, chainID *big.I
}
spanBatch := SpanBatch{
parentCheck: b.parentCheck,
l1OriginCheck: b.l1OriginCheck,
ParentCheck: b.parentCheck,
L1OriginCheck: b.l1OriginCheck,
}
txIdx := 0
for i := 0; i < int(b.blockCount); i++ {
batch := spanBatchElement{}
batch := SpanBatchElement{}
batch.Timestamp = genesisTimestamp + b.relTimestamp + blockTime*uint64(i)
batch.EpochNum = rollup.Epoch(blockOriginNums[i])
for j := 0; j < int(b.blockTxCounts[i]); j++ {
batch.Transactions = append(batch.Transactions, fullTxs[txIdx])
txIdx++
}
spanBatch.batches = append(spanBatch.batches, &batch)
spanBatch.Batches = append(spanBatch.Batches, &batch)
}
return &spanBatch, nil
}
......@@ -426,18 +426,18 @@ func (b *RawSpanBatch) ToSpanBatch(blockTime, genesisTimestamp uint64, chainID *
return spanBatch, nil
}
// spanBatchElement is a derived form of input to build a L2 block.
// SpanBatchElement is a derived form of input to build a L2 block.
// 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.
type spanBatchElement struct {
type SpanBatchElement struct {
EpochNum rollup.Epoch // aka l1 num
Timestamp uint64
Transactions []hexutil.Bytes
}
// singularBatchToElement converts a SingularBatch to a spanBatchElement
func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement {
return &spanBatchElement{
// singularBatchToElement converts a SingularBatch to a SpanBatchElement
func singularBatchToElement(singularBatch *SingularBatch) *SpanBatchElement {
return &SpanBatchElement{
EpochNum: singularBatch.EpochNum,
Timestamp: singularBatch.Timestamp,
Transactions: singularBatch.Transactions,
......@@ -445,11 +445,11 @@ func singularBatchToElement(singularBatch *SingularBatch) *spanBatchElement {
}
// SpanBatch is an implementation of Batch interface,
// containing the input to build a span of L2 blocks in derived form (spanBatchElement)
// containing the input to build a span of L2 blocks in derived form (SpanBatchElement)
type SpanBatch struct {
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
batches []*spanBatchElement // List of block input in derived form
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
Batches []*SpanBatchElement // List of block input in derived form
}
// GetBatchType returns its batch type (batch_version)
......@@ -459,100 +459,100 @@ func (b *SpanBatch) GetBatchType() int {
// GetTimestamp returns timestamp of the first block in the span
func (b *SpanBatch) GetTimestamp() uint64 {
return b.batches[0].Timestamp
return b.Batches[0].Timestamp
}
// LogContext creates a new log context that contains information of the batch
func (b *SpanBatch) LogContext(log log.Logger) log.Logger {
if len(b.batches) == 0 {
if len(b.Batches) == 0 {
return log.New("block_count", 0)
}
return log.New(
"batch_timestamp", b.batches[0].Timestamp,
"parent_check", hexutil.Encode(b.parentCheck[:]),
"origin_check", hexutil.Encode(b.l1OriginCheck[:]),
"batch_timestamp", b.Batches[0].Timestamp,
"parent_check", hexutil.Encode(b.ParentCheck[:]),
"origin_check", hexutil.Encode(b.L1OriginCheck[:]),
"start_epoch_number", b.GetStartEpochNum(),
"end_epoch_number", b.GetBlockEpochNum(len(b.batches)-1),
"block_count", len(b.batches),
"end_epoch_number", b.GetBlockEpochNum(len(b.Batches)-1),
"block_count", len(b.Batches),
)
}
// GetStartEpochNum returns epoch number(L1 origin block number) of the first block in the span
func (b *SpanBatch) GetStartEpochNum() rollup.Epoch {
return b.batches[0].EpochNum
return b.Batches[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.
func (b *SpanBatch) CheckOriginHash(hash common.Hash) bool {
return bytes.Equal(b.l1OriginCheck[:], hash.Bytes()[:20])
return bytes.Equal(b.L1OriginCheck[:], hash.Bytes()[:20])
}
// 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 {
return bytes.Equal(b.parentCheck[:], hash.Bytes()[:20])
return bytes.Equal(b.ParentCheck[:], hash.Bytes()[:20])
}
// 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 {
return uint64(b.batches[i].EpochNum)
return uint64(b.Batches[i].EpochNum)
}
// GetBlockTimestamp returns the timestamp of the block at the given index in the span.
func (b *SpanBatch) GetBlockTimestamp(i int) uint64 {
return b.batches[i].Timestamp
return b.Batches[i].Timestamp
}
// GetBlockTransactions returns the encoded transactions of the block at the given index in the span.
func (b *SpanBatch) GetBlockTransactions(i int) []hexutil.Bytes {
return b.batches[i].Transactions
return b.Batches[i].Transactions
}
// GetBlockCount returns the number of blocks in the span
func (b *SpanBatch) GetBlockCount() int {
return len(b.batches)
return len(b.Batches)
}
// AppendSingularBatch appends a SingularBatch into the span batch
// updates l1OriginCheck or parentCheck if needed.
func (b *SpanBatch) AppendSingularBatch(singularBatch *SingularBatch) {
if len(b.batches) == 0 {
copy(b.parentCheck[:], singularBatch.ParentHash.Bytes()[:20])
if len(b.Batches) == 0 {
copy(b.ParentCheck[:], singularBatch.ParentHash.Bytes()[:20])
}
b.batches = append(b.batches, singularBatchToElement(singularBatch))
copy(b.l1OriginCheck[:], singularBatch.EpochHash.Bytes()[:20])
b.Batches = append(b.Batches, singularBatchToElement(singularBatch))
copy(b.L1OriginCheck[:], singularBatch.EpochHash.Bytes()[:20])
}
// ToRawSpanBatch merges SingularBatch List and initialize single RawSpanBatch
func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint64, chainID *big.Int) (*RawSpanBatch, error) {
if len(b.batches) == 0 {
if len(b.Batches) == 0 {
return nil, errors.New("cannot merge empty singularBatch list")
}
raw := RawSpanBatch{}
// Sort by timestamp of L2 block
sort.Slice(b.batches, func(i, j int) bool {
return b.batches[i].Timestamp < b.batches[j].Timestamp
sort.Slice(b.Batches, func(i, j int) bool {
return b.Batches[i].Timestamp < b.Batches[j].Timestamp
})
// spanBatchPrefix
span_start := b.batches[0]
span_end := b.batches[len(b.batches)-1]
span_start := b.Batches[0]
span_end := b.Batches[len(b.Batches)-1]
raw.relTimestamp = span_start.Timestamp - genesisTimestamp
raw.l1OriginNum = uint64(span_end.EpochNum)
raw.parentCheck = b.parentCheck
raw.l1OriginCheck = b.l1OriginCheck
raw.parentCheck = b.ParentCheck
raw.l1OriginCheck = b.L1OriginCheck
// spanBatchPayload
raw.blockCount = uint64(len(b.batches))
raw.blockCount = uint64(len(b.Batches))
raw.originBits = new(big.Int)
raw.originBits.SetBit(raw.originBits, 0, originChangedBit)
for i := 1; i < len(b.batches); i++ {
for i := 1; i < len(b.Batches); i++ {
bit := uint(0)
if b.batches[i-1].EpochNum < b.batches[i].EpochNum {
if b.Batches[i-1].EpochNum < b.Batches[i].EpochNum {
bit = 1
}
raw.originBits.SetBit(raw.originBits, i, bit)
}
var blockTxCounts []uint64
var txs [][]byte
for _, batch := range b.batches {
for _, batch := range b.Batches {
blockTxCount := uint64(len(batch.Transactions))
blockTxCounts = append(blockTxCounts, blockTxCount)
for _, rawTx := range batch.Transactions {
......@@ -568,13 +568,13 @@ func (b *SpanBatch) ToRawSpanBatch(originChangedBit uint, genesisTimestamp uint6
return &raw, nil
}
// GetSingularBatches converts spanBatchElements after L2 safe head to SingularBatches.
// Since spanBatchElement does not contain EpochHash, set EpochHash from the given L1 blocks.
// GetSingularBatches converts SpanBatchElements after L2 safe head to SingularBatches.
// Since SpanBatchElement 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.
func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead eth.L2BlockRef) ([]*SingularBatch, error) {
var singularBatches []*SingularBatch
originIdx := 0
for _, batch := range b.batches {
for _, batch := range b.Batches {
if batch.Timestamp <= l2SafeHead.Time {
continue
}
......@@ -600,16 +600,16 @@ func (b *SpanBatch) GetSingularBatches(l1Origins []eth.L1BlockRef, l2SafeHead et
return singularBatches, nil
}
// NewSpanBatch converts given singularBatches into spanBatchElements, and creates a new SpanBatch.
// NewSpanBatch converts given singularBatches into SpanBatchElements, and creates a new SpanBatch.
func NewSpanBatch(singularBatches []*SingularBatch) *SpanBatch {
spanBatch := &SpanBatch{}
if len(singularBatches) == 0 {
return spanBatch
}
copy(spanBatch.parentCheck[:], singularBatches[0].ParentHash.Bytes()[:20])
copy(spanBatch.l1OriginCheck[:], singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20])
copy(spanBatch.ParentCheck[:], singularBatches[0].ParentHash.Bytes()[:20])
copy(spanBatch.L1OriginCheck[:], singularBatches[len(singularBatches)-1].EpochHash.Bytes()[:20])
for _, singularBatch := range singularBatches {
spanBatch.batches = append(spanBatch.batches, singularBatchToElement(singularBatch))
spanBatch.Batches = append(spanBatch.Batches, singularBatchToElement(singularBatch))
}
return spanBatch
}
......@@ -660,7 +660,7 @@ func (b *SpanBatchBuilder) GetRawSpanBatch() (*RawSpanBatch, error) {
}
func (b *SpanBatchBuilder) GetBlockCount() int {
return len(b.spanBatch.batches)
return len(b.spanBatch.Batches)
}
func (b *SpanBatchBuilder) Reset() {
......
......@@ -328,18 +328,18 @@ func TestSpanBatchDerive(t *testing.T) {
require.NoError(t, err)
blockCount := len(singularBatches)
require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.parentCheck[:])
require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.l1OriginCheck[:])
require.Equal(t, safeL2Head.Hash.Bytes()[:20], spanBatchDerived.ParentCheck[:])
require.Equal(t, singularBatches[blockCount-1].Epoch().Hash.Bytes()[:20], spanBatchDerived.L1OriginCheck[:])
require.Equal(t, len(singularBatches), int(rawSpanBatch.blockCount))
for i := 1; i < len(singularBatches); i++ {
require.Equal(t, spanBatchDerived.batches[i].Timestamp, spanBatchDerived.batches[i-1].Timestamp+l2BlockTime)
require.Equal(t, spanBatchDerived.Batches[i].Timestamp, spanBatchDerived.Batches[i-1].Timestamp+l2BlockTime)
}
for i := 0; i < len(singularBatches); i++ {
require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.batches[i].EpochNum)
require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.batches[i].Timestamp)
require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.batches[i].Transactions)
require.Equal(t, singularBatches[i].EpochNum, spanBatchDerived.Batches[i].EpochNum)
require.Equal(t, singularBatches[i].Timestamp, spanBatchDerived.Batches[i].Timestamp)
require.Equal(t, singularBatches[i].Transactions, spanBatchDerived.Batches[i].Transactions)
}
}
}
......@@ -508,8 +508,8 @@ func TestSpanBatchBuilder(t *testing.T) {
for i := 0; i < len(singularBatches); i++ {
spanBatchBuilder.AppendSingularBatch(singularBatches[i], seqNum)
require.Equal(t, i+1, spanBatchBuilder.GetBlockCount())
require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.parentCheck[:])
require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.l1OriginCheck[:])
require.Equal(t, singularBatches[0].ParentHash.Bytes()[:20], spanBatchBuilder.spanBatch.ParentCheck[:])
require.Equal(t, singularBatches[i].EpochHash.Bytes()[:20], spanBatchBuilder.spanBatch.L1OriginCheck[:])
}
rawSpanBatch, err := spanBatchBuilder.GetRawSpanBatch()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment