Skip to content

Commit d7af40a

Browse files
committed
add bitmask to encapsulate logic around header information in it. also add vanity count as part of the bitmask
1 parent a242012 commit d7af40a

File tree

4 files changed

+88
-38
lines changed

4 files changed

+88
-38
lines changed

rollup/missing_header_fields/export-headers-toolkit/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ Where:
2929
- unique_vanity_i: unique vanity i
3030
- header_i: block header i
3131
- header:
32-
<vanity_index:uint8><flags:uint8><seal:[65|85]byte>
33-
- vanity_index: index of the vanity in the unique vanity list
32+
<flags:uint8><seal:[65|85]byte>
3433
- flags: bitmask, lsb first
35-
- bit 0: 0 if difficulty is 2, 1 if difficulty is 1
36-
- bit 1: 0 if seal length is 65, 1 if seal length is 85
37-
- rest: 0
34+
- bit 0-5: index of the vanity in the sorted vanities list
35+
- bit 6: 0 if difficulty is 2, 1 if difficulty is 1
36+
- bit 7: 0 if seal length is 65, 1 if seal length is 85
3837
```
3938

4039
## How to run

rollup/missing_header_fields/export-headers-toolkit/cmd/dedup.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ The binary layout of the deduplicated file is as follows:
2424
- 1 byte for the count of unique vanity
2525
- 32 bytes for each unique vanity
2626
- for each header:
27-
- 1 byte for the index of the vanity in the unique vanity list
2827
- 1 byte (bitmask, lsb first):
29-
- bit 0: 0 if difficulty is 2, 1 if difficulty is 1
30-
- bit 1: 0 if seal length is 65, 1 if seal length is 85
31-
- rest: 0
28+
- bit 0-5: index of the vanity in the sorted vanities list
29+
- bit 6: 0 if difficulty is 2, 1 if difficulty is 1
30+
- bit 7: 0 if seal length is 65, 1 if seal length is 85
3231
- 65 or 85 bytes for the seal`,
3332
Run: func(cmd *cobra.Command, args []string) {
3433
inputFile, err := cmd.Flags().GetString("input")
@@ -40,8 +39,8 @@ The binary layout of the deduplicated file is as follows:
4039
log.Fatalf("Error reading output flag: %v", err)
4140
}
4241

43-
seenDifficulty, seenVanity, seenSealLen := runAnalysis(inputFile)
44-
runDedup(inputFile, outputFile, seenDifficulty, seenVanity, seenSealLen)
42+
_, seenVanity, _ := runAnalysis(inputFile)
43+
runDedup(inputFile, outputFile, seenVanity)
4544
runSHA256(outputFile)
4645
},
4746
}
@@ -105,7 +104,7 @@ func runAnalysis(inputFile string) (seenDifficulty map[uint64]int, seenVanity ma
105104
return seenDifficulty, seenVanity, seenSealLen
106105
}
107106

