github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/account/image.go (about)

     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  }