Fix naming violations and code suggestions
MODIFY
WalletWasabi.Tests/Helpers/DependencyGraphExtensions.cs
WalletWasabi.Tests/Helpers/DependencyGraphExtensions.cs
@@ -34,7 +34,7 @@ namespace WalletWasabi.Tests.Helpers
output += " {\n";
output += $" edge [color={color}, fontcolor={color}];\n";
- foreach (var e in g.edgeSets[credentialType].Predecessors.Values.Aggregate((a, b) => a.Union(b)).OrderByDescending(e => e.Value).ThenBy(e => id(e.From)).ThenBy(e => id(e.To)))
+ foreach (var e in g.EdgeSets[credentialType].Predecessors.Values.Aggregate((a, b) => a.Union(b)).OrderByDescending(e => e.Value).ThenBy(e => id(e.From)).ThenBy(e => id(e.To)))
{
output += $" {id(e.From)} -> {id(e.To)} [label=\"{e.Value}{unit}\"{(e.Value == 0 ? ", style=dashed" : "")}];\n";
}

MODIFY
WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs
WalletWasabi.Tests/UnitTests/WabiSabi/Client/CredentialDependencyTests.cs
@@ -12,18 +12,18 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
public class CredentialDependencyTests
{
[Fact]
- public async void AsyncDependencyGraphTraversal()
+ public async void AsyncDependencyGraphTraversalAsync()
{
var g = DependencyGraph.ResolveCredentialDependencies(
inputValues: new[] { new ulong[] { 10000, 1930 }, new ulong[] { 1000, 1930 } },
outputValues: new[] { new ulong[] { 5000, 31 }, new ulong[] { 3500, 31 }, new ulong[] { 2500, 31 } });
- await SimulateAsyncRequests(g);
+ await SimulateAsyncRequestsAsync(g);
}
// Demonstrate how to use the dependency grap. Also checks it can be
// executed with no deadlocks.
- private async Task SimulateAsyncRequests(DependencyGraph g)
+ private async Task SimulateAsyncRequestsAsync(DependencyGraph g)
{
// Keep track of the partial sets credentials to present. Requests
// that are keys in this dictionary are still waiting to be sent.
@@ -33,7 +33,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
// need to be presented is incomplete. Since input registrations and
// connection confirmation are modeled as a single node with in
// degree 0, they are never blocked.
- ImmutableArray<RequestNode> unblockedRequests() => pendingCredentialsToPresent.Keys.Where(node => DependencyGraph.CredentialTypes.All(t => g.InDegree(node, t) == pendingCredentialsToPresent[node][t].Count)).ToImmutableArray();
+ ImmutableArray<RequestNode> UnblockedRequests() => pendingCredentialsToPresent.Keys.Where(node => DependencyGraph.CredentialTypes.All(t => g.InDegree(node, t) == pendingCredentialsToPresent[node][t].Count)).ToImmutableArray();
// Also keep track of the in-flight requests
var inFlightRequests = new List<(Task<ImmutableSortedDictionary<CredentialType, IEnumerable<ulong>>> Task, ImmutableSortedDictionary<CredentialType, IEnumerable<CredentialDependency>> Dependencies)>();
@@ -71,7 +71,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
// Clear unblocked but waiting requests. Not very efficient
// (quadratic complexity), but good enough for demonstration
// purposes.
- foreach (var node in unblockedRequests())
+ foreach (var node in UnblockedRequests())
{
// FIXME this is a little ugly, how should it look in the real code? seems like we're missing an abstraction
var edgesByType = DependencyGraph.CredentialTypes.ToImmutableSortedDictionary(t => t, t => g.OutEdges(node, t));
@@ -177,7 +177,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
Assert.Equal(g.Vertices[1], nonZeroEdge.To);
Assert.Empty(g.OutEdges(nonZeroEdge.To, CredentialType.Amount));
Assert.Equal(2, g.InEdges(nonZeroEdge.To, CredentialType.Amount).Count());
- Assert.Equal(1, g.InEdges(nonZeroEdge.To, CredentialType.Amount).Select(e => e.From).Distinct().Count());
+ Assert.Single(g.InEdges(nonZeroEdge.To, CredentialType.Amount).Select(e => e.From).Distinct());
Assert.Empty(g.OutEdges(nonZeroEdge.To, CredentialType.Vsize));
Assert.Equal(2, g.InEdges(nonZeroEdge.To, CredentialType.Vsize).Count());
Assert.Equal(2, g.InEdges(nonZeroEdge.To, CredentialType.Vsize).Select(e => e.Value == 0).Count());
@@ -253,7 +253,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
[InlineData("21,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1", "11,5 10,5 10,5 10,6", 42)]
[InlineData("21,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1", "10,5 10,5 10,5 10,6", 43)]
[InlineData("21,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1", "10,5 10,5 10,5 10,5", 42)]
- public async void ResolveCredentialDependencies(string inputs, string outputs, int finalVertexCount)
+ public async void ResolveCredentialDependenciesAsync(string inputs, string outputs, int finalVertexCount)
{
// blackbox tests (apart from finalVertexCount, which leaks
// information about implementation) covering valid range
@@ -274,7 +274,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
// TODO when sum(in) == sum(out) for all credential types, also
// verify the reverse graph can be resolved.
- await SimulateAsyncRequests(g);
+ await SimulateAsyncRequestsAsync(g);
}
private void AssertResolvedGraphInvariants(DependencyGraph graph, IEnumerable<IEnumerable<ulong>> inputValues, IEnumerable<IEnumerable<ulong>> outputValues)
@@ -354,7 +354,7 @@ namespace WalletWasabi.Tests.UnitTests.WabiSabi.Client
var i = g.Inputs[0];
var o = g.Outputs[0];
- var edgeSet = g.edgeSets[0];
+ var edgeSet = g.EdgeSets[0];
Assert.Equal(2, DependencyGraph.K);

MODIFY
WalletWasabi/WabiSabi/Client/CredentialDependencies/DependencyGraph.cs
WalletWasabi/WabiSabi/Client/CredentialDependencies/DependencyGraph.cs
@@ -23,19 +23,19 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
public ImmutableList<RequestNode> Reissuances { get; init; } = ImmutableList<RequestNode>.Empty;
// Internal properties used to keep track of effective values and edges
- public ImmutableSortedDictionary<CredentialType, CredentialEdgeSet> edgeSets { get; init; } = ImmutableSortedDictionary<CredentialType, CredentialEdgeSet>.Empty
+ public ImmutableSortedDictionary<CredentialType, CredentialEdgeSet> EdgeSets { get; init; } = ImmutableSortedDictionary<CredentialType, CredentialEdgeSet>.Empty
.Add(CredentialType.Amount, new() { CredentialType = CredentialType.Amount })
.Add(CredentialType.Vsize, new() { CredentialType = CredentialType.Vsize });
- public long Balance(RequestNode node, CredentialType credentialType) => edgeSets[credentialType].Balance(node);
+ public long Balance(RequestNode node, CredentialType credentialType) => EdgeSets[credentialType].Balance(node);
- public IEnumerable<CredentialDependency> InEdges(RequestNode node, CredentialType credentialType) => edgeSets[credentialType].InEdges(node);
+ public IEnumerable<CredentialDependency> InEdges(RequestNode node, CredentialType credentialType) => EdgeSets[credentialType].InEdges(node);
- public IEnumerable<CredentialDependency> OutEdges(RequestNode node, CredentialType credentialType) => edgeSets[credentialType].OutEdges(node);
+ public IEnumerable<CredentialDependency> OutEdges(RequestNode node, CredentialType credentialType) => EdgeSets[credentialType].OutEdges(node);
- public int InDegree(RequestNode node, CredentialType credentialType) => edgeSets[credentialType].InDegree(node);
+ public int InDegree(RequestNode node, CredentialType credentialType) => EdgeSets[credentialType].InDegree(node);
- public int OutDegree(RequestNode node, CredentialType credentialType) => edgeSets[credentialType].OutDegree(node);
+ public int OutDegree(RequestNode node, CredentialType credentialType) => EdgeSets[credentialType].OutDegree(node);
/// <summary>Construct a graph from amounts, and resolve the
/// credential dependencies.</summary>
@@ -56,9 +56,9 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
foreach (var credentialType in CredentialTypes)
{
- long credentialTypeValue(IEnumerable<ulong> x) => (long)x.ElementAt((int)credentialType);
+ long CredentialTypeValue(IEnumerable<ulong> x) => (long)x.ElementAt((int)credentialType);
- if (inputValues.Sum(credentialTypeValue) < outputValues.Sum(credentialTypeValue))
+ if (inputValues.Sum(CredentialTypeValue) < outputValues.Sum(CredentialTypeValue))
{
throw new ArgumentException("Overall balance must not be negative.");
}
@@ -71,7 +71,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
=> this with
{
Vertices = Vertices.Add(node),
- edgeSets = edgeSets.ToImmutableSortedDictionary(
+ EdgeSets = EdgeSets.ToImmutableSortedDictionary(
kvp => kvp.Key,
kvp => kvp.Value with
{
@@ -185,7 +185,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
{
var g = ResolveUniformInputSpecialCases(credentialType);
- var edgeSet = g.edgeSets[credentialType];
+ var edgeSet = g.EdgeSets[credentialType];
var positive = g.Vertices.Where(v => edgeSet.Balance(v) > 0);
var negative = g.Vertices.Where(v => edgeSet.Balance(v) < 0);
@@ -228,7 +228,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
private DependencyGraph ResolveUniformInputSpecialCases(CredentialType credentialType)
{
- var edgeSet = edgeSets[credentialType];
+ var edgeSet = EdgeSets[credentialType];
// Evaluate the linq query eagerly since edgeSet is reassigned
IEnumerable<RequestNode> negative = Vertices.Where(v => edgeSet.Balance(v) < 0).OrderBy(v => edgeSet.Balance(v)).ToImmutableArray();
@@ -254,26 +254,26 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
{
// And if the total amount of the uniform unconstrained nodes is
// larger than the negative nodes, with room to spare
- if (unconstrainedPositive.Count() * edgeSet.Balance(unconstrainedPositive.First()) > -1 * negative.Count() * edgeSet.Balance(negative.First()))
+ if (unconstrainedPositive.Length * edgeSet.Balance(unconstrainedPositive.First()) > -1 * negative.Count() * edgeSet.Balance(negative.First()))
{
// Aggregate the negative nodes if they are more numerous.
// Reducing to `unconstrainedPositive.Count()` (which can be
// significantly larger than K) creates a more balanced
// structure for the next special case, or later iterations.
- if (negative.Count() > unconstrainedPositive.Count())
+ if (negative.Count() > unconstrainedPositive.Length)
{
- (g, negative) = g.ReduceNodes(negative, unconstrainedPositive.Count(), credentialType);
+ (g, negative) = g.ReduceNodes(negative, unconstrainedPositive.Length, credentialType);
}
}
}
- edgeSet = g.edgeSets[credentialType];
+ edgeSet = g.EdgeSets[credentialType];
// Second special case, more general than the previous one.
// If negative nodes are all strictly smaller than the corresponding
// positive nodes (not necessarily of uniform value), discharge them
// in a 1:1 correspondence.
- if (negative.Count() <= unconstrainedPositive.Count() && Enumerable.Zip(unconstrainedPositive, negative).All(p => edgeSet.Balance(p.First) + edgeSet.Balance(p.Second) >= 0))
+ if (negative.Count() <= unconstrainedPositive.Length && Enumerable.Zip(unconstrainedPositive, negative).All(p => edgeSet.Balance(p.First) + edgeSet.Balance(p.Second) >= 0))
{
g = Enumerable.Zip(unconstrainedPositive, negative).Aggregate(g, (g, p) => g.DrainTerminal(p.First, new RequestNode[] { p.Second }, credentialType));
}
@@ -290,7 +290,6 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
return (this, nodes);
}
-
// Replace up to k nodes, possibly the entire queue, with a
// single reissuance node which combines their values. The total
// number of items might be less than K but still larger than
@@ -330,9 +329,9 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
private DependencyGraph DrainReissuance(RequestNode reissuance, IEnumerable<RequestNode> nodes, CredentialType credentialType)
{
- var drainedEdgeSet = edgeSets[credentialType].DrainReissuance(reissuance, nodes);
+ var drainedEdgeSet = EdgeSets[credentialType].DrainReissuance(reissuance, nodes);
- var g = this with { edgeSets = edgeSets.SetItem(credentialType, drainedEdgeSet) };
+ var g = this with { EdgeSets = EdgeSets.SetItem(credentialType, drainedEdgeSet) };
// Also drain all subsequent credential types, to minimize
// dependencies between different requests, weight credentials
@@ -358,7 +357,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
// Here we avoid opportunistically adding edges of other types as it
// provides no benefit with K=2. Stable sorting prevents edge
// crossing to a limited degree, but could be much better.
- => this with { edgeSets = edgeSets.SetItem(credentialType, edgeSets[credentialType].DrainTerminal(node, nodes)) };
+ => this with { EdgeSets = EdgeSets.SetItem(credentialType, EdgeSets[credentialType].DrainTerminal(node, nodes)) };
private DependencyGraph ResolveZeroCredentials(CredentialType credentialType)
{
@@ -370,7 +369,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
// - discharge to direct descendents even if a net reduction in zero creds because of available zero out degree of 0
// - discharge all remaining in degree >0 nodes by topological order
- var edgeSet = edgeSets[credentialType];
+ var edgeSet = EdgeSets[credentialType];
var unresolvedNodes = Vertices.Where(v => edgeSet.RemainingInDegree(v) > 0 && edgeSet.AvailableZeroOutDegree(v) > 0).OrderByDescending(v => edgeSet.AvailableZeroOutDegree(v));
if (!unresolvedNodes.Any())
@@ -398,7 +397,7 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
// This termination condition is guaranteed to be possible because
// connection confirmation and reissuance requests both have an out
// degree of K^2 when accounting for their extra zero credentials.
- var edgeSet = edgeSets[credentialType];
+ var edgeSet = EdgeSets[credentialType];
var unresolvedNodes = Vertices.Where(v => edgeSet.RemainingInDegree(v) > 0).OrderByDescending(v => edgeSet.AvailableZeroOutDegree(v));
if (!unresolvedNodes.Any())
@@ -419,9 +418,9 @@ namespace WalletWasabi.WabiSabi.Client.CredentialDependencies
}
private DependencyGraph DrainZeroCredentials(RequestNode from, RequestNode to, CredentialType credentialType)
- => this with { edgeSets = edgeSets.SetItem(credentialType, edgeSets[credentialType].DrainZeroCredentials(from, to)) };
+ => this with { EdgeSets = EdgeSets.SetItem(credentialType, EdgeSets[credentialType].DrainZeroCredentials(from, to)) };
private DependencyGraph AddZeroCredential(RequestNode from, RequestNode to, CredentialType credentialType)
- => this with { edgeSets = edgeSets.SetItem(credentialType, edgeSets[credentialType].AddZeroEdge(from, to)) };
+ => this with { EdgeSets = EdgeSets.SetItem(credentialType, EdgeSets[credentialType].AddZeroEdge(from, to)) };
}
}

Fix naming violations and code suggestions