mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 02:05:53 +00:00
Link Peer and Wallet directly instead of using an event listener.
This paves the way for tighter coupling in future, needed for various features.
This commit is contained in:
parent
e9babb2772
commit
8b9ddd2caf
@ -53,6 +53,7 @@ public class Peer {
|
|||||||
private final NetworkParameters params;
|
private final NetworkParameters params;
|
||||||
private final AbstractBlockChain blockChain;
|
private final AbstractBlockChain blockChain;
|
||||||
private PeerAddress address;
|
private PeerAddress address;
|
||||||
|
// TODO: Make the types here explicit and remove synchronization on adders/removers.
|
||||||
private List<PeerEventListener> eventListeners;
|
private List<PeerEventListener> eventListeners;
|
||||||
private List<PeerLifecycleListener> lifecycleListeners;
|
private List<PeerLifecycleListener> lifecycleListeners;
|
||||||
// Whether to try and download blocks and transactions from this peer. Set to false by PeerGroup if not the
|
// Whether to try and download blocks and transactions from this peer. Set to false by PeerGroup if not the
|
||||||
@ -69,6 +70,8 @@ public class Peer {
|
|||||||
// A class that tracks recent transactions that have been broadcast across the network, counts how many
|
// 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.
|
// peers announced them and updates the transaction confidence data. It is passed to each Peer.
|
||||||
private MemoryPool memoryPool;
|
private MemoryPool memoryPool;
|
||||||
|
// Each wallet added to the peer will be notified of downloaded transaction data.
|
||||||
|
private CopyOnWriteArrayList<Wallet> wallets;
|
||||||
// A time before which we only download block headers, after that point we download block bodies.
|
// A time before which we only download block headers, after that point we download block bodies.
|
||||||
private long fastCatchupTimeSecs;
|
private long fastCatchupTimeSecs;
|
||||||
// Whether we are currently downloading headers only or block bodies. Starts at true. If the fast catchup time is
|
// Whether we are currently downloading headers only or block bodies. Starts at true. If the fast catchup time is
|
||||||
@ -123,6 +126,7 @@ public class Peer {
|
|||||||
this.handler = new PeerHandler();
|
this.handler = new PeerHandler();
|
||||||
this.pendingPings = new CopyOnWriteArrayList<PendingPing>();
|
this.pendingPings = new CopyOnWriteArrayList<PendingPing>();
|
||||||
this.lastPingTimes = null;
|
this.lastPingTimes = null;
|
||||||
|
this.wallets = new CopyOnWriteArrayList<Wallet>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -413,9 +417,18 @@ public class Peer {
|
|||||||
}
|
}
|
||||||
if (maybeHandleRequestedData(tx))
|
if (maybeHandleRequestedData(tx))
|
||||||
return;
|
return;
|
||||||
// Tell all listeners (like wallets) about this tx so they can decide whether to keep it or not. If no
|
// Tell all wallets about this tx so they can check if it's relevant or not.
|
||||||
// listener keeps a reference around then the memory pool will forget about it after a while too because
|
for (ListIterator<Wallet> it = wallets.listIterator(); it.hasNext();) {
|
||||||
// it uses weak references.
|
Wallet wallet = it.next();
|
||||||
|
try {
|
||||||
|
wallet.receivePending(tx);
|
||||||
|
} catch (VerificationException e) {
|
||||||
|
log.error("Wallet failed to verify tx", e);
|
||||||
|
// Carry on, listeners may still want to know.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Tell all listeners about this tx so they can decide whether to keep it or not. If no listener keeps a
|
||||||
|
// reference around then the memory pool will forget about it after a while too because it uses weak references.
|
||||||
final Transaction ftx = tx;
|
final Transaction ftx = tx;
|
||||||
EventListenerInvoker.invoke(eventListeners, new EventListenerInvoker<PeerEventListener>() {
|
EventListenerInvoker.invoke(eventListeners, new EventListenerInvoker<PeerEventListener>() {
|
||||||
@Override
|
@Override
|
||||||
@ -863,12 +876,12 @@ public class Peer {
|
|||||||
* independently, otherwise the wallet will receive duplicate notifications.
|
* independently, otherwise the wallet will receive duplicate notifications.
|
||||||
*/
|
*/
|
||||||
public void addWallet(Wallet wallet) {
|
public void addWallet(Wallet wallet) {
|
||||||
addEventListener(wallet.getPeerEventListener());
|
wallets.add(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Unlinks the given wallet from peer. See {@link Peer#addWallet(Wallet)}. */
|
/** Unlinks the given wallet from peer. See {@link Peer#addWallet(Wallet)}. */
|
||||||
public void removeWallet(Wallet wallet) {
|
public void removeWallet(Wallet wallet) {
|
||||||
removeEventListener(wallet.getPeerEventListener());
|
wallets.remove(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,7 +542,6 @@ public class PeerGroup extends AbstractIdleService {
|
|||||||
public synchronized void addWallet(Wallet wallet) {
|
public synchronized void addWallet(Wallet wallet) {
|
||||||
Preconditions.checkNotNull(wallet);
|
Preconditions.checkNotNull(wallet);
|
||||||
wallets.add(wallet);
|
wallets.add(wallet);
|
||||||
addEventListener(wallet.getPeerEventListener());
|
|
||||||
announcePendingWalletTransactions(Collections.singletonList(wallet), peers);
|
announcePendingWalletTransactions(Collections.singletonList(wallet), peers);
|
||||||
|
|
||||||
// Don't bother downloading block bodies before the oldest keys in all our wallets. Make sure we recalculate
|
// Don't bother downloading block bodies before the oldest keys in all our wallets. Make sure we recalculate
|
||||||
@ -609,7 +608,6 @@ public class PeerGroup extends AbstractIdleService {
|
|||||||
if (wallet == null)
|
if (wallet == null)
|
||||||
throw new IllegalArgumentException("wallet is null");
|
throw new IllegalArgumentException("wallet is null");
|
||||||
wallets.remove(wallet);
|
wallets.remove(wallet);
|
||||||
removeEventListener(wallet.getPeerEventListener());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -854,13 +852,17 @@ public class PeerGroup extends AbstractIdleService {
|
|||||||
if (downloadPeer != null) {
|
if (downloadPeer != null) {
|
||||||
log.info("Unsetting download peer: {}", downloadPeer);
|
log.info("Unsetting download peer: {}", downloadPeer);
|
||||||
downloadPeer.setDownloadData(false);
|
downloadPeer.setDownloadData(false);
|
||||||
|
for (Wallet wallet : wallets)
|
||||||
|
downloadPeer.removeWallet(wallet);
|
||||||
}
|
}
|
||||||
downloadPeer = peer;
|
downloadPeer = peer;
|
||||||
if (downloadPeer != null) {
|
if (downloadPeer != null) {
|
||||||
log.info("Setting download peer: {}", downloadPeer);
|
log.info("Setting download peer: {}", downloadPeer);
|
||||||
downloadPeer.setDownloadData(true);
|
downloadPeer.setDownloadData(true);
|
||||||
if (chain != null)
|
downloadPeer.setDownloadParameters(fastCatchupTimeSecs, bloomFilter != null);
|
||||||
downloadPeer.setDownloadParameters(fastCatchupTimeSecs, bloomFilter != null);
|
// TODO: The peer should calculate the fast catchup time from the added wallets here.
|
||||||
|
for (Wallet wallet : wallets)
|
||||||
|
downloadPeer.addWallet(wallet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2201,34 +2201,6 @@ public class Wallet implements Serializable, BlockChainListener {
|
|||||||
}
|
}
|
||||||
return earliestTime;
|
return earliestTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This object is used to receive events from a Peer or PeerGroup. Currently it is only used to receive
|
|
||||||
// transactions. Note that it does NOT pay attention to block message because they will be received from the
|
|
||||||
// BlockChain object along with extra data we need for correct handling of re-orgs.
|
|
||||||
private transient PeerEventListener peerEventListener;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The returned object can be used to connect the wallet to a {@link Peer} or {@link PeerGroup} in order to
|
|
||||||
* receive and process blocks and transactions.
|
|
||||||
*/
|
|
||||||
synchronized PeerEventListener getPeerEventListener() {
|
|
||||||
if (peerEventListener == null) {
|
|
||||||
// Instantiate here to avoid issues with wallets resurrected from serialized copies.
|
|
||||||
peerEventListener = new AbstractPeerEventListener() {
|
|
||||||
@Override
|
|
||||||
public void onTransaction(Peer peer, Transaction t) {
|
|
||||||
// Runs locked on a peer thread.
|
|
||||||
try {
|
|
||||||
receivePending(t);
|
|
||||||
} catch (VerificationException e) {
|
|
||||||
log.warn("Received broadcast transaction that does not validate: {}", t);
|
|
||||||
log.warn("VerificationException caught", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return peerEventListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Sha256Hash getLastBlockSeenHash() {
|
public Sha256Hash getLastBlockSeenHash() {
|
||||||
return lastBlockSeenHash;
|
return lastBlockSeenHash;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user