From 666b29db6ec4d6d68c22f7fe8a5af033a21df29b Mon Sep 17 00:00:00 2001 From: Stefaan Ponnet Date: Thu, 16 Feb 2017 15:06:58 +0100 Subject: [PATCH 1/3] ETH validator / test added --- .../util/validation/AltCoinAddressValidator.java | 6 ++++++ .../validation/AltCoinAddressValidatorTest.java | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/gui/src/main/java/io/bitsquare/gui/util/validation/AltCoinAddressValidator.java b/gui/src/main/java/io/bitsquare/gui/util/validation/AltCoinAddressValidator.java index 853f7e0827..3846307037 100644 --- a/gui/src/main/java/io/bitsquare/gui/util/validation/AltCoinAddressValidator.java +++ b/gui/src/main/java/io/bitsquare/gui/util/validation/AltCoinAddressValidator.java @@ -56,6 +56,12 @@ public final class AltCoinAddressValidator extends InputValidator { ValidationResult regexTestFailed = new ValidationResult(false, "Address validation failed because it does not match the structure of a " + currencyCode + " address."); switch (currencyCode) { + case "ETH": + // https://github.com/ethereum/web3.js/blob/master/lib/utils/utils.js#L403 + if (!input.matches("^(0x)?[0-9a-fA-F]{40}$")){ + return regexTestFailed; + } + return new ValidationResult(true); // Example for BTC, though for BTC we use the BitcoinJ library address check case "BTC": // taken form: https://stackoverflow.com/questions/21683680/regex-to-match-bitcoin-addresses diff --git a/gui/src/test/java/io/bitsquare/gui/util/validation/AltCoinAddressValidatorTest.java b/gui/src/test/java/io/bitsquare/gui/util/validation/AltCoinAddressValidatorTest.java index 2bbe88734e..136e04b71d 100644 --- a/gui/src/test/java/io/bitsquare/gui/util/validation/AltCoinAddressValidatorTest.java +++ b/gui/src/test/java/io/bitsquare/gui/util/validation/AltCoinAddressValidatorTest.java @@ -92,4 +92,17 @@ public class AltCoinAddressValidatorTest { assertFalse(validator.validate("XGKZODTTTRXIUA75TKONWHFDCU6634DZ").isValid); } + @Test + public void testETH() { + AltCoinAddressValidator validator = new AltCoinAddressValidator(); + validator.setCurrencyCode("ETH"); + + assertTrue(validator.validate("0x2a65Aca4D5fC5B5C859090a6c34d164135398226").isValid); + assertTrue(validator.validate("2a65Aca4D5fC5B5C859090a6c34d164135398226").isValid); + + assertFalse(validator.validate("0x2a65Aca4D5fC5B5C859090a6c34d1641353982266").isValid); + assertFalse(validator.validate("0x2a65Aca4D5fC5B5C859090a6c34d16413539822g").isValid); + assertFalse(validator.validate("2a65Aca4D5fC5B5C859090a6c34d16413539822g").isValid); + assertFalse(validator.validate("").isValid); + } } From 850f0ef8ef8d46d90217f0985e4e5348741223bc Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sat, 18 Feb 2017 19:16:38 -0500 Subject: [PATCH 2/3] Add pub keys to trade detail window contract print --- .../gui/main/overlays/windows/TradeDetailsWindow.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java index a908278f20..0dab9b5280 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java @@ -43,6 +43,7 @@ import javafx.stage.Modality; import javafx.stage.Stage; import javafx.stage.StageStyle; import javafx.stage.Window; +import org.bitcoinj.core.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -207,7 +208,10 @@ public class TradeDetailsWindow extends Overlay { viewContractButton.setDefaultButton(false); viewContractButton.setOnAction(e -> { TextArea textArea = new TextArea(); - textArea.setText(trade.getContractAsJson()); + String contractAsJson = trade.getContractAsJson(); + contractAsJson += "\n\nBuyerPubKeyHex: " + Utils.HEX.encode(trade.getContract().getBuyerBtcPubKey()); + contractAsJson += "\nSellerPubKeyHex: " + Utils.HEX.encode(trade.getContract().getSellerBtcPubKey()); + textArea.setText(contractAsJson); textArea.setPrefHeight(50); textArea.setEditable(false); textArea.setWrapText(true); From 4f0d6484c555dab57137d7c1aff9ab362b15d636 Mon Sep 17 00:00:00 2001 From: Manfred Karrer Date: Sun, 19 Feb 2017 13:14:27 -0500 Subject: [PATCH 3/3] Add saving of addressEntryList at each change of list, remove usage of AddressEntry in TradeWalletService. Add pubKey to contract window at trade details popup. Remove unused arrays in SpendFromDepositTxWindow. --- .../bitsquare/arbitration/DisputeManager.java | 8 +- .../java/io/bitsquare/btc/AddressEntry.java | 12 +- .../io/bitsquare/btc/AddressEntryList.java | 2 +- .../io/bitsquare/btc/TradeWalletService.java | 165 ++++++++---------- .../java/io/bitsquare/btc/WalletService.java | 33 ++-- .../java/io/bitsquare/trade/Contract.java | 32 ++-- .../java/io/bitsquare/trade/TradeManager.java | 1 - .../placeoffer/tasks/CreateOfferFeeTx.java | 10 +- .../trade/protocol/trade/ProcessModel.java | 2 +- ...ffererCreatesAndSignsDepositTxAsBuyer.java | 10 +- .../buyer/SendFiatTransferStartedMessage.java | 7 +- .../buyer/SendPayoutTxFinalizedMessage.java | 2 +- .../tasks/buyer/SignAndFinalizePayoutTx.java | 10 +- .../buyer/SignAndPublishDepositTxAsBuyer.java | 4 +- .../TakerCreatesDepositTxInputsAsBuyer.java | 9 +- .../tasks/offerer/CreateAndSignContract.java | 12 +- .../offerer/SendPublishDepositTxRequest.java | 8 +- ...fererCreatesAndSignsDepositTxAsSeller.java | 10 +- .../seller/SendFinalizePayoutTxRequest.java | 7 +- .../SignAndPublishDepositTxAsSeller.java | 3 +- .../trade/tasks/seller/SignPayoutTx.java | 10 +- .../TakerCreatesDepositTxInputsAsSeller.java | 12 +- .../tasks/taker/CreateTakeOfferFeeTx.java | 13 +- .../taker/SendDepositTxPublishedMessage.java | 2 +- .../tasks/taker/SendPayDepositRequest.java | 12 +- .../tasks/taker/VerifyAndSignContract.java | 14 +- .../io/bitsquare/gui/main/MainViewModel.java | 2 +- .../gui/main/funds/locked/LockedListItem.java | 2 +- .../main/overlays/windows/ContractWindow.java | 4 +- .../windows/DisputeSummaryWindow.java | 7 +- .../windows/ShowWalletDataWindow.java | 3 +- .../windows/SpendFromDepositTxWindow.java | 17 -- .../overlays/windows/TradeDetailsWindow.java | 4 +- .../failedtrades/FailedTradesView.fxml | 2 +- .../portfolio/openoffer/OpenOffersView.fxml | 2 +- 35 files changed, 238 insertions(+), 215 deletions(-) diff --git a/core/src/main/java/io/bitsquare/arbitration/DisputeManager.java b/core/src/main/java/io/bitsquare/arbitration/DisputeManager.java index eb6f85bdc0..2870852ebe 100644 --- a/core/src/main/java/io/bitsquare/arbitration/DisputeManager.java +++ b/core/src/main/java/io/bitsquare/arbitration/DisputeManager.java @@ -597,7 +597,7 @@ public class DisputeManager { if (dispute.getDepositTxSerialized() != null) { try { log.debug("do payout Transaction "); - + AddressEntry multiSigAddressEntry = walletService.getOrCreateAddressEntry(dispute.getTradeId(), AddressEntry.Context.MULTI_SIG); Transaction signedDisputedPayoutTx = tradeWalletService.traderSignAndFinalizeDisputedPayoutTx( dispute.getDepositTxSerialized(), disputeResult.getArbitratorSignature(), @@ -607,9 +607,9 @@ public class DisputeManager { contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), disputeResult.getArbitratorAddressAsString(), - walletService.getOrCreateAddressEntry(dispute.getTradeId(), AddressEntry.Context.MULTI_SIG), - contract.getBuyerBtcPubKey(), - contract.getSellerBtcPubKey(), + multiSigAddressEntry.getKeyPair(), + contract.getBuyerMultiSigPubKey(), + contract.getSellerMultiSigPubKey(), disputeResult.getArbitratorPubKey() ); Transaction committedDisputedPayoutTx = tradeWalletService.addTransactionToWallet(signedDisputedPayoutTx); diff --git a/core/src/main/java/io/bitsquare/btc/AddressEntry.java b/core/src/main/java/io/bitsquare/btc/AddressEntry.java index b1caa05c30..5d3a958da5 100644 --- a/core/src/main/java/io/bitsquare/btc/AddressEntry.java +++ b/core/src/main/java/io/bitsquare/btc/AddressEntry.java @@ -76,7 +76,7 @@ public final class AddressEntry implements Persistable { private final byte[] pubKeyHash; private final String paramId; @Nullable - private Coin lockedTradeAmount; + private Coin coinLockedInMultiSig; transient private NetworkParameters params; @@ -179,13 +179,13 @@ public final class AddressEntry implements Persistable { return isOpenOffer() || isTrade(); } - public void setLockedTradeAmount(Coin lockedTradeAmount) { - this.lockedTradeAmount = lockedTradeAmount; + public void setCoinLockedInMultiSig(Coin coinLockedInMultiSig) { + this.coinLockedInMultiSig = coinLockedInMultiSig; } - @org.jetbrains.annotations.Nullable - public Coin getLockedTradeAmount() { - return lockedTradeAmount; + @Nullable + public Coin getCoinLockedInMultiSig() { + return coinLockedInMultiSig; } @Override diff --git a/core/src/main/java/io/bitsquare/btc/AddressEntryList.java b/core/src/main/java/io/bitsquare/btc/AddressEntryList.java index 880c71accd..b980f0a983 100644 --- a/core/src/main/java/io/bitsquare/btc/AddressEntryList.java +++ b/core/src/main/java/io/bitsquare/btc/AddressEntryList.java @@ -95,6 +95,6 @@ public final class AddressEntryList extends ArrayList implements P } public void queueUpForSave() { - storage.queueUpForSave(); + storage.queueUpForSave(50); } } diff --git a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java index 34cca326d9..dc9a540f4d 100644 --- a/core/src/main/java/io/bitsquare/btc/TradeWalletService.java +++ b/core/src/main/java/io/bitsquare/btc/TradeWalletService.java @@ -188,20 +188,21 @@ public class TradeWalletService { /** - * The taker creates a dummy transaction to get the input(s) and optional change output for the amount and the takersAddressEntry for that trade. + * The taker creates a dummy transaction to get the input(s) and optional change output for the amount and the takersAddress for that trade. * That will be used to send to the offerer for creating the deposit transaction. * - * @param inputAmount Amount of takers input - * @param takersAddressEntry Address entry of taker + * @param inputAmount Amount of takers input + * @param takersAddress Address of taker + * @param takersChangeAddress Change address of taker * @return A data container holding the inputs, the output value and address * @throws TransactionVerificationException * @throws WalletException */ - public InputsAndChangeOutput takerCreatesDepositsTxInputs(Coin inputAmount, AddressEntry takersAddressEntry, Address takersChangeAddress) throws + public InputsAndChangeOutput takerCreatesDepositsTxInputs(Coin inputAmount, Address takersAddress, Address takersChangeAddress) throws TransactionVerificationException, WalletException, AddressFormatException { log.trace("takerCreatesDepositsTxInputs called"); log.trace("inputAmount " + inputAmount.toFriendlyString()); - log.trace("takersAddressEntry " + takersAddressEntry.toString()); + log.trace("takersAddress " + takersAddress.toString()); // We add the mining fee 2 times to the deposit tx: // 1. Will be spent when publishing the deposit tx (paid by buyer) @@ -231,7 +232,7 @@ public class TradeWalletService { // Find the needed inputs to pay the output, optionally add 1 change output. // Normally only 1 input and no change output is used, but we support multiple inputs and 1 change output. // Our spending transaction output is from the create offer fee payment. - addAvailableInputsAndChangeOutputs(dummyTX, takersAddressEntry, takersChangeAddress); + addAvailableInputsAndChangeOutputs(dummyTX, takersAddress, takersChangeAddress); // The completeTx() call signs the input, but we don't want to pass over signed tx inputs so we remove the signature removeSignatures(dummyTX); @@ -275,7 +276,8 @@ public class TradeWalletService { * @param takerRawTransactionInputs Raw data for the connected outputs for all inputs of the taker (normally 1 input) * @param takerChangeOutputValue Optional taker change output value * @param takerChangeAddressString Optional taker change address - * @param offererAddressEntry The offerer's address entry. + * @param offererAddress The offerer's address. + * @param offererChangeAddress The offerer's change address. * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. * @param arbitratorPubKey The public key of the arbitrator. @@ -291,7 +293,7 @@ public class TradeWalletService { List takerRawTransactionInputs, long takerChangeOutputValue, @Nullable String takerChangeAddressString, - AddressEntry offererAddressEntry, + Address offererAddress, Address offererChangeAddress, byte[] buyerPubKey, byte[] sellerPubKey, @@ -304,6 +306,8 @@ public class TradeWalletService { log.trace("takerRawInputs " + takerRawTransactionInputs.toString()); log.trace("takerChangeOutputValue " + takerChangeOutputValue); log.trace("takerChangeAddressString " + takerChangeAddressString); + log.trace("offererAddress " + offererAddress); + log.trace("offererChangeAddress " + offererChangeAddress); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); @@ -316,7 +320,7 @@ public class TradeWalletService { Coin dummyOutputAmount = offererInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades()); TransactionOutput dummyOutput = new TransactionOutput(params, dummyTx, dummyOutputAmount, new ECKey().toAddress(params)); dummyTx.addOutput(dummyOutput); - addAvailableInputsAndChangeOutputs(dummyTx, offererAddressEntry, offererChangeAddress); + addAvailableInputsAndChangeOutputs(dummyTx, offererAddress, offererChangeAddress); // Normally we have only 1 input but we support multiple inputs if the user has paid in with several transactions. List offererInputs = dummyTx.getInputs(); TransactionOutput offererOutput = null; @@ -504,11 +508,11 @@ public class TradeWalletService { checkScriptSig(depositTx, input, i); } + printTxWithInputs("depositTx", depositTx); + verifyTransaction(depositTx); checkWalletConsistency(); - printTxWithInputs("depositTx", depositTx); - // Broadcast depositTx checkNotNull(walletAppKit); ListenableFuture broadcastComplete = walletAppKit.peerGroup().broadcastTransaction(depositTx).future(); @@ -525,7 +529,7 @@ public class TradeWalletService { * @param buyerPayoutAmount Payout amount for buyer * @param sellerPayoutAmount Payout amount for seller * @param buyerPayoutAddressString Address for buyer - * @param sellerPayoutAddressEntry AddressEntry for seller + * @param multiSigKeyPair DeterministicKey for MultiSig from seller * @param lockTime Lock time * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. @@ -538,8 +542,8 @@ public class TradeWalletService { Coin buyerPayoutAmount, Coin sellerPayoutAmount, String buyerPayoutAddressString, - AddressEntry sellerPayoutAddressEntry, - AddressEntry multiSigAddressEntry, + String sellerPayoutAddressString, + DeterministicKey multiSigKeyPair, long lockTime, byte[] buyerPubKey, byte[] sellerPubKey, @@ -550,8 +554,8 @@ public class TradeWalletService { log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); log.trace("buyerPayoutAddressString " + buyerPayoutAddressString); - log.trace("sellerPayoutAddressEntry " + sellerPayoutAddressEntry.toString()); - log.trace("multiSigAddressEntry " + multiSigAddressEntry.toString()); + log.trace("sellerPayoutAddressString " + sellerPayoutAddressString); + log.trace("multiSigKeyPair (not displayed for security reasons)"); log.trace("lockTime " + lockTime); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); @@ -561,19 +565,18 @@ public class TradeWalletService { buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, - sellerPayoutAddressEntry.getAddressString(), + sellerPayoutAddressString, lockTime ); // MS redeemScript Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); // MS output from prev. tx is index 0 Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - DeterministicKey keyPair = multiSigAddressEntry.getKeyPair(); - checkNotNull(keyPair, "multiSigAddressEntry.getKeyPair() must not be null"); - if (keyPair.isEncrypted()) + checkNotNull(multiSigKeyPair, "multiSigAddressEntry.getKeyPair() must not be null"); + if (multiSigKeyPair.isEncrypted()) checkNotNull(aesKey); - ECKey.ECDSASignature sellerSignature = keyPair.sign(sigHash, aesKey).toCanonicalised(); + ECKey.ECDSASignature sellerSignature = multiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); verifyTransaction(preparedPayoutTx); @@ -585,16 +588,17 @@ public class TradeWalletService { /** * Buyer creates and signs payout transaction and adds signature of seller to complete the transaction * - * @param depositTx Deposit transaction - * @param sellerSignature DER encoded canonical signature of seller - * @param buyerPayoutAmount Payout amount for buyer - * @param sellerPayoutAmount Payout amount for seller - * @param buyerPayoutAddressEntry AddressEntry for buyer - * @param sellerAddressString Address for seller - * @param lockTime Lock time - * @param buyerPubKey The public key of the buyer. - * @param sellerPubKey The public key of the seller. - * @param arbitratorPubKey The public key of the arbitrator. + * @param depositTx Deposit transaction + * @param sellerSignature DER encoded canonical signature of seller + * @param buyerPayoutAmount Payout amount for buyer + * @param sellerPayoutAmount Payout amount for seller + * @param buyerPayoutAddressString Address for buyer + * @param sellerPayoutAddressString Address for seller + * @param multiSigKeyPair Buyer's keypair for MultiSig + * @param lockTime Lock time + * @param buyerPubKey The public key of the buyer. + * @param sellerPubKey The public key of the seller. + * @param arbitratorPubKey The public key of the arbitrator. * @return The payout transaction * @throws AddressFormatException * @throws TransactionVerificationException @@ -604,9 +608,9 @@ public class TradeWalletService { byte[] sellerSignature, Coin buyerPayoutAmount, Coin sellerPayoutAmount, - AddressEntry buyerPayoutAddressEntry, - AddressEntry multiSigAddressEntry, - String sellerAddressString, + String buyerPayoutAddressString, + String sellerPayoutAddressString, + DeterministicKey multiSigKeyPair, long lockTime, byte[] buyerPubKey, byte[] sellerPubKey, @@ -618,9 +622,9 @@ public class TradeWalletService { log.trace("sellerSignature s " + ECKey.ECDSASignature.decodeFromDER(sellerSignature).s.toString()); log.trace("buyerPayoutAmount " + buyerPayoutAmount.toFriendlyString()); log.trace("sellerPayoutAmount " + sellerPayoutAmount.toFriendlyString()); - log.trace("buyerPayoutAddressEntry " + buyerPayoutAddressEntry); - log.trace("multiSigAddressEntry " + multiSigAddressEntry); - log.trace("sellerAddressString " + sellerAddressString); + log.trace("buyerPayoutAddressString " + buyerPayoutAddressString); + log.trace("sellerPayoutAddressString " + sellerPayoutAddressString); + log.trace("multiSigKeyPair (not displayed for security reasons)"); log.trace("lockTime " + lockTime); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); @@ -629,19 +633,18 @@ public class TradeWalletService { Transaction payoutTx = createPayoutTx(depositTx, buyerPayoutAmount, sellerPayoutAmount, - buyerPayoutAddressEntry.getAddressString(), - sellerAddressString, + buyerPayoutAddressString, + sellerPayoutAddressString, lockTime); // MS redeemScript Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); // MS output from prev. tx is index 0 Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - final DeterministicKey keyPair = multiSigAddressEntry.getKeyPair(); - checkNotNull(keyPair, "multiSigAddressEntry.getKeyPair() must not be null"); - if (keyPair.isEncrypted()) + checkNotNull(multiSigKeyPair, "multiSigAddressEntry.getKeyPair() must not be null"); + if (multiSigKeyPair.isEncrypted()) checkNotNull(aesKey); - ECKey.ECDSASignature buyerSignature = keyPair.sign(sigHash, aesKey).toCanonicalised(); + ECKey.ECDSASignature buyerSignature = multiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature sellerTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(sellerSignature), Transaction.SigHash.ALL, false); TransactionSignature buyerTxSig = new TransactionSignature(buyerSignature, Transaction.SigHash.ALL, false); @@ -677,7 +680,7 @@ public class TradeWalletService { * @param arbitratorPayoutAmount The payout amount of the arbitrator. * @param buyerAddressString The address of the buyer. * @param sellerAddressString The address of the seller. - * @param arbitratorAddressEntry The addressEntry of the arbitrator. + * @param arbitratorKeyPair The keypair of the arbitrator. * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. * @param arbitratorPubKey The public key of the arbitrator. @@ -691,7 +694,8 @@ public class TradeWalletService { Coin arbitratorPayoutAmount, String buyerAddressString, String sellerAddressString, - AddressEntry arbitratorAddressEntry, + String arbitratorAddressString, + DeterministicKey arbitratorKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) @@ -704,7 +708,8 @@ public class TradeWalletService { log.trace("arbitratorPayoutAmount " + arbitratorPayoutAmount.toFriendlyString()); log.trace("buyerAddressString " + buyerAddressString); log.trace("sellerAddressString " + sellerAddressString); - log.trace("arbitratorAddressEntry " + arbitratorAddressEntry.toString()); + log.trace("arbitratorAddressString " + arbitratorAddressString); + log.trace("arbitratorKeyPair (not displayed for security reasons)"); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); @@ -717,18 +722,17 @@ public class TradeWalletService { preparedPayoutTx.addOutput(buyerPayoutAmount, new Address(params, buyerAddressString)); if (sellerPayoutAmount.isGreaterThan(Coin.ZERO)) preparedPayoutTx.addOutput(sellerPayoutAmount, new Address(params, sellerAddressString)); - if (arbitratorPayoutAmount.isGreaterThan(Coin.ZERO) && arbitratorAddressEntry.getAddressString() != null) - preparedPayoutTx.addOutput(arbitratorPayoutAmount, new Address(params, arbitratorAddressEntry.getAddressString())); + if (arbitratorPayoutAmount.isGreaterThan(Coin.ZERO) && arbitratorAddressString != null) + preparedPayoutTx.addOutput(arbitratorPayoutAmount, new Address(params, arbitratorAddressString)); // take care of sorting! Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - final DeterministicKey keyPair = arbitratorAddressEntry.getKeyPair(); - checkNotNull(keyPair, "arbitratorAddressEntry.getKeyPair() must not be null"); - if (keyPair.isEncrypted()) + checkNotNull(arbitratorKeyPair, "arbitratorKeyPair.getKeyPair() must not be null"); + if (arbitratorKeyPair.isEncrypted()) checkNotNull(aesKey); - ECKey.ECDSASignature arbitratorSignature = keyPair.sign(sigHash, aesKey).toCanonicalised(); + ECKey.ECDSASignature arbitratorSignature = arbitratorKeyPair.sign(sigHash, aesKey).toCanonicalised(); verifyTransaction(preparedPayoutTx); @@ -748,7 +752,7 @@ public class TradeWalletService { * @param buyerAddressString The address of the buyer. * @param sellerAddressString The address of the seller. * @param arbitratorAddressString The address of the arbitrator. - * @param tradersMultiSigAddressEntry The addressEntry of the trader who calls that method + * @param tradersMultiSigKeyPair The keypair for the MultiSig of the trader who calls that method * @param buyerPubKey The public key of the buyer. * @param sellerPubKey The public key of the seller. * @param arbitratorPubKey The public key of the arbitrator. @@ -765,7 +769,7 @@ public class TradeWalletService { String buyerAddressString, String sellerAddressString, String arbitratorAddressString, - AddressEntry tradersMultiSigAddressEntry, + DeterministicKey tradersMultiSigKeyPair, byte[] buyerPubKey, byte[] sellerPubKey, byte[] arbitratorPubKey) @@ -782,7 +786,7 @@ public class TradeWalletService { log.trace("buyerAddressString " + buyerAddressString); log.trace("sellerAddressString " + sellerAddressString); log.trace("arbitratorAddressString " + arbitratorAddressString); - log.trace("tradersMultiSigAddressEntry " + tradersMultiSigAddressEntry); + log.trace("tradersMultiSigKeyPair (not displayed for security reasons)"); log.trace("buyerPubKey " + ECKey.fromPublicOnly(buyerPubKey).toString()); log.trace("sellerPubKey " + ECKey.fromPublicOnly(sellerPubKey).toString()); log.trace("arbitratorPubKey " + ECKey.fromPublicOnly(arbitratorPubKey).toString()); @@ -801,11 +805,10 @@ public class TradeWalletService { // take care of sorting! Script redeemScript = getMultiSigRedeemScript(buyerPubKey, sellerPubKey, arbitratorPubKey); Sha256Hash sigHash = payoutTx.hashForSignature(0, redeemScript, Transaction.SigHash.ALL, false); - DeterministicKey keyPair = tradersMultiSigAddressEntry.getKeyPair(); - checkNotNull(keyPair, "tradersMultiSigAddressEntry.getKeyPair() must not be null"); - if (keyPair.isEncrypted()) + checkNotNull(tradersMultiSigKeyPair, "tradersMultiSigKeyPair.getKeyPair() must not be null"); + if (tradersMultiSigKeyPair.isEncrypted()) checkNotNull(aesKey); - ECKey.ECDSASignature tradersSignature = keyPair.sign(sigHash, aesKey).toCanonicalised(); + ECKey.ECDSASignature tradersSignature = tradersMultiSigKeyPair.sign(sigHash, aesKey).toCanonicalised(); TransactionSignature tradersTxSig = new TransactionSignature(tradersSignature, Transaction.SigHash.ALL, false); TransactionSignature arbitratorTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(arbitratorSignature), @@ -815,14 +818,14 @@ public class TradeWalletService { TransactionInput input = payoutTx.getInput(0); input.setScriptSig(inputScript); + printTxWithInputs("disputed payoutTx", payoutTx); + verifyTransaction(payoutTx); checkWalletConsistency(); checkScriptSig(payoutTx, input, 0); checkNotNull(input.getConnectedOutput(), "input.getConnectedOutput() must not be null"); input.verify(input.getConnectedOutput()); - printTxWithInputs("disputed payoutTx", payoutTx); - // As we use lockTime the tx will not be relayed as it is not considered standard. // We need to broadcast on our own when we reached the block height. Both peers will do the broadcast. return payoutTx; @@ -845,8 +848,6 @@ public class TradeWalletService { String sellerPubKeyAsHex, String arbitratorPubKeyAsHex, String P2SHMultiSigOutputScript, - List buyerPubKeys, - List sellerPubKeys, FutureCallback callback) throws AddressFormatException, TransactionVerificationException, WalletException { log.info("signAndPublishPayoutTx called"); @@ -864,8 +865,6 @@ public class TradeWalletService { log.info("sellerPubKeyAsHex " + sellerPubKeyAsHex); log.info("arbitratorPubKeyAsHex " + arbitratorPubKeyAsHex); log.info("P2SHMultiSigOutputScript " + P2SHMultiSigOutputScript); - log.info("buyerPubKeys " + buyerPubKeys); - log.info("sellerPubKeys " + sellerPubKeys); checkNotNull((buyerPrivateKeyAsHex != null || sellerPrivateKeyAsHex != null), "either buyerPrivateKeyAsHex or sellerPrivateKeyAsHex must not be null"); @@ -874,34 +873,8 @@ public class TradeWalletService { final byte[] arbitratorPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(arbitratorPubKeyAsHex)).getPubKey(); Script p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(buyerPubKey, sellerPubKey, arbitratorPubKey); - - if (!p2SHMultiSigOutputScript.toString().contains(P2SHMultiSigOutputScript)) { - if (buyerPubKeys.isEmpty()) - buyerPubKeys.add(buyerPubKeyAsHex); - if (sellerPubKeys.isEmpty()) - sellerPubKeys.add(sellerPubKeyAsHex); - - boolean found = false; - for (String b : buyerPubKeys) { - if (found) - break; - byte[] bk = ECKey.fromPublicOnly(Utils.HEX.decode(b)).getPubKey(); - for (String s : sellerPubKeys) { - byte[] sk = ECKey.fromPublicOnly(Utils.HEX.decode(s)).getPubKey(); - p2SHMultiSigOutputScript = getP2SHMultiSigOutputScript(bk, sk, arbitratorPubKey); - if (p2SHMultiSigOutputScript.toString().contains(P2SHMultiSigOutputScript)) { - log.info("Found buyers pub key " + b); - log.info("Found sellers pub key " + s); - buyerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(b)).getPubKey(); - sellerPubKey = ECKey.fromPublicOnly(Utils.HEX.decode(s)).getPubKey(); - found = true; - break; - } - } - } - if (!found) - log.warn("We did not find any matching pub keys for generating the required p2SHMultiSigOutputScript"); - } + if (!p2SHMultiSigOutputScript.toString().contains(P2SHMultiSigOutputScript)) + log.error("p2SHMultiSigOutputScript does not match. Probably a pubkey is not correct."); Coin msOutput = buyerPayoutAmount.add(sellerPayoutAmount).add(arbitratorPayoutAmount).add(FeePolicy.getFixedTxFeeForTrades()); TransactionOutput p2SHMultiSigOutput = new TransactionOutput(params, null, msOutput, p2SHMultiSigOutputScript.getProgram()); @@ -1126,7 +1099,7 @@ public class TradeWalletService { int size = tx.getMessageSize(); log.info(tracePrefix + ": " + tx.toString() + "\nSize (Byte): " + size + "\nFee (Satoshi/Byte): " + (fee / size)); - + for (TransactionInput input : tx.getInputs()) { if (input.getConnectedOutput() != null) log.info(tracePrefix + " input value: " + input.getConnectedOutput().getValue().toFriendlyString()); @@ -1196,7 +1169,7 @@ public class TradeWalletService { } } - private void addAvailableInputsAndChangeOutputs(Transaction transaction, AddressEntry addressEntry, Address changeAddress) throws WalletException { + private void addAvailableInputsAndChangeOutputs(Transaction transaction, Address address, Address changeAddress) throws WalletException { try { // Lets let the framework do the work to find the right inputs Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(transaction); @@ -1206,7 +1179,7 @@ public class TradeWalletService { sendRequest.feePerKb = Coin.ZERO; sendRequest.fee = FeePolicy.getFixedTxFeeForTrades(); // we allow spending of unconfirmed tx (double spend risk is low and usability would suffer if we need to wait for 1 confirmation) - sendRequest.coinSelector = new TradeWalletCoinSelector(params, addressEntry.getAddress()); + sendRequest.coinSelector = new TradeWalletCoinSelector(params, address); // We use always the same address in a trade for all transactions sendRequest.changeAddress = changeAddress; // With the usage of completeTx() we get all the work done with fee calculation, validation and coin selection. diff --git a/core/src/main/java/io/bitsquare/btc/WalletService.java b/core/src/main/java/io/bitsquare/btc/WalletService.java index dfb7f870a7..b8f70de4d6 100644 --- a/core/src/main/java/io/bitsquare/btc/WalletService.java +++ b/core/src/main/java/io/bitsquare/btc/WalletService.java @@ -453,7 +453,6 @@ public class WalletService { public void decryptWallet(@NotNull KeyParameter key) { wallet.decrypt(key); addressEntryList.stream().forEach(e -> { - final DeterministicKey keyPair = e.getKeyPair(); if (keyPair != null && keyPair.isEncrypted()) e.setDeterministicKey(keyPair.decrypt(key)); @@ -519,20 +518,20 @@ public class WalletService { .filter(e -> offerId.equals(e.getOfferId())) .filter(e -> context == e.getContext()) .findAny(); - if (addressEntry.isPresent()) + if (addressEntry.isPresent()) { return addressEntry.get(); - else - return addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context, offerId)); + } else { + AddressEntry entry = addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context, offerId)); + saveAddressEntryList(); + return entry; + } } public AddressEntry getOrCreateAddressEntry(AddressEntry.Context context) { Optional addressEntry = getAddressEntryListAsImmutableList().stream() .filter(e -> context == e.getContext()) .findAny(); - if (addressEntry.isPresent()) - return addressEntry.get(); - else - return addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context)); + return getOrCreateAddressEntry(context, addressEntry); } public AddressEntry getOrCreateUnusedAddressEntry(AddressEntry.Context context) { @@ -540,10 +539,17 @@ public class WalletService { .filter(e -> context == e.getContext()) .filter(e -> getNumTxOutputsForAddress(e.getAddress()) == 0) .findAny(); - if (addressEntry.isPresent()) + return getOrCreateAddressEntry(context, addressEntry); + } + + private AddressEntry getOrCreateAddressEntry(AddressEntry.Context context, Optional addressEntry) { + if (addressEntry.isPresent()) { return addressEntry.get(); - else - return addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context)); + } else { + AddressEntry entry = addressEntryList.addAddressEntry(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), context)); + saveAddressEntryList(); + return entry; + } } public Optional findAddressEntry(String address, AddressEntry.Context context) { @@ -580,7 +586,10 @@ public class WalletService { .filter(e -> offerId.equals(e.getOfferId())) .filter(e -> context == e.getContext()) .findAny(); - addressEntryOptional.ifPresent(addressEntryList::swapToAvailable); + addressEntryOptional.ifPresent(e -> { + addressEntryList.swapToAvailable(e); + saveAddressEntryList(); + }); } public void swapAnyTradeEntryContextToAvailableEntry(String offerId) { diff --git a/core/src/main/java/io/bitsquare/trade/Contract.java b/core/src/main/java/io/bitsquare/trade/Contract.java index 3de8d18a1c..4714c0403e 100644 --- a/core/src/main/java/io/bitsquare/trade/Contract.java +++ b/core/src/main/java/io/bitsquare/trade/Contract.java @@ -60,9 +60,9 @@ public final class Contract implements Payload { private final String offererPayoutAddressString; private final String takerPayoutAddressString; @JsonExclude - private final byte[] offererBtcPubKey; + private final byte[] offererMultiSigPubKey; @JsonExclude - private final byte[] takerBtcPubKey; + private final byte[] takerMultiSigPubKey; public Contract(Offer offer, Coin tradeAmount, @@ -80,8 +80,8 @@ public final class Contract implements Payload { PubKeyRing takerPubKeyRing, String offererPayoutAddressString, String takerPayoutAddressString, - byte[] offererBtcPubKey, - byte[] takerBtcPubKey) { + byte[] offererMultiSigPubKey, + byte[] takerMultiSigPubKey) { this.offer = offer; this.tradePrice = tradePrice.value; this.buyerNodeAddress = buyerNodeAddress; @@ -98,8 +98,8 @@ public final class Contract implements Payload { this.takerPubKeyRing = takerPubKeyRing; this.offererPayoutAddressString = offererPayoutAddressString; this.takerPayoutAddressString = takerPayoutAddressString; - this.offererBtcPubKey = offererBtcPubKey; - this.takerBtcPubKey = takerBtcPubKey; + this.offererMultiSigPubKey = offererMultiSigPubKey; + this.takerMultiSigPubKey = takerMultiSigPubKey; } public boolean isBuyerOffererAndSellerTaker() { @@ -131,12 +131,12 @@ public final class Contract implements Payload { return isBuyerOffererAndSellerTaker ? takerPubKeyRing : offererPubKeyRing; } - public byte[] getBuyerBtcPubKey() { - return isBuyerOffererAndSellerTaker ? offererBtcPubKey : takerBtcPubKey; + public byte[] getBuyerMultiSigPubKey() { + return isBuyerOffererAndSellerTaker ? offererMultiSigPubKey : takerMultiSigPubKey; } - public byte[] getSellerBtcPubKey() { - return isBuyerOffererAndSellerTaker ? takerBtcPubKey : offererBtcPubKey; + public byte[] getSellerMultiSigPubKey() { + return isBuyerOffererAndSellerTaker ? takerMultiSigPubKey : offererMultiSigPubKey; } public PaymentAccountContractData getBuyerPaymentAccountContractData() { @@ -206,8 +206,8 @@ public final class Contract implements Payload { return false; if (takerPayoutAddressString != null ? !takerPayoutAddressString.equals(contract.takerPayoutAddressString) : contract.takerPayoutAddressString != null) return false; - if (!Arrays.equals(offererBtcPubKey, contract.offererBtcPubKey)) return false; - return Arrays.equals(takerBtcPubKey, contract.takerBtcPubKey); + if (!Arrays.equals(offererMultiSigPubKey, contract.offererMultiSigPubKey)) return false; + return Arrays.equals(takerMultiSigPubKey, contract.takerMultiSigPubKey); } @@ -229,8 +229,8 @@ public final class Contract implements Payload { result = 31 * result + (sellerNodeAddress != null ? sellerNodeAddress.hashCode() : 0); result = 31 * result + (offererPayoutAddressString != null ? offererPayoutAddressString.hashCode() : 0); result = 31 * result + (takerPayoutAddressString != null ? takerPayoutAddressString.hashCode() : 0); - result = 31 * result + (offererBtcPubKey != null ? Arrays.hashCode(offererBtcPubKey) : 0); - result = 31 * result + (takerBtcPubKey != null ? Arrays.hashCode(takerBtcPubKey) : 0); + result = 31 * result + (offererMultiSigPubKey != null ? Arrays.hashCode(offererMultiSigPubKey) : 0); + result = 31 * result + (takerMultiSigPubKey != null ? Arrays.hashCode(takerMultiSigPubKey) : 0); return result; } @@ -253,8 +253,8 @@ public final class Contract implements Payload { "\n\tsellerAddress=" + sellerNodeAddress + "\n\toffererPayoutAddressString='" + offererPayoutAddressString + '\'' + "\n\ttakerPayoutAddressString='" + takerPayoutAddressString + '\'' + - "\n\toffererBtcPubKey=" + Arrays.toString(offererBtcPubKey) + - "\n\ttakerBtcPubKey=" + Arrays.toString(takerBtcPubKey) + + "\n\toffererBtcPubKey=" + Arrays.toString(offererMultiSigPubKey) + + "\n\ttakerBtcPubKey=" + Arrays.toString(takerMultiSigPubKey) + '}'; } } diff --git a/core/src/main/java/io/bitsquare/trade/TradeManager.java b/core/src/main/java/io/bitsquare/trade/TradeManager.java index 34d523f901..8c5e55161b 100644 --- a/core/src/main/java/io/bitsquare/trade/TradeManager.java +++ b/core/src/main/java/io/bitsquare/trade/TradeManager.java @@ -382,7 +382,6 @@ public class TradeManager { public void onWithdrawRequest(String toAddress, Coin receiverAmount, KeyParameter aesKey, Trade trade, ResultHandler resultHandler, FaultHandler faultHandler) { String fromAddress = walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(); - FutureCallback callback = new FutureCallback() { @Override public void onSuccess(@javax.annotation.Nullable Transaction transaction) { diff --git a/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/CreateOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/CreateOfferFeeTx.java index f3d9a4e15b..e59fc2c3e3 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/CreateOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/placeoffer/tasks/CreateOfferFeeTx.java @@ -26,6 +26,7 @@ import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.NodeAddress; import io.bitsquare.trade.protocol.placeoffer.PlaceOfferModel; import io.bitsquare.trade.protocol.trade.ArbitrationSelectionRule; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,10 +51,13 @@ public class CreateOfferFeeTx extends Task { checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateOfferFeeTx"); WalletService walletService = model.walletService; String id = model.offer.getId(); + Address fundingAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING).getAddress(); + Address reservedForTradeAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(); + Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); Transaction transaction = model.tradeWalletService.createTradingFeeTx( - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING).getAddress(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(), - walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(), + fundingAddress, + reservedForTradeAddress, + changeAddress, model.reservedFundsForOffer, model.useSavingsWallet, FeePolicy.getCreateOfferFee(), diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java index 50d637254a..34cbb32eab 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/ProcessModel.java @@ -159,7 +159,7 @@ public class ProcessModel implements Model, Serializable { return user; } - public NodeAddress getMyAddress() { + public NodeAddress getMyNodeAddress() { return p2PService.getAddress(); } diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/OffererCreatesAndSignsDepositTxAsBuyer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/OffererCreatesAndSignsDepositTxAsBuyer.java index 0caae04c9e..466c6346dd 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/OffererCreatesAndSignsDepositTxAsBuyer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/OffererCreatesAndSignsDepositTxAsBuyer.java @@ -26,6 +26,7 @@ import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,9 +59,10 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask { trade.setContractHash(contractHash); WalletService walletService = processModel.getWalletService(); String id = processModel.getOffer().getId(); + AddressEntry offererAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); AddressEntry buyerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG); - buyerMultiSigAddressEntry.setLockedTradeAmount(buyerInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades(offer))); - walletService.saveAddressEntryList(); + buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades(offer))); + Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); PreparedDepositTxAndOffererInputs result = processModel.getTradeWalletService().offererCreatesAndSignsDepositTx( true, contractHash, @@ -69,8 +71,8 @@ public class OffererCreatesAndSignsDepositTxAsBuyer extends TradeTask { processModel.tradingPeer.getRawTransactionInputs(), processModel.tradingPeer.getChangeOutputValue(), processModel.tradingPeer.getChangeOutputAddress(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE), - walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(), + offererAddressEntry.getAddress(), + changeAddress, buyerMultiSigAddressEntry.getPubKey(), processModel.tradingPeer.getMultiSigPubKey(), trade.getArbitratorPubKey()); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java index c91a832f79..27adb9f400 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendFiatTransferStartedMessage.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.messaging.SendMailboxMessageListener; import io.bitsquare.trade.Trade; @@ -37,13 +38,15 @@ public class SendFiatTransferStartedMessage extends TradeTask { protected void run() { try { runInterceptHook(); + WalletService walletService = processModel.getWalletService(); + AddressEntry payoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); processModel.getP2PService().sendEncryptedMailboxMessage( trade.getTradingPeerNodeAddress(), processModel.tradingPeer.getPubKeyRing(), new FiatTransferStartedMessage( processModel.getId(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), - processModel.getMyAddress() + payoutAddressEntry.getAddressString(), + processModel.getMyNodeAddress() ), new SendMailboxMessageListener() { @Override diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java index 185e42c11d..4fec1ed03f 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SendPayoutTxFinalizedMessage.java @@ -43,7 +43,7 @@ public class SendPayoutTxFinalizedMessage extends TradeTask { new PayoutTxFinalizedMessage( processModel.getId(), trade.getPayoutTx().bitcoinSerialize(), - processModel.getMyAddress() + processModel.getMyNodeAddress() ), new SendMailboxMessageListener() { @Override diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java index 6a5821e2e9..b1899e57d9 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndFinalizePayoutTx.java @@ -19,6 +19,7 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer; import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.FeePolicy; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; @@ -45,16 +46,19 @@ public class SignAndFinalizePayoutTx extends TradeTask { Coin sellerPayoutAmount = FeePolicy.getSecurityDeposit(trade.getOffer()); Coin buyerPayoutAmount = sellerPayoutAmount.add(trade.getTradeAmount()); + WalletService walletService = processModel.getWalletService(); + AddressEntry buyerAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); + AddressEntry multiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); Transaction transaction = processModel.getTradeWalletService().buyerSignsAndFinalizesPayoutTx( trade.getDepositTx(), processModel.tradingPeer.getSignature(), buyerPayoutAmount, sellerPayoutAmount, - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG), + buyerAddressEntry.getAddressString(), processModel.tradingPeer.getPayoutAddressString(), + multiSigAddressEntry.getKeyPair(), trade.getLockTimeAsBlockHeight(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey(), + multiSigAddressEntry.getPubKey(), processModel.tradingPeer.getMultiSigPubKey(), trade.getArbitratorPubKey() ); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java index 045fcbb45d..8f00c9835e 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/SignAndPublishDepositTxAsBuyer.java @@ -58,8 +58,8 @@ public class SignAndPublishDepositTxAsBuyer extends TradeTask { ArrayList buyerInputs = processModel.getRawTransactionInputs(); WalletService walletService = processModel.getWalletService(); AddressEntry buyerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); - buyerMultiSigAddressEntry.setLockedTradeAmount(Coin.valueOf(buyerInputs.stream().mapToLong(input -> input.value).sum()).subtract(FeePolicy.getFixedTxFeeForTrades(trade.getOffer()))); - walletService.saveAddressEntryList(); + Coin buyerInput = Coin.valueOf(buyerInputs.stream().mapToLong(input -> input.value).sum()); + buyerMultiSigAddressEntry.setCoinLockedInMultiSig(buyerInput.subtract(FeePolicy.getFixedTxFeeForTrades(trade.getOffer()))); TradingPeer tradingPeer = processModel.tradingPeer; Transaction depositTx = processModel.getTradeWalletService().takerSignsAndPublishesDepositTx( false, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/TakerCreatesDepositTxInputsAsBuyer.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/TakerCreatesDepositTxInputsAsBuyer.java index 2a0c1626f1..956f1a08b3 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/TakerCreatesDepositTxInputsAsBuyer.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/buyer/TakerCreatesDepositTxInputsAsBuyer.java @@ -19,11 +19,13 @@ package io.bitsquare.trade.protocol.trade.tasks.buyer; import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.FeePolicy; +import io.bitsquare.btc.WalletService; import io.bitsquare.btc.data.InputsAndChangeOutput; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,10 +43,13 @@ public class TakerCreatesDepositTxInputsAsBuyer extends TradeTask { runInterceptHook(); Offer offer = trade.getOffer(); Coin takerInputAmount = FeePolicy.getSecurityDeposit(offer).add(FeePolicy.getFixedTxFeeForTrades(offer)); + WalletService walletService = processModel.getWalletService(); + AddressEntry takersAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); InputsAndChangeOutput result = processModel.getTradeWalletService().takerCreatesDepositsTxInputs( takerInputAmount, - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.RESERVED_FOR_TRADE), - processModel.getWalletService().getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress()); + takersAddressEntry.getAddress(), + changeAddress); processModel.setRawTransactionInputs(result.rawTransactionInputs); processModel.setChangeOutputValue(result.changeOutputValue); processModel.setChangeOutputAddress(result.changeOutputAddress); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java index ecfa140814..438616dc54 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/CreateAndSignContract.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.offerer; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.crypto.Sig; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.util.Utilities; @@ -52,11 +53,14 @@ public class CreateAndSignContract extends TradeTask { PaymentAccountContractData takerPaymentAccountContractData = taker.getPaymentAccountContractData(); boolean isBuyerOffererAndSellerTaker = trade instanceof BuyerAsOffererTrade; - NodeAddress buyerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerNodeAddress(); - NodeAddress sellerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerNodeAddress() : processModel.getMyAddress(); + NodeAddress buyerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getMyNodeAddress() : processModel.getTempTradingPeerNodeAddress(); + NodeAddress sellerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerNodeAddress() : processModel.getMyNodeAddress(); log.debug("isBuyerOffererAndSellerTaker " + isBuyerOffererAndSellerTaker); log.debug("buyerAddress " + buyerNodeAddress); log.debug("sellerAddress " + sellerNodeAddress); + WalletService walletService = processModel.getWalletService(); + AddressEntry takerAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); + AddressEntry offererAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); Contract contract = new Contract( processModel.getOffer(), trade.getTradeAmount(), @@ -72,9 +76,9 @@ public class CreateAndSignContract extends TradeTask { takerPaymentAccountContractData, processModel.getPubKeyRing(), taker.getPubKeyRing(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), + takerAddressEntry.getAddressString(), taker.getPayoutAddressString(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey(), + offererAddressEntry.getPubKey(), taker.getMultiSigPubKey() ); String contractAsJson = Utilities.objectToJson(contract); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/SendPublishDepositTxRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/SendPublishDepositTxRequest.java index cd0a19ee5c..60a0fd55d9 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/SendPublishDepositTxRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/offerer/SendPublishDepositTxRequest.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.offerer; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.messaging.SendDirectMessageListener; import io.bitsquare.trade.Trade; @@ -37,14 +38,17 @@ public class SendPublishDepositTxRequest extends TradeTask { protected void run() { try { runInterceptHook(); + WalletService walletService = processModel.getWalletService(); + AddressEntry offererMultiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); + AddressEntry offererPayoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); PublishDepositTxRequest tradeMessage = new PublishDepositTxRequest( processModel.getId(), processModel.getPaymentAccountContractData(trade), processModel.getAccountId(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey(), + offererMultiSigAddressEntry.getPubKey(), trade.getContractAsJson(), trade.getOffererContractSignature(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), + offererPayoutAddressEntry.getAddressString(), processModel.getPreparedDepositTx(), processModel.getRawTransactionInputs() ); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/OffererCreatesAndSignsDepositTxAsSeller.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/OffererCreatesAndSignsDepositTxAsSeller.java index d1b9c564c2..c7927909d0 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/OffererCreatesAndSignsDepositTxAsSeller.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/OffererCreatesAndSignsDepositTxAsSeller.java @@ -26,6 +26,7 @@ import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,9 +58,10 @@ public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask { trade.setContractHash(contractHash); WalletService walletService = processModel.getWalletService(); String id = processModel.getOffer().getId(); + AddressEntry offererAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); AddressEntry sellerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG); - sellerMultiSigAddressEntry.setLockedTradeAmount(sellerInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades(offer))); - walletService.saveAddressEntryList(); + sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInputAmount.subtract(FeePolicy.getFixedTxFeeForTrades(offer))); + Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); PreparedDepositTxAndOffererInputs result = processModel.getTradeWalletService().offererCreatesAndSignsDepositTx( false, contractHash, @@ -68,8 +70,8 @@ public class OffererCreatesAndSignsDepositTxAsSeller extends TradeTask { processModel.tradingPeer.getRawTransactionInputs(), processModel.tradingPeer.getChangeOutputValue(), processModel.tradingPeer.getChangeOutputAddress(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE), - walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(), + offererAddressEntry.getAddress(), + changeAddress, processModel.tradingPeer.getMultiSigPubKey(), sellerMultiSigAddressEntry.getPubKey(), trade.getArbitratorPubKey()); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendFinalizePayoutTxRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendFinalizePayoutTxRequest.java index a341d3fe23..45d04dac51 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendFinalizePayoutTxRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SendFinalizePayoutTxRequest.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.seller; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.messaging.SendMailboxMessageListener; import io.bitsquare.trade.Trade; @@ -38,12 +39,14 @@ public class SendFinalizePayoutTxRequest extends TradeTask { try { runInterceptHook(); if (trade.getTradingPeerNodeAddress() != null) { + WalletService walletService = processModel.getWalletService(); + AddressEntry sellerPayoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); FinalizePayoutTxRequest message = new FinalizePayoutTxRequest( processModel.getId(), processModel.getPayoutTxSignature(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), + sellerPayoutAddressEntry.getAddressString(), trade.getLockTimeAsBlockHeight(), - processModel.getMyAddress() + processModel.getMyNodeAddress() ); processModel.getP2PService().sendEncryptedMailboxMessage( diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java index f31cba0e4a..16674de8ac 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignAndPublishDepositTxAsSeller.java @@ -57,8 +57,7 @@ public class SignAndPublishDepositTxAsSeller extends TradeTask { ArrayList sellerInputs = processModel.getRawTransactionInputs(); WalletService walletService = processModel.getWalletService(); AddressEntry sellerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); - sellerMultiSigAddressEntry.setLockedTradeAmount(Coin.valueOf(sellerInputs.stream().mapToLong(input -> input.value).sum()).subtract(FeePolicy.getFixedTxFeeForTrades(trade.getOffer()))); - walletService.saveAddressEntryList(); + sellerMultiSigAddressEntry.setCoinLockedInMultiSig(Coin.valueOf(sellerInputs.stream().mapToLong(input -> input.value).sum()).subtract(FeePolicy.getFixedTxFeeForTrades(trade.getOffer()))); TradingPeer tradingPeer = processModel.tradingPeer; Transaction depositTx = processModel.getTradeWalletService().takerSignsAndPublishesDepositTx( true, diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java index 8cfe1184d2..7d492b98ad 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/SignPayoutTx.java @@ -55,18 +55,20 @@ public class SignPayoutTx extends TradeTask { lockTimeAsBlockHeight = processModel.getTradeWalletService().getLastBlockSeenHeight() + lockTime; trade.setLockTimeAsBlockHeight(lockTimeAsBlockHeight); - WalletService walletService = processModel.getWalletService(); String id = processModel.getOffer().getId(); + WalletService walletService = processModel.getWalletService(); + AddressEntry sellerPayoutAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT); + AddressEntry multiSigAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG); byte[] payoutTxSignature = processModel.getTradeWalletService().sellerSignsPayoutTx( trade.getDepositTx(), buyerPayoutAmount, sellerPayoutAmount, processModel.tradingPeer.getPayoutAddressString(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG), + sellerPayoutAddressEntry.getAddressString(), + multiSigAddressEntry.getKeyPair(), lockTimeAsBlockHeight, processModel.tradingPeer.getMultiSigPubKey(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG).getPubKey(), + multiSigAddressEntry.getPubKey(), trade.getArbitratorPubKey()); processModel.setPayoutTxSignature(payoutTxSignature); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/TakerCreatesDepositTxInputsAsSeller.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/TakerCreatesDepositTxInputsAsSeller.java index 81dff5f243..065b7ad2a5 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/TakerCreatesDepositTxInputsAsSeller.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/seller/TakerCreatesDepositTxInputsAsSeller.java @@ -19,11 +19,13 @@ package io.bitsquare.trade.protocol.trade.tasks.seller; import io.bitsquare.btc.AddressEntry; import io.bitsquare.btc.FeePolicy; +import io.bitsquare.btc.WalletService; import io.bitsquare.btc.data.InputsAndChangeOutput; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.trade.Trade; import io.bitsquare.trade.offer.Offer; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Coin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,9 +45,13 @@ public class TakerCreatesDepositTxInputsAsSeller extends TradeTask { Offer offer = trade.getOffer(); Coin takerInputAmount = FeePolicy.getSecurityDeposit(offer).add(FeePolicy.getFixedTxFeeForTrades(offer)).add(trade.getTradeAmount()); - InputsAndChangeOutput result = processModel.getTradeWalletService().takerCreatesDepositsTxInputs(takerInputAmount, - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.RESERVED_FOR_TRADE), - processModel.getWalletService().getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress()); + WalletService walletService = processModel.getWalletService(); + AddressEntry takersAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.RESERVED_FOR_TRADE); + Address changeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(); + InputsAndChangeOutput result = processModel.getTradeWalletService().takerCreatesDepositsTxInputs( + takerInputAmount, + takersAddressEntry.getAddress(), + changeAddress); processModel.setRawTransactionInputs(result.rawTransactionInputs); processModel.setChangeOutputValue(result.changeOutputValue); processModel.setChangeOutputAddress(result.changeOutputAddress); diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/CreateTakeOfferFeeTx.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/CreateTakeOfferFeeTx.java index c692d45bca..603317f230 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/CreateTakeOfferFeeTx.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/CreateTakeOfferFeeTx.java @@ -27,6 +27,7 @@ import io.bitsquare.trade.Trade; import io.bitsquare.trade.protocol.trade.ArbitrationSelectionRule; import io.bitsquare.trade.protocol.trade.tasks.TradeTask; import io.bitsquare.user.User; +import org.bitcoinj.core.Address; import org.bitcoinj.core.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,10 +53,16 @@ public class CreateTakeOfferFeeTx extends TradeTask { checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateTakeOfferFeeTx"); WalletService walletService = processModel.getWalletService(); String id = model.getOffer().getId(); + AddressEntry addressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING); + AddressEntry reservedForTradeAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE); + AddressEntry changeAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE); + Address fundingAddress = addressEntry.getAddress(); + Address reservedForTradeAddress = reservedForTradeAddressEntry.getAddress(); + Address changeAddress = changeAddressEntry.getAddress(); Transaction createTakeOfferFeeTx = processModel.getTradeWalletService().createTradingFeeTx( - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING).getAddress(), - walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress(), - walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress(), + fundingAddress, + reservedForTradeAddress, + changeAddress, processModel.getFundsNeededForTrade(), processModel.getUseSavingsWallet(), FeePolicy.getTakeOfferFee(), diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendDepositTxPublishedMessage.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendDepositTxPublishedMessage.java index bd28a8ffad..186c7131ca 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendDepositTxPublishedMessage.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendDepositTxPublishedMessage.java @@ -39,7 +39,7 @@ public class SendDepositTxPublishedMessage extends TradeTask { if (trade.getDepositTx() != null) { DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(processModel.getId(), trade.getDepositTx().bitcoinSerialize(), - processModel.getMyAddress()); + processModel.getMyNodeAddress()); processModel.getP2PService().sendEncryptedMailboxMessage( trade.getTradingPeerNodeAddress(), diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendPayDepositRequest.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendPayDepositRequest.java index c669c1c118..182b3f28ca 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendPayDepositRequest.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/SendPayDepositRequest.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.p2p.messaging.SendMailboxMessageListener; import io.bitsquare.trade.Trade; @@ -45,16 +46,21 @@ public class SendPayDepositRequest extends TradeTask { checkNotNull(trade.getTradeAmount(), "TradeAmount must not be null"); checkNotNull(trade.getTakeOfferFeeTxId(), "TakeOfferFeeTxId must not be null"); + WalletService walletService = processModel.getWalletService(); + AddressEntry takerMultiSigPubKeyAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); + AddressEntry takerPayoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); + byte[] takerMultiSigPubKey = takerMultiSigPubKeyAddressEntry.getPubKey(); + String takerPayoutAddressString = takerPayoutAddressEntry.getAddressString(); PayDepositRequest payDepositRequest = new PayDepositRequest( - processModel.getMyAddress(), + processModel.getMyNodeAddress(), processModel.getId(), trade.getTradeAmount().value, trade.getTradePrice().value, processModel.getRawTransactionInputs(), processModel.getChangeOutputValue(), processModel.getChangeOutputAddress(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), + takerMultiSigPubKey, + takerPayoutAddressString, processModel.getPubKeyRing(), processModel.getPaymentAccountContractData(trade), processModel.getAccountId(), diff --git a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java index 1f21cac3e3..0b25141bbf 100644 --- a/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java +++ b/core/src/main/java/io/bitsquare/trade/protocol/trade/tasks/taker/VerifyAndSignContract.java @@ -18,6 +18,7 @@ package io.bitsquare.trade.protocol.trade.tasks.taker; import io.bitsquare.btc.AddressEntry; +import io.bitsquare.btc.WalletService; import io.bitsquare.common.crypto.Sig; import io.bitsquare.common.taskrunner.TaskRunner; import io.bitsquare.common.util.Utilities; @@ -52,12 +53,17 @@ public class VerifyAndSignContract extends TradeTask { PaymentAccountContractData takerPaymentAccountContractData = processModel.getPaymentAccountContractData(trade); boolean isBuyerOffererAndSellerTaker = trade instanceof SellerAsTakerTrade; - NodeAddress buyerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerNodeAddress() : processModel.getMyAddress(); - NodeAddress sellerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getMyAddress() : processModel.getTempTradingPeerNodeAddress(); + NodeAddress buyerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getTempTradingPeerNodeAddress() : processModel.getMyNodeAddress(); + NodeAddress sellerNodeAddress = isBuyerOffererAndSellerTaker ? processModel.getMyNodeAddress() : processModel.getTempTradingPeerNodeAddress(); log.debug("isBuyerOffererAndSellerTaker " + isBuyerOffererAndSellerTaker); log.debug("buyerAddress " + buyerNodeAddress); log.debug("sellerAddress " + sellerNodeAddress); + WalletService walletService = processModel.getWalletService(); + AddressEntry takerPayoutAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT); + String takerPayoutAddressString = takerPayoutAddressEntry.getAddressString(); + AddressEntry takerMultiSigAddressEntry = walletService.getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG); + byte[] takerMultiSigPubKey = takerMultiSigAddressEntry.getPubKey(); Contract contract = new Contract( processModel.getOffer(), trade.getTradeAmount(), @@ -74,9 +80,9 @@ public class VerifyAndSignContract extends TradeTask { offerer.getPubKeyRing(), processModel.getPubKeyRing(), offerer.getPayoutAddressString(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.TRADE_PAYOUT).getAddressString(), + takerPayoutAddressString, offerer.getMultiSigPubKey(), - processModel.getWalletService().getOrCreateAddressEntry(processModel.getOffer().getId(), AddressEntry.Context.MULTI_SIG).getPubKey() + takerMultiSigPubKey ); String contractAsJson = Utilities.objectToJson(contract); String signature = Sig.sign(processModel.getKeyRing().getSignatureKeyPair().getPrivate(), contractAsJson); diff --git a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java index c1cccbe48d..8c32f5268c 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java +++ b/gui/src/main/java/io/bitsquare/gui/main/MainViewModel.java @@ -982,7 +982,7 @@ public class MainViewModel implements ViewModel { private void updateLockedBalance() { Coin sum = Coin.valueOf(tradeManager.getLockedTradeStream() .mapToLong(trade -> { - Coin lockedTradeAmount = walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG).getLockedTradeAmount(); + Coin lockedTradeAmount = walletService.getOrCreateAddressEntry(trade.getId(), AddressEntry.Context.MULTI_SIG).getCoinLockedInMultiSig(); return lockedTradeAmount != null ? lockedTradeAmount.getValue() : 0; }) .sum()); diff --git a/gui/src/main/java/io/bitsquare/gui/main/funds/locked/LockedListItem.java b/gui/src/main/java/io/bitsquare/gui/main/funds/locked/LockedListItem.java index 3c36761e18..3abe2d094f 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/funds/locked/LockedListItem.java +++ b/gui/src/main/java/io/bitsquare/gui/main/funds/locked/LockedListItem.java @@ -71,7 +71,7 @@ public class LockedListItem { } private void updateBalance() { - balance = addressEntry.getLockedTradeAmount(); + balance = addressEntry.getCoinLockedInMultiSig(); if (balance != null) balanceLabel.setText(formatter.formatCoin(this.balance)); } diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ContractWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ContractWindow.java index ae7fdf57df..667f9452db 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ContractWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ContractWindow.java @@ -178,8 +178,8 @@ public class ContractWindow extends Overlay { viewContractButton.setOnAction(e -> { TextArea textArea = new TextArea(); String contractAsJson = dispute.getContractAsJson(); - contractAsJson += "\n\nBuyerPubKeyHex: " + Utils.HEX.encode(dispute.getContract().getBuyerBtcPubKey()); - contractAsJson += "\nSellerPubKeyHex: " + Utils.HEX.encode(dispute.getContract().getSellerBtcPubKey()); + contractAsJson += "\n\nBuyerMultiSigPubKeyAsHex: " + Utils.HEX.encode(dispute.getContract().getBuyerMultiSigPubKey()); + contractAsJson += "\nSellerMultiSigPubKeyAsHex: " + Utils.HEX.encode(dispute.getContract().getSellerMultiSigPubKey()); textArea.setText(contractAsJson); textArea.setPrefHeight(50); textArea.setEditable(false); diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/DisputeSummaryWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/DisputeSummaryWindow.java index 5105f8796a..989374f184 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/DisputeSummaryWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/DisputeSummaryWindow.java @@ -605,9 +605,10 @@ public class DisputeSummaryWindow extends Overlay { disputeResult.getArbitratorPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), - arbitratorAddressEntry, - contract.getBuyerBtcPubKey(), - contract.getSellerBtcPubKey(), + arbitratorAddressEntry.getAddressString(), + arbitratorAddressEntry.getKeyPair(), + contract.getBuyerMultiSigPubKey(), + contract.getSellerMultiSigPubKey(), arbitratorAddressEntry.getPubKey() ); disputeResult.setArbitratorSignature(arbitratorSignature); diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ShowWalletDataWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ShowWalletDataWindow.java index ddace7f48a..ef192a85a5 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ShowWalletDataWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/ShowWalletDataWindow.java @@ -50,7 +50,7 @@ public class ShowWalletDataWindow extends Overlay { if (headLine == null) headLine = "Wallet data"; - width = 1000; + width = 1200; createGridPane(); addHeadLine(); addSeparator(); @@ -82,6 +82,7 @@ public class ShowWalletDataWindow extends Overlay { Label label = labelTextAreaTuple2.first; label.setMinWidth(150); textArea.setPrefHeight(500); + textArea.setStyle("-fx-font-size: 10;"); CheckBox isUpdateCheckBox = addLabelCheckBox(gridPane, ++rowIndex, "Include private keys:", "").second; isUpdateCheckBox.setSelected(false); diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/SpendFromDepositTxWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/SpendFromDepositTxWindow.java index 48030add57..af72913b29 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/SpendFromDepositTxWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/SpendFromDepositTxWindow.java @@ -34,9 +34,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; import static io.bitsquare.gui.util.FormBuilder.addLabelInputTextField; @@ -104,11 +101,6 @@ public class SpendFromDepositTxWindow extends Overlay InputTextField arbitratorPubKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "arbitratorPubKeyAsHex:").second; InputTextField P2SHMultiSigOutputScript = addLabelInputTextField(gridPane, ++rowIndex, "P2SHMultiSigOutputScript:").second; - InputTextField buyerPubKeysInputTextField = addLabelInputTextField(gridPane, ++rowIndex, "buyerPubKeys:").second; - InputTextField sellerPubKeysInputTextField = addLabelInputTextField(gridPane, ++rowIndex, "sellerPubKeys:").second; - - List buyerPubKeys = !buyerPubKeysInputTextField.getText().isEmpty() ? Arrays.asList(buyerPubKeysInputTextField.getText().split(",")) : new ArrayList<>(); - List sellerPubKeys = !sellerPubKeysInputTextField.getText().isEmpty() ? Arrays.asList(sellerPubKeysInputTextField.getText().split(",")) : new ArrayList<>(); // Notes: @@ -144,15 +136,8 @@ public class SpendFromDepositTxWindow extends Overlay P2SHMultiSigOutputScript.setText(""); - sellerPubKeys = Arrays.asList(); - - buyerPubKeys = Arrays.asList(); - - actionButtonText("Sign and publish transaction"); - final List finalSellerPubKeys = sellerPubKeys; - final List finalBuyerPubKeys = buyerPubKeys; FutureCallback callback = new FutureCallback() { @Override public void onSuccess(@Nullable Transaction result) { @@ -188,8 +173,6 @@ public class SpendFromDepositTxWindow extends Overlay sellerPubKeyAsHex.getText(), arbitratorPubKeyAsHex.getText(), P2SHMultiSigOutputScript.getText(), - finalBuyerPubKeys, - finalSellerPubKeys, callback); } catch (AddressFormatException | WalletException | TransactionVerificationException e) { log.error(e.toString()); diff --git a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java index 0dab9b5280..874ec70608 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java +++ b/gui/src/main/java/io/bitsquare/gui/main/overlays/windows/TradeDetailsWindow.java @@ -209,8 +209,8 @@ public class TradeDetailsWindow extends Overlay { viewContractButton.setOnAction(e -> { TextArea textArea = new TextArea(); String contractAsJson = trade.getContractAsJson(); - contractAsJson += "\n\nBuyerPubKeyHex: " + Utils.HEX.encode(trade.getContract().getBuyerBtcPubKey()); - contractAsJson += "\nSellerPubKeyHex: " + Utils.HEX.encode(trade.getContract().getSellerBtcPubKey()); + contractAsJson += "\n\nBuyerMultiSigPubKeyAsHex: " + Utils.HEX.encode(trade.getContract().getBuyerMultiSigPubKey()); + contractAsJson += "\nSellerMultiSigPubKeyAsHex: " + Utils.HEX.encode(trade.getContract().getSellerMultiSigPubKey()); textArea.setText(contractAsJson); textArea.setPrefHeight(50); textArea.setEditable(false); diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/failedtrades/FailedTradesView.fxml b/gui/src/main/java/io/bitsquare/gui/main/portfolio/failedtrades/FailedTradesView.fxml index cadaaf9c34..0ae22d2569 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/failedtrades/FailedTradesView.fxml +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/failedtrades/FailedTradesView.fxml @@ -29,7 +29,7 @@ - + diff --git a/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.fxml b/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.fxml index d0617140a5..6d81cfd48d 100644 --- a/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.fxml +++ b/gui/src/main/java/io/bitsquare/gui/main/portfolio/openoffer/OpenOffersView.fxml @@ -29,7 +29,7 @@ - +