miner/worker: broadcast block immediately once sealed (#2576)
This commit is contained in:
parent
d35b57ae36
commit
6d5b4ad64d
@ -1908,26 +1908,30 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
|||||||
|
|
||||||
// WriteBlockAndSetHead writes the given block and all associated state to the database,
|
// WriteBlockAndSetHead writes the given block and all associated state to the database,
|
||||||
// and applies the block as the new chain head.
|
// and applies the block as the new chain head.
|
||||||
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
|
func (bc *BlockChain) WriteBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, mux *event.TypeMux) (status WriteStatus, err error) {
|
||||||
if !bc.chainmu.TryLock() {
|
if !bc.chainmu.TryLock() {
|
||||||
return NonStatTy, errChainStopped
|
return NonStatTy, errChainStopped
|
||||||
}
|
}
|
||||||
defer bc.chainmu.Unlock()
|
defer bc.chainmu.Unlock()
|
||||||
|
|
||||||
return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent)
|
return bc.writeBlockAndSetHead(block, receipts, logs, state, emitHeadEvent, mux)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
|
// writeBlockAndSetHead is the internal implementation of WriteBlockAndSetHead.
|
||||||
// This function expects the chain mutex to be held.
|
// This function expects the chain mutex to be held.
|
||||||
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool) (status WriteStatus, err error) {
|
func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types.Receipt, logs []*types.Log, state *state.StateDB, emitHeadEvent bool, mux *event.TypeMux) (status WriteStatus, err error) {
|
||||||
if err := bc.writeBlockWithState(block, receipts, state); err != nil {
|
|
||||||
return NonStatTy, err
|
|
||||||
}
|
|
||||||
currentBlock := bc.CurrentBlock()
|
currentBlock := bc.CurrentBlock()
|
||||||
reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock, block.Header())
|
reorg, err := bc.forker.ReorgNeededWithFastFinality(currentBlock, block.Header())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return NonStatTy, err
|
return NonStatTy, err
|
||||||
}
|
}
|
||||||
|
if reorg && mux != nil {
|
||||||
|
mux.Post(NewSealedBlockEvent{Block: block})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := bc.writeBlockWithState(block, receipts, state); err != nil {
|
||||||
|
return NonStatTy, err
|
||||||
|
}
|
||||||
if reorg {
|
if reorg {
|
||||||
// Reorganise the chain if the parent is not the head block
|
// Reorganise the chain if the parent is not the head block
|
||||||
if block.ParentHash() != currentBlock.Hash() {
|
if block.ParentHash() != currentBlock.Hash() {
|
||||||
@ -2300,7 +2304,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool) (int, error)
|
|||||||
// Don't set the head, only insert the block
|
// Don't set the head, only insert the block
|
||||||
err = bc.writeBlockWithState(block, receipts, statedb)
|
err = bc.writeBlockWithState(block, receipts, statedb)
|
||||||
} else {
|
} else {
|
||||||
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false)
|
status, err = bc.writeBlockAndSetHead(block, receipts, logs, statedb, false, nil)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it.index, err
|
return it.index, err
|
||||||
|
@ -27,7 +27,10 @@ type NewTxsEvent struct{ Txs []*types.Transaction }
|
|||||||
// ReannoTxsEvent is posted when a batch of local pending transactions exceed a specified duration.
|
// ReannoTxsEvent is posted when a batch of local pending transactions exceed a specified duration.
|
||||||
type ReannoTxsEvent struct{ Txs []*types.Transaction }
|
type ReannoTxsEvent struct{ Txs []*types.Transaction }
|
||||||
|
|
||||||
// NewMinedBlockEvent is posted when a block has been imported.
|
// NewSealedBlockEvent is posted when a block has been sealed.
|
||||||
|
type NewSealedBlockEvent struct{ Block *types.Block }
|
||||||
|
|
||||||
|
// NewMinedBlockEvent is posted when a block has been mined.
|
||||||
type NewMinedBlockEvent struct{ Block *types.Block }
|
type NewMinedBlockEvent struct{ Block *types.Block }
|
||||||
|
|
||||||
// RemovedLogsEvent is posted when a reorg happens
|
// RemovedLogsEvent is posted when a reorg happens
|
||||||
|
@ -729,7 +729,7 @@ func (h *handler) Start(maxPeers int, maxPeersPerIP int) {
|
|||||||
|
|
||||||
// broadcast mined blocks
|
// broadcast mined blocks
|
||||||
h.wg.Add(1)
|
h.wg.Add(1)
|
||||||
h.minedBlockSub = h.eventMux.Subscribe(core.NewMinedBlockEvent{})
|
h.minedBlockSub = h.eventMux.Subscribe(core.NewMinedBlockEvent{}, core.NewSealedBlockEvent{})
|
||||||
go h.minedBroadcastLoop()
|
go h.minedBroadcastLoop()
|
||||||
|
|
||||||
// start sync handlers
|
// start sync handlers
|
||||||
@ -946,8 +946,9 @@ func (h *handler) minedBroadcastLoop() {
|
|||||||
if obj == nil {
|
if obj == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
if ev, ok := obj.Data.(core.NewSealedBlockEvent); ok {
|
||||||
h.BroadcastBlock(ev.Block, true) // First propagate block to peers
|
h.BroadcastBlock(ev.Block, true) // Propagate block to peers
|
||||||
|
} else if ev, ok := obj.Data.(core.NewMinedBlockEvent); ok {
|
||||||
h.BroadcastBlock(ev.Block, false) // Only then announce to the rest
|
h.BroadcastBlock(ev.Block, false) // Only then announce to the rest
|
||||||
}
|
}
|
||||||
case <-h.stopCh:
|
case <-h.stopCh:
|
||||||
|
@ -665,7 +665,7 @@ func (w *worker) resultLoop() {
|
|||||||
// Commit block and state to database.
|
// Commit block and state to database.
|
||||||
task.state.SetExpectedStateRoot(block.Root())
|
task.state.SetExpectedStateRoot(block.Root())
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
status, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true)
|
status, err := w.chain.WriteBlockAndSetHead(block, receipts, logs, task.state, true, w.mux)
|
||||||
if status != core.CanonStatTy {
|
if status != core.CanonStatTy {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed writing block to chain", "err", err, "status", status)
|
log.Error("Failed writing block to chain", "err", err, "status", status)
|
||||||
|
Loading…
Reference in New Issue
Block a user