forked from ledgerwatch/erigon
/
stage_mining_finish.go
104 lines (91 loc) · 3.12 KB
/
stage_mining_finish.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package stagedsync
import (
"fmt"
"github.com/nebojsa94/erigon/erigon-lib/chain"
"github.com/nebojsa94/erigon/erigon-lib/kv"
"github.com/nebojsa94/erigon/turbo/builder"
"github.com/nebojsa94/erigon/turbo/services"
"github.com/ledgerwatch/log/v3"
"github.com/nebojsa94/erigon/consensus"
"github.com/nebojsa94/erigon/core/types"
)
type MiningFinishCfg struct {
db kv.RwDB
chainConfig chain.Config
engine consensus.Engine
sealCancel chan struct{}
miningState MiningState
blockReader services.FullBlockReader
latestBlockBuiltStore *builder.LatestBlockBuiltStore
}
func StageMiningFinishCfg(
db kv.RwDB,
chainConfig chain.Config,
engine consensus.Engine,
miningState MiningState,
sealCancel chan struct{},
blockReader services.FullBlockReader,
latestBlockBuiltStore *builder.LatestBlockBuiltStore,
) MiningFinishCfg {
return MiningFinishCfg{
db: db,
chainConfig: chainConfig,
engine: engine,
miningState: miningState,
sealCancel: sealCancel,
blockReader: blockReader,
latestBlockBuiltStore: latestBlockBuiltStore,
}
}
func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit <-chan struct{}, logger log.Logger) error {
logPrefix := s.LogPrefix()
current := cfg.miningState.MiningBlock
// Short circuit when receiving duplicate result caused by resubmitting.
//if w.chain.HasBlock(block.Hash(), block.NumberU64()) {
// continue
//}
block := types.NewBlock(current.Header, current.Txs, current.Uncles, current.Receipts, current.Withdrawals)
blockWithReceipts := &types.BlockWithReceipts{Block: block, Receipts: current.Receipts}
*current = MiningBlock{} // hack to clean global data
//sealHash := engine.SealHash(block.Header())
// Reject duplicate sealing work due to resubmitting.
//if sealHash == prev {
// s.Done()
// return nil
//}
//prev = sealHash
cfg.latestBlockBuiltStore.AddBlockBuilt(block)
if cfg.miningState.MiningResultPOSCh != nil {
cfg.miningState.MiningResultPOSCh <- blockWithReceipts
return nil
}
// Tests may set pre-calculated nonce
if block.NonceU64() != 0 {
// Note: To propose a new signer for Clique consensus, the block nonce should be set to 0xFFFFFFFFFFFFFFFF.
if cfg.engine.Type() != chain.CliqueConsensus {
cfg.miningState.MiningResultCh <- block
return nil
}
}
cfg.miningState.PendingResultCh <- block
if block.Transactions().Len() > 0 {
logger.Info(fmt.Sprintf("[%s] block ready for seal", logPrefix),
"block_num", block.NumberU64(),
"transactions", block.Transactions().Len(),
"gas_used", block.GasUsed(),
"gas_limit", block.GasLimit(),
"difficulty", block.Difficulty(),
)
}
// interrupt aborts the in-flight sealing task.
select {
case cfg.sealCancel <- struct{}{}:
default:
logger.Trace("No in-flight sealing task.")
}
chain := ChainReader{Cfg: cfg.chainConfig, Db: tx, BlockReader: cfg.blockReader}
if err := cfg.engine.Seal(chain, block, cfg.miningState.MiningResultCh, cfg.sealCancel); err != nil {
logger.Warn("Block sealing failed", "err", err)
}
return nil
}