aboutsummaryrefslogtreecommitdiffstats
path: root/core/consensus.go
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-09-20 16:08:08 +0800
committerGitHub <noreply@github.com>2018-09-20 16:08:08 +0800
commita4b6b9e6a28a4d8fc49ee76c191454a819265713 (patch)
tree716e5724b182b8dccb01a49faec4c163f1fafdb0 /core/consensus.go
parent2f1e71d9d298d1f6ade8d17a1db7a657b0223872 (diff)
downloaddexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar.gz
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar.bz2
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar.lz
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar.xz
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.tar.zst
dexon-consensus-a4b6b9e6a28a4d8fc49ee76c191454a819265713.zip
core: refactor witness data processing flow (#124)
Since witness data need to include data from application after it processed a block (e.g. stateRoot). We should make the process of witness data asynchronous. An interface `BlockProcessedChan()` is added to the application interface to return a channel for notifying the consensus core when a block is processed. The notification object includes a byte slice (witenss data) which will be include in the final witness data object.
Diffstat (limited to 'core/consensus.go')
-rw-r--r--core/consensus.go52
1 files changed, 42 insertions, 10 deletions
diff --git a/core/consensus.go b/core/consensus.go
index 1af66b3..33a3d7f 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -217,6 +217,8 @@ func (con *Consensus) Run() {
go con.runBA(i, tick)
}
go con.processMsg(con.network.ReceiveChan(), con.PreProcessBlock)
+ go con.processWitnessData()
+
// Reset ticker.
<-con.tickerObj.Tick()
<-con.tickerObj.Tick()
@@ -272,6 +274,7 @@ BALoop:
// RunLegacy starts running Legacy DEXON Consensus.
func (con *Consensus) RunLegacy() {
go con.processMsg(con.network.ReceiveChan(), con.ProcessBlock)
+ go con.processWitnessData()
chainID := uint32(0)
hashes := make(common.Hashes, 0, len(con.gov.GetNotarySet()))
@@ -383,6 +386,45 @@ func (con *Consensus) ProcessVote(vote *types.Vote) (err error) {
return err
}
+// processWitnessData process witness acks.
+func (con *Consensus) processWitnessData() {
+ ch := con.app.BlockProcessedChan()
+
+ for {
+ select {
+ case <-con.ctx.Done():
+ return
+ case result := <-ch:
+ block, err := con.db.Get(result.BlockHash)
+ if err != nil {
+ panic(err)
+ }
+
+ if err = con.ccModule.processWitnessResult(&block, result); err != nil {
+ panic(err)
+ }
+ if err := con.db.Update(block); err != nil {
+ panic(err)
+ }
+
+ // TODO(w): move the acking interval into governance.
+ if block.Witness.Height%5 != 0 {
+ continue
+ }
+
+ witnessAck, err := con.ccModule.prepareWitnessAck(&block, con.prvKey)
+ if err != nil {
+ panic(err)
+ }
+ err = con.ProcessWitnessAck(witnessAck)
+ if err != nil {
+ panic(err)
+ }
+ con.app.WitnessAckDeliver(witnessAck)
+ }
+ }
+}
+
// prepareVote prepares a vote.
func (con *Consensus) prepareVote(chainID uint32, vote *types.Vote) error {
return con.baModules[chainID].prepareVote(vote, con.prvKey)
@@ -482,16 +524,6 @@ func (con *Consensus) ProcessBlock(block *types.Block) (err error) {
// nonBlockingApplication and let them recycle the
// block.
}
- var witnessAck *types.WitnessAck
- witnessAck, err = con.ccModule.prepareWitnessAck(con.prvKey)
- if err != nil {
- return
- }
- err = con.ProcessWitnessAck(witnessAck)
- if err != nil {
- return
- }
- con.app.WitnessAckDeliver(witnessAck)
}
return
}