Gossip e o Grafo de Canais

Como os nós descobrem canais públicos, políticas de roteamento e caminhos possíveis

Lightning · Técnico

No roteamento onion, a origem precisa conhecer uma rota antes de montar o pacote criptografado. Mas a Lightning não tem um servidor central dizendo quais canais existem. Cada nó aprende a rede por gossip: mensagens assinadas que anunciam canais públicos, metadados de nós e políticas de roteamento.

O resultado local desse processo é o grafo de canais. Nesse grafo, os vértices são node ids, as arestas são canais públicos e cada direção da aresta tem uma política própria: fee base, fee proporcional, CLTV delta, valor mínimo, valor máximo e flag de disponibilidade. A busca de caminho usa esse grafo para escolher uma rota, mas o gossip não garante que a rota tenha liquidez real.

A especificação principal é a BOLT 7. Ela conecta Lightning diretamente ao Bitcoin on-chain, porque um canal público só deve ser aceito se apontar para uma funding transaction existente.

Conteúdo

Modelo mental

Gossip não é o pagamento. Gossip é o mapa público aproximado que permite calcular uma rota. O pagamento real ainda usa HTLCs, commitments e onion routing.

  1. Dois peers abrem um canal on-chain com uma funding transaction.
  2. Se quiserem tornar o canal público, eles trocam assinaturas de anúncio.
  3. Depois que a funding output tem profundidade suficiente, um channel_announcement pode ser propagado.
  4. Cada lado publica seu próprio channel_update, porque a política de encaminhamento é direcional.
  5. Os node ids envolvidos podem publicar node_announcement com alias, cor, endereços e features.
  6. Outros nós validam, armazenam e repassam essas mensagens para montar seu próprio grafo.
Três mensagens de gossip: channel_announcement anuncia o canal, channel_update anuncia a política direcional e node_announcement anuncia metadados do nó.
O grafo nasce de mensagens assinadas e propagadas entre peers.
Descrição longa do diagrama

O diagrama mostra vários nós Lightning conectados. Uma mensagem channel_announcement destaca a existência de um canal público. Mensagens channel_update aparecem em cada direção do canal, indicando taxas e CLTV. Uma mensagem node_announcement aparece ligada a um nó, indicando alias e endereço. Setas simples mostram as mensagens sendo repassadas pela rede.

Mensagens BOLT 7

A BOLT 7 não define apenas três mensagens públicas. Ela também define mensagens de consulta e filtros para sincronizar o grafo sem depender de receber tudo por inundação.

Mensagens relevantes de gossip e sincronização
Tipo Mensagem Escopo Função
259 announcement_signatures entre os dois peers do canal Troca assinaturas antes de publicar um canal público.
256 channel_announcement gossip público Prova que um canal público existe e liga dois node ids a uma funding output on-chain.
258 channel_update gossip público Anuncia a política de roteamento de uma direção do canal.
257 node_announcement gossip público Anuncia metadados do nó: alias, cor, endereços e features.
261 query_short_channel_ids sincronização Pede anúncios e updates para uma lista de SCIDs.
263 query_channel_range sincronização Pede os SCIDs conhecidos em uma faixa de blocos.
265 gossip_timestamp_filter sincronização Filtra updates por timestamp para receber apenas informação recente.

Essas mensagens viajam dentro do protocolo wire. Portanto, elas seguem a moldura geral da BOLT 1: type de 2 bytes e payload específico da mensagem.

Antes do anúncio público

O canal público não aparece magicamente no gossip. Primeiro, os dois peers precisam trocar announcement_signatures. Essa mensagem é enviada entre os participantes do canal, não como gossip global. Ela permite que cada lado obtenha as assinaturas necessárias para construir um channel_announcement completo.

Essa etapa importa porque um anúncio público precisa provar duas coisas ao mesmo tempo:

Sem essa dupla prova, qualquer pessoa poderia inventar canais falsos entre node ids conhecidos ou apontar para saídas Bitcoin que não controla.

channel_announcement

O channel_announcement é o certificado público de existência do canal. Ele diz: "existe um canal público nesta blockchain, localizado por este short channel id, entre estes dois node ids, com estas chaves Bitcoin na funding output".

Campos principais de channel_announcement
Campo Tamanho Função
node_signature_1/2 64 bytes cada Assinaturas dos dois node ids sobre o anúncio.
bitcoin_signature_1/2 64 bytes cada Assinaturas das duas chaves Bitcoin que controlam a funding output.
features variável Feature bits do canal, codificados como vetor de features.
chain_hash 32 bytes Identifica a blockchain onde a funding transaction existe, como Bitcoin mainnet ou testnet.
short_channel_id 8 bytes Localização compacta da funding output: bloco, índice da transação e índice da saída.
node_id_1/2 33 bytes cada Chaves públicas comprimidas dos dois nós Lightning.
bitcoin_key_1/2 33 bytes cada Chaves públicas Bitcoin usadas na saída de financiamento 2-de-2.

A ordem dos dois lados não é arbitrária. O protocolo exige que node_id_1 seja a menor das duas chaves públicas comprimidas em ordem lexicográfica, e node_id_2 a maior. Como toda implementação chega ao mesmo critério só de olhar as chaves, os dois peers concordam sem negociar qual lado é "1" e qual é "2". Esse rótulo estável é o que dá sentido à direção anunciada em cada channel_update.

O ponto anti-spam está aqui: para anunciar um canal público, o anunciante precisa apontar para bitcoin realmente travado em uma saída de transação. Verificar essa saída exige conceitos de altura de bloco, txid, vout, UTXO e P2WSH ou outro formato de script usado pela funding output.

ao receber channel_announcement:

1. conferir se chain_hash é da rede esperada
2. decodificar short_channel_id em bloco, txindex e outputindex
3. localizar a transação no bloco indicado
4. conferir se a saída indicada existe e ainda corresponde a funding output válida
5. verificar as bitcoin_signature_1/2 contra as bitcoin_key_1/2
6. verificar as node_signature_1/2 contra os node_id_1/2
7. aceitar o canal no grafo somente se as provas baterem

A validação exata depende do estado da cadeia visto pelo nó. Uma reorganização, uma funding transaction ainda rasa ou um fechamento de canal podem mudar se aquele canal deve permanecer no grafo local.

Short Channel ID (SCID)

O Short Channel ID é um identificador compacto de 8 bytes. Ele não é um hash aleatório. Ele codifica a localização da funding output dentro da blockchain:

SCID = blockheight x txindex x outputindex
SCID numérico = (blockheight << 40) | (txindex << 16) | outputindex
Partes do short channel id
Parte Tamanho Exemplo Significado
blockheight 24 bits 700000 Altura do bloco que confirmou a funding transaction.
txindex 24 bits 1337 Posição da funding transaction dentro daquele bloco.
outputindex 16 bits 0 Índice da funding output dentro da transação.

Na forma humana, o mesmo valor costuma aparecer como 700000x1337x0. O x é apenas separador. Por baixo, os três campos são empacotados em um inteiro de 64 bits.

Short Channel ID dividido em altura do bloco, índice da transação e índice da saída, apontando para uma funding output na blockchain.
O SCID aponta para a saída de financiamento, não para o saldo atual do canal.
Descrição longa do diagrama

O diagrama mostra uma pilha simples de blocos. Um bloco específico está marcado pela altura. Dentro dele há uma lista de transações, com uma transação marcada pelo índice. Dentro dessa transação há saídas numeradas, e a saída zero está destacada como funding output. Ao lado, o valor 700000x1337x0 é decomposto em bloco, transação e saída.

channel_update

O channel_announcement diz que o canal existe. O channel_update diz se uma direção daquele canal pode ser usada para roteamento e quanto custa usar essa direção.

