OSDN Git Service

add error code for veto (#219)
[bytom/vapor.git] / account / image.go
1 // Package account stores and tracks accounts within a Bytom Core.
2 package account
3
4 import (
5         "encoding/json"
6
7         log "github.com/sirupsen/logrus"
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         m.accountMu.Lock()
24         defer m.accountMu.Unlock()
25
26         image := &Image{
27                 Slice: []*ImageSlice{},
28         }
29
30         accountIter := m.db.IteratorPrefix(accountPrefix)
31         defer accountIter.Release()
32         for accountIter.Next() {
33                 a := &Account{}
34                 if err := json.Unmarshal(accountIter.Value(), a); err != nil {
35                         return nil, err
36                 }
37
38                 image.Slice = append(image.Slice, &ImageSlice{
39                         Account:       a,
40                         ContractIndex: m.GetContractIndex(a.ID),
41                 })
42         }
43         return image, nil
44 }
45
46 // Restore import the accountImages into account manage
47 func (m *Manager) Restore(image *Image) error {
48         m.accountMu.Lock()
49         defer m.accountMu.Unlock()
50
51         storeBatch := m.db.NewBatch()
52         for _, slice := range image.Slice {
53                 if existed := m.db.Get(Key(slice.Account.ID)); existed != nil {
54                         log.WithFields(log.Fields{
55                                 "module": logModule,
56                                 "alias":  slice.Account.Alias,
57                                 "id":     slice.Account.ID,
58                         }).Warning("skip restore account due to already existed")
59                         continue
60                 }
61                 if existed := m.db.Get(aliasKey(slice.Account.Alias)); existed != nil {
62                         return ErrDuplicateAlias
63                 }
64
65                 rawAccount, err := json.Marshal(slice.Account)
66                 if err != nil {
67                         return ErrMarshalAccount
68                 }
69
70                 storeBatch.Set(Key(slice.Account.ID), rawAccount)
71                 storeBatch.Set(aliasKey(slice.Account.Alias), []byte(slice.Account.ID))
72         }
73
74         storeBatch.Write()
75         return nil
76 }