This is the multi-page printable view of this section. Click here to print.
Advanced concepts
1 - Event approval process
The approval phase involves asking the approvers to vote for or against the application of an event. This process can be automated but tends to be manual. The response requires interaction with the Kore API if it’s set to manual, so it requires a user who can interact with it and therefore generally takes longer than the other phases.
The approvers are defined by the governance, so they must possess it in order to carry out the evaluation, otherwise they would not have access to the contract, which in turn is stored in the state of the governance.
The approvers will only carry out the evaluation if the version of the governance that the subject’s owner has coincides with that of the approver. If it is lower or higher, an appropriate message for each case is sent to the subject’s owner.
The approval process consists of the following steps:
- The subject owner checks whether the event request requires approval by looking at the response of the evaluators.
- If the request requires it, an approval request is sent to the different approvers.
- Once each approver has the request, they will be able to vote, both for and against, and will send it back to the owner of the subject.
- Every time the owner receives a vote, he will check the following:
- There are enough positive votes for the application to be accepted.
- There are so many negative votes that it is impossible to get the application approved. In both cases, the owner will generate an event. In the case that the vote has not been successful, the event will be generated but it will not produce changes in the state of the subject, remaining merely for informational purposes.
It is important to remember that the subject owner is the only one who can force an effective change on a subject. Therefore, the owner, after the approval process, could decide whether or not to include the event in the chain. This would not follow the standard behavior defined by Kore, but it would not break compatibility. CAUTION
sequenceDiagram %% Comentarios pendientes a que este la invocación externa %% actor Invocador actor Owner actor Evaluator actor Approver 1 actor Approver 2 actor Approver 3 %% Invocador->>Owner: Submit an event request Note over Evaluator: Evaluation phase alt Need for approval detected Owner->Approver 3: Transmit approval request to all approvers Approver 1-->>Owner: Receive Approver 2-->>Owner: Receive Approver 3-->>Owner: Not receive Note over Owner: Wait Approver 1->>Owner: Vote yes Approver 2->>Owner: vote no Note over Owner: Receive vote request Owner->>Approver 3: Transmit request Approver 3-->>Owner: Receive Note over Owner: Wait Approver 3->>Owner: Vote yes Note over Owner: Receive vote request end alt Positive quorum Owner->>Owner: Generate event and update subject else Negative quorum Owner->>Owner: Generate event end Owner->Approver 3: Event goes to the validation phase
2 - Event evaluation process
The evaluation phase consists of the owner of th subject sending an evaluation request to the evaluators, just after the issuer generated an event request with the event type and its content. Currently, evaluation is only present in Fact type events, in the other types it’s skipped. These events affect a certain subject to establish a fact that may or may not modify the subject’s state. A context is also sent containing the necessary information for the evaluators to execute the contract that contains the evaluation logic for our subject, such as previous state, whether the issuer is the owner of the subject, etc. This is the case because the evaluators do not necessarily have a copy of the subject, so they need this data, which includes everything necessary for the execution of the contract.
The evaluators are defined by the governance, so they must possess it in order to carry out the evaluation, otherwise they would not have access to the contract, which in turn is stored in the state of the governance.
The result of applying the event to the subject in terms of property modification is carried out by the evaluators. They have the ability to compile and execute contracts compiled in web assembly.
The Fact event request contains the necessary information to execute one of the functions of the contract (or not, in which case a failed evaluation occurs and the subject owner is notified). The response includes whether the evaluation was successful or failed, if it is necessary to go through the approval phase and the JSON patch that, when applied to the subject’s state, will produce the state change, as well as the hash of the updated state.
The evaluators response is signed by them so that the witnesses can verify that quorum has been reached in the evaluation phase and that the correct evaluators have signed.
The evaluators will only carry out the evaluation if the version of the governance that the subject’s owner has coincides with that of the evaluator. If it is lower or higher, an appropriate message for each case is sent to the subject’s owner.
For issuers, when the governance to which the subject is assigned is updated, the process must be restarted from the beginning of the evaluation, whether you were still in the evaluation phase or already in the approval phase. This is because events must be evaluated/approved with the latest version of governance available.
sequenceDiagram actor Owner as Owner actor Evaluator1 as Evaluator 1 actor Evaluator2 as Evaluator 2 actor Evaluator3 as Evaluator 3 Owner->>Evaluator1: Generate Evaluation Request Owner->>Evaluator2: Generate Evaluation Request Owner->>Evaluator3: Generate Evaluation Request alt Governance Access Granted and Governance Version Matches Evaluator1->>Evaluator1: Check Governance and Execute Contract Evaluator2->>Evaluator2: Check Governance and Execute Contract Evaluator3->>Evaluator3: Check Governance and Execute Contract alt Evaluation Successful Evaluator1->>Owner: Return Evaluation Response and Evaluator's Signature Evaluator2->>Owner: Return Evaluation Response and Evaluator's Signature Evaluator3->>Owner: Return Evaluation Response and Evaluator's Signature else Evaluation Failed Evaluator1->>Owner: Return Evaluation Response (with failed status) and Evaluator's Signature Evaluator2->>Owner: Return Evaluation Response (with failed status) and Evaluator's Signature Evaluator3->>Owner: Return Evaluation Response (with failed status) and Evaluator's Signature end else Governance Access Denied or Governance Version Mismatch Evaluator1->>Owner: Send Appropriate Message Evaluator2->>Owner: Send Appropriate Message Evaluator3->>Owner: Send Appropriate Message Owner->>Owner: Restart Evaluation Process end
3 - Event validation process
The validation process is the last step before achieving a valid event that can be joined to the subject’s chain. The aim of this phase is to ensure the uniqueness of the subject’s chain. It is based on the collection of signatures from the validators, which are defined in the governance. It does not produce a change in the event itself, as the signatures are not included in the event, but they are necessary to validate it in the eyes of the witnesses. It is noteworthy that for the uniqueness of the chain to be fully effective, the validation quorum needs to consist of the majority of validators. This is because if not, several chains could be validated with different validators for each one if the sum of the signature percentage for all quorums does not exceed 100%.
Proof of validation
What the validators sign is called proof of validation, the event itself is not directly signed. This is done to ensure the privacy of the event’s data and at the same time add additional information that allows the validation process to be safer. In turn, when the owners of the subjects send the proof to the validators, it is also signed with the subject’s cryptographic material. It has this form:
pub struct ValidationProof {
/// The identifier of the subject being validated.
pub subject_id: DigestIdentifier,
/// The identifier of the schema used to validate the subject.
pub schema_id: String,
/// The namespace of the subject being validated.
pub namespace: String,
/// The name of the subject being validated.
pub name: String,
/// The identifier of the public key of the subject being validated.
pub subject_public_key: KeyIdentifier,
/// The identifier of the governance contract associated with the subject being validated.
pub governance_id: DigestIdentifier,
/// The version of the governance contract that created the subject being validated.
pub genesis_governance_version: u64,
/// The sequence number of the subject being validated.
pub sn: u64,
/// The identifier of the previous event in the validation chain.
pub prev_event_hash: DigestIdentifier,
/// The identifier of the current event in the validation chain.
pub event_hash: DigestIdentifier,
/// The version of the governance contract used to validate the subject.
pub governance_version: u64,
}
Data such as the governance_version, which is used to verify that the vote should only be returned if it matches the subject’s governance version for the validator, and the subject_public_key is the one used to validate the owner’s signature of the next proof of validation that reaches the validator.
If the validator has the previous proof, they can validate certain aspects, such as the prev_event_hash of the new one matches the event_hash of the previous one. The validators’ database will always store the last proof they signed for each subject. This allows them never to sign two proofs for the same subject_id and sn but with different other data (except for the governance_version). This guarantees the uniqueness of the chain. The ability to change the governance_version is due to what we discussed earlier: if a validator receives a proof with a different governance version than theirs, they should not sign it. Therefore, facing updates of the governance in the middle of a validation process, the owner must restart said process, adapting the governance_version of the proof to the new one.
Another interesting point is the case where validators do not have the previous proof to validate the new one. There is no scenario where validators always have the previous proof, since even when the quorum requires 100% of the signatures, if a change in governance adds a new validator, they will not have the previous proof. This is why when a validation is requested, it should send:
pub struct ValidationEvent {
pub proof: ValidationProof,
pub subject_signature: Signature,
pub previous_proof: Option<ValidationProof>,
pub prev_event_validation_signatures: HashSet<Signature>,
}
The previous proof is optional because it does not exist in the case of event 0. The hashset of signatures includes all the signatures of the validators that allow the previous proof to have reached quorum. With this data, the validator can trust the previous proof sent to them if they do not previously have it.
The communication to request validation and to send validation is direct between the owner and the validator and is carried out asynchronously.
Correct Chain
As we mentioned earlier, the validation phase focuses on achieving a unique chain, but not on whether this chain is correct. This responsibility ultimately falls on the witnesses, who are the subject’s stakeholders. The validators do not need to have the subject’s updated chain to validate the next proof, as the proofs are self-contained and at most require information from the previous proof. But nothing prevents a malicious owner from sending erroneous data in the proof, the validators will not realize it because they do not have the necessary context and will sign as if everything was correct. The witnesses, however, do have the updated subject, so they can detect this kind of tricks. If something like this were to happen, the witnesses are the ones responsible for reporting it and the subject would be blocked.
Sequence Diagram
sequenceDiagram actor Owner as Owner actor Validator1 as Validator 1 actor Validator2 as Validator 2 actor Validator3 as Validator 3 actor Witness as Witness Owner->>Validator1: Send ValidationEvent Owner->>Validator2: Send ValidationEvent Owner->>Validator3: Send ValidationEvent alt Governance Version Matches and Proofs are Valid Validator1->>Validator1: Inspect Governance, Check Last Proof and Signatures Validator2->>Validator2: Inspect Governance, Check Last Proof and Signatures Validator3->>Validator3: Inspect Governance, Check Last Proof and Signatures Validator1->>Owner: Return ValidationEventResponse with Validator's Signature Validator2->>Owner: Return ValidationEventResponse with Validator's Signature Validator3->>Owner: Return ValidationEventResponse with Validator's Signature else Governance Version Mismatch or Proofs are Invalid Validator1->>Owner: Send Appropriate Message (if applicable) Validator2->>Owner: Send Appropriate Message (if applicable) Validator3->>Owner: Send Appropriate Message (if applicable) Note over Validator1,Validator3: End Process (No Response) end Owner->>Owner: Collect Enough Validator Signatures Owner->>Witness: Create Event in Ledger and Distribute