Learning-Bitcoin-from-the-C.../pt/20_3_Closing_a_Channel.md
2021-09-21 11:03:20 -03:00

13 KiB
Raw Blame History

20.3: Fechando um Canal

NOTA: Esta seção foi adicionada recentemente ao curso e é um rascunho inicial que ainda pode estar aguardando revisão.

Neste capítulo, aprenderemos como fechar um canal usando a interface de linha de comando lightning-cli close. Fechar um canal significa que nós e a nossa contraparte enviarão o saldo do canal acordado para a blockchain, pelo qual devemos pagar as taxas de transação e esperar que a mesma seja posta em um bloco. Um fechamento pode ser cooperativo ou não, mas funciona de qualquer maneira.

Para fechar um canal, primeiro precisamos saber o ID do node remoto. Podemos recuperá-lo de duas maneiras.

Encontrando Nossos Canais Pelos Saldos

Podemos usar o comando lightning-cli listfunds para ver nossos canais. Este comando RPC exibe todos os fundos disponíveis, em outputs não gastos (UTXOs) na carteira interna ou bloqueados em channels (canais) abertos.

c$ lightning-cli --testnet listfunds
{
   "outputs": [
      {
         "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
         "output": 1,
         "value": 99847,
         "amount_msat": "99847000msat",
         "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c",
         "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8",
         "status": "confirmed",
         "blockheight": 1862856,
         "reserved": false
      }
   ],
   "channels": [
      {
         "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
         "connected": true,
         "state": "CHANNELD_NORMAL",
         "short_channel_id": "1862856x29x0",
         "channel_sat": 89987,
         "our_amount_msat": "89987000msat",
         "channel_total_sat": 100000,
         "amount_msat": "100000000msat",
         "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
         "funding_output": 0
      }
   ]
}

  "message_flags": 1,
  "channel_flags": 2,
  "active": true,
  "last_update": 1595508075,
  "base_fee_millisatoshi": 1000,
  "fee_per_millionth": 1,
  "delay": 40,
  "htlc_minimum_msat": "1000msat",
  "htlc_maximum_msat": "280000000msat",
  "features": ""
}

Poderíamos também recuperar o ID do enésimo canal em uma variável como esta:

c$ nodeidremote=$(lightning-cli --testnet listfunds | jq '.channels[0] | .peer_id')

Encontrando Canais Usando o JQ

A outra maneira de encontrar canais para serem fechados é usando o comando listchannels. Ele retorna dados dos canais que são conhecidos pelo node. Como os canais podem ser bidirecionais, até dois nodes serão retornados por cada canal (um para cada direção).

No entanto, assim como no mundo real, a fofoca (gossip) da Lightning Network é muito eficaz e, em pouco tempo, iremos conhecer milhares de canais. Isso é ótimo para enviar pagamentos via Lightning Network, mas é pouco útil para descobrir os nossos próprios canais. Fazer isso requer um pouco de trabalho com jq.

Primeiro, precisamos saber nosso próprio ID do node, que pode ser recuperado com o getinfo:

c$ nodeid=$(lightning-cli --testnet getinfo | jq .id)
c$ echo $nodeid
"03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687"
c$

Podemos então usar isso para procurar nos listchannels quaisquer canais onde nosso node seja a origem ou o destino:

c$ lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid')'
{
  "source": "03240a4878a9a64aea6c3921a434e573845267b86e89ab19003b0c910a86d17687",
  "destination": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
  "short_channel_id": "1862856x29x0",
  "public": true,
  "satoshis": 100000,
  "amount_msat": "100000000msat",
  "message_flags": 1,
  "channel_flags": 0,
  "active": true,
  "last_update": 1602639570,
  "base_fee_millisatoshi": 1,
  "fee_per_millionth": 10,
  "delay": 6,
  "htlc_minimum_msat": "1msat",
  "htlc_maximum_msat": "99000000msat",
  "features": ""
}

Aqui está nosso node favorito 032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543 novamente, como sendo o destino.

Depois de saber o que temos, podemos armazená-lo em uma variável:

