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

     1  package storages
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"fmt"
     8  
     9  	"github.com/sixexorg/magnetic-ring/common"
    10  	"github.com/sixexorg/magnetic-ring/errors"
    11  	"github.com/sixexorg/magnetic-ring/store/db"
    12  	"github.com/sixexorg/magnetic-ring/store/storelaw"
    13  )
    14  
    15  // write to db by height
    16  type VoteStore struct {
    17  	dbDir        string
    18  	store        *db.LevelDBStore
    19  	votePrefix   byte
    20  	recordPrefix byte
    21  }
    22  
    23  func NewVoteStore(dbDir string, votePrefix, recordPrefix byte) (*VoteStore, error) {
    24  	var err error
    25  	store, err := db.NewLevelDBStore(dbDir)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	voteStore := &VoteStore{
    30  		dbDir:        dbDir,
    31  		store:        store,
    32  		votePrefix:   votePrefix,
    33  		recordPrefix: recordPrefix,
    34  	}
    35  	return voteStore, nil
    36  }
    37  
    38  func (this *VoteStore) NewBatch() {
    39  	this.store.NewBatch()
    40  }
    41  func (this *VoteStore) CommitTo() error {
    42  	return this.store.BatchCommit()
    43  }
    44  
    45  func (this *VoteStore) GetVoteState(voteId common.Hash, height uint64) (*storelaw.VoteState, error) {
    46  	fmt.Printf("⭕️ vote store get voteId:%s height:%d\n", voteId.String(), height)
    47  	key := this.getKey(voteId, height)
    48  	iter := this.store.NewIterator(nil)
    49  	flag := true
    50  	buff := bytes.NewBuffer(nil)
    51  	if iter.Seek(key) {
    52  		if bytes.Compare(iter.Key(), key) == 0 {
    53  			buff.Write(iter.Key()[1:])
    54  			buff.Write(iter.Value())
    55  			flag = false
    56  		}
    57  	}
    58  	if flag && iter.Prev() {
    59  		buff.Write(iter.Key()[1:])
    60  		buff.Write(iter.Value())
    61  	}
    62  	iter.Release()
    63  	err := iter.Error()
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  	vs := &storelaw.VoteState{}
    68  	err = vs.Deserialize(buff)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	if bytes.Equal(vs.VoteId[:], voteId[:]) {
    73  		return vs, nil
    74  	}
    75  	return nil, errors.ERR_DB_NOT_FOUND
    76  }
    77  
    78  func (this *VoteStore) SaveVotes(vs []*storelaw.VoteState) {
    79  	for _, v := range vs {
    80  		fmt.Printf("⭕️ vote store save voteId:%s height:%d\n", v.VoteId.String(), v.Height)
    81  		key := this.getKey(v.VoteId, v.Height)
    82  		val := v.GetVal()
    83  		this.store.BatchPut(key, val)
    84  	}
    85  }
    86  
    87  func (this *VoteStore) AlreadyVoted(voteId common.Hash, account common.Address) bool {
    88  	key := this.getAccountKey(voteId, account)
    89  	_, err := this.store.Get(key)
    90  	if err != nil {
    91  		return false
    92  	}
    93  	return true
    94  }
    95  func (this *VoteStore) SaveAccountVoted(avs []*storelaw.AccountVoted, height uint64) {
    96  	for _, v := range avs {
    97  		for _, vi := range v.Accounts {
    98  			key := this.getAccountKey(v.VoteId, vi)
    99  
   100  			val := make([]byte, 8)
   101  			binary.LittleEndian.PutUint64(val, height)
   102  			this.store.BatchPut(key, val)
   103  		}
   104  	}
   105  }
   106  
   107  func (this *VoteStore) getKey(voteId common.Hash, height uint64) []byte {
   108  	buff := make([]byte, 1+common.HashLength+8)
   109  	buff[0] = this.votePrefix
   110  	copy(buff[1:common.HashLength+1], voteId[:])
   111  	binary.LittleEndian.PutUint64(buff[common.HashLength+1:], height)
   112  	return buff
   113  }
   114  func (this *VoteStore) getAccountKey(voteId common.Hash, account common.Address) []byte {
   115  	buff := make([]byte, 1+common.HashLength+common.AddrLength)
   116  	buff[0] = this.recordPrefix
   117  	copy(buff[1:common.HashLength+1], voteId[:])
   118  	copy(buff[common.HashLength+1:], account[:])
   119  	return buff
   120  }