eth/fetcher: don't drop on future blocks, just not propagate

This commit is contained in:
Péter Szilágyi 2015-06-29 14:20:13 +03:00
parent 29d53b2073
commit a7d22658ad

View File

@ -7,6 +7,8 @@ import (
"math/rand" "math/rand"
"time" "time"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/logger"
@ -104,6 +106,7 @@ type Fetcher struct {
broadcastMeter metrics.Meter // Counter for metering the inbound propagations broadcastMeter metrics.Meter // Counter for metering the inbound propagations
broadcastTimer metrics.Timer // Counter and timer for metering the block forwarding broadcastTimer metrics.Timer // Counter and timer for metering the block forwarding
discardMeter metrics.Meter // Counter for metering the discarded blocks 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. // 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), broadcastMeter: metrics.GetOrRegisterMeter("eth/sync/RemoteBroadcasts", metrics.DefaultRegistry),
broadcastTimer: metrics.GetOrRegisterTimer("eth/sync/LocalBroadcasts", metrics.DefaultRegistry), broadcastTimer: metrics.GetOrRegisterTimer("eth/sync/LocalBroadcasts", metrics.DefaultRegistry),
discardMeter: metrics.GetOrRegisterMeter("eth/sync/DiscardedBlocks", metrics.DefaultRegistry), discardMeter: metrics.GetOrRegisterMeter("eth/sync/DiscardedBlocks", metrics.DefaultRegistry),
futureMeter: metrics.GetOrRegisterMeter("eth/sync/FutureBlocks", metrics.DefaultRegistry),
} }
} }
@ -416,14 +420,22 @@ func (f *Fetcher) insert(peer string, block *types.Block) {
return return
} }
// Quickly validate the header and propagate the block if it passes // 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) glog.V(logger.Debug).Infof("Peer %s: block #%d [%x] verification failed: %v", peer, block.NumberU64(), hash[:4], err)
f.dropPeer(peer) f.dropPeer(peer)
return return
} }
f.broadcastTimer.UpdateSince(block.ReceivedAt)
go f.broadcastBlock(block, true)
// Run the actual import and log any issues // Run the actual import and log any issues
if _, err := f.insertChain(types.Blocks{block}); err != nil { 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) glog.V(logger.Warn).Infof("Peer %s: block #%d [%x] import failed: %v", peer, block.NumberU64(), hash[:4], err)