Juvix imports
module arch.node.engines.identity_management_behaviour;
import prelude open;
import Stdlib.Data.Bool open;
import Data.Map open;
import arch.node.engines.commitment_environment open;
import arch.node.engines.decryption_environment open;
import arch.node.engines.identity_management_environment open;
import arch.node.engines.identity_management_messages open;
import arch.node.types.anoma_environment open;
import arch.node.types.anoma_message open;
import arch.node.types.engine_behaviour open;
import arch.node.types.engine_environment open;
import arch.node.types.identities open;
import arch.node.types.messages open;
import arch.system.identity.identity open hiding {ExternalIdentity};
Identity Management
Dynamics¶
Overview¶
The behavior of the Identity Management
Engine define how it processes
incoming messages (requests) and produces the corresponding responses and
actions.
Action labels¶
type IdentityManagementActionLabel :=
| DoGenerateIdentity {
backend : Backend;
params : IDParams;
capabilities : Capabilities
}
| DoConnectIdentity {
externalIdentity : EngineID;
backend : Backend;
capabilities : Capabilities
}
| DoDeleteIdentity {
externalIdentity : EngineID;
backend : Backend
};
DoGenerateIdentity
¶
DoGenerateIdentity { backend : Backend; params : IDParams; capabilities : Capabilities }
This action label corresponds to generating a new identity.
DoGenerateIdentity
action effect
This action does the following:
Aspect | Description |
---|---|
State update | A new identity is created and added to the identities map in the local state. The identity includes information about backend, capabilities, and potentially spawned engine references. |
Messages to be sent | A GenerateIdentityResponse message is sent to the requester, containing the new identity information including references to spawned engines (if any) or an error message if the identity already exists. |
Engines to be spawned | Depending on the requested capabilities, Commitment and/or Decryption engines may be spawned. |
Timer updates | No timers are set or cancelled. |
DoConnectIdentity
¶
DoConnectIdentity { externalIdentity : EngineID; backend : Backend; capabilities : Capabilities }
This action label corresponds to connecting to an existing identity.
DoConnectIdentity
action effect
This action does the following:
Aspect | Description |
---|---|
State update | If successful, a new entry is added to the identities map in the local state, copying the the external identity's information to the requesting identity, filtered by the requested capabilities. |
Messages to be sent | A ConnectIdentityResponse message is sent to the requester, confirming the connection and providing references to relevant engines, or an error message if the connection fails (e.g., identity already exists, external identity not found, or requested capabilities not available). |
Engines to be spawned | No new engines are spawned. The action reuses existing engine references from the external identity. |
Timer updates | No timers are set or cancelled. |
DoDeleteIdentity
¶
DoDeleteIdentity { externalIdentity : EngineID; backend : Backend }
This action label corresponds to deleting an existing identity.
DoDeleteIdentity
action effect
This action does the following:
Aspect | Description |
---|---|
State update | The specified identity is removed from the identities map in the local state if it exists. |
Messages to be sent | A DeleteIdentityResponse message is sent to the requester, confirming the deletion or providing an error message if the identity doesn't exist. |
Engines to be spawned | No engines are spawned by this action. |
Timer updates | No timers are set or cancelled. |
Matchable arguments¶
type IdentityManagementMatchableArgument :=
MessageFrom (Option EngineID) (Option MailboxID);
MessageFrom
¶
MessageFrom (Option EngineID) (Option MailboxID)
This matchable argument contains the address and mailbox ID of where the response message should be sent.
Precomputation results¶
The Identity Management Engine does not require any non-trivial pre-computations.
syntax alias IdentityManagementPrecomputation := Unit;
Guards¶
Auxiliary Juvix code
Type alias for the guard.
IdentityManagementGuard : Type :=
Guard
IdentityManagementLocalState
IdentityManagementMailboxState
IdentityManagementTimerHandle
IdentityManagementMatchableArgument
IdentityManagementActionLabel
IdentityManagementPrecomputation;
IdentityManagementGuardOutput : Type :=
GuardOutput
IdentityManagementMatchableArgument
IdentityManagementActionLabel
IdentityManagementPrecomputation;
generateIdentityGuard
¶
generateIdentityGuard
(t : TimestampedTrigger IdentityManagementTimerHandle)
(env : IdentityManagementEnvironment)
: Option IdentityManagementGuardOutput :=
case getMessageFromTimestampedTrigger t of
| some (MsgIdentityManagement (GenerateIdentityRequest x y z)) :=
do {
sender <- getSenderFromTimestampedTrigger t;
pure
mkGuardOutput@{
matchedArgs := [MessageFrom (some sender) none];
actionLabel := DoGenerateIdentity x y z;
precomputationTasks := unit
};
}
| _ := none;
connectIdentityGuard
¶
connectIdentityGuard
(t : TimestampedTrigger IdentityManagementTimerHandle)
(env : IdentityManagementEnvironment)
: Option IdentityManagementGuardOutput :=
case getMessageFromTimestampedTrigger t of
| some (MsgIdentityManagement (ConnectIdentityRequest x y z)) :=
do {
sender <- getSenderFromTimestampedTrigger t;
pure
mkGuardOutput@{
matchedArgs := [MessageFrom (some sender) none];
actionLabel := DoConnectIdentity x y z;
precomputationTasks := unit
};
}
| _ := none;
deleteIdentityGuard
¶
deleteIdentityGuard
(t : TimestampedTrigger IdentityManagementTimerHandle)
(env : IdentityManagementEnvironment)
: Option IdentityManagementGuardOutput :=
case getMessageFromTimestampedTrigger t of
| some (MsgIdentityManagement (DeleteIdentityRequest x y)) :=
do {
sender <- getSenderFromTimestampedTrigger t;
pure
mkGuardOutput@{
matchedArgs := [MessageFrom (some sender) none];
actionLabel := DoDeleteIdentity x y;
precomputationTasks := unit
};
}
| _ := none;
Action function¶
Auxiliary Juvix code
Type alias for the action function.
IdentityManagementActionInput : Type :=
ActionInput
IdentityManagementLocalState
IdentityManagementMailboxState
IdentityManagementTimerHandle
IdentityManagementMatchableArgument
IdentityManagementActionLabel
IdentityManagementPrecomputation;
IdentityManagementActionEffect : Type :=
ActionEffect
IdentityManagementLocalState
IdentityManagementMailboxState
IdentityManagementTimerHandle
IdentityManagementMatchableArgument
IdentityManagementActionLabel
IdentityManagementPrecomputation;
makeDecryptEnv
(env : IdentityManagementEnvironment)
(backend' : Backend)
(addr : EngineID)
: DecryptionEnvironment :=
let
local := EngineEnvironment.localState env;
in mkEngineEnvironment@{
name := nameGen "decryptor" (EngineEnvironment.name env) addr;
localState :=
mkDecryptionLocalState@{
decryptor := IdentityManagementLocalState.genDecryptor local backend';
backend := backend'
};
mailboxCluster :=
fromList
[ mkPair
0
mkMailbox@{
messages := [];
mailboxState := none
}
];
acquaintances := Set.fromList [nameStr addr];
timers := []
};
makeCommitmentEnv
(env : IdentityManagementEnvironment)
(backend' : Backend)
(addr : EngineID)
: CommitmentEnvironment :=
let
local := EngineEnvironment.localState env;
in mkEngineEnvironment@{
name := nameGen "committer" (EngineEnvironment.name env) addr;
localState :=
mkCommitmentLocalState@{
signer := IdentityManagementLocalState.genSigner local backend';
backend := backend'
};
mailboxCluster :=
fromList
[ mkPair
0
mkMailbox@{
messages := [];
mailboxState := none
}
];
acquaintances := Set.fromList [nameStr addr];
timers := []
};
hasCommitCapability (capabilities : Capabilities) : Bool :=
case capabilities of
| CapabilityCommit := true
| CapabilityCommitAndDecrypt := true
| _ := false;
hasDecryptCapability (capabilities : Capabilities) : Bool :=
case capabilities of
| CapabilityDecrypt := true
| CapabilityCommitAndDecrypt := true
| _ := false;
isSubsetCapabilities
(requested : Capabilities) (available : Capabilities) : Bool :=
(not (hasCommitCapability requested) || hasCommitCapability available)
&& not (hasDecryptCapability requested)
|| hasDecryptCapability available;
updateIdentityAndSpawnEngines
(env : IdentityManagementEnvironment)
(backend' : Backend)
(whoAsked : EngineID)
(identityInfo : IdentityInfo)
(capabilities' : Capabilities)
: Pair IdentityInfo (List Env) :=
case capabilities' of
| CapabilityCommitAndDecrypt :=
let
commitmentEnv := makeCommitmentEnv env backend' whoAsked;
commitmentEngineName := EngineEnvironment.name commitmentEnv;
decryptionEnv := makeDecryptEnv env backend' whoAsked;
decryptionEngineName := EngineEnvironment.name decryptionEnv;
spawnedEngines :=
[EnvCommitment commitmentEnv; EnvDecryption decryptionEnv];
updatedIdentityInfo1 :=
identityInfo@IdentityInfo{
commitmentEngine := some (mkPair none (some commitmentEngineName));
decryptionEngine := some (mkPair none (some decryptionEngineName))
};
in mkPair updatedIdentityInfo1 spawnedEngines
| CapabilityCommit :=
let
commitmentEnv := makeCommitmentEnv env backend' whoAsked;
commitmentEngineName := EngineEnvironment.name commitmentEnv;
spawnedEngines := [EnvCommitment commitmentEnv];
updatedIdentityInfo1 :=
identityInfo@IdentityInfo{commitmentEngine := some
(mkPair none (some commitmentEngineName))};
in mkPair updatedIdentityInfo1 spawnedEngines
| CapabilityDecrypt :=
let
decryptionEnv := makeDecryptEnv env backend' whoAsked;
decryptionEngineName := EngineEnvironment.name decryptionEnv;
spawnedEngines := [EnvDecryption decryptionEnv];
updatedIdentityInfo1 :=
identityInfo@IdentityInfo{decryptionEngine := some
(mkPair none (some decryptionEngineName))};
in mkPair updatedIdentityInfo1 spawnedEngines;
copyEnginesForCapabilities
(env : IdentityManagementEnvironment)
(whoAsked : EngineID)
(externalIdentityInfo : IdentityInfo)
(requestedCapabilities : Capabilities)
: IdentityInfo :=
let
newIdentityInfo :=
mkIdentityInfo@{
backend := IdentityInfo.backend externalIdentityInfo;
capabilities := requestedCapabilities;
commitmentEngine :=
case hasCommitCapability requestedCapabilities of
| true := IdentityInfo.commitmentEngine externalIdentityInfo
| false := none;
decryptionEngine :=
case hasDecryptCapability requestedCapabilities of
| true := IdentityInfo.decryptionEngine externalIdentityInfo
| false := none
};
in newIdentityInfo;
identityManagementAction
(input : IdentityManagementActionInput) : IdentityManagementActionEffect :=
let
env := ActionInput.env input;
out := ActionInput.guardOutput input;
local := EngineEnvironment.localState env;
identities := IdentityManagementLocalState.identities local;
in case GuardOutput.actionLabel out of
| DoGenerateIdentity backend' params' capabilities' :=
case GuardOutput.matchedArgs out of {
| MessageFrom (some whoAsked) _ :: _ :=
case Map.lookup whoAsked identities of {
| some _ :=
let
responseMsg :=
GenerateIdentityResponse@{
commitmentEngine := none;
decryptionEngine := none;
externalIdentity := whoAsked;
err := some "Identity already exists"
};
in mkActionEffect@{
newEnv := env;
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
| none :=
let
identityInfo :=
mkIdentityInfo@{
backend := backend';
capabilities := capabilities';
commitmentEngine := none;
decryptionEngine := none
};
pair' :=
updateIdentityAndSpawnEngines
env
backend'
whoAsked
identityInfo
capabilities';
updatedIdentityInfo := fst pair';
spawnedEnginesFinal := snd pair';
updatedIdentities :=
Map.insert whoAsked updatedIdentityInfo identities;
newLocalState :=
local@IdentityManagementLocalState{identities := updatedIdentities};
newEnv' :=
env@EngineEnvironment{localState := newLocalState};
responseMsg :=
GenerateIdentityResponse@{
commitmentEngine :=
IdentityInfo.commitmentEngine updatedIdentityInfo;
decryptionEngine :=
IdentityInfo.decryptionEngine updatedIdentityInfo;
externalIdentity := whoAsked;
err := none
};
in mkActionEffect@{
newEnv := newEnv';
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := spawnedEnginesFinal
}
}
| _ :=
mkActionEffect@{
newEnv := env;
producedMessages := [];
timers := [];
spawnedEngines := []
}
}
| DoConnectIdentity externalIdentity' backend' capabilities' :=
case GuardOutput.matchedArgs out of {
| MessageFrom (some whoAsked) _ :: _ :=
case Map.lookup whoAsked identities of {
| some _ :=
let
responseMsg :=
ConnectIdentityResponse@{
commitmentEngine := none;
decryptionEngine := none;
err := some "Identity already exists"
};
in mkActionEffect@{
newEnv := env;
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
| none :=
case Map.lookup externalIdentity' identities of {
| none :=
let
responseMsg :=
ConnectIdentityResponse@{
commitmentEngine := none;
decryptionEngine := none;
err := some "External identity not found"
};
in mkActionEffect@{
newEnv := env;
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
| some externalIdentityInfo :=
let
externalCapabilities :=
IdentityInfo.capabilities externalIdentityInfo;
requestedCapabilities := capabilities';
isSubset :=
isSubsetCapabilities
requestedCapabilities
externalCapabilities;
in case isSubset of {
| true :=
let
newIdentityInfo :=
copyEnginesForCapabilities
env
whoAsked
externalIdentityInfo
requestedCapabilities;
updatedIdentities :=
Map.insert whoAsked newIdentityInfo identities;
newLocalState :=
local@IdentityManagementLocalState{identities := updatedIdentities};
newEnv' :=
env@EngineEnvironment{localState := newLocalState};
responseMsg :=
ConnectIdentityResponse@{
commitmentEngine :=
IdentityInfo.commitmentEngine
newIdentityInfo;
decryptionEngine :=
IdentityInfo.decryptionEngine
newIdentityInfo;
err := none
};
in mkActionEffect@{
newEnv := newEnv';
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair
none
(some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
| false :=
let
responseMsg :=
ConnectIdentityResponse@{
commitmentEngine := none;
decryptionEngine := none;
err :=
some "Requested capabilities not available"
};
in mkActionEffect@{
newEnv := env;
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair
none
(some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
}
}
}
| _ :=
mkActionEffect@{
newEnv := env;
producedMessages := [];
timers := [];
spawnedEngines := []
}
}
| DoDeleteIdentity externalIdentity backend' :=
case GuardOutput.matchedArgs out of
| MessageFrom (some whoAsked) _ :: _ :=
case Map.lookup externalIdentity identities of {
| none :=
let
responseMsg :=
DeleteIdentityResponse@{
err := some "Identity does not exist"
};
in mkActionEffect@{
newEnv := env;
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
| some _ :=
let
updatedIdentities := Map.delete externalIdentity identities;
newLocalState :=
local@IdentityManagementLocalState{identities := updatedIdentities};
newEnv' :=
env@EngineEnvironment{localState := newLocalState};
responseMsg :=
DeleteIdentityResponse@{
err := none
};
in mkActionEffect@{
newEnv := newEnv';
producedMessages :=
[ mkEngineMessage@{
sender :=
mkPair none (some (EngineEnvironment.name env));
target := whoAsked;
mailbox := some 0;
msg := MsgIdentityManagement responseMsg
}
];
timers := [];
spawnedEngines := []
}
}
| _ :=
mkActionEffect@{
newEnv := env;
producedMessages := [];
timers := [];
spawnedEngines := []
};
Conflict solver¶
identityManagementConflictSolver
: Set IdentityManagementMatchableArgument
-> List (Set IdentityManagementMatchableArgument)
| _ := [];
IdentityManagementBehaviour type¶
IdentityManagementBehaviour : Type :=
EngineBehaviour
IdentityManagementLocalState
IdentityManagementMailboxState
IdentityManagementTimerHandle
IdentityManagementMatchableArgument
IdentityManagementActionLabel
IdentityManagementPrecomputation;
IdentityManagementBehaviour instance¶
identityManagementBehaviour : IdentityManagementBehaviour :=
mkEngineBehaviour@{
guards :=
[generateIdentityGuard; connectIdentityGuard; deleteIdentityGuard];
action := identityManagementAction;
conflictSolver := identityManagementConflictSolver
};