52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
from fastapi import FastAPI, HTTPException
|
|
from typing import Dict
|
|
from .models import BondRecord, ClaimSubmission, ReplayBundle
|
|
from uuid import uuid4
|
|
from datetime import datetime
|
|
|
|
app = FastAPI(title="ReplicaSurety - Surety Ledger")
|
|
|
|
# Simple in-memory store. This is intentionally minimal and pluggable.
|
|
_BONDS: Dict[str, BondRecord] = {}
|
|
_CLAIMS: Dict[str, ClaimSubmission] = {}
|
|
|
|
|
|
@app.post("/bonds", response_model=BondRecord)
|
|
def create_bond(record: BondRecord):
|
|
if record.escrow_id in _BONDS:
|
|
raise HTTPException(status_code=400, detail="escrow_id already exists")
|
|
_BONDS[record.escrow_id] = record
|
|
return record
|
|
|
|
|
|
@app.get("/bonds/{escrow_id}", response_model=BondRecord)
|
|
def get_bond(escrow_id: str):
|
|
r = _BONDS.get(escrow_id)
|
|
if not r:
|
|
raise HTTPException(status_code=404, detail="not found")
|
|
return r
|
|
|
|
|
|
@app.post("/claims", response_model=ClaimSubmission)
|
|
def submit_claim(claim: ClaimSubmission):
|
|
if claim.claim_id in _CLAIMS:
|
|
raise HTTPException(status_code=400, detail="claim_id already submitted")
|
|
# Minimal validation: evidence_root looks present
|
|
if not claim.evidence_root:
|
|
raise HTTPException(status_code=400, detail="evidence_root required")
|
|
_CLAIMS[claim.claim_id] = claim
|
|
# In a real system: dispatch to verifier/adjudicator plugins
|
|
return claim
|
|
|
|
|
|
@app.post("/verify_replay")
|
|
def verify_replay(bundle: ReplayBundle):
|
|
# Minimal deterministic verifier: ensure trace seq monotonic and evidence root present
|
|
last_seq = -1
|
|
for ev in bundle.trace:
|
|
if ev.seq <= last_seq:
|
|
raise HTTPException(status_code=400, detail="non-monotonic trace sequence")
|
|
last_seq = ev.seq
|
|
# In a real verifier we'd replay deterministically and compute a DamageScore
|
|
return {"verdict": "ok", "evidence_root": bundle.evidence_root}
|