mirror of
https://github.com/boldsuck/haveno.git
synced 2025-01-03 14:49:25 +00:00
seller publishes trade statistics if trade amount transferred
This commit is contained in:
parent
3e2206cf5e
commit
14d17023a8
3 changed files with 57 additions and 30 deletions
|
@ -424,6 +424,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
transient private Subscription tradeStateSubscription;
|
transient private Subscription tradeStateSubscription;
|
||||||
transient private Subscription tradePhaseSubscription;
|
transient private Subscription tradePhaseSubscription;
|
||||||
transient private Subscription payoutStateSubscription;
|
transient private Subscription payoutStateSubscription;
|
||||||
|
transient private Subscription disputeStateSubscription;
|
||||||
transient private TaskLooper pollLooper;
|
transient private TaskLooper pollLooper;
|
||||||
transient private Long pollPeriodMs;
|
transient private Long pollPeriodMs;
|
||||||
transient private Long pollNormalStartTimeMs;
|
transient private Long pollNormalStartTimeMs;
|
||||||
|
@ -696,6 +697,9 @@ public abstract class Trade implements Tradable, Model {
|
||||||
// auto complete arbitrator trade
|
// auto complete arbitrator trade
|
||||||
if (isArbitrator() && !isCompleted()) processModel.getTradeManager().onTradeCompleted(this);
|
if (isArbitrator() && !isCompleted()) processModel.getTradeManager().onTradeCompleted(this);
|
||||||
|
|
||||||
|
// maybe publish trade statistic
|
||||||
|
maybePublishTradeStatistics();
|
||||||
|
|
||||||
// reset address entries
|
// reset address entries
|
||||||
processModel.getXmrWalletService().resetAddressEntriesForTrade(getId());
|
processModel.getXmrWalletService().resetAddressEntriesForTrade(getId());
|
||||||
}
|
}
|
||||||
|
@ -709,6 +713,16 @@ public abstract class Trade implements Tradable, Model {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// handle dispute events
|
||||||
|
disputeStateSubscription = EasyBind.subscribe(disputeStateProperty, newValue -> {
|
||||||
|
if (!isInitialized || isShutDownStarted) return;
|
||||||
|
ThreadUtils.submitToPool(() -> {
|
||||||
|
if (isDisputeClosed()) {
|
||||||
|
maybePublishTradeStatistics();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// arbitrator syncs idle wallet when payout unlock expected
|
// arbitrator syncs idle wallet when payout unlock expected
|
||||||
if (this instanceof ArbitratorTrade) {
|
if (this instanceof ArbitratorTrade) {
|
||||||
idlePayoutSyncer = new IdlePayoutSyncer();
|
idlePayoutSyncer = new IdlePayoutSyncer();
|
||||||
|
@ -1422,6 +1436,7 @@ public abstract class Trade implements Tradable, Model {
|
||||||
if (tradeStateSubscription != null) tradeStateSubscription.unsubscribe();
|
if (tradeStateSubscription != null) tradeStateSubscription.unsubscribe();
|
||||||
if (tradePhaseSubscription != null) tradePhaseSubscription.unsubscribe();
|
if (tradePhaseSubscription != null) tradePhaseSubscription.unsubscribe();
|
||||||
if (payoutStateSubscription != null) payoutStateSubscription.unsubscribe();
|
if (payoutStateSubscription != null) payoutStateSubscription.unsubscribe();
|
||||||
|
if (disputeStateSubscription != null) disputeStateSubscription.unsubscribe();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1998,6 +2013,10 @@ public abstract class Trade implements Tradable, Model {
|
||||||
return isArbitrator() ? getBuyer().getDisputeClosedMessage() != null || getSeller().getDisputeClosedMessage() != null : getArbitrator().getDisputeClosedMessage() != null;
|
return isArbitrator() ? getBuyer().getDisputeClosedMessage() != null || getSeller().getDisputeClosedMessage() != null : getArbitrator().getDisputeClosedMessage() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDisputeClosed() {
|
||||||
|
return getDisputeState().isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isPaymentReceived() {
|
public boolean isPaymentReceived() {
|
||||||
return getState().getPhase().ordinal() >= Phase.PAYMENT_RECEIVED.ordinal();
|
return getState().getPhase().ordinal() >= Phase.PAYMENT_RECEIVED.ordinal();
|
||||||
}
|
}
|
||||||
|
@ -2149,6 +2168,39 @@ public abstract class Trade implements Tradable, Model {
|
||||||
return Math.min(MAX_REPROCESS_DELAY_SECONDS, delay);
|
return Math.min(MAX_REPROCESS_DELAY_SECONDS, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void maybePublishTradeStatistics() {
|
||||||
|
if (shouldPublishTradeStatistics()) doPublishTradeStatistics();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean shouldPublishTradeStatistics() {
|
||||||
|
if (!isSeller()) return false;
|
||||||
|
return tradeAmountTransferred();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean tradeAmountTransferred() {
|
||||||
|
return isPaymentReceived() || (getDisputeResult() != null && getDisputeResult().getWinner() == DisputeResult.Winner.SELLER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPublishTradeStatistics() {
|
||||||
|
processModel.getP2PService().findPeersCapabilities(getTradePeer().getNodeAddress())
|
||||||
|
.filter(capabilities -> capabilities.containsAll(Capability.TRADE_STATISTICS_3))
|
||||||
|
.ifPresentOrElse(capabilities -> {
|
||||||
|
String referralId = processModel.getReferralIdService().getOptionalReferralId().orElse(null);
|
||||||
|
boolean isTorNetworkNode = getProcessModel().getP2PService().getNetworkNode() instanceof TorNetworkNode;
|
||||||
|
TradeStatistics3 tradeStatistics = TradeStatistics3.from(this, referralId, isTorNetworkNode);
|
||||||
|
if (tradeStatistics.isValid()) {
|
||||||
|
log.info("Publishing trade statistics");
|
||||||
|
processModel.getP2PService().addPersistableNetworkPayload(tradeStatistics, true);
|
||||||
|
} else {
|
||||||
|
log.warn("Trade statistics are invalid. We do not publish. {}", tradeStatistics);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
log.info("Our peer does not has updated yet, so they will publish the trade statistics. " +
|
||||||
|
"To avoid duplicates we do not publish from our side.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Private
|
// Private
|
||||||
|
@ -2566,31 +2618,6 @@ public abstract class Trade implements Tradable, Model {
|
||||||
} else {
|
} else {
|
||||||
getXmrWalletService().resetAddressEntriesForOpenOffer(getId());
|
getXmrWalletService().resetAddressEntriesForOpenOffer(getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// seller publishes trade statistics
|
|
||||||
if (this instanceof SellerTrade) {
|
|
||||||
checkNotNull(getSeller().getDepositTx());
|
|
||||||
processModel.getP2PService().findPeersCapabilities(getTradePeer().getNodeAddress())
|
|
||||||
.filter(capabilities -> capabilities.containsAll(Capability.TRADE_STATISTICS_3))
|
|
||||||
.ifPresentOrElse(capabilities -> {
|
|
||||||
|
|
||||||
// Our peer has updated, so as we are the seller we will publish the trade statistics.
|
|
||||||
// The peer as buyer does not publish anymore with v.1.4.0 (where Capability.TRADE_STATISTICS_3 was added)
|
|
||||||
String referralId = processModel.getReferralIdService().getOptionalReferralId().orElse(null);
|
|
||||||
boolean isTorNetworkNode = getProcessModel().getP2PService().getNetworkNode() instanceof TorNetworkNode;
|
|
||||||
TradeStatistics3 tradeStatistics = TradeStatistics3.from(this, referralId, isTorNetworkNode);
|
|
||||||
if (tradeStatistics.isValid()) {
|
|
||||||
log.info("Publishing trade statistics");
|
|
||||||
processModel.getP2PService().addPersistableNetworkPayload(tradeStatistics, true);
|
|
||||||
} else {
|
|
||||||
log.warn("Trade statistics are invalid. We do not publish. {}", tradeStatistics);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
() -> {
|
|
||||||
log.info("Our peer does not has updated yet, so they will publish the trade statistics. " +
|
|
||||||
"To avoid duplicates we do not publish from our side.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -103,6 +103,9 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
|
||||||
for (Dispute dispute : trade.getDisputes()) dispute.setIsClosed();
|
for (Dispute dispute : trade.getDisputes()) dispute.setIsClosed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// advance state, arbitrator auto completes when payout published
|
||||||
|
trade.advanceState(Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG);
|
||||||
|
|
||||||
// publish signed witness
|
// publish signed witness
|
||||||
SignedWitness signedWitness = message.getBuyerSignedWitness();
|
SignedWitness signedWitness = message.getBuyerSignedWitness();
|
||||||
if (signedWitness != null && trade instanceof BuyerTrade) {
|
if (signedWitness != null && trade instanceof BuyerTrade) {
|
||||||
|
@ -113,7 +116,6 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
|
||||||
}
|
}
|
||||||
|
|
||||||
// complete
|
// complete
|
||||||
trade.advanceState(Trade.State.SELLER_SENT_PAYMENT_RECEIVED_MSG); // arbitrator auto completes when payout published
|
|
||||||
trade.requestPersistence();
|
trade.requestPersistence();
|
||||||
complete();
|
complete();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
|
|
@ -26,7 +26,6 @@ import haveno.core.locale.CurrencyTuple;
|
||||||
import haveno.core.locale.CurrencyUtil;
|
import haveno.core.locale.CurrencyUtil;
|
||||||
import haveno.core.locale.Res;
|
import haveno.core.locale.Res;
|
||||||
import haveno.core.provider.price.PriceFeedService;
|
import haveno.core.provider.price.PriceFeedService;
|
||||||
import haveno.core.trade.SellerTrade;
|
|
||||||
import haveno.core.trade.Trade;
|
import haveno.core.trade.Trade;
|
||||||
import haveno.core.util.JsonUtil;
|
import haveno.core.util.JsonUtil;
|
||||||
import haveno.network.p2p.P2PService;
|
import haveno.network.p2p.P2PService;
|
||||||
|
@ -200,9 +199,8 @@ public class TradeStatisticsManager {
|
||||||
long ts = System.currentTimeMillis();
|
long ts = System.currentTimeMillis();
|
||||||
Set<P2PDataStorage.ByteArray> hashes = tradeStatistics3StorageService.getMapOfAllData().keySet();
|
Set<P2PDataStorage.ByteArray> hashes = tradeStatistics3StorageService.getMapOfAllData().keySet();
|
||||||
trades.forEach(trade -> {
|
trades.forEach(trade -> {
|
||||||
if (!(trade instanceof SellerTrade)) {
|
if (!trade.shouldPublishTradeStatistics()) {
|
||||||
log.debug("Trade: {} is not a seller trade, we only republish if we were seller",
|
log.debug("Trade: {} should not publish trade statistics", trade.getShortId());
|
||||||
trade.getShortId());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue