Skip to content
Permalink
Browse files

Add "noted" status for first round disrupting

  • Loading branch information...
nopara73 committed Nov 22, 2018
1 parent 52fe7c0 commit 378eb9d94fbb0434b5e276f9de7770853eecd2aa
@@ -17,6 +17,7 @@
using WalletWasabi.Backend.Models;
using WalletWasabi.Backend.Models.Requests;
using WalletWasabi.Backend.Models.Responses;
using WalletWasabi.Crypto;
using WalletWasabi.Exceptions;
using WalletWasabi.KeyManagement;
using WalletWasabi.Logging;
@@ -75,6 +76,7 @@ private async Task<(string password, RPCClient rpc, Network network, CcjCoordina
{
await Global.RpcClient.GenerateAsync(numberOfBlocksToGenerate); // Make sure everything is confirmed.
}
Global.Coordinator.UtxoReferee.Clear();
return ("password", Global.RpcClient, Global.RpcClient.Network, Global.Coordinator);
}

@@ -2062,6 +2064,82 @@ public async Task CcjTestsAsync()
}
}

[Fact, TestPriority(19)]
[Trait("Category", "RunOnCi")]
public async Task NotingTestsAsync()
{
(string password, RPCClient rpc, Network network, CcjCoordinator coordinator) = await InitializeTestEnvironmentAsync(1);

BlindingRsaKey blindingKey = coordinator.RsaKey;
Money denomination = Money.Coins(1m);
decimal coordinatorFeePercent = 0.1m;
int anonymitySet = 2;
int connectionConfirmationTimeout = 1;
bool doesNoteBeforeBan = true;
CcjRoundConfig roundConfig = new CcjRoundConfig(denomination, 140, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, doesNoteBeforeBan);
coordinator.UpdateRoundConfig(roundConfig);
coordinator.AbortAllRoundsInInputRegistration(nameof(RegTests), "");

Uri baseUri = new Uri(RegTestFixture.BackendEndPoint);

var registerRequests = new List<(BitcoinWitPubKeyAddress changeOutputAddress, byte[] blindedData, InputProofModel[] inputsProofs)>();
for (int i = 0; i < roundConfig.AnonymitySet; i++)
{
BitcoinWitPubKeyAddress activeOutputAddress = new Key().PubKey.GetSegwitAddress(network);
BitcoinWitPubKeyAddress changeOutputAddress = new Key().PubKey.GetSegwitAddress(network);
Key inputKey = new Key();
BitcoinWitPubKeyAddress inputAddress = inputKey.PubKey.GetSegwitAddress(network);
var blinded = blindingKey.PubKey.Blind(activeOutputAddress.ScriptPubKey.ToBytes());

uint256 txHash = await rpc.SendToAddressAsync(inputAddress, Money.Coins(2));
await rpc.GenerateAsync(1);
Transaction transaction = await rpc.GetRawTransactionAsync(txHash);
Coin coin = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single();
OutPoint input = coin.Outpoint;

InputProofModel inputProof = new InputProofModel { Input = input.ToTxoRef(), Proof = inputKey.SignMessage(ByteHelpers.ToHex(blinded.BlindedData)) };
InputProofModel[] inputsProofs = new InputProofModel[] { inputProof };
registerRequests.Add((changeOutputAddress, blinded.BlindedData, inputsProofs));
await AliceClient.CreateNewAsync(network, changeOutputAddress, blinded.BlindedData, inputsProofs, baseUri);
}

await WaitForTimeoutAsync(baseUri);

int bannedCount = coordinator.UtxoReferee.CountBanned(false);
Assert.Equal(0, bannedCount);
int notedCount = coordinator.UtxoReferee.CountBanned(true);
Assert.Equal(anonymitySet, notedCount);

foreach (var registerRequest in registerRequests)
{
await AliceClient.CreateNewAsync(network, registerRequest.changeOutputAddress, registerRequest.blindedData, registerRequest.inputsProofs, baseUri);
}

await WaitForTimeoutAsync(baseUri);

bannedCount = coordinator.UtxoReferee.CountBanned(false);
Assert.Equal(anonymitySet, bannedCount);
notedCount = coordinator.UtxoReferee.CountBanned(true);
Assert.Equal(anonymitySet, notedCount);
}

private static async Task WaitForTimeoutAsync(Uri baseUri)
{
using (var satoshiClient = new SatoshiClient(baseUri))
{
var times = 0;
while (!(await satoshiClient.GetAllRoundStatesAsync()).All(x => x.Phase == CcjRoundPhase.InputRegistration))
{
await Task.Delay(100);
if (times > 50) // 5 sec, 3 should be enough
{
throw new TimeoutException("Not all rouns were in InputRegistration.");
}
times++;
}
}
}

