mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-13 02:35:52 +00:00
Wallet: Rename attribute "keychain" to "keyChainGroup".
This commit is contained in:
parent
200f2368c6
commit
fe7b703237
@ -96,10 +96,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
private static final Logger log = LoggerFactory.getLogger(Wallet.class);
|
private static final Logger log = LoggerFactory.getLogger(Wallet.class);
|
||||||
private static final int MINIMUM_BLOOM_DATA_LENGTH = 8;
|
private static final int MINIMUM_BLOOM_DATA_LENGTH = 8;
|
||||||
|
|
||||||
// Ordering: lock > keychainLock. Keychain is protected separately to allow fast querying of current receive address
|
// Ordering: lock > keyChainGroupLock. KeyChainGroup is protected separately to allow fast querying of current receive address
|
||||||
// even if the wallet itself is busy e.g. saving or processing a big reorg. Useful for reducing UI latency.
|
// even if the wallet itself is busy e.g. saving or processing a big reorg. Useful for reducing UI latency.
|
||||||
protected final ReentrantLock lock = Threading.lock("wallet");
|
protected final ReentrantLock lock = Threading.lock("wallet");
|
||||||
protected final ReentrantLock keychainLock = Threading.lock("wallet-keychain");
|
protected final ReentrantLock keyChainGroupLock = Threading.lock("wallet-keychaingroup");
|
||||||
|
|
||||||
// The various pools below give quick access to wallet-relevant transactions by the state they're in:
|
// The various pools below give quick access to wallet-relevant transactions by the state they're in:
|
||||||
//
|
//
|
||||||
@ -148,10 +148,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
|
|
||||||
// The key chain group is not thread safe, and generally the whole hierarchy of objects should not be mutated
|
// The key chain group is not thread safe, and generally the whole hierarchy of objects should not be mutated
|
||||||
// outside the wallet lock. So don't expose this object directly via any accessors!
|
// outside the wallet lock. So don't expose this object directly via any accessors!
|
||||||
@GuardedBy("keychainLock") protected KeyChainGroup keychain;
|
@GuardedBy("keyChainGroupLock") protected KeyChainGroup keyChainGroup;
|
||||||
|
|
||||||
// A list of scripts watched by this wallet.
|
// A list of scripts watched by this wallet.
|
||||||
@GuardedBy("keychainLock") private Set<Script> watchedScripts;
|
@GuardedBy("keyChainGroupLock") private Set<Script> watchedScripts;
|
||||||
|
|
||||||
protected final Context context;
|
protected final Context context;
|
||||||
protected final NetworkParameters params;
|
protected final NetworkParameters params;
|
||||||
@ -267,14 +267,14 @@ public class Wallet extends BaseTaggableObject
|
|||||||
public Wallet(Context context, KeyChainGroup keyChainGroup) {
|
public Wallet(Context context, KeyChainGroup keyChainGroup) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.params = context.getParams();
|
this.params = context.getParams();
|
||||||
this.keychain = checkNotNull(keyChainGroup);
|
this.keyChainGroup = checkNotNull(keyChainGroup);
|
||||||
if (params == UnitTestParams.get())
|
if (params == UnitTestParams.get())
|
||||||
this.keychain.setLookaheadSize(5); // Cut down excess computation for unit tests.
|
this.keyChainGroup.setLookaheadSize(5); // Cut down excess computation for unit tests.
|
||||||
// If this keychain was created fresh just now (new wallet), make HD so a backup can be made immediately
|
// If this keyChainGroup was created fresh just now (new wallet), make HD so a backup can be made immediately
|
||||||
// without having to call current/freshReceiveKey. If there are already keys in the chain of any kind then
|
// without having to call current/freshReceiveKey. If there are already keys in the chain of any kind then
|
||||||
// we're probably being deserialized so leave things alone: the API user can upgrade later.
|
// we're probably being deserialized so leave things alone: the API user can upgrade later.
|
||||||
if (this.keychain.numKeys() == 0)
|
if (this.keyChainGroup.numKeys() == 0)
|
||||||
this.keychain.createAndActivateNewHDChain();
|
this.keyChainGroup.createAndActivateNewHDChain();
|
||||||
watchedScripts = Sets.newHashSet();
|
watchedScripts = Sets.newHashSet();
|
||||||
unspent = new HashMap<Sha256Hash, Transaction>();
|
unspent = new HashMap<Sha256Hash, Transaction>();
|
||||||
spent = new HashMap<Sha256Hash, Transaction>();
|
spent = new HashMap<Sha256Hash, Transaction>();
|
||||||
@ -325,8 +325,8 @@ public class Wallet extends BaseTaggableObject
|
|||||||
/**
|
/**
|
||||||
* Gets the active keychain via {@link KeyChainGroup#getActiveKeyChain()}
|
* Gets the active keychain via {@link KeyChainGroup#getActiveKeyChain()}
|
||||||
*/
|
*/
|
||||||
public DeterministicKeyChain getActiveKeychain() {
|
public DeterministicKeyChain getActiveKeyChain() {
|
||||||
return keychain.getActiveKeyChain();
|
return keyChainGroup.getActiveKeyChain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -368,12 +368,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* a different key (for each purpose independently).
|
* a different key (for each purpose independently).
|
||||||
*/
|
*/
|
||||||
public DeterministicKey currentKey(KeyChain.KeyPurpose purpose) {
|
public DeterministicKey currentKey(KeyChain.KeyPurpose purpose) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.currentKey(purpose);
|
return keyChainGroup.currentKey(purpose);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,12 +389,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* Returns address for a {@link #currentKey(org.bitcoinj.wallet.KeyChain.KeyPurpose)}
|
* Returns address for a {@link #currentKey(org.bitcoinj.wallet.KeyChain.KeyPurpose)}
|
||||||
*/
|
*/
|
||||||
public Address currentAddress(KeyChain.KeyPurpose purpose) {
|
public Address currentAddress(KeyChain.KeyPurpose purpose) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.currentAddress(purpose);
|
return keyChainGroup.currentAddress(purpose);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,12 +428,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
public List<DeterministicKey> freshKeys(KeyChain.KeyPurpose purpose, int numberOfKeys) {
|
public List<DeterministicKey> freshKeys(KeyChain.KeyPurpose purpose, int numberOfKeys) {
|
||||||
List<DeterministicKey> keys;
|
List<DeterministicKey> keys;
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
keys = keychain.freshKeys(purpose, numberOfKeys);
|
keys = keyChainGroup.freshKeys(purpose, numberOfKeys);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
// Do we really need an immediate hard save? Arguably all this is doing is saving the 'current' key
|
// Do we really need an immediate hard save? Arguably all this is doing is saving the 'current' key
|
||||||
// and that's not quite so important, so we could coalesce for more performance.
|
// and that's not quite so important, so we could coalesce for more performance.
|
||||||
@ -454,11 +454,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
public Address freshAddress(KeyChain.KeyPurpose purpose) {
|
public Address freshAddress(KeyChain.KeyPurpose purpose) {
|
||||||
Address key;
|
Address key;
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
key = keychain.freshAddress(purpose);
|
key = keyChainGroup.freshAddress(purpose);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
return key;
|
return key;
|
||||||
@ -477,11 +477,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* {@link #currentReceiveKey()} or {@link #currentReceiveAddress()}.
|
* {@link #currentReceiveKey()} or {@link #currentReceiveAddress()}.
|
||||||
*/
|
*/
|
||||||
public List<ECKey> getIssuedReceiveKeys() {
|
public List<ECKey> getIssuedReceiveKeys() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.getActiveKeyChain().getIssuedReceiveKeys();
|
return keyChainGroup.getActiveKeyChain().getIssuedReceiveKeys();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,11 +505,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* you automatically the first time a new key is requested (this happens when spending due to the change address).
|
* you automatically the first time a new key is requested (this happens when spending due to the change address).
|
||||||
*/
|
*/
|
||||||
public void upgradeToDeterministic(@Nullable KeyParameter aesKey) throws DeterministicUpgradeRequiresPassword {
|
public void upgradeToDeterministic(@Nullable KeyParameter aesKey) throws DeterministicUpgradeRequiresPassword {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
keychain.upgradeToDeterministic(vKeyRotationTimestamp, aesKey);
|
keyChainGroup.upgradeToDeterministic(vKeyRotationTimestamp, aesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -519,11 +519,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* that would require a new address or key.
|
* that would require a new address or key.
|
||||||
*/
|
*/
|
||||||
public boolean isDeterministicUpgradeRequired() {
|
public boolean isDeterministicUpgradeRequired() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.isDeterministicUpgradeRequired();
|
return keyChainGroup.isDeterministicUpgradeRequired();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,10 +531,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
maybeUpgradeToHD(null);
|
maybeUpgradeToHD(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GuardedBy("keychainLock")
|
@GuardedBy("keyChainGroupLock")
|
||||||
private void maybeUpgradeToHD(@Nullable KeyParameter aesKey) throws DeterministicUpgradeRequiresPassword {
|
private void maybeUpgradeToHD(@Nullable KeyParameter aesKey) throws DeterministicUpgradeRequiresPassword {
|
||||||
checkState(keychainLock.isHeldByCurrentThread());
|
checkState(keyChainGroupLock.isHeldByCurrentThread());
|
||||||
if (keychain.isDeterministicUpgradeRequired()) {
|
if (keyChainGroup.isDeterministicUpgradeRequired()) {
|
||||||
log.info("Upgrade to HD wallets is required, attempting to do so.");
|
log.info("Upgrade to HD wallets is required, attempting to do so.");
|
||||||
try {
|
try {
|
||||||
upgradeToDeterministic(aesKey);
|
upgradeToDeterministic(aesKey);
|
||||||
@ -550,11 +550,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* Returns a snapshot of the watched scripts. This view is not live.
|
* Returns a snapshot of the watched scripts. This view is not live.
|
||||||
*/
|
*/
|
||||||
public List<Script> getWatchedScripts() {
|
public List<Script> getWatchedScripts() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return new ArrayList<Script>(watchedScripts);
|
return new ArrayList<Script>(watchedScripts);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -564,23 +564,23 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @return Whether the key was removed or not.
|
* @return Whether the key was removed or not.
|
||||||
*/
|
*/
|
||||||
public boolean removeKey(ECKey key) {
|
public boolean removeKey(ECKey key) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.removeImportedKey(key);
|
return keyChainGroup.removeImportedKey(key);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of keys in the key chain, including lookahead keys.
|
* Returns the number of keys in the key chain group, including lookahead keys.
|
||||||
*/
|
*/
|
||||||
public int getKeychainSize() {
|
public int getKeyChainGroupSize() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.numKeys();
|
return keyChainGroup.numKeys();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,11 +588,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* Returns a list of the non-deterministic keys that have been imported into the wallet, or the empty list if none.
|
* Returns a list of the non-deterministic keys that have been imported into the wallet, or the empty list if none.
|
||||||
*/
|
*/
|
||||||
public List<ECKey> getImportedKeys() {
|
public List<ECKey> getImportedKeys() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.getImportedKeys();
|
return keyChainGroup.getImportedKeys();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -639,11 +639,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
// API usage check.
|
// API usage check.
|
||||||
checkNoDeterministicKeys(keys);
|
checkNoDeterministicKeys(keys);
|
||||||
int result;
|
int result;
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
result = keychain.importKeys(keys);
|
result = keyChainGroup.importKeys(keys);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
return result;
|
return result;
|
||||||
@ -658,23 +658,23 @@ public class Wallet extends BaseTaggableObject
|
|||||||
|
|
||||||
/** Takes a list of keys and a password, then encrypts and imports them in one step using the current keycrypter. */
|
/** Takes a list of keys and a password, then encrypts and imports them in one step using the current keycrypter. */
|
||||||
public int importKeysAndEncrypt(final List<ECKey> keys, CharSequence password) {
|
public int importKeysAndEncrypt(final List<ECKey> keys, CharSequence password) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
checkNotNull(getKeyCrypter(), "Wallet is not encrypted");
|
checkNotNull(getKeyCrypter(), "Wallet is not encrypted");
|
||||||
return importKeysAndEncrypt(keys, getKeyCrypter().deriveKey(password));
|
return importKeysAndEncrypt(keys, getKeyCrypter().deriveKey(password));
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Takes a list of keys and an AES key, then encrypts and imports them in one step using the current keycrypter. */
|
/** Takes a list of keys and an AES key, then encrypts and imports them in one step using the current keycrypter. */
|
||||||
public int importKeysAndEncrypt(final List<ECKey> keys, KeyParameter aesKey) {
|
public int importKeysAndEncrypt(final List<ECKey> keys, KeyParameter aesKey) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
checkNoDeterministicKeys(keys);
|
checkNoDeterministicKeys(keys);
|
||||||
return keychain.importKeysAndEncrypt(keys, aesKey);
|
return keyChainGroup.importKeysAndEncrypt(keys, aesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,53 +690,53 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void addAndActivateHDChain(DeterministicKeyChain chain) {
|
public void addAndActivateHDChain(DeterministicKeyChain chain) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
keychain.addAndActivateHDChain(chain);
|
keyChainGroup.addAndActivateHDChain(chain);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadSize(int)} for more info on this. */
|
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadSize(int)} for more info on this. */
|
||||||
public void setKeychainLookaheadSize(int lookaheadSize) {
|
public void setKeyChainGroupLookaheadSize(int lookaheadSize) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
keychain.setLookaheadSize(lookaheadSize);
|
keyChainGroup.setLookaheadSize(lookaheadSize);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadSize(int)} for more info on this. */
|
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadSize(int)} for more info on this. */
|
||||||
public int getKeychainLookaheadSize() {
|
public int getKeyChainGroupLookaheadSize() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.getLookaheadSize();
|
return keyChainGroup.getLookaheadSize();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */
|
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */
|
||||||
public void setKeychainLookaheadThreshold(int num) {
|
public void setKeyChainGroupLookaheadThreshold(int num) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
keychain.setLookaheadThreshold(num);
|
keyChainGroup.setLookaheadThreshold(num);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */
|
/** See {@link org.bitcoinj.wallet.DeterministicKeyChain#setLookaheadThreshold(int)} for more info on this. */
|
||||||
public int getKeychainLookaheadThreshold() {
|
public int getKeyChainGroupLookaheadThreshold() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.getLookaheadThreshold();
|
return keyChainGroup.getLookaheadThreshold();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,12 +747,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* zero key in the recommended BIP32 hierarchy.
|
* zero key in the recommended BIP32 hierarchy.
|
||||||
*/
|
*/
|
||||||
public DeterministicKey getWatchingKey() {
|
public DeterministicKey getWatchingKey() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.getActiveKeyChain().getWatchingKey();
|
return keyChainGroup.getActiveKeyChain().getWatchingKey();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -764,12 +764,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* if there are no keys, or if there is a mix between watching and non-watching keys.
|
* if there are no keys, or if there is a mix between watching and non-watching keys.
|
||||||
*/
|
*/
|
||||||
public boolean isWatching() {
|
public boolean isWatching() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.isWatching();
|
return keyChainGroup.isWatching();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,7 +828,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
public int addWatchedScripts(final List<Script> scripts) {
|
public int addWatchedScripts(final List<Script> scripts) {
|
||||||
int added = 0;
|
int added = 0;
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
for (final Script script : scripts) {
|
for (final Script script : scripts) {
|
||||||
// Script.equals/hashCode() only takes into account the program bytes, so this step lets the user replace
|
// Script.equals/hashCode() only takes into account the program bytes, so this step lets the user replace
|
||||||
@ -841,7 +841,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
added++;
|
added++;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
if (added > 0) {
|
if (added > 0) {
|
||||||
queueOnScriptsChanged(scripts, true);
|
queueOnScriptsChanged(scripts, true);
|
||||||
@ -902,7 +902,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* Returns all addresses watched by this wallet.
|
* Returns all addresses watched by this wallet.
|
||||||
*/
|
*/
|
||||||
public List<Address> getWatchedAddresses() {
|
public List<Address> getWatchedAddresses() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
List<Address> addresses = new LinkedList<Address>();
|
List<Address> addresses = new LinkedList<Address>();
|
||||||
for (Script script : watchedScripts)
|
for (Script script : watchedScripts)
|
||||||
@ -910,7 +910,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
addresses.add(script.getToAddress(params));
|
addresses.add(script.getToAddress(params));
|
||||||
return addresses;
|
return addresses;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,21 +923,21 @@ public class Wallet extends BaseTaggableObject
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ECKey findKeyFromPubHash(byte[] pubkeyHash) {
|
public ECKey findKeyFromPubHash(byte[] pubkeyHash) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.findKeyFromPubHash(pubkeyHash);
|
return keyChainGroup.findKeyFromPubHash(pubkeyHash);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the given key is in the wallet, false otherwise. Currently an O(N) operation. */
|
/** Returns true if the given key is in the wallet, false otherwise. Currently an O(N) operation. */
|
||||||
public boolean hasKey(ECKey key) {
|
public boolean hasKey(ECKey key) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.hasKey(key);
|
return keyChainGroup.hasKey(key);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,11 +950,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public boolean isWatchedScript(Script script) {
|
public boolean isWatchedScript(Script script) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return watchedScripts.contains(script);
|
return watchedScripts.contains(script);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,11 +965,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public ECKey findKeyFromPubKey(byte[] pubkey) {
|
public ECKey findKeyFromPubKey(byte[] pubkey) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.findKeyFromPubKey(pubkey);
|
return keyChainGroup.findKeyFromPubKey(pubkey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -980,17 +980,17 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locates a redeem data (redeem script and keys) from the keychain given the hash of the script.
|
* Locates a redeem data (redeem script and keys) from the keyChainGroup given the hash of the script.
|
||||||
* Returns RedeemData object or null if no such data was found.
|
* Returns RedeemData object or null if no such data was found.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) {
|
public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.findRedeemDataFromScriptHash(payToScriptHash);
|
return keyChainGroup.findRedeemDataFromScriptHash(payToScriptHash);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1005,20 +1005,20 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* See {@link org.bitcoinj.wallet.DeterministicKeyChain#markKeyAsUsed(DeterministicKey)} for more info on this.
|
* See {@link org.bitcoinj.wallet.DeterministicKeyChain#markKeyAsUsed(DeterministicKey)} for more info on this.
|
||||||
*/
|
*/
|
||||||
private void markKeysAsUsed(Transaction tx) {
|
private void markKeysAsUsed(Transaction tx) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
for (TransactionOutput o : tx.getOutputs()) {
|
for (TransactionOutput o : tx.getOutputs()) {
|
||||||
try {
|
try {
|
||||||
Script script = o.getScriptPubKey();
|
Script script = o.getScriptPubKey();
|
||||||
if (script.isSentToRawPubKey()) {
|
if (script.isSentToRawPubKey()) {
|
||||||
byte[] pubkey = script.getPubKey();
|
byte[] pubkey = script.getPubKey();
|
||||||
keychain.markPubKeyAsUsed(pubkey);
|
keyChainGroup.markPubKeyAsUsed(pubkey);
|
||||||
} else if (script.isSentToAddress()) {
|
} else if (script.isSentToAddress()) {
|
||||||
byte[] pubkeyHash = script.getPubKeyHash();
|
byte[] pubkeyHash = script.getPubKeyHash();
|
||||||
keychain.markPubKeyHashAsUsed(pubkeyHash);
|
keyChainGroup.markPubKeyHashAsUsed(pubkeyHash);
|
||||||
} else if (script.isPayToScriptHash()) {
|
} else if (script.isPayToScriptHash()) {
|
||||||
Address a = Address.fromP2SHScript(tx.getParams(), script);
|
Address a = Address.fromP2SHScript(tx.getParams(), script);
|
||||||
keychain.markP2SHAddressAsUsed(a);
|
keyChainGroup.markP2SHAddressAsUsed(a);
|
||||||
}
|
}
|
||||||
} catch (ScriptException e) {
|
} catch (ScriptException e) {
|
||||||
// Just means we didn't understand the output of this transaction: ignore it.
|
// Just means we didn't understand the output of this transaction: ignore it.
|
||||||
@ -1026,7 +1026,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1035,14 +1035,14 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @throws org.bitcoinj.core.ECKey.MissingPrivateKeyException if the seed is unavailable (watching wallet)
|
* @throws org.bitcoinj.core.ECKey.MissingPrivateKeyException if the seed is unavailable (watching wallet)
|
||||||
*/
|
*/
|
||||||
public DeterministicSeed getKeyChainSeed() {
|
public DeterministicSeed getKeyChainSeed() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
DeterministicSeed seed = keychain.getActiveKeyChain().getSeed();
|
DeterministicSeed seed = keyChainGroup.getActiveKeyChain().getSeed();
|
||||||
if (seed == null)
|
if (seed == null)
|
||||||
throw new ECKey.MissingPrivateKeyException();
|
throw new ECKey.MissingPrivateKeyException();
|
||||||
return seed;
|
return seed;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,12 +1051,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* use currentReceiveKey/freshReceiveKey instead.
|
* use currentReceiveKey/freshReceiveKey instead.
|
||||||
*/
|
*/
|
||||||
public DeterministicKey getKeyByPath(List<ChildNumber> path) {
|
public DeterministicKey getKeyByPath(List<ChildNumber> path) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
maybeUpgradeToHD();
|
maybeUpgradeToHD();
|
||||||
return keychain.getActiveKeyChain().getKeyByPath(path, false);
|
return keyChainGroup.getActiveKeyChain().getKeyByPath(path, false);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1066,12 +1066,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* parameters to derive a key from the given password.
|
* parameters to derive a key from the given password.
|
||||||
*/
|
*/
|
||||||
public void encrypt(CharSequence password) {
|
public void encrypt(CharSequence password) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
final KeyCrypterScrypt scrypt = new KeyCrypterScrypt();
|
final KeyCrypterScrypt scrypt = new KeyCrypterScrypt();
|
||||||
keychain.encrypt(scrypt, scrypt.deriveKey(password));
|
keyChainGroup.encrypt(scrypt, scrypt.deriveKey(password));
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
}
|
}
|
||||||
@ -1085,11 +1085,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @throws KeyCrypterException Thrown if the wallet encryption fails. If so, the wallet state is unchanged.
|
* @throws KeyCrypterException Thrown if the wallet encryption fails. If so, the wallet state is unchanged.
|
||||||
*/
|
*/
|
||||||
public void encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) {
|
public void encrypt(KeyCrypter keyCrypter, KeyParameter aesKey) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
keychain.encrypt(keyCrypter, aesKey);
|
keyChainGroup.encrypt(keyCrypter, aesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
}
|
}
|
||||||
@ -1099,13 +1099,13 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged.
|
* @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged.
|
||||||
*/
|
*/
|
||||||
public void decrypt(CharSequence password) {
|
public void decrypt(CharSequence password) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
final KeyCrypter crypter = keychain.getKeyCrypter();
|
final KeyCrypter crypter = keyChainGroup.getKeyCrypter();
|
||||||
checkState(crypter != null, "Not encrypted");
|
checkState(crypter != null, "Not encrypted");
|
||||||
keychain.decrypt(crypter.deriveKey(password));
|
keyChainGroup.decrypt(crypter.deriveKey(password));
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
}
|
}
|
||||||
@ -1117,11 +1117,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged.
|
* @throws KeyCrypterException Thrown if the wallet decryption fails. If so, the wallet state is unchanged.
|
||||||
*/
|
*/
|
||||||
public void decrypt(KeyParameter aesKey) {
|
public void decrypt(KeyParameter aesKey) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
keychain.decrypt(aesKey);
|
keyChainGroup.decrypt(aesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
}
|
}
|
||||||
@ -1134,11 +1134,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @throws IllegalStateException if the wallet is not encrypted.
|
* @throws IllegalStateException if the wallet is not encrypted.
|
||||||
*/
|
*/
|
||||||
public boolean checkPassword(CharSequence password) {
|
public boolean checkPassword(CharSequence password) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.checkPassword(password);
|
return keyChainGroup.checkPassword(password);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1148,11 +1148,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* @return boolean true if AES key supplied can decrypt the first encrypted private key in the wallet, false otherwise.
|
* @return boolean true if AES key supplied can decrypt the first encrypted private key in the wallet, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean checkAESKey(KeyParameter aesKey) {
|
public boolean checkAESKey(KeyParameter aesKey) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.checkAESKey(aesKey);
|
return keyChainGroup.checkAESKey(aesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,11 +1162,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public KeyCrypter getKeyCrypter() {
|
public KeyCrypter getKeyCrypter() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.getKeyCrypter();
|
return keyChainGroup.getKeyCrypter();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1176,15 +1176,15 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* (This is a convenience method - the encryption type is actually stored in the keyCrypter).
|
* (This is a convenience method - the encryption type is actually stored in the keyCrypter).
|
||||||
*/
|
*/
|
||||||
public EncryptionType getEncryptionType() {
|
public EncryptionType getEncryptionType() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
KeyCrypter crypter = keychain.getKeyCrypter();
|
KeyCrypter crypter = keyChainGroup.getKeyCrypter();
|
||||||
if (crypter != null)
|
if (crypter != null)
|
||||||
return crypter.getUnderstoodEncryptionType();
|
return crypter.getUnderstoodEncryptionType();
|
||||||
else
|
else
|
||||||
return EncryptionType.UNENCRYPTED;
|
return EncryptionType.UNENCRYPTED;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1195,23 +1195,23 @@ public class Wallet extends BaseTaggableObject
|
|||||||
|
|
||||||
/** Changes wallet encryption password, this is atomic operation. */
|
/** Changes wallet encryption password, this is atomic operation. */
|
||||||
public void changeEncryptionPassword(CharSequence currentPassword, CharSequence newPassword){
|
public void changeEncryptionPassword(CharSequence currentPassword, CharSequence newPassword){
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
decrypt(currentPassword);
|
decrypt(currentPassword);
|
||||||
encrypt(newPassword);
|
encrypt(newPassword);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Changes wallet AES encryption key, this is atomic operation. */
|
/** Changes wallet AES encryption key, this is atomic operation. */
|
||||||
public void changeEncryptionKey(KeyCrypter keyCrypter, KeyParameter currentAesKey, KeyParameter newAesKey){
|
public void changeEncryptionKey(KeyCrypter keyCrypter, KeyParameter currentAesKey, KeyParameter newAesKey){
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
decrypt(currentAesKey);
|
decrypt(currentAesKey);
|
||||||
encrypt(keyCrypter, newAesKey);
|
encrypt(keyCrypter, newAesKey);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1223,12 +1223,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
|
|
||||||
// TODO: Make this package private once the classes finish moving around.
|
// TODO: Make this package private once the classes finish moving around.
|
||||||
/** Internal use only. */
|
/** Internal use only. */
|
||||||
public List<Protos.Key> serializeKeychainToProtobuf() {
|
public List<Protos.Key> serializeKeyChainGroupToProtobuf() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return keychain.serializeToProtobuf();
|
return keyChainGroup.serializeToProtobuf();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2320,7 +2320,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
public void addChangeEventListener(Executor executor, WalletChangeEventListener listener) {
|
public void addChangeEventListener(Executor executor, WalletChangeEventListener listener) {
|
||||||
// This is thread safe, so we don't need to take the lock.
|
// This is thread safe, so we don't need to take the lock.
|
||||||
changeListeners.add(new ListenerRegistration<WalletChangeEventListener>(executor, listener));
|
changeListeners.add(new ListenerRegistration<WalletChangeEventListener>(executor, listener));
|
||||||
keychain.addEventListener(listener, executor);
|
keyChainGroup.addEventListener(listener, executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2355,7 +2355,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* was never added.
|
* was never added.
|
||||||
*/
|
*/
|
||||||
public boolean removeChangeEventListener(WalletChangeEventListener listener) {
|
public boolean removeChangeEventListener(WalletChangeEventListener listener) {
|
||||||
keychain.removeEventListener(listener);
|
keyChainGroup.removeEventListener(listener);
|
||||||
return ListenerRegistration.removeFromList(listener, changeListeners);
|
return ListenerRegistration.removeFromList(listener, changeListeners);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2672,7 +2672,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
public List<TransactionOutput> getWatchedOutputs(boolean excludeImmatureCoinbases) {
|
public List<TransactionOutput> getWatchedOutputs(boolean excludeImmatureCoinbases) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
LinkedList<TransactionOutput> candidates = Lists.newLinkedList();
|
LinkedList<TransactionOutput> candidates = Lists.newLinkedList();
|
||||||
for (Transaction tx : Iterables.concat(unspent.values(), pending.values())) {
|
for (Transaction tx : Iterables.concat(unspent.values(), pending.values())) {
|
||||||
@ -2690,7 +2690,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
return candidates;
|
return candidates;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2807,7 +2807,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
public String toString(boolean includePrivateKeys, boolean includeTransactions, boolean includeExtensions,
|
public String toString(boolean includePrivateKeys, boolean includeTransactions, boolean includeExtensions,
|
||||||
@Nullable AbstractBlockChain chain) {
|
@Nullable AbstractBlockChain chain) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
Coin estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
Coin estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
||||||
@ -2822,7 +2822,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
final String lastBlockSeenTimeStr = lastBlockSeenTime == null ? "time unknown" : lastBlockSeenTime.toString();
|
final String lastBlockSeenTimeStr = lastBlockSeenTime == null ? "time unknown" : lastBlockSeenTime.toString();
|
||||||
builder.append(String.format("Last seen best block: %d (%s): %s%n",
|
builder.append(String.format("Last seen best block: %d (%s): %s%n",
|
||||||
getLastBlockSeenHeight(), lastBlockSeenTimeStr, getLastBlockSeenHash()));
|
getLastBlockSeenHeight(), lastBlockSeenTimeStr, getLastBlockSeenHash()));
|
||||||
final KeyCrypter crypter = keychain.getKeyCrypter();
|
final KeyCrypter crypter = keyChainGroup.getKeyCrypter();
|
||||||
if (crypter != null)
|
if (crypter != null)
|
||||||
builder.append(String.format("Encryption: %s%n", crypter));
|
builder.append(String.format("Encryption: %s%n", crypter));
|
||||||
if (isWatching())
|
if (isWatching())
|
||||||
@ -2833,7 +2833,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
final long keyRotationTime = vKeyRotationTimestamp * 1000;
|
final long keyRotationTime = vKeyRotationTimestamp * 1000;
|
||||||
if (keyRotationTime > 0)
|
if (keyRotationTime > 0)
|
||||||
builder.append(String.format("Key rotation time: %s\n", Utils.dateTimeFormat(keyRotationTime)));
|
builder.append(String.format("Key rotation time: %s\n", Utils.dateTimeFormat(keyRotationTime)));
|
||||||
builder.append(keychain.toString(includePrivateKeys));
|
builder.append(keyChainGroup.toString(includePrivateKeys));
|
||||||
|
|
||||||
if (!watchedScripts.isEmpty()) {
|
if (!watchedScripts.isEmpty()) {
|
||||||
builder.append("\nWatched scripts:\n");
|
builder.append("\nWatched scripts:\n");
|
||||||
@ -2869,7 +2869,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2928,16 +2928,16 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public long getEarliestKeyCreationTime() {
|
public long getEarliestKeyCreationTime() {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
long earliestTime = keychain.getEarliestKeyCreationTime();
|
long earliestTime = keyChainGroup.getEarliestKeyCreationTime();
|
||||||
for (Script script : watchedScripts)
|
for (Script script : watchedScripts)
|
||||||
earliestTime = Math.min(script.getCreationTimeSeconds(), earliestTime);
|
earliestTime = Math.min(script.getCreationTimeSeconds(), earliestTime);
|
||||||
if (earliestTime == Long.MAX_VALUE)
|
if (earliestTime == Long.MAX_VALUE)
|
||||||
return Utils.currentTimeSeconds();
|
return Utils.currentTimeSeconds();
|
||||||
return earliestTime;
|
return earliestTime;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3976,7 +3976,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
protected List<UTXO> getStoredOutputsFromUTXOProvider() throws UTXOProviderException {
|
protected List<UTXO> getStoredOutputsFromUTXOProvider() throws UTXOProviderException {
|
||||||
UTXOProvider utxoProvider = checkNotNull(vUTXOProvider, "No UTXO provider has been set");
|
UTXOProvider utxoProvider = checkNotNull(vUTXOProvider, "No UTXO provider has been set");
|
||||||
List<UTXO> candidates = new ArrayList<UTXO>();
|
List<UTXO> candidates = new ArrayList<UTXO>();
|
||||||
List<DeterministicKey> keys = getActiveKeychain().getLeafKeys();
|
List<DeterministicKey> keys = getActiveKeyChain().getLeafKeys();
|
||||||
List<Address> addresses = new ArrayList<Address>();
|
List<Address> addresses = new ArrayList<Address>();
|
||||||
for (ECKey key : keys) {
|
for (ECKey key : keys) {
|
||||||
Address address = new Address(params, key.getPubKeyHash());
|
Address address = new Address(params, key.getPubKeyHash());
|
||||||
@ -4309,7 +4309,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
if (bloomFilterGuard.incrementAndGet() > 1)
|
if (bloomFilterGuard.incrementAndGet() > 1)
|
||||||
return;
|
return;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
//noinspection FieldAccessNotGuarded
|
//noinspection FieldAccessNotGuarded
|
||||||
calcBloomOutPointsLocked();
|
calcBloomOutPointsLocked();
|
||||||
}
|
}
|
||||||
@ -4334,12 +4334,12 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @GuardedBy("keychainLock")
|
@Override @GuardedBy("keyChainGroupLock")
|
||||||
public void endBloomFilterCalculation() {
|
public void endBloomFilterCalculation() {
|
||||||
if (bloomFilterGuard.decrementAndGet() > 0)
|
if (bloomFilterGuard.decrementAndGet() > 0)
|
||||||
return;
|
return;
|
||||||
bloomOutPoints.clear();
|
bloomOutPoints.clear();
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4352,7 +4352,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
beginBloomFilterCalculation();
|
beginBloomFilterCalculation();
|
||||||
try {
|
try {
|
||||||
int size = bloomOutPoints.size();
|
int size = bloomOutPoints.size();
|
||||||
size += keychain.getBloomFilterElementCount();
|
size += keyChainGroup.getBloomFilterElementCount();
|
||||||
// Some scripts may have more than one bloom element. That should normally be okay, because under-counting
|
// Some scripts may have more than one bloom element. That should normally be okay, because under-counting
|
||||||
// just increases false-positive rate.
|
// just increases false-positive rate.
|
||||||
size += watchedScripts.size();
|
size += watchedScripts.size();
|
||||||
@ -4371,11 +4371,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
public boolean isRequiringUpdateAllBloomFilter() {
|
public boolean isRequiringUpdateAllBloomFilter() {
|
||||||
// This is typically called by the PeerGroup, in which case it will have already explicitly taken the lock
|
// This is typically called by the PeerGroup, in which case it will have already explicitly taken the lock
|
||||||
// before calling, but because this is public API we must still lock again regardless.
|
// before calling, but because this is public API we must still lock again regardless.
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
return !watchedScripts.isEmpty();
|
return !watchedScripts.isEmpty();
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4403,11 +4403,11 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* <p>See the docs for {@link BloomFilter(int, double)} for a brief explanation of anonymity when using bloom
|
* <p>See the docs for {@link BloomFilter(int, double)} for a brief explanation of anonymity when using bloom
|
||||||
* filters.</p>
|
* filters.</p>
|
||||||
*/
|
*/
|
||||||
@Override @GuardedBy("keychainLock")
|
@Override @GuardedBy("keyChainGroupLock")
|
||||||
public BloomFilter getBloomFilter(int size, double falsePositiveRate, long nTweak) {
|
public BloomFilter getBloomFilter(int size, double falsePositiveRate, long nTweak) {
|
||||||
beginBloomFilterCalculation();
|
beginBloomFilterCalculation();
|
||||||
try {
|
try {
|
||||||
BloomFilter filter = keychain.getBloomFilter(size, falsePositiveRate, nTweak);
|
BloomFilter filter = keyChainGroup.getBloomFilter(size, falsePositiveRate, nTweak);
|
||||||
for (Script script : watchedScripts) {
|
for (Script script : watchedScripts) {
|
||||||
for (ScriptChunk chunk : script.getChunks()) {
|
for (ScriptChunk chunk : script.getChunks()) {
|
||||||
// Only add long (at least 64 bit) data to the bloom filter.
|
// Only add long (at least 64 bit) data to the bloom filter.
|
||||||
@ -4439,20 +4439,20 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* sequence within it to reliably find relevant transactions.
|
* sequence within it to reliably find relevant transactions.
|
||||||
*/
|
*/
|
||||||
public boolean checkForFilterExhaustion(FilteredBlock block) {
|
public boolean checkForFilterExhaustion(FilteredBlock block) {
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
int epoch = keychain.getCombinedKeyLookaheadEpochs();
|
int epoch = keyChainGroup.getCombinedKeyLookaheadEpochs();
|
||||||
for (Transaction tx : block.getAssociatedTransactions().values()) {
|
for (Transaction tx : block.getAssociatedTransactions().values()) {
|
||||||
markKeysAsUsed(tx);
|
markKeysAsUsed(tx);
|
||||||
}
|
}
|
||||||
int newEpoch = keychain.getCombinedKeyLookaheadEpochs();
|
int newEpoch = keyChainGroup.getCombinedKeyLookaheadEpochs();
|
||||||
checkState(newEpoch >= epoch);
|
checkState(newEpoch >= epoch);
|
||||||
// If the key lookahead epoch has advanced, there was a call to addKeys and the PeerGroup already has a
|
// If the key lookahead epoch has advanced, there was a call to addKeys and the PeerGroup already has a
|
||||||
// pending request to recalculate the filter queued up on another thread. The calling Peer should abandon
|
// pending request to recalculate the filter queued up on another thread. The calling Peer should abandon
|
||||||
// block at this point and await a new filter before restarting the download.
|
// block at this point and await a new filter before restarting the download.
|
||||||
return newEpoch > epoch;
|
return newEpoch > epoch;
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4531,7 +4531,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
*/
|
*/
|
||||||
public void deserializeExtension(WalletExtension extension, byte[] data) throws Exception {
|
public void deserializeExtension(WalletExtension extension, byte[] data) throws Exception {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
// This method exists partly to establish a lock ordering of wallet > extension.
|
// This method exists partly to establish a lock ordering of wallet > extension.
|
||||||
extension.deserializeWalletExtension(this, data);
|
extension.deserializeWalletExtension(this, data);
|
||||||
@ -4541,7 +4541,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
extensions.remove(extension.getWalletExtensionID());
|
extensions.remove(extension.getWalletExtensionID());
|
||||||
Throwables.propagate(throwable);
|
Throwables.propagate(throwable);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4895,13 +4895,13 @@ public class Wallet extends BaseTaggableObject
|
|||||||
public ListenableFuture<List<Transaction>> doMaintenance(@Nullable KeyParameter aesKey, boolean signAndSend) throws DeterministicUpgradeRequiresPassword {
|
public ListenableFuture<List<Transaction>> doMaintenance(@Nullable KeyParameter aesKey, boolean signAndSend) throws DeterministicUpgradeRequiresPassword {
|
||||||
List<Transaction> txns;
|
List<Transaction> txns;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
keychainLock.lock();
|
keyChainGroupLock.lock();
|
||||||
try {
|
try {
|
||||||
txns = maybeRotateKeys(aesKey, signAndSend);
|
txns = maybeRotateKeys(aesKey, signAndSend);
|
||||||
if (!signAndSend)
|
if (!signAndSend)
|
||||||
return Futures.immediateFuture(txns);
|
return Futures.immediateFuture(txns);
|
||||||
} finally {
|
} finally {
|
||||||
keychainLock.unlock();
|
keyChainGroupLock.unlock();
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
checkState(!lock.isHeldByCurrentThread());
|
checkState(!lock.isHeldByCurrentThread());
|
||||||
@ -4930,10 +4930,10 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Checks to see if any coins are controlled by rotating keys and if so, spends them.
|
// Checks to see if any coins are controlled by rotating keys and if so, spends them.
|
||||||
@GuardedBy("keychainLock")
|
@GuardedBy("keyChainGroupLock")
|
||||||
private List<Transaction> maybeRotateKeys(@Nullable KeyParameter aesKey, boolean sign) throws DeterministicUpgradeRequiresPassword {
|
private List<Transaction> maybeRotateKeys(@Nullable KeyParameter aesKey, boolean sign) throws DeterministicUpgradeRequiresPassword {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
checkState(keychainLock.isHeldByCurrentThread());
|
checkState(keyChainGroupLock.isHeldByCurrentThread());
|
||||||
List<Transaction> results = Lists.newLinkedList();
|
List<Transaction> results = Lists.newLinkedList();
|
||||||
// TODO: Handle chain replays here.
|
// TODO: Handle chain replays here.
|
||||||
final long keyRotationTimestamp = vKeyRotationTimestamp;
|
final long keyRotationTimestamp = vKeyRotationTimestamp;
|
||||||
@ -4941,7 +4941,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
|
|
||||||
// We might have to create a new HD hierarchy if the previous ones are now rotating.
|
// We might have to create a new HD hierarchy if the previous ones are now rotating.
|
||||||
boolean allChainsRotating = true;
|
boolean allChainsRotating = true;
|
||||||
for (DeterministicKeyChain chain : keychain.getDeterministicKeyChains()) {
|
for (DeterministicKeyChain chain : keyChainGroup.getDeterministicKeyChains()) {
|
||||||
if (chain.getEarliestKeyCreationTime() >= keyRotationTimestamp) {
|
if (chain.getEarliestKeyCreationTime() >= keyRotationTimestamp) {
|
||||||
allChainsRotating = false;
|
allChainsRotating = false;
|
||||||
break;
|
break;
|
||||||
@ -4949,17 +4949,17 @@ public class Wallet extends BaseTaggableObject
|
|||||||
}
|
}
|
||||||
if (allChainsRotating) {
|
if (allChainsRotating) {
|
||||||
try {
|
try {
|
||||||
if (keychain.getImportedKeys().isEmpty()) {
|
if (keyChainGroup.getImportedKeys().isEmpty()) {
|
||||||
log.info("All HD chains are currently rotating and we have no random keys, creating fresh HD chain ...");
|
log.info("All HD chains are currently rotating and we have no random keys, creating fresh HD chain ...");
|
||||||
keychain.createAndActivateNewHDChain();
|
keyChainGroup.createAndActivateNewHDChain();
|
||||||
} else {
|
} else {
|
||||||
log.info("All HD chains are currently rotating, attempting to create a new one from the next oldest non-rotating key material ...");
|
log.info("All HD chains are currently rotating, attempting to create a new one from the next oldest non-rotating key material ...");
|
||||||
keychain.upgradeToDeterministic(keyRotationTimestamp, aesKey);
|
keyChainGroup.upgradeToDeterministic(keyRotationTimestamp, aesKey);
|
||||||
log.info(" ... upgraded to HD again, based on next best oldest key.");
|
log.info(" ... upgraded to HD again, based on next best oldest key.");
|
||||||
}
|
}
|
||||||
} catch (AllRandomKeysRotating rotating) {
|
} catch (AllRandomKeysRotating rotating) {
|
||||||
log.info(" ... no non-rotating random keys available, generating entirely new HD tree: backup required after this.");
|
log.info(" ... no non-rotating random keys available, generating entirely new HD tree: backup required after this.");
|
||||||
keychain.createAndActivateNewHDChain();
|
keyChainGroup.createAndActivateNewHDChain();
|
||||||
}
|
}
|
||||||
saveNow();
|
saveNow();
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ public class WalletProtobufSerializer {
|
|||||||
walletBuilder.addTransaction(txProto);
|
walletBuilder.addTransaction(txProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
walletBuilder.addAllKey(wallet.serializeKeychainToProtobuf());
|
walletBuilder.addAllKey(wallet.serializeKeyChainGroupToProtobuf());
|
||||||
|
|
||||||
for (Script script : wallet.getWatchedScripts()) {
|
for (Script script : wallet.getWatchedScripts()) {
|
||||||
Protos.Script protoScript =
|
Protos.Script protoScript =
|
||||||
@ -422,15 +422,15 @@ public class WalletProtobufSerializer {
|
|||||||
throw new UnreadableWalletException.WrongNetwork();
|
throw new UnreadableWalletException.WrongNetwork();
|
||||||
|
|
||||||
// Read the scrypt parameters that specify how encryption and decryption is performed.
|
// Read the scrypt parameters that specify how encryption and decryption is performed.
|
||||||
KeyChainGroup chain;
|
KeyChainGroup keyChainGroup;
|
||||||
if (walletProto.hasEncryptionParameters()) {
|
if (walletProto.hasEncryptionParameters()) {
|
||||||
Protos.ScryptParameters encryptionParameters = walletProto.getEncryptionParameters();
|
Protos.ScryptParameters encryptionParameters = walletProto.getEncryptionParameters();
|
||||||
final KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(encryptionParameters);
|
final KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(encryptionParameters);
|
||||||
chain = KeyChainGroup.fromProtobufEncrypted(params, walletProto.getKeyList(), keyCrypter, keyChainFactory);
|
keyChainGroup = KeyChainGroup.fromProtobufEncrypted(params, walletProto.getKeyList(), keyCrypter, keyChainFactory);
|
||||||
} else {
|
} else {
|
||||||
chain = KeyChainGroup.fromProtobufUnencrypted(params, walletProto.getKeyList(), keyChainFactory);
|
keyChainGroup = KeyChainGroup.fromProtobufUnencrypted(params, walletProto.getKeyList(), keyChainFactory);
|
||||||
}
|
}
|
||||||
Wallet wallet = factory.create(params, chain);
|
Wallet wallet = factory.create(params, keyChainGroup);
|
||||||
|
|
||||||
List<Script> scripts = Lists.newArrayList();
|
List<Script> scripts = Lists.newArrayList();
|
||||||
for (Protos.Script protoScript : walletProto.getWatchedScriptList()) {
|
for (Protos.Script protoScript : walletProto.getWatchedScriptList()) {
|
||||||
|
@ -156,7 +156,7 @@ public class FilteredBlockAndPartialMerkleTreeTests extends TestWithPeerGroup {
|
|||||||
assertTrue(tx3.getHash().equals(Sha256Hash.wrap("c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9")));
|
assertTrue(tx3.getHash().equals(Sha256Hash.wrap("c5abc61566dbb1c4bce5e1fda7b66bed22eb2130cea4b721690bc1488465abc9")));
|
||||||
assertEquals(tx3.getHash(),txHashList.get(3));
|
assertEquals(tx3.getHash(),txHashList.get(3));
|
||||||
|
|
||||||
BloomFilter filter = wallet.getBloomFilter(wallet.getKeychainSize()*2, 0.001, 0xDEADBEEF);
|
BloomFilter filter = wallet.getBloomFilter(wallet.getKeyChainGroupSize()*2, 0.001, 0xDEADBEEF);
|
||||||
// Compare the serialized bloom filter to a known-good value
|
// Compare the serialized bloom filter to a known-good value
|
||||||
assertArrayEquals(filter.bitcoinSerialize(), HEX.decode("0e1b091ca195e45a9164889b6bc46a09000000efbeadde02"));
|
assertArrayEquals(filter.bitcoinSerialize(), HEX.decode("0e1b091ca195e45a9164889b6bc46a09000000efbeadde02"));
|
||||||
|
|
||||||
|
@ -629,8 +629,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
public void testBloomResendOnNewKey() throws Exception {
|
public void testBloomResendOnNewKey() throws Exception {
|
||||||
// Check that when we add a new key to the wallet, the Bloom filter is re-calculated and re-sent but only once
|
// Check that when we add a new key to the wallet, the Bloom filter is re-calculated and re-sent but only once
|
||||||
// we exceed the lookahead threshold.
|
// we exceed the lookahead threshold.
|
||||||
wallet.setKeychainLookaheadSize(5);
|
wallet.setKeyChainGroupLookaheadSize(5);
|
||||||
wallet.setKeychainLookaheadThreshold(4);
|
wallet.setKeyChainGroupLookaheadThreshold(4);
|
||||||
peerGroup.start();
|
peerGroup.start();
|
||||||
// Create a couple of peers.
|
// Create a couple of peers.
|
||||||
InboundMessageQueuer p1 = connectPeer(1);
|
InboundMessageQueuer p1 = connectPeer(1);
|
||||||
@ -639,7 +639,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
BloomFilter f1 = p1.lastReceivedFilter;
|
BloomFilter f1 = p1.lastReceivedFilter;
|
||||||
ECKey key = null;
|
ECKey key = null;
|
||||||
// We have to run ahead of the lookahead zone for this test. There should only be one bloom filter recalc.
|
// We have to run ahead of the lookahead zone for this test. There should only be one bloom filter recalc.
|
||||||
for (int i = 0; i < wallet.getKeychainLookaheadSize() + wallet.getKeychainLookaheadThreshold() + 1; i++) {
|
for (int i = 0; i < wallet.getKeyChainGroupLookaheadSize() + wallet.getKeyChainGroupLookaheadThreshold() + 1; i++) {
|
||||||
key = wallet.freshReceiveKey();
|
key = wallet.freshReceiveKey();
|
||||||
}
|
}
|
||||||
peerGroup.waitForJobQueue();
|
peerGroup.waitForJobQueue();
|
||||||
@ -775,8 +775,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
keys.add(shadow.freshReceiveKey());
|
keys.add(shadow.freshReceiveKey());
|
||||||
}
|
}
|
||||||
// Reduce the number of keys we need to work with to speed up this test.
|
// Reduce the number of keys we need to work with to speed up this test.
|
||||||
wallet.setKeychainLookaheadSize(4);
|
wallet.setKeyChainGroupLookaheadSize(4);
|
||||||
wallet.setKeychainLookaheadThreshold(2);
|
wallet.setKeyChainGroupLookaheadThreshold(2);
|
||||||
|
|
||||||
peerGroup.start();
|
peerGroup.start();
|
||||||
InboundMessageQueuer p1 = connectPeer(1);
|
InboundMessageQueuer p1 = connectPeer(1);
|
||||||
@ -800,13 +800,13 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
|
|
||||||
// Send the chain that doesn't have all the transactions in it. The blocks after the exhaustion point should all
|
// Send the chain that doesn't have all the transactions in it. The blocks after the exhaustion point should all
|
||||||
// be ignored.
|
// be ignored.
|
||||||
int epoch = wallet.keychain.getCombinedKeyLookaheadEpochs();
|
int epoch = wallet.keyChainGroup.getCombinedKeyLookaheadEpochs();
|
||||||
BloomFilter filter = new BloomFilter(params, p1.lastReceivedFilter.bitcoinSerialize());
|
BloomFilter filter = new BloomFilter(params, p1.lastReceivedFilter.bitcoinSerialize());
|
||||||
filterAndSend(p1, blocks, filter);
|
filterAndSend(p1, blocks, filter);
|
||||||
Block exhaustionPoint = blocks.get(3);
|
Block exhaustionPoint = blocks.get(3);
|
||||||
pingAndWait(p1);
|
pingAndWait(p1);
|
||||||
|
|
||||||
assertNotEquals(epoch, wallet.keychain.getCombinedKeyLookaheadEpochs());
|
assertNotEquals(epoch, wallet.keyChainGroup.getCombinedKeyLookaheadEpochs());
|
||||||
// 4th block was end of the lookahead zone and thus was discarded, so we got 3 blocks worth of money (50 each).
|
// 4th block was end of the lookahead zone and thus was discarded, so we got 3 blocks worth of money (50 each).
|
||||||
assertEquals(Coin.FIFTY_COINS.multiply(3), wallet.getBalance());
|
assertEquals(Coin.FIFTY_COINS.multiply(3), wallet.getBalance());
|
||||||
assertEquals(exhaustionPoint.getPrevBlockHash(), blockChain.getChainHead().getHeader().getHash());
|
assertEquals(exhaustionPoint.getPrevBlockHash(), blockChain.getChainHead().getHeader().getHash());
|
||||||
|
@ -316,7 +316,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
Wallet wallet1 = roundTrip(myWallet);
|
Wallet wallet1 = roundTrip(myWallet);
|
||||||
assertEquals(0, wallet1.getTransactions(true).size());
|
assertEquals(0, wallet1.getTransactions(true).size());
|
||||||
assertEquals(Coin.ZERO, wallet1.getBalance());
|
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||||
assertEquals(2, wallet1.getActiveKeychain().getSigsRequiredToSpend());
|
assertEquals(2, wallet1.getActiveKeyChain().getSigsRequiredToSpend());
|
||||||
assertEquals(myAddress, wallet1.currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS));
|
assertEquals(myAddress, wallet1.currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,7 +947,7 @@ public class WalletTool {
|
|||||||
if (options.has(lookaheadSize)) {
|
if (options.has(lookaheadSize)) {
|
||||||
Integer size = options.valueOf(lookaheadSize);
|
Integer size = options.valueOf(lookaheadSize);
|
||||||
log.info("Setting keychain lookahead size to {}", size);
|
log.info("Setting keychain lookahead size to {}", size);
|
||||||
wallet.setKeychainLookaheadSize(size);
|
wallet.setKeyChainGroupLookaheadSize(size);
|
||||||
}
|
}
|
||||||
ECKey key;
|
ECKey key;
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user