fix(data): count each visible transfer once, not once per pallet
ci / gate (push) Successful in 4m29s

Every visible transfer emits `Balances::Transfer` and
`Wormhole::NativeTransferred` with the same payload in the same extrinsic
(193,686 of 193,691 on mainnet), and `account_flows`, `flows_for` and
`wormhole_routes` added the two: every account page's sent and received,
the distribution table's `sent on`, and the wormhole page's visible routes
were doubled. A `Balances::Transfer` now counts only when it has no such
twin, which keeps the five that stand alone. Checked on production data:
the bridge custody account's `received` goes from 372,003.992 over 30
receipts to 186,001.996 over 15.

Closes #42

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015pkwBsR54NRmZyU4QVhvfj
This commit is contained in:
2026-10-06 17:42:57 +03:00
co-authored by Claude Opus 5.5
parent b55d323456
commit 9becf2629e
5 changed files with 101 additions and 66 deletions
@@ -1,59 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "\n with moves as (\n select fields->>'from' as src,\n fields->>'to' as dst,\n (fields->>'amount')::numeric as amount\n from chain_event\n where chain = $1\n and accounts && $2::text[]\n and ( (pallet = 'Wormhole' and variant = 'NativeTransferred')\n or (pallet = 'Balances' and variant = 'Transfer'))\n ),\n wanted as (select unnest($2::text[]) as account)\n select w.account as \"account!\",\n coalesce((select sum(amount) from moves where src = w.account), 0) as \"sent!\",\n coalesce((select sum(amount) from moves where dst = w.account), 0) as \"received!\",\n (select count(*) from moves where src = w.account) as \"sends!\",\n (select count(*) from moves where dst = w.account) as \"receipts!\",\n (select count(distinct dst) from moves where src = w.account) as \"recipients!\",\n (select count(distinct src) from moves where dst = w.account) as \"senders!\"\n from wanted w\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "account!",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "sent!",
"type_info": "Numeric"
},
{
"ordinal": 2,
"name": "received!",
"type_info": "Numeric"
},
{
"ordinal": 3,
"name": "sends!",
"type_info": "Int8"
},
{
"ordinal": 4,
"name": "receipts!",
"type_info": "Int8"
},
{
"ordinal": 5,
"name": "recipients!",
"type_info": "Int8"
},
{
"ordinal": 6,
"name": "senders!",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Text",
"TextArray"
]
},
"nullable": [
null,
null,
null,
null,
null,
null,
null
]
},
"hash": "717abd3ad62607561855d8fbe6c4f79ef31cf33677396ddd6f2ecc356ff7b045"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n select\n coalesce(sum((fields->>'amount')::numeric)\n filter (where fields->>'from' = $2), 0) as \"sent!\",\n coalesce(sum((fields->>'amount')::numeric)\n filter (where fields->>'to' = $2), 0) as \"received!\",\n count(*) filter (where fields->>'from' = $2) as \"sends!\",\n count(*) filter (where fields->>'to' = $2) as \"receipts!\",\n count(distinct fields->>'to')\n filter (where fields->>'from' = $2) as \"recipients!\",\n count(distinct fields->>'from')\n filter (where fields->>'to' = $2) as \"senders!\"\n from chain_event\n where chain = $1\n and accounts @> array[$2]\n and ( (pallet = 'Wormhole' and variant = 'NativeTransferred')\n or (pallet = 'Balances' and variant = 'Transfer'))\n ",
"query": "\n select\n coalesce(sum((fields->>'amount')::numeric)\n filter (where fields->>'from' = $2), 0) as \"sent!\",\n coalesce(sum((fields->>'amount')::numeric)\n filter (where fields->>'to' = $2), 0) as \"received!\",\n count(*) filter (where fields->>'from' = $2) as \"sends!\",\n count(*) filter (where fields->>'to' = $2) as \"receipts!\",\n count(distinct fields->>'to')\n filter (where fields->>'from' = $2) as \"recipients!\",\n count(distinct fields->>'from')\n filter (where fields->>'to' = $2) as \"senders!\"\n from chain_event\n where chain = $1\n and accounts @> array[$2]\n and ( (pallet = 'Wormhole' and variant = 'NativeTransferred')\n or (pallet = 'Balances' and variant = 'Transfer'\n -- the same transfer's other event: counted once (#42)\n and not exists (\n select 1 from chain_event twin\n where twin.chain = chain_event.chain\n and twin.height = chain_event.height\n and twin.extrinsic_index is not distinct from chain_event.extrinsic_index\n and twin.pallet = 'Wormhole' and twin.variant = 'NativeTransferred'\n and twin.fields->>'from' = chain_event.fields->>'from'\n and twin.fields->>'to' = chain_event.fields->>'to'\n and twin.fields->>'amount' = chain_event.fields->>'amount')))\n ",
"describe": {
"columns": [
{
@@ -49,5 +49,5 @@
null
]
},
"hash": "fbede02f645d92cce9e02673db479234db0bcb647411773c6416bb072267f35d"
"hash": "74634b489079a40bdf7bdac45a70baade8105b98a527720265f9c24bfccb581f"
}
@@ -1,6 +1,6 @@
{
"db_name": "PostgreSQL",
"query": "\n select\n coalesce(x.pallet || '::' || x.call, '') as \"produced_by!\",\n (e.fields->>'from' = $2) as \"sender_hidden!\",\n count(*) as \"transfers!\",\n count(distinct e.fields->>'to') as \"recipients!\",\n coalesce(sum((e.fields->>'amount')::numeric), 0) as \"amount!\"\n from chain_event e\n left join chain_extrinsic x\n on x.chain = e.chain\n and x.height = e.height\n and x.extrinsic_index = e.extrinsic_index\n where e.chain = $1\n and ( (e.pallet = 'Wormhole' and e.variant = 'NativeTransferred')\n or (e.pallet = 'Balances' and e.variant = 'Transfer'))\n group by 1, 2\n order by count(*) desc\n ",
"query": "\n select\n coalesce(x.pallet || '::' || x.call, '') as \"produced_by!\",\n (e.fields->>'from' = $2) as \"sender_hidden!\",\n count(*) as \"transfers!\",\n count(distinct e.fields->>'to') as \"recipients!\",\n coalesce(sum((e.fields->>'amount')::numeric), 0) as \"amount!\"\n from chain_event e\n left join chain_extrinsic x\n on x.chain = e.chain\n and x.height = e.height\n and x.extrinsic_index = e.extrinsic_index\n where e.chain = $1\n and ( (e.pallet = 'Wormhole' and e.variant = 'NativeTransferred')\n or (e.pallet = 'Balances' and e.variant = 'Transfer'\n -- the same transfer's other event: counted once (#42)\n and not exists (\n select 1 from chain_event twin\n where twin.chain = e.chain\n and twin.height = e.height\n and twin.extrinsic_index is not distinct from e.extrinsic_index\n and twin.pallet = 'Wormhole' and twin.variant = 'NativeTransferred'\n and twin.fields->>'from' = e.fields->>'from'\n and twin.fields->>'to' = e.fields->>'to'\n and twin.fields->>'amount' = e.fields->>'amount')))\n group by 1, 2\n order by count(*) desc\n ",
"describe": {
"columns": [
{
@@ -43,5 +43,5 @@
null
]
},
"hash": "6e5b0988898e0f185fa26915206b1946d73ea0908ada9212941a1e456dcb7567"
"hash": "ee4201fd3cc1ee671ca159ad37897f89dd46a8d958a1def09ae2d61438cb0e9e"
}
@@ -0,0 +1,59 @@
{
"db_name": "PostgreSQL",
"query": "\n with moves as (\n select fields->>'from' as src,\n fields->>'to' as dst,\n (fields->>'amount')::numeric as amount\n from chain_event\n where chain = $1\n and accounts && $2::text[]\n and ( (pallet = 'Wormhole' and variant = 'NativeTransferred')\n or (pallet = 'Balances' and variant = 'Transfer'\n -- the same transfer's other event: counted once (#42)\n and not exists (\n select 1 from chain_event twin\n where twin.chain = chain_event.chain\n and twin.height = chain_event.height\n and twin.extrinsic_index is not distinct from chain_event.extrinsic_index\n and twin.pallet = 'Wormhole' and twin.variant = 'NativeTransferred'\n and twin.fields->>'from' = chain_event.fields->>'from'\n and twin.fields->>'to' = chain_event.fields->>'to'\n and twin.fields->>'amount' = chain_event.fields->>'amount')))\n ),\n wanted as (select unnest($2::text[]) as account)\n select w.account as \"account!\",\n coalesce((select sum(amount) from moves where src = w.account), 0) as \"sent!\",\n coalesce((select sum(amount) from moves where dst = w.account), 0) as \"received!\",\n (select count(*) from moves where src = w.account) as \"sends!\",\n (select count(*) from moves where dst = w.account) as \"receipts!\",\n (select count(distinct dst) from moves where src = w.account) as \"recipients!\",\n (select count(distinct src) from moves where dst = w.account) as \"senders!\"\n from wanted w\n ",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "account!",
"type_info": "Text"
},
{
"ordinal": 1,
"name": "sent!",
"type_info": "Numeric"
},
{
"ordinal": 2,
"name": "received!",
"type_info": "Numeric"
},
{
"ordinal": 3,
"name": "sends!",
"type_info": "Int8"
},
{
"ordinal": 4,
"name": "receipts!",
"type_info": "Int8"
},
{
"ordinal": 5,
"name": "recipients!",
"type_info": "Int8"
},
{
"ordinal": 6,
"name": "senders!",
"type_info": "Int8"
}
],
"parameters": {
"Left": [
"Text",
"TextArray"
]
},
"nullable": [
null,
null,
null,
null,
null,
null,
null
]
},
"hash": "f0c7775b07654af481c7feedf2bfa185dc937f899ed914fcd4c788ab644de1ff"
}