Saltar al contenido principal

Nodos de almacenamiento

Los nodos de almacenamiento guardan los metadatos y los slivers de los blobs registrados en IOTA, de los shards que tienen, y firman las confirmaciones con las que se certifican los blobs. Su API recibe y devuelve BCS para los datos y JSON para lo demás, y admite llamadas desde cualquier página web (CORS).

Casi nadie la llama directamente: lo hacen la app, el cliente de referencia y el aggregator.

Nodos: de https://nodo-1.iotastorage.com a https://nodo-4.iotastorage.com. La dirección de red de cada nodo está registrada en IOTA (nodo-N.iotastorage.com:443); los clientes usan HTTPS con las direcciones del puerto 443. El comité actual lo da el /v1/estado del aggregator.

MétodoRutaCuerpo o respuesta
GET/v1/healthID del nodo, época y shards.
GET/v1/blobs/<blob ID>/statusEstado del registro del blob.
PUT/v1/blobs/<blob ID>/metadataCuerpo: BlobMetadata en BCS.
GET/v1/blobs/<blob ID>/metadataRespuesta: BlobMetadataWithId en BCS.
PUT/v1/blobs/<blob ID>/slivers/<par>/<primary o secondary>Cuerpo: SliverData en BCS.
GET/v1/blobs/<blob ID>/slivers/<par>/<primary o secondary>Respuesta: SliverData en BCS.
GET/v1/blobs/<blob ID>/confirmation/permanentConfirmación firmada para un blob permanente.
GET/v1/blobs/<blob ID>/confirmation/deletable/<ID del objeto>Confirmación firmada para el Blob borrable con ese ID de objeto.

<par> es el índice de un par de slivers, de 0 al número de shards menos uno. El shard de cada par se rota según el blob ID.

Sobres​

Las respuestas JSON usan este sobre:

{ "success": { "code": 200, "data": … } }
{ "error": { "code": 400, "message": "…" } }

Los metadatos y los slivers se envían y se devuelven como bytes BCS (application/octet-stream). El cuerpo de una petición puede tener hasta 64 MiB.

Salud​

curl https://nodo-1.iotastorage.com/v1/health
{
"success": {
"code": 200,
"data": { "nodeId": "0x…", "epoch": 1, "shards": [25, 26, 27, "…", 49] }
}
}

nodeId es el ID del pool de staking del nodo en IOTA; shards, los shards que tiene en la época actual.

Estado de un blob​

data es uno de estos:

  • "nonexistent": no hay ningún registro vigente;
  • { "invalid": {} }: el blob ID se marcó como inválido en IOTA;
  • { "permanent": { "endEpoch", "isCertified", "objects" } } si hay un registro permanente, o { "deletable": { … } } si todos son borrables. endEpoch es la época de fin más tardía, isCertified dice si alguno está certificado y objects cuenta los objetos Blob que registran este blob ID.

Guardar un blob​

Esto es lo que hace un cliente para guardar un blob después de registrarlo en IOTA:

  1. PUT …/metadata en todos los nodos. El nodo solo lo acepta si el blob está registrado y vigente, y los metadatos casan con el blob ID y con el tamaño registrado.
  2. PUT …/slivers/<par>/primary y …/secondary por cada par cuyo shard tenga el nodo. Un sliver de un shard de otro nodo se rechaza con 421. El nodo comprueba la forma del sliver (par, tipo, tamaño).
  3. GET …/confirmation/permanent o …/confirmation/deletable/<ID del objeto>. El nodo solo firma si tiene los metadatos y todos sus slivers del blob:
{
"success": {
"code": 200,
"data": { "signed": { "serializedMessage": "<base64>", "signature": "<base64>" } }
}
}

El mensaje es un StorageConfirmation (época, blob ID y, si el blob es borrable, el ID de su objeto), firmado con la clave BLS del nodo. El cliente agrega las firmas de nodos que suman un quórum de shards y certifica el blob en IOTA con certify_blob.

Leer un blob​

Quien lee obtiene los metadatos de cualquier nodo, los comprueba frente al blob ID y después baja slivers primarios de los nodos hasta tener n − 2f (34 con 100 shards), los decodifica y comprueba el blob ID del resultado.

Cuánto se guardan los datos​

Los nodos siguen los eventos del paquete almacen en IOTA:

  • una renovación (BlobCertified con is_extension) alarga la época de fin de ese Blob;
  • cuando un blob ID se queda sin registros vigentes, porque todos sus objetos Blob caducaron o se borraron con delete_blob, los nodos borran sus datos;
  • quemar un Blob no emite ningún evento, así que los nodos guardan los datos hasta su época de fin.

Lo que todavía no hacen​

Comprobar cada sliver frente a su hash (exige expandirlo con Reed-Solomon), recuperar slivers de otros nodos, migrar shards cuando cambia el comité, desafíos de almacenamiento, pruebas de inconsistencia y TLS con la clave de red del nodo. Un nodo que estuvo parado ve los blobs registrados entretanto, pero no recupera sus slivers. Ver el roadmap.