Where
allways/chain_providers/subtensor.py:79-87 - SubtensorProvider.parse_raw_extrinsic
What's wrong
The signed-extrinsic body layout is:
byte 0 : version byte (top bit = signed)
byte 1 : MultiAddress variant (0x00 = Id)
bytes 2..34 : 32-byte AccountId
…
But the parser reads:
# Sender AccountId is at bytes 1..33
sender_bytes = body[1:33]
sender = ss58_encode(sender_bytes, ss58_format=42)
So it includes the variant byte at the start and drops the last byte of the real AccountId. The resulting SS58 string is well-formed but wrong.
The destination decoder right below (line 109-112) already does this correctly: it checks after_call[0] == 0x00 (the variant) and then takes after_call[1:33] (the AccountId).
Impact
This path is the fallback used when normal block decoding fails (pruned blocks, etc.). When it fires, verify_transaction(..., expected_sender=…) compares the real sender against this off-by-one parse and rejects a legitimate TAO transfer. Validator confirms then fall through as unverified.
Repro
Build a signed extrinsic body whose true sender is 5C4iA2und8WV6mbvTBYupm2eZwtxk3wCYUM2SFHXSyQuapGp, feed it to parse_raw_extrinsic, and observe a different SS58 string come back.
Where
allways/chain_providers/subtensor.py:79-87-SubtensorProvider.parse_raw_extrinsicWhat's wrong
The signed-extrinsic body layout is:
But the parser reads:
So it includes the variant byte at the start and drops the last byte of the real AccountId. The resulting SS58 string is well-formed but wrong.
The destination decoder right below (line 109-112) already does this correctly: it checks
after_call[0] == 0x00(the variant) and then takesafter_call[1:33](the AccountId).Impact
This path is the fallback used when normal block decoding fails (pruned blocks, etc.). When it fires,
verify_transaction(..., expected_sender=…)compares the real sender against this off-by-one parse and rejects a legitimate TAO transfer. Validator confirms then fall through as unverified.Repro
Build a signed extrinsic body whose true sender is
5C4iA2und8WV6mbvTBYupm2eZwtxk3wCYUM2SFHXSyQuapGp, feed it toparse_raw_extrinsic, and observe a different SS58 string come back.