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  }