fix: no atribuir al actor las direcciones de un custodio

Misma raíz que el fallo del CoinJoin, en otra variante. El cluster CIOH ya
excluía los custodios (actorAddrSet), pero la atribución por huella de
software no: la hot wallet de Bitfinex aparecía como 'dirección atribuida al
actor' mientras la conclusión la identificaba como exchange dos líneas más
abajo. La dirección donde el ladrón deposita es del exchange, no suya.

Verificado contra el nodo con un depósito real: de 2 atribuciones a 1.
This commit is contained in:
2026-07-27 13:37:22 +02:00
parent 6f721a535c
commit 8a5efad2ed
2 changed files with 25 additions and 1 deletions
+16 -1
View File
@@ -4311,10 +4311,25 @@
// así que la huella sale "estable" por construcción, no porque sea el
// mismo actor. Atribuir salidas de un CoinJoin por esa señal sería
// señalar a terceros que solo coincidieron en la misma transacción.
// Dos exclusiones, por el mismo motivo de fondo: la huella de software
// solo dice algo del actor cuando la dirección PUEDE ser suya.
// - Mezclas: todos los participantes usan el mismo programa, así que la
// huella sale estable por construcción, no por ser el mismo actor.
// - Custodios: la dirección es del servicio, no de quien deposita.
// Atribuir una hot wallet de exchange "al actor" en un informe que
// puede acabar en una denuncia es señalar al mensajero. Además
// contradice la conclusión del propio informe, que la identifica como
// custodio.
// El cluster CIOH ya excluía los custodios (ver actorAddrSet); esto
// alinea la atribución por huella con ese mismo criterio.
const fingerprintStableAddrs = new Set();
for (const n of allNodes) {
if (n.stopReason === "mixer") continue;
if (n.fingerprintComparison?.changed === false) n.addresses.out.forEach(a=>fingerprintStableAddrs.add(a));
if (n.fingerprintComparison?.changed === false) {
n.addresses.out.forEach(a => {
if (!(n.custodyAddrs || []).includes(a)) fingerprintStableAddrs.add(a);
});
}
}
const attributed = [];