1
1
package main
2
2
3
3
import (
4
+ "bufio"
4
5
"encoding/binary"
5
6
"errors"
6
7
"flag"
7
8
"fmt"
9
+ "io"
8
10
"os"
9
11
12
+ "go.uber.org/zap"
13
+ "go.uber.org/zap/zapcore"
14
+
10
15
"github.com/wavesplatform/gowaves/pkg/logging"
11
16
"github.com/wavesplatform/gowaves/pkg/proto"
12
17
"github.com/wavesplatform/gowaves/pkg/settings"
13
- "go.uber.org/zap"
14
- "go.uber.org/zap/zapcore"
15
18
)
16
19
17
20
const (
18
21
snapshotsByteSize = 4
19
22
)
20
23
21
- func parseSnapshots (nBlocks int , snapshotsBody * os.File , scheme proto.Scheme ) []proto.BlockSnapshot {
24
+ type SnapshotAtHeight struct {
25
+ Height proto.Height
26
+ BlockSnapshot proto.BlockSnapshot
27
+ }
28
+
29
+ func parseSnapshots (start , end uint64 , snapshotsBody io.Reader , scheme proto.Scheme ) []SnapshotAtHeight {
30
+ var buf []byte
22
31
snapshotsSizeBytes := make ([]byte , snapshotsByteSize )
23
- readPos := int64 (0 )
24
- var blocksSnapshots []proto.BlockSnapshot
25
- for height := uint64 (1 ); height <= uint64 (nBlocks ); height ++ {
26
- if _ , readBerr := snapshotsBody .ReadAt (snapshotsSizeBytes , readPos ); readBerr != nil {
27
- zap .S ().Fatalf ("failed to read the snapshots size in block %v" , readBerr )
32
+ var blocksSnapshots []SnapshotAtHeight
33
+ for height := uint64 (2 ); height < end ; height ++ {
34
+ if _ , readBerr := io .ReadFull (snapshotsBody , snapshotsSizeBytes ); readBerr != nil {
35
+ zap .S ().Fatalf ("failed to read the snapshots size in block: %v" , readBerr )
28
36
}
29
37
snapshotsSize := binary .BigEndian .Uint32 (snapshotsSizeBytes )
30
- if snapshotsSize == 0 {
31
- readPos += snapshotsByteSize
38
+ if snapshotsSize == 0 { // add empty block snapshot
39
+ if height >= start {
40
+ blocksSnapshots = append (blocksSnapshots , SnapshotAtHeight {
41
+ Height : height ,
42
+ BlockSnapshot : proto.BlockSnapshot {},
43
+ })
44
+ }
32
45
continue
33
46
}
34
- if snapshotsSize != 0 {
35
- snapshotsInBlock := proto.BlockSnapshot {}
36
- snapshots := make ([]byte , snapshotsSize + snapshotsByteSize ) // []{snapshot, size} + 4 bytes = size of all snapshots
37
- if _ , readRrr := snapshotsBody .ReadAt (snapshots , readPos ); readRrr != nil {
38
- zap .S ().Fatalf ("failed to read the snapshots in block %v" , readRrr )
39
- }
40
- unmrshlErr := snapshotsInBlock .UnmarshalBinaryImport (snapshots , scheme )
41
- if unmrshlErr != nil {
42
- zap .S ().Fatalf ("failed to unmarshal snapshots in block %v" , unmrshlErr )
43
- }
44
- blocksSnapshots = append (blocksSnapshots , snapshotsInBlock )
45
- readPos += int64 (snapshotsSize ) + snapshotsByteSize
47
+
48
+ if cap (buf ) < int (snapshotsSize ) {
49
+ buf = make ([]byte , snapshotsSize )
46
50
}
51
+ buf = buf [:snapshotsSize ]
52
+
53
+ if _ , readRrr := io .ReadFull (snapshotsBody , buf ); readRrr != nil {
54
+ zap .S ().Fatalf ("failed to read the snapshots in block: %v" , readRrr )
55
+ }
56
+ if height < start {
57
+ continue
58
+ }
59
+
60
+ snapshotsInBlock := proto.BlockSnapshot {}
61
+ unmrshlErr := snapshotsInBlock .UnmarshalBinaryImport (buf , scheme )
62
+ if unmrshlErr != nil {
63
+ zap .S ().Fatalf ("failed to unmarshal snapshots in block: %v" , unmrshlErr )
64
+ }
65
+ blocksSnapshots = append (blocksSnapshots , SnapshotAtHeight {
66
+ Height : height ,
67
+ BlockSnapshot : snapshotsInBlock ,
68
+ })
47
69
}
48
70
return blocksSnapshots
49
71
}
50
72
51
73
func main () {
52
- const (
53
- defaultBlocksNumber = 1000
54
- )
55
74
var (
56
75
logLevel = zap .LevelFlag ("log-level" , zapcore .InfoLevel ,
57
76
"Logging level. Supported levels: DEBUG, INFO, WARN, ERROR, FATAL. Default logging level INFO." )
58
77
blockchainType = flag .String ("blockchain-type" , "mainnet" ,
59
- "Blockchain type. Allowed values: mainnet/testnet/stagenet/custom . Default is 'mainnet'." )
78
+ "Blockchain type. Allowed values: mainnet/testnet/stagenet. Default is 'mainnet'." )
60
79
snapshotsPath = flag .String ("snapshots-path" , "" , "Path to binary blockchain file." )
61
- nBlocks = flag .Int ("blocks-number" , defaultBlocksNumber , "Number of blocks to import." )
80
+ blocksStart = flag .Uint64 ("blocks-start" , 0 ,
81
+ "Start block number. Should be greater than 1, because the snapshots file doesn't include genesis." )
82
+ nBlocks = flag .Uint64 ("blocks-number" , 1 , "Number of blocks to read since 'blocks-start'." )
62
83
)
63
84
flag .Parse ()
64
85
@@ -72,6 +93,9 @@ func main() {
72
93
if * snapshotsPath == "" {
73
94
zap .S ().Fatalf ("You must specify snapshots-path option." )
74
95
}
96
+ if * blocksStart < 2 {
97
+ zap .S ().Fatalf ("'blocks-start' must be greater than 1." )
98
+ }
75
99
76
100
ss , err := settings .BlockchainSettingsByTypeName (* blockchainType )
77
101
if err != nil {
@@ -82,7 +106,17 @@ func main() {
82
106
if err != nil {
83
107
zap .S ().Fatalf ("failed to open snapshots file, %v" , err )
84
108
}
85
- blocksSnapshots := parseSnapshots (* nBlocks , snapshotsBody , ss .AddressSchemeCharacter )
109
+ defer func (snapshotsBody * os.File ) {
110
+ if clErr := snapshotsBody .Close (); clErr != nil {
111
+ zap .S ().Fatalf ("failed to close snapshots file, %v" , clErr )
112
+ }
113
+ }(snapshotsBody )
114
+ const MB = 1 << 20
115
+ var (
116
+ start = * blocksStart
117
+ end = start + * nBlocks
118
+ )
119
+ blocksSnapshots := parseSnapshots (start , end , bufio .NewReaderSize (snapshotsBody , MB ), ss .AddressSchemeCharacter )
86
120
87
- zap .S ().Info (blocksSnapshots [ 0 ] )
121
+ zap .S ().Info (blocksSnapshots )
88
122
}
0 commit comments