25
25
import bisq .chat .bisq_easy .open_trades .BisqEasyOpenTradeChannel ;
26
26
import bisq .chat .bisq_easy .open_trades .BisqEasyOpenTradeChannelService ;
27
27
import bisq .common .application .Service ;
28
+ import bisq .common .observable .Pin ;
28
29
import bisq .contract .bisq_easy .BisqEasyContract ;
29
30
import bisq .i18n .Res ;
30
31
import bisq .network .NetworkService ;
41
42
import lombok .extern .slf4j .Slf4j ;
42
43
43
44
import java .nio .charset .StandardCharsets ;
44
- import java .util .ArrayList ;
45
- import java .util .Comparator ;
46
- import java .util .Optional ;
47
- import java .util .Set ;
45
+ import java .util .*;
48
46
import java .util .concurrent .CompletableFuture ;
47
+ import java .util .concurrent .CopyOnWriteArraySet ;
49
48
import java .util .stream .Collectors ;
50
49
51
50
import static com .google .common .base .Preconditions .checkArgument ;
@@ -60,6 +59,8 @@ public class MediationRequestService implements Service, ConfidentialMessageServ
60
59
private final BisqEasyOpenTradeChannelService bisqEasyOpenTradeChannelService ;
61
60
private final AuthorizedBondedRolesService authorizedBondedRolesService ;
62
61
private final BannedUserService bannedUserService ;
62
+ private final Set <MediatorsResponse > pendingMediatorsResponseMessages = new CopyOnWriteArraySet <>();
63
+ private Pin channeldPin ;
63
64
64
65
public MediationRequestService (NetworkService networkService ,
65
66
ChatService chatService ,
@@ -89,6 +90,10 @@ public CompletableFuture<Boolean> initialize() {
89
90
@ Override
90
91
public CompletableFuture <Boolean > shutdown () {
91
92
networkService .removeConfidentialMessageListener (this );
93
+ if (channeldPin != null ) {
94
+ channeldPin .unbind ();
95
+ channeldPin = null ;
96
+ }
92
97
return CompletableFuture .completedFuture (true );
93
98
}
94
99
@@ -110,7 +115,7 @@ public void onMessage(EnvelopePayloadMessage envelopePayloadMessage) {
110
115
/* --------------------------------------------------------------------- */
111
116
112
117
public void requestMediation (BisqEasyOpenTradeChannel channel ,
113
- BisqEasyContract contract ) {
118
+ BisqEasyContract contract ) {
114
119
checkArgument (channel .getBisqEasyOffer ().equals (contract .getOffer ()));
115
120
UserIdentity myUserIdentity = channel .getMyUserIdentity ();
116
121
checkArgument (!bannedUserService .isUserProfileBanned (myUserIdentity .getUserProfile ()));
@@ -166,18 +171,34 @@ public Optional<UserProfile> selectMediator(Set<AuthorizedBondedRole> mediators,
166
171
167
172
private void processMediationResponse (MediatorsResponse mediatorsResponse ) {
168
173
bisqEasyOpenTradeChannelService .findChannelByTradeId (mediatorsResponse .getTradeId ())
169
- .ifPresent (channel -> {
170
- // Requester had it activated at request time
171
- if (channel .isInMediation ()) {
172
- bisqEasyOpenTradeChannelService .addMediatorsResponseMessage (channel , Res .get ("authorizedRole.mediator.message.toRequester" ));
173
- } else {
174
- bisqEasyOpenTradeChannelService .setIsInMediation (channel , true );
175
- bisqEasyOpenTradeChannelService .addMediatorsResponseMessage (channel , Res .get ("authorizedRole.mediator.message.toNonRequester" ));
176
-
177
- //todo (Critical) - check if we do sent from both peers
178
- // Peer who has not requested sends their messages as well, so mediator can be sure to get all messages
179
- }
180
- });
174
+ .ifPresentOrElse (channel -> {
175
+ // Requester had it activated at request time
176
+ if (channel .isInMediation ()) {
177
+ bisqEasyOpenTradeChannelService .addMediatorsResponseMessage (channel , Res .get ("authorizedRole.mediator.message.toRequester" ));
178
+ } else {
179
+ bisqEasyOpenTradeChannelService .setIsInMediation (channel , true );
180
+ bisqEasyOpenTradeChannelService .addMediatorsResponseMessage (channel , Res .get ("authorizedRole.mediator.message.toNonRequester" ));
181
+
182
+ //todo (Critical) - check if we do sent from both peers
183
+ // Peer who has not requested sends their messages as well, so mediator can be sure to get all messages
184
+ }
185
+ pendingMediatorsResponseMessages .remove (mediatorsResponse );
186
+ },
187
+ () -> {
188
+ // This handles an edge case that the MediatorsResponse arrives before the take offer request was
189
+ // processed (in case we are the maker and have been offline at take offer).
190
+ log .warn ("We received a MediatorsResponse but did not find a matching bisqEasyOpenTradeChannel for trade ID {}.\n " +
191
+ "We add it to the pendingMediatorsResponseMessages set and reprocess it once a new trade channel has been added." ,
192
+ mediatorsResponse .getTradeId ());
193
+ pendingMediatorsResponseMessages .add (mediatorsResponse );
194
+ if (channeldPin == null ) {
195
+ channeldPin = bisqEasyOpenTradeChannelService .getChannels ().addObserver (this ::maybeProcessPendingMediatorsResponseMessages );
196
+ }
197
+ });
198
+ }
199
+
200
+ private void maybeProcessPendingMediatorsResponseMessages () {
201
+ new HashSet <>(pendingMediatorsResponseMessages ).forEach (this ::processMediationResponse );
181
202
}
182
203
}
183
204
0 commit comments