fix(#832): retain revoke fence on rejected cycles
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
All checks were successful
ci/woodpecker/pr/ci Pipeline was successful
This commit is contained in:
@@ -303,6 +303,10 @@ class Broker:
|
||||
def __init__(self, store: StateStore, observer: ReceiptObserver | None = None) -> None:
|
||||
self.store = store
|
||||
self.observer: ReceiptObserver = observer if observer is not None else UnavailableReceiptObserver()
|
||||
# Set only by begin_verification after its mandatory revoke-first fence.
|
||||
# It is preserved if later cycle admission is refused; all other broker
|
||||
# actions retain the normal snapshot rollback behavior.
|
||||
self._rejected_cycle_fence: tuple[dict[str, object], dict[str, dict[str, object]]] | None = None
|
||||
# VERIFIED authority is deliberately volatile: broker restart revokes all
|
||||
# leases while preserving WI-1 identity and pending-token integrity.
|
||||
self.leases: dict[str, dict[str, object]] = {}
|
||||
@@ -391,6 +395,7 @@ class Broker:
|
||||
raise StateCommitUncertain()
|
||||
previous = copy.deepcopy(self.store.value)
|
||||
previous_leases = copy.deepcopy(self.leases)
|
||||
self._rejected_cycle_fence = None
|
||||
try:
|
||||
response = self._handle(peer, request)
|
||||
if self.store.value != previous:
|
||||
@@ -405,9 +410,18 @@ class Broker:
|
||||
except StateCommitUncertain:
|
||||
raise
|
||||
except Exception:
|
||||
self.store.value = previous
|
||||
self.leases = previous_leases
|
||||
fence = self._rejected_cycle_fence
|
||||
if fence is None:
|
||||
self.store.value = previous
|
||||
self.leases = previous_leases
|
||||
else:
|
||||
# A refused re-verification must never resurrect the preceding
|
||||
# VERIFIED authority. Preserve only this post-revoke fence;
|
||||
# every unrelated partial-write failure still rolls back.
|
||||
self.store.value, self.leases = fence
|
||||
raise
|
||||
finally:
|
||||
self._rejected_cycle_fence = None
|
||||
|
||||
def _handle(self, peer: tuple[int, int, int], request: dict[str, object]) -> dict[str, object]:
|
||||
peer_pid, peer_uid, peer_gid = peer
|
||||
@@ -473,6 +487,11 @@ class Broker:
|
||||
raise BrokerFailure("INVALID_LEASE_TTL")
|
||||
# Revoke-first is a broker operation, not advisory adapter order.
|
||||
self.revoke_session_authority(session_id)
|
||||
# If subsequent construction admission rejects, handle() restores
|
||||
# this fence rather than the pre-cycle VERIFIED snapshot.
|
||||
self._rejected_cycle_fence = (
|
||||
copy.deepcopy(self.store.value), copy.deepcopy(self.leases)
|
||||
)
|
||||
try:
|
||||
constructed = build_payload_from_wire(construction)
|
||||
except ValueError as exc:
|
||||
|
||||
Reference in New Issue
Block a user