108-
func runDedup(inputFile, outputFile string, seenDifficulty map[uint64]int, seenVanity map[[32]byte]bool, seenSealLen map[int]int) {
107+
func runDedup(inputFile, outputFile string, seenVanity map[[32]byte]bool) {
109108
reader := newHeaderReader(inputFile)
110109
defer reader.close()
111110

rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer.go

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import (
1111
"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
1212
)
1313

14+
// maxVanityCount is the maximum number of unique vanities that can be represented with 6 bits in the bitmask
15+
const maxVanityCount = 1 << 6
16+
1417
type missingHeaderFileWriter struct {
1518
file *os.File
1619
writer *bufio.Writer
@@ -19,6 +22,10 @@ type missingHeaderFileWriter struct {
1922
}
2023

2124
func newMissingHeaderFileWriter(filename string, seenVanity map[[32]byte]bool) *missingHeaderFileWriter {
25+
if len(seenVanity) > maxVanityCount {
26+
log.Fatalf("Number of unique vanities exceeds maximum: %d > %d", len(seenVanity), maxVanityCount)
27+
}
28+
2229
file, err := os.Create(filename)
2330
if err != nil {
2431
log.Fatalf("Error creating file: %v", err)
@@ -86,28 +93,73 @@ func (m *missingHeaderWriter) writeVanities() {
8693
}
8794

8895
func (m *missingHeaderWriter) write(header *types.Header) {
89-
// 1. write the index of the vanity in the unique vanity list
90-
if _, err := m.writer.Write([]byte{uint8(m.sortedVanitiesMap[header.Vanity()])}); err != nil {
91-
log.Fatalf("Error writing vanity index: %v", err)
96+
// 1. prepare the bitmask
97+
bits := newBitMask(m.sortedVanitiesMap[header.Vanity()], int(header.Difficulty), header.SealLen())
98+
99+
// 2. write the header: bitmask and seal
100+
if _, err := m.writer.Write(bits.Bytes()); err != nil {
101+
log.Fatalf("Error writing bitmask: %v", err)
92102
}
93103

94-
// 2. write the bitmask
95-
// - bit 0: 0 if difficulty is 2, 1 if difficulty is 1
96-
// - bit 1: 0 if seal length is 65, 1 if seal length is 85
97-
// - rest: 0
98-
bitmask := uint8(0)
99-
if header.Difficulty == 1 {
100-
bitmask |= 1 << 0
104+
if _, err := m.writer.Write(header.Seal()); err != nil {
105+
log.Fatalf("Error writing seal: %v", err)
101106
}
102-
if header.SealLen() == 85 {
103-
bitmask |= 1 << 1
107+
}
108+
109+
// bitMask is a bitmask that encodes the following information:
110+
//
111+
// bit 0-5: index of the vanity in the sorted vanities list
112+
// bit 6: 0 if difficulty is 2, 1 if difficulty is 1
113+
// bit 7: 0 if seal length is 65, 1 if seal length is 85
114+
type bitMask struct {
115+
b uint8
116+
}
117+
118+
func newBitMask(vanityIndex int, difficulty int, sealLen int) bitMask {
119+
b := uint8(0)
120+
121+
if vanityIndex >= maxVanityCount {
122+
log.Fatalf("Vanity index exceeds maximum: %d >= %d", vanityIndex, maxVanityCount)
104123
}
124+
b |= uint8(vanityIndex) & 0b00111111
105125

106-
if _, err := m.writer.Write([]byte{bitmask}); err != nil {
107-
log.Fatalf("Error writing bitmask: %v", err)
126+
if difficulty == 1 {
127+
b |= 1 << 6
128+
} else if difficulty != 2 {
129+
log.Fatalf("Invalid difficulty: %d", difficulty)
108130
}
109131

110-
if _, err := m.writer.Write(header.Seal()); err != nil {
111-
log.Fatalf("Error writing seal: %v", err)
132+
if sealLen == 85 {
133+
b |= 1 << 7
134+
} else if sealLen != 65 {
135+
log.Fatalf("Invalid seal length: %d", sealLen)
112136
}
137+
138+
return bitMask{b}
139+
}
140+
141+
func (b bitMask) vanityIndex() int {
142+
return int(b.b & 0b00111111)
143+
}
144+
145+
func (b bitMask) difficulty() int {
146+
val := (b.b >> 6) & 0x01
147+
if val == 0 {
148+
return 2
149+
} else {
150+
return 1
151+
}
152+
}
153+
154+
func (b bitMask) sealLen() int {
155+
val := (b.b >> 7) & 0x01
156+
if val == 0 {
157+
return 65
158+
} else {
159+
return 85
160+
}
161+
}
162+
163+
func (b bitMask) Bytes() []byte {
164+
return []byte{b.b}
113165
}

rollup/missing_header_fields/export-headers-toolkit/cmd/missing_header_writer_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ func TestMissingHeaderWriter(t *testing.T) {
3939
header := types.NewHeader(0, 2, append(vanity1[:], seal...))
4040
mhw.write(header)
4141

42-
expectedBytes = append(expectedBytes, 0x00) // index 0
43-
expectedBytes = append(expectedBytes, 0x00) // difficulty 2, seal length 65
42+
// bit 0-5:0x0 index0, bit 6=0: difficulty 2, bit 7=0: seal length 65
43+
expectedBytes = append(expectedBytes, 0b00000000)
4444
expectedBytes = append(expectedBytes, seal...)
4545
assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
4646
}
@@ -51,8 +51,8 @@ func TestMissingHeaderWriter(t *testing.T) {
5151
header := types.NewHeader(1, 1, append(vanity2[:], seal...))
5252
mhw.write(header)
5353

54-
expectedBytes = append(expectedBytes, 0x01) // index 1
55-
expectedBytes = append(expectedBytes, 0x01) // difficulty 1, seal length 65
54+
// bit 0-5:0x1 index1, bit 6=1: difficulty 1, bit 7=0: seal length 65
55+
expectedBytes = append(expectedBytes, 0b01000001)
5656
expectedBytes = append(expectedBytes, seal...)
5757
assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
5858
}
@@ -63,8 +63,8 @@ func TestMissingHeaderWriter(t *testing.T) {
6363
header := types.NewHeader(2, 2, append(vanity2[:], seal...))
6464
mhw.write(header)
6565

66-
expectedBytes = append(expectedBytes, 0x01) // index 1
67-
expectedBytes = append(expectedBytes, 0x02) // difficulty 2, seal length 85
66+
// bit 0-5:0x1 index1, bit 6=0: difficulty 2, bit 7=1: seal length 85
67+
expectedBytes = append(expectedBytes, 0b10000001)
6868
expectedBytes = append(expectedBytes, seal...)
6969
assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
7070
}
@@ -75,8 +75,8 @@ func TestMissingHeaderWriter(t *testing.T) {
7575
header := types.NewHeader(3, 1, append(vanity8[:], seal...))
7676
mhw.write(header)
7777

78-
expectedBytes = append(expectedBytes, 0x02) // index 2
79-
expectedBytes = append(expectedBytes, 0x03) // difficulty 1, seal length 85
78+
// bit 0-5:0x2 index2, bit 6=1: difficulty 1, bit 7=1: seal length 85
79+
expectedBytes = append(expectedBytes, 0b11000010)
8080
expectedBytes = append(expectedBytes, seal...)
8181
assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
8282
}
@@ -87,8 +87,8 @@ func TestMissingHeaderWriter(t *testing.T) {
8787
header := types.NewHeader(4, 2, append(vanity1[:], seal...))
8888
mhw.write(header)
8989

90-
expectedBytes = append(expectedBytes, 0x00) // index 0
91-
expectedBytes = append(expectedBytes, 0x00) // difficulty 2, seal length 65
90+
// bit 0-5:0x0 index0, bit 6=0: difficulty 2, bit 7=0: seal length 65
91+
expectedBytes = append(expectedBytes, 0b00000000)
9292
expectedBytes = append(expectedBytes, seal...)
9393
assert.Equal(t, expectedBytes, bytesBuffer.Bytes())
9494
}

0 commit comments

Comments
 (0)