ContextManager is an Actix actor that manages contexts (application instances), groups (governance units), and the governance DAG. Every context belongs to a group. The manager holds per-group DagStores, handles 20+ message types, and coordinates with GroupStore for persistence.
Module Structure
calimero-context
lib.rs
ContextManager actor — startup, fields, Actix lifecycle, heartbeat timer, DAG reload
group_store.rs
Authoritative persistence layer — apply_local_signed_group_op, op log, DAG heads, nonce management
governance_dag.rs
DAG bridge — GroupGovernanceApplier converts SignedGroupOp to CausalDelta
handlers/
20+ handler files, one per ContextMessage variant (create, join, delete, execute, group ops, etc.)
Actix messages — group-level message types for actor communication
messages.rs
ContextMessage enum — top-level message envelope with 20+ variants
calimero-context-config
client_config.rs
Configuration for context client connections and transport settings
types.rs
Shared configuration types used across context crates
ContextManager Actor
The central actor for all context and group operations. Initialized on node start, it rebuilds in-memory state from persistent storage and starts background coordination tasks.
Resume any application upgrades that were interrupted by a previous shutdown.
2
reload_group_dags
For each group in the store, read the full OpLog and rebuild the in-memory DagStore via restore_applied_delta.
3
start_group_heartbeat (30s)
Periodic timer publishes GroupStateHeartbeat with current dag_heads for every group, triggering catch-up on peers.
Handler Map
All 20+ ContextMessage variants, grouped by function. Each variant is handled by a dedicated file in handlers/.
Context Lifecycle
CreateContext
Create a new context, bind to group, emit ContextRegistered ops
JoinContext
Join existing context via invitation or open membership
DeleteContext
Remove context and clean up all associated state
Execute
Run WASM method, produce state delta, broadcast
UpdateApplication
Upgrade WASM binary for a context
Group Governance
AddGroupMembers
Add one or more members to a group
RemoveGroupMembers
Remove members with cascade to all contexts
ApplySignedGroupOp
Ingest a signed governance operation into the DAG
SetMemberCapabilities
Grant or revoke per-member capability flags
UpdateMemberRole
Change member role (admin, member, etc.)
UpgradeGroup
Propagate application upgrade across group contexts
Membership & Access
JoinGroup
Join a group via invitation claim flow
JoinGroupContext
Join a specific context within a group
CreateGroupInvitation
Generate a SignedGroupOpenInvitation
SetContextVisibility
Toggle open vs restricted context access
ManageContextAllowlist
Add/remove members from context allowlist
SetDefaultCapabilities
Default capability flags for new group members
SetDefaultVisibility
Default visibility for new contexts in group
Configuration & Sync
SyncGroup
Trigger group state synchronization with peers
SetGroupAlias
Set human-readable alias for a group
SetMemberAlias
Set human-readable alias for a member
DeleteGroup
Delete group and cascade to all owned contexts
DetachContextFromGroup
Unbind a context from its group
GroupStore Deep-Dive
The authoritative persistence layer for all group and governance state. Handles signature verification, state-hash optimistic locking, nonce-based idempotency, DAG maintenance, and cascading side effects.
apply_local_signed_group_op Flow
1
Cap parent_op_hashes
Ensure parent hashes reference valid DAG heads (capped at 64 concurrent heads).
2
verify_signature
Ed25519 signature verification on the signable_bytes of the operation.
3
check state_hash
Optimistic lock — the op's state_hash must match the current computed group state hash.
4
check nonce (idempotent on duplicate)
Per-signer monotonic nonce. If the nonce was already seen, the op is silently treated as idempotent (no error, no re-apply).
5
dispatch GroupOp
Match on the GroupOp variant and apply the state mutation (add member, set visibility, cascade removal, etc.).
6
append OpLog
Serialize the SignedGroupOp via borsh and append to the persistent op log with an incrementing sequence number.
7
recompute dag_heads
Update the set of DAG head hashes — the new op becomes a head, its parents are removed from the head set.
8
set nonce
Record the signer's nonce for replay protection.
Key Storage Prefixes
All stored in Column::Group with typed key prefixes:
GroupMeta
Group metadata (name, created_at)
GroupMember
Member records per group
GroupOpLog
Persisted signed operations
GroupOpHead
Current DAG head hashes
GroupLocalGovNonce
Per-signer monotonic nonce
GroupContextIndex
Context → group mapping
ContextGroupRef
Reverse group → context ref
GroupMemberContext
Per-member context tracking
GroupCapability
Member capability grants
GroupAlias
Human-readable group alias
MemberAlias
Human-readable member alias
ContextAllowlist
Per-context member allowlist
sign_apply_and_publish helper
Convenience function used by most handlers to emit governance ops. Combines three steps into one call:
async fnsign_apply_and_publish(
&self,
group_id: GroupId,
op: GroupOp,
) -> Result<()> { // 1. Sign op with node's Ed25519 key // 2. apply_local_signed_group_op (persist + DAG) // 3. Publish via gossipsub on group topic
}
ContextClient
Thin async façade wrapping LazyRecipient<ContextMessage>. Used by Server (for RPC execution) and NodeManager (for delta routing) to invoke context-level operations without importing Actix directly.