aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2015-06-29 19:31:13 +0800
committerJeffrey Wilcke <jeffrey@ethereum.org>2015-06-29 19:31:13 +0800
commit5e7db8f5cd4e44eed67334d1dd0af5854f271232 (patch)
tree97d199539df243eb406f2427dc2cddaf1ed6b158
parenta0191910fcc7f4122c90db49f8381e4d3bd58823 (diff)
parenta7d22658ad81064abad5a12bd38545c98a0c508c (diff)
downloaddexon-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.go22
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)