Skip to content

Commit dcc2356

Browse files
committed
Merge branch 'update-20251114115614' into develop
2 parents 906b730 + cb33236 commit dcc2356

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+38916
-32
lines changed

core/rawdb/accessors_rollup_event.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import (
55
"fmt"
66
"math/big"
77

8-
"github.com/scroll-tech/da-codec/encoding"
9-
108
"github.com/scroll-tech/go-ethereum/common"
9+
"github.com/scroll-tech/go-ethereum/da-codec/encoding"
1110
"github.com/scroll-tech/go-ethereum/ethdb"
1211
"github.com/scroll-tech/go-ethereum/log"
1312
"github.com/scroll-tech/go-ethereum/rlp"

da-codec/encoding/bitmap.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package encoding
2+
3+
import (
4+
"fmt"
5+
"math/big"
6+
7+
"github.com/scroll-tech/go-ethereum/core/types"
8+
)
9+
10+
// constructSkippedBitmap constructs skipped L1 message bitmap of the batch.
11+
func constructSkippedBitmap(batchIndex uint64, chunks []*Chunk, totalL1MessagePoppedBefore uint64) ([]byte, uint64, error) {
12+
// skipped L1 message bitmap, an array of 256-bit bitmaps
13+
var skippedBitmap []*big.Int
14+
15+
// the first queue index that belongs to this batch
16+
baseIndex := totalL1MessagePoppedBefore
17+
18+
// the next queue index that we need to process
19+
nextIndex := totalL1MessagePoppedBefore
20+
21+
for chunkID, chunk := range chunks {
22+
for blockID, block := range chunk.Blocks {
23+
for _, tx := range block.Transactions {
24+
if tx.Type != types.L1MessageTxType {
25+
continue
26+
}
27+
28+
currentIndex := tx.Nonce
29+
30+
if currentIndex < nextIndex {
31+
return nil, 0, fmt.Errorf("unexpected batch payload, expected queue index: %d, got: %d. Batch index: %d, chunk index in batch: %d, block index in chunk: %d, block hash: %v, transaction hash: %v", nextIndex, currentIndex, batchIndex, chunkID, blockID, block.Header.Hash(), tx.TxHash)
32+
}
33+
34+
// mark skipped messages
35+
for skippedIndex := nextIndex; skippedIndex < currentIndex; skippedIndex++ {
36+
quo := int((skippedIndex - baseIndex) / 256)
37+
rem := int((skippedIndex - baseIndex) % 256)
38+
for len(skippedBitmap) <= quo {
39+
bitmap := big.NewInt(0)
40+
skippedBitmap = append(skippedBitmap, bitmap)
41+
}
42+
skippedBitmap[quo].SetBit(skippedBitmap[quo], rem, 1)
43+
}
44+
45+
// process included message
46+
quo := int((currentIndex - baseIndex) / 256)
47+
for len(skippedBitmap) <= quo {
48+
bitmap := big.NewInt(0)
49+
skippedBitmap = append(skippedBitmap, bitmap)
50+
}
51+
52+
nextIndex = currentIndex + 1
53+
}
54+
}
55+
}
56+
57+
skippedL1MessageBitmap := make([]byte, len(skippedBitmap)*skippedL1MessageBitmapByteSize)
58+
for ii, num := range skippedBitmap {
59+
bytes := num.Bytes()
60+
padding := skippedL1MessageBitmapByteSize - len(bytes)
61+
copy(skippedL1MessageBitmap[skippedL1MessageBitmapByteSize*ii+padding:], bytes)
62+
}
63+
64+
return skippedL1MessageBitmap, nextIndex, nil
65+
}
66+
67+
// DecodeBitmap decodes skipped L1 message bitmap of the batch from bytes to big.Int's.
68+
func DecodeBitmap(skippedL1MessageBitmap []byte, totalL1MessagePopped int) ([]*big.Int, error) {
69+
length := len(skippedL1MessageBitmap)
70+
if length%skippedL1MessageBitmapByteSize != 0 {
71+
return nil, fmt.Errorf("skippedL1MessageBitmap length doesn't match, skippedL1MessageBitmap length should be equal 0 modulo %v, length of skippedL1MessageBitmap: %v", skippedL1MessageBitmapByteSize, length)
72+
}
73+
if length*8 < totalL1MessagePopped {
74+
return nil, fmt.Errorf("skippedL1MessageBitmap length is too small, skippedL1MessageBitmap length should be at least %v, length of skippedL1MessageBitmap: %v", (totalL1MessagePopped+7)/8, length)
75+
}
76+
var skippedBitmap []*big.Int
77+
for index := 0; index < length/skippedL1MessageBitmapByteSize; index++ {
78+
bitmap := big.NewInt(0).SetBytes(skippedL1MessageBitmap[index*skippedL1MessageBitmapByteSize : index*skippedL1MessageBitmapByteSize+skippedL1MessageBitmapByteSize])
79+
skippedBitmap = append(skippedBitmap, bitmap)
80+
}
81+
return skippedBitmap, nil
82+
}
83+
84+
// IsL1MessageSkipped checks if the L1 message at the given index is skipped.
85+
func IsL1MessageSkipped(skippedBitmap []*big.Int, index uint64) bool {
86+
if index >= uint64(len(skippedBitmap))*256 {
87+
return false
88+
}
89+
quo := index / 256
90+
rem := index % 256
91+
return skippedBitmap[quo].Bit(int(rem)) == 1
92+
}

da-codec/encoding/bitmap_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package encoding
2+
3+
import (
4+
"encoding/hex"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestDecodeBitmap(t *testing.T) {
11+
bitmapHex := "0000000000000000000000000000000000000000000000000000001ffffffbff"
12+
skippedL1MessageBitmap, err := hex.DecodeString(bitmapHex)
13+
assert.NoError(t, err)
14+
15+
decodedBitmap, err := DecodeBitmap(skippedL1MessageBitmap, 42)
16+
assert.NoError(t, err)
17+
18+
assert.True(t, IsL1MessageSkipped(decodedBitmap, 0))
19+
assert.True(t, IsL1MessageSkipped(decodedBitmap, 9))
20+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 10))
21+
assert.True(t, IsL1MessageSkipped(decodedBitmap, 11))
22+
assert.True(t, IsL1MessageSkipped(decodedBitmap, 36))
23+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 37))
24+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 38))
25+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 39))
26+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 40))
27+
assert.False(t, IsL1MessageSkipped(decodedBitmap, 41))
28+
29+
_, err = DecodeBitmap([]byte{0x00}, 8)
30+
assert.Error(t, err)
31+
32+
_, err = DecodeBitmap([]byte{0x00, 0x00, 0x00, 0x00}, 33)
33+
assert.Error(t, err)
34+
}

0 commit comments

Comments
 (0)