Commit f3541ce0 authored by zeroleak's avatar zeroleak
Browse files

cleanup

parent 9b7bc4da
......@@ -14,7 +14,6 @@ import java.lang.invoke.MethodHandles;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.stream.Collectors;
import org.bitcoinj.core.Transaction;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
......@@ -32,7 +31,6 @@ public class Mix {
private byte[] publicKey;
private Timestamp timeStarted;
private Map<MixStatus, Timestamp> timeStatus;
private ScheduledFuture scheduleRegisterOutput;
private Pool pool;
......@@ -60,7 +58,6 @@ public class Mix {
}
this.timeStarted = new Timestamp(System.currentTimeMillis());
this.timeStatus = new ConcurrentHashMap<>();
this.scheduleRegisterOutput = null;
this.pool = pool;
......@@ -140,21 +137,6 @@ public class Mix {
return timeStatus;
}
public ScheduledFuture getScheduleRegisterOutput() {
return scheduleRegisterOutput;
}
public void setScheduleRegisterOutput(ScheduledFuture scheduleRegisterOutput) {
this.scheduleRegisterOutput = scheduleRegisterOutput;
}
public void clearScheduleRegisterOutput() {
if (scheduleRegisterOutput != null) {
scheduleRegisterOutput.cancel(false);
scheduleRegisterOutput = null;
}
}
public Pool getPool() {
return pool;
}
......
......@@ -4,13 +4,13 @@ import com.samourai.whirlpool.protocol.WhirlpoolProtocol;
import com.samourai.whirlpool.protocol.websocket.messages.SubscribePoolResponse;
import com.samourai.whirlpool.server.services.ExportService;
import com.samourai.whirlpool.server.services.PoolService;
import com.samourai.whirlpool.server.services.TaskService;
import com.samourai.whirlpool.server.services.WebSocketService;
import java.lang.invoke.MethodHandles;
import java.security.Principal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.messaging.handler.annotation.MessageExceptionHandler;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
import org.springframework.messaging.simp.annotation.SubscribeMapping;
......@@ -23,17 +23,17 @@ public class SubscribePoolController extends AbstractWebSocketController {
private static final int SUBSCRIBE_RESPONSE_DELAY = 1000;
private PoolService poolService;
private TaskExecutor taskExecutor;
private TaskService taskService;
@Autowired
public SubscribePoolController(
PoolService poolService,
ExportService exportService,
WebSocketService webSocketService,
TaskExecutor taskExecutor) {
TaskService taskService) {
super(webSocketService, exportService);
this.poolService = poolService;
this.taskExecutor = taskExecutor;
this.taskService = taskService;
}
@SubscribeMapping(
......@@ -52,14 +52,9 @@ public class SubscribePoolController extends AbstractWebSocketController {
poolService.computeSubscribePoolResponse(headerPoolId);
// delay to make sure client processed subscription before sending him private response
taskExecutor.execute(
taskService.runOnce(
SUBSCRIBE_RESPONSE_DELAY,
() -> {
synchronized (this) {
try {
wait(SUBSCRIBE_RESPONSE_DELAY);
} catch (InterruptedException e) {
}
}
// send reply
getWebSocketService().sendPrivate(username, subscribePoolResponse);
});
......
......@@ -22,8 +22,6 @@ import com.samourai.whirlpool.server.utils.Utils;
import java.lang.invoke.MethodHandles;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
......@@ -51,7 +49,7 @@ public class MixService {
private Map<String, Mix> currentMixs;
private static final int GRACE_TIME_CONFIRMING_INPUTS = 10000;
private static final int CONFIRMING_INPUTS_DELAY = 5000;
@Autowired
public MixService(
......@@ -266,77 +264,28 @@ public class MixService {
ConfirmInputResponse confirmInputResponse = new ConfirmInputResponse(mixId, signedBordereau64);
webSocketService.sendPrivate(username, confirmInputResponse);
// check mix ready
checkConfirmInputReady(mix);
return signedBordereau;
}
// check mix ready, after a delay to make sure client processed confirmation
taskService.runOnce(
CONFIRMING_INPUTS_DELAY,
() -> {
checkConfirmInputReady(mix);
});
public void checkConfirmInputReady(Mix mix) {
checkConfirmInputReady(mix, true);
return signedBordereau;
}
private void checkConfirmInputReady(Mix mix, boolean allowGracePeriod) {
private void checkConfirmInputReady(Mix mix) {
if (!whirlpoolServerConfig.isMixEnabled()) {
// mix disabled by server configuration
return;
}
if (MixStatus.CONFIRM_INPUT.equals(mix.getMixStatus()) && isRegisterInputReady(mix)) {
// ready to go REGISTER_OUTPUT
if (allowGracePeriod
&& GRACE_TIME_CONFIRMING_INPUTS > 0
&& mix.hasPendingConfirmingInputs()
&& mix.getNbInputs() < mix.getPool().getAnonymitySet()) {
if (log.isDebugEnabled()) {
log.debug(
"Ready to go REGISTER_OUTPUT - waiting for last pending confirmations: pendingConfirmingInputs="
+ mix.getNbConfirmingInputs()
+ ", nbInputs="
+ mix.getNbInputs()
+ ", anonymitySet="
+ mix.getPool().getAnonymitySet());
}
// allow grace period for pending inputs confirmations...
ScheduledFuture scheduledRegisterOutput = mix.getScheduleRegisterOutput();
if (scheduledRegisterOutput == null) {
// schedule
if (log.isDebugEnabled()) {
log.debug("Scheduling REGISTER_OUTPUT, in " + GRACE_TIME_CONFIRMING_INPUTS + "...");
}
ScheduledFuture scheduledFuture =
taskService.runOnce(
GRACE_TIME_CONFIRMING_INPUTS,
() -> {
if (log.isDebugEnabled()) {
log.debug("REGISTER_OUTPUT schedule expired.");
}
mix.clearScheduleRegisterOutput();
checkConfirmInputReady(mix, false);
});
mix.setScheduleRegisterOutput(scheduledFuture);
} else {
// already scheduled
if (log.isDebugEnabled()) {
log.debug(
"REGISTER_OUTPUT already scheduled, in "
+ scheduledRegisterOutput.getDelay(TimeUnit.SECONDS)
+ "s");
}
}
} else {
// all inputs confirmed or mix full => REGISTER_OUTPUT
goRegisterOutput(mix);
}
if (MixStatus.CONFIRM_INPUT.equals(mix.getMixStatus()) && isConfirmInputReady(mix)) {
// all inputs confirmed => REGISTER_OUTPUT
changeMixStatus(mix.getMixId(), MixStatus.REGISTER_OUTPUT);
}
}
private void goRegisterOutput(Mix mix) {
mix.clearScheduleRegisterOutput();
changeMixStatus(mix.getMixId(), MixStatus.REGISTER_OUTPUT);
}
public boolean isRegisterInputReady(Mix mix) {
if (mix.getNbInputs() == 0) {
return false;
......@@ -357,6 +306,16 @@ public class MixService {
return true;
}
public boolean isConfirmInputReady(Mix mix) {
if (!isRegisterInputReady(mix)) {
return false;
}
if (mix.hasPendingConfirmingInputs()) {
return false;
}
return true;
}
public synchronized Mix registerOutput(
String inputsHash, byte[] unblindedSignedBordereau, String receiveAddress) throws Exception {
Mix mix = getMixByInputsHash(inputsHash, MixStatus.REGISTER_OUTPUT);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment