debug: trace isPezkuwi detection and CheckMortality encoding failure

Real on-device failure while approving a multisig operation on Polkadot Asset
Hub: 'Failed to encode extension CheckMortality'. isPezkuwi is detected via
signedExtensions.any { it.id == "AuthorizeCall" } - confirmed via direct
metadata inspection that AuthorizeCall exists on BOTH Polkadot Asset Hub and
Pezkuwi Asset Hub (both on Metadata V16), so this heuristic can't actually
distinguish the two chains. Need to confirm what isPezkuwi evaluates to at
the moment of the real failure, and exactly where the throw happens
(setTransactionExtension vs buildExtrinsic), before proposing a fix.
This commit is contained in:
2026-07-18 17:23:36 -07:00
parent b700637d3d
commit 3f6e6441c6
@@ -143,17 +143,29 @@ internal class RealExtrinsicSplitter @Inject constructor(
val genesisHash = chain.requireGenesisHash().fromHex()
val isPezkuwi = runtime.metadata.extrinsic.signedExtensions.any { it.id == "AuthorizeCall" }
android.util.Log.e(
"ExtrinsicDebug",
"wrapInFakeExtrinsic: chain=${chain.name} isPezkuwi=$isPezkuwi " +
"signedExtensionIds=${runtime.metadata.extrinsic.signedExtensions.map { it.id }}"
)
return ExtrinsicBuilder(
val builder = ExtrinsicBuilder(
runtime = runtime,
extrinsicVersion = ExtrinsicVersion.V4,
batchMode = BatchMode.BATCH,
).apply {
// Use custom CheckMortality for Pezkuwi chains to avoid DictEnum type lookup issues
if (isPezkuwi) {
android.util.Log.e("ExtrinsicDebug", "using PezkuwiCheckImmortal")
setTransactionExtension(PezkuwiCheckImmortal(genesisHash))
} else {
setTransactionExtension(CheckMortality(Era.Immortal, genesisHash))
android.util.Log.e("ExtrinsicDebug", "using standard CheckMortality(Era.Immortal)")
runCatching {
setTransactionExtension(CheckMortality(Era.Immortal, genesisHash))
}.onFailure { e ->
android.util.Log.e("ExtrinsicDebug", "standard CheckMortality setTransactionExtension threw", e)
throw e
}
}
setTransactionExtension(CheckGenesis(chain.requireGenesisHash().fromHex()))
setTransactionExtension(ChargeTransactionPayment(BigInteger.ZERO))
@@ -167,6 +179,10 @@ internal class RealExtrinsicSplitter @Inject constructor(
val signingContext = signingContextFactory.default(chain)
signer.setSignerDataForFee(signingContext)
}.buildExtrinsic()
}
return runCatching { builder.buildExtrinsic() }
.onFailure { e -> android.util.Log.e("ExtrinsicDebug", "buildExtrinsic threw", e) }
.getOrThrow()
}
}