mirror of
https://github.com/haveno-dex/haveno.git
synced 2025-07-26 08:25:23 -04:00
use toCanonical for signatures
This commit is contained in:
parent
cfee2f32ff
commit
ab8c7d47ce
4 changed files with 45 additions and 46 deletions
|
@ -222,48 +222,48 @@ public class TradeWalletService {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we construct real deposit tx
|
// Now we construct real deposit tx
|
||||||
Transaction depositTx = new Transaction(params);
|
Transaction preparedDepositTx = new Transaction(params);
|
||||||
|
|
||||||
// Add offerer inputs (normally its just 1 input)
|
// Add offerer inputs (normally its just 1 input)
|
||||||
for (TransactionOutput connectedOutputForInput : offererConnectedOutputsForAllInputs) {
|
for (TransactionOutput connectedOutputForInput : offererConnectedOutputsForAllInputs) {
|
||||||
TransactionOutPoint outPoint = new TransactionOutPoint(params, connectedOutputForInput.getIndex(), connectedOutputForInput.getParentTransaction());
|
TransactionOutPoint outPoint = new TransactionOutPoint(params, connectedOutputForInput.getIndex(), connectedOutputForInput.getParentTransaction());
|
||||||
TransactionInput transactionInput = new TransactionInput(params, depositTx, new byte[]{}, outPoint, connectedOutputForInput.getValue());
|
TransactionInput transactionInput = new TransactionInput(params, preparedDepositTx, new byte[]{}, outPoint, connectedOutputForInput.getValue());
|
||||||
depositTx.addInput(transactionInput);
|
preparedDepositTx.addInput(transactionInput);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add taker inputs
|
// Add taker inputs
|
||||||
List<TransactionOutput> connectedOutputsForAllTakerInputs = new ArrayList<>();
|
List<TransactionOutput> connectedOutputsForAllTakerInputs = new ArrayList<>();
|
||||||
for (TransactionInput input : takerInputs) {
|
for (TransactionInput input : takerInputs) {
|
||||||
depositTx.addInput(input);
|
preparedDepositTx.addInput(input);
|
||||||
connectedOutputsForAllTakerInputs.add(input.getConnectedOutput());
|
connectedOutputsForAllTakerInputs.add(input.getConnectedOutput());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add MultiSig output
|
// Add MultiSig output
|
||||||
Script multiSigOutputScript = getP2SHMultiSigOutputScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script multiSigOutputScript = getP2SHMultiSigOutputScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
// Tx fee for deposit tx will be paid by offerer.
|
// Tx fee for deposit tx will be paid by offerer.
|
||||||
TransactionOutput msOutput = new TransactionOutput(params, depositTx, msOutputAmount, multiSigOutputScript.getProgram());
|
TransactionOutput msOutput = new TransactionOutput(params, preparedDepositTx, msOutputAmount, multiSigOutputScript.getProgram());
|
||||||
depositTx.addOutput(msOutput);
|
preparedDepositTx.addOutput(msOutput);
|
||||||
|
|
||||||
// Add optional offerer outputs
|
// Add optional offerer outputs
|
||||||
for (TransactionOutput output : offererOutputs) {
|
for (TransactionOutput output : offererOutputs) {
|
||||||
depositTx.addOutput(output);
|
preparedDepositTx.addOutput(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
Coin takersSpendingAmount = Coin.ZERO;
|
Coin takersSpendingAmount = Coin.ZERO;
|
||||||
|
|
||||||
// Add optional taker outputs
|
// Add optional taker outputs
|
||||||
for (TransactionOutput output : takerOutputs) {
|
for (TransactionOutput output : takerOutputs) {
|
||||||
depositTx.addOutput(output);
|
preparedDepositTx.addOutput(output);
|
||||||
|
|
||||||
// subtract change amount
|
// subtract change amount
|
||||||
takersSpendingAmount = takersSpendingAmount.subtract(output.getValue());
|
takersSpendingAmount = takersSpendingAmount.subtract(output.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign inputs
|
// Sign inputs
|
||||||
for (int i = offererConnectedOutputsForAllInputs.size(); i < depositTx.getInputs().size(); i++) {
|
for (int i = offererConnectedOutputsForAllInputs.size(); i < preparedDepositTx.getInputs().size(); i++) {
|
||||||
TransactionInput input = depositTx.getInput(i);
|
TransactionInput input = preparedDepositTx.getInput(i);
|
||||||
signInput(depositTx, input, i);
|
signInput(preparedDepositTx, input, i);
|
||||||
checkScriptSig(depositTx, input, i);
|
checkScriptSig(preparedDepositTx, input, i);
|
||||||
|
|
||||||
// add up spending amount
|
// add up spending amount
|
||||||
takersSpendingAmount = takersSpendingAmount.add(input.getConnectedOutput().getValue());
|
takersSpendingAmount = takersSpendingAmount.add(input.getConnectedOutput().getValue());
|
||||||
|
@ -272,11 +272,11 @@ public class TradeWalletService {
|
||||||
if (takerInputAmount.compareTo(takersSpendingAmount) != 0)
|
if (takerInputAmount.compareTo(takersSpendingAmount) != 0)
|
||||||
throw new TransactionVerificationException("Takers input amount does not match required value.");
|
throw new TransactionVerificationException("Takers input amount does not match required value.");
|
||||||
|
|
||||||
verifyTransaction(depositTx);
|
verifyTransaction(preparedDepositTx);
|
||||||
checkWalletConsistency();
|
checkWalletConsistency();
|
||||||
|
|
||||||
printTxWithInputs("depositTx", depositTx);
|
printTxWithInputs("preparedDepositTx", preparedDepositTx);
|
||||||
return new TransactionDataResult(depositTx, connectedOutputsForAllTakerInputs, takerOutputs);
|
return new TransactionDataResult(preparedDepositTx, connectedOutputsForAllTakerInputs, takerOutputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void offererSignsAndPublishTx(Transaction takersDepositTx,
|
public void offererSignsAndPublishTx(Transaction takersDepositTx,
|
||||||
|
@ -354,7 +354,7 @@ public class TradeWalletService {
|
||||||
Futures.addCallback(broadcastComplete, callback);
|
Futures.addCallback(broadcastComplete, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transaction takerCommitsDepositTx(Transaction depositTx) throws WalletException {
|
public void takerCommitsDepositTx(Transaction depositTx) throws WalletException {
|
||||||
// We need to recreate the tx we get a null pointer otherwise
|
// We need to recreate the tx we get a null pointer otherwise
|
||||||
depositTx = new Transaction(params, depositTx.bitcoinSerialize());
|
depositTx = new Transaction(params, depositTx.bitcoinSerialize());
|
||||||
|
|
||||||
|
@ -365,8 +365,6 @@ public class TradeWalletService {
|
||||||
t.printStackTrace();
|
t.printStackTrace();
|
||||||
throw new WalletException(t);
|
throw new WalletException(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
return depositTx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx,
|
public byte[] offererCreatesAndSignsPayoutTx(Transaction depositTx,
|
||||||
|
@ -379,14 +377,15 @@ public class TradeWalletService {
|
||||||
byte[] arbitratorPubKey)
|
byte[] arbitratorPubKey)
|
||||||
throws AddressFormatException, TransactionVerificationException {
|
throws AddressFormatException, TransactionVerificationException {
|
||||||
|
|
||||||
Transaction payoutTx = createPayoutTx(depositTx, offererPayoutAmount, takerPayoutAmount, addressEntry.getAddressString(), takerAddressString);
|
Transaction preparedPayoutTx = createPayoutTx(depositTx, offererPayoutAmount, takerPayoutAmount, addressEntry.getAddressString(), takerAddressString);
|
||||||
// We need MS script not the P2SH
|
// We need MS script not the P2SH
|
||||||
Script multiSigScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script multiSigScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
Sha256Hash sigHash = payoutTx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
Sha256Hash sigHash = preparedPayoutTx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
||||||
ECKey.ECDSASignature offererSignature = addressEntry.getKeyPair().sign(sigHash);
|
ECKey.ECDSASignature offererSignature = addressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
||||||
|
|
||||||
verifyTransaction(payoutTx);
|
verifyTransaction(preparedPayoutTx);
|
||||||
|
|
||||||
|
printTxWithInputs("preparedPayoutTx", depositTx);
|
||||||
return offererSignature.encodeToDER();
|
return offererSignature.encodeToDER();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,17 +405,16 @@ public class TradeWalletService {
|
||||||
// We need MS script not the P2SH
|
// We need MS script not the P2SH
|
||||||
Script multiSigScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
Script multiSigScript = getMultiSigRedeemScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||||
Sha256Hash sigHash = payoutTx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
Sha256Hash sigHash = payoutTx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
||||||
ECKey.ECDSASignature takerSignature = takerAddressEntry.getKeyPair().sign(sigHash);
|
ECKey.ECDSASignature takerSignature = takerAddressEntry.getKeyPair().sign(sigHash).toCanonicalised();
|
||||||
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
||||||
TransactionSignature offererTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(offererSignature), Transaction.SigHash.ALL, false);
|
TransactionSignature offererTxSig = new TransactionSignature(ECKey.ECDSASignature.decodeFromDER(offererSignature).toCanonicalised(),
|
||||||
|
Transaction.SigHash.ALL, false);
|
||||||
Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig), multiSigScript);
|
Script inputScript = ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig), multiSigScript);
|
||||||
TransactionInput input = payoutTx.getInput(0);
|
TransactionInput input = payoutTx.getInput(0);
|
||||||
input.setScriptSig(inputScript);
|
input.setScriptSig(inputScript);
|
||||||
|
|
||||||
verifyTransaction(payoutTx);
|
verifyTransaction(payoutTx);
|
||||||
checkWalletConsistency();
|
checkWalletConsistency();
|
||||||
// checkScriptSig(payoutTx, input, 0);
|
|
||||||
// input.verify(input.getConnectedOutput());
|
|
||||||
|
|
||||||
printTxWithInputs("payoutTx", payoutTx);
|
printTxWithInputs("payoutTx", payoutTx);
|
||||||
|
|
||||||
|
@ -515,14 +513,6 @@ public class TradeWalletService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private void checkScriptSigForAllInputs(Transaction transaction) throws TransactionVerificationException {
|
|
||||||
int inputIndex = 0;
|
|
||||||
for (TransactionInput input : transaction.getInputs()) {
|
|
||||||
checkScriptSig(transaction, input, inputIndex);
|
|
||||||
inputIndex++;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
private void removeSignatures(Transaction transaction) {
|
private void removeSignatures(Transaction transaction) {
|
||||||
for (TransactionInput input : transaction.getInputs()) {
|
for (TransactionInput input : transaction.getInputs()) {
|
||||||
input.setScriptSig(new Script(new byte[]{}));
|
input.setScriptSig(new Script(new byte[]{}));
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
package io.bitsquare.gui.main.trade.createoffer;
|
package io.bitsquare.gui.main.trade.createoffer;
|
||||||
|
|
||||||
|
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
||||||
|
import io.bitsquare.common.viewfx.view.FxmlView;
|
||||||
import io.bitsquare.gui.Navigation;
|
import io.bitsquare.gui.Navigation;
|
||||||
import io.bitsquare.gui.OverlayManager;
|
import io.bitsquare.gui.OverlayManager;
|
||||||
import io.bitsquare.gui.components.AddressTextField;
|
import io.bitsquare.gui.components.AddressTextField;
|
||||||
|
@ -31,12 +33,12 @@ import io.bitsquare.gui.main.account.content.restrictions.RestrictionsView;
|
||||||
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
|
import io.bitsquare.gui.main.account.settings.AccountSettingsView;
|
||||||
import io.bitsquare.gui.main.help.Help;
|
import io.bitsquare.gui.main.help.Help;
|
||||||
import io.bitsquare.gui.main.help.HelpId;
|
import io.bitsquare.gui.main.help.HelpId;
|
||||||
|
import io.bitsquare.gui.main.portfolio.PortfolioView;
|
||||||
|
import io.bitsquare.gui.main.portfolio.pending.PendingTradesView;
|
||||||
import io.bitsquare.gui.main.trade.TradeView;
|
import io.bitsquare.gui.main.trade.TradeView;
|
||||||
import io.bitsquare.gui.util.ImageUtil;
|
import io.bitsquare.gui.util.ImageUtil;
|
||||||
import io.bitsquare.locale.BSResources;
|
import io.bitsquare.locale.BSResources;
|
||||||
import io.bitsquare.offer.Direction;
|
import io.bitsquare.offer.Direction;
|
||||||
import io.bitsquare.common.viewfx.view.ActivatableViewAndModel;
|
|
||||||
import io.bitsquare.common.viewfx.view.FxmlView;
|
|
||||||
|
|
||||||
import org.bitcoinj.core.Coin;
|
import org.bitcoinj.core.Coin;
|
||||||
import org.bitcoinj.utils.Fiat;
|
import org.bitcoinj.utils.Fiat;
|
||||||
|
@ -289,6 +291,11 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
});
|
});
|
||||||
|
|
||||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||||
|
// TODO temp just for testing
|
||||||
|
newValue = false;
|
||||||
|
close();
|
||||||
|
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
overlayManager.blurContent();
|
overlayManager.blurContent();
|
||||||
|
|
||||||
|
@ -314,10 +321,9 @@ public class CreateOfferView extends ActivatableViewAndModel<AnchorPane, CreateO
|
||||||
Dialog.Actions.CLOSE.handle(actionEvent);
|
Dialog.Actions.CLOSE.handle(actionEvent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// TODO temp just for testing
|
Popups.openInfoPopup(BSResources.get("createOffer.success.headline"),
|
||||||
/* Popups.openInfoPopup(BSResources.get("createOffer.success.headline"),
|
|
||||||
BSResources.get("createOffer.success.info"),
|
BSResources.get("createOffer.success.info"),
|
||||||
actions);*/
|
actions);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -243,6 +243,11 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
model.errorMessage.addListener(errorMessageChangeListener);
|
model.errorMessage.addListener(errorMessageChangeListener);
|
||||||
|
|
||||||
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
model.showTransactionPublishedScreen.addListener((o, oldValue, newValue) -> {
|
||||||
|
// TODO temp just for testing
|
||||||
|
newValue = false;
|
||||||
|
close();
|
||||||
|
navigation.navigateTo(MainView.class, PortfolioView.class, PendingTradesView.class);
|
||||||
|
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
overlayManager.blurContent();
|
overlayManager.blurContent();
|
||||||
|
|
||||||
|
@ -269,10 +274,10 @@ public class TakeOfferView extends ActivatableViewAndModel<AnchorPane, TakeOffer
|
||||||
Dialog.Actions.CLOSE.handle(actionEvent);
|
Dialog.Actions.CLOSE.handle(actionEvent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// TODO temp just for testing
|
|
||||||
/* Popups.openInfoPopup(BSResources.get("takeOffer.success.headline"),
|
Popups.openInfoPopup(BSResources.get("takeOffer.success.headline"),
|
||||||
BSResources.get("takeOffer.success.info"),
|
BSResources.get("takeOffer.success.info"),
|
||||||
actions);*/
|
actions);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ import io.bitsquare.common.taskrunner.TaskRunner;
|
||||||
import io.bitsquare.trade.Trade;
|
import io.bitsquare.trade.Trade;
|
||||||
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
|
import io.bitsquare.trade.protocol.trade.taker.models.SellerAsTakerModel;
|
||||||
|
|
||||||
import org.bitcoinj.core.Transaction;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -37,8 +35,8 @@ public class TakerCommitDepositTx extends Task<SellerAsTakerModel> {
|
||||||
@Override
|
@Override
|
||||||
protected void doRun() {
|
protected void doRun() {
|
||||||
try {
|
try {
|
||||||
Transaction transaction = model.tradeWalletService.takerCommitsDepositTx(model.getPublishedDepositTx());
|
model.tradeWalletService.takerCommitsDepositTx(model.getPublishedDepositTx());
|
||||||
model.trade.setDepositTx(transaction);
|
model.trade.setDepositTx(model.getPublishedDepositTx());
|
||||||
model.trade.setState(Trade.State.DEPOSIT_PUBLISHED);
|
model.trade.setState(Trade.State.DEPOSIT_PUBLISHED);
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue