diff options
author | Péter Szilágyi <peterke@gmail.com> | 2018-08-23 21:03:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-23 21:03:10 +0800 |
commit | c134e00e488bf4bfd88689ecf6b91ee351fb77e5 (patch) | |
tree | 2ee9858e529c1355fc02461b4ed89b9cab398d35 /miner | |
parent | 40a71f28cf1ada0bf6bdcdc2f3c6f31a8da134a2 (diff) | |
parent | 1136269a79e6ee8bc97f5bf277bf8ec12286b79b (diff) | |
download | go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar.gz go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar.bz2 go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar.lz go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar.xz go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.tar.zst go-tangerine-c134e00e488bf4bfd88689ecf6b91ee351fb77e5.zip |
Merge pull request #17494 from karalabe/mined-block-uncle-check
miner: differentiate between uncle and lost block
Diffstat (limited to 'miner')
-rw-r--r-- | miner/unconfirmed.go | 35 | ||||
-rw-r--r-- | miner/unconfirmed_test.go | 13 | ||||
-rw-r--r-- | miner/worker.go | 2 |
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 18fb12e45..1a881799d 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. |