Isso é direcional. Um canal entre Alice e Bob pode ter uma política para Alice -> Bob e outra para Bob -> Alice. Por isso, um canal público normalmente tem dois updates ativos, um por sentido.

Campos principais de channel_update
Campo Tamanho Função
signature 64 bytes Assinatura do node id responsável por esta direção.
chain_hash 32 bytes Blockchain da funding output.
short_channel_id 8 bytes Canal ao qual esta política pertence.
timestamp 4 bytes Versão temporal do update; updates antigos são ignorados.
message_flags 1 byte Bit 0 = must_be_one (sempre 1); bit 1 = dont_forward.
channel_flags 1 byte Bit 0 = direção do update; bit 1 = direção desabilitada.
cltv_expiry_delta 2 bytes Diferença mínima de CLTV exigida entre HTLC de entrada e de saída.
htlc_minimum_msat 8 bytes Menor HTLC que o nó aceita encaminhar por essa direção.
fee_base_msat 4 bytes Taxa fixa cobrada por encaminhamento nessa direção.
fee_proportional_millionths 4 bytes Taxa proporcional em partes por milhão do valor encaminhado.
htlc_maximum_msat 8 bytes Maior HTLC aceito nessa direção.

Direção e flags

Dois bytes carregam quase toda a semântica de controle do update. O channel_flags diz de qual sentido é a política e se ela está ativa; o message_flags descreve o formato da própria mensagem.

Bits de message_flags e channel_flags
Campo · bit Nome Significado
message_flags · bit 0 must_be_one Sempre 1. Historicamente sinalizava a presença de htlc_maximum_msat, hoje um campo obrigatório.
message_flags · bit 1 dont_forward Update enviado apenas ao peer do canal; não deve ser propagado no gossip global.
channel_flags · bit 0 direction 0 se o originador do update é node_id_1; 1 se é node_id_2.
channel_flags · bit 1 disable Marca a direção como temporária ou permanentemente indisponível.

O bit direction se apoia na ordenação do channel_announcement: valor 0 significa que o update foi assinado por node_id_1, valor 1 que foi por node_id_2. É por isso que um canal saudável costuma ter dois updates, um de cada lado. O bit disable deixa um nó anunciar que sua direção está fora do ar sem fechar o canal, e a busca de caminho deve pular essa direção.

A fórmula de fee anunciada para um hop é:

fee_msat = fee_base_msat + floor(amount_to_forward_msat * fee_proportional_millionths / 1_000_000)

O cltv_expiry_delta entra no cálculo de timeout da rota. Cada hop exige que o HTLC de entrada tenha mais blocos de folga que o HTLC de saída. Isso dá tempo para reagir a falhas e fechamentos unilaterais. Veja a relação com locktime e com a operação de HTLCs em canais.

canal: 700000x1337x0
direção: node_id_1 -> node_id_2

fee_base_msat = 1000
fee_proportional_millionths = 250
cltv_expiry_delta = 40
htlc_minimum_msat = 1000
htlc_maximum_msat = 500000000

valor a encaminhar = 200000 msat
fee = 1000 + floor(200000 * 250 / 1000000)
fee = 1050 msat

Não confunda política de roteamento com liquidez. O gossip pode dizer que uma direção cobra 1050 msat para encaminhar, mas não revela se há saldo remoto suficiente para encaminhar aquele pagamento agora.

node_announcement

O node_announcement descreve um nó público. Ele ajuda carteiras, exploradores e peers a exibirem e encontrarem aquele nó, mas não cria canal sozinho. Um nó sem canal público relevante não é útil para o grafo de roteamento público.

Campos principais de node_announcement
Campo Função
signature Assinatura do node id sobre o anúncio.
features Features do nó, como suporte a campos opcionais e extensões.
timestamp Versão temporal do anúncio.
node_id Chave pública comprimida que identifica o nó Lightning.
rgb_color Cor pública exibida por exploradores e UIs.
alias Nome curto público, não confiável e não único.
addresses Endereços de rede onde outros peers podem tentar conexão.

