Wiki de ZooBC
Proof of Participation

Los recibos y la topología de la red

Una blockchain vive de que sus nodos se pasen bloques y transacciones unos a otros. Proof of Participation mide exactamente ese servicio. Cuando un nodo registrado recibe datos de otro nodo registrado, responde con un recibo, una breve declaración firmada con su clave de nodo. Así, la prueba del trabajo proviene del par que lo recibió, no del nodo que lo reclama. Qué pares cuentan tampoco lo deciden los nodos: cada 40 bloques el protocolo baraja el registro con la semilla del bloque y da a cada nodo sus pares prioritarios.

El nodo A retransmite un bloque al nodo B; B le devuelve un recibo firmado por B; el siguiente bloque de A lleva el recibo, que mueve la puntuación de participación de A y, con ella, su parte de los ZBC nuevos.
El nodo A retransmite un bloque al nodo B; B le devuelve un recibo firmado por B; el siguiente bloque de A lleva el recibo, que mueve la puntuación de participación de A y, con ella, su parte de los ZBC nuevos.

Pares prioritarios: la topología

El registro se vuelve a barajar una vez por periodo de 40 bloques (topology_period_blocks), unos 10 minutos. En el primer bloque de un periodo, cada nodo registrado recibe una clave de ordenación:

key = SHA3-256(seed of the period's first block (64 bytes)
               ‖ node id (8 bytes, little-endian)
               ‖ period height (8 bytes, little-endian)
               ‖ "zbc-topology-v2")

Ordenar el registro por estas claves da la lista barajada. A cada nodo se le asigna de ella una ventana de P nodos consecutivos como pares prioritarios, donde P es max_assigned_peers: 12 en mainnet y 8 en devnet. La ventana del nodo en la posición i empieza en la posición (i × P) mod L, siendo L la longitud de la lista; la ventana siempre tiene P nodos completos, y sus inicios se reparten cuando P y L comparten un factor. La relación es unidireccional: que A sea par prioritario de B no hace que B sea par prioritario de A.

Como el orden depende de una semilla que ninguno de ellos controla, y cambia cada 10 minutos, un grupo de nodos confabulados no puede arreglárselas para ser pares unos de otros y avalarse solo entre sí. La velocidad de conexión no interviene, y nadie publica una lista de pares.

El registro en orden de id de nodo se ordena por una clave SHA3-256 de la semilla, el id de nodo, el periodo y la etiqueta; en la lista barajada se marca la ventana de 12 pares prioritarios de un nodo, que se vuelve a barajar cada 40 bloques.
El registro en orden de id de nodo se ordena por una clave SHA3-256 de la semilla, el id de nodo, el periodo y la etiqueta; en la lista barajada se marca la ventana de 12 pares prioritarios de un nodo, que se vuelve a barajar cada 40 bloques.

Qué dice un recibo

Un recibo ocupa 232 bytes:

CampoBytes
clave de nodo del emisor (el nodo que envió los datos)32
clave de nodo del receptor (el nodo que firma)32
bloque de referencia: el último bloque del receptor, altura4
bloque de referencia: hash32
tipo de dato: 1 para un bloque, 2 para una transacción4
hash del dato: qué bloque o transacción se recibió32
la última raíz de lote de recibos del receptor32
la firma Ed25519 del receptor sobre los 168 bytes anteriores64

Solo los nodos registrados dan y guardan recibos, y solo por datos enviados por otro nodo registrado. Un nodo que no está registrado puede seguir y comprobar la cadena, pero ni da ni gana recibos. Un recibo no nombra ninguna cadena, así que, a diferencia de las transacciones (véase firmas vinculadas a la cadena), no lleva ninguna vinculación a la cadena.

Los recibos no tienen nada que ver con las confirmaciones de la billetera ni con los reembolsos de comisiones, que son registros normales de transacciones y saldos.

Lotes y publicación

El emisor guarda los recibos que gana. Para cada altura los agrupa en un lote de como máximo 1000, ordenados por firma, bajo una raíz de Merkle. Cuando produce un bloque propio, publica en él una muestra de sus recibos, de dos clases: recibos no enlazados, mostrados tal cual, y recibos enlazados, mostrados con una prueba de Merkle frente a una raíz de lote anterior. El software de referencia toma muestras de recibos de unos 40 bloques atrás; ese es su comportamiento, no una regla de validez.

Qué comprueban los validadores

Para cada recibo publicado en un bloque, cada nodo comprueba lo siguiente, donde n es el número de nodos registrados:

  • la firma del receptor;
  • que el hash del bloque de referencia es el bloque de esta cadena a esa altura;
  • su antigüedad: un recibo caduca tras max(max(100, 2 × n) + 1, receipt_lifecycle) bloques, que son 518 400 bloques (unos 90 días) en mainnet;
  • a partir de la altura 40, que el firmante de un recibo no enlazado era un par prioritario del productor del bloque en el periodo del que procede el recibo;
  • a partir de la altura 80, la prueba de Merkle de cada recibo enlazado;
  • el número: como máximo 2 × min(n − 1, P) recibos, y nunca más de 200.

Algunas cosas no son reglas de validez, y no hay que atribuírselas: los validadores no comprueban que el emisor del recibo sea el productor del bloque, que el recibo sea nuevo, que su dato tenga unos 40 bloques de antigüedad, ni que una raíz enlazada haya aparecido antes en la cadena.

De los recibos a la puntuación

Retransmitir gana recibos, no puntuación. La puntuación solo se mueve cuando el nodo publica sus recibos en un bloque propio: mostrar más que un pivote de aproximadamente la mitad de lo que podría mostrar eleva su puntuación, y mostrar menos la reduce. Ninguna puntuación se mueve antes de la altura 40. Véase puntuación de participación para los detalles, y lotería coinbase para saber cómo la puntuación se convierte en ingresos.

Véase también