Context & Groups

calimero-context + calimero-context-primitives + calimero-context-config

Purpose

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.

ContextManager actor contexts cache · group_dags HashMap GroupStore persistence · OpLog DAGs 20+ Handler<ContextMessage> variants upgrade propagators · 30s heartbeat crates/context/src/lib.rs Server / RPC ContextClient NodeManager delta routing GroupStore persistence NetworkManager gossip publish

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.)

calimero-context-primitives

client.rs
ContextClient typedef — thin async façade wrapping LazyRecipient<ContextMessage>
client/sync.rs
Sync-related client helpers (group delta request/response coordination)
client/context_api.rs
Context-level API methods (create, join, delete, execute, config queries)
client/crypto.rs
Cryptographic helpers (signing, key derivation, invitation tokens)
local_governance.rs
Wire types: SignedGroupOp, GroupOp, SignableGroupOp — Ed25519, borsh, schema v3
group.rs
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.

Key Fields

pub struct ContextManager {
    store: Arc<Store>,
    node_client: NodeClient,
    context_client: ContextClient,
    group_dags: HashMap<GroupId, DagStore>,
    contexts: HashMap<ContextId, ContextState>,
    upgrade_propagators: HashMap<GroupId, UpgradeProp>,
    // ... network, runtime refs
}

Startup Sequence

1

recover_in_progress_upgrades

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.

Actor::started() recover upgrades reload DAGs start heartbeat OpLog (storage) per-group sequence borsh(SignedGroupOp) DagStore (memory) restore_applied_delta rebuild heads + pending Heartbeat (30s) GroupStateHeartbeat broadcast dag_heads

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
Caller Server, NodeMgr, SyncManager ContextMessage enum dispatch 20+ variants Context Lifecycle (5) Group Governance (6) Membership & Access (7) Config & Sync (5) handlers/ one file per variant async fn handle(&mut self, ...)

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 fn sign_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
}
GroupOp incoming op verify + check sig · state_hash nonce · parents dispatch match GroupOp variant persist OpLog + heads + nonce DAG updated new heads computed

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.

pub struct ContextClient {
    recipient: LazyRecipient<ContextMessage>,
}

impl ContextClient {
    pub async fn send(&self, msg: ContextMessage) -> Result<ContextResponse>;
}

Context Operations

create_context
Create new context bound to group
join_context
Join an existing context
delete_context
Remove context and clean up state
execute
Run WASM method, produce delta
get_context
Query context metadata

Group Operations

add_group_members
Add members to a group
remove_group_members
Remove members with cascade
apply_signed_group_op
Ingest signed op into DAG
set_member_capabilities
Set capability flags for member

Membership

join_group
Join group via invitation claim
join_group_context
Join context within group
create_group_invitation
Generate invitation token

Configuration

sync_group
Trigger group sync with peers
set_context_visibility
Toggle open/restricted access
manage_context_allowlist
Update context allowlist

Query

context_config
Get context configuration
get_context_application
Get WASM app metadata
get_context_member_page
Paginated member listing

Dependencies

How the three context crates relate to other Calimero crates. Arrows show compile-time dependencies.

calimero-context ContextManager actor + handlers calimero-context-primitives ContextClient + messages + wire types calimero-context-config client config + types store dag node-primitives network-primitives primitives actix tokio borsh ed25519-dalek serde
Context crates
Storage
Node
Network
Primitives
External crates