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 }