private void AssertResolvedGraphInvariants(DependencyGraph graph, IEnumerable <IEnumerable <long> > inputValues, IEnumerable <IEnumerable <long> > outputValues) { foreach (var credentialType in DependencyGraph.CredentialTypes) { // Input nodes foreach (var node in graph.Vertices.Take(inputValues.Count())) { var balance = graph.Balance(node, credentialType); Assert.True(balance >= 0); if (credentialType == CredentialType.Vsize) { Assert.InRange(balance, 0, ProtocolConstants.MaxVsizeCredentialValue); } Assert.Equal(0, node.MaxInDegree); Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType)); var outDegree = graph.OutDegree(node, credentialType); Assert.InRange(outDegree, 0, DependencyGraph.K - (balance == 0 ? 0 : 1)); // for amount creds, 1..K? } // Output nodes foreach (var node in graph.Vertices.Skip(inputValues.Count()).Take(outputValues.Count())) { var balance = graph.Balance(node, credentialType); Assert.Equal(0, balance); Assert.Equal(DependencyGraph.K, node.MaxInDegree); Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType)); Assert.Equal(0, node.MaxOutDegree); Assert.Equal(0, node.MaxZeroOnlyOutDegree); Assert.Equal(0, graph.OutDegree(node, credentialType)); } // Reissuance nodes foreach (var node in graph.Vertices.Skip(inputValues.Count() + outputValues.Count())) { var balance = graph.Balance(node, credentialType); Assert.True(balance >= 0); if (credentialType == CredentialType.Vsize) { Assert.InRange(balance, 0, ProtocolConstants.MaxVsizeCredentialValue); } Assert.Equal(DependencyGraph.K, node.MaxInDegree); Assert.Equal(node.MaxInDegree, graph.InDegree(node, credentialType)); var outDegree = graph.OutDegree(node, credentialType); Assert.InRange(outDegree, 0, DependencyGraph.K - (balance == 0 ? 0 : 1)); } } // Ensure that vsize credentials do not exceed the range proof width foreach (var edge in graph.EdgeSets[CredentialType.Vsize].Successors.Values.SelectMany(x => x)) { Assert.InRange <long>(edge.Value, 0, ProtocolConstants.MaxVsizeCredentialValue); } // TODO add InlineData param for max depth? // TODO assert max depth < ceil(log count)? }