Análisis del algoritmo de consenso de Ethereum POA

1. Conceptos y definiciones en camarilla

  • EPOCH_LENGTH  : La longitud de la época es de 30000 bloques. Cada vez que ingresa una nueva época, los votos anteriores se borran y la grabación comienza nuevamente. La votación aquí se refiere a agregar o eliminar al firmante.
  • BLOCK_PERIOD  : tiempo de generación del bloque, el valor predeterminado es 15 s
  • UNCLE_HASH  : siempre Keccak256(RLP([])) , porque no hay ningún tío
  • SIGNER_COUNT  : cada bloque tiene un número de firmantes
  • SIGNER_LIMIT  : igual a (SIGNER_COUNT / 2) + 1. Cada cantante solo puede firmar 1 de los bloques SIGNER_LIMIT consecutivos.
    • Por ejemplo, hay 5 firmantes: ABCDE, firmando 4 bloques, y el firmante no puede ser ABAC, porque A firmó 2 veces en 3 bloques consecutivos.
  • NONCE_AUTH  : Indica que el tipo de votación es para agregar un nuevo firmante; valor = 0xffffffffffffffff
  • NONCE_DROP  : Indica que el tipo de votación es para expulsar al antiguo firmante; valor = 0x0000000000000000
  • EXTRA_VANITY  : Representa la longitud del campo reservado en el campo Extra en el encabezado del bloque: 32 bytes
  • EXTRA_SEAL  : Representa la longitud de los datos de la firma almacenados en el campo Extra en el encabezado del bloque: 65 bytes
  • EN TURNO/FUERA DE TURNO  : Cada bloque tiene un firmante en turno y otros firmantes están fuera de turno. El peso del firmante en turno es mayor y el tiempo de generación del bloque será más rápido. De esta manera se puede garantizar que un bloque de esta altura tenga una alta probabilidad de ser minado por un firmante a su vez.
  • Los campos adicionales en el bloque de génesis incluyen:
    • Prefijo de 32 bytes (extraVanity)
    • Las direcciones de todos los firmantes.
    • Sufijo de 65 bytes (extraSeal): guarda la firma del firmante
  • Los campos Extra de otros bloques solo incluyen extraVanity y extraSeal
  • El campo Hora indica el intervalo de tiempo para generar bloques: blockPeriod(15s)
  • El campo Nonce indica un voto: agregue (nonceAuthVote: 0xffffffffffffffff) o elimine (nonceDropVote: 0x00000000000000000) un firmante
  • El campo Coinbase almacena  la  dirección votada.
    • Por ejemplo: una votación del firmante A: únase al firmante B, luego Coinbase almacena la dirección de B
  • Valor del campo de dificultad: 1-es  firmante de este bloque  (por turno), 2-  no es firmante de este bloque  (fuera de turno)

2. Características del Programa de Acción

  • PoA se basa en nodos autorizados preestablecidos (firmantes) y es responsable de generar bloques. Los nodos ordinarios no pueden minar y no tienen derecho a generar bloques.
  • Los nuevos firmantes pueden ser elegidos por firmantes autorizados (más del 50% de los votos emitidos).
  • Incluso si hay un firmante malicioso, solo puede atacar como máximo 1 de los bloques consecutivos (el número es (SIGNER_COUNT / 2) + 1). Durante este período, otros firmantes pueden votar para expulsar al firmante malicioso.
  • Puede especificar la hora en la que se genera el bloque.
  • Sin recompensas mineras

