Introduce Alice deadline
MODIFY
WalletWasabi.Tests/Helpers/WabiSabiFactory.cs
WalletWasabi.Tests/Helpers/WabiSabiFactory.cs
@@ -59,6 +59,9 @@ namespace WalletWasabi.Tests.Helpers
cfg.MaxRegistrableAmount,
cfg.MinRegistrableWeight,
cfg.MaxRegistrableWeight,
+ cfg.ConnectionConfirmationTimeout,
+ cfg.OutputRegistrationTimeout,
+ cfg.TransactionSigningTimeout,
new InsecureRandom());
public static Alice CreateAlice(InputRoundSignaturePair inputSigPairs) => CreateAlice(new[] { inputSigPairs });
@@ -121,13 +124,13 @@ namespace WalletWasabi.Tests.Helpers
ai.CredentialIssuerSecretKey.ComputeCredentialIssuerParameters(),
ai.NumberOfCredentials,
rnd,
- round?.MaxRegistrableAmount ?? 4300000000000);
+ round?.MaxRegistrableAmountByAlice ?? 4300000000000);
var wc = new WabiSabiClient(
wi.CredentialIssuerSecretKey.ComputeCredentialIssuerParameters(),
wi.NumberOfCredentials,
rnd,
- round?.MaxRegistrableWeight ?? 4300000000000ul);
+ round?.MaxRegistrableWeightByAlice ?? 4300000000000ul);
return (ac, wc, ai, wi);
}

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/ConfirmConnectionTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/ConfirmConnectionTests.cs
@@ -23,10 +23,12 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
WabiSabiConfig cfg = new();
var round = WabiSabiFactory.CreateRound(cfg);
var alice = WabiSabiFactory.CreateAlice();
+ var preDeadline = alice.Deadline;
round.Alices.Add(alice);
arena.OnTryGetRound = _ => round;
var req = WabiSabiFactory.CreateConnectionConfirmationRequest(round);
+ var minAliceDeadline = DateTimeOffset.UtcNow + cfg.ConnectionConfirmationTimeout * 0.9;
await using PostRequestHandler handler = new(cfg, new Prison(), arena, new MockRpcClient());
var resp = handler.ConfirmConnection(req);
Assert.NotNull(resp);
@@ -34,6 +36,8 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
Assert.NotNull(resp.ZeroWeightCredentials);
Assert.Null(resp.RealAmountCredentials);
Assert.Null(resp.RealWeightCredentials);
+ Assert.NotEqual(preDeadline, alice.Deadline);
+ Assert.True(minAliceDeadline <= alice.Deadline);
}
[Fact]
@@ -44,6 +48,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
var round = WabiSabiFactory.CreateRound(cfg);
round.Phase = Phase.ConnectionConfirmation;
var alice = WabiSabiFactory.CreateAlice();
+ var preDeadline = alice.Deadline;
round.Alices.Add(alice);
arena.OnTryGetRound = _ => round;
@@ -55,6 +60,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
Assert.NotNull(resp.ZeroWeightCredentials);
Assert.NotNull(resp.RealAmountCredentials);
Assert.NotNull(resp.RealWeightCredentials);
+ Assert.Equal(preDeadline, alice.Deadline);
}
[Fact]
@@ -76,6 +82,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
WabiSabiConfig cfg = new();
var round = WabiSabiFactory.CreateRound(cfg);
var alice = WabiSabiFactory.CreateAlice();
+ var preDeadline = alice.Deadline;
round.Alices.Add(alice);
arena.OnTryGetRound = _ => round;
@@ -90,6 +97,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
Assert.Equal(WabiSabiProtocolErrorCode.WrongPhase, ex.ErrorCode);
}
}
+ Assert.Equal(preDeadline, alice.Deadline);
}
[Fact]

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/RegisterInputTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Backend/RegisterInputTests.cs
@@ -37,11 +37,13 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Backend
var req = WabiSabiFactory.CreateInputsRegistrationRequest(key, round);
await using PostRequestHandler handler = new(cfg, new Prison(), arena, rpc);
+ var minAliceDeadline = DateTimeOffset.UtcNow + cfg.ConnectionConfirmationTimeout * 0.9;
var resp = await handler.RegisterInputAsync(req);
- Assert.NotEmpty(round.Alices);
+ var alice = Assert.Single(round.Alices);
Assert.NotNull(resp);
Assert.NotNull(resp.AmountCredentials);
Assert.NotNull(resp.WeightCredentials);
+ Assert.True(minAliceDeadline <= alice.Deadline);
}
[Fact]

