myco-bonding-curve/src/crdt/bridge/peer.py

64 lines
2.4 KiB
Python

"""PeerState and merge_peers — composite CRDT state per peer.
Wraps all 6 CRDT modules into a single PeerState dataclass and provides
a unified merge_peers() that calls each module's merge function.
"""
from dataclasses import dataclass, field
from src.crdt.labor_crdt import CRDTLaborSystem, merge_labor
from src.crdt.intent_matching import IntentSet, merge_intents
from src.crdt.flow_dampening import CRDTFlowSystem, merge_flow_states
from src.crdt.trust_pamm import PeerTrustState, merge_trust
from src.crdt.credit_invariant import CreditPortfolio, merge_portfolios
from src.crdt.dca_schedule import DCAScheduleRegistry, merge_dca_schedules
@dataclass
class PeerState:
"""Composite CRDT state for a single peer in the network.
Holds one instance of each of the 6 CRDT modules. All fields
default to empty/initial state so peers start clean.
"""
labor: CRDTLaborSystem = field(default_factory=CRDTLaborSystem)
intents: IntentSet = field(default_factory=IntentSet)
flows: CRDTFlowSystem = field(default_factory=CRDTFlowSystem)
trust: PeerTrustState = field(default_factory=PeerTrustState)
credit: CreditPortfolio = field(default_factory=CreditPortfolio)
dca: DCAScheduleRegistry = field(default_factory=DCAScheduleRegistry)
def merge_peers(a: PeerState, b: PeerState) -> PeerState:
"""Merge two peer states by calling all 6 CRDT merge functions.
Commutative, associative, and idempotent — inherits these properties
from each underlying merge function.
"""
return PeerState(
labor=merge_labor(a.labor, b.labor),
intents=merge_intents(a.intents, b.intents),
flows=merge_flow_states(a.flows, b.flows),
trust=merge_trust(a.trust, b.trust),
credit=merge_portfolios(a.credit, b.credit),
dca=merge_dca_schedules(a.dca, b.dca),
)
def _state_signature(peer: PeerState) -> tuple:
"""Hash-like signature of a peer's CRDT collection sizes.
Used for divergence detection — peers with the same signature
have converged (same number of entries in each collection).
"""
return (
len(peer.labor.logs),
sum(len(log.entries) for log in peer.labor.logs.values()),
len(peer.intents.intents),
len(peer.flows.peers),
len(peer.trust.peers),
len(peer.credit.lines),
len(peer.dca.schedules),
sum(len(s.chunks) for s in peer.dca.schedules.values()),
)