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 }