From 8f52cabdf7aa59978f532bb805c7c0dad0682299 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Fri, 2 Nov 2012 15:24:39 +0100 Subject: [PATCH] Allow blockChain to be skipped when creating PeerGroups/Peers. --- .../java/com/google/bitcoin/core/Peer.java | 18 +++++------ .../com/google/bitcoin/core/PeerGroup.java | 31 ++++++++++++------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Peer.java b/core/src/main/java/com/google/bitcoin/core/Peer.java index d92bbbd9..c1642a4c 100644 --- a/core/src/main/java/com/google/bitcoin/core/Peer.java +++ b/core/src/main/java/com/google/bitcoin/core/Peer.java @@ -67,8 +67,8 @@ public class Peer { private MemoryPool memoryPool; // A time before which we only download block headers, after that point we download block bodies. private long fastCatchupTimeSecs; - // Whether we are currently downloading headers only or block bodies. Defaults to true, if the fast catchup time - // is set AND our best block is before that date, switch to false until block headers beyond that point have been + // Whether we are currently downloading headers only or block bodies. Starts at true. If the fast catchup time is + // set AND our best block is before that date, switch to false until block headers beyond that point have been // received at which point it gets set to true again. This isn't relevant unless downloadData is true. private boolean downloadBlockBodies = true; // Keeps track of things we requested internally with getdata but didn't receive yet, so we can avoid re-requests. @@ -87,10 +87,10 @@ public class Peer { /** * Construct a peer that reads/writes from the given block chain. */ - public Peer(NetworkParameters params, AbstractBlockChain chain2, VersionMessage ver) { - this.params = params; - this.blockChain = chain2; - this.versionMessage = ver; + public Peer(NetworkParameters params, AbstractBlockChain chain, VersionMessage ver) { + this.params = Preconditions.checkNotNull(params); + this.versionMessage = Preconditions.checkNotNull(ver); + this.blockChain = chain; // Allowed to be null. this.pendingGetBlockFutures = new ArrayList>(); this.eventListeners = new CopyOnWriteArrayList(); this.lifecycleListeners = new CopyOnWriteArrayList(); @@ -104,8 +104,7 @@ public class Peer { * given software name/version strings, which should be something like "MySimpleTool", "1.0" */ public Peer(NetworkParameters params, AbstractBlockChain blockChain, String thisSoftwareName, String thisSoftwareVersion) { - this(params, blockChain, null); - this.versionMessage = new VersionMessage(params, blockChain.getBestChainHeight()); + this(params, blockChain, new VersionMessage(params, blockChain.getBestChainHeight())); this.versionMessage.appendToSubVer(thisSoftwareName, thisSoftwareVersion, null); } @@ -457,7 +456,7 @@ public class Peer { } } - if (blocks.size() > 0 && downloadData) { + if (blocks.size() > 0 && downloadData && blockChain != null) { // Ideally, we'd only ask for the data here if we actually needed it. However that can imply a lot of // disk IO to figure out what we've got. Normally peers will not send us inv for things we already have // so we just re-request it here, and if we get duplicates the block chain / wallet will filter them out. @@ -532,6 +531,7 @@ public class Peer { * @param secondsSinceEpoch Time in seconds since the epoch or 0 to reset to always downloading block bodies. */ public void setFastCatchupTime(long secondsSinceEpoch) { + Preconditions.checkNotNull(blockChain); if (secondsSinceEpoch == 0) { fastCatchupTimeSecs = params.genesisBlock.getTimeSeconds(); downloadBlockBodies = true; diff --git a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java index 237d3dd1..ce431a86 100644 --- a/core/src/main/java/com/google/bitcoin/core/PeerGroup.java +++ b/core/src/main/java/com/google/bitcoin/core/PeerGroup.java @@ -122,14 +122,23 @@ public class PeerGroup { Peer.PeerLifecycleListener startupListener = new PeerStartupListener(); /** - * Creates a PeerGroup with the given parameters and a default 5 second connection timeout. If you don't care - * about blocks or pending transactions, you can just provide a MemoryBlockStore and a newly created Wallet. + * Creates a PeerGroup with the given parameters and a default 5 second connection timeout. * * @param params Network parameters - * @param chain2 a BlockChain object that will receive and handle block messages. + * @param chain a BlockChain object that will receive and handle block messages. */ - public PeerGroup(NetworkParameters params, AbstractBlockChain chain2) { - this(params, chain2, DEFAULT_CONNECTION_DELAY_MILLIS); + public PeerGroup(NetworkParameters params, AbstractBlockChain chain) { + this(params, chain, DEFAULT_CONNECTION_DELAY_MILLIS); + } + + /** + * Creates a PeerGroup with the given parameters and a default 5 second connection timeout. No chain is + * provided so this node will report its chain height as zero to other peers. + * + * @param params Network parameters + */ + public PeerGroup(NetworkParameters params) { + this(params, null, DEFAULT_CONNECTION_DELAY_MILLIS); } /** @@ -152,7 +161,7 @@ public class PeerGroup { PeerGroup(final NetworkParameters params, final AbstractBlockChain chain, int connectionDelayMillis, ClientBootstrap bootstrap) { this.params = params; - this.chain = chain; + this.chain = chain; // Can be null. this.connectionDelayMillis = connectionDelayMillis; this.fastCatchupTimeSecs = params.genesisBlock.getTimeSeconds(); this.wallets = new ArrayList(1); @@ -162,9 +171,8 @@ public class PeerGroup { // - using connectTo() will increment it by one this.maxConnections = 0; - // Set up a default template version message that doesn't tell the other side what kind of bitcoinj user - // this is. - this.versionMessage = new VersionMessage(params, chain.getBestChainHeight()); + int height = chain == null ? 0 : chain.getBestChainHeight(); + this.versionMessage = new VersionMessage(params, height); memoryPool = new MemoryPool(); this.bootstrap = bootstrap; @@ -194,7 +202,7 @@ public class PeerGroup { return new ChannelPipelineFactory() { public ChannelPipeline getPipeline() throws Exception { VersionMessage ver = getVersionMessage().duplicate(); - ver.bestHeight = chain.getBestChainHeight(); + ver.bestHeight = chain == null ? 0 : chain.getBestChainHeight(); ver.time = Utils.now().getTime() / 1000; ChannelPipeline p = Channels.pipeline(); @@ -685,7 +693,8 @@ public class PeerGroup { if (downloadPeer != null) { log.info("Setting download peer: {}", downloadPeer); downloadPeer.setDownloadData(true); - downloadPeer.setFastCatchupTime(fastCatchupTimeSecs); + if (chain != null) + downloadPeer.setFastCatchupTime(fastCatchupTimeSecs); } }