c$ nodeidremote=$(lightning-cli --testnet listchannels | jq '.channels[] | select(.source == '$nodeid' or .destination == '$nodeid') | .destination')

Fechando um Canal

Agora que temos um ID do node remoto, estamos prontos para usar o comando lightning-cli close para fechar um canal. Por padrão, ele tentará fechar o canal cooperativamente com o par; se quisermos fechá-lo unilateralmente, precisamos definir o argumento unilateraltimeout com o número de segundos de espera. Se definirmos como sendo 0 e o par estiver online, um fechamento mútuo ainda irá ser tentado. Para este exemplo, tentaremos um fechamento mútuo.

c$ lightning-cli --testnet close $nodeidremote 0
{
   "tx": "02000000011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c150900000000",
   "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
   "type": "mutual"
}

A transação de fechamento na blockchain é [f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f] (https://blockstream.info/testnet/tx/f68de52d80a1076e36c67795f9f9db4f13048519489593f].

É essa transação de fechamento que realmente gasta os fundos que foram negociados de um lado para outro por meio de transações Lightning. Isso pode ser visto examinando a transação:

$ bitcoin-cli --named getrawtransaction txid=f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f verbose=1
{
  "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
  "hash": "3a6b3994932ae781bab80e159314bad06fc55d3d33453a1d663f9f9415c9719c",
  "version": 2,
  "size": 334,
  "vsize": 169,
  "weight": 673,
  "locktime": 0,
  "vin": [
    {
      "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
      "vout": 0,
      "scriptSig": {
        "asm": "",
        "hex": ""
      },
      "txinwitness": [
        "",
        "304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01",
        "3045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab01",
        "522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae"
      ],
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.00010012,
      "n": 0,
      "scriptPubKey": {
        "asm": "0 d39feb57a663803da116402d6cb0ac050bf051d9",
        "hex": "0014d39feb57a663803da116402d6cb0ac050bf051d9",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "tb1q6w07k4axvwqrmggkgqkkev9vq59lq5we5fcrzn"
        ]
      }
    },
    {
      "value": 0.00089804,
      "n": 1,
      "scriptPubKey": {
        "asm": "0 51c88b44420940c52a384bd8a03888e3676c1509",
        "hex": "001451c88b44420940c52a384bd8a03888e3676c1509",
        "reqSigs": 1,
        "type": "witness_v0_keyhash",
        "addresses": [
          "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4"
        ]
      }
    }
  ],
  "hex": "020000000001011d3cf2126ae36e12be3aee893b385ed6a2e19b1da7f4e579e3ef15ca234d69660000000000ffffffff021c27000000000000160014d39feb57a663803da116402d6cb0ac050bf051d9cc5e01000000000016001451c88b44420940c52a384bd8a03888e3676c1509040047304402207f8048e29192ec86019bc83be8b4cac5d1fc682374538bed0707f58192d41c390220512ebcde122d53747feedd70c09153a40c56d09a5fec02e47642afdbb20aa2ac01483045022100d686a16084b60800fa0f6b14c25dca1c13d10a55c5fb7c6a3eb1c5f4a2fb20360220555f5b6e672cf9ef82941f7d46ee03dd52e0e848b9f094a41ff299deb8207cab0147522102f7589fd8366252cdbb37827dff65e3304abd5d17bbab57460eff71a9e32bc00b210343b980dff4f2723e0db99ac72d0841aad934b51cbe556ce3a1b257b34059a17052ae00000000",
  "blockhash": "000000000000002a214b1ffc3a67c64deda838dd24d12154c15d3a6f1137e94d",
  "confirmations": 1,
  "time": 1602713519,
  "blocktime": 1602713519
}

A entrada da transação é 66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d, que foi a transação de financiamento feita na seção §19.3. A transação tem duas saídas, uma para o node remoto e outra para a carteira local da c-lightning. A saída no índice 0 corresponde ao node remoto com um valor de 0,00010012 BTC e, a saída no índice 1 corresponde ao node local com um valor de 0,00089804 BTC.

A Lightning mostrará da mesma forma 89.804 satoshis retornados como um novo UTXO em nossa carteira:

