Files
git.stella-ops.org/bench/proof-chain/Benchmarks/ProofSpineAssemblyBenchmarks.cs
master 8bbfe4d2d2 feat(rate-limiting): Implement core rate limiting functionality with configuration, decision-making, metrics, middleware, and service registration
- Add RateLimitConfig for configuration management with YAML binding support.
- Introduce RateLimitDecision to encapsulate the result of rate limit checks.
- Implement RateLimitMetrics for OpenTelemetry metrics tracking.
- Create RateLimitMiddleware for enforcing rate limits on incoming requests.
- Develop RateLimitService to orchestrate instance and environment rate limit checks.
- Add RateLimitServiceCollectionExtensions for dependency injection registration.
2025-12-17 18:02:37 +02:00

200 lines
5.9 KiB
C#

// -----------------------------------------------------------------------------
// ProofSpineAssemblyBenchmarks.cs
// Sprint: SPRINT_0501_0001_0001_proof_evidence_chain_master
// Task: PROOF-MASTER-0005
// Description: Benchmarks for proof spine assembly and Merkle tree operations
// -----------------------------------------------------------------------------
using System.Security.Cryptography;
using BenchmarkDotNet.Attributes;
namespace StellaOps.Bench.ProofChain.Benchmarks;
/// <summary>
/// Benchmarks for proof spine assembly operations.
/// Target: Spine assembly (5 items) < 5ms.
/// </summary>
[MemoryDiagnoser]
[SimpleJob(warmupCount: 3, iterationCount: 10)]
public class ProofSpineAssemblyBenchmarks
{
private List<byte[]> _evidenceItems = null!;
private List<byte[]> _merkleLeaves = null!;
private byte[] _reasoning = null!;
private byte[] _vexVerdict = null!;
[Params(1, 5, 10, 50)]
public int EvidenceCount { get; set; }
[GlobalSetup]
public void Setup()
{
// Generate evidence items of varying sizes
_evidenceItems = Enumerable.Range(0, 100)
.Select(i =>
{
var data = new byte[1024 + (i * 100)]; // 1KB to ~10KB
RandomNumberGenerator.Fill(data);
return data;
})
.ToList();
// Merkle tree leaves
_merkleLeaves = Enumerable.Range(0, 100)
.Select(_ =>
{
var leaf = new byte[32];
RandomNumberGenerator.Fill(leaf);
return leaf;
})
.ToList();
// Reasoning and verdict
_reasoning = new byte[2048];
RandomNumberGenerator.Fill(_reasoning);
_vexVerdict = new byte[512];
RandomNumberGenerator.Fill(_vexVerdict);
}
/// <summary>
/// Assemble proof spine from evidence items.
/// Target: < 5ms for 5 items.
/// </summary>
[Benchmark]
public ProofSpineResult AssembleSpine()
{
var evidence = _evidenceItems.Take(EvidenceCount).ToList();
return AssembleProofSpine(evidence, _reasoning, _vexVerdict);
}
/// <summary>
/// Build Merkle tree from leaves.
/// Target: < 1ms for 100 leaves.
/// </summary>
[Benchmark]
public byte[] BuildMerkleTree()
{
return ComputeMerkleRoot(_merkleLeaves.Take(EvidenceCount).ToList());
}
/// <summary>
/// Generate deterministic bundle ID from spine.
/// Target: < 500μs.
/// </summary>
[Benchmark]
public string GenerateBundleId()
{
var spine = AssembleProofSpine(
_evidenceItems.Take(EvidenceCount).ToList(),
_reasoning,
_vexVerdict);
return ComputeBundleId(spine);
}
/// <summary>
/// Verify spine determinism (same inputs = same output).
/// </summary>
[Benchmark]
public bool VerifyDeterminism()
{
var evidence = _evidenceItems.Take(EvidenceCount).ToList();
var spine1 = AssembleProofSpine(evidence, _reasoning, _vexVerdict);
var spine2 = AssembleProofSpine(evidence, _reasoning, _vexVerdict);
return spine1.BundleId == spine2.BundleId;
}
#region Implementation
private static ProofSpineResult AssembleProofSpine(
List<byte[]> evidence,
byte[] reasoning,
byte[] vexVerdict)
{
// 1. Generate evidence IDs
var evidenceIds = evidence
.OrderBy(e => Convert.ToHexString(SHA256.HashData(e))) // Deterministic ordering
.Select(e => SHA256.HashData(e))
.ToList();
// 2. Build Merkle tree
var merkleRoot = ComputeMerkleRoot(evidenceIds);
// 3. Compute reasoning ID
var reasoningId = SHA256.HashData(reasoning);
// 4. Compute verdict ID
var verdictId = SHA256.HashData(vexVerdict);
// 5. Assemble bundle content
var bundleContent = new List<byte>();
bundleContent.AddRange(merkleRoot);
bundleContent.AddRange(reasoningId);
bundleContent.AddRange(verdictId);
// 6. Compute bundle ID
var bundleId = SHA256.HashData(bundleContent.ToArray());
return new ProofSpineResult
{
BundleId = $"sha256:{Convert.ToHexString(bundleId).ToLowerInvariant()}",
MerkleRoot = merkleRoot,
EvidenceIds = evidenceIds.Select(e => $"sha256:{Convert.ToHexString(e).ToLowerInvariant()}").ToList()
};
}
private static byte[] ComputeMerkleRoot(List<byte[]> leaves)
{
if (leaves.Count == 0)
return SHA256.HashData(Array.Empty<byte>());
if (leaves.Count == 1)
return leaves[0];
var currentLevel = leaves.ToList();
while (currentLevel.Count > 1)
{
var nextLevel = new List<byte[]>();
for (int i = 0; i < currentLevel.Count; i += 2)
{
if (i + 1 < currentLevel.Count)
{
// Hash pair
var combined = new byte[currentLevel[i].Length + currentLevel[i + 1].Length];
currentLevel[i].CopyTo(combined, 0);
currentLevel[i + 1].CopyTo(combined, currentLevel[i].Length);
nextLevel.Add(SHA256.HashData(combined));
}
else
{
// Odd node - promote
nextLevel.Add(currentLevel[i]);
}
}
currentLevel = nextLevel;
}
return currentLevel[0];
}
private static string ComputeBundleId(ProofSpineResult spine)
{
return spine.BundleId;
}
#endregion
}
/// <summary>
/// Result of proof spine assembly.
/// </summary>
public sealed class ProofSpineResult
{
public required string BundleId { get; init; }
public required byte[] MerkleRoot { get; init; }
public required List<string> EvidenceIds { get; init; }
}