aboutsummaryrefslogtreecommitdiffstats
path: root/miner
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2018-08-23 20:44:27 +0800
committerPéter Szilágyi <peterke@gmail.com>2018-08-23 20:44:27 +0800
commit1136269a79e6ee8bc97f5bf277bf8ec12286b79b (patch)
tree958598e13e11292c21896c105c649560c760ba5d /miner
parent67d6d0bb7d0e9b18334d45e2d811f00746320d65 (diff)
downloaddexon-1136269a79e6ee8bc97f5bf277bf8ec12286b79b.tar.gz
dexon-1136269a79e6ee8bc97f5bf277bf8ec12286b79b.tar.zst
dexon-1136269a79e6ee8bc97f5bf277bf8ec12286b79b.zip
miner: differentiate between uncle and lost block
Diffstat (limited to 'miner')
-rw-r--r--miner/unconfirmed.go35
-rw-r--r--miner/unconfirmed_test.go13
-rw-r--r--miner/worker.go2
3 files changed, 36 insertions, 14 deletions
diff --git a/miner/unconfirmed.go b/miner/unconfirmed.go
index 7a4fc7cc5..3eb29bc70 100644
--- a/miner/unconfirmed.go
+++ b/miner/unconfirmed.go
@@ -25,11 +25,14 @@ import (
"github.com/ethereum/go-ethereum/log"
)
-// headerRetriever is used by the unconfirmed block set to verify whether a previously
+// chainRetriever is used by the unconfirmed block set to verify whether a previously
// mined block is part of the canonical chain or not.
-type headerRetriever interface {
+type chainRetriever interface {
// GetHeaderByNumber retrieves the canonical header associated with a block number.
GetHeaderByNumber(number uint64) *types.Header
+
+ // GetBlockByNumber retrieves the canonical block associated with a block number.
+ GetBlockByNumber(number uint64) *types.Block
}
// unconfirmedBlock is a small collection of metadata about a locally mined block
@@ -44,14 +47,14 @@ type unconfirmedBlock struct {
// used by the miner to provide logs to the user when a previously mined block
// has a high enough guarantee to not be reorged out of the canonical chain.
type unconfirmedBlocks struct {
- chain headerRetriever // Blockchain to verify canonical status through
- depth uint // Depth after which to discard previous blocks
- blocks *ring.Ring // Block infos to allow canonical chain cross checks
- lock sync.RWMutex // Protects the fields from concurrent access
+ chain chainRetriever // Blockchain to verify canonical status through
+ depth uint // Depth after which to discard previous blocks
+ blocks *ring.Ring // Block infos to allow canonical chain cross checks
+ lock sync.RWMutex // Protects the fields from concurrent access
}
// newUnconfirmedBlocks returns new data structure to track currently unconfirmed blocks.
-func newUnconfirmedBlocks(chain headerRetriever, depth uint) *unconfirmedBlocks {
+func newUnconfirmedBlocks(chain chainRetriever, depth uint) *unconfirmedBlocks {
return &unconfirmedBlocks{
chain: chain,
depth: depth,
@@ -103,7 +106,23 @@ func (set *unconfirmedBlocks) Shift(height uint64) {
case header.Hash() == next.hash:
log.Info("🔗 block reached canonical chain", "number", next.index, "hash", next.hash)
default:
- log.Info("⑂ block became a side fork", "number", next.index, "hash", next.hash)
+ // Block is not canonical, check whether we have an uncle or a lost block
+ included := false
+ for number := next.index; !included && number < next.index+uint64(set.depth) && number <= height; number++ {
+ if block := set.chain.GetBlockByNumber(number); block != nil {
+ for _, uncle := range block.Uncles() {
+ if uncle.Hash() == next.hash {
+ included = true
+ break
+ }
+ }
+ }
+ }
+ if included {
+ log.Info("⑂ block became an uncle", "number", next.index, "hash", next.hash)
+ } else {
+ log.Info("😱 block lost", "number", next.index, "hash", next.hash)
+ }
}
// Drop the block out of the ring
if set.blocks.Value == set.blocks.Next().Value {
diff --git a/miner/unconfirmed_test.go b/miner/unconfirmed_test.go
index 456af1764..42e77f3e6 100644
--- a/miner/unconfirmed_test.go
+++ b/miner/unconfirmed_test.go
@@ -23,11 +23,14 @@ import (
"github.com/ethereum/go-ethereum/core/types"
)
-// noopHeaderRetriever is an implementation of headerRetriever that always
+// noopChainRetriever is an implementation of headerRetriever that always
// returns nil for any requested headers.
-type noopHeaderRetriever struct{}
+type noopChainRetriever struct{}
-func (r *noopHeaderRetriever) GetHeaderByNumber(number uint64) *types.Header {
+func (r *noopChainRetriever) GetHeaderByNumber(number uint64) *types.Header {
+ return nil
+}
+func (r *noopChainRetriever) GetBlockByNumber(number uint64) *types.Block {
return nil
}
@@ -36,7 +39,7 @@ func (r *noopHeaderRetriever) GetHeaderByNumber(number uint64) *types.Header {
func TestUnconfirmedInsertBounds(t *testing.T) {
limit := uint(10)
- pool := newUnconfirmedBlocks(new(noopHeaderRetriever), limit)
+ pool := newUnconfirmedBlocks(new(noopChainRetriever), limit)
for depth := uint64(0); depth < 2*uint64(limit); depth++ {
// Insert multiple blocks for the same level just to stress it
for i := 0; i < int(depth); i++ {
@@ -58,7 +61,7 @@ func TestUnconfirmedShifts(t *testing.T) {
// Create a pool with a few blocks on various depths
limit, start := uint(10), uint64(25)
- pool := newUnconfirmedBlocks(new(noopHeaderRetriever), limit)
+ pool := newUnconfirmedBlocks(new(noopChainRetriever), limit)
for depth := start; depth < start+uint64(limit); depth++ {
pool.Insert(depth, common.Hash([32]byte{byte(depth)}))
}
diff --git a/miner/worker.go b/miner/worker.go
index 8c3337ba4..cedc158b5 100644
--- a/miner/worker.go
+++ b/miner/worker.go
@@ -55,7 +55,7 @@ const (
resubmitAdjustChanSize = 10
// miningLogAtDepth is the number of confirmations before logging successful mining.
- miningLogAtDepth = 5
+ miningLogAtDepth = 7
// minRecommitInterval is the minimal time interval to recreate the mining block with
// any newly arrived transactions.