[Fact, TestPriority(19)]
[Trait("Category", "RunOnCi")]
public async Task BanningTestsAsync()
@@ -157,7 +157,7 @@ public CcjRound(RPCClient rpc, UtxoReferee utxoReferee, CcjRoundConfig config)
Logger.LogInfo<CcjRound>($"New round ({RoundId}) is created.\n\t" +
$"{nameof(Denomination)}: {Denomination.ToString(false, true)} BTC.\n\t" +
$"{nameof(ConfirmationTarget)}: {ConfirmationTarget}.\n\t" +
$"{nameof(CoordinatorFeePercent)}: {CoordinatorFeePercent}.\n\t" +
$"{nameof(CoordinatorFeePercent)}: {CoordinatorFeePercent}%.\n\t" +
$"{nameof(AnonymitySet)}: {AnonymitySet}.");
}
catch (Exception ex)
@@ -96,8 +96,7 @@ public async Task BanUtxosAsync(int severity, DateTimeOffset timeOfBan, bool for
}

var lines = new List<string>();
var append = false;
var updatedOrAdded = false;
var updated = false;
foreach (var utxo in toBan)
{
var isNoted = true;
@@ -126,51 +125,32 @@ public async Task BanUtxosAsync(int severity, DateTimeOffset timeOfBan, bool for
isNoted = false;
}
}
if (!BannedUtxos.TryAdd(utxo, (severity, timeOfBan, isNoted, bannedForRound)))
if (BannedUtxos.TryAdd(utxo, (severity, timeOfBan, isNoted, bannedForRound)))
{
string line = $"{timeOfBan.ToString(CultureInfo.InvariantCulture)}:{severity}:{utxo.N}:{utxo.Hash}:{isNoted}:{bannedForRound}";
lines.Add(line);
}
else
{
var elem = BannedUtxos[utxo];
if (elem.severity != severity)
{
elem.severity = severity;
updatedOrAdded = true;
}
if (elem.isNoted != isNoted)
{
elem.isNoted = isNoted;
updatedOrAdded = true;
}
if (elem.bannedForRound != bannedForRound)
{
elem.bannedForRound = bannedForRound;
updatedOrAdded = true;
BannedUtxos[utxo] = (elem.severity, elem.timeOfBan, isNoted, elem.bannedForRound);
updated = true;
}
}
else
{
append = true;
updatedOrAdded = true;

string line = $"{timeOfBan.ToString(CultureInfo.InvariantCulture)}:{severity}:{utxo.N}:{utxo.Hash}:{isNoted}:{bannedForRound}";
lines.Add(line);
}

Logger.LogInfo<UtxoReferee>($"UTXO {(isNoted ? "noted" : "banned")} with severity: {severity}. UTXO: {utxo.N}:{utxo.Hash}.");
}

if (updatedOrAdded)
if (updated) // If at any time we set updated then we must update the whole thing.
{
if (append)
{
if (lines.Count != 0)
{
await File.AppendAllLinesAsync(BannedUtxosFilePath, lines);
}
}
else
{
var allLines = BannedUtxos.Select(x => $"{x.Value.timeOfBan.ToString(CultureInfo.InvariantCulture)}:{x.Value.severity}:{x.Key.N}:{x.Key.Hash}:{x.Value.isNoted}:{x.Value.bannedForRound}");
await File.WriteAllLinesAsync(BannedUtxosFilePath, allLines);
}
var allLines = BannedUtxos.Select(x => $"{x.Value.timeOfBan.ToString(CultureInfo.InvariantCulture)}:{x.Value.severity}:{x.Key.N}:{x.Key.Hash}:{x.Value.isNoted}:{x.Value.bannedForRound}");
await File.WriteAllLinesAsync(BannedUtxosFilePath, allLines);
}
else if (lines.Count != 0) // If we don't have to update the whole thing, we must check if we added a line and so only append.
{
await File.AppendAllLinesAsync(BannedUtxosFilePath, lines);
}
}

@@ -228,5 +208,11 @@ public int CountBanned(bool notedToo)
return BannedUtxos.Count(x => !x.Value.isNoted);
}
}

public void Clear()
{
BannedUtxos.Clear();
File.Delete(BannedUtxosFilePath);
}
}
}

0 comments on commit 378eb9d

Please sign in to comment.
You can’t perform that action at this time.