@@ -2,15 +2,20 @@ package cmd
2
2
3
3
import (
4
4
"bufio"
5
+ "bytes"
5
6
"crypto/sha256"
6
7
"encoding/binary"
7
8
"fmt"
8
9
"io"
9
10
"log"
10
11
"os"
12
+ "strconv"
13
+ "strings"
11
14
12
15
"github.com/spf13/cobra"
13
16
17
+ "github.com/scroll-tech/go-ethereum/common"
18
+
14
19
"github.com/scroll-tech/go-ethereum/export-headers-toolkit/types"
15
20
)
16
21
@@ -38,33 +43,32 @@ The binary layout of the deduplicated file is as follows:
38
43
if err != nil {
39
44
log .Fatalf ("Error reading output flag: %v" , err )
40
45
}
46
+ verifyFile , err := cmd .Flags ().GetString ("verify" )
47
+ if err != nil {
48
+ log .Fatalf ("Error reading verify flag: %v" , err )
49
+ }
50
+
51
+ if verifyFile != "" {
52
+ verifyInputFile (verifyFile , inputFile )
53
+ }
41
54
42
55
_ , seenVanity , _ := runAnalysis (inputFile )
43
56
runDedup (inputFile , outputFile , seenVanity )
44
- runSHA256 (outputFile )
45
- },
46
- }
47
57
48
- func runSHA256 (outputFile string ) {
49
- f , err := os .Open (outputFile )
50
- defer f .Close ()
51
- if err != nil {
52
- log .Fatalf ("Error opening file: %v" , err )
53
- }
54
-
55
- h := sha256 .New ()
56
- if _ , err = io .Copy (h , f ); err != nil {
57
- log .Fatalf ("Error hashing file: %v" , err )
58
- }
58
+ if verifyFile != "" {
59
+ verifyOutputFile (verifyFile , outputFile )
60
+ }
59
61
60
- fmt .Printf ("Deduplicated headers written to %s with sha256 checksum: %x\n " , outputFile , h .Sum (nil ))
62
+ runSHA256 (outputFile )
63
+ },
61
64
}
62
65
63
66
func init () {
64
67
rootCmd .AddCommand (dedupCmd )
65
68
66
69
dedupCmd .Flags ().String ("input" , "headers.bin" , "headers file" )
67
70
dedupCmd .Flags ().String ("output" , "headers-dedup.bin" , "deduplicated, binary formatted file" )
71
+ dedupCmd .Flags ().String ("verify" , "" , "verify the input and output files with the given .csv file" )
68
72
}
69
73
70
74
func runAnalysis (inputFile string ) (seenDifficulty map [uint64 ]int , seenVanity map [[32 ]byte ]bool , seenSealLen map [int ]int ) {
@@ -118,6 +122,21 @@ func runDedup(inputFile, outputFile string, seenVanity map[[32]byte]bool) {
118
122
})
119
123
}
120
124
125
+ func runSHA256 (outputFile string ) {
126
+ f , err := os .Open (outputFile )
127
+ defer f .Close ()
128
+ if err != nil {
129
+ log .Fatalf ("Error opening file: %v" , err )
130
+ }
131
+
132
+ h := sha256 .New ()
133
+ if _ , err = io .Copy (h , f ); err != nil {
134
+ log .Fatalf ("Error hashing file: %v" , err )
135
+ }
136
+
137
+ fmt .Printf ("Deduplicated headers written to %s with sha256 checksum: %x\n " , outputFile , h .Sum (nil ))
138
+ }
139
+
121
140
type headerReader struct {
122
141
file * os.File
123
142
reader * bufio.Reader
@@ -175,3 +194,103 @@ func (h *headerReader) read(callback func(header *types.Header)) {
175
194
func (h * headerReader ) close () {
176
195
h .file .Close ()
177
196
}
197
+
198
+ type csvHeaderReader struct {
199
+ file * os.File
200
+ reader * bufio.Reader
201
+ }
202
+
203
+ func newCSVHeaderReader (verifyFile string ) * csvHeaderReader {
204
+ f , err := os .Open (verifyFile )
205
+ if err != nil {
206
+ log .Fatalf ("Error opening verify file: %v" , err )
207
+ }
208
+
209
+ h := & csvHeaderReader {
210
+ file : f ,
211
+ reader : bufio .NewReader (f ),
212
+ }
213
+
214
+ return h
215
+ }
216
+
217
+ func (h * csvHeaderReader ) readNext () * types.Header {
218
+ line , err := h .reader .ReadString ('\n' )
219
+ if err != nil {
220
+ if err == io .EOF {
221
+ return nil
222
+ }
223
+ log .Fatalf ("Error reading line: %v" , err )
224
+ }
225
+
226
+ s := strings .Split (line , "," )
227
+ extraString := strings .Split (s [2 ], "\n " )
228
+
229
+ num , err := strconv .ParseUint (s [0 ], 10 , 64 )
230
+ if err != nil {
231
+ log .Fatalf ("Error parsing block number: %v" , err )
232
+ }
233
+ difficulty , err := strconv .ParseUint (s [1 ], 10 , 64 )
234
+ if err != nil {
235
+ log .Fatalf ("Error parsing difficulty: %v" , err )
236
+ }
237
+ extra := common .FromHex (extraString [0 ])
238
+
239
+ header := types .NewHeader (num , difficulty , extra )
240
+ return header
241
+ }
242
+
243
+ func (h * csvHeaderReader ) close () {
244
+ h .file .Close ()
245
+ }
246
+
247
+ func verifyInputFile (verifyFile , inputFile string ) {
248
+ csvReader := newCSVHeaderReader (verifyFile )
249
+ defer csvReader .close ()
250
+
251
+ binaryReader := newHeaderReader (inputFile )
252
+ defer binaryReader .close ()
253
+
254
+ binaryReader .read (func (header * types.Header ) {
255
+ csvHeader := csvReader .readNext ()
256
+
257
+ if ! csvHeader .Equal (header ) {
258
+ log .Fatalf ("Header mismatch: %v != %v" , csvHeader , header )
259
+ }
260
+ })
261
+
262
+ log .Printf ("All headers match in %s and %s\n " , verifyFile , inputFile )
263
+ }
264
+
265
+ func verifyOutputFile (verifyFile , outputFile string ) {
266
+ csvReader := newCSVHeaderReader (verifyFile )
267
+ defer csvReader .close ()
268
+
269
+ dedupReader , err := NewReader (outputFile )
270
+ if err != nil {
271
+ log .Fatalf ("Error opening dedup file: %v" , err )
272
+ }
273
+ defer dedupReader .Close ()
274
+
275
+ for {
276
+ header := csvReader .readNext ()
277
+ if header == nil {
278
+ if _ , _ , err = dedupReader .ReadNext (); err == nil {
279
+ log .Fatalf ("Expected EOF, got more headers" )
280
+ }
281
+ break
282
+ }
283
+
284
+ difficulty , extraData , err := dedupReader .Read (header .Number )
285
+ if err != nil {
286
+ log .Fatalf ("Error reading header: %v" , err )
287
+ }
288
+
289
+ if header .Difficulty != difficulty {
290
+ log .Fatalf ("Difficulty mismatch: headerNum %d: %d != %d" , header .Number , header .Difficulty , difficulty )
291
+ }
292
+ if ! bytes .Equal (header .ExtraData , extraData ) {
293
+ log .Fatalf ("ExtraData mismatch: headerNum %d: %x != %x" , header .Number , header .ExtraData , extraData )
294
+ }
295
+ }
296
+ }
0 commit comments