$ lightning-cli --network=testnet listfunds
{
   "outputs": [
      {
         "txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
         "output": 1,
         "value": 99847,
         "amount_msat": "99847000msat",
         "scriptpubkey": "00142fe02e5be9283e8c5bcb93ae61421baf8cb64f9c",
         "address": "tb1q9lszuklf9qlgck7tjwhxzssm47xtvnuu4jslf8",
         "status": "confirmed",
         "blockheight": 1862856,
         "reserved": false
      },
      {
         "txid": "f68de52d80a1076e36c677ef640539c50e3d03f77f9f9db4f13048519489593f",
         "output": 1,
         "value": 89804,
         "amount_msat": "89804000msat",
         "scriptpubkey": "001451c88b44420940c52a384bd8a03888e3676c1509",
         "address": "tb1q28ygk3zzp9qv223cf0v2qwygudnkc9gfp30ud4",
         "status": "confirmed",
         "blockheight": 1863006,
         "reserved": false
      }
   ],
   "channels": [
      {
         "peer_id": "032a7572dc013b6382cde391d79f292ced27305aa4162ec3906279fc4334602543",
         "connected": false,
         "state": "ONCHAIN",
         "short_channel_id": "1862856x29x0",
         "channel_sat": 89987,
         "our_amount_msat": "89987000msat",
         "channel_total_sat": 100000,
         "amount_msat": "100000000msat",
         "funding_txid": "66694d23ca15efe379e5f4a71d9be1a2d65e383b89ee3abe126ee36a12f23c1d",
         "funding_output": 0
      }
   ]
}

Compreendendo os Tipos de Canais de Fechamento.

O comando close do RPC tenta fechar um canal cooperativamente com nosso par ou unilateralmente após o argumento unilateraltimeout expirar. Isso traz alguma discussão adicional, pois vai ao cerne do design que não precisa de nenhuma confiança da Lightning:

Cada participante de um canal pode criar tantos pagamentos Lightning para a contraparte quanto os fundos permitirem. Na maioria das vezes não haverá desentendimentos entre os participantes, portanto, haverá apenas duas transações na rede, uma abrindo e outra fechando o canal. No entanto, pode haver cenários em que um par não está online ou não concorda com o estado final do canal ou quando alguém tenta roubar fundos da outra parte. É por isso que existem fechamentos cooperativos e forçados.

Fechamento Cooperativo

No caso de um fechamento cooperativo, ambos os participantes do canal concordam em fechar o canal e estabelecer o estado final na blockchain. Ambos os participantes devem estar online, pois o fechamento é realizado transmitindo um gasto incondicional da transação de financiamento com uma saída para cada par.

Fechamento Forçado

No caso de fechamento forçado, apenas um participante está online ou os participantes discordam sobre o estado final do canal. Nessa situação, um par pode realizar um fechamento unilateral do canal sem a cooperação do outro node. É executado transmitindo uma transação de confirmação que confirma o estado do canal anterior que ambas as partes concordaram. Esta transação de compromisso contém o estado do canal dividido em duas partes: o saldo de cada participante e todos os pagamentos pendentes (HTLCs).

Para realizar este tipo de fechamento, devemos especificar um argumento unilateraltimeout. Se este valor não for zero, o comando de fechamento fechará unilateralmente o canal quando esse número de segundos for atingido:

c$ lightning-cli --network=testnet close $newidremote 60
{
   "tx": "0200000001a1091f727e6041cc93fead2ea46b8402133f53e6ab89ab106b49638c11f27cba00000000006a40aa8001df85010000000000160014d22818913daf3b4f86e0bcb302a5a812d1ef6b91c6772d20",
   "txid": "02cc4c647eb3e06f37fcbde39871ebae4333b7581954ea86b27b85ced6a5c4f7",
   "type": "unilateral"
}

Resumo: Fechando um Canal

Ao fechar um canal, realizamos uma transação na blockchain encerrando nosso relacionamento financeiro com o node remoto. Para fechar um canal, devemos levar em consideração nosso status e o tipo de fechamento que desejamos executar.

O Que Vem Depois?

Vamos continuar "Usando a Lightning" na seção §20.4: Expandindo a Lightning Network.