OSDN Git Service

store federation (#83)
[bytom/vapor.git] / database / store.go
index f1c2b23..7db4a92 100644 (file)
@@ -25,6 +25,7 @@ var (
        blockPrefix       = []byte("B:")
        blockHeaderPrefix = []byte("BH:")
        txStatusPrefix    = []byte("BTS:")
+       voteResultPrefix  = []byte("VR:")
 )
 
 func loadBlockStoreStateJSON(db dbm.DB) *protocol.BlockStoreState {
@@ -62,6 +63,12 @@ func calcTxStatusKey(hash *bc.Hash) []byte {
        return append(txStatusPrefix, hash.Bytes()...)
 }
 
+func calcVoteResultKey(seq uint64) []byte {
+       buf := [8]byte{}
+       binary.BigEndian.PutUint64(buf[:], seq)
+       return append(voteResultPrefix, buf[:]...)
+}
+
 // GetBlock return the block by given hash
 func GetBlock(db dbm.DB, hash *bc.Hash) (*types.Block, error) {
        bytez := db.Get(calcBlockKey(hash))
@@ -125,6 +132,20 @@ func (s *Store) GetStoreStatus() *protocol.BlockStoreState {
        return loadBlockStoreStateJSON(s.db)
 }
 
+// GetVoteResult retrive the voting result in specified vote sequence
+func (s *Store) GetVoteResult(seq uint64) (*state.VoteResult, error) {
+       data := s.db.Get(calcVoteResultKey(seq))
+       if data == nil {
+               return nil, protocol.ErrNotFoundVoteResult
+       }
+
+       vr := &state.VoteResult{}
+       if err := json.Unmarshal(data, vr); err != nil {
+               return nil, errors.Wrap(err, "unmarshaling vote result")
+       }
+       return vr, nil
+}
+
 func (s *Store) LoadBlockIndex(stateBestHeight uint64) (*state.BlockIndex, error) {
        startTime := time.Now()
        blockIndex := state.NewBlockIndex()
@@ -203,13 +224,22 @@ func (s *Store) SaveBlock(block *types.Block, ts *bc.TransactionStatus) error {
 }
 
 // SaveChainStatus save the core's newest status && delete old status
-func (s *Store) SaveChainStatus(node *state.BlockNode, view *state.UtxoViewpoint) error {
+func (s *Store) SaveChainStatus(node, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, voteMap map[uint64]*state.VoteResult) error {
        batch := s.db.NewBatch()
        if err := saveUtxoView(batch, view); err != nil {
                return err
        }
 
-       bytes, err := json.Marshal(protocol.BlockStoreState{Height: node.Height, Hash: &node.Hash})
+       if err := saveVoteResult(batch, voteMap); err != nil {
+               return err
+       }
+
+       bytes, err := json.Marshal(protocol.BlockStoreState{
+               Height:             node.Height,
+               Hash:               &node.Hash,
+               IrreversibleHeight: irreversibleNode.Height,
+               IrreversibleHash:   &irreversibleNode.Hash,
+       })
        if err != nil {
                return err
        }
@@ -218,3 +248,32 @@ func (s *Store) SaveChainStatus(node *state.BlockNode, view *state.UtxoViewpoint
        batch.Write()
        return nil
 }
+
+// SaveChainNodeStatus update the best node and irreversible node
+func (s *Store) SaveChainNodeStatus(bestNode, irreversibleNode *state.BlockNode) error {
+       bytes, err := json.Marshal(protocol.BlockStoreState{
+               Height:             bestNode.Height,
+               Hash:               &bestNode.Hash,
+               IrreversibleHeight: irreversibleNode.Height,
+               IrreversibleHash:   &irreversibleNode.Hash,
+       })
+       if err != nil {
+               return err
+       }
+
+       s.db.Set(blockStoreKey, bytes)
+       return nil
+}
+
+// saveVoteResult update the voting results generated by each irreversible block
+func saveVoteResult(batch dbm.Batch, voteMap map[uint64]*state.VoteResult) error {
+       for _, vote := range voteMap {
+               bytes, err := json.Marshal(vote)
+               if err != nil {
+                       return err
+               }
+
+               batch.Set(calcVoteResultKey(vote.Seq), bytes)
+       }
+       return nil
+}