3. Interfaz y flujo de trabajo de PoA

  1. Especifique un conjunto de firmantes autorizados iniciales en el bloque de génesis y todas las direcciones se almacenan en el campo Extra del bloque de génesis.
  2. Después de iniciar la minería, el grupo de firmantes comienza a firmar y difundir los bloques generados .
  3. El resultado de la firma  se almacena en el campo Extra del encabezado del bloque.
  4. Actualice las direcciones de todos los firmantes actualmente altamente autorizados en Extra  porque hay firmantes recién agregados o expulsados.
  5. Hay un firmante en cada altura en el estado EN TURNO, y otros firmantes están en el estado FUERA DE TURNO. El bloque firmado por el firmante EN TURNO se transmitirá inmediatamente y el bloque firmado por el FUERA  de -El firmante de TURNO se retrasará  un poco al azar. La hora se transmitirá nuevamente para garantizar que el bloque de firma IN-TURN tenga una mayor prioridad y se cargue en la cadena.
  6. Si es necesario agregar un nuevo firmante, el firmante inicia una propuesta a través de la interfaz API y la propuesta se transmite a otros nodos reutilizando los campos Coinbase (nueva dirección del firmante) y Nonce ("0xffffffffffffffff")  en el encabezado del bloque. Los firmantes autorizados responderán al nuevo firmante. Los firmantes votan para "unirse". Si los votos afirmativos superan el 50% del número total de firmantes, aceptan unirse.
  7. Si es necesario expulsar a un antiguo firmante, todos los firmantes autorizados votarán para "expulsar" al antiguo firmante. Si el voto afirmativo supera el 50% del número total de firmantes, significa que el antiguo firmante es expulsado.

el firmante firma el encabezado del bloque

  1. La longitud de Extra es de al menos 65 bytes (el resultado de la firma es de 65 bytes, es decir, R, S, V y V son 0 o 1)
  2. RLP codifica  todos los campos en blockHeader excepto los últimos 65 bytes de Extra
  3. Keccak256 hash los datos codificados 
  4. Los datos firmados (65 bytes) se guardan en  los últimos 65 bytes de Extra

clique.go implementa todas las interfaces en consenso para implementar el algoritmo POA.

Clique.Prepare(cadena, encabezado)

Prepare es una de las interfaces del motor de consenso. Esta función configura los parámetros relacionados con el consenso en el encabezado (Cionbase, Dificultad, Extra, MixDigest, Tiempo).

  • Para bloques que no son de época (número % Época! = 0):
  1. Obtenga los datos de votación en Clique.proposals (por ejemplo: A se une a C, B expulsa a D)
  2. Analice si el número de votos es válido en función de los firmantes de la instantánea (por ejemplo: C no estaba originalmente entre los firmantes y el voto para agregar es válido; D estaba originalmente entre los firmantes y el voto para eliminar es válido)
  3. De la lista de direcciones votadas (C, D),  seleccione aleatoriamente una dirección  como Coinbase del encabezado y configure el Nonce para unirse (0xffffffffffffffff) o expulsar (0x0000000000000000)
  4. Si Clique.signer es el firmante de esta ronda (por turno), establezca header.Difficulty = diffInTurn(1); de lo contrario, es diffNoTurn(2).
  5. Configure los datos del encabezado.Extra como [extraVanity + todos los firmantes en snap + extraSeal]
  6. MixDigest debe configurarse como nulo
  7. Configurar marca de tiempo: la hora es la hora del bloque principal + 15 s
  8. Complete Coinbase, Nonce, Dificultad, Extra del objeto de encabezado (sufijo reservado, usado para Seal() para almacenar la firma del firmante del bloque actual)

Inicialización de la camarilla del motor de consenso

En Ethereum.StartMining, si Ethereum.engine está configurado como clique.Clique, configure el  firmante de clique de acuerdo con la dirección del minero del nodo actual (el valor predeterminado es cuentas[0])  : clique.Authorize(eb, wallet.SignHash), donde  la firma La función  es SignHash, que firma el hash dado.

Clique.snapshot (cadena, número, hash, padres)

Snapshot recupera instantáneas autorizadas dentro de un tiempo específico, primero las encapsula en la memoria y el disco y busca instantáneas;

Si está en el bloque génesis, crea una nueva instantánea;

Si no hay una instantánea del encabezado del bloque, el bloque de colección se mueve hacia atrás. Si hay un padre claro, se fuerza al padre. Si no hay un padre claro, se encuentra en la base de datos.

Después de encontrar la instantánea, mueva la segunda mitad de todos los encabezados hacia adelante.

Luego genere una nueva instantánea a través del encabezado del bloque, guarde el hash del bloque actual en la última instantánea y guarde la instantánea generada en el disco.

La aplicación de votos almacena el número de votos.

Instantánea.aplicar (encabezados)

