mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-06-13 09:37:53 +02:00
126 lines
4.2 KiB
Python
126 lines
4.2 KiB
Python
"""Bridge between Infonet economy events and the legacy ``mesh_hashchain``.
|
|
|
|
Sprint 1 ships this as a **dry-run-only** surface. We do NOT call the
|
|
legacy ``Infonet.append`` for new event types because that method
|
|
hard-rejects anything not in ``ACTIVE_APPEND_EVENT_TYPES`` (defined in
|
|
``mesh_schema.py``). Modifying that set is a Sprint 4 task — it requires
|
|
the rest of the producer code to exist, otherwise a malformed
|
|
``prediction_create`` could land on the chain with no resolver to
|
|
process it.
|
|
|
|
What this adapter DOES today:
|
|
|
|
- ``extended_active_event_types()`` — returns the union of legacy active
|
|
types and new economy types, for tooling that needs the full surface
|
|
(e.g. RPC layer, frontend type generation).
|
|
- ``InfonetHashchainAdapter.dry_run_append`` — validates a payload
|
|
against the new schema and returns the event dict the legacy
|
|
``Infonet.append`` would have built. Useful for tests and for the
|
|
future cutover plan.
|
|
|
|
What this adapter will do in Sprint 4:
|
|
|
|
- ``append_infonet_event`` — actually call ``Infonet.append`` once
|
|
``ACTIVE_APPEND_EVENT_TYPES`` is unioned with the economy types.
|
|
|
|
The Sprint 1 contract:
|
|
|
|
- ``mesh_hashchain.py`` is byte-identical to the pre-Sprint-1 baseline.
|
|
- No event reaches the legacy chain via this adapter in Sprint 1.
|
|
- Tests cover validation behavior only.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import json
|
|
import time
|
|
from typing import Any
|
|
|
|
from services.mesh.mesh_schema import (
|
|
ACTIVE_PUBLIC_LEDGER_EVENT_TYPES as _LEGACY_ACTIVE_TYPES,
|
|
)
|
|
|
|
from services.infonet.schema import (
|
|
INFONET_ECONOMY_EVENT_TYPES,
|
|
validate_infonet_event_payload,
|
|
)
|
|
|
|
|
|
def extended_active_event_types() -> frozenset[str]:
|
|
"""Union of legacy active types and new economy types.
|
|
|
|
Frozen at import time. The legacy set is itself a frozenset so this
|
|
is safe to call from any thread.
|
|
"""
|
|
return _LEGACY_ACTIVE_TYPES | INFONET_ECONOMY_EVENT_TYPES
|
|
|
|
|
|
class InfonetHashchainAdapter:
|
|
"""Validation-only adapter for new Infonet economy events.
|
|
|
|
Real chain integration lives in Sprint 4. Tests should use
|
|
``dry_run_append`` to assert that producer code is constructing
|
|
correctly-shaped events before the cutover.
|
|
"""
|
|
|
|
def dry_run_append(
|
|
self,
|
|
event_type: str,
|
|
node_id: str,
|
|
payload: dict[str, Any],
|
|
*,
|
|
sequence: int = 1,
|
|
timestamp: float | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Validate and return a synthetic event dict.
|
|
|
|
Mirrors the shape that ``mesh_hashchain.Infonet.append`` would
|
|
produce for legacy types — same field set, same ordering. Does
|
|
NOT compute a real signature (Sprint 4 territory) and does NOT
|
|
write to disk.
|
|
|
|
Raises ``ValueError`` on validation failure — the same exception
|
|
type the legacy ``append`` raises so callers don't need to
|
|
special-case the cutover later.
|
|
"""
|
|
if event_type not in INFONET_ECONOMY_EVENT_TYPES:
|
|
raise ValueError(f"event_type {event_type!r} not in INFONET_ECONOMY_EVENT_TYPES")
|
|
if not isinstance(node_id, str) or not node_id:
|
|
raise ValueError("node_id is required")
|
|
if not isinstance(sequence, int) or isinstance(sequence, bool) or sequence <= 0:
|
|
raise ValueError("sequence must be a positive integer")
|
|
|
|
ok, reason = validate_infonet_event_payload(event_type, payload)
|
|
if not ok:
|
|
raise ValueError(reason)
|
|
|
|
ts = float(timestamp) if timestamp is not None else float(time.time())
|
|
|
|
canonical = {
|
|
"event_type": event_type,
|
|
"node_id": node_id,
|
|
"payload": payload,
|
|
"timestamp": ts,
|
|
"sequence": sequence,
|
|
}
|
|
encoded = json.dumps(canonical, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
|
|
event_id = hashlib.sha256(encoded.encode("utf-8")).hexdigest()
|
|
|
|
return {
|
|
"event_id": event_id,
|
|
"event_type": event_type,
|
|
"node_id": node_id,
|
|
"timestamp": ts,
|
|
"sequence": sequence,
|
|
"payload": payload,
|
|
# signature / public_key intentionally omitted in Sprint 1.
|
|
"is_provisional": True,
|
|
}
|
|
|
|
|
|
__all__ = [
|
|
"InfonetHashchainAdapter",
|
|
"extended_active_event_types",
|
|
]
|