mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-11 17:55:53 +00:00
Rename MemoryPool to TxConfidencePool and make singleton
This commit is contained in:
parent
4854099cde
commit
ec7cec67a7
@ -93,7 +93,7 @@ public class BloomFilter extends Message {
|
||||
*
|
||||
* <p>In order for filtered block download to function efficiently, the number of matched transactions in any given
|
||||
* block should be less than (with some headroom) the maximum size of the MemoryPool used by the Peer
|
||||
* doing the downloading (default is {@link MemoryPool#MAX_SIZE}). See the comment in processBlock(FilteredBlock)
|
||||
* doing the downloading (default is {@link TxConfidencePool#MAX_SIZE}). See the comment in processBlock(FilteredBlock)
|
||||
* for more information on this restriction.</p>
|
||||
*
|
||||
* <p>randomNonce is a tweak for the hash function used to prevent some theoretical DoS attacks.
|
||||
|
@ -22,7 +22,7 @@ import java.io.OutputStream;
|
||||
/**
|
||||
* The "mempool" message asks a remote peer to announce all transactions in its memory pool, possibly restricted by
|
||||
* any Bloom filter set on the connection. The list of transaction hashes comes back in an inv message. Note that
|
||||
* this is different to the {@link MemoryPool} object which doesn't try to keep track of all pending transactions,
|
||||
* this is different to the {@link TxConfidencePool} object which doesn't try to keep track of all pending transactions,
|
||||
* it's just a holding area for transactions that a part of the app may find interesting. The mempool message has
|
||||
* no fields.
|
||||
*/
|
||||
|
@ -77,6 +77,7 @@ public abstract class NetworkParameters implements Serializable {
|
||||
protected byte[] alertSigningKey;
|
||||
protected int bip32HeaderPub;
|
||||
protected int bip32HeaderPriv;
|
||||
transient protected TxConfidencePool confidencePool;
|
||||
|
||||
/**
|
||||
* See getId(). This may be null for old deserialized wallets. In that case we derive it heuristically
|
||||
@ -97,6 +98,7 @@ public abstract class NetworkParameters implements Serializable {
|
||||
protected NetworkParameters() {
|
||||
alertSigningKey = SATOSHI_KEY;
|
||||
genesisBlock = createGenesis(this);
|
||||
confidencePool = new TxConfidencePool();
|
||||
}
|
||||
|
||||
private static Block createGenesis(NetworkParameters n) {
|
||||
@ -356,4 +358,8 @@ public abstract class NetworkParameters implements Serializable {
|
||||
public int getBip32HeaderPriv() {
|
||||
return bip32HeaderPriv;
|
||||
}
|
||||
|
||||
public TxConfidencePool getConfidencePool() {
|
||||
return confidencePool;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class Peer extends PeerSocketHandler {
|
||||
private final AtomicInteger blocksAnnounced = new AtomicInteger();
|
||||
// A class that tracks recent transactions that have been broadcast across the network, counts how many
|
||||
// peers announced them and updates the transaction confidence data. It is passed to each Peer.
|
||||
private final MemoryPool memoryPool;
|
||||
private final TxConfidencePool confidencePool;
|
||||
// Each wallet added to the peer will be notified of downloaded transaction data.
|
||||
private final CopyOnWriteArrayList<Wallet> wallets;
|
||||
// A time before which we only download block headers, after that point we download block bodies.
|
||||
@ -179,7 +179,7 @@ public class Peer extends PeerSocketHandler {
|
||||
* used to keep track of which peers relayed transactions and offer more descriptive logging.</p>
|
||||
*/
|
||||
public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress,
|
||||
@Nullable AbstractBlockChain chain, @Nullable MemoryPool mempool) {
|
||||
@Nullable AbstractBlockChain chain, @Nullable TxConfidencePool mempool) {
|
||||
this(params, ver, remoteAddress, chain, mempool, true);
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ public class Peer extends PeerSocketHandler {
|
||||
* used to keep track of which peers relayed transactions and offer more descriptive logging.</p>
|
||||
*/
|
||||
public Peer(NetworkParameters params, VersionMessage ver, PeerAddress remoteAddress,
|
||||
@Nullable AbstractBlockChain chain, @Nullable MemoryPool mempool, boolean downloadTxDependencies) {
|
||||
@Nullable AbstractBlockChain chain, @Nullable TxConfidencePool mempool, boolean downloadTxDependencies) {
|
||||
super(params, remoteAddress);
|
||||
this.params = Preconditions.checkNotNull(params);
|
||||
this.versionMessage = Preconditions.checkNotNull(ver);
|
||||
@ -211,7 +211,7 @@ public class Peer extends PeerSocketHandler {
|
||||
this.isAcked = false;
|
||||
this.pendingPings = new CopyOnWriteArrayList<PendingPing>();
|
||||
this.wallets = new CopyOnWriteArrayList<Wallet>();
|
||||
this.memoryPool = mempool;
|
||||
this.confidencePool = mempool;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -583,9 +583,9 @@ public class Peer extends PeerSocketHandler {
|
||||
lock.lock();
|
||||
try {
|
||||
log.debug("{}: Received tx {}", getAddress(), tx.getHashAsString());
|
||||
if (memoryPool != null) {
|
||||
if (confidencePool != null) {
|
||||
// We may get back a different transaction object.
|
||||
tx = memoryPool.seen(tx, getAddress());
|
||||
tx = confidencePool.seen(tx, getAddress());
|
||||
}
|
||||
fTx = tx;
|
||||
// Label the transaction as coming in from the P2P network (as opposed to being created by us, direct import,
|
||||
@ -686,7 +686,7 @@ public class Peer extends PeerSocketHandler {
|
||||
* <p>Note that dependencies downloaded this way will not trigger the onTransaction method of event listeners.</p>
|
||||
*/
|
||||
public ListenableFuture<List<Transaction>> downloadDependencies(Transaction tx) {
|
||||
checkNotNull(memoryPool, "Must have a configured MemoryPool object to download dependencies.");
|
||||
checkNotNull(confidencePool, "Must have a configured MemoryPool object to download dependencies.");
|
||||
TransactionConfidence.ConfidenceType txConfidence = tx.getConfidence().getConfidenceType();
|
||||
Preconditions.checkArgument(txConfidence != TransactionConfidence.ConfidenceType.BUILDING);
|
||||
log.info("{}: Downloading dependencies of {}", getAddress(), tx.getHashAsString());
|
||||
@ -712,7 +712,7 @@ public class Peer extends PeerSocketHandler {
|
||||
private ListenableFuture<Object> downloadDependenciesInternal(final Transaction tx,
|
||||
final Object marker,
|
||||
final List<Transaction> results) {
|
||||
checkNotNull(memoryPool, "Must have a configured MemoryPool object to download dependencies.");
|
||||
checkNotNull(confidencePool, "Must have a configured MemoryPool object to download dependencies.");
|
||||
final SettableFuture<Object> resultFuture = SettableFuture.create();
|
||||
final Sha256Hash rootTxHash = tx.getHash();
|
||||
// We want to recursively grab its dependencies. This is so listeners can learn important information like
|
||||
@ -727,7 +727,7 @@ public class Peer extends PeerSocketHandler {
|
||||
for (TransactionInput input : tx.getInputs()) {
|
||||
// There may be multiple inputs that connect to the same transaction.
|
||||
Sha256Hash hash = input.getOutpoint().getHash();
|
||||
Transaction dep = memoryPool.get(hash);
|
||||
Transaction dep = confidencePool.get(hash);
|
||||
if (dep == null) {
|
||||
needToRequest.add(hash);
|
||||
} else {
|
||||
@ -1043,7 +1043,7 @@ public class Peer extends PeerSocketHandler {
|
||||
Iterator<InventoryItem> it = transactions.iterator();
|
||||
while (it.hasNext()) {
|
||||
InventoryItem item = it.next();
|
||||
if (memoryPool == null) {
|
||||
if (confidencePool == null) {
|
||||
if (downloadData) {
|
||||
// If there's no memory pool only download transactions if we're configured to.
|
||||
getdata.addItem(item);
|
||||
@ -1055,7 +1055,7 @@ public class Peer extends PeerSocketHandler {
|
||||
// peers run at different speeds. However to conserve bandwidth on mobile devices we try to only download a
|
||||
// transaction once. This means we can miss broadcasts if the peer disconnects between sending us an inv and
|
||||
// sending us the transaction: currently we'll never try to re-fetch after a timeout.
|
||||
if (memoryPool.maybeWasSeen(item.hash)) {
|
||||
if (confidencePool.maybeWasSeen(item.hash)) {
|
||||
// Some other peer already announced this so don't download.
|
||||
it.remove();
|
||||
} else {
|
||||
@ -1063,7 +1063,7 @@ public class Peer extends PeerSocketHandler {
|
||||
getdata.addItem(item);
|
||||
}
|
||||
// This can trigger transaction confidence listeners.
|
||||
memoryPool.seen(item.hash, this.getAddress());
|
||||
confidencePool.seen(item.hash, this.getAddress());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1528,7 +1528,7 @@ public class Peer extends PeerSocketHandler {
|
||||
* unset a filter, though the underlying p2p protocol does support it.</p>
|
||||
*/
|
||||
public void setBloomFilter(BloomFilter filter) {
|
||||
setBloomFilter(filter, memoryPool != null || vDownloadData);
|
||||
setBloomFilter(filter, confidencePool != null || vDownloadData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,7 +121,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
@GuardedBy("lock") private boolean downloadTxDependencies;
|
||||
// A class that tracks recent transactions that have been broadcast across the network, counts how many
|
||||
// peers announced them and updates the transaction confidence data. It is passed to each Peer.
|
||||
private final MemoryPool memoryPool;
|
||||
private final TxConfidencePool confidencePool;
|
||||
// How many connections we want to have open at the current time. If we lose connections, we'll try opening more
|
||||
// until we reach this count.
|
||||
@GuardedBy("lock") private int maxConnections;
|
||||
@ -335,7 +335,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
|
||||
downloadTxDependencies = true;
|
||||
|
||||
memoryPool = new MemoryPool();
|
||||
confidencePool = params.getConfidencePool();
|
||||
|
||||
inactives = new PriorityQueue<PeerAddress>(1, new Comparator<PeerAddress>() {
|
||||
@SuppressWarnings("FieldAccessNotGuarded") // only called when inactives is accessed, and lock is held then.
|
||||
@ -516,7 +516,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
while (it.hasNext()) {
|
||||
InventoryItem item = it.next();
|
||||
// Check the mempool first.
|
||||
Transaction tx = memoryPool.get(item.hash);
|
||||
Transaction tx = confidencePool.get(item.hash);
|
||||
if (tx != null) {
|
||||
transactions.add(tx);
|
||||
it.remove();
|
||||
@ -1137,7 +1137,7 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
ver.bestHeight = chain == null ? 0 : chain.getBestChainHeight();
|
||||
ver.time = Utils.currentTimeSeconds();
|
||||
|
||||
Peer peer = new Peer(params, ver, address, chain, memoryPool, downloadTxDependencies);
|
||||
Peer peer = new Peer(params, ver, address, chain, confidencePool, downloadTxDependencies);
|
||||
peer.addEventListener(startupListener, Threading.SAME_THREAD);
|
||||
peer.setMinProtocolVersion(vMinRequiredProtocolVersion);
|
||||
pendingPeers.add(peer);
|
||||
@ -1321,13 +1321,13 @@ public class PeerGroup implements TransactionBroadcaster {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MemoryPool} created by this peer group to synchronize its peers. The pool tracks advertised
|
||||
* Returns the {@link TxConfidencePool} created by this peer group to synchronize its peers. The pool tracks advertised
|
||||
* and downloaded transactions so their confidence can be measured as a proportion of how many peers announced it.
|
||||
* With an un-tampered with internet connection, the more peers announce a transaction the more confidence you can
|
||||
* have that it's really valid.
|
||||
*/
|
||||
public MemoryPool getMemoryPool() {
|
||||
return memoryPool;
|
||||
public TxConfidencePool getConfidencePool() {
|
||||
return confidencePool;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,7 +101,7 @@ public class TransactionBroadcast {
|
||||
// a big effect.
|
||||
List<Peer> peers = peerGroup.getConnectedPeers(); // snapshots
|
||||
// We intern the tx here so we are using a canonical version of the object (as it's unfortunately mutable).
|
||||
pinnedTx = peerGroup.getMemoryPool().intern(tx);
|
||||
pinnedTx = peerGroup.getConfidencePool().intern(tx);
|
||||
// Prepare to send the transaction by adding a listener that'll be called when confidence changes.
|
||||
// Only bother with this if we might actually hear back:
|
||||
if (minConnections > 1)
|
||||
|
@ -44,9 +44,9 @@ import static com.google.common.base.Preconditions.checkState;
|
||||
* <p>It is <b>not</b> at this time directly equivalent to the Satoshi clients memory pool, which tracks
|
||||
* all transactions not currently included in the best chain - it's simply a cache.</p>
|
||||
*/
|
||||
public class MemoryPool {
|
||||
private static final Logger log = LoggerFactory.getLogger(MemoryPool.class);
|
||||
protected ReentrantLock lock = Threading.lock("mempool");
|
||||
public class TxConfidencePool {
|
||||
private static final Logger log = LoggerFactory.getLogger(TxConfidencePool.class);
|
||||
protected ReentrantLock lock = Threading.lock("txconfidencepool");
|
||||
|
||||
// For each transaction we may have seen:
|
||||
// - only its hash in an inv packet
|
||||
@ -72,10 +72,10 @@ public class MemoryPool {
|
||||
// allowing us to delete the associated entry (the tx itself has already gone away).
|
||||
WeakTransactionReference tx;
|
||||
}
|
||||
private LinkedHashMap<Sha256Hash, Entry> memoryPool;
|
||||
private LinkedHashMap<Sha256Hash, Entry> pool;
|
||||
|
||||
// This ReferenceQueue gets entries added to it when they are only weakly reachable, ie, the MemoryPool is the
|
||||
// only thing that is tracking the transaction anymore. We check it from time to time and delete memoryPool entries
|
||||
// only thing that is tracking the transaction anymore. We check it from time to time and delete pool entries
|
||||
// corresponding to expired transactions. In this way memory usage of the system is in line with however many
|
||||
// transactions you actually care to track the confidence of. We can still end up with lots of hashes being stored
|
||||
// if our peers flood us with invs but the MAX_SIZE param caps this.
|
||||
@ -89,10 +89,10 @@ public class MemoryPool {
|
||||
* usage).
|
||||
* @param size Max number of transactions to track. The pool will fill up to this size then stop growing.
|
||||
*/
|
||||
public MemoryPool(final int size) {
|
||||
memoryPool = new LinkedHashMap<Sha256Hash, Entry>() {
|
||||
public TxConfidencePool(final int size) {
|
||||
pool = new LinkedHashMap<Sha256Hash, Entry>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Sha256Hash, Entry> entry) {
|
||||
protected boolean removeEldestEntry(Map.Entry<Sha256Hash, TxConfidencePool.Entry> entry) {
|
||||
// An arbitrary choice to stop the memory used by tracked transactions getting too huge in the event
|
||||
// of some kind of DoS attack.
|
||||
return size() > size;
|
||||
@ -102,16 +102,16 @@ public class MemoryPool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a memory pool that will track at most {@link MemoryPool#MAX_SIZE} entries. You should normally use
|
||||
* Creates a memory pool that will track at most {@link TxConfidencePool#MAX_SIZE} entries. You should normally use
|
||||
* this constructor.
|
||||
*/
|
||||
public MemoryPool() {
|
||||
public TxConfidencePool() {
|
||||
this(MAX_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* If any transactions have expired due to being only weakly reachable through us, go ahead and delete their
|
||||
* memoryPool entries - it means we downloaded the transaction and sent it to various event listeners, none of
|
||||
* pool entries - it means we downloaded the transaction and sent it to various event listeners, none of
|
||||
* which bothered to keep a reference. Typically, this is because the transaction does not involve any keys that
|
||||
* are relevant to any of our wallets.
|
||||
*/
|
||||
@ -123,7 +123,7 @@ public class MemoryPool {
|
||||
// Find which transaction got deleted by the GC.
|
||||
WeakTransactionReference txRef = (WeakTransactionReference) ref;
|
||||
// And remove the associated map entry so the other bits of memory can also be reclaimed.
|
||||
memoryPool.remove(txRef.hash);
|
||||
pool.remove(txRef.hash);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
@ -137,7 +137,7 @@ public class MemoryPool {
|
||||
lock.lock();
|
||||
try {
|
||||
cleanPool();
|
||||
Entry entry = memoryPool.get(txHash);
|
||||
Entry entry = pool.get(txHash);
|
||||
if (entry == null) {
|
||||
// No such TX known.
|
||||
return 0;
|
||||
@ -151,7 +151,7 @@ public class MemoryPool {
|
||||
// We previously downloaded this transaction, but nothing cared about it so the garbage collector threw
|
||||
// it away. We also deleted the set that tracked which peers had seen it. Treat this case as a zero and
|
||||
// just delete it from the map.
|
||||
memoryPool.remove(txHash);
|
||||
pool.remove(txHash);
|
||||
return 0;
|
||||
} else {
|
||||
checkState(entry.addresses == null);
|
||||
@ -172,7 +172,7 @@ public class MemoryPool {
|
||||
lock.lock();
|
||||
try {
|
||||
cleanPool();
|
||||
Entry entry = memoryPool.get(tx.getHash());
|
||||
Entry entry = pool.get(tx.getHash());
|
||||
if (entry != null) {
|
||||
// This TX or its hash have been previously interned.
|
||||
if (entry.tx != null) {
|
||||
@ -206,7 +206,7 @@ public class MemoryPool {
|
||||
log.debug("Provided with a downloaded transaction we didn't see announced yet: {}", tx.getHashAsString());
|
||||
entry = new Entry();
|
||||
entry.tx = new WeakTransactionReference(tx, referenceQueue);
|
||||
memoryPool.put(tx.getHash(), entry);
|
||||
pool.put(tx.getHash(), entry);
|
||||
return tx;
|
||||
}
|
||||
} finally {
|
||||
@ -239,7 +239,7 @@ public class MemoryPool {
|
||||
lock.lock();
|
||||
try {
|
||||
cleanPool();
|
||||
Entry entry = memoryPool.get(hash);
|
||||
Entry entry = pool.get(hash);
|
||||
if (entry != null) {
|
||||
// This TX or its hash have been previously announced.
|
||||
if (entry.tx != null) {
|
||||
@ -265,7 +265,7 @@ public class MemoryPool {
|
||||
// TODO: Using hashsets here is inefficient compared to just having an array.
|
||||
entry.addresses = new HashSet<PeerAddress>();
|
||||
entry.addresses.add(byPeer);
|
||||
memoryPool.put(hash, entry);
|
||||
pool.put(hash, entry);
|
||||
log.info("{}: Peer announced new transaction [1] {}", byPeer, hash);
|
||||
}
|
||||
} finally {
|
||||
@ -289,7 +289,7 @@ public class MemoryPool {
|
||||
public Transaction get(Sha256Hash hash) {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = memoryPool.get(hash);
|
||||
Entry entry = pool.get(hash);
|
||||
if (entry == null) return null; // Unknown.
|
||||
if (entry.tx == null) return null; // Seen but only in advertisements.
|
||||
if (entry.tx.get() == null) return null; // Was downloaded but garbage collected.
|
||||
@ -309,7 +309,7 @@ public class MemoryPool {
|
||||
public boolean maybeWasSeen(Sha256Hash hash) {
|
||||
lock.lock();
|
||||
try {
|
||||
Entry entry = memoryPool.get(hash);
|
||||
Entry entry = pool.get(hash);
|
||||
return entry != null;
|
||||
} finally {
|
||||
lock.unlock();
|
@ -46,7 +46,7 @@ public class MemoryPoolTest {
|
||||
|
||||
@Test
|
||||
public void canonicalInstance() throws Exception {
|
||||
MemoryPool pool = new MemoryPool();
|
||||
TxConfidencePool pool = new TxConfidencePool();
|
||||
// Check that if we repeatedly send it the same transaction but with different objects, we get back the same
|
||||
// canonical instance with the confidences update.
|
||||
assertEquals(0, pool.numBroadcastPeers(tx1.getHash()));
|
||||
@ -61,7 +61,7 @@ public class MemoryPoolTest {
|
||||
|
||||
@Test
|
||||
public void invAndDownload() throws Exception {
|
||||
MemoryPool pool = new MemoryPool();
|
||||
TxConfidencePool pool = new TxConfidencePool();
|
||||
// Base case: we see a transaction announced twice and then download it. The count is in the confidence object.
|
||||
assertEquals(0, pool.numBroadcastPeers(tx1.getHash()));
|
||||
pool.seen(tx1.getHash(), address1);
|
||||
|
@ -375,7 +375,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
inbound(p2, inv);
|
||||
assertTrue(outbound(p2) instanceof GetDataMessage);
|
||||
assertEquals(0, tx.getConfidence().numBroadcastPeers());
|
||||
assertTrue(peerGroup.getMemoryPool().maybeWasSeen(tx.getHash()));
|
||||
assertTrue(peerGroup.getConfidencePool().maybeWasSeen(tx.getHash()));
|
||||
assertNull(event[0]);
|
||||
// Peer 1 advertises the tx, we don't do anything as it's already been requested.
|
||||
inbound(p1, inv);
|
||||
|
@ -56,7 +56,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
private Peer peer;
|
||||
private InboundMessageQueuer writeTarget;
|
||||
private static final int OTHER_PEER_CHAIN_HEIGHT = 110;
|
||||
private MemoryPool memoryPool;
|
||||
private TxConfidencePool confidencePool;
|
||||
private final AtomicBoolean fail = new AtomicBoolean(false);
|
||||
|
||||
|
||||
@ -77,10 +77,10 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
memoryPool = new MemoryPool();
|
||||
confidencePool = new TxConfidencePool();
|
||||
VersionMessage ver = new VersionMessage(unitTestParams, 100);
|
||||
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 4000);
|
||||
peer = new Peer(unitTestParams, ver, new PeerAddress(address), blockChain, memoryPool);
|
||||
peer = new Peer(unitTestParams, ver, new PeerAddress(address), blockChain, confidencePool);
|
||||
peer.addWallet(wallet);
|
||||
}
|
||||
|
||||
@ -269,7 +269,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
// Check co-ordination of which peer to download via the memory pool.
|
||||
VersionMessage ver = new VersionMessage(unitTestParams, 100);
|
||||
InetSocketAddress address = new InetSocketAddress("127.0.0.1", 4242);
|
||||
Peer peer2 = new Peer(unitTestParams, ver, new PeerAddress(address), blockChain, memoryPool);
|
||||
Peer peer2 = new Peer(unitTestParams, ver, new PeerAddress(address), blockChain, confidencePool);
|
||||
peer2.addWallet(wallet);
|
||||
VersionMessage peerVersion = new VersionMessage(unitTestParams, OTHER_PEER_CHAIN_HEIGHT);
|
||||
peerVersion.clientVersion = 70001;
|
||||
@ -291,7 +291,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
GetDataMessage message = (GetDataMessage)outbound(writeTarget);
|
||||
assertEquals(1, message.getItems().size());
|
||||
assertEquals(tx.getHash(), message.getItems().get(0).hash);
|
||||
assertTrue(memoryPool.maybeWasSeen(tx.getHash()));
|
||||
assertTrue(confidencePool.maybeWasSeen(tx.getHash()));
|
||||
|
||||
// Advertising to peer2 results in no getdata message.
|
||||
inbound(writeTarget2, inv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user