Cree una nueva instantánea de los firmantes autorizados y actualice las propuestas en el encabezado del bloque desde la instantánea anterior hasta la última instantánea.

  1. Realice una verificación de integridad en los encabezados de los parámetros de entrada: debido a que se pueden pasar varios encabezados de bloque,  los números de bloque deben ser consecutivos.
  2. Recorra todos los encabezados. Si el número de bloque se encuentra al comienzo de la época (número%Época == 0), restablezca los votos y el recuento en la instantánea (  descarte todos los datos históricos  ) .
  3. Para cada encabezado, obtenga  el firmante de la firma.
  4. Si el firmante está en snap.Recents, significa que  ha habido una firma recientemente  , no se permite ninguna firma nuevamente y se devolverá vacío.
  5. Registre  que el firmante es el firmante del bloque: snap.Recents[number] = firmante
  6. Cuente el número de votos para header.Coinbase, si  supera el 50% del número total de firmantes.
  7. Realizar operaciones de agregar o quitar
  8. Eliminar un registro de firmante en snap.Recents: clave=número- (uint64(len(snap.Signers)/2 + 1)), lo que significa que el firmante está liberado y el bloque se puede firmar la próxima vez
  9. Borrar votos de Coinbase que fueron eliminados
  10. Eliminar todos los registros de votación para esta Conibase en snap.Votes
  11. Elimine todos los registros de votos para esta Conibase en un instante.Tally

 Clique.Seal(cadena, bloque, parada)

Seal es también una de las interfaces del motor de consenso. Esta función utiliza clique.signer para firmar el bloque. Para lograr el consenso, el motor intenta crear un bloque sellado y generar una firma en el sufijo del encabezado.Extra

Un bloque que ha llamado a Finalize() puede autorizarse o sellarse. Cuando tiene éxito, todos los miembros del bloque devuelto están completos y pueden considerarse como un bloque normal. Puede transmitirse a toda la red o insertarse en la cadena de bloques, etc.

  • Los bloques de génesis sellados no son compatibles
  • Si el firmante no se encuentra entre los firmantes de la instantánea, no se permite firmar el bloque.
  • Si el firmante no es el firmante de este bloque, debe esperar un período de tiempo aleatorio antes de firmar. Si es el firmante de este bloque, firmará directamente.
  • Si el firmante actual se encuentra entre los 'firmantes recientes', espere a la siguiente época
  • No admite cadenas de período 0, no admite el sellado de bloques vacíos, no admite recompensas pero se puede sellar
  • Utilice copiar para reemplazar el resultado de la firma y guárdelo en los 65 bytes de extraSeal en el campo Extra del encabezado del bloque.

Clique.VerifySeal (cadena, encabezado)

VerifySeal es también una de las interfaces del motor de consenso.

  1. Recupera la dirección de la cuenta a partir de la firma del encabezado. El requisito de cambio de dirección está en los firmantes de la instantánea.
  2. Comprueba si la dificultad calculada en el encabezado del bloque coincide (en turno o fuera de turno)

Camarilla.Finalizar

Finalizar es también una de las interfaces del motor de consenso. Esta función genera un bloque y "finaliza" el nuevo bloque. No hay procesamiento de bloque tío ni mecanismo de recompensa.

  1. header.Root: el estado raíz permanece intacto
  2. header.UncleHash: es nulo
  3. tipos.NewBlock (encabezado, txs, nil, recibos): encapsula y devuelve el bloque final

API.Propose(dirección, autenticación)

Agregar una propuesta: el voto de la persona que llama por addr, la autenticación indica si unirse o expulsarse

verificartíos (cadena, bloque)

Determine si el bloque tío en el bloque es mayor que cero, ya que este consenso no permite los bloques tío

ecercover (encabezado, sigcache)

Extraiga la dirección de la cuenta Ethereum del encabezado de la firma

CalcDificultad (cadena, tiempo, padre)

Devuelve la dificultad computacional del bloque.La dificultad computacional es el algoritmo de ajuste de dificultad.

Valor del campo de dificultad: 1-es  firmante de este bloque  (por turno), 2-  no es firmante de este bloque  (fuera de turno)

estrategia de votación

