OSDN Git Service

edit for code review
[bytom/bytom.git] / account / image.go
1 // Package account stores and tracks accounts within a Chain Core.
2 package account
3
4 import (
5         "encoding/json"
6
7         "github.com/bytom/common"
8 )
9
10 // ImageSlice record info of single account
11 type ImageSlice struct {
12         Account       *Account `json:"account"`
13         ContractIndex uint64   `json:"contract_index"`
14 }
15
16 // Image is the struct for hold export account data
17 type Image struct {
18         Slice []*ImageSlice `json:"slices"`
19 }
20
21 // Backup export all the account info into image
22 func (m *Manager) Backup() (*Image, error) {
23         image := &Image{
24                 Slice: []*ImageSlice{},
25         }
26
27         accountIter := m.db.IteratorPrefix(accountPrefix)
28         defer accountIter.Release()
29         for accountIter.Next() {
30                 a := &Account{}
31                 if err := json.Unmarshal(accountIter.Value(), a); err != nil {
32                         return nil, err
33                 }
34
35                 image.Slice = append(image.Slice, &ImageSlice{
36                         Account:       a,
37                         ContractIndex: m.getNextContractIndex(a.ID),
38                 })
39         }
40         return image, nil
41 }
42
43 // Restore import the accountImages into account manage
44 func (m *Manager) Restore(image *Image) error {
45         maxAccountIndex := uint64(0)
46         storeBatch := m.db.NewBatch()
47         for _, slice := range image.Slice {
48                 if existed := m.db.Get(aliasKey(slice.Account.Alias)); existed != nil {
49                         return ErrDuplicateAlias
50                 }
51
52                 rawAccount, err := json.Marshal(slice.Account)
53                 if err != nil {
54                         return ErrMarshalAccount
55                 }
56
57                 if slice.Account.Signer.KeyIndex > maxAccountIndex {
58                         maxAccountIndex = slice.Account.Signer.KeyIndex
59                 }
60                 storeBatch.Set(Key(slice.Account.ID), rawAccount)
61                 storeBatch.Set(aliasKey(slice.Account.Alias), []byte(slice.Account.ID))
62                 storeBatch.Set(contractIndexKey(slice.Account.ID), common.Unit64ToBytes(slice.ContractIndex))
63         }
64
65         if localIndex := m.getNextAccountIndex(); localIndex < maxAccountIndex {
66                 storeBatch.Set(accountIndexKey, common.Unit64ToBytes(maxAccountIndex))
67         }
68         storeBatch.Write()
69
70         for _, slice := range image.Slice {
71                 for i := uint64(1); i < slice.ContractIndex; i++ {
72                         if _, err := m.createAddress(nil, slice.Account, false); err != nil {
73                                 return err
74                         }
75                 }
76         }
77         return nil
78 }