O campo addresses é uma lista de descritores, cada um começando por um byte de tipo que diz como interpretar os bytes seguintes. Assim um nó anuncia por onde aceita conexões:

Tipos de endereço em node_announcement
Tipo Rede Tamanho Formato
1 IPv4 6 bytes 4 bytes de endereço e 2 bytes de porta.
2 IPv6 18 bytes 16 bytes de endereço e 2 bytes de porta.
4 Tor v3 37 bytes 35 bytes do serviço onion e 2 bytes de porta.
5 DNS variável 1 byte de tamanho, o hostname e 2 bytes de porta.

O tipo 3 existia para Tor v2 e está obsoleto. Os descritores devem vir em ordem crescente de tipo, e um nó que não reconhece um tipo apenas ignora aquele endereço.

Alias e cor não são identidade forte. A identidade forte é o node id, uma chave pública comprimida. Dois nós podem escolher aliases parecidos, e um alias pode mudar ao longo do tempo.

Sincronização de gossip

Um nó recém-conectado não precisa esperar passivamente o mundo inteiro reenviar todos os anúncios. A BOLT 7 define mensagens de consulta para sincronizar o grafo por faixas de blocos, listas de SCIDs e janelas de timestamp.

Mensagens de consulta e filtro
Mensagem Uso
query_channel_range Pergunta quais SCIDs existem em uma faixa de alturas de bloco.
reply_channel_range Responde com uma lista compacta de SCIDs e pode indicar se a resposta está completa.
query_short_channel_ids Pede os anúncios e updates correspondentes a SCIDs específicos.
reply_short_channel_ids_end Marca o fim da resposta para uma consulta por SCID.
gossip_timestamp_filter Pede apenas mensagens com timestamp dentro de uma janela.

Como as consultas são codificadas

As listas de SCIDs em query_short_channel_ids e reply_channel_range começam por um byte de codificação. O valor 0 significa um array bruto, oito bytes por SCID. O valor 1 significa compressão zlib, mas a especificação proíbe usá-lo, porque um payload comprimido pequeno poderia forçar o receptor a alocar muita memória.

Para não pedir tudo às cegas, o query_short_channel_ids pode anexar um query_flags, um bitfield por SCID que escolhe exatamente o que se quer daquele canal:

O query_channel_range pode ir além e pedir, por TLV, os timestamps e os checksums de cada canal. O checksum é um CRC32C calculado sobre o channel_update ignorando signature e timestamp. Com isso, o reply_channel_range devolve, junto dos SCIDs, informação suficiente para o nó decidir se já tem a versão mais recente de cada canal, evitando rebaixar e rebuscar tudo.

Na prática, a rede precisa equilibrar atualidade e custo. Flooding agressivo demais desperdiçaria banda. Flooding lento demais deixaria carteiras calculando rotas com políticas antigas. Por isso, implementações fazem deduplicação, ignoram updates antigos, aplicam limites de frequência e podam canais fechados ou obsoletos.

Propagação escalonada e limites de spam

O gossip não é retransmitido no instante em que chega. A recomendação é acumular as mensagens e liberá-las em lote a cada 60 segundos, independentemente de quando chegaram. Essa propagação escalonada (staggered broadcast) dilui rajadas, facilita a deduplicação e limita o quanto um nó consegue fazer a rede trabalhar.

Poda de canais e nós zumbis

O grafo também precisa esquecer o que morreu. Um canal cuja funding output foi gasta é considerado fechado depois de 72 confirmações e removido da visão local; o atraso dá tempo para anúncios de splice se propagarem antes do descarte. Além disso, um canal cujo channel_update mais recente, em qualquer direção, seja mais velho que duas semanas (1209600 segundos) vira um canal zumbi e pode ser podado. E um nó que perdeu todos os canais associados pode ter seu node_announcement removido também.

