use of org.bitcoinj.crypto.DeterministicKey in project bitsquare by bitsquare.
the class AddressEntryList method onWalletReady.
public void onWalletReady(Wallet wallet) {
this.wallet = wallet;
AddressEntryList persisted = storage.initAndGetPersisted(this);
if (persisted != null) {
for (AddressEntry addressEntry : persisted) {
DeterministicKey keyFromPubHash = (DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash());
if (keyFromPubHash != null) {
addressEntry.setDeterministicKey(keyFromPubHash);
add(addressEntry);
} else {
log.warn("Key from addressEntry not found in that wallet " + addressEntry.toString());
}
}
} else {
add(new AddressEntry(wallet.freshReceiveKey(), wallet.getParams(), AddressEntry.Context.ARBITRATOR));
storage.queueUpForSave();
}
}
use of org.bitcoinj.crypto.DeterministicKey in project bisq-core by bisq-network.
the class DisputeManager method onDisputeResultMessage.
// We get that message at both peers. The dispute object is in context of the trader
private void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
DisputeResult disputeResult = disputeResultMessage.getDisputeResult();
if (!isArbitrator(disputeResult)) {
final String tradeId = disputeResult.getTradeId();
Optional<Dispute> disputeOptional = findDispute(tradeId, disputeResult.getTraderId());
final String uid = disputeResultMessage.getUid();
if (disputeOptional.isPresent()) {
cleanupRetryMap(uid);
Dispute dispute = disputeOptional.get();
DisputeCommunicationMessage disputeCommunicationMessage = disputeResult.getDisputeCommunicationMessage();
if (!dispute.getDisputeCommunicationMessages().contains(disputeCommunicationMessage))
dispute.addDisputeMessage(disputeCommunicationMessage);
else
log.warn("We got a dispute mail msg what we have already stored. TradeId = " + disputeCommunicationMessage.getTradeId());
dispute.setIsClosed(true);
if (dispute.disputeResultProperty().get() != null)
log.warn("We got already a dispute result. That should only happen if a dispute needs to be closed " + "again because the first close did not succeed. TradeId = " + tradeId);
dispute.setDisputeResult(disputeResult);
// We need to avoid publishing the tx from both traders as it would create problems with zero confirmation withdrawals
// There would be different transactions if both sign and publish (signers: once buyer+arb, once seller+arb)
// The tx publisher is the winner or in case both get 50% the buyer, as the buyer has more inventive to publish the tx as he receives
// more BTC as he has deposited
final Contract contract = dispute.getContract();
boolean isBuyer = keyRing.getPubKeyRing().equals(contract.getBuyerPubKeyRing());
DisputeResult.Winner publisher = disputeResult.getWinner();
// Default isLoserPublisher is set to false
if (disputeResult.isLoserPublisher()) {
// we invert the logic
if (publisher == DisputeResult.Winner.BUYER)
publisher = DisputeResult.Winner.SELLER;
else if (publisher == DisputeResult.Winner.SELLER)
publisher = DisputeResult.Winner.BUYER;
}
if ((isBuyer && publisher == DisputeResult.Winner.BUYER) || (!isBuyer && publisher == DisputeResult.Winner.SELLER)) {
final Optional<Trade> tradeOptional = tradeManager.getTradeById(tradeId);
Transaction payoutTx = null;
if (tradeOptional.isPresent()) {
payoutTx = tradeOptional.get().getPayoutTx();
} else {
final Optional<Tradable> tradableOptional = closedTradableManager.getTradableById(tradeId);
if (tradableOptional.isPresent() && tradableOptional.get() instanceof Trade) {
payoutTx = ((Trade) tradableOptional.get()).getPayoutTx();
}
}
if (payoutTx == null) {
if (dispute.getDepositTxSerialized() != null) {
try {
log.debug("do payout Transaction ");
byte[] multiSigPubKey = isBuyer ? contract.getBuyerMultiSigPubKey() : contract.getSellerMultiSigPubKey();
DeterministicKey multiSigKeyPair = walletService.getMultiSigKeyPair(dispute.getTradeId(), multiSigPubKey);
Transaction signedDisputedPayoutTx = tradeWalletService.traderSignAndFinalizeDisputedPayoutTx(dispute.getDepositTxSerialized(), disputeResult.getArbitratorSignature(), disputeResult.getBuyerPayoutAmount(), disputeResult.getSellerPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), multiSigKeyPair, contract.getBuyerMultiSigPubKey(), contract.getSellerMultiSigPubKey(), disputeResult.getArbitratorPubKey());
Transaction committedDisputedPayoutTx = tradeWalletService.addTxToWallet(signedDisputedPayoutTx);
log.debug("broadcast committedDisputedPayoutTx");
tradeWalletService.broadcastTx(committedDisputedPayoutTx, new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.debug("BroadcastTx succeeded. Transaction:" + transaction);
// after successful publish we send peer the tx
dispute.setDisputePayoutTxId(transaction.getHashAsString());
sendPeerPublishedPayoutTxMessage(transaction, dispute, contract);
// set state after payout as we call swapTradeEntryToAvailableEntry
if (tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
else {
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(dispute.getTradeId());
if (openOfferOptional.isPresent())
openOfferManager.closeOpenOffer(openOfferOptional.get().getOffer());
}
}
@Override
public void onFailure(@NotNull Throwable t) {
log.error(t.getMessage());
}
}, 15);
} catch (AddressFormatException | WalletException | TransactionVerificationException e) {
e.printStackTrace();
log.error("Error at traderSignAndFinalizeDisputedPayoutTx " + e.getMessage());
throw new RuntimeException("Error at traderSignAndFinalizeDisputedPayoutTx " + e.toString());
}
} else {
log.warn("DepositTx is null. TradeId = " + tradeId);
}
} else {
log.warn("We got already a payout tx. That might be the case if the other peer did not get the " + "payout tx and opened a dispute. TradeId = " + tradeId);
dispute.setDisputePayoutTxId(payoutTx.getHashAsString());
sendPeerPublishedPayoutTxMessage(payoutTx, dispute, contract);
}
} else {
log.trace("We don't publish the tx as we are not the winning party.");
// Clean up tangling trades
if (dispute.disputeResultProperty().get() != null && dispute.isClosed() && tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
}
} else {
log.debug("We got a dispute result msg but we don't have a matching dispute. " + "That might happen when we get the disputeResultMessage before the dispute was created. " + "We try again after 2 sec. to apply the disputeResultMessage. TradeId = " + tradeId);
if (!delayMsgMap.containsKey(uid)) {
// We delay2 sec. to be sure the comm. msg gets added first
Timer timer = UserThread.runAfter(() -> onDisputeResultMessage(disputeResultMessage), 2);
delayMsgMap.put(uid, timer);
} else {
log.warn("We got a dispute result msg after we already repeated to apply the message after a delay. " + "That should never happen. TradeId = " + tradeId);
}
}
} else {
log.error("Arbitrator received disputeResultMessage. That must never happen.");
}
}
use of org.bitcoinj.crypto.DeterministicKey in project bisq-core by bisq-network.
the class GenericProposalService method prepareGenericProposal.
// TODO move code to consensus package
public GenericProposal prepareGenericProposal(GenericProposalPayload genericProposalPayload) throws InsufficientMoneyException, ChangeBelowDustException, TransactionVerificationException, WalletException {
GenericProposal compensationRequest = new GenericProposal(genericProposalPayload);
final Transaction preparedBurnFeeTx = bsqWalletService.getPreparedBurnFeeTx(ProposalConsensus.getCreateCompensationRequestFee(readableBsqBlockChain));
checkArgument(!preparedBurnFeeTx.getInputs().isEmpty(), "preparedTx inputs must not be empty");
// We use the key of the first BSQ input for signing the data
TransactionOutput connectedOutput = preparedBurnFeeTx.getInputs().get(0).getConnectedOutput();
checkNotNull(connectedOutput, "connectedOutput must not be null");
DeterministicKey bsqKeyPair = bsqWalletService.findKeyFromPubKeyHash(connectedOutput.getScriptPubKey().getPubKeyHash());
checkNotNull(bsqKeyPair, "bsqKeyPair must not be null");
// We get the JSON of the object excluding signature and feeTxId
String payloadAsJson = StringUtils.deleteWhitespace(Utilities.objectToJson(genericProposalPayload));
// Signs a text message using the standard Bitcoin messaging signing format and returns the signature as a base64
// encoded string.
String signature = bsqKeyPair.signMessage(payloadAsJson);
genericProposalPayload.setSignature(signature);
String dataAndSig = payloadAsJson + signature;
byte[] opReturnData = OpReturnData.getBytes(dataAndSig);
final Transaction txWithBtcFee = btcWalletService.completePreparedGenericProposalTx(preparedBurnFeeTx, opReturnData);
compensationRequest.setTx(bsqWalletService.signTx(txWithBtcFee));
return compensationRequest;
}
use of org.bitcoinj.crypto.DeterministicKey in project bisq-core by bisq-network.
the class BtcWalletService method getMultiSigKeyPair.
public DeterministicKey getMultiSigKeyPair(String tradeId, byte[] pubKey) {
Optional<AddressEntry> multiSigAddressEntryOptional = getAddressEntry(tradeId, AddressEntry.Context.MULTI_SIG);
DeterministicKey multiSigKeyPair;
if (multiSigAddressEntryOptional.isPresent()) {
AddressEntry multiSigAddressEntry = multiSigAddressEntryOptional.get();
multiSigKeyPair = multiSigAddressEntry.getKeyPair();
if (!Arrays.equals(pubKey, multiSigAddressEntry.getPubKey())) {
log.error("Pub Key from AddressEntry does not match key pair from trade data. Trade ID={}\n" + "We try to find the keypair in the wallet with the pubKey we found in the trade data.", tradeId);
multiSigKeyPair = findKeyFromPubKey(pubKey);
}
} else {
log.error("multiSigAddressEntry not found for trade ID={}.\n" + "We try to find the keypair in the wallet with the pubKey we found in the trade data.", tradeId);
multiSigKeyPair = findKeyFromPubKey(pubKey);
}
return multiSigKeyPair;
}
use of org.bitcoinj.crypto.DeterministicKey in project bisq-core by bisq-network.
the class AddressEntryList method onWalletReady.
// /////////////////////////////////////////////////////////////////////////////////////////
// API
// /////////////////////////////////////////////////////////////////////////////////////////
public void onWalletReady(Wallet wallet) {
this.wallet = wallet;
if (list != null) {
list.forEach(addressEntry -> {
DeterministicKey keyFromPubHash = (DeterministicKey) wallet.findKeyFromPubHash(addressEntry.getPubKeyHash());
if (keyFromPubHash != null) {
addressEntry.setDeterministicKey(keyFromPubHash);
} else {
log.error("Key from addressEntry not found in that wallet " + addressEntry.toString());
}
});
} else {
list = new ArrayList<>();
add(new AddressEntry(wallet.freshReceiveKey(), AddressEntry.Context.ARBITRATOR));
// In case we restore from seed words and have balance we need to add the relevant addresses to our list:
if (wallet.getBalance().isPositive()) {
wallet.getIssuedReceiveAddresses().forEach(address -> {
log.info("Create AddressEntry for address={}", address);
add(new AddressEntry((DeterministicKey) wallet.findKeyFromPubHash(address.getHash160()), AddressEntry.Context.AVAILABLE));
});
}
persist();
}
}
Aggregations