1 // Package account stores and tracks accounts within a Bytom Core.
7 log "github.com/sirupsen/logrus"
9 "github.com/bytom/common"
12 // ImageSlice record info of single account
13 type ImageSlice struct {
14 Account *Account `json:"account"`
15 ContractIndex uint64 `json:"contract_index"`
18 // Image is the struct for hold export account data
20 Slice []*ImageSlice `json:"slices"`
23 // Backup export all the account info into image
24 func (m *Manager) Backup() (*Image, error) {
26 Slice: []*ImageSlice{},
29 accountIter := m.db.IteratorPrefix(accountPrefix)
30 defer accountIter.Release()
31 for accountIter.Next() {
33 if err := json.Unmarshal(accountIter.Value(), a); err != nil {
37 image.Slice = append(image.Slice, &ImageSlice{
39 ContractIndex: m.getNextContractIndex(a.ID),
45 // Restore import the accountImages into account manage
46 func (m *Manager) Restore(image *Image) error {
47 maxAccountIndex := uint64(0)
48 storeBatch := m.db.NewBatch()
49 for _, slice := range image.Slice {
50 if existed := m.db.Get(Key(slice.Account.ID)); existed != nil {
51 log.WithFields(log.Fields{
52 "alias": slice.Account.Alias,
53 "id": slice.Account.ID,
54 }).Warning("skip restore account due to already existed")
57 if existed := m.db.Get(aliasKey(slice.Account.Alias)); existed != nil {
58 return ErrDuplicateAlias
61 rawAccount, err := json.Marshal(slice.Account)
63 return ErrMarshalAccount
66 if slice.Account.Signer.KeyIndex > maxAccountIndex {
67 maxAccountIndex = slice.Account.Signer.KeyIndex
69 storeBatch.Set(Key(slice.Account.ID), rawAccount)
70 storeBatch.Set(aliasKey(slice.Account.Alias), []byte(slice.Account.ID))
73 if localIndex := m.getNextAccountIndex(); localIndex < maxAccountIndex {
74 storeBatch.Set(accountIndexKey, common.Unit64ToBytes(maxAccountIndex))
78 for _, slice := range image.Slice {
79 for i := uint64(1); i <= slice.ContractIndex; i++ {
80 if _, err := m.createAddress(nil, slice.Account, false); err != nil {