mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-12 10:15:52 +00:00
Automatically set up fast catchup time on a PeerGroup when wallets are added. Resolves issue 183.
This commit is contained in:
parent
adb46c7dcb
commit
1f96f850e0
@ -91,9 +91,14 @@ public abstract class AbstractWalletEventListener implements WalletEventListener
|
|||||||
onChange();
|
onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onKeyAdded(ECKey key) {
|
||||||
|
onChange();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by the other default method implementations when something (anything) changes in the wallet.
|
* Called by the other default method implementations when something (anything) changes in the wallet.
|
||||||
*/
|
*/
|
||||||
public void onChange() {
|
public void onChange() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -339,18 +339,41 @@ public class PeerGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link the given wallet to this PeerGroup. This is used for two purposes:
|
* <p>Link the given wallet to this PeerGroup. This is used for three purposes:</p>
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>So the wallet receives broadcast transactions.</li>
|
* <li>So the wallet receives broadcast transactions.</li>
|
||||||
* <li>Announcing pending transactions that didn't get into the chain yet to our peers.</li>
|
* <li>Announcing pending transactions that didn't get into the chain yet to our peers.</li>
|
||||||
|
* <li>Set the fast catchup time using {@link PeerGroup#setFastCatchupTimeSecs(long)}, to optimize chain
|
||||||
|
* download.</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
|
* <p>Note that this should be done before chain download commences because if you add a wallet with keys earlier
|
||||||
|
* than the current chain head, the relevant parts of the chain won't be redownloaded for you.</p>
|
||||||
*/
|
*/
|
||||||
public synchronized void addWallet(Wallet wallet) {
|
public synchronized void addWallet(Wallet wallet) {
|
||||||
if (wallet == null)
|
Preconditions.checkNotNull(wallet);
|
||||||
throw new IllegalArgumentException("wallet is null");
|
|
||||||
wallets.add(wallet);
|
wallets.add(wallet);
|
||||||
addEventListener(wallet.getPeerEventListener());
|
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
|
||||||
|
// if a key is added. Of course, by then we may have downloaded the chain already. Ideally adding keys would
|
||||||
|
// automatically rewind the block chain and redownload the blocks to find transactions relevant to those keys,
|
||||||
|
// all transparently and in the background. But we are a long way from that yet.
|
||||||
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
|
@Override
|
||||||
|
public void onKeyAdded(ECKey key) {
|
||||||
|
recalculateFastCatchupTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
recalculateFastCatchupTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void recalculateFastCatchupTime() {
|
||||||
|
long earliestKeyTime = Long.MAX_VALUE;
|
||||||
|
for (Wallet w : wallets) {
|
||||||
|
earliestKeyTime = Math.min(earliestKeyTime, w.getEarliestKeyCreationTime());
|
||||||
|
}
|
||||||
|
setFastCatchupTimeSecs(earliestKeyTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -738,6 +761,16 @@ public class PeerGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current fast catchup time. The contents of blocks before this time won't be downloaded as they
|
||||||
|
* cannot contain any interesting transactions. If you use {@link PeerGroup#addWallet(Wallet)} this just returns
|
||||||
|
* the min of the wallets earliest key times.
|
||||||
|
* @return a time in seconds since the epoch
|
||||||
|
*/
|
||||||
|
public synchronized long getFastCatchupTimeSecs() {
|
||||||
|
return fastCatchupTimeSecs;
|
||||||
|
}
|
||||||
|
|
||||||
protected synchronized void handlePeerDeath(final Peer peer) {
|
protected synchronized void handlePeerDeath(final Peer peer) {
|
||||||
if (!isRunning()) {
|
if (!isRunning()) {
|
||||||
log.info("Peer death while shutting down");
|
log.info("Peer death while shutting down");
|
||||||
|
@ -1194,9 +1194,15 @@ public class Wallet implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Adds the given ECKey to the wallet. There is currently no way to delete keys (that would result in coin loss).
|
* Adds the given ECKey to the wallet. There is currently no way to delete keys (that would result in coin loss).
|
||||||
*/
|
*/
|
||||||
public synchronized void addKey(ECKey key) {
|
public synchronized void addKey(final ECKey key) {
|
||||||
checkArgument(!keychain.contains(key), "Key already present");
|
checkArgument(!keychain.contains(key), "Key already present");
|
||||||
keychain.add(key);
|
keychain.add(key);
|
||||||
|
EventListenerInvoker.invoke(eventListeners, new EventListenerInvoker<WalletEventListener>() {
|
||||||
|
@Override
|
||||||
|
public void invoke(WalletEventListener listener) {
|
||||||
|
listener.onKeyAdded(key);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,4 +99,10 @@ public interface WalletEventListener {
|
|||||||
* @param tx
|
* @param tx
|
||||||
*/
|
*/
|
||||||
void onTransactionConfidenceChanged(Wallet wallet, Transaction tx);
|
void onTransactionConfidenceChanged(Wallet wallet, Transaction tx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the {@link Wallet#addKey(ECKey)} method on whatever the calling thread was.
|
||||||
|
* @param key
|
||||||
|
*/
|
||||||
|
void onKeyAdded(ECKey key);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import org.junit.Test;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@ -306,6 +307,25 @@ public class PeerGroupTest extends TestWithNetworkConnections {
|
|||||||
assertTrue(n3.outbound() instanceof InventoryMessage);
|
assertTrue(n3.outbound() instanceof InventoryMessage);
|
||||||
peerGroup.stop();
|
peerGroup.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWalletCatchupTime() throws Exception {
|
||||||
|
// Check the fast catchup time was initialized to something around the current runtime. The wallet was
|
||||||
|
// already added to the peer in setup.
|
||||||
|
long time = new Date().getTime() / 1000;
|
||||||
|
assertTrue(peerGroup.getFastCatchupTimeSecs() > time - 10000);
|
||||||
|
Wallet w2 = new Wallet(params);
|
||||||
|
ECKey key1 = new ECKey();
|
||||||
|
key1.setCreationTimeSeconds(time - 86400); // One day ago.
|
||||||
|
w2.addKey(key1);
|
||||||
|
peerGroup.addWallet(w2);
|
||||||
|
assertEquals(peerGroup.getFastCatchupTimeSecs(), time - 86400);
|
||||||
|
// Adding a key to the wallet should update the fast catchup time.
|
||||||
|
ECKey key2 = new ECKey();
|
||||||
|
key2.setCreationTimeSeconds(time - 100000);
|
||||||
|
w2.addKey(key2);
|
||||||
|
assertEquals(peerGroup.getFastCatchupTimeSecs(), time - 100000);
|
||||||
|
}
|
||||||
|
|
||||||
private void disconnectAndWait(MockNetworkConnection conn) throws IOException, InterruptedException {
|
private void disconnectAndWait(MockNetworkConnection conn) throws IOException, InterruptedException {
|
||||||
conn.disconnect();
|
conn.disconnect();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user