Montando o grafo de canais

Cada nó constrói seu próprio grafo local. Não existe "o grafo oficial" da Lightning. Existem visões locais que convergem razoavelmente, mas podem divergir por latência, filtros, conexões, canais privados, políticas recentes e informações que ainda não chegaram.

Como mensagens viram grafo
Mensagem Elemento no grafo Dados usados
channel_announcement aresta SCID, dois node ids, chaves Bitcoin e prova on-chain do canal.
channel_update aresta direcional fees, CLTV delta, limites de HTLC, flag disabled e timestamp.
node_announcement vértice alias, cor, endereços e features do nó.
para montar o grafo:

1. guardar channel_announcement válido como canal público
2. anexar channel_update de cada direção ao canal
3. ignorar update com timestamp mais antigo que o conhecido
4. marcar direção como indisponível quando o bit disabled estiver ativo
5. guardar node_announcement somente para node id ligado a canal conhecido
6. podar canais fechados ou inconsistentes com a cadeia
7. entregar o grafo resultante para a busca de caminho
Grafo de canais montado a partir de anúncios de canais, updates direcionais e anúncios de nós.
A busca de caminho trabalha sobre uma visão local do grafo público.
Descrição longa do diagrama

O diagrama mostra um grafo com vários nós conectados por canais. Os nós aparecem como círculos e os canais como linhas. Algumas linhas possuem setas em sentidos diferentes, indicando que cada direção pode ter política própria. Uma caixa lateral lista dados vindos de channel_announcement, channel_update e node_announcement.

Canais públicos vs. privados

Nem todo canal entra no gossip. Um canal privado, ou não anunciado, existe entre dois peers, mas não aparece no grafo público. Ele ainda pode receber ou enviar pagamentos, desde que o pagador receba informação suficiente por outro caminho.

Em invoices BOLT 11, isso aparece como routing hints no campo r. O recebedor inclui uma pequena rota final com node id, SCID, fee base, fee proporcional e CLTV delta para que o pagador consiga chegar até um canal que não descobriria pelo gossip público.

Essa diferença é importante para privacidade: canal privado reduz exposição no grafo público, mas não torna o pagamento invisível para os peers envolvidos. Também aumenta a dependência de hints corretos e atualizados na invoice.

Ferramenta: Short Channel ID

A ferramenta abaixo converte entre a forma humana blocoxtxxsaida, decimal e hexadecimal do SCID. Ela é didática e roda somente no navegador. Não cole dados sensíveis de carteira; SCID de canal público pode ser público, mas exemplos educativos devem usar valores fictícios.

Short Channel ID

Short Channel ID

O SCID identifica um canal pela localização da sua saída de financiamento na blockchain: bloco, índice da transação e índice da saída, empacotados em 64 bits (escritos como blocoxtxxsaída).

Compor

Limites: bloco e transação usam 24 bits; saída usa 16 bits.

SCID (string):
SCID (decimal):
SCID (hex):
Bytes (bloco | tx | saída):

Decompor

O valor deve caber em 64 bits. Um alias pode não representar uma localização on-chain.

Bloco: · Tx: · Saída:
SCID (string):
SCID (decimal):
SCID (hex):

Privacidade, segurança e limites

Gossip é público por design. Isso ajuda roteamento e auditoria, mas expõe metadados:

Do ponto de vista de segurança, a regra mais importante é não aceitar gossip sem validação. Assinaturas, chain hash, SCID, funding output e timestamps existem para impedir spam barato, impersonação e atualizações antigas sobrescrevendo informação mais nova.

Armadilhas comuns

Mapa de dependências conceituais

Antes de ler esta página

Depois desta página

Referências técnicas usadas

Com o grafo em mãos, o próximo problema é escolher uma rota que provavelmente funcione, pese fees, respeite CLTV e lide com falhas. Esse é o assunto da busca de caminho.