mirror of
https://github.com/boldsuck/haveno.git
synced 2024-12-22 20:19:21 +00:00
re-export multisig hex on create multisig tx or open dispute
This commit is contained in:
parent
d4a9838cd8
commit
79cd9f3e82
9 changed files with 120 additions and 104 deletions
|
@ -112,7 +112,7 @@ public class CoreDisputesService {
|
||||||
|
|
||||||
// Sends the openNewDisputeMessage to arbitrator, who will then create 2 disputes
|
// Sends the openNewDisputeMessage to arbitrator, who will then create 2 disputes
|
||||||
// one for the opener, the other for the peer, see sendPeerOpenedDisputeMessage.
|
// one for the opener, the other for the peer, see sendPeerOpenedDisputeMessage.
|
||||||
disputeManager.sendDisputeOpenedMessage(dispute, false, trade.getSelf().getUpdatedMultisigHex(), resultHandler, faultHandler);
|
disputeManager.sendDisputeOpenedMessage(dispute, false, resultHandler, faultHandler);
|
||||||
tradeManager.requestPersistence();
|
tradeManager.requestPersistence();
|
||||||
}, trade.getId());
|
}, trade.getId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,6 +157,11 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
disputeListService.requestPersistence();
|
disputeListService.requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void requestPersistence(Trade trade) {
|
||||||
|
trade.requestPersistence();
|
||||||
|
disputeListService.requestPersistence();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeAddress getPeerNodeAddress(ChatMessage message) {
|
public NodeAddress getPeerNodeAddress(ChatMessage message) {
|
||||||
Optional<Dispute> disputeOptional = findDispute(message);
|
Optional<Dispute> disputeOptional = findDispute(message);
|
||||||
|
@ -322,7 +327,6 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
// trader sends message to arbitrator to open dispute
|
// trader sends message to arbitrator to open dispute
|
||||||
public void sendDisputeOpenedMessage(Dispute dispute,
|
public void sendDisputeOpenedMessage(Dispute dispute,
|
||||||
boolean reOpen,
|
boolean reOpen,
|
||||||
String updatedMultisigHex,
|
|
||||||
ResultHandler resultHandler,
|
ResultHandler resultHandler,
|
||||||
FaultHandler faultHandler) {
|
FaultHandler faultHandler) {
|
||||||
|
|
||||||
|
@ -372,12 +376,13 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
}
|
}
|
||||||
|
|
||||||
// create dispute opened message
|
// create dispute opened message
|
||||||
|
trade.exportMultisigHex();
|
||||||
NodeAddress agentNodeAddress = getAgentNodeAddress(dispute);
|
NodeAddress agentNodeAddress = getAgentNodeAddress(dispute);
|
||||||
DisputeOpenedMessage disputeOpenedMessage = new DisputeOpenedMessage(dispute,
|
DisputeOpenedMessage disputeOpenedMessage = new DisputeOpenedMessage(dispute,
|
||||||
p2PService.getAddress(),
|
p2PService.getAddress(),
|
||||||
UUID.randomUUID().toString(),
|
UUID.randomUUID().toString(),
|
||||||
getSupportType(),
|
getSupportType(),
|
||||||
updatedMultisigHex,
|
trade.getSelf().getUpdatedMultisigHex(),
|
||||||
trade.getArbitrator().getPaymentSentMessage());
|
trade.getArbitrator().getPaymentSentMessage());
|
||||||
log.info("Send {} to peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
log.info("Send {} to peer {}. tradeId={}, openNewDisputeMessage.uid={}, " +
|
||||||
"chatMessage.uid={}",
|
"chatMessage.uid={}",
|
||||||
|
@ -792,7 +797,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
disputeResult.getChatMessage().setArrived(true);
|
disputeResult.getChatMessage().setArrived(true);
|
||||||
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SAW_ARRIVED_DISPUTE_CLOSED_MSG);
|
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SAW_ARRIVED_DISPUTE_CLOSED_MSG);
|
||||||
trade.pollWalletNormallyForMs(30000);
|
trade.pollWalletNormallyForMs(30000);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -811,7 +816,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
disputeResult.getChatMessage().setStoredInMailbox(true);
|
disputeResult.getChatMessage().setStoredInMailbox(true);
|
||||||
Trade trade = tradeManager.getTrade(dispute.getTradeId());
|
Trade trade = tradeManager.getTrade(dispute.getTradeId());
|
||||||
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_STORED_IN_MAILBOX_DISPUTE_CLOSED_MSG);
|
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_STORED_IN_MAILBOX_DISPUTE_CLOSED_MSG);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
resultHandler.handleResult();
|
resultHandler.handleResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,13 +833,13 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
// the state, as that is displayed to the user and we only persist that msg
|
// the state, as that is displayed to the user and we only persist that msg
|
||||||
disputeResult.getChatMessage().setSendMessageError(errorMessage);
|
disputeResult.getChatMessage().setSendMessageError(errorMessage);
|
||||||
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SEND_FAILED_DISPUTE_CLOSED_MSG);
|
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SEND_FAILED_DISPUTE_CLOSED_MSG);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
faultHandler.handleFault(errorMessage, new RuntimeException(errorMessage));
|
faultHandler.handleFault(errorMessage, new RuntimeException(errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SENT_DISPUTE_CLOSED_MSG);
|
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SENT_DISPUTE_CLOSED_MSG);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
faultHandler.handleFault(e.getMessage(), e);
|
faultHandler.handleFault(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -900,11 +905,11 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||||
// update trade state
|
// update trade state
|
||||||
if (updateState) {
|
if (updateState) {
|
||||||
trade.getProcessModel().setUnsignedPayoutTx(payoutTx);
|
trade.getProcessModel().setUnsignedPayoutTx(payoutTx);
|
||||||
trade.getSelf().setUpdatedMultisigHex(trade.getWallet().exportMultisigHex());
|
|
||||||
trade.updatePayout(payoutTx);
|
trade.updatePayout(payoutTx);
|
||||||
if (trade.getBuyer().getUpdatedMultisigHex() != null && trade.getBuyer().getUnsignedPayoutTxHex() == null) trade.getBuyer().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
if (trade.getBuyer().getUpdatedMultisigHex() != null && trade.getBuyer().getUnsignedPayoutTxHex() == null) trade.getBuyer().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
||||||
if (trade.getSeller().getUpdatedMultisigHex() != null && trade.getSeller().getUnsignedPayoutTxHex() == null) trade.getSeller().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
if (trade.getSeller().getUpdatedMultisigHex() != null && trade.getSeller().getUnsignedPayoutTxHex() == null) trade.getSeller().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
||||||
}
|
}
|
||||||
|
trade.requestPersistence();
|
||||||
return payoutTx;
|
return payoutTx;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
trade.syncAndPollWallet();
|
trade.syncAndPollWallet();
|
||||||
|
|
|
@ -252,7 +252,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
|
|
||||||
// save dispute closed message for reprocessing
|
// save dispute closed message for reprocessing
|
||||||
trade.getArbitrator().setDisputeClosedMessage(disputeClosedMessage);
|
trade.getArbitrator().setDisputeClosedMessage(disputeClosedMessage);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
|
|
||||||
// verify arbitrator does not receive DisputeClosedMessage
|
// verify arbitrator does not receive DisputeClosedMessage
|
||||||
if (keyRing.getPubKeyRing().equals(dispute.getAgentPubKeyRing())) {
|
if (keyRing.getPubKeyRing().equals(dispute.getAgentPubKeyRing())) {
|
||||||
|
@ -326,17 +326,17 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
// We use the chatMessage as we only persist those not the DisputeClosedMessage.
|
// We use the chatMessage as we only persist those not the DisputeClosedMessage.
|
||||||
// If we would use the DisputeClosedMessage we could not lookup for the msg when we receive the AckMessage.
|
// If we would use the DisputeClosedMessage we could not lookup for the msg when we receive the AckMessage.
|
||||||
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), true, null);
|
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), true, null);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Error processing dispute closed message: " + e.getMessage());
|
log.warn("Error processing dispute closed message: " + e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
|
|
||||||
// nack bad message and do not reprocess
|
// nack bad message and do not reprocess
|
||||||
if (e instanceof IllegalArgumentException) {
|
if (e instanceof IllegalArgumentException) {
|
||||||
trade.getArbitrator().setDisputeClosedMessage(null); // message is processed
|
trade.getArbitrator().setDisputeClosedMessage(null); // message is processed
|
||||||
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), false, e.getMessage());
|
sendAckMessage(chatMessage, dispute.getAgentPubKeyRing(), false, e.getMessage());
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
String signedMultisigTxHex = result.getSignedMultisigTxHex();
|
String signedMultisigTxHex = result.getSignedMultisigTxHex();
|
||||||
disputeTxSet.setMultisigTxHex(signedMultisigTxHex);
|
disputeTxSet.setMultisigTxHex(signedMultisigTxHex);
|
||||||
trade.setPayoutTxHex(signedMultisigTxHex);
|
trade.setPayoutTxHex(signedMultisigTxHex);
|
||||||
requestPersistence();
|
requestPersistence(trade);
|
||||||
|
|
||||||
// verify mining fee is within tolerance by recreating payout tx
|
// verify mining fee is within tolerance by recreating payout tx
|
||||||
// TODO (monero-project): creating tx will require exchanging updated multisig hex if message needs reprocessed. provide weight with describe_transfer so fee can be estimated?
|
// TODO (monero-project): creating tx will require exchanging updated multisig hex if message needs reprocessed. provide weight with describe_transfer so fee can be estimated?
|
||||||
|
@ -487,6 +487,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
|
||||||
trade.updatePayout(disputeTxSet.getTxs().get(0));
|
trade.updatePayout(disputeTxSet.getTxs().get(0));
|
||||||
trade.setPayoutState(Trade.PayoutState.PAYOUT_PUBLISHED);
|
trade.setPayoutState(Trade.PayoutState.PAYOUT_PUBLISHED);
|
||||||
dispute.setDisputePayoutTxId(disputeTxSet.getTxs().get(0).getHash());
|
dispute.setDisputePayoutTxId(disputeTxSet.getTxs().get(0).getHash());
|
||||||
|
requestPersistence(trade);
|
||||||
return disputeTxSet;
|
return disputeTxSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1058,11 +1058,21 @@ public abstract class Trade implements Tradable, Model {
|
||||||
public MoneroTxWallet createTx(MoneroTxConfig txConfig) {
|
public MoneroTxWallet createTx(MoneroTxConfig txConfig) {
|
||||||
synchronized (walletLock) {
|
synchronized (walletLock) {
|
||||||
synchronized (HavenoUtils.getWalletFunctionLock()) {
|
synchronized (HavenoUtils.getWalletFunctionLock()) {
|
||||||
return wallet.createTx(txConfig);
|
MoneroTxWallet tx = wallet.createTx(txConfig);
|
||||||
|
exportMultisigHex();
|
||||||
|
requestSaveWallet();
|
||||||
|
return tx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exportMultisigHex() {
|
||||||
|
synchronized (walletLock) {
|
||||||
|
getSelf().setUpdatedMultisigHex(wallet.exportMultisigHex());
|
||||||
|
requestPersistence();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void importMultisigHex() {
|
public void importMultisigHex() {
|
||||||
synchronized (walletLock) {
|
synchronized (walletLock) {
|
||||||
synchronized (HavenoUtils.getDaemonLock()) { // lock on daemon because import calls full refresh
|
synchronized (HavenoUtils.getDaemonLock()) { // lock on daemon because import calls full refresh
|
||||||
|
@ -1220,13 +1230,11 @@ public abstract class Trade implements Tradable, Model {
|
||||||
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY));
|
.setPriority(XmrWalletService.PROTOCOL_FEE_PRIORITY));
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
saveWallet();
|
|
||||||
BigInteger payoutTxFeeSplit = payoutTx.getFee().divide(BigInteger.valueOf(2));
|
BigInteger payoutTxFeeSplit = payoutTx.getFee().divide(BigInteger.valueOf(2));
|
||||||
getBuyer().setPayoutTxFee(payoutTxFeeSplit);
|
getBuyer().setPayoutTxFee(payoutTxFeeSplit);
|
||||||
getBuyer().setPayoutAmount(HavenoUtils.getDestination(buyerPayoutAddress, payoutTx).getAmount());
|
getBuyer().setPayoutAmount(HavenoUtils.getDestination(buyerPayoutAddress, payoutTx).getAmount());
|
||||||
getSeller().setPayoutTxFee(payoutTxFeeSplit);
|
getSeller().setPayoutTxFee(payoutTxFeeSplit);
|
||||||
getSeller().setPayoutAmount(HavenoUtils.getDestination(sellerPayoutAddress, payoutTx).getAmount());
|
getSeller().setPayoutAmount(HavenoUtils.getDestination(sellerPayoutAddress, payoutTx).getAmount());
|
||||||
getSelf().setUpdatedMultisigHex(wallet.exportMultisigHex());
|
|
||||||
return payoutTx;
|
return payoutTx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1273,6 +1281,9 @@ public abstract class Trade implements Tradable, Model {
|
||||||
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
|
if (i == TradeProtocol.MAX_ATTEMPTS - 1) throw e;
|
||||||
if (xmrConnectionService.isConnected()) requestSwitchToNextBestConnection();
|
if (xmrConnectionService.isConnected()) requestSwitchToNextBestConnection();
|
||||||
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
|
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
|
||||||
|
} finally {
|
||||||
|
requestSaveWallet();
|
||||||
|
requestPersistence();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,9 +64,9 @@ public class BuyerPreparePaymentSentMessage extends TradeTask {
|
||||||
|
|
||||||
// skip if payout tx already created
|
// skip if payout tx already created
|
||||||
if (trade.getSelf().getUnsignedPayoutTxHex() != null) {
|
if (trade.getSelf().getUnsignedPayoutTxHex() != null) {
|
||||||
log.warn("Skipping preparation of payment sent message because payout tx is already created for {} {}", trade.getClass().getSimpleName(), trade.getShortId());
|
log.warn("Skipping preparation of payment sent message because payout tx is already created for {} {}", trade.getClass().getSimpleName(), trade.getShortId());
|
||||||
complete();
|
complete();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate state
|
// validate state
|
||||||
|
@ -87,6 +87,7 @@ public class BuyerPreparePaymentSentMessage extends TradeTask {
|
||||||
MoneroTxWallet payoutTx = trade.createPayoutTx();
|
MoneroTxWallet payoutTx = trade.createPayoutTx();
|
||||||
trade.updatePayout(payoutTx);
|
trade.updatePayout(payoutTx);
|
||||||
trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
trade.getSelf().setUnsignedPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
||||||
|
trade.requestPersistence();
|
||||||
}
|
}
|
||||||
|
|
||||||
complete();
|
complete();
|
||||||
|
@ -107,101 +108,100 @@ public class BuyerPreparePaymentSentMessage extends TradeTask {
|
||||||
*/
|
*/
|
||||||
public static class Pair<F, S> {
|
public static class Pair<F, S> {
|
||||||
|
|
||||||
private F first;
|
private F first;
|
||||||
private S second;
|
private S second;
|
||||||
|
|
||||||
public Pair(F first, S second) {
|
public Pair(F first, S second) {
|
||||||
super();
|
super();
|
||||||
this.first = first;
|
this.first = first;
|
||||||
this.second = second;
|
this.second = second;
|
||||||
}
|
}
|
||||||
|
|
||||||
public F getFirst() {
|
public F getFirst() {
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFirst(F first) {
|
public void setFirst(F first) {
|
||||||
this.first = first;
|
this.first = first;
|
||||||
}
|
}
|
||||||
|
|
||||||
public S getSecond() {
|
public S getSecond() {
|
||||||
return second;
|
return second;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSecond(S second) {
|
public void setSecond(S second) {
|
||||||
this.second = second;
|
this.second = second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printBalances(MoneroWallet wallet) {
|
public static void printBalances(MoneroWallet wallet) {
|
||||||
|
|
||||||
// collect info about subaddresses
|
// collect info about subaddresses
|
||||||
List<Pair<String, List<Object>>> pairs = new ArrayList<Pair<String, List<Object>>>();
|
List<Pair<String, List<Object>>> pairs = new ArrayList<Pair<String, List<Object>>>();
|
||||||
//if (wallet == null) wallet = TestUtils.getWalletJni();
|
//if (wallet == null) wallet = TestUtils.getWalletJni();
|
||||||
BigInteger balance = wallet.getBalance();
|
BigInteger balance = wallet.getBalance();
|
||||||
BigInteger unlockedBalance = wallet.getUnlockedBalance();
|
BigInteger unlockedBalance = wallet.getUnlockedBalance();
|
||||||
List<MoneroAccount> accounts = wallet.getAccounts(true);
|
List<MoneroAccount> accounts = wallet.getAccounts(true);
|
||||||
System.out.println("Wallet balance: " + balance);
|
System.out.println("Wallet balance: " + balance);
|
||||||
System.out.println("Wallet unlocked balance: " + unlockedBalance);
|
System.out.println("Wallet unlocked balance: " + unlockedBalance);
|
||||||
for (MoneroAccount account : accounts) {
|
for (MoneroAccount account : accounts) {
|
||||||
add(pairs, "ACCOUNT", account.getIndex());
|
add(pairs, "ACCOUNT", account.getIndex());
|
||||||
add(pairs, "SUBADDRESS", "");
|
add(pairs, "SUBADDRESS", "");
|
||||||
add(pairs, "LABEL", "");
|
add(pairs, "LABEL", "");
|
||||||
add(pairs, "ADDRESS", "");
|
add(pairs, "ADDRESS", "");
|
||||||
add(pairs, "BALANCE", account.getBalance());
|
add(pairs, "BALANCE", account.getBalance());
|
||||||
add(pairs, "UNLOCKED", account.getUnlockedBalance());
|
add(pairs, "UNLOCKED", account.getUnlockedBalance());
|
||||||
for (MoneroSubaddress subaddress : account.getSubaddresses()) {
|
for (MoneroSubaddress subaddress : account.getSubaddresses()) {
|
||||||
add(pairs, "ACCOUNT", account.getIndex());
|
add(pairs, "ACCOUNT", account.getIndex());
|
||||||
add(pairs, "SUBADDRESS", subaddress.getIndex());
|
add(pairs, "SUBADDRESS", subaddress.getIndex());
|
||||||
add(pairs, "LABEL", subaddress.getLabel());
|
add(pairs, "LABEL", subaddress.getLabel());
|
||||||
add(pairs, "ADDRESS", subaddress.getAddress());
|
add(pairs, "ADDRESS", subaddress.getAddress());
|
||||||
add(pairs, "BALANCE", subaddress.getBalance());
|
add(pairs, "BALANCE", subaddress.getBalance());
|
||||||
add(pairs, "UNLOCKED", subaddress.getUnlockedBalance());
|
add(pairs, "UNLOCKED", subaddress.getUnlockedBalance());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// convert info to csv
|
// convert info to csv
|
||||||
Integer length = null;
|
Integer length = null;
|
||||||
for (Pair<String, List<Object>> pair : pairs) {
|
for (Pair<String, List<Object>> pair : pairs) {
|
||||||
if (length == null) length = pair.getSecond().size();
|
if (length == null)
|
||||||
}
|
length = pair.getSecond().size();
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println(pairsToCsv(pairs));
|
System.out.println(pairsToCsv(pairs));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void add(List<Pair<String, List<Object>>> pairs, String header, Object value) {
|
private static void add(List<Pair<String, List<Object>>> pairs, String header, Object value) {
|
||||||
if (value == null) value = "";
|
if (value == null) value = "";
|
||||||
Pair<String, List<Object>> pair = null;
|
Pair<String, List<Object>> pair = null;
|
||||||
for (Pair<String, List<Object>> aPair : pairs) {
|
for (Pair<String, List<Object>> aPair : pairs) {
|
||||||
if (aPair.getFirst().equals(header)) {
|
if (aPair.getFirst().equals(header)) {
|
||||||
pair = aPair;
|
pair = aPair;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (pair == null) {
|
||||||
if (pair == null) {
|
List<Object> vals = new ArrayList<Object>();
|
||||||
List<Object> vals = new ArrayList<Object>();
|
pair = new Pair<String, List<Object>>(header, vals);
|
||||||
pair = new Pair<String, List<Object>>(header, vals);
|
pairs.add(pair);
|
||||||
pairs.add(pair);
|
}
|
||||||
}
|
pair.getSecond().add(value);
|
||||||
pair.getSecond().add(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String pairsToCsv(List<Pair<String, List<Object>>> pairs) {
|
private static String pairsToCsv(List<Pair<String, List<Object>>> pairs) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < pairs.size(); i++) {
|
for (int i = 0; i < pairs.size(); i++) {
|
||||||
sb.append(pairs.get(i).getFirst());
|
sb.append(pairs.get(i).getFirst());
|
||||||
if (i < pairs.size() - 1) sb.append(',');
|
if (i < pairs.size() - 1) sb.append(',');
|
||||||
else sb.append('\n');
|
else sb.append('\n');
|
||||||
}
|
|
||||||
for (int i = 0; i < pairs.get(0).getSecond().size(); i++) {
|
|
||||||
for (int j = 0; j < pairs.size(); j++) {
|
|
||||||
sb.append(pairs.get(j).getSecond().get(i));
|
|
||||||
if (j < pairs.size() - 1) sb.append(',');
|
|
||||||
else sb.append('\n');
|
|
||||||
}
|
}
|
||||||
}
|
for (int i = 0; i < pairs.get(0).getSecond().size(); i++) {
|
||||||
return sb.toString();
|
for (int j = 0; j < pairs.size(); j++) {
|
||||||
|
sb.append(pairs.get(j).getSecond().get(i));
|
||||||
|
if (j < pairs.size() - 1) sb.append(',');
|
||||||
|
else sb.append('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,6 @@ public class ProcessPaymentSentMessage extends TradeTask {
|
||||||
|
|
||||||
// if seller, decrypt buyer's payment account payload
|
// if seller, decrypt buyer's payment account payload
|
||||||
if (trade.isSeller()) trade.decryptPeerPaymentAccountPayload(message.getPaymentAccountKey());
|
if (trade.isSeller()) trade.decryptPeerPaymentAccountPayload(message.getPaymentAccountKey());
|
||||||
trade.requestPersistence();
|
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
trade.advanceState(Trade.State.BUYER_SENT_PAYMENT_SENT_MSG);
|
trade.advanceState(Trade.State.BUYER_SENT_PAYMENT_SENT_MSG);
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class SellerPreparePaymentReceivedMessage extends TradeTask {
|
||||||
for (Dispute dispute : trade.getDisputes()) dispute.setIsClosed();
|
for (Dispute dispute : trade.getDisputes()) dispute.setIsClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
processModel.getTradeManager().requestPersistence();
|
trade.requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
failed(t);
|
failed(t);
|
||||||
|
|
|
@ -76,8 +76,7 @@ public abstract class SendDepositsConfirmedMessage extends SendMailboxMessageTas
|
||||||
|
|
||||||
// export multisig hex once
|
// export multisig hex once
|
||||||
if (trade.getSelf().getUpdatedMultisigHex() == null) {
|
if (trade.getSelf().getUpdatedMultisigHex() == null) {
|
||||||
trade.getSelf().setUpdatedMultisigHex(trade.getWallet().exportMultisigHex());
|
trade.exportMultisigHex();
|
||||||
processModel.getTradeManager().requestPersistence();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do not use a real unique ID here as we want to be able to re-send the exact same message in case the
|
// We do not use a real unique ID here as we want to be able to re-send the exact same message in case the
|
||||||
|
|
|
@ -545,27 +545,28 @@ public class PendingTradesDataModel extends ActivatableDataModel {
|
||||||
dispute.setExtraData("counterCurrencyExtraData", trade.getCounterCurrencyExtraData());
|
dispute.setExtraData("counterCurrencyExtraData", trade.getCounterCurrencyExtraData());
|
||||||
|
|
||||||
trade.setDisputeState(Trade.DisputeState.MEDIATION_REQUESTED);
|
trade.setDisputeState(Trade.DisputeState.MEDIATION_REQUESTED);
|
||||||
sendDisputeOpenedMessage(dispute, false, disputeManager, trade.getSelf().getUpdatedMultisigHex());
|
sendDisputeOpenedMessage(dispute, false, disputeManager);
|
||||||
tradeManager.requestPersistence();
|
tradeManager.requestPersistence();
|
||||||
} else if (useArbitration) {
|
} else if (useArbitration) {
|
||||||
// Only if we have completed mediation we allow arbitration
|
// Only if we have completed mediation we allow arbitration
|
||||||
disputeManager = arbitrationManager;
|
disputeManager = arbitrationManager;
|
||||||
Dispute dispute = disputesService.createDisputeForTrade(trade, offer, pubKeyRingProvider.get(), isMaker, isSupportTicket);
|
Dispute dispute = disputesService.createDisputeForTrade(trade, offer, pubKeyRingProvider.get(), isMaker, isSupportTicket);
|
||||||
sendDisputeOpenedMessage(dispute, false, disputeManager, trade.getSelf().getUpdatedMultisigHex());
|
trade.exportMultisigHex();
|
||||||
|
sendDisputeOpenedMessage(dispute, false, disputeManager);
|
||||||
tradeManager.requestPersistence();
|
tradeManager.requestPersistence();
|
||||||
} else {
|
} else {
|
||||||
log.warn("Invalid dispute state {}", disputeState.name());
|
log.warn("Invalid dispute state {}", disputeState.name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendDisputeOpenedMessage(Dispute dispute, boolean reOpen, DisputeManager<? extends DisputeList<Dispute>> disputeManager, String senderMultisigHex) {
|
private void sendDisputeOpenedMessage(Dispute dispute, boolean reOpen, DisputeManager<? extends DisputeList<Dispute>> disputeManager) {
|
||||||
disputeManager.sendDisputeOpenedMessage(dispute, reOpen, senderMultisigHex,
|
disputeManager.sendDisputeOpenedMessage(dispute, reOpen,
|
||||||
() -> navigation.navigateTo(MainView.class, SupportView.class, ArbitrationClientView.class), (errorMessage, throwable) -> {
|
() -> navigation.navigateTo(MainView.class, SupportView.class, ArbitrationClientView.class), (errorMessage, throwable) -> {
|
||||||
if ((throwable instanceof DisputeAlreadyOpenException)) {
|
if ((throwable instanceof DisputeAlreadyOpenException)) {
|
||||||
errorMessage += "\n\n" + Res.get("portfolio.pending.openAgainDispute.msg");
|
errorMessage += "\n\n" + Res.get("portfolio.pending.openAgainDispute.msg");
|
||||||
new Popup().warning(errorMessage)
|
new Popup().warning(errorMessage)
|
||||||
.actionButtonText(Res.get("portfolio.pending.openAgainDispute.button"))
|
.actionButtonText(Res.get("portfolio.pending.openAgainDispute.button"))
|
||||||
.onAction(() -> sendDisputeOpenedMessage(dispute, true, disputeManager, senderMultisigHex))
|
.onAction(() -> sendDisputeOpenedMessage(dispute, true, disputeManager))
|
||||||
.closeButtonText(Res.get("shared.cancel")).show();
|
.closeButtonText(Res.get("shared.cancel")).show();
|
||||||
} else {
|
} else {
|
||||||
new Popup().warning(errorMessage).show();
|
new Popup().warning(errorMessage).show();
|
||||||
|
|
Loading…
Reference in a new issue