-
-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
- }
-
- emptyHash := bc.Hash{}
- if voteResult.LastBlockHash != emptyHash && voteResult.LastBlockHash != block.PreviousBlockHash {
- return errors.New("bbft append block error, the block parent hash is not equals last block hash of vote result")
- }
-
- for _, tx := range block.Transactions {
- for _, input := range tx.Inputs {
- unVoteInput, ok := input.TypedInput.(*types.UnvoteInput)
- if !ok {
- continue
- }
-
- pubkey := hex.EncodeToString(unVoteInput.Vote)
- voteResult.NumOfVote[pubkey], ok = checked.SubUint64(voteResult.NumOfVote[pubkey], unVoteInput.Amount)
- if !ok {
- return errVotingOperationOverFlow
- }
- }
- for _, output := range tx.Outputs {
- voteOutput, ok := output.TypedOutput.(*types.VoteTxOutput)
- if !ok {
- continue
- }
-
- pubkey := hex.EncodeToString(voteOutput.Vote)
- voteResult.NumOfVote[pubkey], ok = checked.AddUint64(voteResult.NumOfVote[pubkey], voteOutput.Amount)
- if !ok {
- return errVotingOperationOverFlow
- }
- }
- }
-
- voteResult.Finalized = (block.Height+1)%RoundVoteBlockNums == 0
- return nil
-}
-
-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/RoundVoteBlockNums + 1
- voteResult := voteResultMap[seq]
- if blockHeight == 0 {
- voteResult = &state.VoteResult{
- Seq: seq,
- NumOfVote: make(map[string]uint64),
- Finalized: false,
- }
- }
-
- if voteResult == nil {
- prevVoteResult := voteResultMap[seq-1]
- if prevVoteResult != nil {
- voteResult = &state.VoteResult{
- Seq: seq,
- NumOfVote: prevVoteResult.NumOfVote,
- Finalized: false,
- }
- }
- }
-
- 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 {
- // previous round voting must have finalized
- if !voteResult.Finalized {
- return nil, errors.New("previous round voting has not finalized")
- }
-
- voteResult.Seq = seq
- voteResult.Finalized = false
- 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 / RoundVoteBlockNums
- voteResult := voteResultMap[voteSeq]
-
- if voteResult == nil {
- voteResult, err := c.store.GetVoteResult(voteSeq)
- if err != nil {
- return err
- }
- voteResultMap[voteSeq] = voteResult
- }
-
- if voteResult.LastBlockHash != block.Hash() {
- return errors.New("bbft detach block error, the block hash is not equals last block hash of vote result")
- }
-
- for _, tx := range block.Transactions {
- for _, input := range tx.Inputs {
- unVoteInput, ok := input.TypedInput.(*types.UnvoteInput)
- if !ok {
- continue
- }
-
- pubkey := hex.EncodeToString(unVoteInput.Vote)
- voteResult.NumOfVote[pubkey], ok = checked.AddUint64(voteResult.NumOfVote[pubkey], unVoteInput.Amount)
- if !ok {
- return errVotingOperationOverFlow
- }
- }
- for _, output := range tx.Outputs {
- voteOutput, ok := output.TypedOutput.(*types.VoteTxOutput)
- if !ok {
- continue
- }
-
- pubkey := hex.EncodeToString(voteOutput.Vote)
- voteResult.NumOfVote[pubkey], ok = checked.SubUint64(voteResult.NumOfVote[pubkey], voteOutput.Amount)
- if !ok {
- return errVotingOperationOverFlow
- }
- }
- }
-
- voteResult.Finalized = false
- return nil
-}
-
-func initConsensusNodes() map[string]*consensusNode {
- voteResult := map[string]*consensusNode{}
- for i, pubkey := range config.CommonConfig.Federation.Xpubs {
- pubkeyStr := pubkey.String()
- voteResult[pubkeyStr] = &consensusNode{pubkey: pubkeyStr, voteNum: 0, order: uint64(i)}
- }
- return voteResult
-}