Las transacciones se distribuyen a la red directamente en su número de bloque enviado y se implementan dentro de eso.
Las transacciones se retrasan un bloque de tiempo para ser distribuidas a través de la red y, en consecuencia, se implementan un bloque de tiempo tarde.
Tengo un pequeño grupo que está conectado a una cadena privada de Ethereum que usa POA
y el tiempo de bloqueo se fija en 15 segundos. El clúster tiene cuatro nodos, todos los nodos están conectados entre sí. Tenga en cuenta que hay tres nodos de firma en mi clúster.
Cuando envío una transacción desde un nodo; la transacción no llega a todos los nodos firmantes del bloque actual, sino que se transfiere al siguiente bloque. Pero observo que la transacción enviada fue recibida por el nodo no firmante justo después de enviarla.
Por ejemplo; cuando envié una transacción dentro del bloque actual, no se implementará en el bloque actual sino en el próximo bloque. Entonces, esto obliga a la red a implementar una transacción en 2 bloques de tiempo, que está entre 15 y 30 segundos.
Entonces, si envié mi transacción en el primer segundo del bloque, primero debo esperar 14 segundos para que llegue el siguiente bloque. Y espere 15 segundos más en el siguiente bloque para que se implemente esa transacción, por lo que en total debo esperar 29 segundos.
Caso de ejemplo: alper@home
es un nodo no firmante y otros nodos son nodos firmantes.
Envié una transacción dentro del número de bloque 869,334
del nodo denominado eBloc@netlab
(nodo firmante) y la transacción aparece justo después en alper@home
el nodo designado (nodo no firmante) en el número de bloque 869,334
, pero no aparece en los nodos firmantes ni siquiera en el nodo que envié desde.
En el siguiente bloque ( 869,335
) observo que todos los nodos reciben las transacciones.
Y finalmente en el bloque número ( 869,336
) se despliega la transacción.
=> Si la transacción se distribuyó a todo el clúster justo después de enviarla, debe implementarse en el número de bloque ( 869,334
), pero usó 1 bloque de tiempo adicional para esto.
[P1] ¿Por qué la transacción enviada la reciben los nodos no firmantes justo después de enviarla, pero no los nodos firmantes?
[P2] ¿Es normal que la transacción enviada no se transfiera a toda la red justo después de enviarla, pero lleva 1 bloque de tiempo adicional incluso si todos los nodos están conectados entre sí? ¿Hay alguna forma de forzar la transferencia de una transacción a todos mis nodos de firmante justo después de que se haya enviado?
Nota: Se puede ver más discusión sobre un problema abierto en go-ethereum
.
Este problema ha sido resuelto por el go-ethereum
equipo.
@karalabe:
La transacción debe propagarse a través de la red al mismo tiempo.
Sin embargo, no está incluido en el bloque actual, porque el bloque que se está extrayendo actualmente ya está finalizado. Es costoso recrear un nuevo bloque cada vez que aparece una nueva transacción. Y en el caso de la red principal, los bloques están llenos de cualquier manera, por lo que no tiene mucho sentido. Es por eso que siempre hay un retraso de 1 bloque entre el envío y la extracción.
Sin embargo, para las redes de prueba, tenemos un código que vuelve a trabajar con el minero y, entre otras cosas, también queremos tener la funcionalidad para incluir inmediatamente transacciones en bloques si todavía hay espacio.
Hemos rediseñado el minero en la rama principal. El código actual regenerará bloques cada 3 segundos durante la minería, por lo que si hay más/mejores transacciones para ingresar, el nodo las elegirá.
En una red pública (blockchain de prueba de trabajo), a los mineros no les interesa incluir transacciones tan pronto como se les dice chismes. Una razón para ello se puede derivar del siguiente extracto del documento amarillo (Página 7, publicación revisada EIP 150):
Debido a que el nonce debe satisfacer los requisitos [de validación del bloque], y debido a que su satisfacción depende del contenido del bloque y, a su vez, de sus transacciones compuestas , es difícil crear bloques nuevos y válidos...
En otras palabras, cuando intenta encontrar el bloque nonce, el minero ya necesita tener una raíz Merkle de todas las transacciones para incluir en el bloque. Si agregara constantemente nuevas transacciones, el hash raíz cambiaría y tendría que comenzar a minar desde el principio.
No sé exactamente sobre el retraso de dos bloques entre la transmisión y la minería, pero esto es lo que asumo: si el Bloque n es el bloque en el que se extrae su transacción, entonces
Bloque n-2: las transacciones se transmiten al mempool del minero.
Bloque n-1: el minero selecciona y ejecuta/valida las transacciones lo más rápido posible, para tener "todo listo" para competir por extraer el siguiente bloque válido, solo esperando recibir el hash del bloque principal.
Bloque n: Miner obtuvo el hash del bloque principal, nada más cambia en su candidato de bloque, extrae el nonce correcto y sella el bloque.
Por supuesto, uno podría cambiar este comportamiento en el cliente del nodo de minería, esto requeriría algunas habilidades en go or rust, por supuesto;)
functionality to immediately include transactions into blocks if there is still space
) se consideraría implementado en el futuro para las redes de prueba .@Nikita Fuchsclique.getSigners()
, consulte ( ethereum.stackexchange.com/a/15779/4575 ). Como mostré en mi pregunta cuando envié una transacción, no aparecerá en el bloque actual que se extraería inmediatamente en el bloque que se envía, incluso si no existe otra transacción en el bloque. Entonces, si envié mi transacción en el primer segundo del bloque, primero debo esperar 14 segundos para que llegue el siguiente bloque. Y espere 15 segundos más para que se implemente esa transacción, por lo que en total debo esperar 29 segundos.
Nikita Fuchs
alper