diff options
author | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-06-29 19:31:13 +0800 |
---|---|---|
committer | Jeffrey Wilcke <jeffrey@ethereum.org> | 2015-06-29 19:31:13 +0800 |
commit | 5e7db8f5cd4e44eed67334d1dd0af5854f271232 (patch) | |
tree | 97d199539df243eb406f2427dc2cddaf1ed6b158 | |
parent | a0191910fcc7f4122c90db49f8381e4d3bd58823 (diff) | |
parent | a7d22658ad81064abad5a12bd38545c98a0c508c (diff) | |
download | dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar.gz dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar.bz2 dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar.lz dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar.xz dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.tar.zst dexon-5e7db8f5cd4e44eed67334d1dd0af5854f271232.zip |
Merge pull request #1353 from karalabe/fix-double-fetch
eth/fetcher: don't double filter/fetch the same block
-rw-r--r-- | eth/fetcher/fetcher.go | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go index 07a32b9f1..5a1509f89 100644 --- a/eth/fetcher/fetcher.go +++ b/eth/fetcher/fetcher.go @@ -7,6 +7,8 @@ import ( "math/rand" "time" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/logger" @@ -104,6 +106,7 @@ type Fetcher struct { broadcastMeter metrics.Meter // Counter for metering the inbound propagations broadcastTimer metrics.Timer // Counter and timer for metering the block forwarding discardMeter metrics.Meter // Counter for metering the discarded blocks + futureMeter metrics.Meter // Counter for metering future blocks } // New creates a block fetcher to retrieve blocks based on hash announcements. @@ -131,6 +134,7 @@ func New(getBlock blockRetrievalFn, validateBlock blockValidatorFn, broadcastBlo broadcastMeter: metrics.GetOrRegisterMeter("eth/sync/RemoteBroadcasts", metrics.DefaultRegistry), broadcastTimer: metrics.GetOrRegisterTimer("eth/sync/LocalBroadcasts", metrics.DefaultRegistry), discardMeter: metrics.GetOrRegisterMeter("eth/sync/DiscardedBlocks", metrics.DefaultRegistry), + futureMeter: metrics.GetOrRegisterMeter("eth/sync/FutureBlocks", metrics.DefaultRegistry), } } @@ -323,7 +327,7 @@ func (f *Fetcher) loop() { hash := block.Hash() // Filter explicitly requested blocks from hash announcements - if _, ok := f.fetching[hash]; ok { + if f.fetching[hash] != nil && f.queued[hash] == nil { // Discard if already imported by other means if f.getBlock(hash) == nil { explicit = append(explicit, block) @@ -416,14 +420,22 @@ func (f *Fetcher) insert(peer string, block *types.Block) { return } // Quickly validate the header and propagate the block if it passes - if err := f.validateBlock(block, parent); err != nil { + switch err := f.validateBlock(block, parent); err { + case nil: + // All ok, quickly propagate to our peers + f.broadcastTimer.UpdateSince(block.ReceivedAt) + go f.broadcastBlock(block, true) + + case core.BlockFutureErr: + f.futureMeter.Mark(1) + // Weird future block, don't fail, but neither propagate + + default: + // Something went very wrong, drop the peer glog.V(logger.Debug).Infof("Peer %s: block #%d [%x] verification failed: %v", peer, block.NumberU64(), hash[:4], err) f.dropPeer(peer) return } - f.broadcastTimer.UpdateSince(block.ReceivedAt) - go f.broadcastBlock(block, true) - // Run the actual import and log any issues if _, err := f.insertChain(types.Blocks{block}); err != nil { glog.V(logger.Warn).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err) |