From f186b390182da7af368e7a5a1e9eff8d690b7414 Mon Sep 17 00:00:00 2001 From: Péter Szilágyi Date: Mon, 28 Sep 2015 19:27:31 +0300 Subject: eth/downloader: add fast and light sync strategies --- eth/handler.go | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'eth/handler.go') diff --git a/eth/handler.go b/eth/handler.go index 021be1024..daa285730 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -120,15 +120,25 @@ func NewProtocolManager(mode Mode, networkId int, mux *event.TypeMux, txpool txP return nil, errIncompatibleConfig } // Construct the different synchronisation mechanisms - manager.downloader = downloader.New(manager.eventMux, manager.blockchain.HasBlock, manager.blockchain.GetBlock, manager.blockchain.CurrentBlock, manager.blockchain.GetTd, manager.blockchain.InsertChain, manager.removePeer) + var syncMode downloader.SyncMode + switch mode { + case ArchiveMode: + syncMode = downloader.FullSync + case FullMode: + syncMode = downloader.FastSync + case LightMode: + syncMode = downloader.LightSync + } + manager.downloader = downloader.New(syncMode, manager.eventMux, blockchain.HasHeader, blockchain.HasBlock, blockchain.GetHeader, blockchain.GetBlock, + blockchain.CurrentHeader, blockchain.CurrentBlock, blockchain.GetTd, blockchain.InsertHeaderChain, blockchain.InsertChain, nil, manager.removePeer) validator := func(block *types.Block, parent *types.Block) error { return core.ValidateHeader(pow, block.Header(), parent.Header(), true, false) } heighter := func() uint64 { - return manager.blockchain.CurrentBlock().NumberU64() + return blockchain.CurrentBlock().NumberU64() } - manager.fetcher = fetcher.New(manager.blockchain.GetBlock, validator, manager.BroadcastBlock, heighter, manager.blockchain.InsertChain, manager.removePeer) + manager.fetcher = fetcher.New(blockchain.GetBlock, validator, manager.BroadcastBlock, heighter, blockchain.InsertChain, manager.removePeer) return manager, nil } @@ -210,7 +220,7 @@ func (pm *ProtocolManager) handle(p *peer) error { // Register the peer in the downloader. If the downloader considers it banned, we disconnect if err := pm.downloader.RegisterPeer(p.id, p.version, p.Head(), p.RequestHashes, p.RequestHashesFromNumber, p.RequestBlocks, - p.RequestHeadersByHash, p.RequestHeadersByNumber, p.RequestBodies); err != nil { + p.RequestHeadersByHash, p.RequestHeadersByNumber, p.RequestBodies, p.RequestReceipts); err != nil { return err } // Propagate existing transactions. new transactions appearing @@ -514,22 +524,31 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { var ( hash common.Hash bytes int - receipts []*types.Receipt + receipts []rlp.RawValue ) - for bytes < softResponseLimit && len(receipts) < downloader.MaxReceiptsFetch { - // Retrieve the hash of the next transaction receipt + for bytes < softResponseLimit && len(receipts) < downloader.MaxReceiptFetch { + // Retrieve the hash of the next block if err := msgStream.Decode(&hash); err == rlp.EOL { break } else if err != nil { return errResp(ErrDecode, "msg %v: %v", msg, err) } - // Retrieve the requested receipt, stopping if enough was found - if receipt := core.GetReceipt(pm.chaindb, hash); receipt != nil { - receipts = append(receipts, receipt) - bytes += len(receipt.RlpEncode()) + // Retrieve the requested block's receipts, skipping if unknown to us + results := core.GetBlockReceipts(pm.chaindb, hash) + if results == nil { + if header := pm.blockchain.GetHeader(hash); header == nil || header.ReceiptHash != types.EmptyRootHash { + continue + } + } + // If known, encode and queue for response packet + if encoded, err := rlp.EncodeToBytes(results); err != nil { + glog.V(logger.Error).Infof("failed to encode receipt: %v", err) + } else { + receipts = append(receipts, encoded) + bytes += len(encoded) } } - return p.SendReceipts(receipts) + return p.SendReceiptsRLP(receipts) case msg.Code == NewBlockHashesMsg: // Retrieve and deseralize the remote new block hashes notification -- cgit