78 lines
2.7 KiB
C#
78 lines
2.7 KiB
C#
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace StellaOps.Provcache.Api;
|
|
|
|
public static partial class ProvcacheEndpointExtensions
|
|
{
|
|
/// <summary>
|
|
/// POST /v1/provcache/proofs/{proofRoot}/verify
|
|
/// </summary>
|
|
private static async Task<IResult> VerifyProofAsync(
|
|
string proofRoot,
|
|
[FromServices] IEvidenceChunkRepository chunkRepository,
|
|
[FromServices] IEvidenceChunker chunker,
|
|
ILogger<ProofsApiEndpoints> logger,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
logger.LogDebug("POST /v1/provcache/proofs/{ProofRoot}/verify", proofRoot);
|
|
|
|
try
|
|
{
|
|
var chunks = await chunkRepository.GetChunksAsync(proofRoot, cancellationToken);
|
|
if (chunks.Count == 0)
|
|
{
|
|
return Results.NotFound();
|
|
}
|
|
|
|
var orderedChunks = chunks.OrderBy(c => c.ChunkIndex).ToList();
|
|
var chunkResults = new List<ChunkVerificationResult>();
|
|
var allValid = true;
|
|
|
|
foreach (var chunk in orderedChunks)
|
|
{
|
|
var isValid = chunker.VerifyChunk(chunk);
|
|
var computedHash = isValid ? chunk.ChunkHash : ComputeChunkHash(chunk.Blob);
|
|
|
|
chunkResults.Add(new ChunkVerificationResult
|
|
{
|
|
Index = chunk.ChunkIndex,
|
|
IsValid = isValid,
|
|
ExpectedHash = chunk.ChunkHash,
|
|
ComputedHash = isValid ? null : computedHash
|
|
});
|
|
|
|
if (!isValid)
|
|
{
|
|
allValid = false;
|
|
}
|
|
}
|
|
|
|
// Verify Merkle root
|
|
var chunkHashes = orderedChunks.Select(c => c.ChunkHash).ToList();
|
|
var computedRoot = chunker.ComputeMerkleRoot(chunkHashes);
|
|
var rootMatches = string.Equals(computedRoot, proofRoot, StringComparison.OrdinalIgnoreCase);
|
|
|
|
return Results.Ok(new ProofVerificationResponse
|
|
{
|
|
ProofRoot = proofRoot,
|
|
IsValid = allValid && rootMatches,
|
|
ChunkResults = chunkResults,
|
|
Error = !rootMatches ? $"Merkle root mismatch. Expected: {proofRoot}, Computed: {computedRoot}" : null
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Error verifying proof root {ProofRoot}", proofRoot);
|
|
return InternalError("Proof verification failed");
|
|
}
|
|
}
|
|
|
|
private static string ComputeChunkHash(byte[] data)
|
|
{
|
|
var hash = System.Security.Cryptography.SHA256.HashData(data);
|
|
return $"sha256:{Convert.ToHexStringLower(hash)}";
|
|
}
|
|
}
|