Debido a que la cadena de bloques puede sufrir pequeñas reorganizaciones, los mecanismos de votación convencionales (emitir y olvidar) pueden no ser óptimos porque el bloque que contiene un solo voto puede no estar en la cadena final debido a que el último bloque ha sido descartado.

Una forma simple pero efectiva es configurar una "propuesta" para los firmantes, por ejemplo, "agregar 0x ...", "eliminar 0x ...", cuando hay varias propuestas simultáneas, el código de firma selecciona una propuesta "al azar". Se inyecta en el bloque firmado por el firmante, de modo que se puedan guardar múltiples propuestas y reorganizaciones simultáneas en la cadena.

La lista puede caducar después de un cierto número de bloques/épocas. Aprobar la propuesta no significa que no se recuperará, por lo que no debe descartarse inmediatamente después de que se apruebe la propuesta.

  • Los votos para agregar y eliminar nuevos firmantes entran en vigencia de inmediato y participarán en el próximo conteo de votos.
  • Tanto para unirse como para expulsarse se requiere  que vote más del 50% del número total actual de firmantes.
  • Puedes expulsarte (también requiere más del 50% de los votos)
  • Es posible la votación paralela (A y B votan de forma cruzada a C y D), siempre que el número final de votos sea del 50%.
  • Si el voto de un firmante no se aprueba antes de entrar en una nueva época, los votos de otros firmantes para ese firmante también se contarán en el juicio.
  • Al ingresar a una nueva época, todos los votos pendientes anteriores serán invalidados y el recuento de votos comenzará nuevamente.
  • No se permite la votación repetida y continua (debido a la restricción de firmantes recientes, dentro de SIGNER_COUNT/2+1 bloques, el firmante solo puede firmar un bloque)

Ejemplos de escenarios de votación

  • ABCD y AB primero expulsan a CD y C expulsa a D. El resultado es que ABC queda
  • ABCD, AB expulsó primero a CD, C expulsó a D y B votó por el voto restante de C. El resultado es que ABC se queda
  • ABCD, AB expulsó primero a CD y C expulsó a D. Incluso si C votara por sí mismo, AB se quedaría.
  • ABCDE, ABC se une primero a F (éxito, ABCDEF), BCDE expulsa a F (éxito, ABCDE), DE se une a F (fracaso, ABCDE), BCD expulsa a A (éxito, BCDE), B se une a F (debido a que DE se une a F Todavía existe. En este momento, BDE se une a F y reúne más del 50% de los votos), y el resultado es que queda BCDEF.

4. Ataque y defensa en PoA

  • Firmante malicioso. Se agrega un usuario malicioso a la lista de firmantes, o la clave/máquina del firmante está comprometida. La solución es una lista de N firmantes autorizados, y cualquier firmante solo puede firmar para cada K 1 de las firmas en bloque. Esto minimiza el daño y los mineros restantes pueden votar para expulsar al usuario malicioso.
  • Censura del firmante. Si un firmante (o un grupo de firmantes) intenta verificar las propuestas de otros firmantes en el bloque (especialmente votando para expulsarlos), para resolver este problema, aumentaremos la minería permitida del firmante. La frecuencia es limitado a 1/(N/2). Si no quiere que lo echen, debe controlar más del 50% de los firmantes.
  • Firmantes "spam". Estos firmantes inyectan una nueva propuesta de votación en cada bloque que firman. Dado que los nodos necesitan contar todos los votos para crear una lista de firmantes autorizados, con el tiempo esto generará una gran cantidad de spam inútil. corre más lento A través del mecanismo de época, los votos antiguos se descartarán cada vez que se ingrese una nueva época.
  • Bloques concurrentes: si el número de firmantes autorizados es N y permitimos que cada firmante firme 1/K, entonces al menos los firmantes NK pueden firmar con éxito un bloque en cualquier momento. Para evitar estas competencias de bloques ( forks  ), cada firmante agregará un retraso aleatorio al generar un nuevo bloque. Esto asegura que sea difícil que se produzcan puntas abiertas.

Supongo que te gusta

Origin blog.csdn.net/m0_55345224/article/details/120881258
Recomendado
Clasificación