diff --git a/core/src/main/java/org/bitcoinj/core/UTXOProvider.java b/core/src/main/java/org/bitcoinj/core/UTXOProvider.java index e26b8580..22fbf2d9 100644 --- a/core/src/main/java/org/bitcoinj/core/UTXOProvider.java +++ b/core/src/main/java/org/bitcoinj/core/UTXOProvider.java @@ -25,15 +25,13 @@ import java.util.List; *

A {@link org.bitcoinj.store.FullPrunedBlockStore} is an internal implementation within bitcoinj.

*/ public interface UTXOProvider { - - // TODO currently the access to outputs is by address. Change to ECKey /** - * Get the list of {@link UTXO}'s for a given address. - * @param addresses List of address. + * Get the list of {@link UTXO}'s for given keys. + * @param keys List of keys. * @return The list of transaction outputs. * @throws UTXOProviderException If there is an error. */ - List getOpenTransactionOutputs(List addresses) throws UTXOProviderException; + List getOpenTransactionOutputs(List keys) throws UTXOProviderException; /** * Get the height of the chain head. diff --git a/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java b/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java index 4e75fa13..fcbf0f0a 100644 --- a/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/DatabaseFullPrunedBlockStore.java @@ -1150,14 +1150,15 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto } @Override - public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { + public List getOpenTransactionOutputs(List keys) throws UTXOProviderException { PreparedStatement s = null; List outputs = new ArrayList<>(); try { maybeConnect(); s = conn.get().prepareStatement(getTransactionOutputSelectSQL()); - for (LegacyAddress address : addresses) { - s.setString(1, address.toString()); + for (ECKey key : keys) { + // TODO switch to pubKeyHash in order to support native segwit addresses + s.setString(1, LegacyAddress.fromKey(params, key).toString()); ResultSet rs = s.executeQuery(); while (rs.next()) { Sha256Hash hash = Sha256Hash.wrap(rs.getBytes(1)); diff --git a/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java b/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java index bbb02f8f..7a54f9fc 100644 --- a/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/LevelDBFullPrunedBlockStore.java @@ -30,6 +30,7 @@ import java.nio.ByteBuffer; import org.bitcoinj.core.LegacyAddress; import org.bitcoinj.core.AddressFormatException; +import org.bitcoinj.core.ECKey; import org.bitcoinj.core.NetworkParameters; import org.bitcoinj.core.Sha256Hash; import org.bitcoinj.core.StoredBlock; @@ -420,16 +421,16 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore { } @Override - public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { + public List getOpenTransactionOutputs(List keys) throws UTXOProviderException { // Run this on a snapshot of database so internally consistent result // This is critical or if one address paid another could get incorrect // results List results = new LinkedList<>(); - for (LegacyAddress a : addresses) { + for (ECKey key : keys) { ByteBuffer bb = ByteBuffer.allocate(21); bb.put((byte) KeyType.ADDRESS_HASHINDEX.ordinal()); - bb.put(a.getHash()); + bb.put(key.getPubKeyHash()); ReadOptions ro = new ReadOptions(); Snapshot sn = db.getSnapshot(); @@ -443,7 +444,7 @@ public class LevelDBFullPrunedBlockStore implements FullPrunedBlockStore { bbKey.get(); // remove the address_hashindex byte. byte[] addressKey = new byte[20]; bbKey.get(addressKey); - if (!Arrays.equals(addressKey, a.getHash())) { + if (!Arrays.equals(addressKey, key.getPubKeyHash())) { break; } byte[] hashBytes = new byte[32]; diff --git a/core/src/main/java/org/bitcoinj/store/MemoryFullPrunedBlockStore.java b/core/src/main/java/org/bitcoinj/store/MemoryFullPrunedBlockStore.java index af0a21f4..f5c35799 100644 --- a/core/src/main/java/org/bitcoinj/store/MemoryFullPrunedBlockStore.java +++ b/core/src/main/java/org/bitcoinj/store/MemoryFullPrunedBlockStore.java @@ -412,13 +412,15 @@ public class MemoryFullPrunedBlockStore implements FullPrunedBlockStore { } @Override - public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { + public List getOpenTransactionOutputs(List keys) throws UTXOProviderException { // This is *NOT* optimal: We go through all the outputs and select the ones we are looking for. // If someone uses this store for production then they have a lot more to worry about than an inefficient impl :) List foundOutputs = new ArrayList<>(); List outputsList = transactionOutputMap.values(); for (UTXO output : outputsList) { - for (LegacyAddress address : addresses) { + for (ECKey key : keys) { + // TODO switch to pubKeyHash in order to support native segwit addresses + Address address = LegacyAddress.fromKey(params, key); if (output.getAddress().equals(address.toString())) { foundOutputs.add(output); } diff --git a/core/src/main/java/org/bitcoinj/wallet/Wallet.java b/core/src/main/java/org/bitcoinj/wallet/Wallet.java index c0904e71..a04f13b9 100644 --- a/core/src/main/java/org/bitcoinj/wallet/Wallet.java +++ b/core/src/main/java/org/bitcoinj/wallet/Wallet.java @@ -4300,12 +4300,7 @@ public class Wallet extends BaseTaggableObject List candidates = new ArrayList<>(); List keys = getImportedKeys(); keys.addAll(getActiveKeyChain().getLeafKeys()); - List addresses = new ArrayList<>(); - for (ECKey key : keys) { - LegacyAddress address = LegacyAddress.fromKey(params, key); - addresses.add(address); - } - candidates.addAll(utxoProvider.getOpenTransactionOutputs(addresses)); + candidates.addAll(utxoProvider.getOpenTransactionOutputs(keys)); return candidates; } diff --git a/core/src/test/java/org/bitcoinj/core/AbstractFullPrunedBlockChainTest.java b/core/src/test/java/org/bitcoinj/core/AbstractFullPrunedBlockChainTest.java index 394247f1..96183469 100644 --- a/core/src/test/java/org/bitcoinj/core/AbstractFullPrunedBlockChainTest.java +++ b/core/src/test/java/org/bitcoinj/core/AbstractFullPrunedBlockChainTest.java @@ -272,7 +272,7 @@ public abstract class AbstractFullPrunedBlockChainTest { chain.add(rollingBlock); totalAmount = totalAmount.add(amount); - List outputs = store.getOpenTransactionOutputs(Lists.newArrayList(address)); + List outputs = store.getOpenTransactionOutputs(Lists.newArrayList(toKey)); assertNotNull(outputs); assertEquals("Wrong Number of Outputs", 1, outputs.size()); UTXO output = outputs.get(0); diff --git a/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java b/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java index 252b389c..35f56fde 100644 --- a/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java +++ b/core/src/test/java/org/bitcoinj/core/TransactionInputTest.java @@ -69,7 +69,7 @@ public class TransactionInputTest { } @Override - public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { + public List getOpenTransactionOutputs(List addresses) throws UTXOProviderException { return Lists.newArrayList(utxo); }