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.
This commit is contained in:
199
bench/proof-chain/Benchmarks/ProofSpineAssemblyBenchmarks.cs
Normal file
199
bench/proof-chain/Benchmarks/ProofSpineAssemblyBenchmarks.cs
Normal file
@@ -0,0 +1,199 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
// 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; }
|
||||
}
|
||||
Reference in New Issue
Block a user