}
// 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
}
+// saveVoteResult save mainchain output id in case of double spending
+func saveMainchainOutputIDs(batch dbm.Batch, mainchainOutMap map[bc.Hash]bool) error {
+ // for _, vote := range voteMap {
+ // bytes, err := json.Marshal(vote)
+ // if err != nil {
+ // return err
+ // }
+
+ // batch.Set(calcVoteResultKey(vote.Seq), 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 {
irreversibleNode = node
}
- if err := c.setState(node, irreversibleNode, utxoView, voteResultMap); err != nil {
+ mainchainOutMap := make(map[bc.Hash]bool)
+ if err := c.setState(node, irreversibleNode, utxoView, mainchainOutMap, voteResultMap); err != nil {
return err
}
func (c *Chain) reorganizeChain(node *state.BlockNode) error {
attachNodes, detachNodes := c.calcReorganizeNodes(node)
utxoView := state.NewUtxoViewpoint()
+ mainchainOutMap := make(map[bc.Hash]bool)
voteResultMap := make(map[uint64]*state.VoteResult)
irreversibleNode := c.bestIrreversibleNode
-
+
for _, detachNode := range detachNodes {
b, err := c.store.GetBlock(&detachNode.Hash)
if err != nil {
if err := utxoView.DetachBlock(detachBlock, txStatus); err != nil {
return err
}
-
+
if err := c.bbft.DetachBlock(voteResultMap, b); err != nil {
return err
}
log.WithFields(log.Fields{"module": logModule, "height": node.Height, "hash": node.Hash.String()}).Debug("attach from mainchain")
}
- return c.setState(node, irreversibleNode, utxoView, voteResultMap)
+ return c.setState(node, irreversibleNode, utxoView, mainchainOutMap, voteResultMap)
}
// SaveBlock will validate and save block into storage
if block.Height <= c.bestIrreversibleNode.Height {
return false, errors.New("the height of block below the height of irreversible block")
}
-
+
blockHash := block.Hash()
if c.BlockExist(&blockHash) {
log.WithFields(log.Fields{"module": logModule, "hash": blockHash.String(), "height": block.Height}).Info("block has been processed")
if err != nil {
return err
}
- return c.store.SaveChainStatus(node, node, utxoView, map[uint64]*state.VoteResult{})
+ mainchainOutMap := make(map[bc.Hash]bool)
+ return c.store.SaveChainStatus(node, node, utxoView, mainchainOutMap, map[uint64]*state.VoteResult{})
}
// BestBlockHeight returns the current height of the blockchain.
}
// This function must be called with mu lock in above level
-func (c *Chain) setState(node *state.BlockNode, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, voteMap map[uint64]*state.VoteResult) error {
- if err := c.store.SaveChainStatus(node, irreversibleNode, view, voteMap); err != nil {
+func (c *Chain) setState(node *state.BlockNode, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, mainchainOutMap map[bc.Hash]bool, voteMap map[uint64]*state.VoteResult) error {
+ if err := c.store.SaveChainStatus(node, irreversibleNode, view, mainchainOutMap, voteMap); err != nil {
return err
}
LoadBlockIndex(uint64) (*state.BlockIndex, error)
SaveBlock(*types.Block, *bc.TransactionStatus) error
- SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error
+ SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[bc.Hash]bool, map[uint64]*state.VoteResult) error
SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error
}