Añadir miembros

Añadiendo mienmbros a la gobernanza

Segundo nodo

Para agregar un segundo miembro, podemos repetir el paso anterior pero cambiando ligeramente el cuerpo de la solicitud. Para hacer esto, primero ejecutaremos kore-keygen nuevamente para crear un segundo material criptográfico que identifique al segundo miembro:

PRIVATE KEY ED25519 (HEX): 388e07385cfd8871f990fe05f82610af1989f7abf5d4e42884c8337498086ba0
CONTROLLER ID ED25519: {{CONTROLLER-ID}}
PeerID: 12D3KooWRS3QVwqBtNp7rUCG4SF3nBrinQqJYC1N5qc1Wdr4jrze

Deberemos levantar el segundo nodo para ello crearemos un archivo de configuración añadiendo el peer-id del nodo 1, para ello debemos ejecutar:

curl --silent 'http://127.0.0.1:3000/peer-id'
//config2.json
{
    "kore": {
      "network": {
          "listen_addresses": ["/ip4/0.0.0.0/tcp/50000"],
          "routing": {
            "boot_nodes": ["/ip4/172.17.0.1/tcp/50000/p2p/{{PEER-ID}}"]
          }
      },
    }
  }

Levantamos el nodo 2 en el puerto 3001:

docker run -p 3001:3000 -p 50001:50000 -e KORE_PASSWORD=polopo -e KORE_FILE_PATH=./config.json -v ./config2.json:/config.json koreadmin/kore-http:0.5-sqlite

Obtenemos el controler_id del Nodo 2:

curl --silent 'http://127.0.0.1:3000/controller-id'
{
  "request": {
    "Fact": {
      "subject_id": "{{GOVERNANCE-ID}}",
      "payload": {
          "Patch": {
              "data": [
                {
                    "op": "add",
                    "path": "/members/1",
                    "value": {
                    "id": "{{CONTROLER-ID}}",
                    "name": "Node2"
                    }
                }
            ]
          }
      }
    }
  }
}

Debemos aprobar nuevamente la nueva solicitud como en el caso anterior.

Comunicación entre nodos

Ahora que está activo y encuentra el nodo definido en boot_nodes. Los eventos de la gobernanza comenzarán a llegar al segundo nodo, aunque aún no quedarán guardados en su base de datos. Esto se debe a que las gobernanzas siempre deben estar previamente autorizadas para permitir la recepción de sus eventos. Para esto se utiliza el endpoint /allowed-subjects/{{GOVERNANCE-ID}} y el método PUT. Recordad que en este caso hay que lanzarlo en el segundo nodo, que por la configuración que hemos puesto estará escuchando en el puerto 3001 de localhost. El segundo nodo ahora se actualizará correctamente con el sujeto de gobernanza.

curl --silent --request PUT 'http://localhost:3001/allowed-subjects/{{GOVERNANCE-ID}}' \
--header 'Content-Type: application/json' \
--data '{
    "providers": []
}'

Respuesta:

OK

Modificar la gobernanza

Como hemos visto anteriormente, el contrato de gobernanza actualmente solo tiene un método para modificar su estado, el método Patch. Este método incluye un objeto con un atributo de datos que a su vez es una matriz que representa un JSON Patch. Este parche se aplicará al estado actual de la gobernanza para modificarlo. Además al realizar la modificación se comprueba que el estado obtenido sea válido para una gobernanza, no sólo realizando la validación con el propio esquema de gobernanza sino también realizando comprobaciones exhaustivas, como que no haya miembros repetidos, cada esquema definido por turno…

Para facilitar la obtención del resultado que queremos y generar el JSON Patch específico podemos utilizar la herramienta kore-patch, incluida entre las kore-tools. A este ejecutable se le pasa el estado actual y el estado deseado y genera el parche correspondiente tras cuya aplicación se pasa de uno a otro.

Por ejemplo, haremos que todos los miembros de la gobernanza sean aprobadores, para ello debemos agregar el rol:

{
    "namespace": "",
    "role": "APPROVER",
    "schema": {
        "ID": "governance"
    },
    "who": "MEMBERS"
}

Entonces el JSON Patch que tendremos que aplicar será:

