Saltearse al contenido

Transacciones emitidas

Todos los cambios realizados en Xahau deben ser el resultado de aplicar una transacción válida al ledger. Por lo tanto, si se realiza algún cambio X, entonces alguna transacción Y es responsable.

Al diseñar la API de Hooks, necesitábamos una forma de que los Hooks pudieran realizar cambios en el ledger más allá de simplemente aceptar o rechazar una transacción. Sin embargo, asociar estos cambios a la Transacción Originaria resultaba confuso y aumentaba significativamente la complejidad general del sistema.

Supongamos, por ejemplo, que un Hook necesita enviarte fondos… la operación de envío se aplicaría efectivamente en el ledger a través de la Transacción Originaria, que podría haber sido algo completamente distinto, como una transacción AccountSet. Además, esta operación de envío debería poder activar otro Hook en el lado receptor del pago.

La solución: Transacciones emitidas. Permitimos que la Transacción Originaria haga exactamente lo que indica su contenido. Si nuestro Hook necesita realizar un cambio adicional en el ledger, como enviar un pago, crea y luego emite una nueva transacción.

Las Transacciones emitidas son transacciones nuevas creadas por la ejecución de un Hook y que entran en consenso para ser procesadas en el siguiente ledger. La transacción puede ser de cualquier tipo, pero debe seguir reglas estrictas de emisión.

Para emitir una transacción, el Hook primero prepara la transacción serializada y luego llama a emit.

Dado que las transacciones emitidas pueden activar Hooks en el siguiente ledger, que a su vez pueden emitir más transacciones, todas las transacciones emitidas incluyen un campo burden y un campo generation dentro de su bloque EmitDetails. El bloque EmitDetails reemplaza el campo de firma en una transacción tradicional.

Los campos burden y generation previenen conjuntamente ataques de tipo Fork bomb en el ledger al aumentar exponencialmente el coste de las transacciones emitidas que crecen de forma exponencial.

Es importante destacar que la API de Hooks sigue la regla estricta de no reescritura. Debes presentar una transacción emitida completa, válida y canónicamente formada a xahaud para su emisión, o será rechazada. No es responsabilidad de xahaud construir tu transacción por ti. El Hook debe hacerlo por sí mismo.

Como se introdujo en Introducción y Terminología, las transacciones emitidas activan callbacks cuando son aceptadas en un ledger. Debido a la naturaleza descentralizada del consenso, la aceptación en un ledger de una transacción emitida no está garantizada, aunque normalmente es muy probable.

Si una transacción emitida expira antes de poder ser aceptada en un ledger (por varias razones: los ledgers pueden estar llenos, la comisión puede ser demasiado alta o la transacción puede ser inválida), entonces se crea una pseudo-transacción en el ledger para limpiar la transacción emitida. Esta pseudo-transacción también llama al callback de tu Hook, con parameter = 1 para indicar que la transacción emitida ha fallado.

La API emit aplicará las siguientes reglas sobre una transacción propuesta (a emitir):

#Regla de emisiónExplicación
1sfSequence = 0Las transacciones emitidas no incrementan el número de secuencia de la cuenta del Hook. Siempre debe establecerse en cero.
2sfPubSigningKey = 0Las transacciones emitidas no están firmadas, pero este campo es obligatorio para el procesamiento en xrpld. Debe establecerse en ceros.
3sfEmitDetails presente y válidoLas transacciones emitidas requieren un bloque sfEmitDetails correctamente completado. Consulta la sección EmitDetails más abajo.
4sfSignature ausenteEste campo debe estar ausente en la transacción emitida, ya que de lo contrario la transacción sería ambigua.
5LastLedgerSequence válido y en el futuroTodas las transacciones emitidas deben tener este campo definido para que el Hook pueda detectar fallos si no recibe callback. Actualmente se establece como máximo en 5 ledgers después del ledger actual.
6FirstLedgerSequence válido y en el siguiente ledgerTodas las transacciones emitidas deben comenzar en el siguiente ledger (después del actual) para evitar ejecuciones recursivas dentro de un mismo ledger.
7Fee correctamente calculada y establecidaLa comisión depende del tamaño de la transacción emitida y de la carga en la red (por ejemplo, si proviene de otra transacción emitida).
8Límite de generación no excedidoUna transacción emitida puede generar otras, formando una cadena. La longitud de esta cadena (sfEmitGeneration) está actualmente limitada a 10.

Todas las transacciones emitidas deben contener un objeto sfEmitDetails correctamente rellenado con los campos siguientes:

CampoValor requeridoDescripción
sfEmitGeneration

Si la Transacción Originaria es una transacción emitida, entonces uno más que su sfEmitGeneration.

Si no lo es, entonces 1.

Debe establecerse usando etxn_generation.

Este campo realiza el seguimiento de la cadena de transacciones emitidas que generan otras transacciones.
sfEmitBurden

Si la Transacción Originaria es una transacción emitida, entonces su burden multiplicado por el número máximo de transacciones que el Hook ha declarado emitir mediante etxn_reserve.

Si no lo es, entonces 1.

Debe establecerse usando etxn_burden.

Este campo sirve como heurística para detectar ataques tipo fork bomb. Las comisiones aumentan exponencialmente en cadenas de emisión para evitar la saturación de la red.
sfEmitParentTxnIDEl ID de la Transacción OriginariaConecta la ejecución del Hook con la transacción original, permitiendo trazar el comportamiento de forma eficiente.
sfEmitNonceUn nonce determinista generado mediante nonceEvita que transacciones idénticas tengan el mismo hash. Todos los nodos deben coincidir en este valor, por lo que se usa una API determinista.
sfEmitCallbackEl ID de cuenta del Hook (20 bytes)Permite a xahaud saber a qué Hook y cuenta debe enviar el callback cuando la transacción emitida es aceptada en un ledger.