4. Automated Validation & Rate Limits
What this layer does
Validation rules
Example: minimal validator (TypeScript)
type Window = {
batch_id: `0x${string}`;
device_id: `0x${string}`;
start_ts: number; // UTC seconds
end_ts: number; // UTC seconds
quantity_wh: number;
nonce: `0x${string}`;
};
type Now = () => number; // ms
export function validateWindow(
payloadCanonicalJson: string,
headers: { xDeviceId: string; xWindowId: string; xNonce: string; xTimestamp: number },
opts: {
now: Now;
minDurSec: number; maxDurSec: number;
maxSkewMs: number;
ratedWhPerWindow: number;
lastWindows: Array<{start_ts:number; end_ts:number}>;
seenBatchIds: Set<string>;
seenNoncesByDevice: Map<string, Set<string>>;
idempotentStore: Map<string, string>; // batch_id -> canonical JSON
}
) {
// 1) Canonical match
const parsed = JSON.parse(payloadCanonicalJson) as Window;
const reCanon = JSON.stringify(parsed, Object.keys(parsed).sort().reduce((o,k)=>(o[k]=parsed[k as keyof Window],o),{} as any)).replace(/\s+/g,'');
if (reCanon !== payloadCanonicalJson) throw new Error("NON_CANONICAL_JSON");
// 2) Header congruence
if (headers.xDeviceId !== parsed.device_id) throw new Error("SCHEMA_INVALID");
if (headers.xWindowId !== parsed.batch_id) throw new Error("SCHEMA_INVALID");
if (headers.xNonce !== parsed.nonce) throw new Error("SCHEMA_INVALID");
// 3) Window integrity
if (!(parsed.start_ts < parsed.end_ts)) throw new Error("SCHEMA_INVALID");
const dur = parsed.end_ts - parsed.start_ts;
if (dur < opts.minDurSec || dur > opts.maxDurSec) throw new Error("OUT_OF_BOUNDS");
// 4) Timestamp skew
const skew = Math.abs(opts.now() - headers.xTimestamp);
if (skew > opts.maxSkewMs) throw new Error("TIMESTAMP_SKEW");
// 5) Overlap check for this device
for (const w of opts.lastWindows) {
const overlap = Math.max(0, Math.min(parsed.end_ts, w.end_ts) - Math.max(parsed.start_ts, w.start_ts));
if (overlap > 0) throw new Error("OVERLAPPING_WINDOW");
}
// 6) Plausibility
if (parsed.quantity_wh < 0) throw new Error("NEGATIVE_QUANTITY");
if (parsed.quantity_wh > opts.ratedWhPerWindow * 1.15) throw new Error("OUT_OF_BOUNDS");
// 7) Duplicate batch id (idempotent upsert)
if (opts.seenBatchIds.has(parsed.batch_id)) {
const prior = opts.idempotentStore.get(parsed.batch_id);
if (prior !== payloadCanonicalJson) throw new Error("DUPLICATE_BATCH");
}
// 8) Nonce replay per device
const nonces = opts.seenNoncesByDevice.get(parsed.device_id) ?? new Set<string>();
if (nonces.has(parsed.nonce)) throw new Error("REPLAY_NONCE");
// if all good, record idempotently
opts.seenBatchIds.add(parsed.batch_id);
nonces.add(parsed.nonce);
opts.seenNoncesByDevice.set(parsed.device_id, nonces);
opts.idempotentStore.set(parsed.batch_id, payloadCanonicalJson);
return parsed; // safe to hash and attest
}Clear outcomes
Conformance
Last updated