[
  {
    "op": "add",
    "path": "/roles/1",
    "value": {
        "namespace": "",
        "role": "APPROVER",
        "schema": {
            "ID": "governance"
        },
        "who": "MEMBERS"
    }
  }
]

Entonces el cuerpo de la solicitud será:

{
  "request": {
    "Fact": {
      "subject_id": "{{GOVERNANCE-ID}}",
      "payload": {
          "Patch": {
              "data": [
                {
                  "op": "add",
                  "path": "/roles/1",
                  "value": {
                      "namespace": "",
                      "role": "APPROVER",
                      "schema": {
                          "ID": "governance"
                      },
                      "who": "MEMBERS"
                  }
                }
              ]
          }
      }
    }
  }
}

Aunque el siguiente estado dice que ambos son aprobadores, para calcular los firmantes de las diferentes fases se utiliza el estado actual del sujeto, previo a aplicar el cambio de estado de este nuevo evento que estamos creando, por lo que el único derecho de aprobador ahora seguirá siendo el primer nodo por ser el dueño de la gobernanza, por lo que debemos repetir el paso de autorización anterior.

Tercer nodo

Levantar el tercer nodo

Para agregar un tercer miembro repetimos los pasos anteriores, lo primero es crear el material criptográfico con kore-keygen o dejar que el nodo lo genere:

Lanzamos el contenedor de docker modificando los puertos pero usando el mismo archivo de config que el nodo 2:

docker run -p 3002:3000 -p 50002:50000 -e KORE_PASSWORD=polopo -e KORE_FILE_PATH=./config.json -v ./config2.json:/config.json koreadmin/kore-http:0.5-sqlite

Modificar la gobernanza

Ahora lanzaremos el evento que suma al tercer miembro a la gobernanza, pero para comprobar el funcionamiento de las aprobaciones votaremos con un nodo y no con el otro, lo que dejará el evento como rechazado en la fase de aprobación. Aún se agregará a la cadena del sujeto, pero no modificará su estado.

{
  "request": {
    "Fact": {
      "subject_id": "{{GOVERNANCE-ID}}",
      "payload": {
          "Patch": {
              "data": [
                {
                    "op": "add",
                    "path": "/members/2",
                    "value": {
                    "id": "{{CONTOLLER-ID}}",
                    "name": "Node3"
                    }
                }
            ]
          }
      }
    }
  }
}

Primero debemos solicitar aprobaciones pendientes en /approval-requests?status=pending usando un GET. El id del json de respuesta es el que debemos utilizar para aprobarlo. En /approval-requests/{id} usando un PATCH agregaremos la identificación recibida para emitir el voto.

curl --silent 'http://localhost:3000/approval-requests?status=pending'

En el nodo 1(puerto 3000) lo aprobaremos pero en el nodo 2(puerto 3001) lo rechazaremos. Como el quórum es de mayoría, esto significa que ambos deben aprobarlo para que sea aprobado. Por lo que si uno de los dos lo rechaza, será rechazado porque no se puede alcanzar el quórum de aceptación.

Nodo 1:

{"state": "RespondedAccepted"}
curl --silent --request PATCH 'http://localhost:3000/approval-requests/{{REQUEST-ID}}' \
--header 'Content-Type: application/json' \
--data '{"state": "RespondedAccepted"}'

Nodo 2:

{"state": "RespondedRejected"}
curl --silent --request PATCH 'http://localhost:3001/approval-requests/{{REQUEST_ID}}' \
--header 'Content-Type: application/json' \
--data '{"state": "RespondedRejected"}'

Comprobamos que el estado no se ha modificado buscando a nuestros sujetos, sin embargo, el sn del sujeto habrá aumentado en 1:

También podemos buscar un evento específico con la api de eventos: /subjects/{id}/events/{sn} cuyo id es el SubjectId del sujeto, el sn es el evento específico al que vamos a buscar (si no se agrega nada devolverá todos los eventos del asunto) y la solicitud es de tipo GET.

curl --silent 'http://localhost:3000/subjects/{{GOVERNANCE-ID}}/events/4' \

Ahora repetiremos la misma solicitud pero votaremos sí con ambos nodos, los cuales aprobarán la solicitud y modificarán el estado del asunto. Aprobamos la gobernanza en el tercer nodo y veremos cómo se actualiza en un corto periodo de tiempo.

Última modificación: 14/06/2024