Conversation
A pointer state at u64::MAX is now final (ant-protocol): nothing replaces it, not even another final state whose target sorts first. That is what lets an owner hand a pointer's address over for good, by signing one last state that points at the new owner's pointer. The store, the admission gate, fresh offers, repair and hints all compare with the protocol's replaces(), so they keep whichever final state they took first with no code of their own. The merge rule alone leaves one gap: a node holding no final state takes any, so a former owner could still finalize again on a node that joined the group after the transfer, or lost its copy. So before a node takes a final state it does not hold, from a client or a fresh offer, it asks its close group which state each holds. A peer claiming a different final state is asked for the record, and if it verifies -- only the owner could have signed it -- the write is refused as stale, naming the state the group proved. A claim alone refuses nothing, so one peer cannot block a transfer. The look runs after payment is verified, only asks peers that have sent a pointer message, and is bounded at four seconds inside the client's store timeout; silence proves nothing. Two different final states can still exist if the owner races them to different nodes. Each node keeps its first; the client decides by the close group's majority. So the possession check no longer penalises a member holding the other side of such a fork -- it holds what the merge rule told it to -- and repair, between two final states a wide group backs at quorum, adopts the larger side rather than whichever answered first. with_pointers now takes the service and wires both directions, so the node and the e2e harness cannot attach one and forget the other. ADR-0018 records the decision and amends ADR-0016's merge rule.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linear issue
Closes V2-1354
Risk tier
This changes which pointer state a node keeps at the final counter, and adds a close-group round trip before a node takes a final state.
What
Pointer ownership transfer by final redirection (ADR-0018). The owner key never changes. The owner signs one last state at
counter == u64::MAX, pointing at a pointer the new owner holds the key to. Readers of the address are redirected there, the address stays the same, and the former owner has no move left. WithAutonomi/ant-protocol#40 makes a final state final: nothing replaces it, not even another final state whose target sorts first. This PR pins that rev and does the node's half.replaces. They keep whichever final state they took first, with no code of their own.Stale, naming the state the group proved.ReplicationEngine::with_pointersnow takes thePointerServiceand wires both directions: fresh writes and the finality witness. The node and the e2e harness can no longer attach one and forget the other.Compatibility
PointerStateRequestandPointerFetchRequest.ReplicationEngine::with_pointers(&PointerService)replaceswith_pointers(PointerStore, UnboundedReceiver<PointerFreshWrite>). Newpointer::FinalStateWitnessandPointerService::attach_final_state_witness. Behaviour: a node refuses a second final state withStalewhere it previously took one whose target sorted first.Semver impact
Test evidence
cargo test --all-features --lib: 1233 passed. New tests in the request handler:cargo test --all-features --test pointer_convergence: 17 passed.cargo test --all-features --test e2e pointer_replicationover real QUIC: 15 passed, 3 of them new.cargo test --all-features --test poc_audit_handler_live --test poc_commitment_audit_attacks: 16 and 19 passed.cargo clippy --all-targets --all-features -- -D warnings,cargo clippy --all-features -- -D clippy::panic -D clippy::unwrap_used -D clippy::expect_used,cargo fmt --all -- --checkandscripts/adr-governance.py: all clean.New dependency
None.
ADR
https://github.com/WithAutonomi/ant-node/blob/feat/pointer-ownership-transfer/docs/adr/ADR-0018-pointer-transfer-by-final-redirection.md:
docs/adr/ADR-0018-pointer-transfer-by-final-redirection.md, added by this PR (Proposed). It amends ADR-0016's merge rule at the final counter.Mitigation / rollback
Re-pin ant-protocol to the previous rev and revert this branch. No stored record changes shape. The only coordinated part is that nodes and clients should agree on the final-counter rule, and a mixed group degrades to reads by majority, not to lost data.