mirror of
https://github.com/bisq-network/bisq.git
synced 2025-01-19 05:44:05 +01:00
payment process cleanup
This commit is contained in:
parent
5d9d7a9a3d
commit
1215f338ad
@ -1,231 +0,0 @@
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.script.Script;
|
||||
import com.google.bitcoin.script.ScriptBuilder;
|
||||
import com.google.bitcoin.store.UnreadableWalletException;
|
||||
import com.google.bitcoin.store.WalletProtobufSerializer;
|
||||
import com.google.common.util.concurrent.FutureCallback;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import io.bitsquare.BitSquare;
|
||||
import io.bitsquare.util.Utilities;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.google.bitcoin.script.ScriptOpCodes.OP_RETURN;
|
||||
|
||||
public class AccountRegistrationWallet extends Wallet implements WalletEventListener
|
||||
{
|
||||
// private static final Logger log = LoggerFactory.getLogger(AccountRegistrationWallet.class);
|
||||
private final File walletFile;
|
||||
|
||||
private NetworkParameters params;
|
||||
private BlockChain chain;
|
||||
private PeerGroup peerGroup;
|
||||
private List<WalletFacade.WalletListener> walletListeners = new ArrayList<>();
|
||||
|
||||
AccountRegistrationWallet(NetworkParameters params, BlockChain chain, PeerGroup peerGroup)
|
||||
{
|
||||
super(params);
|
||||
|
||||
this.params = params;
|
||||
this.chain = chain;
|
||||
this.peerGroup = peerGroup;
|
||||
|
||||
/* try
|
||||
{
|
||||
final InetAddress localHost = InetAddress.getLocalHost();
|
||||
PeerAddress peerAddress = new PeerAddress(localHost, params.getPort());
|
||||
peerGroup.addAddress(peerAddress);
|
||||
} catch (UnknownHostException e)
|
||||
{
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
} */
|
||||
|
||||
walletFile = new File(Utilities.getRootDir() + BitSquare.ID + "_account_reg" + ".wallet");
|
||||
if (walletFile.exists())
|
||||
{
|
||||
FileInputStream walletStream = null;
|
||||
try
|
||||
{
|
||||
walletStream = new FileInputStream(walletFile);
|
||||
} catch (FileNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
new WalletProtobufSerializer().readWallet(WalletProtobufSerializer.parseToProto(walletStream), this);
|
||||
} catch (UnreadableWalletException | IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
addKey(new ECKey());
|
||||
}
|
||||
|
||||
chain.addWallet(this);
|
||||
peerGroup.addWallet(this);
|
||||
try
|
||||
{
|
||||
saveToFile(walletFile);
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
autosaveToFile(walletFile, 1, TimeUnit.SECONDS, null);
|
||||
peerGroup.setMinBroadcastConnections(1);
|
||||
|
||||
allowSpendingUnconfirmedTransactions();
|
||||
}
|
||||
|
||||
void shutDown()
|
||||
{
|
||||
try
|
||||
{
|
||||
saveToFile(walletFile);
|
||||
} catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Address getAddress()
|
||||
{
|
||||
return getKey().toAddress(params);
|
||||
}
|
||||
|
||||
ECKey getKey()
|
||||
{
|
||||
return getKeys().get(0);
|
||||
}
|
||||
|
||||
void addWalletListener(WalletFacade.WalletListener listener)
|
||||
{
|
||||
if (walletListeners.size() == 0)
|
||||
addEventListener(this);
|
||||
|
||||
walletListeners.add(listener);
|
||||
}
|
||||
|
||||
void removeWalletListener(WalletFacade.WalletListener listener)
|
||||
{
|
||||
walletListeners.remove(listener);
|
||||
|
||||
if (walletListeners.size() == 0)
|
||||
removeEventListener(this);
|
||||
}
|
||||
|
||||
void saveToBlockchain(byte[] dataToEmbed) throws InsufficientMoneyException
|
||||
{
|
||||
Script script = new ScriptBuilder()
|
||||
.op(OP_RETURN)
|
||||
.data(dataToEmbed)
|
||||
.build();
|
||||
Transaction transaction = new Transaction(params);
|
||||
TransactionOutput dataOutput = new TransactionOutput(params,
|
||||
transaction,
|
||||
Transaction.MIN_NONDUST_OUTPUT,
|
||||
script.getProgram());
|
||||
transaction.addOutput(dataOutput);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(transaction);
|
||||
|
||||
// give fee to miners yet. Later it could be spent to other traders via lottery...
|
||||
sendRequest.fee = Fees.ACCOUNT_REGISTRATION_FEE;
|
||||
|
||||
Wallet.SendResult sendResult = sendCoins(sendRequest);
|
||||
|
||||
//TODO
|
||||
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>()
|
||||
{
|
||||
@Override
|
||||
public void onSuccess(Transaction result)
|
||||
{
|
||||
//log.info("sendResult onSuccess:" + result.toString());
|
||||
// Platform.runLater(overlayUi::done);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t)
|
||||
{
|
||||
//log.warn("sendResult onFailure:" + t.toString());
|
||||
// We died trying to empty the wallet.
|
||||
// crashAlert(t);
|
||||
}
|
||||
});
|
||||
|
||||
//TODO
|
||||
sendResult.tx.getConfidence().addEventListener((tx, reason) -> {
|
||||
//if (reason == TransactionConfidence.Listener.ChangeReason.SEEN_PEERS)
|
||||
//updateTitleForBroadcast();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
|
||||
{
|
||||
for (WalletFacade.WalletListener walletListener : walletListeners)
|
||||
walletListener.onCoinsReceived(newBalance);
|
||||
|
||||
// //log.info("onCoinsReceived");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
|
||||
{
|
||||
for (WalletFacade.WalletListener walletListener : walletListeners)
|
||||
walletListener.onConfidenceChanged(tx.getConfidence().numBroadcastPeers(), WalletUtil.getConfDepthInBlocks(this));
|
||||
|
||||
// //log.info("onTransactionConfidenceChanged " + tx.getConfidence().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
|
||||
{
|
||||
//log.info("onCoinsSent");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReorganize(Wallet wallet)
|
||||
{
|
||||
//log.info("onReorganize");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalletChanged(Wallet wallet)
|
||||
{
|
||||
// //log.info("onWalletChanged");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeysAdded(Wallet wallet, List<ECKey> keys)
|
||||
{
|
||||
//log.info("onKeysAdded");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScriptsAdded(Wallet wallet, List<Script> scripts)
|
||||
{
|
||||
//log.info("onScriptsAdded");
|
||||
}
|
||||
|
||||
int getConfNumBroadcastPeers()
|
||||
{
|
||||
Transaction transaction = WalletUtil.getTransaction(this);
|
||||
return (transaction == null || transaction.getConfidence() == null) ? 0 : transaction.getConfidence().numBroadcastPeers();
|
||||
}
|
||||
|
||||
}
|
23
src/main/java/io/bitsquare/btc/BitSquareWallet.java
Normal file
23
src/main/java/io/bitsquare/btc/BitSquareWallet.java
Normal file
@ -0,0 +1,23 @@
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.crypto.KeyCrypter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class BitSquareWallet extends Wallet
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(BitSquareWallet.class);
|
||||
|
||||
public BitSquareWallet(NetworkParameters params)
|
||||
{
|
||||
super(params);
|
||||
}
|
||||
|
||||
public BitSquareWallet(NetworkParameters params, KeyCrypter keyCrypter)
|
||||
{
|
||||
super(params, keyCrypter);
|
||||
}
|
||||
|
||||
}
|
@ -9,7 +9,7 @@ public class Fees
|
||||
{
|
||||
// min dust value lead to exception at for non standard to address pay scripts, so we use a value >= 7860 instead
|
||||
public static BigInteger MS_TX_FEE = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
public static BigInteger ACCOUNT_REGISTRATION_FEE = Utils.toNanoCoins("0.01");
|
||||
public static BigInteger OFFER_CREATION_FEE = Utils.toNanoCoins("0.001");
|
||||
public static BigInteger ACCOUNT_REGISTRATION_FEE = Utils.toNanoCoins("0.0002");
|
||||
public static BigInteger OFFER_CREATION_FEE = Utils.toNanoCoins("0.0002");
|
||||
public static BigInteger OFFER_TAKER_FEE = OFFER_CREATION_FEE;
|
||||
}
|
||||
|
21
src/main/java/io/bitsquare/btc/WalletConfig.java
Normal file
21
src/main/java/io/bitsquare/btc/WalletConfig.java
Normal file
@ -0,0 +1,21 @@
|
||||
package io.bitsquare.btc;
|
||||
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.kits.WalletAppKit;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class WalletConfig extends WalletAppKit
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(WalletConfig.class);
|
||||
|
||||
|
||||
public WalletConfig(NetworkParameters params, File directory, String filePrefix)
|
||||
{
|
||||
super(params, directory, filePrefix);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -91,7 +91,7 @@ public class WalletFacade
|
||||
|
||||
// Now configure and start the appkit. This will take a second or two - we could show a temporary splash screen
|
||||
// or progress widget to keep the user engaged whilst we initialise, but we don't.
|
||||
walletAppKit.setDownloadListener(new BlockChainDownloadListener()).setBlockingStartup(false).setUserAgent("BitSquare", "0.1");
|
||||
walletAppKit.setDownloadListener(new BlockChainDownloadListener()).setBlockingStartup(false).setUserAgent(BitSquare.ID, "0.1");
|
||||
walletAppKit.startAsync();
|
||||
walletAppKit.awaitRunning();
|
||||
|
||||
@ -102,11 +102,12 @@ public class WalletFacade
|
||||
wallet.addKey(tradingKey);
|
||||
|
||||
wallet.allowSpendingUnconfirmedTransactions();
|
||||
// walletAppKit.peerGroup().setMaxConnections(10);
|
||||
//TODO for regtest set 1
|
||||
walletAppKit.peerGroup().setMinBroadcastConnections(1);
|
||||
//walletAppKit.peerGroup().setMaxConnections(11);
|
||||
|
||||
//wallet.addWatchedAddress(tradingKey.toAddress(params));
|
||||
if (params == RegTestParams.get())
|
||||
walletAppKit.peerGroup().setMinBroadcastConnections(1);
|
||||
/* else
|
||||
walletAppKit.peerGroup().setMinBroadcastConnections(2); */
|
||||
}
|
||||
|
||||
public void shutDown()
|
||||
@ -178,24 +179,27 @@ public class WalletFacade
|
||||
|
||||
public void publishRegistrationTxWithExtraData(String stringifiedBankAccounts) throws InsufficientMoneyException
|
||||
{
|
||||
log.debug("publishRegistrationTxWithExtraData");
|
||||
log.trace("inputs: ");
|
||||
log.trace("stringifiedBankAccounts " + stringifiedBankAccounts);
|
||||
byte[] dataToEmbed = cryptoFacade.getEmbeddedAccountRegistrationData(registrationKey, stringifiedBankAccounts);
|
||||
Script script = new ScriptBuilder().op(OP_RETURN).data(dataToEmbed).build();
|
||||
Transaction transaction = new Transaction(params);
|
||||
TransactionOutput dataOutput = new TransactionOutput(params, transaction, Transaction.MIN_NONDUST_OUTPUT, script.getProgram());
|
||||
transaction.addOutput(dataOutput);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(transaction);
|
||||
Transaction tx = new Transaction(params);
|
||||
TransactionOutput dataOutput = new TransactionOutput(params, tx, Transaction.MIN_NONDUST_OUTPUT, script.getProgram());
|
||||
tx.addOutput(dataOutput);
|
||||
Wallet.SendRequest sendRequest = Wallet.SendRequest.forTx(tx);
|
||||
|
||||
// give fee to miners yet. Later it could be spent to other traders via lottery...
|
||||
sendRequest.fee = Fees.ACCOUNT_REGISTRATION_FEE;
|
||||
sendRequest.fee = Fees.ACCOUNT_REGISTRATION_FEE.subtract(Transaction.MIN_NONDUST_OUTPUT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
|
||||
log.debug("Registration transaction: " + transaction.toString());
|
||||
//TODO
|
||||
log.debug("Registration transaction: " + tx.toString());
|
||||
printInputs("publishRegistrationTxWithExtraData", tx);
|
||||
Futures.addCallback(sendResult.broadcastComplete, new FutureCallback<Transaction>()
|
||||
{
|
||||
@Override
|
||||
public void onSuccess(Transaction result)
|
||||
{
|
||||
log.debug("sendResult onSuccess:" + result.toString());
|
||||
log.debug("sendResult onSuccess");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -223,6 +227,8 @@ public class WalletFacade
|
||||
Wallet.SendResult sendResult = wallet.sendCoins(sendRequest);
|
||||
Futures.addCallback(sendResult.broadcastComplete, callback);
|
||||
|
||||
log.debug("Check if wallet is consistent: result=" + wallet.isConsistent());
|
||||
printInputs("payOfferFee", tx);
|
||||
log.debug("tx=" + tx.toString());
|
||||
return tx.getHashAsString();
|
||||
}
|
||||
@ -235,37 +241,52 @@ public class WalletFacade
|
||||
}
|
||||
|
||||
|
||||
// Offerer creates deposit tx with his input and change output, the MS has just a dummy value at the moment
|
||||
// 1. step: deposit tx
|
||||
// Offerer creates the 2of3 multiSig deposit tx with his unsigned input and change output
|
||||
public Transaction offererCreatesMSTxAndAddPayment(BigInteger offererInputAmount, String offererPubKey, String takerPubKey, String arbitratorPubKey) throws InsufficientMoneyException
|
||||
{
|
||||
log.debug("offererCreatesMSTxAndAddPayment");
|
||||
log.trace("inputs: ");
|
||||
log.trace("offererInputAmount=" + Utils.bitcoinValueToFriendlyString(offererInputAmount));
|
||||
log.trace("offererPubKey=" + offererPubKey);
|
||||
log.trace("takerPubKey=" + takerPubKey);
|
||||
log.trace("arbitratorPubKey=" + arbitratorPubKey);
|
||||
|
||||
// we pay the offererInputAmount to a dummy MS output, that way we get the best coin selection and fee calculation form the wallet and the correct change amount
|
||||
// we don't commit that tx to the wallet as it will be changed later and it's not signed yet
|
||||
// btc ntx fee will be included by the completeTx call, so we don't add it manually
|
||||
// We pay the offererInputAmount to a temporary MS output which will be changed later to the correct value.
|
||||
// With the usage of completeTx() we get all the work done with fee calculation, validation and coin selection.
|
||||
// Later with more customized coin selection we can use a custom CoinSelector implementation.
|
||||
// We don't commit that tx to the wallet as it will be changed later and it's not signed yet.
|
||||
// So it will not change the wallet balance.
|
||||
// The btc tx fee will be included by the completeTx() call, so we don't need to add it manually.
|
||||
Transaction tx = new Transaction(params);
|
||||
Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
tx.addOutput(offererInputAmount, multiSigOutputScript);
|
||||
Wallet.SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
wallet.completeTx(request);
|
||||
wallet.completeTx(Wallet.SendRequest.forTx(tx));
|
||||
|
||||
// we remove the signature to make sure the tx is invalid to publish
|
||||
// The completeTx() call signs the input, but we don't want to pass over a signed tx so we remove the
|
||||
// signature to make sure the tx is invalid for publishing
|
||||
tx.getInput(0).setScriptSig(new Script(new byte[]{}));
|
||||
|
||||
// tx looks like:
|
||||
log.trace("verify tx");
|
||||
tx.verify();
|
||||
|
||||
// The created tx looks like:
|
||||
/*
|
||||
IN[0]
|
||||
IN[0] any input > offererInputAmount + fee (unsigned)
|
||||
OUT[0] MS offererInputAmount
|
||||
OUT[1] offerer change amount
|
||||
OUT[1] Change = input - offererInputAmount - fee
|
||||
btc tx fee
|
||||
*/
|
||||
|
||||
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
|
||||
printInputs("offererCreatesMSTxAndAddPayment", tx);
|
||||
log.debug("tx = " + tx.toString());
|
||||
return tx;
|
||||
}
|
||||
|
||||
// Taker put his input in, change the MS amount to the correct value and sign his input
|
||||
public Transaction takerAddPaymentAndSign(BigInteger takerAmount,
|
||||
// 2. step: deposit tx
|
||||
// Taker adds his input and change output, changes the multiSig amount to the correct value and sign his input
|
||||
public Transaction takerAddPaymentAndSignTx(BigInteger takerInputAmount,
|
||||
BigInteger msOutputAmount,
|
||||
String offererPubKey,
|
||||
String takerPubKey,
|
||||
@ -273,40 +294,60 @@ public class WalletFacade
|
||||
String offerersPartialDepositTxAsHex
|
||||
) throws InsufficientMoneyException, ExecutionException, InterruptedException, AddressFormatException
|
||||
{
|
||||
log.debug("takerAddPaymentAndSign");
|
||||
log.debug("takerAddPaymentAndSignTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("takerInputAmount=" + Utils.bitcoinValueToFriendlyString(takerInputAmount));
|
||||
log.trace("msOutputAmount=" + Utils.bitcoinValueToFriendlyString(msOutputAmount));
|
||||
log.trace("offererPubKey=" + offererPubKey);
|
||||
log.trace("takerPubKey=" + takerPubKey);
|
||||
log.trace("arbitratorPubKey=" + arbitratorPubKey);
|
||||
log.trace("offerersPartialDepositTxAsHex=" + offerersPartialDepositTxAsHex);
|
||||
|
||||
// We pay the btc tx fee 2 times to the deposit tx:
|
||||
// 1. will be spent to miners when publishing the deposit tx
|
||||
// 2. will be as added to the MS amount, so when spending the payout tx the fee is already there and the outputs are not changed by fee reduction
|
||||
// Both traders pay 1 times a fee, so it is equally split between them
|
||||
|
||||
// We do exactly the same as in the 1. step but with the takers input.
|
||||
Transaction tempTx = new Transaction(params);
|
||||
Script multiSigOutputScript = getMultiSigScript(offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
tempTx.addOutput(takerInputAmount, multiSigOutputScript);
|
||||
wallet.completeTx(Wallet.SendRequest.forTx(tempTx));
|
||||
printInputs("tempTx", tempTx);
|
||||
log.trace("tempTx=" + tempTx);
|
||||
// That tx has signed input, but we don't need to remove it as we don't send that tx out, it is just used temporary.
|
||||
|
||||
// we pay the btc tx fee 2 times directly in the deposit tx:
|
||||
// 1. will be spent to miners when publishing the deposit tx (sum inputs - sum outputs = fee)
|
||||
// 2. will be as added to the MS amount, so when spending the payout tx the fee is already there
|
||||
// both traders pay 1 times a fee, so its equally split
|
||||
|
||||
// we construct a dummy tx to get the best coin selection and fee calculation form the wallet and the correct change amount
|
||||
// btc ntx fee will be included by the completeTx call, so we don't add it manually
|
||||
Transaction dummyTx = new Transaction(params);
|
||||
dummyTx.addOutput(takerAmount, multiSigOutputScript);
|
||||
wallet.completeTx(Wallet.SendRequest.forTx(dummyTx)); // it is signed but we don't care as it will not be used further
|
||||
|
||||
// Now we construct the real MS tx from the passed tx from the offerer
|
||||
Transaction tx = new Transaction(params, Utils.parseAsHexOrBase58(offerersPartialDepositTxAsHex));
|
||||
|
||||
// it looks like that
|
||||
// The created tempTx looks like:
|
||||
/*
|
||||
IN[0] offerer input
|
||||
OUT[0] MS offererInputAmount
|
||||
OUT[1] offerer change
|
||||
IN[0] any input taker > takerInputAmount + fee (signed)
|
||||
OUT[0] MS takerInputAmount
|
||||
OUT[1] Change = input taker - takerInputAmount - fee
|
||||
btc tx fee
|
||||
*/
|
||||
|
||||
// we add our inputs and outputs and change the MS amount to the correct one
|
||||
tx.addInput(dummyTx.getInput(0));
|
||||
tx.addOutput(dummyTx.getOutput(1));
|
||||
|
||||
// we add the btc tx fee
|
||||
// Now we construct the real 2of3 multiSig tx from the serialized offerers tx
|
||||
Transaction tx = new Transaction(params, Utils.parseAsHexOrBase58(offerersPartialDepositTxAsHex));
|
||||
log.trace("offerersPartialDepositTx=" + tx);
|
||||
|
||||
// The serialized offerers tx looks like:
|
||||
/*
|
||||
IN[0] any input offerer > offererInputAmount + fee (unsigned)
|
||||
OUT[0] MS offererInputAmount
|
||||
OUT[1] Change = input offerer - offererInputAmount - fee
|
||||
btc tx fee
|
||||
*/
|
||||
|
||||
// Now we add the inputs and outputs from our temp tx and change the multiSig amount to the correct value
|
||||
tx.addInput(tempTx.getInput(0));
|
||||
if (tempTx.getOutputs().size() == 2)
|
||||
tx.addOutput(tempTx.getOutput(1));
|
||||
|
||||
// We add the btc tx fee to the msOutputAmount and apply the change to the multiSig output
|
||||
msOutputAmount = msOutputAmount.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
// and change the value of the MS output
|
||||
tx.getOutput(0).setValue(msOutputAmount);
|
||||
|
||||
// Now we sign our input
|
||||
TransactionInput input = tx.getInput(1);
|
||||
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
|
||||
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
|
||||
@ -320,54 +361,92 @@ public class WalletFacade
|
||||
else
|
||||
throw new ScriptException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey);
|
||||
|
||||
log.debug("check if correctly spends");
|
||||
log.trace("check if it can be correctly spent for input 1");
|
||||
input.getScriptSig().correctlySpends(tx, 1, scriptPubKey, false);
|
||||
|
||||
log.debug("verify tx");
|
||||
log.trace("verify tx");
|
||||
tx.verify();
|
||||
|
||||
// The resulting tx looks like:
|
||||
/*
|
||||
IN[0] offerer 0.1001
|
||||
IN[1] taker signed 1.1001
|
||||
OUT[0] MS (include btc tx fee for payout tx) 1.2001
|
||||
OUT[1] offerer change
|
||||
OUT[2] taker change
|
||||
btc tx fee 0.0001
|
||||
IN[0] any input offerer > offererInputAmount + fee (unsigned) e.g.: 0.1001
|
||||
IN[1] any input taker > takerInputAmount + fee (signed) e.g.: 1.1001
|
||||
OUT[0] MS offererInputAmount e.g.: 1.2001
|
||||
OUT[1] Change = input offerer - offererInputAmount - fee e.g.: 0 if input is matching correct value
|
||||
OUT[2] Change = input taker - takerInputAmount - fee e.g.: 0 if input is matching correct value
|
||||
btc tx fee e.g.: 0.1001
|
||||
*/
|
||||
|
||||
wallet.commitTx(tx);
|
||||
log.debug("tx" + tx.toString());
|
||||
// We must not commit that tx to the wallet as we will get it over the network when the offerer
|
||||
// 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.toString());
|
||||
return tx;
|
||||
}
|
||||
|
||||
// deposit 3. offerer
|
||||
public Transaction offererSignAndSendTx(String tx1AsHex,
|
||||
String tx2AsHex,
|
||||
String tx2ConnOutAsHex,
|
||||
String tx2ScriptSigAsHex,
|
||||
|
||||
// 3. step: deposit tx
|
||||
// Offerer signs tx and publishes it
|
||||
public Transaction offererSignAndPublishTx(String offerersFirstTxAsHex,
|
||||
String takersSignedTxAsHex,
|
||||
String takersSignedConnOutAsHex,
|
||||
String takersSignedScriptSigAsHex,
|
||||
FutureCallback<Transaction> callback) throws Exception
|
||||
{
|
||||
log.info("offererSignAndSendTx start");
|
||||
log.debug("offererSignAndPublishTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("offerersFirstTxAsHex=" + offerersFirstTxAsHex);
|
||||
log.trace("takersSignedTxAsHex=" + takersSignedTxAsHex);
|
||||
log.trace("takersSignedConnOutAsHex=" + takersSignedConnOutAsHex);
|
||||
log.trace("takersSignedScriptSigAsHex=" + takersSignedScriptSigAsHex);
|
||||
log.trace("callback=" + callback.toString());
|
||||
log.trace("Wallet balance initial: " + wallet.getBalance());
|
||||
|
||||
// We create an empty tx (did not find a way to manipulate a tx input, otherwise the takers tx could be used directly and add the offerers input and output)
|
||||
Transaction tx = new Transaction(params);
|
||||
|
||||
Transaction tx1 = new Transaction(params, Utils.parseAsHexOrBase58(tx1AsHex));
|
||||
Transaction tx1ConnOut = wallet.getTransaction(tx1.getInput(0).getOutpoint().getHash());
|
||||
TransactionOutPoint tx1OutPoint = new TransactionOutPoint(params, 1, tx1ConnOut);
|
||||
TransactionInput tx1Input = new TransactionInput(params, tx, tx1.getInput(0).getScriptBytes(), tx1OutPoint);
|
||||
tx1Input.setParent(tx);
|
||||
tx.addInput(tx1Input);
|
||||
// offerers first tx
|
||||
Transaction offerersFirstTx = new Transaction(params, Utils.parseAsHexOrBase58(offerersFirstTxAsHex));
|
||||
|
||||
Transaction tx2 = new Transaction(params, Utils.parseAsHexOrBase58(tx2AsHex));
|
||||
Transaction tx2ConnOut = new Transaction(params, Utils.parseAsHexOrBase58(tx2ConnOutAsHex));
|
||||
TransactionOutPoint tx2OutPoint = new TransactionOutPoint(params, 1, tx2ConnOut);
|
||||
TransactionInput tx2Input = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(tx2ScriptSigAsHex), tx2OutPoint);
|
||||
tx2Input.setParent(tx);
|
||||
tx.addInput(tx2Input);
|
||||
printInputs("offerersFirstTx", offerersFirstTx);
|
||||
log.trace("offerersFirstTx = " + offerersFirstTx.toString());
|
||||
|
||||
tx.addOutput(tx2.getOutput(0));
|
||||
tx.addOutput(tx2.getOutput(1));
|
||||
tx.addOutput(tx2.getOutput(2));
|
||||
// add input
|
||||
Transaction offerersFirstTxConnOut = wallet.getTransaction(offerersFirstTx.getInput(0).getOutpoint().getHash()); // pass that around!
|
||||
TransactionOutPoint offerersFirstTxOutPoint = new TransactionOutPoint(params, 1, offerersFirstTxConnOut);
|
||||
//TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, offerersFirstTx.getInput(0).getScriptBytes(), offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes aray
|
||||
TransactionInput offerersFirstTxInput = new TransactionInput(params, tx, new byte[]{}, offerersFirstTxOutPoint); // pass that around! getScriptBytes = empty bytes aray
|
||||
offerersFirstTxInput.setParent(tx);
|
||||
tx.addInput(offerersFirstTxInput);
|
||||
|
||||
// takers signed tx
|
||||
Transaction takersSignedTx = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedTxAsHex));
|
||||
|
||||
printInputs("takersSignedTxInput", takersSignedTx);
|
||||
log.trace("takersSignedTx = " + takersSignedTx.toString());
|
||||
|
||||
// add input
|
||||
Transaction takersSignedTxConnOut = new Transaction(params, Utils.parseAsHexOrBase58(takersSignedConnOutAsHex));
|
||||
TransactionOutPoint takersSignedTxOutPoint = new TransactionOutPoint(params, 1, takersSignedTxConnOut);
|
||||
TransactionInput takersSignedTxInput = new TransactionInput(params, tx, Utils.parseAsHexOrBase58(takersSignedScriptSigAsHex), takersSignedTxOutPoint);
|
||||
takersSignedTxInput.setParent(tx);
|
||||
tx.addInput(takersSignedTxInput);
|
||||
|
||||
//TODO handle non change output cases
|
||||
// add outputs from takers tx, they are already correct
|
||||
|
||||
for (int i = 0; i < takersSignedTx.getOutputs().size(); i++)
|
||||
{
|
||||
tx.addOutput(takersSignedTx.getOutput(i));
|
||||
}
|
||||
|
||||
printInputs("tx", tx);
|
||||
log.trace("tx = " + tx.toString());
|
||||
log.trace("Wallet balance before signing: " + wallet.getBalance());
|
||||
|
||||
// sign the input
|
||||
TransactionInput input = tx.getInput(0);
|
||||
Script scriptPubKey = input.getConnectedOutput().getScriptPubKey();
|
||||
ECKey sigKey = input.getOutpoint().getConnectedKey(wallet);
|
||||
@ -381,72 +460,88 @@ public class WalletFacade
|
||||
else
|
||||
throw new ScriptException("Don't know how to sign for this kind of scriptPubKey: " + scriptPubKey);
|
||||
|
||||
log.info("offererSignAndSendTx check correctlySpends input 0");
|
||||
log.trace("check if it can be correctly spent for input 0");
|
||||
input.getScriptSig().correctlySpends(tx, 0, scriptPubKey, false);
|
||||
|
||||
log.info("offererSignAndSendTx check correctlySpends input 1");
|
||||
input = tx.getInput(1);
|
||||
scriptPubKey = input.getConnectedOutput().getScriptPubKey();
|
||||
input.getScriptSig().correctlySpends(tx, 1, scriptPubKey, false);
|
||||
log.trace("check if it can be correctly spent for input 1");
|
||||
TransactionInput input1 = tx.getInput(1);
|
||||
scriptPubKey = input1.getConnectedOutput().getScriptPubKey();
|
||||
input1.getScriptSig().correctlySpends(tx, 1, scriptPubKey, false);
|
||||
|
||||
/*
|
||||
IN[0] offerer signed
|
||||
IN[1] taker signed
|
||||
OUT[0] MS
|
||||
IN[0] offerer signed 0.1001
|
||||
IN[1] taker signed 1.1001
|
||||
OUT[0] MS (include btc tx fee for payout tx) 1.2001
|
||||
OUT[1] offerer change
|
||||
OUT[2] taker change
|
||||
btc tx fee 0.0001
|
||||
*/
|
||||
log.info("offererSignAndSendTx broadcastTransaction verify ");
|
||||
|
||||
log.trace("verify ");
|
||||
tx.verify();
|
||||
|
||||
log.info("offererSignAndSendTx broadcastTransaction");
|
||||
printInputs("tx", tx);
|
||||
log.debug("tx = " + tx.toString());
|
||||
|
||||
log.trace("Wallet balance before broadcastTransaction: " + wallet.getBalance());
|
||||
log.trace("Check if wallet is consistent before broadcastTransaction: result=" + wallet.isConsistent());
|
||||
ListenableFuture<Transaction> broadcastComplete = walletAppKit.peerGroup().broadcastTransaction(tx);
|
||||
/*FutureCallback<Transaction> localCallback = new FutureCallback<Transaction>()
|
||||
{
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction)
|
||||
{
|
||||
log.info("offererSignAndSendTx onSuccess" + transaction.getHashAsString());
|
||||
}
|
||||
log.trace("Wallet balance after broadcastTransaction: " + wallet.getBalance());
|
||||
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t)
|
||||
{
|
||||
log.info("offererSignAndSendTx onFailure" + t.toString());
|
||||
Popups.openErrorPopup("Fee payment failed", "Fee payment failed. " + t.toString());
|
||||
}
|
||||
};
|
||||
Futures.addCallback(broadcastComplete, localCallback); */
|
||||
Futures.addCallback(broadcastComplete, callback);
|
||||
|
||||
printInputs("tx", tx);
|
||||
log.debug("tx = " + tx.toString());
|
||||
return tx;
|
||||
}
|
||||
|
||||
// payout 1. offerer
|
||||
public Pair<ECKey.ECDSASignature, Transaction> offererCreateAndSignPayoutTx(String depositTxID,
|
||||
// 4 step deposit tx: Offerer send deposit tx to taker
|
||||
public void takerCommitDepositTx(String depositTxAsHex)
|
||||
{
|
||||
log.trace("takerCommitDepositTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("depositTxID=" + depositTxAsHex);
|
||||
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
|
||||
log.trace("depositTx=" + depositTx);
|
||||
wallet.commitTx(depositTx);
|
||||
}
|
||||
|
||||
// 5. step payout tx: Offerer creates payout tx and signs it
|
||||
public Pair<ECKey.ECDSASignature, String> offererCreatesAndSignsPayoutTx(String depositTxID,
|
||||
BigInteger offererPaybackAmount,
|
||||
BigInteger takerPaybackAmount,
|
||||
String takerAddress) throws InsufficientMoneyException, AddressFormatException
|
||||
{
|
||||
// offerer has published depositTx so he has it in wallet
|
||||
log.debug("offererCreatesAndSignsPayoutTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("depositTxID=" + depositTxID);
|
||||
log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount));
|
||||
log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount));
|
||||
log.trace("takerAddress=" + takerAddress);
|
||||
|
||||
// Offerer has published depositTx earlier, so he has it in his wallet
|
||||
Transaction depositTx = wallet.getTransaction(new Sha256Hash(depositTxID));
|
||||
TransactionOutput multiSigOutput = depositTx.getOutput(0);
|
||||
String depositTxAsHex = Utils.bytesToHexString(depositTx.bitcoinSerialize());
|
||||
|
||||
// We create the payout tx
|
||||
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, getTradingAddress(), takerAddress);
|
||||
|
||||
// We create the signature for that tx
|
||||
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
|
||||
Script multiSigScript = multiSigOutput.getScriptPubKey();
|
||||
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(multiSigOutput);
|
||||
//TODO fee calculation
|
||||
tx.addOutput(offererPaybackAmount.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), tradingKey.toAddress(params));
|
||||
tx.addOutput(takerPaybackAmount.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), new Address(params, takerAddress));
|
||||
|
||||
Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
||||
ECKey.ECDSASignature signature = tradingKey.sign(sigHash);
|
||||
ECKey.ECDSASignature offererSignature = tradingKey.sign(sigHash);
|
||||
|
||||
return new Pair<>(signature, depositTx);
|
||||
TransactionSignature offererTxSig = new TransactionSignature(offererSignature, Transaction.SigHash.ALL, false);
|
||||
Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig));
|
||||
tx.getInput(0).setScriptSig(inputScript);
|
||||
|
||||
log.trace("sigHash=" + sigHash.toString());
|
||||
return new Pair<>(offererSignature, depositTxAsHex);
|
||||
}
|
||||
|
||||
// payout 2. taker
|
||||
public Transaction takerSignAndSendTx(String depositTxAsHex,
|
||||
// 6. step payout tx: Taker signs and publish tx
|
||||
public Transaction takerSignsAndSendsTx(String depositTxAsHex,
|
||||
String offererSignatureR,
|
||||
String offererSignatureS,
|
||||
BigInteger offererPaybackAmount,
|
||||
@ -454,23 +549,24 @@ public class WalletFacade
|
||||
String offererAddress,
|
||||
FutureCallback<Transaction> callback) throws InsufficientMoneyException, AddressFormatException
|
||||
{
|
||||
log.debug("takerSignsAndSendsTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("depositTxAsHex=" + depositTxAsHex);
|
||||
log.trace("offererSignatureR=" + offererSignatureR);
|
||||
log.trace("offererSignatureS=" + offererSignatureS);
|
||||
log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount));
|
||||
log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount));
|
||||
log.trace("offererAddress=" + offererAddress);
|
||||
log.trace("callback=" + callback.toString());
|
||||
|
||||
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
|
||||
TransactionOutput multiSigOutput = depositTx.getOutput(0);
|
||||
// We create the payout tx
|
||||
Transaction tx = createPayoutTx(depositTxAsHex, offererPaybackAmount, takerPaybackAmount, offererAddress, getTradingAddress());
|
||||
|
||||
// We sign that tx with our key and apply the signature form the offerer
|
||||
TransactionOutput multiSigOutput = tx.getInput(0).getConnectedOutput();
|
||||
Script multiSigScript = multiSigOutput.getScriptPubKey();
|
||||
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(multiSigOutput);
|
||||
//TODO fee calculation
|
||||
if (offererPaybackAmount.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) <= 0)
|
||||
log.error("Cannot use such low value");
|
||||
if (takerPaybackAmount.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) <= 0)
|
||||
log.error("Cannot use such low value");
|
||||
|
||||
tx.addOutput(offererPaybackAmount.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), new Address(params, offererAddress));
|
||||
tx.addOutput(takerPaybackAmount.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), tradingKey.toAddress(params));
|
||||
|
||||
Sha256Hash sigHash = tx.hashForSignature(0, multiSigScript, Transaction.SigHash.ALL, false);
|
||||
log.trace("sigHash=" + sigHash.toString());
|
||||
|
||||
ECKey.ECDSASignature takerSignature = tradingKey.sign(sigHash);
|
||||
TransactionSignature takerTxSig = new TransactionSignature(takerSignature, Transaction.SigHash.ALL, false);
|
||||
@ -481,59 +577,22 @@ public class WalletFacade
|
||||
Script inputScript = ScriptBuilder.createMultiSigInputScript(ImmutableList.of(offererTxSig, takerTxSig));
|
||||
tx.getInput(0).setScriptSig(inputScript);
|
||||
|
||||
log.info("verify tx");
|
||||
log.trace("verify tx");
|
||||
tx.verify();
|
||||
|
||||
try
|
||||
{
|
||||
log.info("verify correctlySpends");
|
||||
log.trace("check if it can be correctly spent for ms input");
|
||||
tx.getInput(0).getScriptSig().correctlySpends(tx, 0, multiSigScript, false);
|
||||
} catch (Exception e)
|
||||
{
|
||||
log.error("verify correctlySpends 0:" + e.getMessage());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
log.info("verify multiSigOutput");
|
||||
log.trace("verify multiSigOutput");
|
||||
tx.getInput(0).verify(multiSigOutput);
|
||||
} catch (Exception e)
|
||||
{
|
||||
log.error("verify multiSigOutput 1:" + e.getMessage());
|
||||
}
|
||||
|
||||
log.info("broadcastTransaction:" + tx.toString());
|
||||
Object t = wallet.getTransactions(true);
|
||||
log.info("pre broadcastTransaction broadcastTransaction:" + wallet.getTransactions(true).size());
|
||||
ListenableFuture<Transaction> broadcastComplete = walletAppKit.peerGroup().broadcastTransaction(tx);
|
||||
|
||||
FutureCallback<Transaction> localCallback = new FutureCallback<Transaction>()
|
||||
{
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction)
|
||||
{
|
||||
Object t = wallet.getTransactions(true);
|
||||
log.info("onSuccess broadcastTransaction:" + wallet.getTransactions(true).size());
|
||||
|
||||
log.info("sendResult onSuccess:" + transaction.toString());
|
||||
log.info("is in wallet?" + wallet.getTransaction(transaction.getHash()).getHashAsString());
|
||||
/*if (wallet.getTransaction(transaction.getHash()) == null)
|
||||
wallet.commitTx(transaction); */
|
||||
log.info("now must be in wallet?" + wallet.getTransaction(transaction.getHash()).getHashAsString());
|
||||
log.info("##################### now must be in wallet?" + wallet.getTransaction(transaction.getHash()).getHashAsString());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Throwable t)
|
||||
{
|
||||
log.warn("sendResult onFailure:" + t.toString());
|
||||
}
|
||||
};
|
||||
|
||||
Futures.addCallback(broadcastComplete, localCallback);
|
||||
Futures.addCallback(broadcastComplete, callback);
|
||||
|
||||
log.trace("getTransactions.size=" + wallet.getTransactions(true).size());
|
||||
log.trace("Check if wallet is consistent: result=" + wallet.isConsistent());
|
||||
printInputs("takerSignsAndSendsTx", tx);
|
||||
log.debug("tx = " + tx.toString());
|
||||
return tx;
|
||||
}
|
||||
|
||||
@ -552,114 +611,37 @@ public class WalletFacade
|
||||
return ScriptBuilder.createMultiSigOutputScript(2, keys);
|
||||
}
|
||||
|
||||
|
||||
// TODO only temp. for testing trade process between offerer and taker
|
||||
// deposit
|
||||
private void testTradeProcessDepositTx()
|
||||
public Transaction createPayoutTx(String depositTxAsHex,
|
||||
BigInteger offererPaybackAmount,
|
||||
BigInteger takerPaybackAmount,
|
||||
String offererAddress,
|
||||
String takerAddress) throws AddressFormatException
|
||||
{
|
||||
try
|
||||
{
|
||||
String tx1AsHex, tx2AsHex, tx2ScriptSigAsHex, tx2ConnOutAsHex;
|
||||
log.trace("createPayoutTx");
|
||||
log.trace("inputs: ");
|
||||
log.trace("depositTxAsHex=" + depositTxAsHex);
|
||||
log.trace("offererPaybackAmount=" + Utils.bitcoinValueToFriendlyString(offererPaybackAmount));
|
||||
log.trace("takerPaybackAmount=" + Utils.bitcoinValueToFriendlyString(takerPaybackAmount));
|
||||
log.trace("offererAddress=" + offererAddress);
|
||||
log.trace("takerAddress=" + takerAddress);
|
||||
|
||||
BigInteger offererAmount = Utils.toNanoCoins("0.01");
|
||||
BigInteger takerAmount = Utils.toNanoCoins("0.02");
|
||||
|
||||
String takerPubKey = "0207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568";
|
||||
String offererPubKey = "0352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7";
|
||||
String arbitratorPubKey = "";
|
||||
|
||||
// 1 offerer creates MS TX and pay in
|
||||
Transaction tx1 = offererCreatesMSTxAndAddPayment(offererAmount, offererPubKey, takerPubKey, arbitratorPubKey);
|
||||
tx1AsHex = Utils.bytesToHexString(tx1.bitcoinSerialize());
|
||||
|
||||
|
||||
tx1AsHex = "01000000014378dfcd19add18eb6f118a1e35ced127ff23c9dc5034eee1cda5b9caeb814f0000000006b4830450221008e599dd7bb7223c7b036869198b14f08009f9bc117709d23c249d0bdd6b483be022047be181f467782ea277b36890feb2f6de3ceddcedf8730a9f505bac36b3b015b01210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7ffffffff0240420f00000000004852210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b65680053aeb077e605000000001976a9149fc3d8e0371b6eab89a8c3c015839f9e493ccf6588ac00000000";
|
||||
|
||||
// 2. taker pay in and sign
|
||||
/* Transaction tx2 = takerAddPaymentAndSign(takerAmount, msOutputAmount, offererPubKey, takerPubKey, arbitratorPubKey, tx1AsHex);
|
||||
tx2AsHex = Utils.bytesToHexString(tx2.bitcoinSerialize());
|
||||
tx2ScriptSigAsHex = Utils.bytesToHexString(tx2.getInput(1).getScriptBytes());
|
||||
tx2ConnOutAsHex = Utils.bytesToHexString(tx2.getInput(1).getConnectedOutput().getParentTransaction().bitcoinSerialize());
|
||||
*/
|
||||
|
||||
tx2AsHex = "01000000024378dfcd19add18eb6f118a1e35ced127ff23c9dc5034eee1cda5b9caeb814f0000000006b4830450221008e599dd7bb7223c7b036869198b14f08009f9bc117709d23c249d0bdd6b483be022047be181f467782ea277b36890feb2f6de3ceddcedf8730a9f505bac36b3b015b01210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7ffffffffa58b22a93a0fcf99ba48aa3b96d842284b2b3d24f72d045cc192ea8a6b89435c010000006a47304402207f4beeb1a86432be0b4c3d4f4db7416b52b66c84383d1980d39e21d547a1762f02200405d0d4b80d1094e3a08cb39ef6f1161be163026d417af08d54c5a1cfdbbbeb01210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568ffffffff03c0c62d00000000004852210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b65680053aeb077e605000000001976a9149fc3d8e0371b6eab89a8c3c015839f9e493ccf6588ac7035d705000000001976a914e5175c1f71c28218306d4a27c8cec0269dddbbde88ac00000000";
|
||||
tx2ScriptSigAsHex = "47304402207f4beeb1a86432be0b4c3d4f4db7416b52b66c84383d1980d39e21d547a1762f02200405d0d4b80d1094e3a08cb39ef6f1161be163026d417af08d54c5a1cfdbbbeb01210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568";
|
||||
tx2ConnOutAsHex = "01000000014378dfcd19add18eb6f118a1e35ced127ff23c9dc5034eee1cda5b9caeb814f0010000006a473044022011431387fc19b093b26a6d2371995c828179aae68e94ad5804e5d0986a6b471302206abc2b698375620e65fc9970b7781da0af2179d1bdc4ebc82a13e285359a3ce7012103c7b9e9ef657705522c85b8429bb2b42c04f0fd4a09e0605cd7dd62ffecb57944ffffffff02c0ce823e000000001976a9142d1b4347ae850805f3badbb4b2949674f46c4ccd88ac00e1f505000000001976a914e5175c1f71c28218306d4a27c8cec0269dddbbde88ac00000000";
|
||||
|
||||
// 3. offerer sign and send
|
||||
Transaction tx3 = offererSignAndSendTx(tx1AsHex, tx2AsHex, tx2ConnOutAsHex, tx2ScriptSigAsHex, null);
|
||||
|
||||
log.info(tx3.toString()); // tx has 453 Bytes
|
||||
|
||||
} catch (AddressFormatException | InsufficientMoneyException | InterruptedException | ExecutionException e)
|
||||
{
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
} catch (Exception e)
|
||||
{
|
||||
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
|
||||
}
|
||||
Transaction depositTx = new Transaction(params, Utils.parseAsHexOrBase58(depositTxAsHex));
|
||||
TransactionOutput multiSigOutput = depositTx.getOutput(0);
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(multiSigOutput);
|
||||
tx.addOutput(offererPaybackAmount, new Address(params, offererAddress));
|
||||
tx.addOutput(takerPaybackAmount, new Address(params, takerAddress));
|
||||
log.trace("tx=" + tx);
|
||||
return tx;
|
||||
}
|
||||
|
||||
// payout
|
||||
private void testTradeProcessPayOutTx()
|
||||
private void printInputs(String tracePrefix, Transaction tx)
|
||||
{
|
||||
String depositTxAsHex, offererSignatureR, offererSignatureS;
|
||||
BigInteger offererPaybackAmount = Utils.toNanoCoins("0.029");
|
||||
BigInteger takerPaybackAmount = Utils.toNanoCoins("0.001");
|
||||
|
||||
ECKey takerKey = new ECKey(null, Utils.parseAsHexOrBase58("0207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568"));
|
||||
String takerAddress = takerKey.toAddress(params).toString();
|
||||
|
||||
ECKey offererKey = new ECKey(null, Utils.parseAsHexOrBase58("0352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7"));
|
||||
String offererAddress = offererKey.toAddress(params).toString();
|
||||
|
||||
String depositTxID = "4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9";
|
||||
|
||||
try
|
||||
{
|
||||
// 1. offerer create and sign payout tx
|
||||
/* Pair<ECKey.ECDSASignature, Transaction> result = offererCreateAndSignPayoutTx(depositTxID,
|
||||
offererPaybackAmount,
|
||||
takerPaybackAmount,
|
||||
takerAddress);
|
||||
|
||||
ECKey.ECDSASignature offererSignature = result.getKey();
|
||||
Transaction depositTx = result.getValue();
|
||||
offererSignatureR = offererSignature.r.toString();
|
||||
offererSignatureS = offererSignature.s.toString();
|
||||
depositTxAsHex = Utils.bytesToHexString(depositTx.bitcoinSerialize()); */
|
||||
|
||||
|
||||
depositTxAsHex = "01000000024378dfcd19add18eb6f118a1e35ced127ff23c9dc5034eee1cda5b9caeb814f0000000006a473044022008addf33a37f8f058e629020d73c3873953e1eca559fcb59d9db651f2c9b524f02203cbfd319b2675974adfbff2cb605fc9b89a92f2f3197ee634b39c892fb57d1be01210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7ffffffffa58b22a93a0fcf99ba48aa3b96d842284b2b3d24f72d045cc192ea8a6b89435c010000006a47304402207f4beeb1a86432be0b4c3d4f4db7416b52b66c84383d1980d39e21d547a1762f02200405d0d4b80d1094e3a08cb39ef6f1161be163026d417af08d54c5a1cfdbbbeb01210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568ffffffff03c0c62d00000000004852210352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7210207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b65680053aeb077e605000000001976a9149fc3d8e0371b6eab89a8c3c015839f9e493ccf6588ac7035d705000000001976a914e5175c1f71c28218306d4a27c8cec0269dddbbde88ac00000000";
|
||||
offererSignatureR = "64562406184784382000330465585294975882418886289667123258365244289311131050102";
|
||||
offererSignatureS = "9282449224979858852843663340827968850695102089943078462704407873774672151491";
|
||||
|
||||
// 2. taker sign and publish tx
|
||||
Transaction takerTx = takerSignAndSendTx(depositTxAsHex,
|
||||
offererSignatureR,
|
||||
offererSignatureS,
|
||||
offererPaybackAmount,
|
||||
takerPaybackAmount,
|
||||
offererAddress, null);
|
||||
|
||||
log.info(takerTx.toString()); // tx has 265 Bytes
|
||||
|
||||
/*
|
||||
6606c366a487bff9e412d0b6c09c14916319932db5954bf5d8719f43f828a3ba: Unknown confidence level.
|
||||
in [] [30450221008ebd06e53ce1ab7b599098b3117f2073b1d224baae21190ef7839b70a638207602201485ae19965f2d954398f691aa40fecb4d08d625ae96037a4fc5eecb7a4803c301]
|
||||
[30440220521c485045a46fbb61c634ebf456c470f9c2f7307a743e3fce10b50f7a69115d0220249ff5f9796a9fcd12984afcfd3f7d16d2f8c49ddcef245db7c7b02b909af9a601]
|
||||
outpoint:4142ee4877eb116abf955a7ec6ef2dc38133b793df762b76d75e3d7d4d8badc9:0 hash160:[exception: Script not in the standard scriptPubKey form]
|
||||
out DUP HASH160 [9fc3d8e0371b6eab89a8c3c015839f9e493ccf65] EQUALVERIFY CHECKSIG 0.0289 BTC
|
||||
out DUP HASH160 [e5175c1f71c28218306d4a27c8cec0269dddbbde] EQUALVERIFY CHECKSIG 0.0009 BTC
|
||||
|
||||
2 [0352f2e34760514099f90b03aab91239466924c3b06047d3cf0e011f26ef96ceb7] [0207cf5fb65d6923d5d41db21ceac9567a0fc3eb92c6137f274018381ced7b6568] [] 3 CHECKMULTISIG
|
||||
*/
|
||||
|
||||
} catch (InsufficientMoneyException | AddressFormatException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (TransactionInput input : tx.getInputs())
|
||||
if (input.getConnectedOutput() != null)
|
||||
log.trace(tracePrefix + ": " + Utils.bitcoinValueToFriendlyString(input.getConnectedOutput().getValue()));
|
||||
else
|
||||
log.trace(tracePrefix + ": " + "Transaction already has inputs but we don't have the connected outputs, so we don't know the value.");
|
||||
}
|
||||
|
||||
|
||||
@ -673,14 +655,24 @@ public class WalletFacade
|
||||
protected void progress(double percent, int blocksSoFar, Date date)
|
||||
{
|
||||
super.progress(percent, blocksSoFar, date);
|
||||
for (DownloadListener downloadListener : downloadListeners)
|
||||
downloadListener.progress(percent, blocksSoFar, date);
|
||||
Platform.runLater(() -> onProgressInUserThread(percent, blocksSoFar, date));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doneDownload()
|
||||
{
|
||||
super.doneDownload();
|
||||
Platform.runLater(() -> onDoneDownloadInUserThread());
|
||||
}
|
||||
|
||||
private void onProgressInUserThread(double percent, int blocksSoFar, final Date date)
|
||||
{
|
||||
for (DownloadListener downloadListener : downloadListeners)
|
||||
downloadListener.progress(percent, blocksSoFar, date);
|
||||
}
|
||||
|
||||
private void onDoneDownloadInUserThread()
|
||||
{
|
||||
for (DownloadListener downloadListener : downloadListeners)
|
||||
downloadListener.doneDownload();
|
||||
}
|
||||
@ -693,11 +685,4 @@ public class WalletFacade
|
||||
void doneDownload();
|
||||
}
|
||||
|
||||
public static interface WalletListener
|
||||
{
|
||||
void onConfidenceChanged(int numBroadcastPeers, int depthInBlocks);
|
||||
|
||||
void onCoinsReceived(BigInteger newBalance);
|
||||
}
|
||||
|
||||
}
|
@ -17,7 +17,6 @@ import io.bitsquare.msg.TradeMessage;
|
||||
import io.bitsquare.trade.Direction;
|
||||
import io.bitsquare.trade.Trading;
|
||||
import io.bitsquare.user.User;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.value.ChangeListener;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.FXCollections;
|
||||
@ -41,7 +40,7 @@ import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class MainController implements Initializable, NavigationController, WalletFacade.DownloadListener
|
||||
public class MainController implements Initializable, NavigationController
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(MainController.class);
|
||||
|
||||
@ -97,7 +96,21 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
|
||||
messageFacade.init();
|
||||
|
||||
walletFacade.addDownloadListener(this);
|
||||
walletFacade.addDownloadListener(new WalletFacade.DownloadListener()
|
||||
{
|
||||
@Override
|
||||
public void progress(double percent, int blocksSoFar, Date date)
|
||||
{
|
||||
networkSyncPane.setProgress(percent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doneDownload()
|
||||
{
|
||||
networkSyncPane.doneDownload();
|
||||
}
|
||||
});
|
||||
|
||||
walletFacade.initWallet();
|
||||
|
||||
if (user.getAccountID() == null)
|
||||
@ -183,25 +196,6 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Interface implementation: WalletFacade.DownloadListener
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public void progress(double percent, int blocksSoFar, Date date)
|
||||
{
|
||||
if (networkSyncPane != null)
|
||||
Platform.runLater(() -> networkSyncPane.setProgress(percent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doneDownload()
|
||||
{
|
||||
if (networkSyncPane != null)
|
||||
Platform.runLater(networkSyncPane::doneDownload);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -339,16 +333,19 @@ public class MainController implements Initializable, NavigationController, Wall
|
||||
@Override
|
||||
public void onTransactionConfidenceChanged(Wallet wallet, Transaction tx)
|
||||
{
|
||||
balanceTextField.setText(Utils.bitcoinValueToFriendlyString(walletFacade.getWallet().getBalance()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance)
|
||||
{
|
||||
balanceTextField.setText(Utils.bitcoinValueToFriendlyString(newBalance));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReorganize(Wallet wallet)
|
||||
{
|
||||
balanceTextField.setText(Utils.bitcoinValueToFriendlyString(walletFacade.getWallet().getBalance()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,10 +94,10 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
|
||||
|
||||
//TODO
|
||||
amountTextField.setText("1");
|
||||
minAmountTextField.setText("0,1");
|
||||
priceTextField.setText("500");
|
||||
collateralTextField.setText("10");
|
||||
amountTextField.setText("0,1");
|
||||
minAmountTextField.setText("0,001");
|
||||
priceTextField.setText("300");
|
||||
collateralTextField.setText("50");
|
||||
updateVolume();
|
||||
|
||||
amountTextField.textProperty().addListener(new ChangeListener<String>()
|
||||
@ -132,7 +132,7 @@ public class CreateOfferController implements Initializable, ChildController
|
||||
bankAccountCountyTextField.setText(user.getCurrentBankAccount().getCountryLocale().getDisplayCountry());
|
||||
acceptedCountriesTextField.setText(Formatter.countryLocalesToString(settings.getAcceptedCountryLocales()));
|
||||
acceptedLanguagesTextField.setText(Formatter.languageLocalesToString(settings.getAcceptedLanguageLocales()));
|
||||
feeLabel.setText(Utils.bitcoinValueToFriendlyString(Fees.OFFER_CREATION_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE)));
|
||||
feeLabel.setText(Utils.bitcoinValueToFriendlyString(Fees.OFFER_CREATION_FEE));
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,6 +6,7 @@ import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.UUID;
|
||||
|
||||
//TODO refactor
|
||||
public class TradeMessage implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 7916445031849763995L;
|
||||
@ -21,6 +22,8 @@ public class TradeMessage implements Serializable
|
||||
private String takerPayoutAddress;
|
||||
private TradeMessageType type;
|
||||
private String depositTxID;
|
||||
private String depositTxAsHex;
|
||||
|
||||
private String offererSignatureR;
|
||||
private String offererSignatureS;
|
||||
private BigInteger offererPaybackAmount;
|
||||
@ -94,11 +97,11 @@ public class TradeMessage implements Serializable
|
||||
uid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public TradeMessage(TradeMessageType type, String offerUID, String depositTxID)
|
||||
public TradeMessage(TradeMessageType type, String offerUID, String depositTxAsHex)
|
||||
{
|
||||
this.offerUID = offerUID;
|
||||
this.type = type;
|
||||
this.depositTxID = depositTxID;
|
||||
this.depositTxAsHex = depositTxAsHex;
|
||||
|
||||
uid = UUID.randomUUID().toString();
|
||||
}
|
||||
@ -106,7 +109,7 @@ public class TradeMessage implements Serializable
|
||||
// 3.10
|
||||
|
||||
public TradeMessage(TradeMessageType type, String offerUID,
|
||||
String depositTxID,
|
||||
String depositTxAsHex,
|
||||
String offererSignatureR,
|
||||
String offererSignatureS,
|
||||
BigInteger offererPaybackAmount,
|
||||
@ -115,7 +118,7 @@ public class TradeMessage implements Serializable
|
||||
{
|
||||
this.offerUID = offerUID;
|
||||
this.type = type;
|
||||
this.depositTxID = depositTxID;
|
||||
this.depositTxAsHex = depositTxAsHex;
|
||||
this.offererSignatureR = offererSignatureR;
|
||||
this.offererSignatureS = offererSignatureS;
|
||||
this.offererPaybackAmount = offererPaybackAmount;
|
||||
@ -252,4 +255,8 @@ public class TradeMessage implements Serializable
|
||||
}
|
||||
|
||||
|
||||
public String getDepositTxAsHex()
|
||||
{
|
||||
return depositTxAsHex;
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import java.math.BigInteger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
||||
//TODO refactor to process based pattern
|
||||
public class OffererPaymentProtocol
|
||||
{
|
||||
|
||||
@ -407,7 +407,7 @@ public class OffererPaymentProtocol
|
||||
try
|
||||
{
|
||||
log.debug("3.4 offererSignAndSendTx");
|
||||
depositTransaction = walletFacade.offererSignAndSendTx(preparedOffererDepositTxAsHex, signedTakerDepositTxAsHex, txConnOutAsHex, txScriptSigAsHex, callback);
|
||||
depositTransaction = walletFacade.offererSignAndPublishTx(preparedOffererDepositTxAsHex, signedTakerDepositTxAsHex, txConnOutAsHex, txScriptSigAsHex, callback);
|
||||
} catch (Exception e)
|
||||
{
|
||||
log.error("3.4 error at walletFacade.offererSignAndSendTx: " + e.getMessage());
|
||||
@ -440,7 +440,7 @@ public class OffererPaymentProtocol
|
||||
offererPaymentProtocolListener.onFailure("sendDepositTxAndDataForContract onSendTradingMessageFailed");
|
||||
}
|
||||
};
|
||||
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.DEPOSIT_TX_PUBLISHED, trade.getUid(), transaction.getHashAsString());
|
||||
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.DEPOSIT_TX_PUBLISHED, trade.getUid(), Utils.bytesToHexString(transaction.bitcoinSerialize()));
|
||||
log.debug("3.5 sendTradingMessage");
|
||||
messageFacade.sendTradeMessage(peerAddress, tradeMessage, listener);
|
||||
|
||||
@ -554,24 +554,23 @@ public class OffererPaymentProtocol
|
||||
log.debug("takerPaybackAmount " + takerPaybackAmount.toString());
|
||||
log.debug("depositTransaction.getHashAsString() " + depositTransaction.getHashAsString());
|
||||
log.debug("takerPayoutAddress " + takerPayoutAddress);
|
||||
log.debug("walletFacade.offererCreateAndSignPayoutTx");
|
||||
Pair<ECKey.ECDSASignature, Transaction> result = walletFacade.offererCreateAndSignPayoutTx(depositTransaction.getHashAsString(), offererPaybackAmount, takerPaybackAmount, takerPayoutAddress);
|
||||
log.debug("walletFacade.offererCreatesAndSignsPayoutTx");
|
||||
Pair<ECKey.ECDSASignature, String> result = walletFacade.offererCreatesAndSignsPayoutTx(depositTransaction.getHashAsString(), offererPaybackAmount, takerPaybackAmount, takerPayoutAddress);
|
||||
|
||||
ECKey.ECDSASignature offererSignature = result.getKey();
|
||||
String offererSignatureR = offererSignature.r.toString();
|
||||
String offererSignatureS = offererSignature.s.toString();
|
||||
Transaction depositTx = result.getValue();
|
||||
String depositTxID = Utils.bytesToHexString(depositTx.bitcoinSerialize());
|
||||
String depositTxAsHex = result.getValue();
|
||||
String offererPayoutAddress = walletFacade.getTradingAddress();
|
||||
TradeMessage tradeMessage = new TradeMessage(TradeMessageType.BANK_TX_INITED, trade.getUid(),
|
||||
depositTxID,
|
||||
depositTxAsHex,
|
||||
offererSignatureR,
|
||||
offererSignatureS,
|
||||
offererPaybackAmount,
|
||||
takerPaybackAmount,
|
||||
offererPayoutAddress);
|
||||
|
||||
log.debug("depositTxID " + depositTxID);
|
||||
log.debug("depositTxAsHex " + depositTxAsHex);
|
||||
log.debug("offererSignatureR " + offererSignatureR);
|
||||
log.debug("offererSignatureS " + offererSignatureS);
|
||||
log.debug("offererPaybackAmount " + offererPaybackAmount.toString());
|
||||
@ -583,10 +582,10 @@ public class OffererPaymentProtocol
|
||||
|
||||
} catch (InsufficientMoneyException e)
|
||||
{
|
||||
log.error("3.10 offererCreateAndSignPayoutTx onFailed InsufficientMoneyException " + e.getMessage());
|
||||
log.error("3.10 offererCreatesAndSignsPayoutTx onFailed InsufficientMoneyException " + e.getMessage());
|
||||
} catch (AddressFormatException e)
|
||||
{
|
||||
log.error("3.10 offererCreateAndSignPayoutTx onFailed AddressFormatException " + e.getMessage());
|
||||
log.error("3.10 offererCreatesAndSignsPayoutTx onFailed AddressFormatException " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
||||
//TODO refactor to process based pattern
|
||||
public class TakerPaymentProtocol
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(TakerPaymentProtocol.class);
|
||||
@ -387,7 +387,7 @@ public class TakerPaymentProtocol
|
||||
log.debug("preparedOffererDepositTxAsHex " + preparedOffererDepositTxAsHex);
|
||||
try
|
||||
{
|
||||
Transaction signedTakerDepositTx = walletFacade.takerAddPaymentAndSign(takerInputAmount, msOutputAmount, offererPubKey, takerPubKey, arbitratorPubKey, preparedOffererDepositTxAsHex);
|
||||
Transaction signedTakerDepositTx = walletFacade.takerAddPaymentAndSignTx(takerInputAmount, msOutputAmount, offererPubKey, takerPubKey, arbitratorPubKey, preparedOffererDepositTxAsHex);
|
||||
log.debug("2.10 deposit tx created: " + signedTakerDepositTx);
|
||||
sendSignedTakerDepositTxAsHex(signedTakerDepositTx);
|
||||
} catch (InterruptedException | AddressFormatException | ExecutionException | InsufficientMoneyException e)
|
||||
@ -469,13 +469,11 @@ public class TakerPaymentProtocol
|
||||
|
||||
public void onDepositTxPublished(TradeMessage tradeMessage)
|
||||
{
|
||||
log.debug("3.6 DepositTxID received: " + tradeMessage.getDepositTxID());
|
||||
|
||||
//Transaction tx = walletFacade.getWallet().getTransaction(new Sha256Hash(tradeMessage.getDepositTxID()));
|
||||
//walletFacade.getWallet().commitTx(tx);
|
||||
log.debug("3.6 DepositTxID received: " + tradeMessage.getDepositTxAsHex());
|
||||
|
||||
walletFacade.takerCommitDepositTx(tradeMessage.getDepositTxAsHex());
|
||||
takerPaymentProtocolListener.onProgress(getProgress());
|
||||
takerPaymentProtocolListener.onDepositTxPublished(tradeMessage.getDepositTxID());
|
||||
takerPaymentProtocolListener.onDepositTxPublished(tradeMessage.getDepositTxAsHex());
|
||||
}
|
||||
|
||||
|
||||
@ -511,8 +509,8 @@ public class TakerPaymentProtocol
|
||||
@Override
|
||||
public void onSuccess(Transaction transaction)
|
||||
{
|
||||
System.out.println("######### 3.12 onSuccess walletFacade.takerSignAndSendTx " + transaction.toString());
|
||||
log.error("3.12 onSuccess walletFacade.takerSignAndSendTx " + transaction.toString());
|
||||
System.out.println("######### 3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction.toString());
|
||||
log.debug("3.12 onSuccess walletFacade.takerSignsAndSendsTx " + transaction.toString());
|
||||
takerPaymentProtocolListener.onTradeCompleted(transaction.getHashAsString());
|
||||
|
||||
sendPayoutTxToOfferer(transaction.getHashAsString());
|
||||
@ -521,22 +519,22 @@ public class TakerPaymentProtocol
|
||||
@Override
|
||||
public void onFailure(Throwable t)
|
||||
{
|
||||
log.error("######### 3.12 onFailure walletFacade.takerSignAndSendTx");
|
||||
System.err.println("3.12 onFailure walletFacade.takerSignAndSendTx");
|
||||
takerPaymentProtocolListener.onFailure("takerSignAndSendTx failed " + t.getMessage());
|
||||
log.error("######### 3.12 onFailure walletFacade.takerSignsAndSendsTx");
|
||||
System.err.println("3.12 onFailure walletFacade.takerSignsAndSendsTx");
|
||||
takerPaymentProtocolListener.onFailure("takerSignsAndSendsTx failed " + t.getMessage());
|
||||
}
|
||||
};
|
||||
try
|
||||
{
|
||||
String depositTxID = tradeMessage.getDepositTxID();
|
||||
String depositTxAsHex = tradeMessage.getDepositTxAsHex();
|
||||
String offererSignatureR = tradeMessage.getOffererSignatureR();
|
||||
String offererSignatureS = tradeMessage.getOffererSignatureS();
|
||||
BigInteger offererPaybackAmount = tradeMessage.getOffererPaybackAmount();
|
||||
BigInteger takerPaybackAmount = tradeMessage.getTakerPaybackAmount();
|
||||
String offererPayoutAddress = tradeMessage.getOffererPayoutAddress();
|
||||
|
||||
log.debug("3.12 walletFacade.takerSignAndSendTx");
|
||||
walletFacade.takerSignAndSendTx(depositTxID,
|
||||
log.debug("3.12 walletFacade.takerSignsAndSendsTx");
|
||||
walletFacade.takerSignsAndSendsTx(depositTxAsHex,
|
||||
offererSignatureR,
|
||||
offererSignatureS,
|
||||
offererPaybackAmount,
|
||||
@ -545,10 +543,10 @@ public class TakerPaymentProtocol
|
||||
callback);
|
||||
} catch (InsufficientMoneyException e)
|
||||
{
|
||||
log.error("3.12 offererCreateAndSignPayoutTx onFailed InsufficientMoneyException " + e.getMessage());
|
||||
log.error("3.12 offererCreatesAndSignsPayoutTx onFailed InsufficientMoneyException " + e.getMessage());
|
||||
} catch (AddressFormatException e)
|
||||
{
|
||||
log.error("3.12 offererCreateAndSignPayoutTx onFailed AddressFormatException " + e.getMessage());
|
||||
log.error("3.12 offererCreatesAndSignsPayoutTx onFailed AddressFormatException " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,17 @@
|
||||
<appender-ref ref="CONSOLE_APPENDER"/>
|
||||
</root>
|
||||
|
||||
<logger name="io.bitsquare" level="DEBUG"/>
|
||||
<logger name="io.bitsquare" level="TRACE"/>
|
||||
|
||||
<logger name="com.google.bitcoin" level="INFO"/>
|
||||
<logger name="com.google.bitcoin" level="TRACE"/>
|
||||
<logger name="net.tomp2p" level="WARN"/>
|
||||
|
||||
<!--
|
||||
-->
|
||||
|
||||
<logger name="com.google.bitcoin.core.DownloadListener" level="WARN" additivity="false"/>
|
||||
<logger name="com.google.bitcoin.core.TransactionOutput" level="INFO" additivity="false"/>
|
||||
<logger name="com.google.bitcoin.core.BitcoinSerializer" level="WARN" additivity="false"/>
|
||||
<logger name="com.google.bitcoin.core.Peer" level="ERROR" additivity="false"/>
|
||||
<logger name="com.google.bitcoin.core.PeerGroup" level="ERROR" additivity="false"/>
|
||||
<logger name="com.google.bitcoin.core.PeerSocketHandler" level="OFF" additivity="false"/>
|
||||
|
Loading…
Reference in New Issue
Block a user