Mensagens Wire e TLV

Inspecione tipos Lightning e a estrutura canônica de streams TLV

Depois que a camada de transporte decripta um frame, o receptor obtém uma mensagem Lightning: um type de 2 bytes em big-endian, seguido pelo payload definido para aquele tipo e, quando previsto, uma extensão TLV.

Esta ferramenta executa duas tarefas limitadas: identifica o número do tipo usando um catálogo didático parcial e desmonta a estrutura genérica de um stream TLV. Ela não valida o schema completo, não confirma suporte por uma implementação e não executa mensagens.

Conteúdo

Ferramenta

Use somente bytes públicos, fictícios ou de teste. Os exemplos mostram mensagens completas e incompletas de propósito, tipos custom desconhecidos, TLV canônico e erros estruturais.

Mensagens Wire e TLV

Mensagens Wire e TLV

Identifica o tipo de 2 bytes e valida a estrutura genérica de um stream TLV. Não valida o schema completo.

Tipo da mensagem

Os 2 primeiros bytes são o tipo em big-endian. O catálogo de nomes desta ferramenta é parcial.

Exemplos:

Resultado da mensagem wire

Stream TLV

Sequência type-length-value com BigSize mínimo e types em ordem crescente.

Exemplos:

Resultado do stream TLV

Fonte primária

A BOLT 1 define o envelope da mensagem, os grupos numéricos, a regra par/ímpar, o formato TLV, o inteiro BigSize e vetores oficiais de teste. O formato interno de cada payload pode vir da própria BOLT 1 ou de especificações como BOLT 2, BOLT 4 e BOLT 7.

Transporte, wire e schema

  1. A BOLT 8 autentica peers, cifra o tráfego e delimita frames.
  2. A BOLT 1 lê os 2 primeiros bytes plaintext como type.
  3. O BOLT responsável pelo tipo define os campos e as regras do payload.
  4. Features negociadas e o estado da conexão ou do canal determinam se a mensagem pode ser aceita naquele momento.

Identificar 0012 como ping não basta para validar a mensagem. Ainda é preciso ler num_pong_bytes, byteslen, conferir o tamanho de ignored e aplicar os limites definidos pela BOLT 1.

Anatomia da mensagem

Mensagem Lightning decriptada dividida em type de 2 bytes, payload variável e extensão TLV opcional.
O transporte informa o tamanho total; o type determina qual schema deve interpretar os bytes restantes.
Descrição longa do diagrama

Uma barra horizontal representa os bytes plaintext de uma mensagem. Os dois primeiros bytes formam o campo type em big-endian. A região seguinte é o payload de tamanho variável, interpretado conforme o tipo. No fim pode existir uma extensão composta por registros TLV. O diagrama deixa a camada de transporte fora da barra porque a decriptação e o framing já aconteceram.

Grupos numéricos definidos pela BOLT 1
Faixa Grupo Uso
0–31 Setup e controle Conexão, init, features, warning, error, ping e pong.
32–127 Canal Abertura, financiamento e fechamento de canais.
128–255 Commitment HTLCs, assinaturas, revogações, fees e ressincronização.
256–511 Roteamento Gossip, anúncios, updates e consultas do grafo.
32768–65535 Custom Mensagens experimentais ou específicas de aplicações.

A faixa 512–32767 não pertence a um dos cinco grupos base listados pela BOLT 1. A ferramenta informa isso como classificação numérica; não tenta adivinhar se um número foi reservado, proposto em outro documento ou usado por uma implementação.

A mensagem inteira, incluindo os 2 bytes de type, precisa caber no limite de 65.535 bytes do transporte. Mensagens de canal com channel_id compartilham uma única conexão entre os mesmos peers; o identificador direciona cada mensagem ao canal correspondente.

Conhecido, desconhecido e custom

“Conhecido” é uma propriedade do receptor e do contexto, não apenas de uma tabela. Um número pode estar atribuído em um BOLT atual, mas ser desconhecido por uma implementação antiga. Também pode exigir feature negotiation. Por isso a ferramenta usa a expressão catálogo parcial: encontrar um nome não prova que seu nó suporte ou aceite a mensagem.

Regra para tipos de mensagem realmente desconhecidos
Paridade Recepção Envio
ÍmparO receptor deve ignorar a mensagem desconhecida.Pode ser usado quando receptores sem suporte devem ignorar os dados.
ParO receptor deve fechar a conexão e pode falhar os canais.Não deve ser enviado sem atribuição conhecida ou negociação prévia.

Na faixa custom, 0x8000 é par e 0x8001 é ímpar. Isso classifica o comportamento de um receptor que não conhece o tipo; não declara que qualquer um deles esteja atribuído ou suportado.

BigSize

Os campos type e length de um registro TLV são inteiros uint64 codificados como BigSize. O formato lembra o CompactSize do Bitcoin, mas os inteiros multibyte do BigSize usam big-endian.

Fronteiras canônicas do BigSize
Intervalo Bytes Exemplo mínimo
0–2521fc = 252
253–65.5353fd00fd = 253
65.536–4.294.967.2955fe00010000 = 65.536
4.294.967.296–264-19ff0000000100000000 = 4.294.967.296

A codificação deve ser mínima. fd00fc também produziria numericamente 252, mas é inválido porque fc usa menos bytes. Essa unicidade é importante para parsers e para estruturas assinadas.

Stream TLV

Um registro concatena três partes:

[ type: BigSize ][ length: BigSize ][ value: length bytes ]
Registro TLV dividido em type BigSize, length BigSize e value com o número de bytes indicado pelo length.
Um stream é a concatenação de zero ou mais registros em ordem estritamente crescente de type.

O parser genérico pode verificar BigSize mínimo, ordem, duplicação e truncamento. Ele não pode, sem receber o schema daquele stream, saber se o type está definido, se o value tem o formato correto ou se um peer negociou suporte.

O namespace também importa. Types abaixo de 216 são reservados para a especificação Lightning; types a partir de 216 ficam disponíveis para registros custom. Em ambos os espaços, se um type for realmente desconhecido, par faz o parse falhar e ímpar permite descartar exatamente os bytes indicados por length.

Exemplos trabalhados

init mínimo

0010 0000 0000
^^^^ ^^^^ ^^^^
type gflen flen

type = 0x0010 = 16 = init
globalfeatures = 0 bytes
features = 0 bytes

Este exemplo é completo e tem 6 bytes. Já 0010 contém somente o type: a ferramenta consegue nomeá-lo, mas alerta implicitamente pela contagem de payload que ainda não houve validação do schema.

Dois registros TLV

c9 01 2a  cb 01 04
^^ ^^ ^^  ^^ ^^ ^^
T  L  V   T  L  V

registro 1: type 201, length 1, value 2a
registro 2: type 203, length 1, value 04

Os types são ímpares, estão em ordem crescente e os values têm o tamanho declarado. O stream é estruturalmente canônico. Sem um schema específico, porém, não se pode afirmar o significado de 2a ou 04.

Falhas que a ferramenta detecta

Limites e armadilhas

Mapa de dependências conceituais

Antes de usar esta ferramenta

Depois desta ferramenta

Referências técnicas usadas