+// 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(blockHeight, hex.EncodeToString(pubkey))
+ if err != nil {
+ return false, err
+ }
+
+ if !ed25519.Verify(ed25519.PublicKey(pubkey), blockHash.Bytes(), signature) {
+ return false, errInvalidSignature
+ }
+
+ isDoubleSign, err := b.checkDoubleSign(consensusNode.order, blockHeight, *blockHash)
+ if err != nil {
+ return false, 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")
+ return false, errDoubleSignBlock
+ }
+
+ orphanBlock, ok := b.orphanManage.Get(blockHash)
+ if ok {
+ orphanBlock.Witness[consensusNode.order] = signature
+ 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
+}
+