module arch.node.engines.naming_behaviour; import prelude open; import arch.node.types.messages open; import arch.node.types.engine open; import arch.node.types.identities open; import arch.node.engines.naming_messages open; import arch.node.engines.naming_config open; import arch.node.engines.naming_environment open; import arch.node.types.anoma as Anoma open; type ReplyTo := mkReplyTo@{ whoAsked : Option EngineID; mailbox : Option MailboxID; }; type NamingActionArgument := | NamingActionArgumentReplyTo ReplyTo; NamingActionArguments : Type := List NamingActionArgument; NamingAction : Type := Action NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; NamingActionInput : Type := ActionInput NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg; NamingActionEffect : Type := ActionEffect NamingLocalState NamingMailboxState NamingTimerHandle Anoma.Msg Anoma.Cfg Anoma.Env; NamingActionExec : Type := ActionExec NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; resolveNameAction (input : NamingActionInput) : Option NamingActionEffect := let env := ActionInput.env input; cfg := ActionInput.cfg input; tt := ActionInput.trigger input; localState := EngineEnv.localState env; identityName := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingResolveNameRequest req); } := some (RequestResolveName.identityName req) | _ := none; in case identityName of | some name := let matchingEvidence := AVLTree.filter \{evidence := isEqual (Ord.cmp (IdentityNameEvidence.identityName evidence) name)} (NamingLocalState.evidenceStore localState); identities := Set.fromList (map \{evidence := IdentityNameEvidence.externalIdentity evidence} (Set.toList matchingEvidence)); responseMsg := mkReplyResolveName@{ externalIdentities := identities; err := none; }; in case getEngineMsgFromTimestampedTrigger tt of { | some emsg := some mkActionEffect@{ env := env; msgs := [ mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := EngineMsg.sender emsg; mailbox := some 0; msg := Anoma.MsgNaming (MsgNamingResolveNameReply responseMsg); }; ]; timers := []; engines := []; } | _ := none } | _ := none; submitNameEvidenceAction (input : NamingActionInput) : Option NamingActionEffect := let env := ActionInput.env input; cfg := ActionInput.cfg input; tt := ActionInput.trigger input; localState := EngineEnv.localState env; evidence := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingSubmitNameEvidenceRequest req); } := some (RequestSubmitNameEvidence.evidence req) | _ := none; in case evidence of | some ev := let isValid := verifyEvidence ev; alreadyExists := case isValid of | true := isElement \{a b := a && b} true (map \{e := isEqual (Ord.cmp e ev)} (Set.toList (NamingLocalState.evidenceStore localState))) | false := false; newEnv := case isValid && not alreadyExists of | true := env@EngineEnv{localState := localState@NamingLocalState{evidenceStore := Set.insert ev (NamingLocalState.evidenceStore localState)}} | false := env; responseMsg := mkReplySubmitNameEvidence@{ err := case isValid of | false := some "Invalid evidence" | true := case alreadyExists of | true := some "Evidence already exists" | false := none; }; in case getEngineMsgFromTimestampedTrigger tt of { | some emsg := some mkActionEffect@{ env := newEnv; msgs := [ mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := EngineMsg.sender emsg; mailbox := some 0; msg := Anoma.MsgNaming (MsgNamingSubmitNameEvidenceReply responseMsg); }; ]; timers := []; engines := []; } | _ := none } | _ := none; queryNameEvidenceAction (input : NamingActionInput) : Option NamingActionEffect := let env := ActionInput.env input; cfg := ActionInput.cfg input; tt := ActionInput.trigger input; localState := EngineEnv.localState env; externalIdentity := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingQueryNameEvidenceRequest req); } := some (RequestQueryNameEvidence.externalIdentity req) | _ := none; in case externalIdentity of | some extId := let relevantEvidence := AVLTree.filter \{evidence := isEqual (Ord.cmp (IdentityNameEvidence.externalIdentity evidence) extId)} (NamingLocalState.evidenceStore localState); responseMsg := mkReplyQueryNameEvidence@{ externalIdentity := extId; evidence := relevantEvidence; err := none; }; in case getEngineMsgFromTimestampedTrigger tt of { | some emsg := some mkActionEffect@{ env := env; msgs := [ mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := EngineMsg.sender emsg; mailbox := some 0; msg := Anoma.MsgNaming (MsgNamingQueryNameEvidenceReply responseMsg); }; ]; timers := []; engines := []; } | _ := none } | _ := none; resolveNameActionLabel : NamingActionExec := Seq [resolveNameAction]; submitNameEvidenceActionLabel : NamingActionExec := Seq [submitNameEvidenceAction]; queryNameEvidenceActionLabel : NamingActionExec := Seq [queryNameEvidenceAction]; NamingGuard : Type := Guard NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; NamingGuardOutput : Type := GuardOutput NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; NamingGuardEval : Type := GuardEval NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; resolveNameGuard (tt : TimestampedTrigger NamingTimerHandle Anoma.Msg) (cfg : EngineCfg NamingCfg) (env : NamingEnv) : Option NamingGuardOutput := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingResolveNameRequest _); } := some mkGuardOutput@{ action := resolveNameActionLabel; args := []; } | _ := none; submitNameEvidenceGuard (tt : TimestampedTrigger NamingTimerHandle Anoma.Msg) (cfg : EngineCfg NamingCfg) (env : NamingEnv) : Option NamingGuardOutput := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingSubmitNameEvidenceRequest _); } := some mkGuardOutput@{ action := submitNameEvidenceActionLabel; args := []; } | _ := none; queryNameEvidenceGuard (tt : TimestampedTrigger NamingTimerHandle Anoma.Msg) (cfg : EngineCfg NamingCfg) (env : NamingEnv) : Option NamingGuardOutput := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgNaming (MsgNamingQueryNameEvidenceRequest _); } := some mkGuardOutput@{ action := queryNameEvidenceActionLabel; args := []; } | _ := none; NamingBehaviour : Type := EngineBehaviour NamingCfg NamingLocalState NamingMailboxState NamingTimerHandle NamingActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; namingBehaviour : NamingBehaviour := mkEngineBehaviour@{ guards := First [resolveNameGuard; submitNameEvidenceGuard; queryNameEvidenceGuard]; };