mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-11-04 19:43:49 +08:00
Validate each FLM binding once per witness call
This commit is contained in:
@@ -138,11 +138,11 @@ def _source_key(context):
|
||||
_VALID_SOURCE_CONTEXTS = OrderedDict()
|
||||
|
||||
|
||||
def validate_source_context(context):
|
||||
def _validated_source_key(context):
|
||||
key = _source_key(context)
|
||||
if key in _VALID_SOURCE_CONTEXTS:
|
||||
_VALID_SOURCE_CONTEXTS.move_to_end(key)
|
||||
return context
|
||||
return key
|
||||
context.binding.validate()
|
||||
if (
|
||||
context.version != SOURCE_VERSION
|
||||
@@ -165,6 +165,11 @@ def validate_source_context(context):
|
||||
_VALID_SOURCE_CONTEXTS[key] = None
|
||||
if len(_VALID_SOURCE_CONTEXTS) > 8:
|
||||
_VALID_SOURCE_CONTEXTS.popitem(last=False)
|
||||
return key
|
||||
|
||||
|
||||
def validate_source_context(context):
|
||||
_validated_source_key(context)
|
||||
return context
|
||||
|
||||
|
||||
@@ -424,11 +429,23 @@ class ResponseWitness:
|
||||
def _validate_raw_witness(witness, binding, now_ns, *, content=True):
|
||||
if type(witness) is not ResponseWitness:
|
||||
raise ValueError('fresh source physical residual witness required')
|
||||
cert = validate_certificate(witness.certificate) if content else witness.certificate
|
||||
owned = _owned(witness, ResponseWitness, _WITNESS_FIELDS)
|
||||
cert = owned['certificate']
|
||||
source_key = _validated_source_key(cert) if content and type(cert) is TrackingSourceContext else None
|
||||
if content and source_key is None:
|
||||
cert = validate_certificate(cert)
|
||||
source_only = type(cert) is TrackingSourceContext
|
||||
# Share immutable values only within this call. Every new call still checks
|
||||
# the actual dictionaries/accessors, expected binding and original clocks.
|
||||
cert_binding = cert.binding
|
||||
cert_values = source_key[1] if source_key is not None else _binding_values(cert_binding)
|
||||
expected = cert_values if binding is cert_binding else _binding_values(binding)
|
||||
actual_binding = owned['binding']
|
||||
actual = (cert_values if actual_binding is cert_binding else
|
||||
expected if actual_binding is binding else _binding_values(actual_binding))
|
||||
if (
|
||||
_binding_values(witness.binding) != _binding_values(binding)
|
||||
or _binding_values(cert.binding) != _binding_values(binding)
|
||||
actual != expected
|
||||
or cert_values != expected
|
||||
or any(
|
||||
type(v) is not int
|
||||
for v in (
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Per-call binding validation deduplicates identities, never clocks or grants."""
|
||||
from dataclasses import replace
|
||||
import pytest
|
||||
from openpilot.starpilot.flm import live_tracking_response as response
|
||||
from openpilot.starpilot.flm.tests.test_tracking_source_context import context
|
||||
|
||||
|
||||
@pytest.mark.parametrize('same_witness,same_expected', [(True, True), (False, True), (True, False), (False, False)])
|
||||
def test_each_distinct_binding_validated_once_per_witness_call(monkeypatch, same_witness, same_expected):
|
||||
certificate = context()
|
||||
now = 10_000_000_000
|
||||
actual = certificate.binding if same_witness else replace(certificate.binding)
|
||||
expected = certificate.binding if same_expected else replace(certificate.binding)
|
||||
raw = response.ResponseWitness(certificate, actual, now-certificate.lag_ns,
|
||||
now-certificate.lag_ns, now, now-350_000_000, 8, None, now+100_000_000)
|
||||
calls = []
|
||||
original = response._binding_values
|
||||
def measured(value):
|
||||
calls.append(value)
|
||||
return original(value)
|
||||
monkeypatch.setattr(response, '_binding_values', measured)
|
||||
assert response.validate_response_witness(raw, expected, now) is raw
|
||||
assert len(calls) == len({id(actual), id(expected), id(certificate.binding)})
|
||||
|
||||
|
||||
def test_binding_deduplication_does_not_reuse_a_previous_call():
|
||||
certificate = context()
|
||||
now = 10_000_000_000
|
||||
raw = response.ResponseWitness(certificate, certificate.binding, now-certificate.lag_ns,
|
||||
now-certificate.lag_ns, now, now-350_000_000, 8, None, now+100_000_000)
|
||||
assert response.validate_response_witness(raw, certificate.binding, now) is raw
|
||||
with pytest.raises(ValueError):
|
||||
response.validate_response_witness(raw, certificate.binding, now+100_000_001)
|
||||
with pytest.raises(ValueError):
|
||||
response.validate_response_witness(raw, replace(certificate.binding, source_epoch='0'*64), now)
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"protected_inventory_sha256": "7f8eb67a69cd1ecbdcbabd4305fd8e2cb8c86c0e1185710d118e22210091159a", "schema_version": 1}
|
||||
{"protected_inventory_sha256": "df20c562268a9a77c5f28cebfefaf91594010416c0a50ef59bdcf8f3bc759bb5", "schema_version": 1}
|
||||
|
||||
Reference in New Issue
Block a user