Documentation
¶
Index ¶
- func NewMsgServerImpl(keeper Keeper) types.MsgServer
- type Keeper
- func (k Keeper) CheckAndConsumeGaslessQuota(ctx context.Context, m sdk.Msg) error
- func (k Keeper) CheckInvariants(ctx context.Context) error
- func (k Keeper) CheckOperatorNodeCounts(ctx context.Context) error
- func (k Keeper) CheckRecentNodeActivity(ctx context.Context) error
- func (k Keeper) CountRecentActiveNodes(ctx context.Context, operator, nodeType string, blockTime time.Time) (uint64, error)
- func (k Keeper) CreateAccountIfNotExists(ctx context.Context, addr sdk.AccAddress)
- func (k Keeper) EnsureOperatorLicensed(ctx context.Context, operator string) error
- func (k Keeper) EnsureOperatorLicensedForNodeType(ctx context.Context, operator, nodeType string) error
- func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState
- func (k Keeper) GetActivationKey(ctx context.Context, address string) (types.ActivationKey, bool, error)
- func (k Keeper) GetAuthority() string
- func (k Keeper) GetNode(ctx context.Context, address string) (types.Node, bool, error)
- func (k Keeper) GetOperatorNodeCounts(ctx context.Context, operator, nodeType string) (types.OperatorNodeCounts, error)
- func (k Keeper) GetParams(ctx context.Context) (types.Params, error)
- func (k *Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) error
- func (k Keeper) IsActiveNode(ctx context.Context, nodeAddr string) (types.Node, bool, error)
- func (k Keeper) Logger() log.Logger
- func (k Keeper) TouchNodeActivity(ctx context.Context, nodeAddr string) error
- type Querier
- func (q Querier) Actions(_ context.Context, _ *types.QueryActionsRequest) (*types.QueryActionsResponse, error)
- func (q Querier) ActivationKey(ctx context.Context, req *types.QueryActivationKeyRequest) (*types.QueryActivationKeyResponse, error)
- func (q Querier) ActivationKeys(ctx context.Context, req *types.QueryActivationKeysRequest) (*types.QueryActivationKeysResponse, error)
- func (q Querier) Can(ctx context.Context, req *types.QueryCanRequest) (*types.QueryCanResponse, error)
- func (q Querier) Grants(ctx context.Context, req *types.QueryGrantsRequest) (*types.QueryGrantsResponse, error)
- func (q Querier) GrantsByGrantee(ctx context.Context, req *types.QueryGrantsByGranteeRequest) (*types.QueryGrantsByGranteeResponse, error)
- func (q Querier) Node(ctx context.Context, req *types.QueryNodeRequest) (*types.QueryNodeResponse, error)
- func (q Querier) NodeCounts(ctx context.Context, req *types.QueryNodeCountsRequest) (*types.QueryNodeCountsResponse, error)
- func (q Querier) NodeType(ctx context.Context, req *types.QueryNodeTypeRequest) (*types.QueryNodeTypeResponse, error)
- func (q Querier) NodeTypes(ctx context.Context, req *types.QueryNodeTypesRequest) (*types.QueryNodeTypesResponse, error)
- func (q Querier) Nodes(ctx context.Context, req *types.QueryNodesRequest) (*types.QueryNodesResponse, error)
- func (q Querier) NodesByOperator(ctx context.Context, req *types.QueryNodesByOperatorRequest) (*types.QueryNodesByOperatorResponse, error)
- func (q Querier) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewMsgServerImpl ¶
Types ¶
type Keeper ¶
type Keeper struct {
// state management
Schema collections.Schema
Params collections.Item[types.Params]
// Nodes holds every node ever activated, keyed by node address. Records
// are never removed: a deactivated node's record is what prevents the
// address from ever being re-activated.
Nodes collections.Map[string, types.Node]
// Operators is the set of operator wallets registered by authorizing a
// key or activating a node.
Operators collections.KeySet[string]
// ActivationKeys holds every activation key ever authorized, keyed
// globally by activation address. Records are never removed: a disabled
// key's record is what permanently binds (burns) the address.
ActivationKeys collections.Map[string, types.ActivationKey]
// NodeStatusCounters is the per-node rolling daily MsgUpdateNodeStatus
// counter, incremented by ante admission and re-read by the handler.
NodeStatusCounters collections.Map[string, types.ActivityCounter]
// NodeTypes holds every registered node type, keyed by id. Records are
// never removed: a node's type must stay resolvable for the life of the
// chain, and the registry is what gates activation.
NodeTypes collections.Map[string, types.NodeType]
// OperatorNodes indexes (operator, nodeAddress) for all of an operator's
// nodes, active and deactivated.
OperatorNodes collections.KeySet[collections.Pair[string, string]]
// OperatorActivationKeys indexes (operator, activationAddress) for all of
// an operator's keys, active and disabled.
OperatorActivationKeys collections.KeySet[collections.Pair[string, string]]
// OperatorNodeCounts is the denormalized {total, active} node tally per
// (operator, nodeType), maintained by ActivateNode/DeactivateNode. The
// node-type dimension is load-bearing: activation limits are per node
// type, so a tally pooled across types would let one type's nodes consume
// another's allowance.
OperatorNodeCounts collections.Map[collections.Pair[string, string], types.OperatorNodeCounts]
// RecentNodeActivity indexes (operator, nodeType, dayEpoch, nodeAddress)
// with exactly one entry per node at all times: seeded by ActivateNode and
// moved between day buckets by TouchNodeActivity. Deactivation does not
// touch it. The two-prefix (today/yesterday) count over it is the
// activation algorithm's RecentActiveNodeCount, which is per node type for
// the same reason OperatorNodeCounts is.
RecentNodeActivity collections.KeySet[collections.Quad[string, string, uint64, string]]
// GaslessCounters holds the remaining ante-admission daily counters,
// keyed (kind, signer, scope): authorize per operator, activate per
// activation key, deactivate per signer.
//
// The scope carries the node type for the activate kind and is empty for
// the others. It is load-bearing for the same reason the node-type
// dimension on OperatorNodeCounts is: an activate counter is measured
// against a ceiling derived from the licenses backing *one* node type, so
// pooling attempts across types would let a well-licensed type's activity
// exhaust a sparsely-licensed one's daily quota. The other kinds are
// measured against flat params, so they have nothing to scope by.
GaslessCounters collections.Map[collections.Triple[string, string, string], types.ActivityCounter]
// NodeTypeByLicenseType maps a license type id to the single node type bound to
// it. The binding is one-to-one in both directions — a node type names
// exactly one license type, and a license type backs at most one node type
// — so this is a map rather than an index, and the map shape is what makes
// a second binding to the same license type impossible to represent.
NodeTypeByLicenseType collections.Map[string, string]
// Grants holds the module's access grants, keyed (grantee, action, scope).
// Scope is always empty: this module does not scope its actions.
Grants accesskeeper.Grants
// contains filtered or unexported fields
}
func NewKeeper ¶
func NewKeeper( cdc codec.BinaryCodec, storeService storetypes.KVStoreService, logger log.Logger, authority string, licenseKeeper types.LicenseKeeper, accountKeeper types.AccountKeeper, bankKeeper types.BankKeeper, ) Keeper
func (Keeper) CheckAndConsumeGaslessQuota ¶
CheckAndConsumeGaslessQuota is the ante-side admission check for this module's gasless msgs: it verifies signer standing and rolls + increments the relevant daily counter. Because it runs in the ante chain, its writes are committed even when the msg handler later fails, and over-limit spam is rejected at CheckTx. Handlers re-read these counters and never re-increment.
Per msg:
- MsgAuthorizeActivationKey: operator must hold >= 1 active counted license (a licenseless address must not have a free tx channel); counter per operator, limit recent_key_limit per day.
- MsgActivateNode: signing key must exist, be active, and be bound to the named licensed operator; counter per activation key, limit spam_limit_multiplier x license count per day (the same ceiling the handler's recent-activity check enforces on successes).
- MsgDeactivateNode: signer must be the node's operator, its original still-active activation key, or the node itself, and the node must be active; counter per signer, limit status_daily_limit per day. Not license-gated: winding down a fleet must stay possible after revocation.
- MsgUpdateNodeStatus: node must be active; on the counter's first roll of each UTC day the operator must still hold >= 1 active counted license (a revoked operator's fleet must not keep its free tx channel forever); counter per node, limit status_daily_limit per day.
func (Keeper) CheckInvariants ¶
CheckInvariants runs every consistency check and reports all problems rather than stopping at the first, so one pass gives the full picture.
func (Keeper) CheckOperatorNodeCounts ¶
CheckOperatorNodeCounts verifies the denormalized {total, active} tally against the node records. Missing entries compare as zero on either side, so a stored zero tally and an absent one are equivalent — the handlers never write a zero, but treating them alike keeps the comparison total.
func (Keeper) CheckRecentNodeActivity ¶
CheckRecentNodeActivity verifies the index holds exactly one entry per node, in the day bucket of that node's last_active_time. The count over this index is an activation-limit comparand, so a duplicate entry inflates an operator's recent-activity figure and a missing one deflates it — and because deactivation deliberately leaves entries in place, "one per node" must hold for deactivated nodes too.
func (Keeper) CountRecentActiveNodes ¶
func (k Keeper) CountRecentActiveNodes(ctx context.Context, operator, nodeType string, blockTime time.Time) (uint64, error)
CountRecentActiveNodes returns the number of the operator's nodes *of one node type* with counted activity today or yesterday (UTC): the two-prefix walk over RecentNodeActivity. Each node has exactly one index entry, so no dedup is needed.
func (Keeper) CreateAccountIfNotExists ¶
func (k Keeper) CreateAccountIfNotExists(ctx context.Context, addr sdk.AccAddress)
CreateAccountIfNotExists creates a BaseAccount for addr if none exists. Pubkeys are set lazily by the stock SetPubKeyDecorator on the account's first signed tx.
func (Keeper) EnsureOperatorLicensed ¶
EnsureOperatorLicensed rejects operators that hold no active license of any license type backing a registered node type. It is the gate for actions that name no node type — authorizing an activation key happens before any node exists, so there is nothing narrower to check.
The walk stops at the first license type the operator holds, so a licensed operator costs one lookup; only an unlicensed one pays the full sweep, and the registry is chain-level configuration rather than user-controlled.
func (Keeper) EnsureOperatorLicensedForNodeType ¶
func (k Keeper) EnsureOperatorLicensedForNodeType(ctx context.Context, operator, nodeType string) error
EnsureOperatorLicensedForNodeType rejects operators that hold no active license of the type backing nodeType. It is the gate for actions that do name a node type, and is strictly narrower than EnsureOperatorLicensed: licenses of another node type's license type do not satisfy it.
func (*Keeper) ExportGenesis ¶
func (k *Keeper) ExportGenesis(ctx context.Context) *types.GenesisState
ExportGenesis exports the module's state to a genesis state. Derived structures are not exported; InitGenesis rebuilds them.
func (Keeper) GetActivationKey ¶
func (k Keeper) GetActivationKey(ctx context.Context, address string) (types.ActivationKey, bool, error)
GetActivationKey returns an activation key by address and whether it was found.
func (Keeper) GetAuthority ¶
func (Keeper) GetOperatorNodeCounts ¶
func (k Keeper) GetOperatorNodeCounts(ctx context.Context, operator, nodeType string) (types.OperatorNodeCounts, error)
GetOperatorNodeCounts returns the operator's denormalized node tally for one node type, zero-valued when the operator has never activated a node of it.
func (Keeper) GetParams ¶
GetParams returns the module parameters. A missing params item is surfaced as an error: params are always seeded at genesis or upgrade.
func (*Keeper) InitGenesis ¶
InitGenesis initializes the module's state from a genesis state. The denormalized structures (operator set, operator indexes, node counts, the recent-activity index, and the node-type-by-license index) are derived from the primary records here, so they can never disagree with them.
func (Keeper) IsActiveNode ¶
IsActiveNode returns the node record for nodeAddr and whether it exists with active status. It is the read half of the interface consumed by attestation-style modules.
func (Keeper) TouchNodeActivity ¶
TouchNodeActivity records counted activity for a node at the current block time: it moves the node's single RecentNodeActivity entry into the current day bucket (derived from the stored last_active_time, so the index always holds exactly one entry per node) and updates last_active_time. Callers are responsible for checking the node is active; the entry-per-node invariant must hold for deactivated nodes too.
type Querier ¶
type Querier struct {
Keeper
}
func NewQuerier ¶
func (Querier) Actions ¶
func (q Querier) Actions(_ context.Context, _ *types.QueryActionsRequest) (*types.QueryActionsResponse, error)
Actions returns the module's action vocabulary. It is compiled in rather than stored, so this reads no state. There is no unscoped list: this module does not scope its actions, so every action is module-wide.
func (Querier) ActivationKey ¶
func (q Querier) ActivationKey(ctx context.Context, req *types.QueryActivationKeyRequest) (*types.QueryActivationKeyResponse, error)
func (Querier) ActivationKeys ¶
func (q Querier) ActivationKeys(ctx context.Context, req *types.QueryActivationKeysRequest) (*types.QueryActivationKeysResponse, error)
func (Querier) Can ¶
func (q Querier) Can(ctx context.Context, req *types.QueryCanRequest) (*types.QueryCanResponse, error)
Can reports whether a grantee holds an action grant. Grants here are always module-wide, so the lookup uses the empty scope.
func (Querier) Grants ¶
func (q Querier) Grants(ctx context.Context, req *types.QueryGrantsRequest) (*types.QueryGrantsResponse, error)
func (Querier) GrantsByGrantee ¶
func (q Querier) GrantsByGrantee(ctx context.Context, req *types.QueryGrantsByGranteeRequest) (*types.QueryGrantsByGranteeResponse, error)
func (Querier) Node ¶
func (q Querier) Node(ctx context.Context, req *types.QueryNodeRequest) (*types.QueryNodeResponse, error)
func (Querier) NodeCounts ¶
func (q Querier) NodeCounts(ctx context.Context, req *types.QueryNodeCountsRequest) (*types.QueryNodeCountsResponse, error)
NodeCounts returns the operator's node tallies alongside the limits their licenses imply, so a hosting provider can pre-check whether an activation would be admitted. Entitlement is per node type, so the answer is a breakdown: one entry per registered node type, or just the requested one.
func (Querier) NodeType ¶
func (q Querier) NodeType(ctx context.Context, req *types.QueryNodeTypeRequest) (*types.QueryNodeTypeResponse, error)
NodeType returns a registered node type by id.
func (Querier) NodeTypes ¶
func (q Querier) NodeTypes(ctx context.Context, req *types.QueryNodeTypesRequest) (*types.QueryNodeTypesResponse, error)
NodeTypes returns registered node types. When license_type_id is set the binding is one-to-one, so the answer is a single direct lookup and the result holds at most one node type; the list shape is kept so callers do not need a second response type for the filtered case. When it is empty every node type is returned, paginated.
func (Querier) Nodes ¶
func (q Querier) Nodes(ctx context.Context, req *types.QueryNodesRequest) (*types.QueryNodesResponse, error)
Nodes returns every node record, optionally filtered by status. Records are retained after deactivation, so an unfiltered listing includes every node ever activated.
func (Querier) NodesByOperator ¶
func (q Querier) NodesByOperator(ctx context.Context, req *types.QueryNodesByOperatorRequest) (*types.QueryNodesByOperatorResponse, error)
NodesByOperator returns the operator's node records, optionally filtered by status. The status filter narrows within the operator prefix; it never widens the scan beyond that operator.
func (Querier) Params ¶
func (q Querier) Params(ctx context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error)