1 - Proceso de aprobación del evento

Descripción del proceso de aprobación del evento.

La fase de aprobación consiste en pedir a los aprobadores que voten a favor o en contra de la aplicación de un evento. Este proceso puede automatizarse, pero tiende a ser manual. La respuesta requiere interacción con la API de Kore si está configurada como manual, por lo que requiere un usuario que pueda interactuar con ella y, por lo tanto, suele llevar más tiempo que las otras fases.

Los aprobadores están definidos por la gobernanza, por lo que deben poseerlo para realizar la evaluación, de lo contrario no tendrían acceso al contrato, que a su vez se almacena en el estado del gobierno.

Los aprobadores sólo realizarán la evaluación si la versión de la gobernanza que posee el propietario del sujeto coincide con la del aprobador. Si es inferior o superior, se envía al propietario del sujeto un mensaje adecuado a cada caso.

El proceso de aprobación consta de los siguientes pasos:

  • El propietario del sujeto verifica si la solicitud de evento requiere aprobación observando la respuesta de los evaluadores.
  • Si la solicitud lo requiere, se envía una solicitud de aprobación a los diferentes aprobadores.
  • Una vez que cada aprobador tenga la solicitud, podrá votar, tanto a favor como en contra, y la enviará de vuelta al propietario del sujeto.
  • Cada vez que el titular reciba un voto comprobará lo siguiente:
    • Hay suficientes votos positivos para que la solicitud sea aceptada.
    • Hay tantos votos negativos que es imposible que se apruebe la solicitud. En ambos casos, el propietario generará un evento. En el caso de que la votación no haya sido exitosa, se generará el evento pero no producirá cambios en el estado del sujeto, quedando con fines meramente informativos.
sequenceDiagram
    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 - Proceso de evaluación de eventos

Descripción del proceso de evaluación del evento.

La fase de evaluación consiste en que el propietario del sujeto envía una solicitud de evaluación a los evaluadores, justo después de que el emisor generó una solicitud de evento con el tipo de evento y su contenido. Actualmente, la evaluación sólo está presente en eventos de tipo Fact, en los otros tipos se omite. Estos acontecimientos afectan a un determinado sujeto para establecer un Fact que puede modificar o no el estado del sujeto. También se envía un contexto que contiene la información necesaria para que los evaluadores ejecuten el contrato que contiene la lógica de evaluación de nuestro sujeto, como el estado anterior, si el emisor es el propietario del sujeto, etc. Este es el caso porque los evaluadores no necesariamente tienen una copia del sujeto, por lo que necesitan estos datos, que incluyen todo lo necesario para la ejecución del contrato.

Los evaluadores están definidos en la gobernanza, por lo que deben poseerlo para poder realizar la evaluación, de lo contrario no tendrían acceso al contrato, que a su vez se almacena en el estado del gobierno.

El resultado de aplicar el evento al sujeto en términos de modificación de propiedad lo realizan los evaluadores. Tienen la capacidad de compilar y ejecutar contratos compilados en WebAssembly.

La solicitud de evento de Fact contiene la información necesaria para ejecutar una de las funciones del contrato (o no, en cuyo caso se produce una evaluación fallida y se notifica al propietario del sujeto). La respuesta incluye si la evaluación fue exitosa o fallida, si es necesario pasar por la fase de aprobación y el JSON patch que, aplicado al estado del sujeto, producirá el cambio de estado, así como el hash del estado actualizado.

La respuesta de los evaluadores es firmada por ellos para que los testigos puedan verificar que se ha alcanzado el quórum en la fase de evaluación y que han firmado los evaluadores correctos.

Los evaluadores sólo realizarán la evaluación si la versión de la gobernanza que tiene el propietario del sujeto coincide con la del evaluador. Si es inferior o superior, se envía un mensaje adecuado a cada caso al propietario del sujeto.

Para los emisores, cuando se actualiza la gobernanza al que está asignado el sujeto, se debe reiniciar el proceso desde el inicio de la evaluación, ya sea que aún se encontrara en la fase de evaluación o ya en la fase de aprobación. Esto se debe a que los eventos deben evaluarse/aprobarse con la última versión de gobernanza disponible.

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 - Proceso de validación de eventos

Descripción del proceso de validación de eventos.

El proceso de validación es el último paso antes de lograr un evento válido que pueda incorporarse a la cadena del sujeto. El objetivo de esta fase es asegurar la unicidad de la cadena del sujeto. Se basa en la recogida de firmas de los validadores, que están definidas en la gobernanza. No produce un cambio en el evento en sí, ya que las firmas no están incluidas en el evento, pero son necesarias para validarlo ante los ojos de los testigos. Cabe señalar que para que la unicidad de la cadena sea plenamente efectiva, el quórum de validación debe estar formado por la mayoría de validadores. Esto se debe a que de no ser así se podrían validar varias cadenas con validadores diferentes para cada una si la suma del porcentaje de firmas para todos los quórumes no supera el 100%.

