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 {
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)
}
// 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
}
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 {