github.com/sixexorg/magnetic-ring@v0.0.0-20191119090307-31705a21e419/store/mainchain/storages/league_store.go (about) 1 package storages 2 3 import ( 4 "bytes" 5 6 "encoding/binary" 7 8 "github.com/sixexorg/magnetic-ring/common" 9 "github.com/sixexorg/magnetic-ring/common/sink" 10 "github.com/sixexorg/magnetic-ring/errors" 11 "github.com/sixexorg/magnetic-ring/store/db" 12 mcom "github.com/sixexorg/magnetic-ring/store/mainchain/common" 13 "github.com/sixexorg/magnetic-ring/store/mainchain/states" 14 ) 15 16 //prototype pattern 17 type LeagueStore struct { 18 enableCache bool 19 dbDir string 20 store *db.LevelDBStore 21 } 22 23 func NewLeagueStore(dbDir string) (*LeagueStore, error) { 24 var err error 25 store, err := db.NewLevelDBStore(dbDir) 26 if err != nil { 27 return nil, err 28 } 29 leagueStates := &LeagueStore{ 30 dbDir: dbDir, 31 store: store, 32 } 33 return leagueStates, nil 34 } 35 36 //NewBatch start a commit batch 37 func (this *LeagueStore) NewBatch() { 38 this.store.NewBatch() 39 } 40 func (this *LeagueStore) CommitTo() error { 41 return this.store.BatchCommit() 42 } 43 44 func (this *LeagueStore) GetPrev(height uint64, leagueId common.Address) (*states.LeagueState, error) { 45 key := this.getKey(height, leagueId) 46 //fmt.Println("🈚️ 🈚️ 🈚️ get", hex.EncodeToString(key)) 47 iter := this.store.NewIterator(nil) 48 buff := bytes.NewBuffer(nil) 49 flag := true 50 if iter.Seek(key) { 51 //fmt.Println("🈚️ 🈚️ 🈚️ get 0.5") 52 if bytes.Compare(iter.Key(), key) == 0 { 53 //fmt.Println("🈚️ 🈚️ 🈚️ get 0.6") 54 buff.Write(iter.Key()) 55 buff.Write(iter.Value()) 56 flag = false 57 } 58 } 59 if flag && iter.Prev() { 60 //fmt.Println("🈚️ 🈚️ 🈚️ get 0.7") 61 buff.Write(iter.Key()) 62 buff.Write(iter.Value()) 63 } 64 iter.Release() 65 err := iter.Error() 66 //fmt.Println("🈚️ 🈚️ 🈚️ get1") 67 if err != nil { 68 return nil, err 69 } 70 //fmt.Println("🈚️ 🈚️ 🈚️ get2") 71 if buff.Len() == 0 { 72 return nil, errors.ERR_DB_NOT_FOUND 73 } 74 //fmt.Println("🈚️ 🈚️ 🈚️ get3") 75 as := &states.LeagueState{} 76 err = as.Deserialize(buff) 77 //fmt.Println("🈚️ 🈚️ 🈚️ get4") 78 if err != nil { 79 return nil, err 80 } 81 //fmt.Println("🈚️ 🈚️ 🈚️ get5") 82 if as.Address.Equals(leagueId) { 83 rate, creator, minBox, symbol, private, err := this.GetMetaData(leagueId) 84 if err != nil { 85 return nil, err 86 } 87 as.Rate = rate 88 as.MinBox = minBox 89 as.Creator = creator 90 as.Symbol = symbol 91 as.Private = private 92 return as, nil 93 } 94 //fmt.Println("🈚️ 🈚️ 🈚️ get6") 95 return nil, errors.ERR_DB_NOT_FOUND 96 } 97 func (this *LeagueStore) GetMetaData(leagueId common.Address) (rate uint32, creator common.Address, minBox uint64, symbol common.Symbol, private bool, err error) { 98 //fmt.Println("🈚️ 🈚️ 🈚️ GetMetaData 1") 99 k := this.getMetaKey(leagueId) 100 v, err := this.store.Get(k) 101 if err != nil { 102 return 103 } 104 //fmt.Println("🈚️ 🈚️ 🈚️ GetMetaData 2") 105 sk := sink.NewZeroCopySource(v) 106 eof := false 107 rate, eof = sk.NextUint32() 108 creator, eof = sk.NextAddress() 109 minBox, eof = sk.NextUint64() 110 symbol, eof = sk.NextSymbol() 111 private, _, eof = sk.NextBool() 112 if eof { 113 err = errors.ERR_SINK_EOF 114 } 115 //fmt.Println("🈚️ 🈚️ 🈚️ GetMetaData 3") 116 return 117 } 118 119 //SaveBlock persist block to store 120 func (this *LeagueStore) Save(state *states.LeagueState) error { 121 key := state.GetKey() 122 buff := new(bytes.Buffer) 123 err := state.Serialize(buff) 124 if err != nil { 125 return err 126 } 127 err = this.store.Put(key, buff.Bytes()) 128 if err != nil { 129 return err 130 } 131 return nil 132 } 133 func (this *LeagueStore) SymbolExists(symbol common.Symbol) error { 134 bl, err := this.store.Has(this.getSymbolKey(symbol)) 135 if err != nil || bl { 136 return errors.ERR_STATE_SYMBOL_EXISTS 137 } 138 return nil 139 } 140 func (this *LeagueStore) BatchSave(states states.LeagueStates) error { 141 for _, v := range states { 142 key := v.GetKey() 143 //fmt.Println("🈚️ 🈚️ 🈚️ save league ", hex.EncodeToString(key), v.Address.ToString(), v.Data.FrozenBox.Uint64(), v.Rate, v.Height) 144 buff := new(bytes.Buffer) 145 err := v.Serialize(buff) 146 if err != nil { 147 return err 148 } 149 this.store.BatchPut(key, buff.Bytes()) 150 if v.Data.Nonce == 1 { 151 mk := this.getMetaKey(v.Address) 152 if bl, _ := this.store.Has(mk); !bl { 153 mv := this.getMetaVal(v.Rate, v.Creator, v.MinBox, v.Symbol, v.Private) 154 this.store.BatchPut(mk, mv) 155 //fmt.Println("🈚️ 🈚️ 🈚️ save first ", hex.EncodeToString(key), v.Address.ToString(), v.Rate) 156 sym := this.getSymbolKey(v.Symbol) 157 this.store.BatchPut(sym, v.Address[:]) 158 } 159 } 160 } 161 return nil 162 } 163 func (this *LeagueStore) getKey(height uint64, leagueId common.Address) []byte { 164 buff := make([]byte, 1+common.AddrLength+8) 165 buff[0] = byte(mcom.ST_LEAGUE) 166 copy(buff[1:common.AddrLength+1], leagueId[:]) 167 binary.LittleEndian.PutUint64(buff[common.AddrLength+1:], height) 168 return buff 169 } 170 171 func (this *LeagueStore) getMetaKey(leagueId common.Address) []byte { 172 buff := make([]byte, 1+common.AddrLength) 173 buff[0] = byte(mcom.ST_LEAGUE_META) 174 copy(buff[1:common.AddrLength+1], leagueId[:]) 175 return buff 176 } 177 178 func (this *LeagueStore) getMetaVal(rate uint32, creator common.Address, minBox uint64, symbol common.Symbol, private bool) []byte { 179 sk := sink.NewZeroCopySink(nil) 180 sk.WriteUint32(rate) 181 sk.WriteAddress(creator) 182 sk.WriteUint64(minBox) 183 sk.WriteSymbol(symbol) 184 sk.WriteBool(private) 185 return sk.Bytes() 186 } 187 188 func (this *LeagueStore) getSymbolKey(symbol common.Symbol) []byte { 189 buff := make([]byte, 1+common.SymbolLen) 190 buff[0] = byte(mcom.ST_SYMBOL) 191 copy(buff[1:], symbol[:]) 192 return buff 193 }