@@ -148,6 +148,7 @@ public abstract class Trade extends XmrWalletBase implements Tradable, Model {
148
148
private static final long EXTENDED_RPC_TIMEOUT = 600000 ; // 10 minutes
149
149
private static final long DELETE_AFTER_MS = TradeProtocol .TRADE_STEP_TIMEOUT_SECONDS ;
150
150
private static final int NUM_CONFIRMATIONS_FOR_SCHEDULED_IMPORT = 5 ;
151
+ private static final int NUM_BLOCKS_FINALIZED = 60 ; // ~2 hours before payout is considered finalized and multisig deleted
151
152
protected final Object pollLock = new Object ();
152
153
private final Object removeTradeOnErrorLock = new Object ();
153
154
protected static final Object importMultisigLock = new Object ();
@@ -264,7 +265,8 @@ public enum PayoutState {
264
265
PAYOUT_UNPUBLISHED ,
265
266
PAYOUT_PUBLISHED ,
266
267
PAYOUT_CONFIRMED ,
267
- PAYOUT_UNLOCKED ;
268
+ PAYOUT_UNLOCKED ,
269
+ PAYOUT_FINALIZED ;
268
270
269
271
public static Trade .PayoutState fromProto (protobuf .Trade .PayoutState state ) {
270
272
return ProtoUtil .enumFromProto (Trade .PayoutState .class , state .name ());
@@ -658,7 +660,7 @@ public void initialize(ProcessModelServiceProvider serviceProvider) {
658
660
if (newValue == Trade .Phase .DEPOSITS_CONFIRMED ) onDepositsConfirmed ();
659
661
if (newValue == Trade .Phase .DEPOSITS_UNLOCKED ) onDepositsUnlocked ();
660
662
if (newValue == Trade .Phase .PAYMENT_SENT ) onPaymentSent ();
661
- if (isDepositsPublished () && !isPayoutUnlocked ()) updatePollPeriod ();
663
+ if (isDepositsPublished () && !isPayoutFinalized ()) updatePollPeriod ();
662
664
if (isPaymentReceived ()) {
663
665
UserThread .execute (() -> {
664
666
if (tradePhaseSubscription != null ) {
@@ -704,10 +706,10 @@ public void initialize(ProcessModelServiceProvider serviceProvider) {
704
706
processModel .getXmrWalletService ().swapPayoutAddressEntryToAvailable (getId ());
705
707
}
706
708
707
- // handle when payout unlocks
708
- if (newValue == Trade .PayoutState .PAYOUT_UNLOCKED ) {
709
+ // handle when payout finalized
710
+ if (newValue == Trade .PayoutState .PAYOUT_FINALIZED ) {
709
711
if (!isInitialized ) return ;
710
- log .info ("Payout unlocked for {} {}, deleting multisig wallet" , getClass ().getSimpleName (), getId ());
712
+ log .info ("Payout finalized for {} {}, deleting multisig wallet" , getClass ().getSimpleName (), getId ());
711
713
if (isInitialized && isFinished ()) clearAndShutDown ();
712
714
else deleteWallet ();
713
715
}
@@ -744,8 +746,8 @@ public void initialize(ProcessModelServiceProvider serviceProvider) {
744
746
importMultisigHexIfScheduled ();
745
747
});
746
748
747
- // done if deposit not requested or payout unlocked
748
- if (!isDepositRequested () || isPayoutUnlocked ()) {
749
+ // done if deposit not requested or payout finalized
750
+ if (!isDepositRequested () || isPayoutFinalized ()) {
749
751
isInitialized = true ;
750
752
isFullyInitialized = true ;
751
753
return ;
@@ -755,9 +757,17 @@ public void initialize(ProcessModelServiceProvider serviceProvider) {
755
757
if (walletExists ()) getWallet ();
756
758
else {
757
759
MoneroTx payoutTx = getPayoutTx ();
758
- if (payoutTx != null && payoutTx .getNumConfirmations () >= XmrWalletService .NUM_BLOCKS_UNLOCK ) {
759
- log .warn ("Payout state for {} {} is {} but payout is unlocked, updating state" , getClass ().getSimpleName (), getId (), getPayoutState ());
760
- setPayoutStateUnlocked ();
760
+ if (payoutTx != null ) {
761
+
762
+ // update payout state if necessary
763
+ if (payoutTx .getNumConfirmations () >= XmrWalletService .NUM_BLOCKS_UNLOCK ) {
764
+ log .warn ("Payout state for {} {} is {} but payout is unlocked, updating state" , getClass ().getSimpleName (), getId (), getPayoutState ());
765
+ setPayoutStateUnlocked ();
766
+ }
767
+ if (payoutTx .getNumConfirmations () >= NUM_BLOCKS_FINALIZED ) {
768
+ log .warn ("Payout state for {} {} is {} but payout is finalized, updating state" , getClass ().getSimpleName (), getId (), getPayoutState ());
769
+ setPayoutStateFinalized ();
770
+ }
761
771
isInitialized = true ;
762
772
isFullyInitialized = true ;
763
773
return ;
@@ -777,7 +787,7 @@ public void initialize(ProcessModelServiceProvider serviceProvider) {
777
787
}
778
788
779
789
public boolean isFinished () {
780
- return isPayoutUnlocked () && isCompleted ();
790
+ return isPayoutFinalized () && isCompleted ();
781
791
}
782
792
783
793
public void resetToPaymentSentState () {
@@ -790,7 +800,7 @@ public void resetToPaymentSentState() {
790
800
}
791
801
792
802
public void initializeAfterMailboxMessages () {
793
- if (!isDepositRequested () || isPayoutUnlocked () || isCompleted ()) return ;
803
+ if (!isDepositRequested () || isPayoutFinalized () || isCompleted ()) return ;
794
804
getProtocol ().maybeReprocessPaymentSentMessage (false );
795
805
getProtocol ().maybeReprocessPaymentReceivedMessage (false );
796
806
HavenoUtils .arbitrationManager .maybeReprocessDisputeClosedMessage (this , false );
@@ -1030,15 +1040,15 @@ public void deleteWallet() {
1030
1040
syncedWallet = true ;
1031
1041
}
1032
1042
1033
- // sync wallet if deposit requested and payout not unlocked
1034
- if (!isPayoutUnlocked () && !syncedWallet ) {
1043
+ // sync wallet if deposit requested and payout not finalized
1044
+ if (!isPayoutFinalized () && !syncedWallet ) {
1035
1045
log .warn ("Syncing wallet on deletion for trade {} {}, syncing" , getClass ().getSimpleName (), getId ());
1036
1046
syncWallet (true );
1037
1047
}
1038
1048
1039
- // check if deposits published and payout not unlocked
1040
- if (isDepositsPublished () && !isPayoutUnlocked ()) {
1041
- throw new IllegalStateException ("Refusing to delete wallet for " + getClass ().getSimpleName () + " " + getId () + " because the deposit txs have been published but payout tx has not unlocked " );
1049
+ // check if deposits published and payout not finalized
1050
+ if (isDepositsPublished () && !isPayoutFinalized ()) {
1051
+ throw new IllegalStateException ("Refusing to delete wallet for " + getClass ().getSimpleName () + " " + getId () + " because the deposit txs have been published but payout tx has not finalized " );
1042
1052
}
1043
1053
1044
1054
// check for balance
@@ -1645,7 +1655,7 @@ public void onShutDownStarted() {
1645
1655
public void shutDown () {
1646
1656
if (isShutDown ) return ; // ignore if already shut down
1647
1657
isShutDownStarted = true ;
1648
- if (!isPayoutUnlocked ()) log .info ("Shutting down {} {}" , getClass ().getSimpleName (), getId ());
1658
+ if (!isPayoutFinalized ()) log .info ("Shutting down {} {}" , getClass ().getSimpleName (), getId ());
1649
1659
1650
1660
// unregister p2p message listener
1651
1661
removeDecryptedDirectMessageListener ();
@@ -2338,6 +2348,10 @@ public boolean isPayoutUnlocked() {
2338
2348
return getPayoutState ().ordinal () >= PayoutState .PAYOUT_UNLOCKED .ordinal ();
2339
2349
}
2340
2350
2351
+ public boolean isPayoutFinalized () {
2352
+ return getPayoutState ().ordinal () >= PayoutState .PAYOUT_FINALIZED .ordinal ();
2353
+ }
2354
+
2341
2355
public ReadOnlyDoubleProperty initProgressProperty () {
2342
2356
return initProgressProperty ;
2343
2357
}
@@ -2718,8 +2732,8 @@ private void doPollWallet() {
2718
2732
// skip if shut down started
2719
2733
if (isShutDownStarted ) return ;
2720
2734
2721
- // skip if payout unlocked
2722
- if (isPayoutUnlocked ()) return ;
2735
+ // skip if payout finalized
2736
+ if (isPayoutFinalized ()) return ;
2723
2737
2724
2738
// skip if deposit txs unknown or not requested
2725
2739
if (!isDepositRequested () || processModel .getMaker ().getDepositTxHash () == null || (processModel .getTaker ().getDepositTxHash () == null && !hasBuyerAsTakerWithoutDeposit ())) return ;
@@ -2847,6 +2861,7 @@ else if (hasFailedTx && isPayoutPublished()) {
2847
2861
setPayoutStatePublished ();
2848
2862
if (tx .isConfirmed ()) setPayoutStateConfirmed ();
2849
2863
if (!tx .isLocked ()) setPayoutStateUnlocked ();
2864
+ if (tx .getNumConfirmations () != null && tx .getNumConfirmations () >= NUM_BLOCKS_FINALIZED ) setPayoutStateFinalized ();
2850
2865
}
2851
2866
}
2852
2867
}
@@ -3108,6 +3123,10 @@ private void setPayoutStateUnlocked() {
3108
3123
if (!isPayoutUnlocked ()) setPayoutState (PayoutState .PAYOUT_UNLOCKED );
3109
3124
}
3110
3125
3126
+ private void setPayoutStateFinalized () {
3127
+ if (!isPayoutFinalized ()) setPayoutState (PayoutState .PAYOUT_FINALIZED );
3128
+ }
3129
+
3111
3130
private Trade getTrade () {
3112
3131
return this ;
3113
3132
}
@@ -3128,8 +3147,8 @@ public void onNewBlock(long height) {
3128
3147
if (processing ) return ;
3129
3148
processing = true ;
3130
3149
3131
- // skip if not idling and not waiting for payout to unlock
3132
- if (!isIdling () || !isPayoutPublished () || isPayoutUnlocked ()) {
3150
+ // skip if not idling and not waiting for payout to finalize
3151
+ if (!isIdling () || !isPayoutPublished () || isPayoutFinalized ()) {
3133
3152
processing = false ;
3134
3153
return ;
3135
3154
}
0 commit comments