diff --git a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java index 3f05643d..c8f9ea6b 100644 --- a/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java +++ b/src/main/java/org/qortal/api/resource/CrossChainHtlcResource.java @@ -157,7 +157,7 @@ public class CrossChainHtlcResource { htlcStatus.bitcoinP2shAddress = p2shAddress; htlcStatus.bitcoinP2shBalance = BigDecimal.valueOf(p2shBalance, 8); - List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddress.toString()); + List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddress.toString(), false); if (p2shBalance > 0L && !fundingOutputs.isEmpty()) { htlcStatus.canRedeem = now >= medianBlockTime * 1000L; @@ -401,7 +401,7 @@ public class CrossChainHtlcResource { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(decodedTradePrivateKey); - List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(bitcoiny.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, decodedSecret, foreignBlockchainReceivingAccountInfo); @@ -664,7 +664,7 @@ public class CrossChainHtlcResource { // ElectrumX coins ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoiny.getUnspentOutputs(p2shAddressA, false); // Validate the destination foreign blockchain address Address receiving = Address.fromString(bitcoiny.getNetworkParameters(), receiveAddress); diff --git a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java index 6963f11c..e7cb0fb8 100644 --- a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv1TradeBot.java @@ -894,7 +894,7 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { // Redeem P2SH-B using secret-B Coin redeemAmount = Coin.valueOf(P2SH_B_OUTPUT_AMOUNT); // An actual amount to avoid dust filter, remaining used as fees. The real funds are in P2SH-A. ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressB); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressB, false); byte[] receivingAccountInfo = tradeBotData.getReceivingAccountInfo(); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(bitcoin.getNetworkParameters(), redeemAmount, redeemKey, @@ -1064,7 +1064,7 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount - P2SH_B_OUTPUT_AMOUNT); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(bitcoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -1136,7 +1136,7 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(P2SH_B_OUTPUT_AMOUNT); // An actual amount to avoid dust filter, remaining used as fees. ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressB); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressB, false); // Determine receive address for refund String receiveAddress = bitcoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); @@ -1202,7 +1202,7 @@ public class BitcoinACCTv1TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount - P2SH_B_OUTPUT_AMOUNT); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = bitcoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv3TradeBot.java index 48f089d2..18f79b81 100644 --- a/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/BitcoinACCTv3TradeBot.java @@ -752,7 +752,7 @@ public class BitcoinACCTv3TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(bitcoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -816,7 +816,7 @@ public class BitcoinACCTv3TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = bitcoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = bitcoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/DigibyteACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/DigibyteACCTv3TradeBot.java index b8ce66e5..5b65c9a1 100644 --- a/src/main/java/org/qortal/controller/tradebot/DigibyteACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/DigibyteACCTv3TradeBot.java @@ -753,7 +753,7 @@ public class DigibyteACCTv3TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = digibyte.getUnspentOutputs(p2shAddressA); + List fundingOutputs = digibyte.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(digibyte.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -817,7 +817,7 @@ public class DigibyteACCTv3TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = digibyte.getUnspentOutputs(p2shAddressA); + List fundingOutputs = digibyte.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = digibyte.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv1TradeBot.java index 1d03bec7..6c9f5a29 100644 --- a/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv1TradeBot.java @@ -794,7 +794,7 @@ public class DogecoinACCTv1TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(dogecoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -858,7 +858,7 @@ public class DogecoinACCTv1TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = dogecoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv3TradeBot.java index 84e00a14..6a2ef700 100644 --- a/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/DogecoinACCTv3TradeBot.java @@ -753,7 +753,7 @@ public class DogecoinACCTv3TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(dogecoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -817,7 +817,7 @@ public class DogecoinACCTv3TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = dogecoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = dogecoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java index 43009421..cef93d12 100644 --- a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv1TradeBot.java @@ -757,7 +757,7 @@ public class LitecoinACCTv1TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(litecoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -821,7 +821,7 @@ public class LitecoinACCTv1TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = litecoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv3TradeBot.java index 5359d436..aa791e96 100644 --- a/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/LitecoinACCTv3TradeBot.java @@ -752,7 +752,7 @@ public class LitecoinACCTv3TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(litecoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -816,7 +816,7 @@ public class LitecoinACCTv3TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = litecoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = litecoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/controller/tradebot/RavencoinACCTv3TradeBot.java b/src/main/java/org/qortal/controller/tradebot/RavencoinACCTv3TradeBot.java index 2b640927..a383dfd8 100644 --- a/src/main/java/org/qortal/controller/tradebot/RavencoinACCTv3TradeBot.java +++ b/src/main/java/org/qortal/controller/tradebot/RavencoinACCTv3TradeBot.java @@ -753,7 +753,7 @@ public class RavencoinACCTv3TradeBot implements AcctTradeBot { case FUNDED: { Coin redeemAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey redeemKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = ravencoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = ravencoin.getUnspentOutputs(p2shAddressA, false); Transaction p2shRedeemTransaction = BitcoinyHTLC.buildRedeemTransaction(ravencoin.getNetworkParameters(), redeemAmount, redeemKey, fundingOutputs, redeemScriptA, secretA, receivingAccountInfo); @@ -817,7 +817,7 @@ public class RavencoinACCTv3TradeBot implements AcctTradeBot { case FUNDED:{ Coin refundAmount = Coin.valueOf(crossChainTradeData.expectedForeignAmount); ECKey refundKey = ECKey.fromPrivate(tradeBotData.getTradePrivateKey()); - List fundingOutputs = ravencoin.getUnspentOutputs(p2shAddressA); + List fundingOutputs = ravencoin.getUnspentOutputs(p2shAddressA, false); // Determine receive address for refund String receiveAddress = ravencoin.getUnusedReceiveAddress(tradeBotData.getForeignKey()); diff --git a/src/main/java/org/qortal/crosschain/Bitcoiny.java b/src/main/java/org/qortal/crosschain/Bitcoiny.java index b1938639..4a819209 100644 --- a/src/main/java/org/qortal/crosschain/Bitcoiny.java +++ b/src/main/java/org/qortal/crosschain/Bitcoiny.java @@ -208,8 +208,8 @@ public abstract class Bitcoiny implements ForeignBlockchain { * @throws ForeignBlockchainException if there was an error. */ // TODO: don't return bitcoinj-based objects like TransactionOutput, use BitcoinyTransaction.Output instead - public List getUnspentOutputs(String base58Address) throws ForeignBlockchainException { - List unspentOutputs = this.blockchainProvider.getUnspentOutputs(addressToScriptPubKey(base58Address), false); + public List getUnspentOutputs(String base58Address, boolean includeUnconfirmed) throws ForeignBlockchainException { + List unspentOutputs = this.blockchainProvider.getUnspentOutputs(addressToScriptPubKey(base58Address), includeUnconfirmed); List unspentTransactionOutputs = new ArrayList<>(); for (UnspentOutput unspentOutput : unspentOutputs) { @@ -430,7 +430,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { List allUnspentOutputs = new ArrayList<>(); Set walletAddresses = this.getWalletAddresses(key58); for (String address : walletAddresses) { - allUnspentOutputs.addAll(this.getUnspentOutputs(address)); + allUnspentOutputs.addAll(this.getUnspentOutputs(address, true)); } for (TransactionOutput output : allUnspentOutputs) { if (!output.isAvailableForSpending()) { @@ -504,7 +504,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { byte[] script = ScriptBuilder.createOutputScript(address).getProgram(); // Ask for transaction history - if it's empty then key has never been used - List historicTransactionHashes = this.getAddressTransactions(script, false); + List historicTransactionHashes = this.getAddressTransactions(script, true); if (!historicTransactionHashes.isEmpty()) { areAllKeysUnused = false; @@ -608,7 +608,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { byte[] script = ScriptBuilder.createOutputScript(address).getProgram(); // Ask for transaction history - if it's empty then key has never been used - List historicTransactionHashes = this.getAddressTransactions(script, false); + List historicTransactionHashes = this.getAddressTransactions(script, true); if (!historicTransactionHashes.isEmpty()) { areAllKeysUnused = false; @@ -842,7 +842,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { List unspentOutputs; try { - unspentOutputs = this.bitcoiny.blockchainProvider.getUnspentOutputs(script, false); + unspentOutputs = this.bitcoiny.blockchainProvider.getUnspentOutputs(script, true); } catch (ForeignBlockchainException e) { throw new UTXOProviderException(String.format("Unable to fetch unspent outputs for %s", address)); } @@ -932,7 +932,7 @@ public abstract class Bitcoiny implements ForeignBlockchain { } private Long summingUnspentOutputs(String walletAddress) throws ForeignBlockchainException { - return this.getUnspentOutputs(walletAddress).stream() + return this.getUnspentOutputs(walletAddress, true).stream() .map(TransactionOutput::getValue) .mapToLong(Coin::longValue) .sum(); diff --git a/src/main/java/org/qortal/crosschain/BitcoinyUTXOProvider.java b/src/main/java/org/qortal/crosschain/BitcoinyUTXOProvider.java index df596de4..2fcd7cee 100644 --- a/src/main/java/org/qortal/crosschain/BitcoinyUTXOProvider.java +++ b/src/main/java/org/qortal/crosschain/BitcoinyUTXOProvider.java @@ -30,7 +30,7 @@ public class BitcoinyUTXOProvider implements UTXOProvider { byte[] script = ScriptBuilder.createOutputScript(address).getProgram(); // collection UTXO's for all confirmed unspent outputs - for (UnspentOutput output : this.bitcoiny.blockchainProvider.getUnspentOutputs(script, false)) { + for (UnspentOutput output : this.bitcoiny.blockchainProvider.getUnspentOutputs(script, true)) { utxos.add(toUTXO(output)); } } diff --git a/src/test/java/org/qortal/test/crosschain/apps/Common.java b/src/test/java/org/qortal/test/crosschain/apps/Common.java index dd3130b9..5bba0dc4 100644 --- a/src/test/java/org/qortal/test/crosschain/apps/Common.java +++ b/src/test/java/org/qortal/test/crosschain/apps/Common.java @@ -92,7 +92,7 @@ public abstract class Common { List unspentOutputs = Collections.emptyList(); try { - unspentOutputs = bitcoiny.getUnspentOutputs(address58); + unspentOutputs = bitcoiny.getUnspentOutputs(address58, false); } catch (ForeignBlockchainException e) { System.err.println(String.format("Can't find unspent outputs for %s: %s", address58, e.getMessage())); return unspentOutputs;