-
Notifications
You must be signed in to change notification settings - Fork 1
/
datadir.go
103 lines (92 loc) · 2.06 KB
/
datadir.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main
import (
"compress/gzip"
"fmt"
"log"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
)
const blocksDirectoryName = "blocks"
const blockFileFormat = "%010d %s.gz"
const blockFileGlob = "*.gz"
var blocksDir = ""
var currentBlockHeight = 0
var reBlockFilename = regexp.MustCompile(`^([0-9]+) (.+?)\.gz$`)
func initDataDir() {
log.Println("Data directory:", *dataDir)
blocksDir = path.Join(*dataDir, blocksDirectoryName)
if _, err := os.Stat(*dataDir); os.IsNotExist(err) {
bootstrapDataDir()
} else if !dbFilePresent() || countDataDirBlocks() < 1 {
bootstrapDataDir()
}
}
func countDataDirBlocks() int {
blocks, err := filepath.Glob(path.Join(blocksDir, blockFileGlob))
if err != nil {
log.Println(err)
return -1
}
return len(blocks)
}
func getBlockFilename(b BlockWithHeader, height int) string {
return path.Join(blocksDir, fmt.Sprintf(blockFileFormat, height, b.BlockHeader.Hash))
}
func getBlockDataFromFilename(fn string) (int, string) {
base := filepath.Base(fn)
m := reBlockFilename.FindStringSubmatch(base)
height, err := strconv.Atoi(m[1])
if err != nil {
return -1, ""
}
return height, m[2]
}
func bootstrapDataDir() {
err := os.Mkdir(*dataDir, 0750)
if err != nil && !os.IsExist(err) {
log.Fatal(err)
}
err = os.Mkdir(blocksDir, 0750)
if err != nil && !os.IsExist(err) {
log.Fatal(err)
}
err = dataDirSaveBlock(GenesisBlock, 0)
if err != nil {
log.Fatal(err)
}
}
func dataDirSaveBlock(b BlockWithHeader, height int) error {
fname := getBlockFilename(b, height)
// Write the genesis block data file. All block files are gzipped.
f, err := os.Create(fname)
if err != nil {
return err
}
zf, err := gzip.NewWriterLevel(f, 9)
if err != nil {
os.Remove(fname)
return err
}
err = b.Block.Serialise(zf)
if err != nil {
os.Remove(fname)
return err
}
err = zf.Close()
if err != nil {
os.Remove(fname)
return err
}
err = f.Close()
if err != nil {
os.Remove(fname)
return err
}
return nil
}
func dataDirDeleteBlock(b BlockWithHeader, height int) error {
return os.Remove(getBlockFilename(b, height))
}