diff options
Diffstat (limited to 'les/sync.go')
-rw-r--r-- | les/sync.go | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/les/sync.go b/les/sync.go new file mode 100644 index 000000000..f92f8ce04 --- /dev/null +++ b/les/sync.go @@ -0,0 +1,84 @@ +// Copyright 2015 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. + +package les + +import ( + "time" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/light" + "golang.org/x/net/context" +) + +const ( + //forceSyncCycle = 10 * time.Second // Time interval to force syncs, even if few peers are available + minDesiredPeerCount = 5 // Amount of peers desired to start syncing +) + +// syncer is responsible for periodically synchronising with the network, both +// downloading hashes and blocks as well as handling the announcement handler. +func (pm *ProtocolManager) syncer() { + // Start and ensure cleanup of sync mechanisms + //pm.fetcher.Start() + //defer pm.fetcher.Stop() + defer pm.downloader.Terminate() + + // Wait for different events to fire synchronisation operations + //forceSync := time.Tick(forceSyncCycle) + for { + select { + case <-pm.newPeerCh: +/* // Make sure we have peers to select from, then sync + if pm.peers.Len() < minDesiredPeerCount { + break + } + go pm.synchronise(pm.peers.BestPeer()) +*/ + /*case <-forceSync: + // Force a sync even if not enough peers are present + go pm.synchronise(pm.peers.BestPeer()) + */ + case <-pm.noMorePeers: + return + } + } +} + +func (pm *ProtocolManager) needToSync(peerHead blockInfo) bool { + head := pm.blockchain.CurrentHeader() + currentTd := core.GetTd(pm.chainDb, head.Hash(), head.Number.Uint64()) + return currentTd != nil && peerHead.Td.Cmp(currentTd) > 0 +} + +// synchronise tries to sync up our local block chain with a remote peer. +func (pm *ProtocolManager) synchronise(peer *peer) { + // Short circuit if no peers are available + if peer == nil { + return + } + + // Make sure the peer's TD is higher than our own. + if !pm.needToSync(peer.headBlockInfo()) { + return + } + + ctx, _ := context.WithTimeout(context.Background(), time.Second*5) + pm.blockchain.(*light.LightChain).SyncCht(ctx) + + pm.downloader.Synchronise(peer.id, peer.Head(), peer.Td(), downloader.LightSync) +} |