3
0
mirror of https://github.com/Qortal/altcoinj.git synced 2025-02-12 10:15:52 +00:00

Fix bugs and misc review comments from Harold Hoyer's key lookahead pull request. Still needed: unit tests.

This commit is contained in:
Mike Hearn 2014-05-19 17:33:59 +02:00
parent 5726b97f70
commit c63f5f7553
2 changed files with 19 additions and 19 deletions

View File

@ -480,14 +480,12 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
/** See {@link com.google.bitcoin.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */ /** See {@link com.google.bitcoin.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */
public int getKeychainLookaheadThreshold() { public int getKeychainLookaheadThreshold() {
int threshold = 0;
lock.lock(); lock.lock();
try { try {
threshold = keychain.getLookaheadThreshold(); return keychain.getLookaheadThreshold();
} finally { } finally {
lock.unlock(); lock.unlock();
} }
return threshold;
} }
/** /**
@ -1257,7 +1255,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset, bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset,
block != null ? block.getHeader().getHash() : "(unit test)"); block != null ? block.getHeader().getHash() : "(unit test)");
// mark the deterministic keys in this transaction as used // Inform the key chains that the issued keys were observed in a transaction, so they know to
// calculate more keys for the next Bloom filters.
markKeysAsUsed(tx); markKeysAsUsed(tx);
onWalletChangedSuppressions++; onWalletChangedSuppressions++;

View File

@ -34,7 +34,6 @@ import javax.annotation.Nullable;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -101,7 +100,10 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
// chains, it will be calculated on demand from the number of loaded keys. // chains, it will be calculated on demand from the number of loaded keys.
private static final int LAZY_CALCULATE_LOOKAHEAD = -1; private static final int LAZY_CALCULATE_LOOKAHEAD = -1;
private int lookaheadSize = 100; private int lookaheadSize = 100;
private int lookaheadThreshold = 33; // The lookahead threshold causes us to batch up creation of new keys to minimize the frequency of Bloom filter
// regenerations, which are expensive and will (in future) trigger chain download stalls/retries. One third
// is an efficiency tradeoff.
private int lookaheadThreshold = lookaheadSize / 3;
// The parent keys for external keys (handed out to other people) and internal keys (used for change addresses). // The parent keys for external keys (handed out to other people) and internal keys (used for change addresses).
private DeterministicKey externalKey, internalKey; private DeterministicKey externalKey, internalKey;
@ -298,19 +300,19 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
/** /**
* Mark the DeterministicKey as used. * Mark the DeterministicKey as used.
* Also correct the issued{Internal|External}Keys counter, because all lower children seem to be requested already. * Also correct the issued{Internal|External}Keys counter, because all lower children seem to be requested already.
* If the counter was updated, we also might want to update the lookahead keys. * If the counter was updated, we also might trigger lookahead.
*/ */
public DeterministicKey markKeyAsUsed(DeterministicKey k) { public DeterministicKey markKeyAsUsed(DeterministicKey k) {
int numchilds = k.getChildNumber().i() + 1; int numChildren = k.getChildNumber().i() + 1;
if (k.getParent() == internalKey) { if (k.getParent() == internalKey) {
if (issuedInternalKeys < numchilds) { if (issuedInternalKeys < numChildren) {
issuedInternalKeys = numchilds; issuedInternalKeys = numChildren;
maybeLookAhead(); maybeLookAhead();
} }
} else if (k.getParent() == externalKey) { } else if (k.getParent() == externalKey) {
if (issuedExternalKeys < numchilds) { if (issuedExternalKeys < numChildren) {
issuedExternalKeys = numchilds; issuedExternalKeys = numChildren;
maybeLookAhead(); maybeLookAhead();
} }
} }
@ -739,10 +741,9 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
*/ */
public void setLookaheadThreshold(int num) { public void setLookaheadThreshold(int num) {
lock.lock(); lock.lock();
try {
if (num >= lookaheadSize) if (num >= lookaheadSize)
throw new IllegalArgumentException("Threshold larger or equal to the lookaheadSize"); throw new IllegalArgumentException("Threshold larger or equal to the lookaheadSize");
try {
this.lookaheadThreshold = num; this.lookaheadThreshold = num;
} finally { } finally {
lock.unlock(); lock.unlock();
@ -783,7 +784,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
* Pre-generate enough keys to reach the lookahead size, but only if there are more than the lookaheadThreshold to * Pre-generate enough keys to reach the lookahead size, but only if there are more than the lookaheadThreshold to
* be generated, so that the Bloom filter does not have to be regenerated that often. * be generated, so that the Bloom filter does not have to be regenerated that often.
* *
* Returned keys must be inserted into the basic key chain. * The return mutable list of keys must be inserted into the basic key chain.
*/ */
private List<DeterministicKey> maybeLookAhead(DeterministicKey parent, int issued) { private List<DeterministicKey> maybeLookAhead(DeterministicKey parent, int issued) {
checkState(lock.isHeldByCurrentThread()); checkState(lock.isHeldByCurrentThread());
@ -796,7 +797,7 @@ public class DeterministicKeyChain implements EncryptableKeyChain {
/* Even if needed is negative, we have more than enough */ /* Even if needed is negative, we have more than enough */
if (needed <= getLookaheadThreshold()) if (needed <= getLookaheadThreshold())
return Collections.emptyList(); return new ArrayList<DeterministicKey>();
List<DeterministicKey> result = new ArrayList<DeterministicKey>(needed); List<DeterministicKey> result = new ArrayList<DeterministicKey>(needed);
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();