@Override protected void parse() throws ProtocolException { try { nonce = readInt64(); hasNonce = true; } catch(ProtocolException e) { hasNonce = false; } length = hasNonce ? 8 : 0; }
@Override public void run() { lock.lock(); checkNotNull(awaitingFreshFilter); GetDataMessage getdata = new GetDataMessage(params); for (Sha256Hash hash : awaitingFreshFilter) getdata.addFilteredBlock(hash); awaitingFreshFilter = null; lock.unlock(); log.info("Restarting chain download"); sendMessage(getdata); // TODO: This bizarre ping-after-getdata hack probably isn't necessary. // It's to ensure we know when the end of a filtered block stream of txns is, but we should just be // able to match txns with the merkleblock. Ask Matt why it's written this way. sendMessage(new Ping((long) (Math.random() * Long.MAX_VALUE))); } }, Threading.SAME_THREAD);
assertNextMessageIs(p1, MemoryPoolMessage.class); Ping ping = assertNextMessageIs(p1, Ping.class); inbound(p1, new Pong(ping.getNonce())); newFilter = assertNextMessageIs(p1, BloomFilter.class); assertNextMessageIs(p1, MemoryPoolMessage.class); inbound(p1, new Pong(assertNextMessageIs(p1, Ping.class).getNonce())); assertNextMessageIs(p1, GetDataMessage.class); newBlocks = blocks.subList(6, blocks.size()); filterAndSend(p1, newBlocks, newFilter); inbound(p1, new Ping()); pingAndWait(p1);
@Override protected void processMessage(Message m) throws Exception { if (m instanceof Ping) { SettableFuture<Void> future = mapPingFutures.get(((Ping) m).getNonce()); if (future != null) { future.set(null); return; } } if (m instanceof BloomFilter) { lastReceivedFilter = (BloomFilter) m; } inboundMessages.offer(m); } }
@Override public void run() { lock.lock(); checkNotNull(awaitingFreshFilter); GetDataMessage getdata = new GetDataMessage(params); for (Sha256Hash hash : awaitingFreshFilter) getdata.addFilteredBlock(hash); awaitingFreshFilter = null; lock.unlock(); log.info("Restarting chain download"); sendMessage(getdata); // TODO: This bizarre ping-after-getdata hack probably isn't necessary. // It's to ensure we know when the end of a filtered block stream of txns is, but we should just be // able to match txns with the merkleblock. Ask Matt why it's written this way. sendMessage(new Ping((long) (Math.random() * Long.MAX_VALUE))); } }, Threading.SAME_THREAD);
@Test public void pings() throws Exception { peerGroup.start(); peerGroup.setPingIntervalMsec(100); VersionMessage versionMessage = new VersionMessage(PARAMS, 2); versionMessage.clientVersion = NetworkParameters.ProtocolVersion.BLOOM_FILTER.getBitcoinProtocolVersion(); versionMessage.localServices = VersionMessage.NODE_NETWORK; InboundMessageQueuer p1 = connectPeer(1, versionMessage); Ping ping = (Ping) waitForOutbound(p1); inbound(p1, new Pong(ping.getNonce())); pingAndWait(p1); assertTrue(peerGroup.getConnectedPeers().get(0).getLastPingTime() < Long.MAX_VALUE); // The call to outbound should block until a ping arrives. ping = (Ping) waitForOutbound(p1); inbound(p1, new Pong(ping.getNonce())); assertTrue(peerGroup.getConnectedPeers().get(0).getLastPingTime() < Long.MAX_VALUE); }
@Override public void run() { lock.lock(); checkNotNull(awaitingFreshFilter); GetDataMessage getdata = new GetDataMessage(params); for (Sha256Hash hash : awaitingFreshFilter) getdata.addFilteredBlock(hash); awaitingFreshFilter = null; lock.unlock(); log.info("Restarting chain download"); sendMessage(getdata); // TODO: This bizarre ping-after-getdata hack probably isn't necessary. // It's to ensure we know when the end of a filtered block stream of txns is, but we should just be // able to match txns with the merkleblock. Ask Matt why it's written this way. sendMessage(new Ping((long) (Math.random() * Long.MAX_VALUE))); } }, Threading.SAME_THREAD);
inbound(p1, tx2); inbound(p1, tx3); inbound(p1, new Pong(((Ping)ping).getNonce()));
@Override protected void parse() throws ProtocolException { try { nonce = readInt64(); hasNonce = true; } catch(ProtocolException e) { hasNonce = false; } length = hasNonce ? 8 : 0; }
@Override public void run() { lock.lock(); checkNotNull(awaitingFreshFilter); GetDataMessage getdata = new GetDataMessage(params); for (Sha256Hash hash : awaitingFreshFilter) getdata.addFilteredBlock(hash); awaitingFreshFilter = null; lock.unlock(); log.info("Restarting chain download"); sendMessage(getdata); // TODO: This bizarre ping-after-getdata hack probably isn't necessary. // It's to ensure we know when the end of a filtered block stream of txns is, but we should just be // able to match txns with the merkleblock. Ask Matt why it's written this way. sendMessage(new Ping((long) (Math.random() * Long.MAX_VALUE))); } }, Threading.SAME_THREAD);
@Test public void pingPong() throws Exception { connect(); Utils.setMockClock(); // No ping pong happened yet. assertEquals(Long.MAX_VALUE, peer.getLastPingTime()); assertEquals(Long.MAX_VALUE, peer.getPingTime()); ListenableFuture<Long> future = peer.ping(); assertEquals(Long.MAX_VALUE, peer.getLastPingTime()); assertEquals(Long.MAX_VALUE, peer.getPingTime()); assertFalse(future.isDone()); Ping pingMsg = (Ping) outbound(writeTarget); Utils.rollMockClock(5); // The pong is returned. inbound(writeTarget, new Pong(pingMsg.getNonce())); pingAndWait(writeTarget); assertTrue(future.isDone()); long elapsed = future.get(); assertTrue("" + elapsed, elapsed > 1000); assertEquals(elapsed, peer.getLastPingTime()); assertEquals(elapsed, peer.getPingTime()); // Do it again and make sure it affects the average. future = peer.ping(); pingMsg = (Ping) outbound(writeTarget); Utils.rollMockClock(50); inbound(writeTarget, new Pong(pingMsg.getNonce())); elapsed = future.get(); assertEquals(elapsed, peer.getLastPingTime()); assertEquals(7250, peer.getPingTime()); }
@Override protected void parse() throws ProtocolException { try { nonce = readInt64(); hasNonce = true; } catch(ProtocolException e) { hasNonce = false; } length = hasNonce ? 8 : 0; }
protected ListenableFuture<Long> ping(long nonce) throws ProtocolException { final VersionMessage ver = vPeerVersionMessage; if (!ver.isPingPongSupported()) throw new ProtocolException("Peer version is too low for measurable pings: " + ver); PendingPing pendingPing = new PendingPing(nonce); pendingPings.add(pendingPing); sendMessage(new Ping(pendingPing.nonce)); return pendingPing.future; }
@Override protected void parse() throws ProtocolException { try { nonce = readInt64(); hasNonce = true; } catch(ProtocolException e) { hasNonce = false; } length = hasNonce ? 8 : 0; }
protected ListenableFuture<Long> ping(long nonce) throws ProtocolException { final VersionMessage ver = vPeerVersionMessage; if (!ver.isPingPongSupported()) throw new ProtocolException("Peer version is too low for measurable pings: " + ver); PendingPing pendingPing = new PendingPing(nonce); pendingPings.add(pendingPing); sendMessage(new Ping(pendingPing.nonce)); return pendingPing.future; }
protected ListenableFuture<Long> ping(long nonce) throws ProtocolException { final VersionMessage ver = vPeerVersionMessage; if (!ver.isPingPongSupported()) throw new ProtocolException("Peer version is too low for measurable pings: " + ver); PendingPing pendingPing = new PendingPing(nonce); pendingPings.add(pendingPing); sendMessage(new Ping(pendingPing.nonce)); return pendingPing.future; }