Skip to main content

decdn_incentive/
origin_assignment.rs

1//! `OriginAssignment` contract ABI bindings (ADR 011 § Origin Assignment
2//! Authority, ADR 022 § FIND\_VALUE Flow "Origin discovery").
3//!
4//! Generated by the `alloy::sol!` macro from the Solidity surface in
5//! `contracts/src/OriginAssignment.sol`. Only the read path, the publisher
6//! control-plane writes the CLI submits, and the membership-mutating events the
7//! node's chain-backed origin directory ([`crate`] consumer
8//! `decdn-node::dht::chain_origin_directory`) consumes are mirrored. The
9//! directory keeps a `namespaceId → authorized-operator` cache current from
10//! these events, falling back to `getOrigins` for the bootstrap snapshot.
11//!
12//! The contract has two planes. Whether a **publisher wallet** may seat origins
13//! is decided by a swappable `IVettingPolicy` (governance re-points it with
14//! `setVettingPolicy`); a vetted publisher then seats and unseats origins for
15//! its own namespaces instantly, one operator at a time. So every event here is
16//! a single-operator delta — `OriginAdded` seats one, `OriginRemoved` /
17//! `InactiveOriginPruned` remove one — and the directory treats each as a
18//! signal to re-read `getOrigins`, not as history. Namespace 0 has no publisher
19//! and no authorized origins, so `getOrigins(0)` is always empty.
20//!
21//! Vetting is not a CLI flow: a `VETTER_ROLE` holder on the installed policy
22//! (an operator, multisig, or governance) vets a wallet out-of-band, after
23//! which it may seat origins immediately. `OriginAssignment::vettingPolicy`
24//! exposes the installed policy address for tooling that wants to read it.
25
26// The `sol!`-generated bindings include macro-emitted code that uses
27// patterns workspace clippy denies (raw indexing into ABI fixed-size
28// byte arrays, `unwrap` on infallible conversions). These allows scope
29// the relaxation to this module only.
30#[allow(
31    clippy::expect_used,
32    clippy::indexing_slicing,
33    clippy::panic,
34    clippy::unwrap_used,
35    clippy::pub_underscore_fields,
36    clippy::missing_docs_in_private_items,
37    clippy::too_many_arguments,
38    missing_debug_implementations,
39    missing_docs,
40    non_snake_case,
41    non_camel_case_types
42)]
43mod sol_types {
44    alloy::sol! {
45        #[sol(rpc)]
46        contract OriginAssignment {
47            // -----------------------------------------------------------------
48            // View functions (only those consumed by the node runtime + CLI)
49            // -----------------------------------------------------------------
50
51            /// Current authorized-origin operator addresses for a namespace.
52            /// `namespaceId == 0` has no set and always returns empty. Returns
53            /// the live `EnumerableSet` values.
54            function getOrigins(uint256 namespaceId) external view returns (address[] memory);
55
56            /// How many namespaces currently have a non-empty authorized set.
57            function assignedNamespaceCount() external view returns (uint256);
58
59            /// A page of the namespaces that currently have origins. Membership
60            /// within a namespace was always readable via `getOrigins`; this is
61            /// the key set, whose absence was the sole reason a bootstrap had to
62            /// replay the seating events from the deploy block.
63            ///
64            /// Order is NOT stable across mutations (swap-and-pop removal), so
65            /// every page and the count it is checked against MUST be read at one
66            /// pinned block height.
67            function assignedNamespaces(uint256 offset, uint256 limit)
68                external
69                view
70                returns (uint256[] memory);
71
72            /// Whether the installed policy vets `publisher` to seat origins for
73            /// its own namespaces. `addOrigin` reverts `PublisherNotVetted` while
74            /// false. A passthrough to `vettingPolicy().isVetted(publisher)`.
75            function isVettedPublisher(address publisher) external view returns (bool);
76
77            /// The installed vetting authority (an `IVettingPolicy`). Exposed for
78            /// tooling that wants to read the policy address; vetting itself is a
79            /// `VETTER_ROLE` action on that policy, not a CLI flow.
80            function vettingPolicy() external view returns (address);
81
82            // -----------------------------------------------------------------
83            // Write functions (publisher control plane, issues #1029 / #1491)
84            // -----------------------------------------------------------------
85
86            /// Vetted namespace owner seats one more authorized origin. Instant:
87            /// there is no pending state and no governance step. Reverts if the
88            /// caller does not own the namespace, is not vetted, or the operator
89            /// is not an active bonded node, is already seated, or would exceed
90            /// `maxOriginsPerNamespace`.
91            function addOrigin(uint256 namespaceId, address operator) external;
92
93            /// Namespace owner (own namespace) or governance (any) unseats one
94            /// authorized origin. Instant; reverts if the operator is not seated.
95            function removeOrigin(uint256 namespaceId, address operator) external;
96
97            // -----------------------------------------------------------------
98            // Per-namespace origin-membership events
99            // -----------------------------------------------------------------
100
101            /// One `operator` was seated as an authorized origin for
102            /// `namespaceId` by its vetted publisher. The single "origin seated"
103            /// event: there is no wholesale set replacement.
104            event OriginAdded(
105                uint256 indexed namespaceId,
106                address indexed operator,
107                address indexed by
108            );
109
110            /// A single `operator` was unseated from `namespaceId`'s authorized
111            /// set (by the namespace owner or governance).
112            event OriginRemoved(
113                uint256 indexed namespaceId,
114                address indexed operator,
115                address indexed by
116            );
117
118            /// An `operator` that left the active set (unbonded, deregistered,
119            /// or ejected) was permissionlessly pruned from `namespaceId`'s
120            /// authorized set. Same cache effect as a removal (remove one).
121            event InactiveOriginPruned(
122                uint256 indexed namespaceId,
123                address indexed operator,
124                address indexed pruner
125            );
126        }
127    }
128}
129
130pub use sol_types::OriginAssignment;