From 908854e2eeebd0e59dd98a872a4858fe4b451955 Mon Sep 17 00:00:00 2001 From: Paladz Date: Wed, 5 Jun 2019 13:25:44 +0800 Subject: [PATCH] Edit bbft (#133) * Revert "Revert "edit" (#132)" This reverts commit 885e0da9b0527988339a5039250ef88449adc95a. * edit the consensus node * fix the solo net * edit for code review --- database/store.go | 8 +- database/store_test.go | 2 +- proposal/blockproposer/blockproposer.go | 9 +- protocol/bbft.go | 4 +- protocol/block.go | 26 +++-- protocol/consensus_node_manager.go | 163 ++++++++------------------------ protocol/protocol.go | 17 ++-- protocol/state/blockindex.go | 18 +--- protocol/state/vote_result.go | 48 ++++++++-- protocol/store.go | 2 +- protocol/txpool_test.go | 4 +- test/utxo_view/utxo_view_test.go | 4 +- 12 files changed, 131 insertions(+), 174 deletions(-) diff --git a/database/store.go b/database/store.go index 7db4a92d..4a61726c 100644 --- a/database/store.go +++ b/database/store.go @@ -224,13 +224,13 @@ 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, voteResults []*state.VoteResult) error { batch := s.db.NewBatch() if err := saveUtxoView(batch, view); err != nil { return err } - if err := saveVoteResult(batch, voteMap); err != nil { + if err := saveVoteResult(batch, voteResults); err != nil { return err } @@ -266,8 +266,8 @@ func (s *Store) SaveChainNodeStatus(bestNode, irreversibleNode *state.BlockNode) } // 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 { +func saveVoteResult(batch dbm.Batch, voteResults []*state.VoteResult) error { + for _, vote := range voteResults { bytes, err := json.Marshal(vote) if err != nil { return err diff --git a/database/store_test.go b/database/store_test.go index 45ff0168..68f62c3a 100644 --- a/database/store_test.go +++ b/database/store_test.go @@ -174,7 +174,7 @@ func TestSaveChainStatus(t *testing.T) { }, } - if err := store.SaveChainStatus(node, node, view, map[uint64]*state.VoteResult{}); err != nil { + if err := store.SaveChainStatus(node, node, view, []*state.VoteResult{}); err != nil { t.Fatal(err) } diff --git a/proposal/blockproposer/blockproposer.go b/proposal/blockproposer/blockproposer.go index cd84e708..13ebf174 100644 --- a/proposal/blockproposer/blockproposer.go +++ b/proposal/blockproposer/blockproposer.go @@ -57,8 +57,13 @@ func (b *BlockProposer) generateBlocks() { nextBlockTime = minNextBlockTime } - if isBlocker, err := b.chain.IsBlocker(&bestBlockHash, xpubStr, nextBlockTime); !isBlocker { - log.WithFields(log.Fields{"module": logModule, "error": err, "pubKey": xpubStr}).Debug("fail on check is next blocker") + isBlocker, err := b.chain.IsBlocker(&bestBlockHash, xpubStr, nextBlockTime) + if err != nil { + log.WithFields(log.Fields{"module": logModule, "error": err, "pubKey": xpubStr}).Error("fail on check is next blocker") + continue + } + + if !isBlocker { continue } diff --git a/protocol/bbft.go b/protocol/bbft.go index 5667bc6f..40b27300 100644 --- a/protocol/bbft.go +++ b/protocol/bbft.go @@ -28,7 +28,7 @@ func signCacheKey(blockHash, pubkey string) string { } func (c *Chain) isIrreversible(blockNode *state.BlockNode) bool { - consensusNodes, err := c.consensusNodeManager.getConsensusNodesByVoteResult(&blockNode.Parent.Hash) + consensusNodes, err := c.consensusNodeManager.getConsensusNodes(&blockNode.Parent.Hash) if err != nil { return false } @@ -97,7 +97,7 @@ func (c *Chain) ProcessBlockSignature(signature []byte, xPub [64]byte, blockHash // if some signature is invalid, they will be reset to nil // if the block has not the signature of blocker, it will return error func (c *Chain) validateSign(block *types.Block) (uint64, error) { - consensusNodeMap, err := c.consensusNodeManager.getConsensusNodesByVoteResult(&block.PreviousBlockHash) + consensusNodeMap, err := c.consensusNodeManager.getConsensusNodes(&block.PreviousBlockHash) if err != nil { return 0, err } diff --git a/protocol/block.go b/protocol/block.go index e3f0f839..45a5f2be 100644 --- a/protocol/block.go +++ b/protocol/block.go @@ -90,8 +90,11 @@ func (c *Chain) connectBlock(block *types.Block) (err error) { return err } - voteResultMap := make(map[uint64]*state.VoteResult) - if err := c.consensusNodeManager.applyBlock(voteResultMap, block); err != nil { + voteResult, err := c.consensusNodeManager.getBestVoteResult() + if err != nil { + return err + } + if err := voteResult.ApplyBlock(block); err != nil { return err } @@ -100,7 +103,7 @@ func (c *Chain) connectBlock(block *types.Block) (err error) { irreversibleNode = node } - if err := c.setState(node, irreversibleNode, utxoView, voteResultMap); err != nil { + if err := c.setState(node, irreversibleNode, utxoView, []*state.VoteResult{voteResult}); err != nil { return err } @@ -113,8 +116,12 @@ func (c *Chain) connectBlock(block *types.Block) (err error) { func (c *Chain) reorganizeChain(node *state.BlockNode) error { attachNodes, detachNodes := c.calcReorganizeNodes(node) utxoView := state.NewUtxoViewpoint() - voteResultMap := make(map[uint64]*state.VoteResult) + voteResults := []*state.VoteResult{} irreversibleNode := c.bestIrreversibleNode + voteResult, err := c.consensusNodeManager.getBestVoteResult() + if err != nil { + return err + } for _, detachNode := range detachNodes { b, err := c.store.GetBlock(&detachNode.Hash) @@ -140,7 +147,7 @@ func (c *Chain) reorganizeChain(node *state.BlockNode) error { return err } - if err := c.consensusNodeManager.detachBlock(voteResultMap, b); err != nil { + if err := voteResult.DetachBlock(b); err != nil { return err } @@ -167,10 +174,14 @@ func (c *Chain) reorganizeChain(node *state.BlockNode) error { return err } - if err := c.consensusNodeManager.applyBlock(voteResultMap, b); err != nil { + if err := voteResult.ApplyBlock(b); err != nil { return err } + if voteResult.IsFinalize() { + voteResults = append(voteResults, voteResult.Fork()) + } + if c.isIrreversible(attachNode) && b.Height > irreversibleNode.Height { irreversibleNode = attachNode } @@ -178,7 +189,8 @@ func (c *Chain) reorganizeChain(node *state.BlockNode) error { log.WithFields(log.Fields{"module": logModule, "height": node.Height, "hash": node.Hash.String()}).Debug("attach from mainchain") } - return c.setState(node, irreversibleNode, utxoView, voteResultMap) + voteResults = append(voteResults, voteResult.Fork()) + return c.setState(node, irreversibleNode, utxoView, voteResults) } // SaveBlock will validate and save block into storage diff --git a/protocol/consensus_node_manager.go b/protocol/consensus_node_manager.go index fd7de372..99693ab1 100644 --- a/protocol/consensus_node_manager.go +++ b/protocol/consensus_node_manager.go @@ -5,7 +5,6 @@ import ( "github.com/vapor/consensus" "github.com/vapor/errors" "github.com/vapor/protocol/bc" - "github.com/vapor/protocol/bc/types" "github.com/vapor/protocol/state" ) @@ -27,7 +26,7 @@ func newConsensusNodeManager(store Store, blockIndex *state.BlockIndex) *consens } func (c *consensusNodeManager) getConsensusNode(prevBlockHash *bc.Hash, pubkey string) (*state.ConsensusNode, error) { - consensusNodeMap, err := c.getConsensusNodesByVoteResult(prevBlockHash) + consensusNodeMap, err := c.getConsensusNodes(prevBlockHash) if err != nil { return nil, err } @@ -40,7 +39,7 @@ func (c *consensusNodeManager) getConsensusNode(prevBlockHash *bc.Hash, pubkey s } func (c *consensusNodeManager) isBlocker(prevBlockHash *bc.Hash, pubKey string, timeStamp uint64) (bool, error) { - consensusNodeMap, err := c.getConsensusNodesByVoteResult(prevBlockHash) + consensusNodeMap, err := c.getConsensusNodes(prevBlockHash) if err != nil { return false, err } @@ -50,64 +49,56 @@ func (c *consensusNodeManager) isBlocker(prevBlockHash *bc.Hash, pubKey string, return false, nil } - prevVoteRoundLastBlock, err := c.getPrevRoundVoteLastBlock(prevBlockHash) + prevVoteRoundLastBlock, err := c.getPrevRoundLastBlock(prevBlockHash) if err != nil { return false, err } startTimestamp := prevVoteRoundLastBlock.Timestamp + consensus.BlockTimeInterval - begin := getLastBlockTimeInTimeRange(startTimestamp, timeStamp, consensusNode.Order, len(consensusNodeMap)) + begin := getLastBlockTimeInTimeRange(startTimestamp, timeStamp, consensusNode.Order, uint64(len(consensusNodeMap))) end := begin + consensus.BlockNumEachNode*consensus.BlockTimeInterval return timeStamp >= begin && timeStamp < end, nil } -func getLastBlockTimeInTimeRange(startTimestamp, endTimestamp, order uint64, numOfConsensusNode int) uint64 { +func getLastBlockTimeInTimeRange(startTimestamp, endTimestamp, order, numOfConsensusNode uint64) uint64 { // One round of product block time for all consensus nodes - roundBlockTime := uint64(consensus.BlockNumEachNode * numOfConsensusNode * consensus.BlockTimeInterval) + roundBlockTime := consensus.BlockNumEachNode * numOfConsensusNode * consensus.BlockTimeInterval // The start time of the last round of product block lastRoundStartTime := startTimestamp + (endTimestamp-startTimestamp)/roundBlockTime*roundBlockTime // The time of product block of the consensus in last round return lastRoundStartTime + order*(consensus.BlockNumEachNode*consensus.BlockTimeInterval) } -func (c *consensusNodeManager) getPrevRoundVoteLastBlock(prevBlockHash *bc.Hash) (*state.BlockNode, error) { - prevBlockNode := c.blockIndex.GetNode(prevBlockHash) - if prevBlockNode == nil { +func (c *consensusNodeManager) getPrevRoundLastBlock(prevBlockHash *bc.Hash) (*state.BlockNode, error) { + node := c.blockIndex.GetNode(prevBlockHash) + if node == nil { return nil, errNotFoundBlockNode } - blockHeight := prevBlockNode.Height + 1 - - prevVoteRoundLastBlockHeight := blockHeight/consensus.RoundVoteBlockNums*consensus.RoundVoteBlockNums - 1 - // first round - if blockHeight/consensus.RoundVoteBlockNums == 0 { - prevVoteRoundLastBlockHeight = 0 + for node.Height%consensus.RoundVoteBlockNums != 0 { + node = node.Parent } - - lastBlockNode := prevBlockNode.GetParent(prevVoteRoundLastBlockHeight) - if lastBlockNode == nil { - return nil, errNotFoundBlockNode - } - return lastBlockNode, nil + return node, nil } -func (c *consensusNodeManager) getConsensusNodesByVoteResult(prevBlockHash *bc.Hash) (map[string]*state.ConsensusNode, error) { +func (c *consensusNodeManager) getConsensusNodes(prevBlockHash *bc.Hash) (map[string]*state.ConsensusNode, error) { prevBlockNode := c.blockIndex.GetNode(prevBlockHash) if prevBlockNode == nil { return nil, errNotFoundBlockNode } - seq := (prevBlockNode.Height + 1) / consensus.RoundVoteBlockNums - voteResult, err := c.store.GetVoteResult(seq) + seqHeight := prevBlockNode.Height + 1 + if bestHeight := c.blockIndex.BestNode().Height; bestHeight < seqHeight && bestHeight != 0 { + seqHeight = bestHeight + } + + preSeq := state.CalcVoteSeq(seqHeight) - 1 + voteResult, err := c.store.GetVoteResult(preSeq) if err != nil { - // TODO find previous round vote - voteResult = &state.VoteResult{ - Seq: seq, - NumOfVote: make(map[string]uint64), - } + return nil, err } - lastBlockNode, err := c.getPrevRoundVoteLastBlock(prevBlockHash) + lastBlockNode, err := c.getPrevRoundLastBlock(prevBlockHash) if err != nil { return nil, err } @@ -117,34 +108,36 @@ func (c *consensusNodeManager) getConsensusNodesByVoteResult(prevBlockHash *bc.H } if len(voteResult.NumOfVote) == 0 { - return initConsensusNodes(), nil + return federationNodes(), nil } - return voteResult.ConsensusNodes() } -func (c *consensusNodeManager) reorganizeVoteResult(voteResult *state.VoteResult, forkChainNode *state.BlockNode) error { - genesisBlockHash := config.GenesisBlock().Hash() - mainChainNode := c.blockIndex.GetNode(&genesisBlockHash) +func (c *consensusNodeManager) getBestVoteResult() (*state.VoteResult, error) { + blockNode := c.blockIndex.BestNode() + seq := state.CalcVoteSeq(blockNode.Height) + voteResult, err := c.store.GetVoteResult(seq) + if err != nil { + return nil, err + } - emptyHash := bc.Hash{} - if voteResult.LastBlockHash != emptyHash { - mainChainNode = c.blockIndex.GetNode(&voteResult.LastBlockHash) - if mainChainNode == nil { - return errNotFoundBlockNode - } + if err := c.reorganizeVoteResult(voteResult, blockNode); err != nil { + return nil, err } + return voteResult, nil +} + +func (c *consensusNodeManager) reorganizeVoteResult(voteResult *state.VoteResult, node *state.BlockNode) error { + mainChainNode := c.blockIndex.GetNode(&voteResult.BlockHash) var attachNodes []*state.BlockNode var detachNodes []*state.BlockNode - - for forkChainNode != nil && mainChainNode != nil && forkChainNode.Hash != mainChainNode.Hash { + for forkChainNode := node; mainChainNode != forkChainNode; node = node.Parent { if forkChainNode.Height == mainChainNode.Height { detachNodes = append(detachNodes, mainChainNode) mainChainNode = mainChainNode.Parent } attachNodes = append([]*state.BlockNode{forkChainNode}, attachNodes...) - forkChainNode = forkChainNode.Parent } for _, node := range detachNodes { @@ -153,7 +146,7 @@ func (c *consensusNodeManager) reorganizeVoteResult(voteResult *state.VoteResult return err } - if err := c.detachBlock(map[uint64]*state.VoteResult{voteResult.Seq: voteResult}, block); err != nil { + if err := voteResult.DetachBlock(block); err != nil { return err } } @@ -164,88 +157,14 @@ func (c *consensusNodeManager) reorganizeVoteResult(voteResult *state.VoteResult return err } - if err := c.applyBlock(map[uint64]*state.VoteResult{voteResult.Seq: voteResult}, block); err != nil { - return err - } - } - return nil -} - -func (c *consensusNodeManager) applyBlock(voteResultMap map[uint64]*state.VoteResult, block *types.Block) (err error) { - voteResult, err := c.getVoteResult(voteResultMap, block.Height) - if err != nil { - return err - } - - return voteResult.ApplyBlock(block) -} - -func (c *consensusNodeManager) getVoteResult(voteResultMap map[uint64]*state.VoteResult, blockHeight uint64) (*state.VoteResult, error) { - var err error - // This round of voting prepares for the next round - seq := blockHeight/consensus.RoundVoteBlockNums + 1 - voteResult := voteResultMap[seq] - if blockHeight == 0 { - voteResult = &state.VoteResult{ - Seq: seq, - NumOfVote: make(map[string]uint64), - } - } - - if voteResult == nil { - prevVoteResult := voteResultMap[seq-1] - if prevVoteResult != nil { - voteResult = &state.VoteResult{ - Seq: seq, - NumOfVote: prevVoteResult.NumOfVote, - } - } - } - - if voteResult == nil { - voteResult, err = c.store.GetVoteResult(seq) - if err != nil && err != ErrNotFoundVoteResult { - return nil, err - } - } - - if voteResult == nil { - voteResult, err = c.store.GetVoteResult(seq - 1) - if err != nil && err != ErrNotFoundVoteResult { - return nil, err - } - - if voteResult != nil { - voteResult.Seq = seq - voteResult.LastBlockHash = bc.Hash{} - } - } - - if voteResult == nil { - return nil, errors.New("fail to get vote result") - } - - voteResultMap[seq] = voteResult - return voteResult, nil -} - -func (c *consensusNodeManager) detachBlock(voteResultMap map[uint64]*state.VoteResult, block *types.Block) error { - voteSeq := block.Height / consensus.RoundVoteBlockNums - voteResult := voteResultMap[voteSeq] - - if voteResult == nil { - voteResult, err := c.store.GetVoteResult(voteSeq) - if err != nil { + if err := voteResult.ApplyBlock(block); err != nil { return err } - voteResultMap[voteSeq] = voteResult } - - voteResult.DetachBlock(block) return nil } -func initConsensusNodes() map[string]*state.ConsensusNode { +func federationNodes() map[string]*state.ConsensusNode { voteResult := map[string]*state.ConsensusNode{} for i, xpub := range config.CommonConfig.Federation.Xpubs { voteResult[xpub.String()] = &state.ConsensusNode{XPub: xpub, VoteNum: 0, Order: uint64(i)} diff --git a/protocol/protocol.go b/protocol/protocol.go index b893e8a5..10795886 100644 --- a/protocol/protocol.go +++ b/protocol/protocol.go @@ -85,17 +85,18 @@ func (c *Chain) initChainStatus() error { return err } - voteResultMap := make(map[uint64]*state.VoteResult) - if err := c.consensusNodeManager.applyBlock(voteResultMap, genesisBlock); err != nil { - return err - } - + voteResults := []*state.VoteResult{&state.VoteResult{ + Seq: 0, + NumOfVote: map[string]uint64{}, + BlockHash: genesisBlock.Hash(), + BlockHeight: 0, + }} node, err := state.NewBlockNode(&genesisBlock.BlockHeader, nil) if err != nil { return err } - return c.store.SaveChainStatus(node, node, utxoView, voteResultMap) + return c.store.SaveChainStatus(node, node, utxoView, voteResults) } // BestBlockHeight returns the current height of the blockchain. @@ -124,8 +125,8 @@ func (c *Chain) InMainChain(hash bc.Hash) bool { } // 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, voteResults []*state.VoteResult) error { + if err := c.store.SaveChainStatus(node, irreversibleNode, view, voteResults); err != nil { return err } diff --git a/protocol/state/blockindex.go b/protocol/state/blockindex.go index c2e39637..e2e13548 100644 --- a/protocol/state/blockindex.go +++ b/protocol/state/blockindex.go @@ -85,20 +85,6 @@ func (node *BlockNode) CalcPastMedianTime() uint64 { return timestamps[len(timestamps)/2] } -// GetParent return the node of specified height -// And the node satisfies the same chain as current node -// Height of current node must greater than height parameter -func (node *BlockNode) GetParent(height uint64) *BlockNode { - prevBlockNode := node - for prevBlockNode != nil && prevBlockNode.Height != height { - if prevBlockNode.Height < height { - return nil - } - prevBlockNode = prevBlockNode.Parent - } - return prevBlockNode -} - // BlockIndex is the struct for help chain trace block chain as tree type BlockIndex struct { sync.RWMutex @@ -111,9 +97,9 @@ type BlockIndex struct { // NewBlockIndex will create a empty BlockIndex func NewBlockIndex() *BlockIndex { return &BlockIndex{ - index: make(map[bc.Hash]*BlockNode), + index: make(map[bc.Hash]*BlockNode), heightIndex: make(map[uint64][]*BlockNode), - mainChain: make([]*BlockNode, 0, approxNodesPerDay), + mainChain: make([]*BlockNode, 0, approxNodesPerDay), } } diff --git a/protocol/state/vote_result.go b/protocol/state/vote_result.go index acbd58f2..129f3a35 100644 --- a/protocol/state/vote_result.go +++ b/protocol/state/vote_result.go @@ -28,18 +28,30 @@ func (c byVote) Less(i, j int) bool { } func (c byVote) Swap(i, j int) { c[i], c[j] = c[j], c[i] } +// seq 0 is the genesis block +// seq 1 is the the block height 1, to block height RoundVoteBlockNums +// seq 2 is the block height RoundVoteBlockNums + 1 to block height 2 * RoundVoteBlockNums +// consensus node of the current round is the final result of previous round +func CalcVoteSeq(blockHeight uint64) uint64 { + if blockHeight == 0 { + return 0 + } + return (blockHeight-1)/consensus.RoundVoteBlockNums + 1 +} + // VoteResult represents a snapshot of each round of DPOS voting // Seq indicates the sequence of current votes, which start from zero // NumOfVote indicates the number of votes each consensus node receives, the key of map represent public key // Finalized indicates whether this vote is finalized type VoteResult struct { - Seq uint64 - NumOfVote map[string]uint64 - LastBlockHash bc.Hash + Seq uint64 + NumOfVote map[string]uint64 + BlockHash bc.Hash + BlockHeight uint64 } func (v *VoteResult) ApplyBlock(block *types.Block) error { - if v.LastBlockHash != block.PreviousBlockHash { + if v.BlockHash != block.PreviousBlockHash { return errors.New("block parent hash is not equals last block hash of vote result") } @@ -74,7 +86,9 @@ func (v *VoteResult) ApplyBlock(block *types.Block) error { } } - v.LastBlockHash = block.Hash() + v.BlockHash = block.Hash() + v.BlockHeight = block.Height + v.Seq = CalcVoteSeq(block.Height) return nil } @@ -102,7 +116,7 @@ func (v *VoteResult) ConsensusNodes() (map[string]*ConsensusNode, error) { } func (v *VoteResult) DetachBlock(block *types.Block) error { - if v.LastBlockHash != block.Hash() { + if v.BlockHash != block.Hash() { return errors.New("block hash is not equals last block hash of vote result") } @@ -137,6 +151,26 @@ func (v *VoteResult) DetachBlock(block *types.Block) error { } } - v.LastBlockHash = block.PreviousBlockHash + v.BlockHash = block.PreviousBlockHash + v.BlockHeight = block.Height - 1 + v.Seq = CalcVoteSeq(block.Height - 1) return nil } + +func (v *VoteResult) Fork() *VoteResult { + f := &VoteResult{ + Seq: v.Seq, + NumOfVote: map[string]uint64{}, + BlockHash: v.BlockHash, + BlockHeight: v.BlockHeight, + } + + for key, value := range v.NumOfVote { + f.NumOfVote[key] = value + } + return f +} + +func (v *VoteResult) IsFinalize() bool { + return v.BlockHeight%consensus.RoundVoteBlockNums == 0 +} diff --git a/protocol/store.go b/protocol/store.go index 48ac4e8e..d2d11265 100644 --- a/protocol/store.go +++ b/protocol/store.go @@ -26,7 +26,7 @@ type Store interface { 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, []*state.VoteResult) error SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error } diff --git a/protocol/txpool_test.go b/protocol/txpool_test.go index c3891336..38200c30 100644 --- a/protocol/txpool_test.go +++ b/protocol/txpool_test.go @@ -120,7 +120,7 @@ func (s *mockStore) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error) func (s *mockStore) GetVoteResult(uint64) (*state.VoteResult, error) { return nil, nil } func (s *mockStore) LoadBlockIndex(uint64) (*state.BlockIndex, error) { return nil, nil } func (s *mockStore) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil } -func (s *mockStore) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error { +func (s *mockStore) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, []*state.VoteResult) error { return nil } func (s *mockStore) SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error { return nil } @@ -669,7 +669,7 @@ func (s *mockStore1) GetUtxo(*bc.Hash) (*storage.UtxoEntry, error) { retu func (s *mockStore1) GetVoteResult(uint64) (*state.VoteResult, error) { return nil, nil } func (s *mockStore1) LoadBlockIndex(uint64) (*state.BlockIndex, error) { return nil, nil } func (s *mockStore1) SaveBlock(*types.Block, *bc.TransactionStatus) error { return nil } -func (s *mockStore1) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, map[uint64]*state.VoteResult) error { +func (s *mockStore1) SaveChainStatus(*state.BlockNode, *state.BlockNode, *state.UtxoViewpoint, []*state.VoteResult) error { return nil } func (s *mockStore1) SaveChainNodeStatus(*state.BlockNode, *state.BlockNode) error { return nil } diff --git a/test/utxo_view/utxo_view_test.go b/test/utxo_view/utxo_view_test.go index ac7cfff7..bddeb543 100644 --- a/test/utxo_view/utxo_view_test.go +++ b/test/utxo_view/utxo_view_test.go @@ -414,7 +414,7 @@ func TestAttachOrDetachBlocks(t *testing.T) { for k, v := range c.before { utxoViewpoint.Entries[k] = v } - if err := store.SaveChainStatus(node, node, utxoViewpoint, map[uint64]*state.VoteResult{}); err != nil { + if err := store.SaveChainStatus(node, node, utxoViewpoint, []*state.VoteResult{}); err != nil { t.Error(err) } @@ -436,7 +436,7 @@ func TestAttachOrDetachBlocks(t *testing.T) { t.Error(err) } } - if err := store.SaveChainStatus(node, node, utxoViewpoint, map[uint64]*state.VoteResult{}); err != nil { + if err := store.SaveChainStatus(node, node, utxoViewpoint, []*state.VoteResult{}); err != nil { t.Error(err) } -- 2.11.0