Track 4 / 5
Qué mensajes se mandan los nodos, por qué un peer block-relay-only nunca recibe transacciones, y cómo una tx confirmada vuelve al mempool tras un reorg.
Probá
bob getpeerinfo | jq '.[] | {addr, bytessent_per_msg}'Mirá
Cada nodo cuenta cuántos bytes mandó y recibió por tipo de mensaje y por peer. Aparecen los del handshake y los de uso diario:
version y verack: el saludo.sendaddrv2 (BIP155), wtxidrelay (BIP339), sendcmpct (BIP152) y feefilter (BIP133): lo que cada uno soporta y quiere recibir.getheaders / headers: sincronizar la cadena.ping / pong: seguir vivos. Core manda un ping cada 2 minutos.inv, getdata, tx: las transacciones que vimos en el track 2.Por qué
Los anuncios de transacciones no salen al instante. Core los agrupa y los manda cada 2 s en promedio a peers salientes y cada 5 s a peers entrantes, con tiempos aleatorios. Así es más difícil deducir qué nodo originó una tx. Por eso usamos lab_wait_tx en vez de mirar el mempool enseguida.
Probá
Abrimos una conexión block-relay-only de alice a carol. addconnection es un RPC oculto que solo existe para pruebas en regtest:
alice addconnection carol:18444 block-relay-only false
alice getpeerinfo | jq '.[] | {id, addr, connection_type}'Anotá el id del peer block-relay-only y mandá una tx a carol:
TX=$(alice sendtoaddress "$(carol getnewaddress)" 1)
lab_wait_tx carol "$TX"
docker compose logs alice | grep -E "sending (inv|tx) .* peer=<id>$"Mirá
grep no devuelve nada: alice nunca le ofrece la tx a ese peer.net de alice tiene que estar encendida (track 2).Por qué
En mainnet cada nodo abre 2 conexiones block-relay-only además de las 8 full-relay. Sirven contra ataques de partición: como no intercambian transacciones ni direcciones, a un tercero le cuesta más detectarlas, y la topología de la red queda más oculta.
Minamos un bloque para dejar el mempool vacío:
alice -generate 1
lab_wait_syncPregunta
¿Qué pasa si dos partes de la red minan al mismo tiempo sin verse?
Probá
Cortamos la red. alice incluye una tx en un bloque mientras carol mina dos:
lab_split
TX=$(alice sendtoaddress "$(alice getnewaddress)" 1)
FORK=$(alice -generate 1 | jq -r '.blocks[0]')
carol -generate 2
alice getbestblockhash; carol getbestblockhashLas dos puntas son distintas. Reconectamos:
lab_join
lab_wait_sync
alice getchaintips
alice getblock "$FORK" | jq .confirmations
alice getrawmempoolMirá
getchaintips muestra dos puntas: la active y el bloque de alice como valid-fork con branchlen: 1.confirmations: -1: el bloque de alice ya no está en la cadena activa.A <tx> la tx entra al mempool
C <FORK> alice mina su bloque
D <FORK> el bloque se desconecta: la cadena de carol tiene más trabajo
A <tx> la tx vuelve al mempool
C <…> primer bloque de carol
C <…> segundo bloque de carolPor qué
Una confirmación no es una garantía absoluta: si aparece una cadena con más trabajo, el nodo se reorganiza. Por eso se esperan varias confirmaciones. En el log de alice (docker compose logs alice | grep UpdateTip) se ve la altura bajar y volver a subir.