El denominador de la nota incluía dos pesos que nunca restan (rbf, peeling) y
excluía uno que sí (input_linkage, hasta 30), así que las deducciones podían
superarlo en 17 puntos y dar negativo. Corregido en ambas direcciones, con los
cortes de banda recalibrados a 79/54 para que ninguna transacción cambie de
banda por el arreglo.
'Redondo' equivalía a 'múltiplo de 0,001 BTC' por dos condiciones redundantes,
y se le escapaban pagos de 10.000 o 50.000 sats. Ahora se mide por ceros
finales y la señal se gradúa.
Dos checks nuevos. El de polvo avisaba de una vinculación futura y nunca
miraba si estaba ocurriendo delante: ahora la detecta cuando el polvo se gasta
junto a monedas normales. Y la consolidación pura (N entradas, 1 salida) no
disparaba el check de inputs innecesarios; ahora se nombra, sin cobrarla dos
veces porque input_linkage ya la penaliza.
tests/test6.js cubre lo nuevo y la coherencia de la nota.
La matemática pasa todos los vectores oficiales (RIPEMD-160, secp256k1, BIP32
vectores 1 y 2, bech32/BIP173) y no se ha tocado. Los fallos estaban en la
validación de la entrada:
- No se comprobaba la checksum del xpub: un carácter mal copiado generaba 200
direcciones ajenas y el usuario veía su cartera 'sin actividad'. Mismo
patrón de falso negativo silencioso que el resto de fallos de hoy.
- No se validaba la longitud (78 bytes) ni el formato de la clave pública.
- tpub se trataba como mainnet: la red se detectaba por prefijo de texto
('tb'/'u'/'v') y un tpub empieza por 't' pero no por 'tb'. Ahora se detecta
por bytes de versión, con las diez variantes.
- deriveChildPubkey aceptaba índices endurecidos, imposibles desde una clave
pública. No alcanzable desde la UI, pero debe defenderse sola.
Se añade tests/ con las cuatro baterías, documentando también qué NO cubren:
no sustituyen una auditoría externa.