-
Para este momento, ya deberías estar familiarizado con cerrar un canal de manera forzada, es decir, transmitiendo la transacción de compromiso directamente. Pero, ¿qué hay de cerrar un canal de manera cooperativa? ### Cerrando un canal de manera cooperativa Alice y Bob ciertamente tuvieron buenos momentos juntos, pero todas las cosas buenas deben llegar a su fin. Cerrar un canal de manera cooperativa requiere que los dos pares decidan sobre una transacción de cierre final que gastará de la transacción de financiación y pagará a cada uno su saldo final del canal de inmediato. #### Paso 1: Bob -> Alice: shutdown Bob ha decidido que es hora de cortar lazos y envía a Alice el mensaje de cierre. ![shutdown](https://cdn.satellite.earth/c426f513d9ee71c22851c630a785342bcde0da7657817a766f51ad779b235271.png) El mensaje de cierre contiene el `scriptpubkey` al que Bob le gustaría que se enviara su saldo final del canal en la transacción de cierre. Una vez que Bob ha enviado este mensaje final, ya no puede enviar nuevos mensajes `update_add_htlc`. Solo puede enviar mensajes de eliminación de HTLC y `update_fee`. Cuando Alice recibe este mensaje de Bob, debe responder con su propio mensaje de cierre y tampoco puede enviar nuevos mensajes `update_add_htlc`. Alice y Bob ahora deben esperar hasta que todos los HTLC restantes hayan sido eliminados de ambas transacciones de compromiso. Dado que la transacción de cierre gastará de la transacción de financiación y se verá explícitamente diferente de las transacciones de compromiso, volveré a introducir algunos de los detalles en el diagrama de estado: ![1_initial_1](https://cdn.satellite.earth/96ea96228ee4ba11199405503b1ad5e0c3c07e913bafd7b0217f0b35197d14d1.png) Una vez que todos los HTLC hayan sido eliminados, lo cual en nuestro ejemplo ya es el caso, pueden comenzar a negociar una tarifa para usar en la transacción de cierre final. El financiador del canal debe iniciar esta negociación. Supongamos que el financiador del canal es Alice. #### Paso 2: Alice -> Bob: closing_signed Alice primero elegirá una tasa de tarifa que considera apropiada para la transacción de cierre. Luego usará esa tasa de tarifa para completar la construcción de la transacción de cierre y firmarla. Luego envía el mensaje `closing_signed` a Bob: ![closing_signed](https://cdn.satellite.earth/d2163f54634661a04d0bf6b48253893ca793c32cee962bdb26f0a0a6255f3b8c.png) El campo `fee_satoshis` le dice a Bob la tarifa en satoshis que Alice utilizó para construir la primera propuesta de transacción de cierre. La firma contiene la firma de Alice para esta propuesta. Ella también puede incluir opcionalmente los campos `min_fee_satoshis` y `max_fee_satoshis` para hacerle saber a Bob que si no está de acuerdo con su propuesta de `fee_satoshis`, puede enviar una contrapropuesta siempre que su contrapropuesta esté entre el rango mínimo y máximo proporcionado. En este punto, el estado del canal se ve así: ![32_closing_alice_prop](https://cdn.satellite.earth/362b08699664bc07019932d815081b9dd4656f4219b668e6c4f77569048d7a09.png) Hay dos transacciones de compromiso válidas que pueden ser firmadas en cualquier momento por cada parte para realizar un cierre forzado, y hay una propuesta de transacción de cierre que utiliza una tasa de tarifa de `x` sats por byte. Esta transacción de cierre actualmente solo tiene la firma de Alice y, por lo tanto, aún no es válida. Si en este punto, Bob está contento con la propuesta de Alice, podría proceder a firmar la transacción de cierre utilizando la tasa de tarifa propuesta por Alice y podría transmitirla, y eso sería el final. Pero, para el bien del ejemplo, digamos que Bob no está del todo contento todavía. #### Paso 3: Bob -> Alice: closing_signed Bob puede decidir que la tasa de tarifa que utilizó Alice es demasiado baja. Así que envía una contrapropuesta con una nueva tasa de tarifa, `y` sats por byte, junto con su firma para esta contrapropuesta. ![33_closing_bob_prop](https://cdn.satellite.earth/5fc6c7973fda63eb972347d82302d0ec5cb6ee095ce32d5af7ecc7122a626dd8.png) #### Paso 4: Alice -> Bob: closing_signed Si Alice está contenta con la contrapropuesta de Bob, entonces firma la transacción de cierre utilizando la tasa de tarifa sugerida por Bob. Luego puede transmitir la transacción y dar por terminado el asunto. Sin embargo, se recomienda en la especificación que Alice envíe un mensaje más `closing_signed` a Bob, pero esta vez con el campo `fee_satoshis` establecido en `y` sat por byte junto con su firma para la transacción. Ambas partes ahora tendrán ambas firmas requeridas para transmitir la transacción de cierre final que utiliza la tasa de tarifa de `y` sats por byte. ![34_closing_alice_agree](https://cdn.satellite.earth/660b1dfa2d15557f189c74a9be25ddf722f2e5094709a93c81c85d0114d53813.png) Cualquiera de las partes o ambas pueden ahora transmitir la transacción de cierre a la red de Bitcoin. Eventualmente será confirmada y el canal se cerrará oficialmente. ![35_closed](https://cdn.satellite.earth/9277334bc72854e910ca6154ea2a05098ebc085e9484dbe209984d25a0f1db1c.png) Si este canal era un canal público, entonces cualquier nodo en la red que tuviera este canal en su gráfico de enrutamiento podrá ver que la salida de financiación del canal ha sido gastada y, por lo tanto, eliminará el canal de su gráfico en este punto. La belleza del canal es que Alice y Bob podrían haber enviado millones de HTLCs de un lado a otro a lo largo de la vida del canal y, al final, todo lo que apareció en la cadena fue la transacción de apertura y la transacción de cierre. Alice y Bob vivieron felices para siempre. ### Referencias - [BOLT2 Protocolo de pares](https://github.com/lightning/bolts/blob/master/02-peer-protocol.md) - [Operación normal de un canal LN previo a taproot](https://ellemouton.com/posts/normal-operation-pre-taproot/) por nostr:nprofile1qqswrt9pnxatlplu49h6meld8svmwqt87wwvk256rqk07n6eu4qeh5gpz3mhxue69uhhyetvv9ujuerpd46hxtnfduqs6amnwvaz7tmwdaejumr0dszpfjtz - [Una guía técnica sobre contratos de tiempo bloqueado por hash y operaciones de canales Lightning](https://lightning.engineering/posts/2023-06-28-channel-normal-op/)