3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-01-30 23:02:15 +00:00

Refactor the code that sets filters a bit, and send a mempool query after wallet contents change in case of a key import.

This commit is contained in:
Mike Hearn 2013-02-19 16:10:21 +01:00
parent 3c606516be
commit 5a3515bef0
3 changed files with 39 additions and 15 deletions

View File

@ -1241,4 +1241,35 @@ public class Peer {
return null;
}
}
/**
* <p>Sets a Bloom filter on this connection. This will cause the given {@link BloomFilter} object to be sent to the
* remote peer and if either a memory pool has been set using {@link Peer#setMemoryPool(MemoryPool)} or the
* downloadData property is true, a {@link MemoryPoolMessage} is sent as well to trigger downloading of any
* pending transactions that may be relevant.</p>
*
* <p>The Peer does not keep a reference to the BloomFilter. Also, it will not automatically request filters
* from any wallets added using {@link Peer#addWallet(Wallet)}. This is to allow callers to avoid redundantly
* recalculating the same filter repeatedly when using multiple peers together.</p>
*
* <p>Therefore, you should not use this method if your app uses a {@link PeerGroup}. It is called for you.</p>
*
* <p>If the remote peer doesn't support Bloom filtering, then this call is ignored.</p>
*/
public void setBloomFilter(BloomFilter filter) throws IOException {
if (!getPeerVersionMessage().isBloomFilteringSupported())
return;
boolean shouldQueryMemPool;
synchronized (this) {
shouldQueryMemPool = memoryPool != null || downloadData.get();
}
log.info("{}: Sending Bloom filter{}", this, shouldQueryMemPool ? " and querying mempool" : "");
ChannelFuture future = sendMessage(filter);
if (shouldQueryMemPool)
future.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
sendMessage(new MemoryPoolMessage());
}
});
}
}

View File

@ -580,16 +580,12 @@ public class PeerGroup extends AbstractIdleService {
for (Wallet w : wallets)
filter.merge(w.getBloomFilter(lastBloomFilterElementCount, bloomFilterFPRate, bloomFilterTweak));
bloomFilter = filter;
for (Peer peer : peers) {
if (peer.getPeerVersionMessage().isBloomFilteringSupported()) {
try {
log.info("{}: Sending peer an updated Bloom Filter.", peer);
peer.sendMessage(filter);
} catch (IOException e) {
throw new RuntimeException(e);
}
for (Peer peer : peers)
try {
peer.setBloomFilter(filter);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
// Do this last so that bloomFilter is already set when it gets called.
setFastCatchupTimeSecs(earliestKeyTime);
@ -719,11 +715,7 @@ public class PeerGroup extends AbstractIdleService {
// aren't relevant to our wallet. We may still receive some false positives, which is
// OK because it helps improve wallet privacy. Old nodes will just ignore the message.
try {
if (bloomFilter != null && peer.getPeerVersionMessage().isBloomFilteringSupported()) {
log.info("{}: Sending Bloom filter and querying memory pool", peer);
peer.sendMessage(bloomFilter);
peer.sendMessage(new MemoryPoolMessage());
}
if (bloomFilter != null) peer.setBloomFilter(bloomFilter);
} catch (IOException e) { } // That was quick...already disconnected
// Link the peer to the memory pool so broadcast transactions have their confidence levels updated.
peer.setMemoryPool(memoryPool);

View File

@ -311,12 +311,13 @@ public class PeerGroupTest extends TestWithPeerGroup {
peerGroup.addWallet(wallet);
// Transaction announced to the first peer.
InventoryMessage inv1 = (InventoryMessage) outbound(p1);
assertTrue(outbound(p1) instanceof BloomFilter); // Filter is recalculated.
assertTrue(outbound(p1) instanceof MemoryPoolMessage);
assertEquals(t3.getHash(), inv1.getItems().get(0).hash);
// Peer asks for the transaction, and get it.
GetDataMessage getdata = new GetDataMessage(params);
getdata.addItem(inv1.getItems().get(0));
inbound(p1, getdata);
assertTrue(outbound(p1) instanceof BloomFilter); // Filter is recalculated.
Transaction t4 = (Transaction) outbound(p1);
assertEquals(t3, t4);