github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/orgchain/storages/account_store.go (about)

     1  package storages
     2  
     3  import (
     4  	"math/big"
     5  
     6  	"bytes"
     7  
     8  	"fmt"
     9  
    10  	"github.com/syndtr/goleveldb/leveldb/util"
    11  	"github.com/sixexorg/magnetic-ring/common"
    12  	"github.com/sixexorg/magnetic-ring/store/db"
    13  	"github.com/sixexorg/magnetic-ring/store/orgchain/states"
    14  	"github.com/sixexorg/magnetic-ring/store/storelaw"
    15  )
    16  
    17  var (
    18  	zero = big.NewInt(0)
    19  )
    20  
    21  //prototype pattern
    22  type AccountStore struct {
    23  	dbDir string
    24  	store *db.LevelDBStore
    25  }
    26  
    27  func NewAccountStore(dbDir string) (*AccountStore, error) {
    28  	var err error
    29  	store, err := db.NewLevelDBStore(dbDir)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  	accountStore := &AccountStore{
    34  		dbDir: dbDir,
    35  		store: store,
    36  	}
    37  	return accountStore, nil
    38  }
    39  
    40  //NewBatch start a commit batch
    41  func (this *AccountStore) NewBatch() {
    42  	this.store.NewBatch()
    43  }
    44  func (this *AccountStore) CommitTo() error {
    45  	return this.store.BatchCommit()
    46  }
    47  
    48  func (this *AccountStore) GetByHeight(height uint64, account common.Address) (storelaw.AccountStater, error) {
    49  	key := states.GetAccountStateKey(account, height)
    50  	v, err := this.store.Get(key)
    51  	if err != nil {
    52  		return nil, err
    53  	}
    54  	bf := bytes.NewBuffer(key)
    55  	bf.Write(v)
    56  	as := &states.AccountState{}
    57  	err = as.Deserialize(bf)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	return as, nil
    62  }
    63  func (this *AccountStore) GetPrev(height uint64, account, leagueId common.Address) (storelaw.AccountStater, error) {
    64  	key := states.GetAccountStateKey(account, height)
    65  	iter := this.store.NewIterator(nil)
    66  	buff := bytes.NewBuffer(nil)
    67  	flag := true
    68  	if iter.Seek(key) {
    69  		if bytes.Compare(iter.Key(), key) == 0 {
    70  			buff.Write(iter.Key())
    71  			buff.Write(iter.Value())
    72  			flag = false
    73  		}
    74  	}
    75  	if flag && iter.Prev() {
    76  		buff.Write(iter.Key())
    77  		buff.Write(iter.Value())
    78  	}
    79  	iter.Release()
    80  	err := iter.Error()
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	if buff.Len() == 0 {
    85  		return &states.AccountState{
    86  			Address: account,
    87  			Data: &states.Account{
    88  				Balance:     big.NewInt(0),
    89  				EnergyBalance: big.NewInt(0),
    90  			},
    91  		}, nil
    92  	}
    93  	as := &states.AccountState{}
    94  	err = as.Deserialize(buff)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	if as.Address.Equals(account) {
    99  		return as, nil
   100  	}
   101  	return &states.AccountState{
   102  		Address: account,
   103  		Data: &states.Account{
   104  			Balance:     big.NewInt(0),
   105  			EnergyBalance: big.NewInt(0),
   106  		},
   107  	}, nil
   108  }
   109  func (this *AccountStore) GetAccountRange(start, end uint64, account common.Address) (storelaw.AccountStaters, error) {
   110  	s := states.GetAccountStateKey(account, start)
   111  	l := states.GetAccountStateKey(account, end)
   112  	iter := this.store.NewSeniorIterator(&util.Range{Start: s, Limit: l})
   113  	ass := storelaw.AccountStaters{}
   114  	bf := bytes.NewBuffer(nil)
   115  	var err error
   116  	for iter.Next() {
   117  		bf.Write(iter.Key())
   118  		bf.Write(iter.Value())
   119  		as := &states.AccountState{}
   120  		err = as.Deserialize(bf)
   121  		if err != nil {
   122  			return nil, err
   123  		}
   124  		ass = append(ass, as)
   125  		bf.Reset()
   126  	}
   127  	iter.Release()
   128  	return ass, nil
   129  }
   130  
   131  //SaveBlock persist block to store
   132  func (this *AccountStore) Save(state storelaw.AccountStater) error {
   133  	key := state.GetKey()
   134  	buff := new(bytes.Buffer)
   135  	err := state.Serialize(buff)
   136  	if err != nil {
   137  		return err
   138  	}
   139  	err = this.store.Put(key, buff.Bytes())
   140  	if err != nil {
   141  		return err
   142  
   143  	}
   144  	return nil
   145  }
   146  func (this *AccountStore) BatchSave(states storelaw.AccountStaters) error {
   147  	for _, v := range states {
   148  		fmt.Println("⭕️ accountSave ", v.Balance().Uint64(), v.Energy().Uint64())
   149  		key := v.GetKey()
   150  		buff := new(bytes.Buffer)
   151  		err := v.Serialize(buff)
   152  		if err != nil {
   153  			return err
   154  		}
   155  		this.store.BatchPut(key, buff.Bytes())
   156  	}
   157  	return nil
   158  }
   159  
   160  func (this *AccountStore) BatchRemove(height uint64, addresses []common.Address) {
   161  	for _, v := range addresses {
   162  		key := states.GetAccountStateKey(v, height)
   163  		this.store.BatchDelete(key)
   164  	}
   165  }