OSDN Git Service

Mov (#518)
[bytom/vapor.git] / protocol / bbft.go
index 888ce99..06b4859 100644 (file)
@@ -6,13 +6,13 @@ import (
 
        log "github.com/sirupsen/logrus"
 
-       "github.com/vapor/config"
-       "github.com/vapor/crypto/ed25519/chainkd"
-       "github.com/vapor/errors"
-       "github.com/vapor/event"
-       "github.com/vapor/protocol/bc"
-       "github.com/vapor/protocol/bc/types"
-       "github.com/vapor/protocol/state"
+       "github.com/bytom/vapor/config"
+       "github.com/bytom/vapor/crypto/ed25519/chainkd"
+       "github.com/bytom/vapor/errors"
+       "github.com/bytom/vapor/event"
+       "github.com/bytom/vapor/protocol/bc"
+       "github.com/bytom/vapor/protocol/bc/types"
+       "github.com/bytom/vapor/protocol/state"
 )
 
 const (
@@ -133,7 +133,7 @@ func (c *Chain) validateSign(block *types.Block) error {
                        cachekey := signCacheKey(blockHash.String(), pubKey)
                        if signature, ok := c.signatureCache.Get(cachekey); ok {
                                block.Set(node.Order, signature.([]byte))
-                               c.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: blockHash, Signature: signature.([]byte), XPub: []byte(pubKey)})
+                               c.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: blockHash, Signature: signature.([]byte), XPub: node.XPub[:]})
                                c.signatureCache.Remove(cachekey)
                        } else {
                                continue
@@ -142,8 +142,13 @@ func (c *Chain) validateSign(block *types.Block) error {
 
                if err := c.checkNodeSign(&block.BlockHeader, node, block.Get(node.Order)); err == errDoubleSignBlock {
                        log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String(), "pubKey": pubKey}).Warn("the consensus node double sign the same height of different block")
-                       block.BlockWitness.Delete(node.Order)
-                       continue
+                       // if the blocker double sign & become the mainchain, that means
+                       // all the side chain will reject the main chain make the chain
+                       // fork. All the node will ban each other & can't roll back
+                       if blocker != pubKey {
+                               block.BlockWitness.Delete(node.Order)
+                               continue
+                       }
                } else if err != nil {
                        return err
                }
@@ -168,7 +173,7 @@ func (c *Chain) ProcessBlockSignature(signature, xPub []byte, blockHash *bc.Hash
        // save the signature if the block is not exist
        if blockHeader == nil {
                var xPubKey chainkd.XPub
-               copy(xPub[:], xPub[:])
+               copy(xPubKey[:], xPub[:])
                if !xPubKey.Verify(blockHash.Bytes(), signature) {
                        return errInvalidSignature
                }
@@ -199,27 +204,54 @@ func (c *Chain) ProcessBlockSignature(signature, xPub []byte, blockHash *bc.Hash
        return c.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: *blockHash, Signature: signature, XPub: xPub})
 }
 
-// SignBlock signing the block if current node is consensus node
-func (c *Chain) SignBlock(block *types.Block) ([]byte, error) {
+// SignBlockHeader signing the block if current node is consensus node
+func (c *Chain) SignBlockHeader(blockHeader *types.BlockHeader) error {
+       _, err := c.signBlockHeader(blockHeader)
+       return err
+}
+
+func (c *Chain) applyBlockSign(blockHeader *types.BlockHeader) error {
+       signature, err := c.signBlockHeader(blockHeader)
+       if err != nil {
+               return err
+       }
+
+       if len(signature) == 0 {
+               return nil
+       }
+
+       if err := c.store.SaveBlockHeader(blockHeader); err != nil {
+               return err
+       }
+
+       xpub := config.CommonConfig.PrivateKey().XPub()
+       return c.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: blockHeader.Hash(), Signature: signature, XPub: xpub[:]})
+}
+
+func (c *Chain) signBlockHeader(blockHeader *types.BlockHeader) ([]byte, error) {
        xprv := config.CommonConfig.PrivateKey()
-       xpubStr := xprv.XPub().String()
-       node, err := c.getConsensusNode(&block.PreviousBlockHash, xpubStr)
+       xpub := xprv.XPub()
+       node, err := c.getConsensusNode(&blockHeader.PreviousBlockHash, xpub.String())
+       blockHash := blockHeader.Hash()
        if err == errNotFoundConsensusNode {
+               log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String()}).Debug("can't find consensus node of current node")
                return nil, nil
        } else if err != nil {
                return nil, err
        }
 
-       if err := c.checkDoubleSign(&block.BlockHeader, node.XPub.String()); err == errDoubleSignBlock {
+       if len(blockHeader.Get(node.Order)) != 0 {
+               return nil, nil
+       }
+
+       if err := c.checkDoubleSign(blockHeader, node.XPub.String()); err == errDoubleSignBlock {
+               log.WithFields(log.Fields{"module": logModule, "blockHash": blockHash.String()}).Warn("current node has double sign the block")
                return nil, nil
        } else if err != nil {
                return nil, err
        }
 
-       signature := block.Get(node.Order)
-       if len(signature) == 0 {
-               signature = xprv.Sign(block.Hash().Bytes())
-               block.Set(node.Order, signature)
-       }
+       signature := xprv.Sign(blockHeader.Hash().Bytes())
+       blockHeader.Set(node.Order, signature)
        return signature, nil
 }