"github.com/vapor/protocol/bc"
"github.com/vapor/protocol/bc/types"
"github.com/vapor/protocol/state"
+ "github.com/vapor/crypto/ed25519/chainkd"
)
const (
}
}
-// IsConsensusPubkey determine whether a public key is a consensus node at a specified height
-func (b *bbft) IsConsensusPubkey(blockHash *bc.Hash, pubkey []byte) (bool, error) {
- node, err := b.consensusNodeManager.getConsensusNode(blockHash, hex.EncodeToString(pubkey))
- if err != nil && err != errNotFoundConsensusNode {
- return false, err
- }
- return node != nil, nil
-}
-
func (b *bbft) isIrreversible(block *types.Block) bool {
signNum, err := b.validateSign(block)
if err != nil {
return false
}
- return signNum > (numOfConsensusNode * 2 / 3)
+ return signNum > (NumOfConsensusNode * 2 / 3)
}
// NextLeaderTime returns the start time of the specified public key as the next leader node
}
// ProcessBlockSignature process the received block signature messages
-// return once a block become irreversible, whether it's height greater than best block height
-// if so, the chain module must update status
-func (b *bbft) ProcessBlockSignature(signature, pubkey []byte, blockHeight uint64, blockHash *bc.Hash) (bool, error) {
- consensusNode, err := b.consensusNodeManager.getConsensusNode(blockHash, hex.EncodeToString(pubkey))
+// return whether a block become irreversible, if so, the chain module must update status
+func (b *bbft) ProcessBlockSignature(signature []byte, xPub [64]byte, blockHeight uint64, blockHash *bc.Hash) (bool, error) {
+ block, err := b.consensusNodeManager.store.GetBlock(blockHash)
+ if err != nil {
+ // block is not exist, save the signature
+ key := fmt.Sprintf("%s:%s", blockHash.String(), hex.EncodeToString(xPub[:]))
+ b.signatureCache.Add(key, signature)
+ return false, err
+ }
+
+ consensusNode, err := b.consensusNodeManager.getConsensusNode(&block.PreviousBlockHash, hex.EncodeToString(xPub[:]))
if err != nil {
return false, err
}
- if !ed25519.Verify(ed25519.PublicKey(pubkey), blockHash.Bytes(), signature) {
+
+ if chainkd.XPub(xPub).Verify(blockHash.Bytes(), signature) {
return false, errInvalidSignature
}
}
if isDoubleSign {
- log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubkey": pubkey}).Warn("the consensus node double sign the same height of different block")
+ log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "xPub": hex.EncodeToString(xPub[:])}).Warn("the consensus node double sign the same height of different block")
return false, errDoubleSignBlock
}
return false, nil
}
- block, err := b.consensusNodeManager.store.GetBlock(blockHash)
- if err != nil {
- // block is not exist, save the signature
- key := fmt.Sprintf("%s:%s", blockHash.String(), hex.EncodeToString(pubkey))
- b.signatureCache.Add(key, signature)
- return false, err
- }
-
if err := b.updateBlockSignature(block, consensusNode.order, signature); err != nil {
return false, err
}
- return b.isIrreversible(block) && blockHeight > b.consensusNodeManager.blockIndex.BestNode().Height, nil
+ return b.isIrreversible(block), nil
}
// ValidateBlock verify whether the block is valid
// if the block has not the signature of blocker, it will return error
func (b *bbft) validateSign(block *types.Block) (uint64, error) {
var correctSignNum uint64
- blockHash := block.Hash()
- consensusNodeMap, err := b.consensusNodeManager.getConsensusNodesByVoteResult(&blockHash)
+ consensusNodeMap, err := b.consensusNodeManager.getConsensusNodesByVoteResult(&block.PreviousBlockHash)
if err != nil {
return 0, err
}
hasBlockerSign := false
- for pubkey, node := range consensusNodeMap {
+ for pubKey, node := range consensusNodeMap {
if len(block.Witness) <= int(node.order) {
continue
}
blockHash := block.Hash()
if block.Witness[node.order] == nil {
- key := fmt.Sprintf("%s:%s", blockHash.String(), pubkey)
+ key := fmt.Sprintf("%s:%s", blockHash.String(), pubKey)
signature, ok := b.signatureCache.Get(key)
if ok {
block.Witness[node.order] = signature.([]byte)
}
}
- if ed25519.Verify(ed25519.PublicKey(pubkey), blockHash.Bytes(), block.Witness[node.order]) {
+ pubKeyBytes, err := hex.DecodeString(pubKey)
+ if err != nil {
+ return 0, err
+ }
+
+ if ed25519.Verify(ed25519.PublicKey(pubKeyBytes[:32]), blockHash.Bytes(), block.Witness[node.order]) {
isDoubleSign, err := b.checkDoubleSign(node.order, block.Height, block.Hash())
if err != nil {
return 0, err
}
if isDoubleSign {
- log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubkey": pubkey}).Warn("the consensus node double sign the same height of different block")
+ log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubKey": pubKey}).Warn("the consensus node double sign the same height of different block")
// Consensus node is signed twice with the same block height, discard the signature
block.Witness[node.order] = nil
} else {
correctSignNum++
- isBlocker, err := b.consensusNodeManager.isBlocker(&blockHash, pubkey)
+ isBlocker, err := b.consensusNodeManager.isBlocker(block, pubKey)
if err != nil {
return 0, err
}
func (b *bbft) SignBlock(block *types.Block) ([]byte, error) {
xprv := config.CommonConfig.PrivateKey()
xpub := [64]byte(xprv.XPub())
- blockHash := block.Hash()
- node, err := b.consensusNodeManager.getConsensusNode(&blockHash, hex.EncodeToString(xpub[:]))
+ node, err := b.consensusNodeManager.getConsensusNode(&block.PreviousBlockHash, hex.EncodeToString(xpub[:]))
if err != nil && err != errNotFoundConsensusNode {
return nil, err
}
return nil, nil
}
- signature := xprv.Sign(block.Hash().Bytes())
- block.Witness[node.order] = signature
+ signature := block.Witness[node.order]
+ if len(signature) == 0 {
+ signature = xprv.Sign(block.Hash().Bytes())
+ block.Witness[node.order] = signature
+ }
return signature, nil
}