MODIFY
WalletWasabi/WabiSabi/Backend/Models/Alice.cs
WalletWasabi/WabiSabi/Backend/Models/Alice.cs
@@ -16,7 +16,14 @@ namespace WalletWasabi.WabiSabi.Backend.Models
}
public Guid Id { get; } = Guid.NewGuid();
+ public DateTimeOffset Deadline { get; private set; } = DateTimeOffset.UtcNow;
public IEnumerable<Coin> Coins { get; }
public IDictionary<Coin, byte[]> CoinRoundSignaturePairs { get; }
+
+ public void SetDeadlineRelativeTo(TimeSpan connectionConfirmationTimeout)
+ {
+ // Have alice timeouts a bit sooner than the timeout of connection confirmation phase.
+ Deadline = DateTimeOffset.UtcNow + (connectionConfirmationTimeout * 0.9);
+ }
}
}

MODIFY
WalletWasabi/WabiSabi/Backend/Rounds/Round.cs
WalletWasabi/WabiSabi/Backend/Rounds/Round.cs
@@ -20,36 +20,46 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
public Round(
Network network,
uint maxInputCountByAlice,
- Money minRegistrableAmount,
- Money maxRegistrableAmount,
- uint minRegistrableWeight,
- uint maxRegistrableWeight,
+ Money minRegistrableAmountByAlice,
+ Money maxRegistrableAmountByAlice,
+ uint minRegistrableWeightByAlice,
+ uint maxRegistrableWeightByAlice,
+ TimeSpan connectionConfirmationTimeout,
+ TimeSpan outputRegistrationTimeout,
+ TimeSpan transactionSigningTimeout,
WasabiRandom random)
{
Network = network;
MaxInputCountByAlice = maxInputCountByAlice;
- MinRegistrableAmount = minRegistrableAmount;
- MaxRegistrableAmount = maxRegistrableAmount;
- MinRegistrableWeight = minRegistrableWeight;
- MaxRegistrableWeight = maxRegistrableWeight;
+ MinRegistrableAmountByAlice = minRegistrableAmountByAlice;
+ MaxRegistrableAmountByAlice = maxRegistrableAmountByAlice;
+ MinRegistrableWeightByAlice = minRegistrableWeightByAlice;
+ MaxRegistrableWeightByAlice = maxRegistrableWeightByAlice;
+
+ ConnectionConfirmationTimeout = connectionConfirmationTimeout;
+ OutputRegistrationTimeout = outputRegistrationTimeout;
+ TransactionSigningTimeout = transactionSigningTimeout;
Random = random;
- AmountCredentialIssuer = new(new CredentialIssuerSecretKey(Random), 2, random, MaxRegistrableAmount);
- WeightCredentialIssuer = new(new CredentialIssuerSecretKey(Random), 2, random, MaxRegistrableWeight);
+ AmountCredentialIssuer = new(new CredentialIssuerSecretKey(Random), 2, random, MaxRegistrableAmountByAlice);
+ WeightCredentialIssuer = new(new CredentialIssuerSecretKey(Random), 2, random, MaxRegistrableWeightByAlice);
AmountCredentialIssuerParameters = AmountCredentialIssuer.CredentialIssuerSecretKey.ComputeCredentialIssuerParameters();
WeightCredentialIssuerParameters = WeightCredentialIssuer.CredentialIssuerSecretKey.ComputeCredentialIssuerParameters();
- Hash = new uint256(HashHelpers.GenerateSha256Hash($"{Id}{MaxInputCountByAlice}{MinRegistrableAmount}{MaxRegistrableAmount}{MinRegistrableWeight}{MaxRegistrableWeight}{AmountCredentialIssuerParameters}{WeightCredentialIssuerParameters}"));
+ Hash = new uint256(HashHelpers.GenerateSha256Hash($"{Id}{MaxInputCountByAlice}{MinRegistrableAmountByAlice}{MaxRegistrableAmountByAlice}{MinRegistrableWeightByAlice}{MaxRegistrableWeightByAlice}{AmountCredentialIssuerParameters}{WeightCredentialIssuerParameters}"));
}
public Round(Round blameOf)
: this(
blameOf.Network,
blameOf.MaxInputCountByAlice,
- blameOf.MinRegistrableAmount,
- blameOf.MaxRegistrableAmount,
- blameOf.MinRegistrableWeight,
- blameOf.MaxRegistrableWeight,
+ blameOf.MinRegistrableAmountByAlice,
+ blameOf.MaxRegistrableAmountByAlice,
+ blameOf.MinRegistrableWeightByAlice,
+ blameOf.MaxRegistrableWeightByAlice,
+ blameOf.ConnectionConfirmationTimeout,
+ blameOf.OutputRegistrationTimeout,
+ blameOf.TransactionSigningTimeout,
blameOf.Random)
{
BlameOf = blameOf;
@@ -63,10 +73,13 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
public uint256 Hash { get; }
public Network Network { get; }
public uint MaxInputCountByAlice { get; }
- public Money MinRegistrableAmount { get; }
- public Money MaxRegistrableAmount { get; }
- public uint MinRegistrableWeight { get; }
- public uint MaxRegistrableWeight { get; }
+ public Money MinRegistrableAmountByAlice { get; }
+ public Money MaxRegistrableAmountByAlice { get; }
+ public uint MinRegistrableWeightByAlice { get; }
+ public uint MaxRegistrableWeightByAlice { get; }
+ public TimeSpan ConnectionConfirmationTimeout { get; }
+ public TimeSpan OutputRegistrationTimeout { get; }
+ public TimeSpan TransactionSigningTimeout { get; }
public WasabiRandom Random { get; }
public CredentialIssuer AmountCredentialIssuer { get; }
public CredentialIssuer WeightCredentialIssuer { get; }
@@ -125,20 +138,20 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
}
}
- if (inputValueSum < MinRegistrableAmount)
+ if (inputValueSum < MinRegistrableAmountByAlice)
{
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.NotEnoughFunds);
}
- if (inputValueSum > MaxRegistrableAmount)
+ if (inputValueSum > MaxRegistrableAmountByAlice)
{
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.TooMuchFunds);
}
- if (inputWeightSum < MinRegistrableWeight)
+ if (inputWeightSum < MinRegistrableWeightByAlice)
{
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.NotEnoughWeight);
}
- if (inputWeightSum > MaxRegistrableWeight)
+ if (inputWeightSum > MaxRegistrableWeightByAlice)
{
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.TooMuchWeight);
}
@@ -152,6 +165,7 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
{
throw new WabiSabiProtocolException(WabiSabiProtocolErrorCode.WrongPhase);
}
+ alice.SetDeadlineRelativeTo(ConnectionConfirmationTimeout);
Alices.Add(alice);
}
@@ -173,6 +187,7 @@ namespace WalletWasabi.WabiSabi.Backend.Rounds
if (Phase == Phase.InputRegistration)
{
+ alice.SetDeadlineRelativeTo(ConnectionConfirmationTimeout);
return new ConnectionConfirmationResponse(
amountZeroCredentialResponse,
weightZeroCredentialResponse);

MODIFY
WalletWasabi/WabiSabi/Backend/WabiSabiConfig.cs
WalletWasabi/WabiSabi/Backend/WabiSabiConfig.cs
@@ -67,5 +67,20 @@ namespace WalletWasabi.WabiSabi.Backend
[DefaultValue(true)]
[JsonProperty(PropertyName = "AllowNotedInputRegistration", DefaultValueHandling = DefaultValueHandling.Populate)]
public bool AllowNotedInputRegistration { get; set; } = true;
+
+ [DefaultValueTimeSpan("0d 0h 1m 0s")]
+ [JsonProperty(PropertyName = "ConnectionConfirmationTimeout", DefaultValueHandling = DefaultValueHandling.Populate)]
+ [JsonConverter(typeof(TimeSpanJsonConverter))]
+ public TimeSpan ConnectionConfirmationTimeout { get; set; } = TimeSpan.FromMinutes(1);
+
+ [DefaultValueTimeSpan("0d 0h 1m 0s")]
+ [JsonProperty(PropertyName = "OutputRegistrationTimeout", DefaultValueHandling = DefaultValueHandling.Populate)]
+ [JsonConverter(typeof(TimeSpanJsonConverter))]
+ public TimeSpan OutputRegistrationTimeout { get; set; } = TimeSpan.FromMinutes(1);
+
+ [DefaultValueTimeSpan("0d 0h 1m 0s")]
+ [JsonProperty(PropertyName = "TransactionSigningTimeout", DefaultValueHandling = DefaultValueHandling.Populate)]
+ [JsonConverter(typeof(TimeSpanJsonConverter))]
+ public TimeSpan TransactionSigningTimeout { get; set; } = TimeSpan.FromMinutes(1);
}
}

Introduce Alice deadline