From 7f5b6753f54f4dbdcb5cd411f722657c8ba6f1c6 Mon Sep 17 00:00:00 2001 From: Andreas Schildbach Date: Sun, 4 Mar 2018 19:58:49 +0100 Subject: [PATCH] Use Address whereever possible in the API, rather than LegacyAddress. This is a preparation for the remaining segwit changes. LegacyAddress variables in unit tests are also changed. --- .../main/java/org/bitcoinj/core/ECKey.java | 2 +- .../org/bitcoinj/core/GetAddrMessage.java | 2 +- .../org/bitcoinj/crypto/DeterministicKey.java | 2 +- .../protocols/payments/PaymentProtocol.java | 6 +- .../protocols/payments/PaymentSession.java | 4 +- .../org/bitcoinj/script/ScriptBuilder.java | 7 +-- .../store/DatabaseFullPrunedBlockStore.java | 2 +- .../store/LevelDBFullPrunedBlockStore.java | 8 +-- .../org/bitcoinj/wallet/KeyChainGroup.java | 22 ++++--- .../java/org/bitcoinj/wallet/SendRequest.java | 2 +- .../main/java/org/bitcoinj/wallet/Wallet.java | 50 ++++++++-------- .../AbstractFullPrunedBlockChainTest.java | 4 +- .../org/bitcoinj/core/BlockChainTest.java | 8 +-- .../org/bitcoinj/core/BloomFilterTest.java | 2 +- .../org/bitcoinj/core/ChainSplitTest.java | 14 ++--- .../java/org/bitcoinj/core/ECKeyTest.java | 4 +- .../java/org/bitcoinj/core/PeerGroupTest.java | 4 +- .../core/TransactionBroadcastTest.java | 4 +- .../bitcoinj/core/TransactionInputTest.java | 4 +- .../bitcoinj/core/TransactionOutputTest.java | 2 +- .../org/bitcoinj/core/TransactionTest.java | 4 +- .../bitcoinj/core/TxConfidenceTableTest.java | 4 +- .../payments/PaymentProtocolTest.java | 11 +++- .../payments/PaymentSessionTest.java | 14 ++++- .../java/org/bitcoinj/script/ScriptTest.java | 10 ++-- .../bitcoinj/store/LevelDBBlockStoreTest.java | 8 ++- .../org/bitcoinj/store/SPVBlockStoreTest.java | 5 +- .../store/WalletProtobufSerializerTest.java | 18 +++++- .../org/bitcoinj/testing/FakeTxBuilder.java | 6 +- .../testing/TestWithNetworkConnections.java | 2 +- .../org/bitcoinj/testing/TestWithWallet.java | 18 ++++-- .../java/org/bitcoinj/uri/BitcoinURITest.java | 3 +- .../wallet/DeterministicKeyChainTest.java | 14 +++-- .../bitcoinj/wallet/KeyChainGroupTest.java | 39 +++++++------ .../java/org/bitcoinj/wallet/WalletTest.java | 58 +++++++++---------- .../bitcoinj/examples/ForwardingService.java | 12 +++- .../org/bitcoinj/examples/PrivateKeys.java | 12 +++- .../java/org/bitcoinj/tools/WalletTool.java | 31 +++++++++- .../controls/ClickableBitcoinAddress.java | 10 ++-- .../wallettemplate/utils/BitcoinUIModel.java | 7 ++- 40 files changed, 269 insertions(+), 170 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/ECKey.java b/core/src/main/java/org/bitcoinj/core/ECKey.java index 44bd2133..77f843cc 100644 --- a/core/src/main/java/org/bitcoinj/core/ECKey.java +++ b/core/src/main/java/org/bitcoinj/core/ECKey.java @@ -1268,7 +1268,7 @@ public class ECKey implements EncryptableItem { public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, NetworkParameters params) { - final LegacyAddress address = LegacyAddress.fromKey(params, this); + final Address address = LegacyAddress.fromKey(params, this); builder.append(" addr:"); builder.append(address.toString()); builder.append(" hash160:"); diff --git a/core/src/main/java/org/bitcoinj/core/GetAddrMessage.java b/core/src/main/java/org/bitcoinj/core/GetAddrMessage.java index 96ab00c4..69146569 100644 --- a/core/src/main/java/org/bitcoinj/core/GetAddrMessage.java +++ b/core/src/main/java/org/bitcoinj/core/GetAddrMessage.java @@ -18,7 +18,7 @@ package org.bitcoinj.core; /** *

Represents the "getaddr" P2P protocol message, which requests network {@link AddressMessage}s from a peer. Not to - * be confused with {@link LegacyAddress} which is sort of like an account number.

+ * be confused with {@link Address} which is sort of like an account number.

* *

Instances of this class are not safe for use by multiple threads.

*/ diff --git a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java index 84a8c660..a4599d17 100644 --- a/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java +++ b/core/src/main/java/org/bitcoinj/crypto/DeterministicKey.java @@ -617,7 +617,7 @@ public class DeterministicKey extends ECKey { @Override public void formatKeyWithAddress(boolean includePrivateKeys, @Nullable KeyParameter aesKey, StringBuilder builder, NetworkParameters params) { - final LegacyAddress address = LegacyAddress.fromKey(params, this); + final Address address = LegacyAddress.fromKey(params, this); builder.append(" addr:").append(address); builder.append(" hash160:").append(Utils.HEX.encode(getPubKeyHash())); builder.append(" (").append(getPathAsString()).append(")\n"); diff --git a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java index 5f8a4e71..f583f25e 100644 --- a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java +++ b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java @@ -66,7 +66,7 @@ public class PaymentProtocol { * @return created payment request, in its builder form */ public static Protos.PaymentRequest.Builder createPaymentRequest(NetworkParameters params, - @Nullable Coin amount, LegacyAddress toAddress, @Nullable String memo, @Nullable String paymentUrl, + @Nullable Coin amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl, @Nullable byte[] merchantData) { return createPaymentRequest(params, ImmutableList.of(createPayToAddressOutput(amount, toAddress)), memo, paymentUrl, merchantData); @@ -292,7 +292,7 @@ public class PaymentProtocol { * @return created payment message */ public static Protos.Payment createPaymentMessage(List transactions, - @Nullable Coin refundAmount, @Nullable LegacyAddress refundAddress, @Nullable String memo, + @Nullable Coin refundAmount, @Nullable Address refundAddress, @Nullable String memo, @Nullable byte[] merchantData) { if (refundAddress != null) { if (refundAmount == null) @@ -397,7 +397,7 @@ public class PaymentProtocol { * @param address address to pay to * @return output */ - public static Protos.Output createPayToAddressOutput(@Nullable Coin amount, LegacyAddress address) { + public static Protos.Output createPayToAddressOutput(@Nullable Coin amount, Address address) { Protos.Output.Builder output = Protos.Output.newBuilder(); if (amount != null) { final NetworkParameters params = address.getParameters(); diff --git a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentSession.java b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentSession.java index c11eaa7d..2c91b63d 100644 --- a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentSession.java +++ b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentSession.java @@ -316,7 +316,7 @@ public class PaymentSession { * @param memo is a message to include in the payment message sent to the merchant. */ @Nullable - public ListenableFuture sendPayment(List txns, @Nullable LegacyAddress refundAddr, @Nullable String memo) + public ListenableFuture sendPayment(List txns, @Nullable Address refundAddr, @Nullable String memo) throws PaymentProtocolException, VerificationException, IOException { Protos.Payment payment = getPayment(txns, refundAddr, memo); if (payment == null) @@ -341,7 +341,7 @@ public class PaymentSession { * @param memo is a message to include in the payment message sent to the merchant. */ @Nullable - public Protos.Payment getPayment(List txns, @Nullable LegacyAddress refundAddr, @Nullable String memo) + public Protos.Payment getPayment(List txns, @Nullable Address refundAddr, @Nullable String memo) throws IOException, PaymentProtocolException.InvalidNetwork { if (paymentDetails.hasPaymentUrl()) { for (Transaction tx : txns) diff --git a/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java b/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java index 764734a7..fbe2bea3 100644 --- a/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java +++ b/core/src/main/java/org/bitcoinj/script/ScriptBuilder.java @@ -255,19 +255,18 @@ public class ScriptBuilder { public static Script createOutputScript(Address to) { ScriptBuilder builder = new ScriptBuilder(); if (to instanceof LegacyAddress) { - LegacyAddress toLegacy = (LegacyAddress) to; - ScriptType scriptType = toLegacy.getOutputScriptType(); + ScriptType scriptType = to.getOutputScriptType(); if (scriptType == ScriptType.P2PKH) { // OP_DUP OP_HASH160 OP_EQUALVERIFY OP_CHECKSIG builder.op(OP_DUP); builder.op(OP_HASH160); - builder.data(toLegacy.getHash()); + builder.data(to.getHash()); builder.op(OP_EQUALVERIFY); builder.op(OP_CHECKSIG); } else if (scriptType == ScriptType.P2SH) { // OP_HASH160 OP_EQUAL builder.op(OP_HASH160); - builder.data(toLegacy.getHash()); + builder.data(to.getHash()); builder.op(OP_EQUAL); } else { throw new IllegalStateException("Cannot handle " + scriptType); diff --git a/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java b/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java index fcbf0f0a..2b001859 100644 --- a/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java @@ -1124,7 +1124,7 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto * address, the return value is 0. * @throws BlockStoreException If there is an error getting the balance. */ - public BigInteger calculateBalanceForAddress(LegacyAddress address) throws BlockStoreException { + public BigInteger calculateBalanceForAddress(Address address) throws BlockStoreException { maybeConnect(); PreparedStatement s = null; try { diff --git a/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java b/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java index 1e3fd549..6aa08a26 100644 --- a/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java @@ -28,10 +28,10 @@ import java.util.concurrent.TimeUnit; import java.io.*; import java.nio.ByteBuffer; -import org.bitcoinj.core.LegacyAddress; import org.bitcoinj.core.Address; import org.bitcoinj.core.AddressFormatException; import org.bitcoinj.core.ECKey; +import org.bitcoinj.core.LegacyAddress; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.StoredBlock; @@ -788,7 +788,7 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore { // Could run this in parallel with above too. // Should update instrumentation to see if worth while. - LegacyAddress a; + Address a; if (out.getAddress() == null || out.getAddress().equals("")) { if (instrument) endMethod("addUnspentTransactionOutput"); @@ -882,13 +882,13 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore { // TODO storing as byte[] hash to save space. But think should just // store as String of address. Might be faster. Need to test. ByteBuffer bb = ByteBuffer.allocate(57); - LegacyAddress a; + Address a; byte[] hashBytes = null; try { String address = out.getAddress(); if (address == null || address.equals("")) { Script sc = out.getScript(); - a = (LegacyAddress) sc.getToAddress(params); + a = sc.getToAddress(params); hashBytes = a.getHash(); } else { a = LegacyAddress.fromBase58(params, out.getAddress()); diff --git a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java index 17a10c64..e707650d 100644 --- a/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java +++ b/core/src/main/java/org/bitcoinj/wallet/KeyChainGroup.java @@ -19,7 +19,13 @@ package org.bitcoinj.wallet; import com.google.common.collect.*; import com.google.protobuf.*; -import org.bitcoinj.core.*; + +import org.bitcoinj.core.Address; +import org.bitcoinj.core.BloomFilter; +import org.bitcoinj.core.ECKey; +import org.bitcoinj.core.LegacyAddress; +import org.bitcoinj.core.NetworkParameters; +import org.bitcoinj.core.Utils; import org.bitcoinj.crypto.*; import org.bitcoinj.script.*; import org.bitcoinj.script.Script.ScriptType; @@ -70,7 +76,7 @@ public class KeyChainGroup implements KeyBag { // currentKeys is used for normal, non-multisig/married wallets. currentAddresses is used when we're handing out // P2SH addresses. They're mutually exclusive. private final EnumMap currentKeys; - private final EnumMap currentAddresses; + private final EnumMap currentAddresses; @Nullable private KeyCrypter keyCrypter; private int lookaheadSize = -1; private int lookaheadThreshold = -1; @@ -125,7 +131,7 @@ public class KeyChainGroup implements KeyBag { if (isMarried()) { for (Map.Entry entry : this.currentKeys.entrySet()) { Address address = makeP2SHOutputScript(entry.getValue(), getActiveKeyChain()).getToAddress(params); - currentAddresses.put(entry.getKey(), (LegacyAddress) address); + currentAddresses.put(entry.getKey(), address); } } } @@ -187,10 +193,10 @@ public class KeyChainGroup implements KeyBag { /** * Returns address for a {@link #currentKey(KeyChain.KeyPurpose)} */ - public LegacyAddress currentAddress(KeyChain.KeyPurpose purpose) { + public Address currentAddress(KeyChain.KeyPurpose purpose) { DeterministicKeyChain chain = getActiveKeyChain(); if (chain.isMarried()) { - LegacyAddress current = currentAddresses.get(purpose); + Address current = currentAddresses.get(purpose); if (current == null) { current = freshAddress(purpose); currentAddresses.put(purpose, current); @@ -241,12 +247,12 @@ public class KeyChainGroup implements KeyBag { /** * Returns address for a {@link #freshKey(KeyChain.KeyPurpose)} */ - public LegacyAddress freshAddress(KeyChain.KeyPurpose purpose) { + public Address freshAddress(KeyChain.KeyPurpose purpose) { DeterministicKeyChain chain = getActiveKeyChain(); if (chain.isMarried()) { Script outputScript = chain.freshOutputScript(purpose); checkState(ScriptPattern.isPayToScriptHash(outputScript)); // Only handle P2SH for now - LegacyAddress freshAddress = LegacyAddress.fromScriptHash(params, + Address freshAddress = LegacyAddress.fromScriptHash(params, ScriptPattern.extractHashFromPayToScriptHash(outputScript)); maybeLookaheadScripts(); currentAddresses.put(purpose, freshAddress); @@ -411,7 +417,7 @@ public class KeyChainGroup implements KeyBag { /** If the given P2SH address is "current", advance it to a new one. */ private void maybeMarkCurrentAddressAsUsed(LegacyAddress address) { checkArgument(address.getOutputScriptType() == ScriptType.P2SH); - for (Map.Entry entry : currentAddresses.entrySet()) { + for (Map.Entry entry : currentAddresses.entrySet()) { if (entry.getValue() != null && entry.getValue().equals(address)) { log.info("Marking P2SH address as used: {}", address); currentAddresses.put(entry.getKey(), freshAddress(entry.getKey())); diff --git a/core/src/main/java/org/bitcoinj/wallet/SendRequest.java b/core/src/main/java/org/bitcoinj/wallet/SendRequest.java index 24f5eed9..bf7f0bdf 100644 --- a/core/src/main/java/org/bitcoinj/wallet/SendRequest.java +++ b/core/src/main/java/org/bitcoinj/wallet/SendRequest.java @@ -76,7 +76,7 @@ public class SendRequest { * don't really control as it depends on who sent you money), and the value being sent somewhere else. The * change address should be selected from this wallet, normally. If null this will be chosen for you. */ - public LegacyAddress changeAddress = null; + public Address changeAddress = null; /** *

A transaction can have a fee attached, which is defined as the difference between the input values diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index cad62eca..e0a1eadd 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -27,7 +27,6 @@ import net.jcip.annotations.*; import org.bitcoinj.core.listeners.*; import org.bitcoinj.core.Address; import org.bitcoinj.core.AbstractBlockChain; -import org.bitcoinj.core.LegacyAddress; import org.bitcoinj.core.BlockChain; import org.bitcoinj.core.BloomFilter; import org.bitcoinj.core.Coin; @@ -35,6 +34,7 @@ import org.bitcoinj.core.Context; import org.bitcoinj.core.ECKey; import org.bitcoinj.core.FilteredBlock; import org.bitcoinj.core.InsufficientMoneyException; +import org.bitcoinj.core.LegacyAddress; import org.bitcoinj.core.Message; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Peer; @@ -469,7 +469,7 @@ public class Wallet extends BaseTaggableObject /** * Returns address for a {@link #currentKey(org.bitcoinj.wallet.KeyChain.KeyPurpose)} */ - public LegacyAddress currentAddress(KeyChain.KeyPurpose purpose) { + public Address currentAddress(KeyChain.KeyPurpose purpose) { keyChainGroupLock.lock(); try { maybeUpgradeToHD(); @@ -483,7 +483,7 @@ public class Wallet extends BaseTaggableObject * An alias for calling {@link #currentAddress(org.bitcoinj.wallet.KeyChain.KeyPurpose)} with * {@link org.bitcoinj.wallet.KeyChain.KeyPurpose#RECEIVE_FUNDS} as the parameter. */ - public LegacyAddress currentReceiveAddress() { + public Address currentReceiveAddress() { return currentAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); } @@ -533,23 +533,23 @@ public class Wallet extends BaseTaggableObject /** * Returns address for a {@link #freshKey(org.bitcoinj.wallet.KeyChain.KeyPurpose)} */ - public LegacyAddress freshAddress(KeyChain.KeyPurpose purpose) { - LegacyAddress key; + public Address freshAddress(KeyChain.KeyPurpose purpose) { + Address address; keyChainGroupLock.lock(); try { - key = keyChainGroup.freshAddress(purpose); + address = keyChainGroup.freshAddress(purpose); } finally { keyChainGroupLock.unlock(); } saveNow(); - return key; + return address; } /** * An alias for calling {@link #freshAddress(org.bitcoinj.wallet.KeyChain.KeyPurpose)} with * {@link org.bitcoinj.wallet.KeyChain.KeyPurpose#RECEIVE_FUNDS} as the parameter. */ - public LegacyAddress freshReceiveAddress() { + public Address freshReceiveAddress() { return freshAddress(KeyChain.KeyPurpose.RECEIVE_FUNDS); } @@ -570,9 +570,9 @@ public class Wallet extends BaseTaggableObject * Returns only the addresses that have been issued by {@link #freshReceiveKey()}, {@link #freshReceiveAddress()}, * {@link #currentReceiveKey()} or {@link #currentReceiveAddress()}. */ - public List getIssuedReceiveAddresses() { + public List

getIssuedReceiveAddresses() { final List keys = getIssuedReceiveKeys(); - List addresses = new ArrayList<>(keys.size()); + List
addresses = new ArrayList<>(keys.size()); for (ECKey key : keys) addresses.add(LegacyAddress.fromKey(getParams(), key)); return addresses; @@ -688,7 +688,7 @@ public class Wallet extends BaseTaggableObject } /** Returns the address used for change outputs. Note: this will probably go away in future. */ - public LegacyAddress currentChangeAddress() { + public Address currentChangeAddress() { return currentAddress(KeyChain.KeyPurpose.CHANGE); } @@ -850,15 +850,15 @@ public class Wallet extends BaseTaggableObject /** * Return true if we are watching this address. */ - public boolean isAddressWatched(LegacyAddress address) { + public boolean isAddressWatched(Address address) { Script script = ScriptBuilder.createOutputScript(address); return isWatchedScript(script); } /** - * Same as {@link #addWatchedAddress(LegacyAddress, long)} with the current time as the creation time. + * Same as {@link #addWatchedAddress(Address, long)} with the current time as the creation time. */ - public boolean addWatchedAddress(final LegacyAddress address) { + public boolean addWatchedAddress(final Address address) { long now = Utils.currentTimeMillis() / 1000; return addWatchedAddresses(Lists.newArrayList(address), now) == 1; } @@ -869,7 +869,7 @@ public class Wallet extends BaseTaggableObject * @param creationTime creation time in seconds since the epoch, for scanning the blockchain * @return whether the address was added successfully (not already present) */ - public boolean addWatchedAddress(final LegacyAddress address, long creationTime) { + public boolean addWatchedAddress(final Address address, long creationTime) { return addWatchedAddresses(Lists.newArrayList(address), creationTime) == 1; } @@ -879,10 +879,10 @@ public class Wallet extends BaseTaggableObject * * @return how many addresses were added successfully */ - public int addWatchedAddresses(final List addresses, long creationTime) { + public int addWatchedAddresses(final List
addresses, long creationTime) { List