/
image.go
86 lines (73 loc) · 2.16 KB
/
image.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
// Package account stores and tracks accounts within a Bytom Core.
package account
import (
"encoding/json"
log "github.com/sirupsen/logrus"
"github.com/bytom-gm/common"
)
// ImageSlice record info of single account
type ImageSlice struct {
Account *Account `json:"account"`
ContractIndex uint64 `json:"contract_index"`
}
// Image is the struct for hold export account data
type Image struct {
Slice []*ImageSlice `json:"slices"`
}
// Backup export all the account info into image
func (m *Manager) Backup() (*Image, error) {
image := &Image{
Slice: []*ImageSlice{},
}
accountIter := m.db.IteratorPrefix(accountPrefix)
defer accountIter.Release()
for accountIter.Next() {
a := &Account{}
if err := json.Unmarshal(accountIter.Value(), a); err != nil {
return nil, err
}
image.Slice = append(image.Slice, &ImageSlice{
Account: a,
ContractIndex: m.getNextContractIndex(a.ID),
})
}
return image, nil
}
// Restore import the accountImages into account manage
func (m *Manager) Restore(image *Image) error {
maxAccountIndex := uint64(0)
storeBatch := m.db.NewBatch()
for _, slice := range image.Slice {
if existed := m.db.Get(Key(slice.Account.ID)); existed != nil {
log.WithFields(log.Fields{
"alias": slice.Account.Alias,
"id": slice.Account.ID,
}).Warning("skip restore account due to already existed")
continue
}
if existed := m.db.Get(aliasKey(slice.Account.Alias)); existed != nil {
return ErrDuplicateAlias
}
rawAccount, err := json.Marshal(slice.Account)
if err != nil {
return ErrMarshalAccount
}
if slice.Account.Signer.KeyIndex > maxAccountIndex {
maxAccountIndex = slice.Account.Signer.KeyIndex
}
storeBatch.Set(Key(slice.Account.ID), rawAccount)
storeBatch.Set(aliasKey(slice.Account.Alias), []byte(slice.Account.ID))
}
if localIndex := m.getNextAccountIndex(); localIndex < maxAccountIndex {
storeBatch.Set(accountIndexKey, common.Unit64ToBytes(maxAccountIndex))
}
storeBatch.Write()
for _, slice := range image.Slice {
for i := uint64(1); i <= slice.ContractIndex; i++ {
if _, err := m.createAddress(slice.Account, false); err != nil {
return err
}
}
}
return nil
}