OSDN Git Service

init CrossInViewpoint
[bytom/vapor.git] / database / store.go
index d218f0b..4e4464f 100644 (file)
@@ -21,11 +21,12 @@ import (
 const logModule = "leveldb"
 
 var (
-       blockStoreKey     = []byte("blockStore")
-       blockPrefix       = []byte("B:")
-       blockHeaderPrefix = []byte("BH:")
-       txStatusPrefix    = []byte("BTS:")
-       voteResultPrefix  = []byte("VR:")
+       blockStoreKey      = []byte("blockStore")
+       blockPrefix        = []byte("B:")
+       blockHeaderPrefix  = []byte("BH:")
+       txStatusPrefix     = []byte("BTS:")
+       mainchainOutPrefix = []byte("MCO:")
+       voteResultPrefix   = []byte("VR:")
 )
 
 func loadBlockStoreStateJSON(db dbm.DB) *protocol.BlockStoreState {
@@ -63,6 +64,11 @@ func calcTxStatusKey(hash *bc.Hash) []byte {
        return append(txStatusPrefix, hash.Bytes()...)
 }
 
+// TODO: maybe use pointer?
+func calcMainchainOutputKey(outputID bc.Hash) []byte {
+       return append(mainchainOutPrefix, outputID.Bytes()...)
+}
+
 func calcVoteResultKey(seq uint64) []byte {
        buf := [8]byte{}
        binary.BigEndian.PutUint64(buf[:], seq)
@@ -224,12 +230,16 @@ 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, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, voteMap map[uint64]*state.VoteResult) error {
+func (s *Store) SaveChainStatus(node, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, mainchainOutMap map[bc.Hash]bool, voteMap map[uint64]*state.VoteResult) error {
        batch := s.db.NewBatch()
        if err := saveUtxoView(batch, view); err != nil {
                return err
        }
 
+       if err := saveMainchainOutputIDs(batch, mainchainOutMap); err != nil {
+               return err
+       }
+
        if err := saveVoteResult(batch, voteMap); err != nil {
                return err
        }
@@ -249,6 +259,36 @@ func (s *Store) SaveChainStatus(node, irreversibleNode *state.BlockNode, view *s
        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
+}
+
+// TODO: what if in 1 tx?!
+// saveMainchainOutputIDs save mainchain output id in case of double spending
+func saveMainchainOutputIDs(batch dbm.Batch, mainchainOutMap map[bc.Hash]bool) error {
+       for outputID, output := range mainchainOutMap {
+               bytes, err := json.Marshal(output)
+               if err != nil {
+                       return err
+               }
+
+               batch.Set(calcMainchainOutputKey(outputID), 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 {