module arch.node.engines.verification_behaviour; import prelude open; import arch.node.types.messages open; import arch.system.identity.identity open hiding {ExternalIdentity}; import arch.node.types.engine open; import arch.node.engines.verification_config open; import arch.node.engines.verification_environment open; import arch.node.engines.verification_messages open; import arch.node.engines.signs_for_messages open; import arch.node.types.crypto open; import arch.node.types.identities open; import arch.node.types.anoma as Anoma open; type ReplyTo := mkReplyTo@{ whoAsked : Option EngineID; mailbox : Option MailboxID; }; type VerificationActionArgument := | VerificationActionArgumentReplyTo ReplyTo; VerificationActionArguments : Type := List VerificationActionArgument; VerificationAction : Type := Action VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; VerificationActionInput : Type := ActionInput VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg; VerificationActionEffect : Type := ActionEffect VerificationLocalState VerificationMailboxState VerificationTimerHandle Anoma.Msg Anoma.Cfg Anoma.Env; VerificationActionExec : Type := ActionExec VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; verifyAction (input : VerificationActionInput) : Option VerificationActionEffect := let env := ActionInput.env input; cfg := ActionInput.cfg input; tt := ActionInput.trigger input; localState := EngineEnv.localState env; in case getEngineMsgFromTimestampedTrigger tt of | some emsg := case emsg of { | mkEngineMsg@{ msg := Anoma.MsgVerification (MsgVerificationRequest (mkRequestVerification data commitment externalIdentity useSignsFor)); } := case useSignsFor of { | false := some mkActionEffect@{ env := env; msgs := [ mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := EngineMsg.sender emsg; mailbox := some 0; msg := Anoma.MsgVerification (MsgVerificationReply (mkReplyVerification (Verifier.verify (VerificationCfg.verifier (EngineCfg.cfg cfg) Set.empty externalIdentity) (VerificationCfg.backend (EngineCfg.cfg cfg)) data commitment) none)); }; ]; timers := []; engines := []; } | true := let existingRequests := Map.lookup externalIdentity (VerificationLocalState.pendingRequests localState); newPendingList := case existingRequests of | some reqs := reqs ++ [ mkPair (EngineMsg.sender emsg) (mkPair data commitment); ] | none := [ mkPair (EngineMsg.sender emsg) (mkPair data commitment); ]; newPendingRequests := Map.insert externalIdentity newPendingList (VerificationLocalState.pendingRequests localState); newLocalState := localState@VerificationLocalState{pendingRequests := newPendingRequests}; newEnv := env@EngineEnv{localState := newLocalState}; in some mkActionEffect@{ env := newEnv; msgs := case existingRequests of | some _ := [] | none := [ mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := VerificationCfg.signsForEngineAddress (EngineCfg.cfg cfg); mailbox := some 0; msg := Anoma.MsgSignsFor (MsgQuerySignsForEvidenceRequest (mkRequestQuerySignsForEvidence externalIdentity)); }; ]; timers := []; engines := []; } } | _ := none } | _ := none; signsForReplyAction (input : VerificationActionInput) : Option VerificationActionEffect := let env := ActionInput.env input; cfg := ActionInput.cfg input; tt := ActionInput.trigger input; localState := EngineEnv.localState env; in case getEngineMsgFromTimestampedTrigger tt of | some emsg := case emsg of { | mkEngineMsg@{ msg := Anoma.MsgSignsFor (MsgQuerySignsForEvidenceReply (mkReplyQuerySignsForEvidence externalIdentity evidence err)); } := case Map.lookup externalIdentity (VerificationLocalState.pendingRequests localState) of { | some reqs := let newPendingRequests := Map.delete externalIdentity (VerificationLocalState.pendingRequests localState); newLocalState := localState@VerificationLocalState{pendingRequests := newPendingRequests}; newEnv := env@EngineEnv{localState := newLocalState}; in some mkActionEffect@{ env := newEnv; msgs := map \{req := let whoAsked := fst req; data := fst (snd req); commitment := snd (snd req); in mkEngineMsg@{ sender := getEngineIDFromEngineCfg cfg; target := whoAsked; mailbox := some 0; msg := Anoma.MsgVerification (MsgVerificationReply (mkReplyVerification (Verifier.verify (VerificationCfg.verifier (EngineCfg.cfg cfg) evidence externalIdentity) (VerificationCfg.backend (EngineCfg.cfg cfg)) data commitment) none)); }} reqs; timers := []; engines := []; } | none := some mkActionEffect@{ env := env; msgs := []; timers := []; engines := []; } } | _ := none } | _ := none; verifyActionLabel : VerificationActionExec := Seq [verifyAction]; signsForReplyActionLabel : VerificationActionExec := Seq [signsForReplyAction]; VerificationGuard : Type := Guard VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; VerificationGuardOutput : Type := GuardOutput VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; VerificationGuardEval : Type := GuardEval VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; verifyGuard (tt : TimestampedTrigger VerificationTimerHandle Anoma.Msg) (cfg : EngineCfg VerificationCfg) (env : VerificationEnv) : Option VerificationGuardOutput := case getEngineMsgFromTimestampedTrigger tt of | some mkEngineMsg@{ msg := Anoma.MsgVerification (MsgVerificationRequest _); } := some mkGuardOutput@{ action := verifyActionLabel; args := []; } | _ := none; signsForReplyGuard (tt : TimestampedTrigger VerificationTimerHandle Anoma.Msg) (cfg : EngineCfg VerificationCfg) (env : VerificationEnv) : Option VerificationGuardOutput := case getEngineMsgFromTimestampedTrigger tt of | some emsg := case emsg of { | mkEngineMsg@{ msg := Anoma.MsgSignsFor (MsgQuerySignsForEvidenceReply _); sender := sender; } := case isEqual (Ord.cmp sender (VerificationCfg.signsForEngineAddress (EngineCfg.cfg cfg))) of { | true := some mkGuardOutput@{ action := signsForReplyActionLabel; args := []; } | false := none } | _ := none } | none := none; VerificationBehaviour : Type := EngineBehaviour VerificationCfg VerificationLocalState VerificationMailboxState VerificationTimerHandle VerificationActionArguments Anoma.Msg Anoma.Cfg Anoma.Env; verificationBehaviour : VerificationBehaviour := mkEngineBehaviour@{ guards := First [verifyGuard; signsForReplyGuard]; };