Skip to content

Commit

Permalink
feat(coinjoin): track state and joined status with onSessionComplete …
Browse files Browse the repository at this point in the history
…listener
  • Loading branch information
HashEngineering committed Jul 21, 2023
1 parent 26cf42a commit 7a2855d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ public class CoinJoinClientSession extends CoinJoinBaseSession {
private String strAutoDenomResult;

private Masternode mixingMasternode;
private boolean joined; // did we join a session (true), or start a session (false)
private Transaction txMyCollateral; // client side collateral
private boolean isMyCollateralValid = false;
private PendingDsaRequest pendingDsaRequest;
Expand Down Expand Up @@ -599,6 +600,7 @@ private boolean joinExistingQueue(Coin balanceNeedsAnonymized) {
log.info("coinjoin: join existing queue -> pending connection, sessionDenom: {} ({}), addr={}",
sessionDenom, CoinJoin.denominationToString(sessionDenom), dmn.getService());
setStatus(PoolStatus.CONNECTING);
joined = true;
return true;
}
setStatus(PoolStatus.WARN_NO_MIXING_QUEUES);
Expand Down Expand Up @@ -673,6 +675,7 @@ private boolean startNewQueue(Coin balanceNeedsAnonymized) {
sessionDenom, CoinJoin.denominationToString(sessionDenom), dmn.getService());
context.coinJoinManager.startAsync();
setStatus(PoolStatus.CONNECTING);
joined = false;
return true;
}
strAutoDenomResult = "Failed to start a new mixing queue";
Expand Down Expand Up @@ -858,7 +861,7 @@ private void processPoolStateUpdate(Peer peer, CoinJoinStatusUpdate statusUpdate
keyHolderStorage.returnAll();
switch (statusUpdate.getMessageID()) {
case ERR_INVALID_COLLATERAL:
log.error("coinjoin: collateral valid: {}", CoinJoin.isCollateralValid(txMyCollateral));
log.error("coinjoin: collateral invalid: {}", CoinJoin.isCollateralValid(txMyCollateral));
isMyCollateralValid = false;
setNull(); // for now lets disconnect. TODO: Why is the collateral invalid?
break;
Expand Down Expand Up @@ -895,7 +898,7 @@ private void setState(PoolState state) {
private void completedTransaction(PoolMessage messageID) {
if (messageID == MSG_SUCCESS) {
log.info("coinjoin: CompletedTransaction -- success");
queueSessionCompleteListeners(MSG_SUCCESS);
queueSessionCompleteListeners(getState(), MSG_SUCCESS);
mixingWallet.getContext().coinJoinManager.coinJoinClientManagers.get(mixingWallet.getDescription()).updatedSuccessBlock();
keyHolderStorage.keepAll();
} else {
Expand Down Expand Up @@ -1258,7 +1261,7 @@ public boolean doAutomaticDenominating(boolean fDryRun) {
//status.set(PoolStatus.ERR_NO_MASTERNODES_DETECTED);
//hasNothingToDo.set(true);
setStatus(PoolStatus.ERR_NO_MASTERNODES_DETECTED);
queueSessionCompleteListeners(ERR_SESSION);
queueSessionCompleteListeners(getState(), ERR_SESSION);
return false;
}

Expand Down Expand Up @@ -1292,7 +1295,7 @@ public boolean doAutomaticDenominating(boolean fDryRun) {
// mixable balance is way too small
if (nBalanceAnonymizable.isLessThan(nValueMin)) {
setStatus(PoolStatus.ERR_NOT_ENOUGH_FUNDS);
queueSessionCompleteListeners(ERR_SESSION);
queueSessionCompleteListeners(getState(), ERR_SESSION);
return false;
}

Expand Down Expand Up @@ -1502,7 +1505,7 @@ public boolean process(Peer peer) {
} else if (pendingDsaRequest.isExpired()) {
log.info("coinjoin -- failed to connect to {}; reason: expired", pendingDsaRequest.getAddress());
setStatus(PoolStatus.CONNECTION_TIMEOUT);
queueSessionCompleteListeners(ERR_CONNECTION_TIMEOUT);
queueSessionCompleteListeners(getState(), ERR_CONNECTION_TIMEOUT);
setNull();
}

Expand Down Expand Up @@ -1532,8 +1535,8 @@ public boolean checkTimeout() {

log.info("coinjoin: {} {} timed out ({})", (state.get() == POOL_STATE_SIGNING) ? "Signing at session" : "Session", sessionID.get(), nTimeout);

queueSessionCompleteListeners(getState(), ERR_TIMEOUT);
setState(POOL_STATE_ERROR);
queueSessionCompleteListeners(ERR_TIMEOUT);
setStatus(PoolStatus.TIMEOUT);
unlockCoins();
keyHolderStorage.returnAll();
Expand All @@ -1547,6 +1550,7 @@ public boolean checkTimeout() {
public String toString() {
return "CoinJoinClientSession{id=" + id +
", mixer=" + (mixingMasternode != null ? mixingMasternode.getService().getSocketAddress() : "none") +
", joined=" + joined +
", msg='" + strLastMessage + '\'' +
", dsa=" + pendingDsaRequest +
", entries=" + entries.size() +
Expand Down Expand Up @@ -1637,14 +1641,14 @@ public boolean removeSessionCompleteListener(SessionCompleteListener listener) {
return ListenerRegistration.removeFromList(listener, sessionCompleteListeners);
}

protected void queueSessionCompleteListeners(PoolMessage message) {
protected void queueSessionCompleteListeners(PoolState state, PoolMessage message) {
//checkState(lock.isHeldByCurrentThread());
for (final ListenerRegistration<SessionCompleteListener> registration : sessionCompleteListeners) {
registration.executor.execute(new Runnable() {
@Override
public void run() {
MasternodeAddress address = mixingMasternode.getService();
registration.listener.onSessionComplete(mixingWallet, getSessionID(), getSessionDenom(), message, address);
registration.listener.onSessionComplete(mixingWallet, getSessionID(), getSessionDenom(), state, message, address, joined);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
package org.bitcoinj.coinjoin.listeners;

import org.bitcoinj.coinjoin.PoolMessage;
import org.bitcoinj.coinjoin.PoolState;
import org.bitcoinj.core.MasternodeAddress;
import org.bitcoinj.wallet.WalletEx;

public interface SessionCompleteListener {
void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolMessage message, MasternodeAddress address);
void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolState state, PoolMessage message, MasternodeAddress address, boolean joined);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.common.util.concurrent.SettableFuture;

import org.bitcoinj.coinjoin.PoolMessage;
import org.bitcoinj.coinjoin.PoolState;
import org.bitcoinj.coinjoin.PoolStatus;
import org.bitcoinj.coinjoin.listeners.CoinJoinTransactionListener;
import org.bitcoinj.coinjoin.listeners.CoinJoinTransactionType;
Expand Down Expand Up @@ -51,7 +52,8 @@ public MixingProgressTracker() {
}

@Override
public void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolMessage message, MasternodeAddress address) {
public void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolState state,
PoolMessage message, MasternodeAddress address, boolean joined) {
if (message == PoolMessage.MSG_SUCCESS) {
completedSessions++;
lastPercent = calculatePercentage(wallet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.google.common.collect.Maps;
import org.bitcoinj.coinjoin.CoinJoin;
import org.bitcoinj.coinjoin.PoolMessage;
import org.bitcoinj.coinjoin.PoolState;
import org.bitcoinj.coinjoin.PoolStatus;
import org.bitcoinj.coinjoin.listeners.CoinJoinTransactionType;
import org.bitcoinj.coinjoin.progress.MixingProgressTracker;
Expand Down Expand Up @@ -110,27 +111,27 @@ public void onSessionStarted(WalletEx wallet, int sessionId, int denomination, P
}

@Override
public void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolMessage message, MasternodeAddress address) {
super.onSessionComplete(wallet, sessionId, denomination, message, address);
public void onSessionComplete(WalletEx wallet, int sessionId, int denomination, PoolState state, PoolMessage message, MasternodeAddress address, boolean joined) {
super.onSessionComplete(wallet, sessionId, denomination, state, message, address, joined);
try {
writeTime();
Stopwatch watch = sessionMap.get(sessionId);
if (watch != null)
watch.stop();
if (message == PoolMessage.MSG_SUCCESS) {
writer.write("Session Complete: ");
writer.write(String.format("id: %d, denom: %s[%d]", sessionId, CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination));
writer.write(String.format("id: %d, denom: %s[%d], joined: %b", sessionId, CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination, joined));
writeWatch(watch);
writer.newLine();
writeStats(wallet);
} else if (message == PoolMessage.ERR_CONNECTION_TIMEOUT) {
writer.write("Session Failure to connect: ");
writer.write(String.format("address: %s, denom: %s[%d]", address.getSocketAddress(), CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination));
writer.write(String.format("%s, address: %s, denom: %s[%d], joined: %b", state, address.getSocketAddress(), CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination, joined));
writeWatch(watch);
writer.write(CoinJoin.getMessageByID(message));
} else {
writer.write("Session Failure: ");
writer.write(String.format("id: %d, denom: %s[%d]", sessionId, CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination));
writer.write(String.format("%s, id: %d, denom: %s[%d], joined: %b", state, sessionId, CoinJoin.denominationToAmount(denomination).toFriendlyString(), denomination, joined));
writeWatch(watch);
writer.write(CoinJoin.getMessageByID(message));
}
Expand Down

0 comments on commit 7a2855d

Please sign in to comment.