github.com/n1ghtfa1l/go-vnt@v0.6.4-alpha.6/consensus/dpos/bft_msg.go (about)

     1  // Copyright 2019 The go-vnt Authors
     2  // This file is part of the go-vnt library.
     3  //
     4  // The go-vnt library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-vnt library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-vnt library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package dpos
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"github.com/vntchain/go-vnt/accounts"
    23  	"github.com/vntchain/go-vnt/common"
    24  	"github.com/vntchain/go-vnt/core/types"
    25  	"github.com/vntchain/go-vnt/crypto"
    26  	"github.com/vntchain/go-vnt/log"
    27  )
    28  
    29  func (bft *BftManager) makePrePrepareMsg(block *types.Block, round uint32) *types.PreprepareMsg {
    30  	msg := &types.PreprepareMsg{
    31  		Round: round,
    32  		Block: block,
    33  	}
    34  	return msg
    35  }
    36  
    37  func (bft *BftManager) makePrepareMsg(prePreMsg *types.PreprepareMsg) (*types.PrepareMsg, error) {
    38  	msg := &types.PrepareMsg{
    39  		Round:       prePreMsg.Round,
    40  		PrepareAddr: bft.coinBase,
    41  		BlockNumber: prePreMsg.Block.Number(),
    42  		BlockHash:   prePreMsg.Block.Hash(),
    43  		PrepareSig:  nil,
    44  	}
    45  
    46  	if sig, err := bft.dp.signFn(accounts.Account{Address: bft.coinBase}, msg.Hash().Bytes()); err != nil {
    47  		log.Error("Make prepare msg failed", "error", err)
    48  		return nil, fmt.Errorf("makePrepareMsg, error: %s", err)
    49  	} else {
    50  		msg.PrepareSig = make([]byte, len(sig))
    51  		copy(msg.PrepareSig, sig)
    52  		return msg, nil
    53  	}
    54  }
    55  
    56  func (bft *BftManager) makeCommitMsg(prePreMsg *types.PreprepareMsg) (*types.CommitMsg, error) {
    57  	msg := &types.CommitMsg{
    58  		Round:       prePreMsg.Round,
    59  		Commiter:    bft.coinBase,
    60  		BlockNumber: prePreMsg.Block.Number(),
    61  		BlockHash:   prePreMsg.Block.Hash(),
    62  		CommitSig:   nil,
    63  	}
    64  
    65  	if sig, err := bft.dp.signFn(accounts.Account{Address: bft.coinBase}, msg.Hash().Bytes()); err != nil {
    66  		log.Error("Make commit msg failed", "error", err)
    67  		return nil, fmt.Errorf("makeCommitMsg, error: %s", err)
    68  	} else {
    69  		msg.CommitSig = make([]byte, len(sig))
    70  		copy(msg.CommitSig, sig)
    71  		return msg, nil
    72  	}
    73  }
    74  
    75  func (bft *BftManager) verifyPrePrepareMsg(msg *types.PreprepareMsg) error {
    76  	// Nothing to verify
    77  	return nil
    78  }
    79  
    80  func (bft *BftManager) verifyPrepareMsg(msg *types.PrepareMsg) error {
    81  	var emptyHash common.Hash
    82  	if msg.BlockHash == emptyHash {
    83  		return fmt.Errorf("prepare msg's block hash is empty")
    84  	}
    85  
    86  	// Sender is witness
    87  	if !bft.validWitness(msg.PrepareAddr) {
    88  		return fmt.Errorf("prepare sender is not witness: %s", msg.PrepareAddr.String())
    89  	}
    90  
    91  	// Verify signature
    92  	data := msg.Hash().Bytes()
    93  	if !bft.verifySig(msg.PrepareAddr, data, msg.PrepareSig) {
    94  		return fmt.Errorf("prepare smg signature is invalid")
    95  	}
    96  
    97  	return nil
    98  }
    99  
   100  func (bft *BftManager) verifyCommitMsg(msg *types.CommitMsg) error {
   101  	var emptyHash common.Hash
   102  	if msg.BlockHash == emptyHash {
   103  		return fmt.Errorf("commit msg's block hash is empty")
   104  	}
   105  
   106  	// Sender is witness
   107  	if !bft.validWitness(msg.Commiter) {
   108  		return fmt.Errorf("commiter is not witness: %s", msg.Commiter.String())
   109  	}
   110  
   111  	// Verify signature
   112  	data := msg.Hash().Bytes()
   113  	if !bft.verifySig(msg.Commiter, data, msg.CommitSig) {
   114  		return fmt.Errorf("commiter signature is invalid")
   115  	}
   116  
   117  	// Other
   118  	return nil
   119  }
   120  
   121  func (bft *BftManager) VerifyCmtMsgOf(block *types.Block) error {
   122  	cmtMsges := block.CmtMsges()
   123  	if len(cmtMsges) < bft.quorum {
   124  		return fmt.Errorf("too less commit msg, len = %d", len(cmtMsges))
   125  	}
   126  
   127  	// Build witness cache
   128  	witCaches := make(map[common.Address]struct{})
   129  	for _, wit := range block.Witnesses() {
   130  		witCaches[wit] = struct{}{}
   131  	}
   132  
   133  	// Check each commit msg
   134  	for _, m := range cmtMsges {
   135  		if block.Hash() != m.BlockHash {
   136  			return errors.New("commit msg hash not match with block hash")
   137  		}
   138  
   139  		if _, ok := witCaches[m.Commiter]; !ok {
   140  			return errors.New("committer is not a valid witness")
   141  		}
   142  
   143  		if !bft.verifySig(m.Commiter, m.Hash().Bytes(), m.CommitSig) {
   144  			return errors.New("commit msg's signature is error")
   145  		}
   146  	}
   147  
   148  	return nil
   149  }
   150  
   151  func (bft *BftManager) verifySig(sender common.Address, data []byte, sig []byte) bool {
   152  	pubkey, err := crypto.Ecrecover(data, sig)
   153  	if err != nil {
   154  		return false
   155  	}
   156  	var signer common.Address
   157  	copy(signer[:], crypto.Keccak256(pubkey[1:])[12:])
   158  	return sender == signer
   159  }