Prueba de validación

Lo que firman los validadores se llama prueba de validación, el evento en sí no está firmado directamente. Esto se hace para garantizar la privacidad de los datos del evento y al mismo tiempo agregar información adicional que permita que el proceso de validación sea más seguro. A su vez, cuando los propietarios de los sujetos envían la prueba a los validadores, ésta también es firmada con el material criptográfico del sujeto. Tiene esta forma:

pub struct ValidationProof {
    /// El identificador del sujeto que está siendo validado.
    pub subject_id: DigestIdentifier,
    /// El identificador del esquema utilizado para validar el sujeto.
    pub schema_id: String,
    /// El espacio de nombres del sujeto que está siendo validado.
    pub namespace: String,
    /// El nombre del sujeto que está siendo validado.
    pub name: String,
    /// El identificador de la clave pública del sujeto que está siendo validado.
    pub subject_public_key: KeyIdentifier,
    /// El identificador del contrato de gobernanza asociado con el sujeto que está siendo validado.
    pub governance_id: DigestIdentifier,
    /// La versión del contrato de gobernanza que creó el sujeto que está siendo validado.
    pub genesis_governance_version: u64,
    /// El número de secuencia del sujeto que está siendo validado.
    pub sn: u64,
    /// El identificador del evento previo en la cadena de validación.
    pub prev_event_hash: DigestIdentifier,
    /// El identificador del evento actual en la cadena de validación.
    pub event_hash: DigestIdentifier,
    /// La versión del contrato de gobernanza utilizado para validar el sujeto.
    pub governance_version: u64,
}

Datos como la versión de la gobernanza(que denominaremos sn), que se usa para verificar que el voto solo debe devolverse si coincide con la versión de la gobernanza del sujeto para el validador, y la clave_pública(que denominaremos subject_id) es la que se usa para validar la firma del propietario de la próxima prueba de validación que llegue al validador.

Si el validador tiene la prueba anterior, puede validar ciertos aspectos, como que el prev_event_hash del nuevo coincida con el event_hash del anterior. La base de datos de los validadores siempre almacenará la última prueba que firmaron para cada sujeto. Esto les permite nunca firmar dos pruebas para el mismo suject_id y sn pero con otros datos diferentes (excepto la sn). Esto garantiza la unicidad de la cadena. La capacidad de cambiar la versión de la gobernanza se debe a lo que discutimos anteriormente: si un validador recibe una prueba con una versión de gobernanza diferente a la suya, no debe firmarla. Por lo tanto, ante actualizaciones de la gobernanza en medio de un proceso de validación, el propietario deberá reiniciar dicho proceso, adaptando la versión de la gobernanza de la prueba a la nueva.

Otro punto interesante es el caso en el que los validadores no cuentan con la prueba anterior para validar la nueva. No existe un escenario donde los validadores siempre tengan la prueba anterior, ya que incluso cuando el quórum requiere el 100% de las firmas, si un cambio de gobernanza agrega un nuevo validador, no tendrá la prueba anterior. Es por esto que cuando se solicita una validación se debe enviar:

pub struct ValidationEvent {
    pub proof: ValidationProof,
    pub subject_signature: Signature,
    pub previous_proof: Option<ValidationProof>,
    pub prev_event_validation_signatures: HashSet<Signature>,
}

La prueba anterior es opcional porque no existe en el caso del evento 0. El hashset de firmas incluye todas las firmas de los validadores que permiten que la prueba anterior haya alcanzado el quórum. Con estos datos, el validador puede confiar en la prueba previa que se le envía si no la dispone previamente.

La comunicación para solicitar validación y enviar validación es directa entre el propietario y el validador y se realiza de forma asíncrona.

Cadena correcta

Como mencionamos anteriormente, la fase de validación se centra en lograr una cadena única, pero no en si esta cadena es correcta. Esta responsabilidad recae en última instancia en los testigos, que son los interesados ​​del sujeto. Los validadores no necesitan tener la cadena actualizada del sujeto para validar la siguiente prueba, ya que las pruebas son autocontenidas y como máximo requieren información de la prueba anterior. Pero nada impide que un propietario malicioso envíe datos erróneos en la prueba, los validadores no se darán cuenta porque no tienen el contexto necesario y firmarán como si todo estuviera correcto. Los testigos, sin embargo, sí tienen el sujeto actualizado, por lo que pueden detectar este tipo de engaños. Si algo así sucediera, los testigos son los encargados de denunciarlo y el sujeto sería bloqueado.

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