import (
"sync"
+ "github.com/golang/groupcache/lru"
log "github.com/sirupsen/logrus"
"github.com/vapor/config"
- engine "github.com/vapor/consensus/consensus"
- dpos "github.com/vapor/consensus/consensus/dpos"
- "github.com/vapor/errors"
+ "github.com/vapor/event"
"github.com/vapor/protocol/bc"
"github.com/vapor/protocol/bc/types"
"github.com/vapor/protocol/state"
store Store
processBlockCh chan *processBlockMsg
- cond sync.Cond
- bestNode *state.BlockNode
- Engine engine.Engine
+ consensusNodeManager *consensusNodeManager
+ signatureCache *lru.Cache
+ eventDispatcher *event.Dispatcher
+
+ cond sync.Cond
+ bestNode *state.BlockNode
+ bestIrreversibleNode *state.BlockNode
}
// NewChain returns a new Chain using store as the underlying storage.
-func NewChain(store Store, txPool *TxPool) (*Chain, error) {
-
- var engine engine.Engine
- switch config.CommonConfig.Consensus.Type {
- case "dpos":
- engine = dpos.GDpos
- }
-
+func NewChain(store Store, txPool *TxPool, eventDispatcher *event.Dispatcher) (*Chain, error) {
c := &Chain{
- orphanManage: NewOrphanManage(),
- txPool: txPool,
- store: store,
- processBlockCh: make(chan *processBlockMsg, maxProcessBlockChSize),
- Engine: engine,
+ orphanManage: NewOrphanManage(),
+ txPool: txPool,
+ store: store,
+ signatureCache: lru.New(maxSignatureCacheSize),
+ consensusNodeManager: newConsensusNodeManager(store, nil),
+ eventDispatcher: eventDispatcher,
+ processBlockCh: make(chan *processBlockMsg, maxProcessBlockChSize),
}
c.cond.L = new(sync.Mutex)
}
c.bestNode = c.index.GetNode(storeStatus.Hash)
+ c.bestIrreversibleNode = c.index.GetNode(storeStatus.IrreversibleHash)
c.index.SetMainChain(c.bestNode)
+ c.consensusNodeManager.blockIndex = c.index
go c.blockProcesser()
return c, nil
}
return err
}
+ voteResultMap := make(map[uint64]*state.VoteResult)
+ if err := c.ApplyBlock(voteResultMap, genesisBlock); err != nil {
+ return err
+ }
+
node, err := state.NewBlockNode(&genesisBlock.BlockHeader, nil)
if err != nil {
return err
}
- return c.store.SaveChainStatus(node, utxoView)
+
+ return c.store.SaveChainStatus(node, node, utxoView, voteResultMap)
}
// BestBlockHeight returns the current height of the blockchain.
return c.index.InMainchain(hash)
}
-// CalcNextSeed return the seed for the given block
-func (c *Chain) CalcNextSeed(preBlock *bc.Hash) (*bc.Hash, error) {
- node := c.index.GetNode(preBlock)
- if node == nil {
- return nil, errors.New("can't find preblock in the blockindex")
- }
- return node.CalcNextSeed(), nil
-}
-
-// CalcNextBits return the seed for the given block
-func (c *Chain) CalcNextBits(preBlock *bc.Hash) (uint64, error) {
- node := c.index.GetNode(preBlock)
- if node == nil {
- return 0, errors.New("can't find preblock in the blockindex")
- }
- return node.CalcNextBits(), nil
-}
-
// This function must be called with mu lock in above level
-func (c *Chain) setState(node *state.BlockNode, view *state.UtxoViewpoint) error {
- if err := c.store.SaveChainStatus(node, view); err != nil {
+func (c *Chain) setState(node *state.BlockNode, irreversibleNode *state.BlockNode, view *state.UtxoViewpoint, voteMap map[uint64]*state.VoteResult) error {
+ if err := c.store.SaveChainStatus(node, irreversibleNode, view, voteMap); err != nil {
return err
}
c.index.SetMainChain(node)
c.bestNode = node
+ c.bestIrreversibleNode = irreversibleNode
- log.WithFields(log.Fields{"height": c.bestNode.Height, "hash": c.bestNode.Hash.String()}).Debug("chain best status has been update")
+ log.WithFields(log.Fields{"module": logModule, "height": c.bestNode.Height, "hash": c.bestNode.Hash.String()}).Debug("chain best status has been update")
c.cond.Broadcast()
return nil
}