Use Transaction instead of hex

This commit is contained in:
Manfred Karrer 2015-03-14 22:07:31 +01:00
parent 6823b0cfe3
commit ae058f37c8
13 changed files with 79 additions and 75 deletions

View File

@ -38,7 +38,6 @@ import org.bitcoinj.core.TransactionConfidence;
import org.bitcoinj.core.TransactionInput;
import org.bitcoinj.core.TransactionOutPoint;
import org.bitcoinj.core.TransactionOutput;
import org.bitcoinj.core.Utils;
import org.bitcoinj.core.Wallet;
import org.bitcoinj.core.WalletEventListener;
import org.bitcoinj.crypto.DeterministicKey;
@ -712,7 +711,6 @@ public class WalletService {
*/
// Now we construct the real 2of3 multiSig tx from the serialized offerers tx
Transaction tx = new Transaction(params, preparedDepositTx.bitcoinSerialize());
// The serialized offerers tx looks like:
/*
@ -724,23 +722,23 @@ public class WalletService {
// Now we add the inputs and outputs from our temp tx and change the multiSig amount to the correct value
for (TransactionInput input : tempTx.getInputs()) {
tx.addInput(input);
preparedDepositTx.addInput(input);
}
// handle optional change output
if (tempTx.getOutputs().size() == 2) {
tx.addOutput(tempTx.getOutput(1));
preparedDepositTx.addOutput(tempTx.getOutput(1));
}
tx.getOutput(0).setValue(msOutputAmount);
preparedDepositTx.getOutput(0).setValue(msOutputAmount);
// Now we sign our input (index 1)
TransactionInput input = tx.getInput(1);
TransactionInput input = preparedDepositTx.getInput(1);
if (input == null || input.getConnectedOutput() == null)
log.error("Must not happen - input or input.getConnectedOutput() is null: " + input);
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
Sha256Hash hash = tx.hashForSignature(1, scriptPubKey, Transaction.SigHash.ALL, false);
Sha256Hash hash = preparedDepositTx.hashForSignature(1, scriptPubKey, Transaction.SigHash.ALL, false);
ECKey.ECDSASignature ecSig = sigKey.sign(hash);
TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false);
if (scriptPubKey.isSentToRawPubKey()) {
@ -754,10 +752,10 @@ public class WalletService {
}
log.trace("check if it can be correctly spent for input 1");
input.getScriptSig().correctlySpends(tx, 1, scriptPubKey);
input.getScriptSig().correctlySpends(preparedDepositTx, 1, scriptPubKey);
log.trace("verify tx");
tx.verify();
preparedDepositTx.verify();
// The resulting tx looks like:
/*
@ -772,9 +770,9 @@ public class WalletService {
// publishes it and it will have a different tx hash, so it would invalidate our wallet.
log.trace("Check if wallet is consistent before commit: result=" + wallet.isConsistent());
printInputs("takerAddPaymentAndSignTx", tx);
log.debug("tx = " + tx);
return tx;
printInputs("takerAddPaymentAndSignTx", preparedDepositTx);
log.debug("tx = " + preparedDepositTx);
return preparedDepositTx;
}
@ -799,28 +797,20 @@ public class WalletService {
// directly and add the offerers input and output)
Transaction tx = new Transaction(params);
// offerers first tx
Transaction offerersFirstTx = new Transaction(params, preparedDepositTx.bitcoinSerialize());
printInputs("offerersFirstTx", offerersFirstTx);
log.trace("offerersFirstTx = " + offerersFirstTx);
printInputs("preparedDepositTx", preparedDepositTx);
log.trace("preparedDepositTx = " + preparedDepositTx);
// add input
Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash());
Transaction offerersFirstTxConnOut = wallet.getTransaction(preparedDepositTx.getInput(0).getOutpoint().getHash());
TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, offererTxOutIndex, offerersFirstTxConnOut);
TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint);
offerersFirstTxInput.setParent(tx);
tx.addInput(offerersFirstTxInput);
// takers signed tx
takersSignedDepositTx = new Transaction(params, takersSignedDepositTx.bitcoinSerialize());
printInputs("takersSignedTxInput", takersSignedDepositTx);
log.trace("takersSignedTx = " + takersSignedDepositTx);
// add input
//todo not needed
takersFromTx = new Transaction(params, takersFromTx.bitcoinSerialize());
TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, takerTxOutIndex, takersFromTx);
TransactionInput takersSignedTxInput = new TransactionInput(
params, tx, takersSignedScriptSig, takersSignedTxOutPoint);
@ -896,18 +886,23 @@ public class WalletService {
}
// 4 step deposit tx: Offerer send deposit tx to taker
public Transaction takerCommitDepositTx(String depositTxAsHex) {
public Transaction takerCommitDepositTx(Transaction depositTx) {
log.trace("takerCommitDepositTx");
log.trace("inputs: ");
log.trace("depositTxID=" + depositTxAsHex);
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
log.trace("depositTx=" + depositTx);
// If not recreate the tx we get a null pointer at receivePending
depositTx = new Transaction(params, depositTx.bitcoinSerialize());
log.trace("depositTx=" + depositTx);
// boolean isAlreadyInWallet = wallet.maybeCommitTx(depositTx);
//log.trace("isAlreadyInWallet=" + isAlreadyInWallet);
// Manually add the multisigContract to the wallet, overriding the isRelevant checks so we can track
// it and check for double-spends later
wallet.receivePending(depositTx, null, true);
try {
wallet.receivePending(depositTx, null, true);
} catch (Throwable t) {
log.error(t.getMessage());
}
return depositTx;
@ -915,7 +910,7 @@ public class WalletService {
// 5. step payout tx: Offerer creates payout tx and signs it
public Pair<ECKey.ECDSASignature, String> offererCreatesAndSignsPayoutTx(String depositTxID,
public Pair<ECKey.ECDSASignature, Transaction> offererCreatesAndSignsPayoutTx(String depositTxID,
Coin offererPaybackAmount,
Coin takerPaybackAmount,
String takerAddress,
@ -930,10 +925,10 @@ public class WalletService {
// Offerer has published depositTx earlier, so he has it in his wallet
Transaction depositTx = wallet.getTransaction(new Sha256Hash(depositTxID));
String depositTxAsHex = Utils.HEX.encode(depositTx.bitcoinSerialize());
// String depositTxAsHex = Utils.HEX.encode(depositTx.bitcoinSerialize());
// We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount,
Transaction tx = createPayoutTx(depositTx, offererPaybackAmount, takerPaybackAmount,
getAddressInfo(tradeID).getAddressString(), takerAddress);
// We create the signature for that tx
@ -947,11 +942,11 @@ public class WalletService {
tx.getInput(0).setScriptSig(inputScript);
log.trace("sigHash=" + sigHash);
return new Pair<>(offererSignature, depositTxAsHex);
return new Pair<>(offererSignature, depositTx);
}
// 6. step payout tx: Taker signs and publish tx
public void takerSignsAndSendsTx(String depositTxAsHex,
public void takerSignsAndSendsTx(Transaction depositTx,
String offererSignatureR,
String offererSignatureS,
Coin offererPaybackAmount,
@ -961,7 +956,7 @@ public class WalletService {
FutureCallback<Transaction> callback) throws AddressFormatException {
log.debug("takerSignsAndSendsTx");
log.trace("inputs: ");
log.trace("depositTxAsHex=" + depositTxAsHex);
log.trace("depositTx=" + depositTx);
log.trace("offererSignatureR=" + offererSignatureR);
log.trace("offererSignatureS=" + offererSignatureS);
log.trace("offererPaybackAmount=" + offererPaybackAmount.toFriendlyString());
@ -970,7 +965,7 @@ public class WalletService {
log.trace("callback=" + callback);
// We create the payout tx
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress,
Transaction tx = createPayoutTx(depositTx, offererPaybackAmount, takerPaybackAmount, offererAddress,
getAddressInfo(tradeID).getAddressString());
// We sign that tx with our key and apply the signature form the offerer
@ -1031,17 +1026,17 @@ public class WalletService {
return ScriptBuilder.createMultiSigOutputScript(2, keys);
}
private Transaction createPayoutTx(String depositTxAsHex, Coin offererPaybackAmount, Coin takerPaybackAmount,
private Transaction createPayoutTx(Transaction depositTx, Coin offererPaybackAmount, Coin takerPaybackAmount,
String offererAddress, String takerAddress) throws AddressFormatException {
log.trace("createPayoutTx");
log.trace("inputs: ");
log.trace("depositTxAsHex=" + depositTxAsHex);
log.trace("depositTx=" + depositTx);
log.trace("offererPaybackAmount=" + offererPaybackAmount.toFriendlyString());
log.trace("takerPaybackAmount=" + takerPaybackAmount.toFriendlyString());
log.trace("offererAddress=" + offererAddress);
log.trace("takerAddress=" + takerAddress);
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
// Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTx));
TransactionOutput multiSigOutput = depositTx.getOutput(0);
Transaction tx = new Transaction(params);
tx.addInput(multiSigOutput);

View File

@ -52,7 +52,7 @@ public class BuyerAsOffererModel extends OfferSharedModel {
private Peer taker;
private Transaction preparedDepositTx;
private String depositTxAsHex;
private Transaction depositTx;
private String takerAccountId;
private BankAccount takerBankAccount;
@ -218,12 +218,12 @@ public class BuyerAsOffererModel extends OfferSharedModel {
this.offererPubKey = offererPubKey;
}
public String getDepositTxAsHex() {
return depositTxAsHex;
public Transaction getDepositTx() {
return depositTx;
}
public void setDepositTxAsHex(String depositTxAsHex) {
this.depositTxAsHex = depositTxAsHex;
public void setDepositTx(Transaction depositTx) {
this.depositTx = depositTx;
}
public String getOffererSignatureR() {

View File

@ -20,6 +20,7 @@ package io.bitsquare.trade.protocol.trade.offerer.messages;
import io.bitsquare.trade.protocol.trade.TradeMessage;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.Transaction;
import java.io.Serializable;
@ -27,7 +28,7 @@ public class BankTransferStartedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = -3479634129543632523L;
private final String tradeId;
private final String depositTxAsHex;
private final Transaction depositTx;
private final String offererSignatureR;
private final String offererSignatureS;
private final Coin offererPaybackAmount;
@ -35,14 +36,14 @@ public class BankTransferStartedMessage implements Serializable, TradeMessage {
private final String offererPayoutAddress;
public BankTransferStartedMessage(String tradeId,
String depositTxAsHex,
Transaction depositTx,
String offererSignatureR,
String offererSignatureS,
Coin offererPaybackAmount,
Coin takerPaybackAmount,
String offererPayoutAddress) {
this.tradeId = tradeId;
this.depositTxAsHex = depositTxAsHex;
this.depositTx = depositTx;
this.offererSignatureR = offererSignatureR;
this.offererSignatureS = offererSignatureS;
this.offererPaybackAmount = offererPaybackAmount;
@ -55,8 +56,8 @@ public class BankTransferStartedMessage implements Serializable, TradeMessage {
return tradeId;
}
public String getDepositTxAsHex() {
return depositTxAsHex;
public Transaction getDepositTx() {
return depositTx;
}
public String getOffererPayoutAddress() {

View File

@ -19,6 +19,8 @@ package io.bitsquare.trade.protocol.trade.offerer.messages;
import io.bitsquare.trade.protocol.trade.TradeMessage;
import org.bitcoinj.core.Transaction;
import java.io.Serializable;
public class DepositTxPublishedMessage implements Serializable, TradeMessage {
@ -26,11 +28,11 @@ public class DepositTxPublishedMessage implements Serializable, TradeMessage {
private static final long serialVersionUID = -1532231540167406581L;
private final String tradeId;
private final String depositTxAsHex;
private final Transaction depositTx;
public DepositTxPublishedMessage(String tradeId, String depositTxAsHex) {
public DepositTxPublishedMessage(String tradeId, Transaction depositTx) {
this.tradeId = tradeId;
this.depositTxAsHex = depositTxAsHex;
this.depositTx = depositTx;
}
@Override
@ -38,7 +40,7 @@ public class DepositTxPublishedMessage implements Serializable, TradeMessage {
return tradeId;
}
public String getDepositTxAsHex() {
return depositTxAsHex;
public Transaction getDepositTx() {
return depositTx;
}
}

View File

@ -37,7 +37,7 @@ public class SendBankTransferInitedMessage extends Task<BuyerAsOffererModel> {
protected void doRun() {
BankTransferStartedMessage tradeMessage = new BankTransferStartedMessage(
model.getTrade().getId(),
model.getDepositTxAsHex(),
model.getDepositTx(),
model.getOffererSignatureR(),
model.getOffererSignatureS(),
model.getOffererPaybackAmount(),

View File

@ -23,8 +23,6 @@ import io.bitsquare.trade.protocol.trade.offerer.messages.DepositTxPublishedMess
import io.bitsquare.util.taskrunner.Task;
import io.bitsquare.util.taskrunner.TaskRunner;
import org.bitcoinj.core.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -38,7 +36,7 @@ public class SendDepositTxIdToTaker extends Task<BuyerAsOffererModel> {
@Override
protected void doRun() {
DepositTxPublishedMessage tradeMessage = new DepositTxPublishedMessage(model.getTrade().getId(),
Utils.HEX.encode(model.getTrade().getDepositTx().bitcoinSerialize()));
model.getTrade().getDepositTx());
model.getTradeMessageService().sendMessage(model.getTaker(), tradeMessage, new SendMessageListener() {
@Override

View File

@ -24,6 +24,7 @@ import io.bitsquare.util.taskrunner.TaskRunner;
import org.bitcoinj.core.Coin;
import org.bitcoinj.core.ECKey;
import org.bitcoinj.core.Transaction;
import javafx.util.Pair;
@ -45,13 +46,15 @@ public class SignPayoutTx extends Task<BuyerAsOffererModel> {
Coin offererPaybackAmount = trade.getTradeAmount().add(securityDeposit);
@SuppressWarnings("UnnecessaryLocalVariable") Coin takerPaybackAmount = securityDeposit;
Pair<ECKey.ECDSASignature, String> result = model.getWalletService().offererCreatesAndSignsPayoutTx(
trade.getDepositTx().getHashAsString(), offererPaybackAmount, takerPaybackAmount, model.getTakerPayoutAddress(), model.getTrade().getId());
Pair<ECKey.ECDSASignature, Transaction> result = model.getWalletService().offererCreatesAndSignsPayoutTx(
trade.getDepositTx().getHashAsString(),
offererPaybackAmount,
takerPaybackAmount,
model.getTakerPayoutAddress(),
model.getTrade().getId());
model.setDepositTx(result.getValue());
ECKey.ECDSASignature offererSignature = result.getKey();
String depositTxAsHex = result.getValue();
model.setDepositTxAsHex(depositTxAsHex);
model.setOffererSignatureR(offererSignature.r.toString());
model.setOffererSignatureS(offererSignature.s.toString());
model.setOffererPaybackAmount(offererPaybackAmount);

View File

@ -41,7 +41,7 @@ public class SellerAsTakerModel extends OfferSharedModel {
// written/read by task
private Peer offerer;
private Transaction preparedDepositTx;
private String depositTxAsHex;
private Transaction depositTx;
private Transaction signedTakerDepositTx;
private Transaction payoutTx;
private String payoutTxAsHex;
@ -123,12 +123,12 @@ public class SellerAsTakerModel extends OfferSharedModel {
this.offererTxOutIndex = offererTxOutIndex;
}
public String getDepositTxAsHex() {
return depositTxAsHex;
public Transaction getDepositTx() {
return depositTx;
}
public void setDepositTxAsHex(String depositTxAsHex) {
this.depositTxAsHex = depositTxAsHex;
public void setDepositTx(Transaction depositTx) {
this.depositTx = depositTx;
}
public String getOffererSignatureR() {

View File

@ -25,6 +25,7 @@ import io.bitsquare.util.taskrunner.TaskRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.bitsquare.util.Validator.*;
public class ProcessBankTransferInitedMessage extends Task<SellerAsTakerModel> {
@ -40,7 +41,7 @@ public class ProcessBankTransferInitedMessage extends Task<SellerAsTakerModel> {
checkTradeId(model.getTrade().getId(), model.getTradeMessage());
BankTransferStartedMessage message = (BankTransferStartedMessage) model.getTradeMessage();
model.setDepositTxAsHex(nonEmptyStringOf(message.getDepositTxAsHex()));
model.setDepositTx(checkNotNull(message.getDepositTx()));
model.setOffererSignatureR(nonEmptyStringOf(message.getOffererSignatureR()));
model.setOffererSignatureS(nonEmptyStringOf(message.getOffererSignatureS()));
model.setOffererPaybackAmount(positiveCoinOf(nonZeroCoinOf(message.getOffererPaybackAmount())));

View File

@ -25,6 +25,7 @@ import io.bitsquare.util.taskrunner.TaskRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.Preconditions.checkNotNull;
import static io.bitsquare.util.Validator.*;
public class ProcessDepositTxPublishedMessage extends Task<SellerAsTakerModel> {
@ -40,7 +41,7 @@ public class ProcessDepositTxPublishedMessage extends Task<SellerAsTakerModel> {
checkTradeId(model.getTrade().getId(), model.getTradeMessage());
DepositTxPublishedMessage message = (DepositTxPublishedMessage) model.getTradeMessage();
model.setDepositTxAsHex(nonEmptyStringOf(message.getDepositTxAsHex()));
model.setDepositTx(checkNotNull(message.getDepositTx()));
complete();
} catch (Throwable t) {

View File

@ -43,7 +43,7 @@ public class SignAndPublishPayoutTx extends Task<SellerAsTakerModel> {
@Override
protected void doRun() {
try {
model.getWalletService().takerSignsAndSendsTx(model.getDepositTxAsHex(),
model.getWalletService().takerSignsAndSendsTx(model.getDepositTx(),
model.getOffererSignatureR(),
model.getOffererSignatureS(),
model.getOffererPaybackAmount(),

View File

@ -36,12 +36,15 @@ public class TakerCommitDepositTx extends Task<SellerAsTakerModel> {
@Override
protected void doRun() {
Transaction transaction = model.getWalletService().takerCommitDepositTx(model.getDepositTxAsHex());
try {
Transaction transaction = model.getWalletService().takerCommitDepositTx(model.getDepositTx());
model.getTrade().setDepositTx(transaction);
model.getTrade().setState(Trade.State.DEPOSIT_PUBLISHED);
model.getTrade().setDepositTx(transaction);
model.getTrade().setState(Trade.State.DEPOSIT_PUBLISHED);
complete();
complete();
} catch (Throwable t) {
failed(t);
}
}
@Override

View File

@ -34,7 +34,7 @@
<logger name="io.bitsquare.persistence.Persistence" level="ERROR"/>
<logger name="io.bitsquare.locale.BSResources" level="ERROR"/>
<logger name="org.bitcoinj" level="ERROR"/>
<logger name="org.bitcoinj" level="TRACE"/>
<logger name="net.tomp2p" level="ERROR"/>
<logger name="com.vinumeris.updatefx" level="OFF"/>
<logger name="io.netty" level="OFF"/>