-
Notifications
You must be signed in to change notification settings - Fork 124
/
storetool.go
105 lines (91 loc) · 2.86 KB
/
storetool.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
104
105
package blockchain
import (
"errors"
"fmt"
cfg "github.com/spf13/viper"
pbtypes "github.com/dappledger/AnnChain/angine/protos/types"
dbm "github.com/dappledger/AnnChain/module/lib/go-db"
"github.com/dappledger/AnnChain/module/xlib/def"
)
var (
ErrBlockIsNil = errors.New("the chain has no block data")
ErrBranchNameUsed = errors.New("blockchain:branch name has been used")
ErrConvertToFuture = errors.New("can't revert to future height")
ErrRevertBackup = errors.New("revert from backup,not find data")
)
func BlockStoreDB(config *cfg.Viper) (dbm.DB, dbm.DB) {
var (
db_backend = config.GetString("db_backend")
db_dir = config.GetString("db_dir")
db_archive_dir = config.GetString("db_archive_dir")
)
return dbm.NewDB("blockstore", db_backend, db_dir),
dbm.NewDB("blockstore", db_backend, db_archive_dir)
}
func LoadBlockStore(blockStoreDB, blockArchiveDB dbm.DB, height def.INT) (*pbtypes.Block, *pbtypes.BlockMeta, *pbtypes.BlockID) {
blockStore := NewBlockStore(blockStoreDB, blockArchiveDB)
nextBlock := blockStore.LoadBlock(height + 1)
if nextBlock == nil {
return nil, nil, &pbtypes.BlockID{}
}
blockc, blockMeta := blockStore.LoadBlock(height), blockStore.LoadBlockMeta(height)
return blockc.Block, blockMeta, nextBlock.Header.LastBlockID
}
type StoreTool struct {
db dbm.DB
archDB dbm.DB
lastBlock BlockStoreStateJSON
}
func (st *StoreTool) Init(config *cfg.Viper) error {
st.db, st.archDB = BlockStoreDB(config)
st.lastBlock = LoadBlockStoreStateJSON(st.db)
if st.lastBlock.Height <= 0 {
return ErrBlockIsNil
}
return nil
}
func (st *StoreTool) LoadBlock(height def.INT) (*pbtypes.Block, *pbtypes.BlockMeta, *pbtypes.BlockID) {
return LoadBlockStore(st.db, st.archDB, height)
}
func (st *StoreTool) LastHeight() def.INT {
return st.lastBlock.Height
}
func (st *StoreTool) backupName(branchName string) []byte {
return []byte(fmt.Sprintf("%s-%s", blockStoreKey, branchName))
}
func (st *StoreTool) BackupLastBlock(branchName string) error {
preKeyName := st.backupName(branchName)
dataBs := st.db.Get(preKeyName)
if len(dataBs) > 0 {
return ErrBranchNameUsed
}
st.lastBlock.SaveByKey(preKeyName, st.db)
return nil
}
func (st *StoreTool) DelBackup(branchName string) {
st.db.Delete(st.backupName(branchName))
}
func (st *StoreTool) RevertFromBackup(branchName string) error {
bs := st.db.Get(st.backupName(branchName))
if len(bs) == 0 {
return ErrRevertBackup
}
st.db.Set(blockStoreKey, bs)
return nil
}
func (st *StoreTool) SaveNewLastBlock(toHeight def.INT) error {
if toHeight >= st.lastBlock.Height {
return ErrConvertToFuture
}
originHeight := st.lastBlock.OriginHeight
if originHeight > toHeight {
// 从最低高度 归档
originHeight = toHeight
}
newLastBlockStore := BlockStoreStateJSON{
Height: toHeight,
OriginHeight: originHeight,
}
newLastBlockStore.Save(st.db)
return nil
}