import (
log "github.com/sirupsen/logrus"
+ "github.com/vapor/config"
"github.com/vapor/errors"
"github.com/vapor/event"
- "github.com/vapor/config"
"github.com/vapor/protocol/bc"
"github.com/vapor/protocol/bc/types"
"github.com/vapor/protocol/state"
ErrBadBlock = errors.New("invalid block")
// ErrBadStateRoot is returned when the computed assets merkle root
// disagrees with the one declared in a block header.
- ErrBadStateRoot = errors.New("invalid state merkle root")
+ ErrBadStateRoot = errors.New("invalid state merkle root")
+ errBelowIrreversibleBlock = errors.New("the height of block below the height of irreversible block")
)
// BlockExist check is a block in chain or orphan
return err
}
- voteResultMap := make(map[uint64]*state.VoteResult)
- if err := c.bbft.ApplyBlock(voteResultMap, block); err != nil {
+ voteResult, err := c.consensusNodeManager.getBestVoteResult()
+ if err != nil {
+ return err
+ }
+ if err := voteResult.ApplyBlock(block); err != nil {
return err
}
node := c.index.GetNode(&bcBlock.ID)
- if c.bbft.isIrreversible(block) && block.Height > irreversibleNode.Height {
+ if c.isIrreversible(node) && block.Height > irreversibleNode.Height {
irreversibleNode = node
}
- if err := c.setState(node, irreversibleNode, utxoView, voteResultMap); err != nil {
+ if err := c.setState(node, irreversibleNode, utxoView, []*state.VoteResult{voteResult}); err != nil {
return err
}
func (c *Chain) reorganizeChain(node *state.BlockNode) error {
attachNodes, detachNodes := c.calcReorganizeNodes(node)
utxoView := state.NewUtxoViewpoint()
- voteResultMap := make(map[uint64]*state.VoteResult)
+ voteResults := []*state.VoteResult{}
irreversibleNode := c.bestIrreversibleNode
+ voteResult, err := c.consensusNodeManager.getBestVoteResult()
+ if err != nil {
+ return err
+ }
for _, detachNode := range detachNodes {
b, err := c.store.GetBlock(&detachNode.Hash)
return err
}
- if err := c.bbft.DetachBlock(voteResultMap, b); err != nil {
+ if err := voteResult.DetachBlock(b); err != nil {
return err
}
return err
}
- if err := c.bbft.ApplyBlock(voteResultMap, b); err != nil {
+ if err := voteResult.ApplyBlock(b); err != nil {
return err
}
- if c.bbft.isIrreversible(b) && b.Height > irreversibleNode.Height {
+ if voteResult.IsFinalize() {
+ voteResults = append(voteResults, voteResult.Fork())
+ }
+
+ if c.isIrreversible(attachNode) && b.Height > irreversibleNode.Height {
irreversibleNode = attachNode
}
log.WithFields(log.Fields{"module": logModule, "height": node.Height, "hash": node.Hash.String()}).Debug("attach from mainchain")
}
- return c.setState(node, irreversibleNode, utxoView, voteResultMap)
+ voteResults = append(voteResults, voteResult.Fork())
+ return c.setState(node, irreversibleNode, utxoView, voteResults)
}
// SaveBlock will validate and save block into storage
func (c *Chain) saveBlock(block *types.Block) error {
- if err := c.bbft.ValidateBlock(block); err != nil {
+ if _, err := c.validateSign(block); err != nil {
return errors.Sub(ErrBadBlock, err)
}
return errors.Sub(ErrBadBlock, err)
}
- signature, err := c.bbft.SignBlock(block)
+ signature, err := c.SignBlock(block)
if err != nil {
return errors.Sub(ErrBadBlock, err)
}
if len(signature) != 0 {
xPub := config.CommonConfig.PrivateKey().XPub()
- if err := c.bbft.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: block.Hash(), Signature: signature, XPub: xPub}); err != nil {
+ if err := c.eventDispatcher.Post(event.BlockSignatureEvent{BlockHash: block.Hash(), Signature: signature, XPub: xPub}); err != nil {
return err
}
}
// ProcessBlock is the entry for handle block insert
func (c *Chain) processBlock(block *types.Block) (bool, error) {
+ blockHash := block.Hash()
if block.Height <= c.bestIrreversibleNode.Height {
- return false, errors.New("the height of block below the height of irreversible block")
+ log.WithFields(log.Fields{"module": logModule, "hash": blockHash.String(), "height": block.Height}).Info(errBelowIrreversibleBlock.Error())
+ return false, errBelowIrreversibleBlock
}
- blockHash := block.Hash()
if c.BlockExist(&blockHash) {
log.WithFields(log.Fields{"module": logModule, "hash": blockHash.String(), "height": block.Height}).Info("block has been processed")
return c.orphanManage.BlockExist(&blockHash), nil
}
- parent := c.index.GetNode(&block.PreviousBlockHash)
- if parent == nil {
+ if parent := c.index.GetNode(&block.PreviousBlockHash); parent == nil {
c.orphanManage.Add(block)
return true, nil
}
- forkPointBlock := parent
- for !c.index.InMainchain(forkPointBlock.Hash) {
- forkPointBlock = forkPointBlock.Parent
- }
- if forkPointBlock.Height < c.bestIrreversibleNode.Height {
- return false, errors.New("the block impossible to be block of main chain")
- }
-
if err := c.saveBlock(block); err != nil {
return false, err
}
}
return false, nil
}
-
-func (c *Chain) ProcessBlockSignature(signature []byte, xPub [64]byte, blockHeight uint64, blockHash *bc.Hash) error {
- isIrreversible, err := c.bbft.ProcessBlockSignature(signature, xPub, blockHeight, blockHash)
- if err != nil {
- return err
- }
-
- if isIrreversible && blockHeight > c.bestIrreversibleNode.Height {
- bestIrreversibleNode := c.index.GetNode(blockHash)
- if err := c.store.SaveChainNodeStatus(c.bestNode, bestIrreversibleNode); err != nil {
- return err
- }
-
- c.bestIrreversibleNode = bestIrreversibleNode
- }
- return nil
-}