mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-06 20:43:46 +08:00
321 lines
11 KiB
Python
321 lines
11 KiB
Python
"""Explicit full30 original-anchor envelope. No storage or driving authority."""
|
|
|
|
from dataclasses import dataclass, asdict, replace
|
|
import hashlib
|
|
from openpilot.starpilot.flm.canonical_surface_adapter import (
|
|
NAMES,
|
|
MANIFEST_SHA256,
|
|
canonical_names,
|
|
parameters_for,
|
|
full_original_anchor,
|
|
original_anchor,
|
|
full_profile_sha256,
|
|
)
|
|
|
|
POLICY = 'event_effect_coordinate_v2'
|
|
RESTORE_POLICY = 'event_effect_restore_v1'
|
|
VERSION = 1
|
|
|
|
|
|
def hex64(value):
|
|
return type(value) is str and len(value) == 64 and all(c in '0123456789abcdef' for c in value)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class FullSurfaceEnvelope:
|
|
version: int
|
|
manifest_sha256: str
|
|
full_original_anchor: str
|
|
trial_anchor: str
|
|
context_key: str
|
|
cp_sha256: str
|
|
controller_revision: str
|
|
source_epoch: str
|
|
reset_generation: str
|
|
selected_baseline_revision: str
|
|
prior_full_profile_sha256: str
|
|
full_profile_sha256: str
|
|
prior_coordinates: tuple[tuple[str, float], ...]
|
|
coordinates: tuple[tuple[str, float], ...]
|
|
trial_names: tuple[str, ...]
|
|
persistent_source_epoch: str = ''
|
|
operation: str = 'trial'
|
|
history_full_profile_sha256: str = ''
|
|
restore_transaction_sha256: str = ''
|
|
|
|
@classmethod
|
|
def initial(
|
|
cls, *, cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, trial_names, persistent_source_epoch='', prior=None
|
|
):
|
|
names = canonical_names(trial_names)
|
|
if prior is not None:
|
|
raise ValueError('historical prior is not actual accepted current state; use explicit restore transaction')
|
|
rows = neutral_coordinates()
|
|
full_anchor = full_original_anchor(selected_baseline_revision)
|
|
binding = (cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, full_anchor, source_epoch, persistent_source_epoch)
|
|
if prior is not None and (not prior.historical_only or prior.envelope.source_binding() != binding):
|
|
raise ValueError('foreign historical full surface prior')
|
|
digest = full_profile_sha256(selected_baseline_revision, rows)
|
|
return cls(
|
|
VERSION,
|
|
MANIFEST_SHA256,
|
|
full_anchor,
|
|
original_anchor(selected_baseline_revision, names),
|
|
source_epoch,
|
|
cp_sha256,
|
|
controller_revision,
|
|
source_epoch,
|
|
reset_generation,
|
|
selected_baseline_revision,
|
|
digest,
|
|
digest,
|
|
rows,
|
|
rows,
|
|
names,
|
|
persistent_source_epoch,
|
|
).validate()
|
|
|
|
def validate(self, profile=None):
|
|
if self.version not in (VERSION, 2) or type(self.version) is not int or self.manifest_sha256 != MANIFEST_SHA256:
|
|
raise ValueError('full surface envelope version/manifest')
|
|
if self.persistent_source_epoch and not hex64(self.persistent_source_epoch):
|
|
raise ValueError('stable persistent source epoch')
|
|
if self.context_key != self.source_epoch:
|
|
raise ValueError('event context must equal exact source epoch')
|
|
if not all(
|
|
hex64(v)
|
|
for v in (
|
|
self.full_original_anchor,
|
|
self.trial_anchor,
|
|
self.context_key,
|
|
self.cp_sha256,
|
|
self.source_epoch,
|
|
self.selected_baseline_revision,
|
|
self.prior_full_profile_sha256,
|
|
self.full_profile_sha256,
|
|
)
|
|
):
|
|
raise ValueError('full surface binding')
|
|
if (
|
|
type(self.controller_revision) is not str
|
|
or not 1 <= len(self.controller_revision) <= 128
|
|
or type(self.reset_generation) is not str
|
|
or not 1 <= len(self.reset_generation) <= 64
|
|
or any(c not in '0123456789abcdef' for c in self.reset_generation)
|
|
):
|
|
raise ValueError('source/controller/reset binding')
|
|
names = canonical_names(self.trial_names)
|
|
if (
|
|
self.trial_names != names
|
|
or self.full_original_anchor != full_original_anchor(self.selected_baseline_revision)
|
|
or self.trial_anchor != original_anchor(self.selected_baseline_revision, names)
|
|
):
|
|
raise ValueError('changed original full/trial anchor')
|
|
for rows, digest in ((self.prior_coordinates, self.prior_full_profile_sha256), (self.coordinates, self.full_profile_sha256)):
|
|
if type(rows) is not tuple or len(rows) != 30 or tuple(n for n, _ in rows) != NAMES or len(dict(rows)) != 30:
|
|
raise ValueError('exact canonical full30 map')
|
|
if full_profile_sha256(self.selected_baseline_revision, rows) != digest:
|
|
raise ValueError('full surface content hash')
|
|
prior, current = dict(self.prior_coordinates), dict(self.coordinates)
|
|
if self.operation == 'trial':
|
|
if self.version != VERSION or self.history_full_profile_sha256 or self.restore_transaction_sha256:
|
|
raise ValueError('trial cannot carry restore authority')
|
|
if any(prior[n] != current[n] for n in NAMES if n not in names):
|
|
raise ValueError('outside trial group changed')
|
|
if any(abs(current[n] - prior[n]) > 0.005 + 1e-12 for n in names):
|
|
raise ValueError('trial step exceeds .005 original effect')
|
|
expected_policy = POLICY
|
|
elif self.operation == 'restore':
|
|
if (
|
|
self.version != 2
|
|
or not hex64(self.history_full_profile_sha256)
|
|
or not hex64(self.restore_transaction_sha256)
|
|
or self.prior_coordinates != neutral_coordinates()
|
|
or self.history_full_profile_sha256 != self.full_profile_sha256
|
|
or self.restore_transaction_sha256 != restore_transaction(self)
|
|
):
|
|
raise ValueError('explicit neutral-to-history restore transaction')
|
|
self.persistent_binding() # Never restore another unknown vehicle/session.
|
|
expected_policy = RESTORE_POLICY
|
|
else:
|
|
raise ValueError('unknown full surface operation')
|
|
if profile is not None and (
|
|
profile.policy != expected_policy or profile.parameters != parameters_for(names) or tuple(profile.coefficients) != tuple(current[n] for n in names)
|
|
):
|
|
raise ValueError('profile/full-surface operation mismatch')
|
|
return self
|
|
|
|
def source_binding(self):
|
|
return (
|
|
self.cp_sha256,
|
|
self.controller_revision,
|
|
self.source_epoch,
|
|
self.reset_generation,
|
|
self.selected_baseline_revision,
|
|
self.full_original_anchor,
|
|
self.context_key,
|
|
self.persistent_source_epoch,
|
|
)
|
|
|
|
def persistent_binding(self):
|
|
if not hex64(self.persistent_source_epoch):
|
|
raise ValueError('known VIN/static source required for persistence')
|
|
return (
|
|
self.cp_sha256,
|
|
self.controller_revision,
|
|
self.persistent_source_epoch,
|
|
self.reset_generation,
|
|
self.selected_baseline_revision,
|
|
self.full_original_anchor,
|
|
)
|
|
|
|
def scope(self):
|
|
return hashlib.sha256(repr(self.persistent_binding()).encode()).hexdigest()
|
|
|
|
def replay_anchor(self):
|
|
self.validate()
|
|
payload = {
|
|
'version': 1,
|
|
'manifest_sha256': self.manifest_sha256,
|
|
'full_original_anchor': self.full_original_anchor,
|
|
'anchor_digest': self.trial_anchor,
|
|
'accumulated': self.prior_coordinates,
|
|
'full_profile_sha256': self.prior_full_profile_sha256,
|
|
'context_key': self.context_key,
|
|
'cp_sha256': self.cp_sha256,
|
|
'controller_revision': self.controller_revision,
|
|
'source_epoch': self.source_epoch,
|
|
'reset_generation': self.reset_generation,
|
|
'selected_baseline_revision': self.selected_baseline_revision,
|
|
'persistent_source_epoch': self.persistent_source_epoch,
|
|
}
|
|
if self.operation == 'restore':
|
|
payload.update(
|
|
version=2,
|
|
operation='restore',
|
|
history_full_profile_sha256=self.history_full_profile_sha256,
|
|
restore_transaction_sha256=self.restore_transaction_sha256,
|
|
restore_target=self.coordinates,
|
|
)
|
|
return payload
|
|
|
|
def restore_from_history(self, prior):
|
|
self.validate()
|
|
if (
|
|
self.operation != 'trial'
|
|
or self.prior_coordinates != neutral_coordinates()
|
|
or not getattr(prior, 'historical_only', False)
|
|
or prior.envelope.source_binding() != self.source_binding()
|
|
):
|
|
raise ValueError('restore requires exact current neutral state and stable historical prior')
|
|
history = prior.envelope.validate()
|
|
proposed = replace(
|
|
self,
|
|
version=2,
|
|
operation='restore',
|
|
coordinates=history.coordinates,
|
|
full_profile_sha256=history.full_profile_sha256,
|
|
history_full_profile_sha256=history.full_profile_sha256,
|
|
)
|
|
proposed = replace(proposed, restore_transaction_sha256=restore_transaction(proposed))
|
|
return proposed.validate()
|
|
|
|
@property
|
|
def restoration_groups(self):
|
|
from openpilot.starpilot.flm.canonical_surface_adapter import GROUPS
|
|
|
|
values = dict(self.coordinates)
|
|
return tuple(group for group, names in GROUPS.items() if any(values[name] != 0.0 for name in names))
|
|
|
|
def for_trial(self, names):
|
|
names = canonical_names(names)
|
|
return replace(
|
|
self,
|
|
version=VERSION,
|
|
operation='trial',
|
|
history_full_profile_sha256='',
|
|
restore_transaction_sha256='',
|
|
trial_names=names,
|
|
trial_anchor=original_anchor(self.selected_baseline_revision, names),
|
|
coordinates=self.prior_coordinates,
|
|
full_profile_sha256=self.prior_full_profile_sha256,
|
|
).validate()
|
|
|
|
def with_proposal(self, coordinates):
|
|
from openpilot.starpilot.flm.canonical_surface_adapter import validate_trial
|
|
|
|
if self.operation != 'trial':
|
|
raise ValueError('restoration is not a tiny fitted trial')
|
|
proposal = dict(validate_trial(coordinates))
|
|
if tuple(name for name in NAMES if name in proposal) != self.trial_names:
|
|
raise ValueError('trial names changed')
|
|
full = dict(self.prior_coordinates)
|
|
full.update(proposal)
|
|
merged = tuple((name, float(full[name])) for name in NAMES)
|
|
return replace(self, coordinates=merged, full_profile_sha256=full_profile_sha256(self.selected_baseline_revision, merged)).validate()
|
|
|
|
def admit_context(
|
|
self,
|
|
*,
|
|
cp_sha256,
|
|
controller_revision,
|
|
source_epoch,
|
|
reset_generation,
|
|
selected_baseline_revision,
|
|
context_key,
|
|
current_full_profile_sha256,
|
|
persistent_source_epoch='',
|
|
):
|
|
self.validate()
|
|
expected = (cp_sha256, controller_revision, source_epoch, reset_generation, selected_baseline_revision, context_key, persistent_source_epoch)
|
|
observed = (
|
|
self.cp_sha256,
|
|
self.controller_revision,
|
|
self.source_epoch,
|
|
self.reset_generation,
|
|
self.selected_baseline_revision,
|
|
self.context_key,
|
|
self.persistent_source_epoch,
|
|
)
|
|
if expected != observed or current_full_profile_sha256 != self.prior_full_profile_sha256:
|
|
raise ValueError('stale full profile/source CAS')
|
|
return self
|
|
|
|
|
|
def envelope_from_dict(value):
|
|
if type(value) is not dict or set(value) != set(FullSurfaceEnvelope.__dataclass_fields__):
|
|
raise ValueError('full surface envelope fields')
|
|
copied = dict(value)
|
|
for key in ('prior_coordinates', 'coordinates'):
|
|
copied[key] = tuple(tuple(row) for row in copied[key])
|
|
copied['trial_names'] = tuple(copied['trial_names'])
|
|
return FullSurfaceEnvelope(**copied).validate()
|
|
|
|
|
|
def envelope_dict(value):
|
|
if not isinstance(value, FullSurfaceEnvelope):
|
|
raise ValueError('typed full surface envelope required')
|
|
value.validate()
|
|
return asdict(value)
|
|
|
|
|
|
def neutral_coordinates():
|
|
return tuple((n, 0.0) for n in NAMES)
|
|
|
|
|
|
def restore_transaction(envelope):
|
|
return hashlib.sha256(
|
|
repr(
|
|
(
|
|
'full-surface-history-restore-v1',
|
|
envelope.source_binding(),
|
|
envelope.manifest_sha256,
|
|
envelope.full_original_anchor,
|
|
envelope.prior_full_profile_sha256,
|
|
envelope.full_profile_sha256,
|
|
envelope.history_full_profile_sha256,
|
|
envelope.trial_anchor,
|
|
)
|
|
).encode()
|
|
).hexdigest()
|