diff --git a/core/src/main/java/com/matthewmitchell/peercoinj/core/AbstractBlockChain.java b/core/src/main/java/com/matthewmitchell/peercoinj/core/AbstractBlockChain.java index e583ba9a..85030203 100644 --- a/core/src/main/java/com/matthewmitchell/peercoinj/core/AbstractBlockChain.java +++ b/core/src/main/java/com/matthewmitchell/peercoinj/core/AbstractBlockChain.java @@ -119,10 +119,7 @@ class OrphanBlock { final boolean filtered = filteredTxHashes != null && filteredTxn != null; Preconditions.checkArgument((block.transactions == null && filtered) || (block.transactions != null && !filtered)); - if (!shouldVerifyTransactions()) - this.block = block.cloneAsHeader(); - else - this.block = block; + this.block = block; this.filteredTxHashes = filteredTxHashes; this.filteredTxn = filteredTxn; } @@ -424,13 +421,13 @@ private boolean add(Block block, boolean tryConnecting, // Determine if centrally trusted hash // Wait a while for the server if the block is less than three hours old try { - if (validHashStore != null && !validHashStore.isValidHash(block.getHash(), this, block.getTimeSeconds() > Utils.currentTimeSeconds() - 60*60*3)) { - throw new VerificationException("Invalid hash received"); - } - } catch (IOException e) { - log.error("IO Error when determining valid hashes: ", e); - return false; - } + if (validHashStore != null && !validHashStore.isValidHash(block.getHash(), this, block.getTimeSeconds() > Utils.currentTimeSeconds() - 60*60*3)) { + throw new VerificationException("Invalid hash received"); + } + } catch (IOException e) { + log.error("IO Error when determining valid hashes: ", e); + return false; + } checkDifficultyTransitions(storedPrev, block); connectBlock(block, storedPrev, shouldVerifyTransactions(), filteredTxHashList, filteredTxn); diff --git a/core/src/main/java/com/matthewmitchell/peercoinj/core/Peer.java b/core/src/main/java/com/matthewmitchell/peercoinj/core/Peer.java index 6565a67c..afb93e2c 100644 --- a/core/src/main/java/com/matthewmitchell/peercoinj/core/Peer.java +++ b/core/src/main/java/com/matthewmitchell/peercoinj/core/Peer.java @@ -16,31 +16,32 @@ package com.matthewmitchell.peercoinj.core; -import com.matthewmitchell.peercoinj.store.BlockStore; -import com.matthewmitchell.peercoinj.store.BlockStoreException; -import com.matthewmitchell.peercoinj.utils.ListenerRegistration; -import com.matthewmitchell.peercoinj.utils.Threading; import com.google.common.base.Objects; import com.google.common.base.Preconditions; +import static com.google.common.base.Preconditions.checkNotNull; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; import com.google.common.collect.Lists; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.SettableFuture; -import net.jcip.annotations.GuardedBy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Nullable; +import com.matthewmitchell.peercoinj.net.AbstractTimeoutHandler; +import com.matthewmitchell.peercoinj.store.BlockStore; +import com.matthewmitchell.peercoinj.store.BlockStoreException; +import com.matthewmitchell.peercoinj.utils.ListenerRegistration; +import com.matthewmitchell.peercoinj.utils.Threading; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; - -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; +import javax.annotation.Nullable; +import net.jcip.annotations.GuardedBy; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** *
A Peer handles the high level communication with a Peercoin node, extending a {@link PeerSocketHandler} which
@@ -341,6 +342,9 @@ protected void processMessage(Message m) throws Exception {
endFilteredBlock(currentFilteredBlock);
currentFilteredBlock = null;
}
+
+ // If we have a block and we expected one then we reset the timeout for the next block.
+ blockResponseTimeout.processMessage(m);
if (m instanceof Ping) {
if (((Ping) m).hasNonce())
@@ -853,8 +857,14 @@ private void processBlock(Block m) {
try {
// Otherwise it's a block sent to us because the peer thought we needed it, so add it to the block chain.
if (blockChain.add(m)) {
+
// The block was successfully linked into the chain. Notify the user of our progress.
invokeOnBlocksDownloaded(m);
+
+ // Expect more responses if there are more blocks remaining
+ if (vPeerVersionMessage.bestHeight > checkNotNull(blockChain).getBestChainHeight())
+ blockResponseTimeout.setTimeoutEnabled(true);
+
} else {
// This block is an orphan - we don't know how to get from it back to the genesis block yet. That
// must mean that there are blocks we are missing, so do another getblocks with a new block locator
@@ -1021,6 +1031,7 @@ private void invokeOnBlocksDownloaded(final Block m) {
// since the time we first connected to the peer. However, it's weird and unexpected to receive a callback
// with negative "blocks left" in this case, so we clamp to zero so the API user doesn't have to think about it.
final int blocksLeft = Math.max(0, (int) vPeerVersionMessage.bestHeight - checkNotNull(blockChain).getBestChainHeight());
+
for (final ListenerRegistration