I already read this post XCM cross-chain transfer error FailedToTransactAsset("InsufficientBalance")? , but nothing helped.
I get the following XCM logs (originates from Parachain 2001):
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::origin_conversion: [Parachain] SovereignSignedViaLocation origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, kind: Superuser
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::origin_conversion: [Parachain] RelayChainAsNative origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, kind: Superuser
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::origin_conversion: [Parachain] SiblingParachainAsNative origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, kind: Superuser
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::origin_conversion: [Parachain] SignedAccountId32AsNative origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, kind: Superuser
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::convert_origin: [Parachain] could not convert: origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, kind: Superuser
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::weight: [Parachain] FixedWeightBounds message: Xcm([DescendOrigin(X1(AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] })), WithdrawAsset(MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }])), BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }, weight_limit: Unlimited }, LockAsset { asset: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000) }, unlocker: MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }])
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, message: Xcm([DescendOrigin(X1(AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] })), WithdrawAsset(MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }])), BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }, weight_limit: Unlimited }, LockAsset { asset: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000) }, unlocker: MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }]), weight_credit: <wasm:stripped>
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::barriers: [Parachain] TakeWeightCredit origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) }, instructions: [DescendOrigin(X1(AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] })), WithdrawAsset(MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }])), BuyExecution { fees: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }, weight_limit: Unlimited }, LockAsset { asset: MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000) }, unlocker: MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) } }], max_weight: <wasm:stripped>, properties: Properties { weight_credit: <wasm:stripped>, message_id: None }
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::process: [Parachain] origin: Some(MultiLocation { parents: 1, interior: X1(Parachain(2000)) }), total_surplus/refunded: <wasm:stripped>/<wasm:stripped>, error_handler_weight: <wasm:stripped>
2023-11-02 05:35:24.357 TRACE tokio-runtime-worker xcm::process_instruction: [Parachain] === DescendOrigin(X1(AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }))
2023-11-02 05:35:24.358 TRACE tokio-runtime-worker xcm::process_instruction: [Parachain] === WithdrawAsset(MultiAssets([MultiAsset { id: Concrete(MultiLocation { parents: 0, interior: X1(GeneralKey { length: 2, data: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }) }), fun: Fungible(10000000000000) }]))
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::execute: [Parachain] !!! ERROR: FailedToTransactAsset("InsufficientBalance")
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] result: Err(ExecutorError { index: 1, xcm_error: FailedToTransactAsset("InsufficientBalance"), weight: <wasm:stripped> })
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::weight: [Parachain] FixedRateOfFungible::refund_weight weight: <wasm:stripped>, context: XcmContext { origin: Some(MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }), message_id: [143, 158, 177, 103, 122, 233, 162, 35, 234, 11, 70, 43, 39, 79, 250, 6, 104, 7, 82, 112, 172, 195, 84, 137, 36, 29, 174, 18, 82, 246, 144, 80], topic: None }
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::weight: [Parachain] FixedRateOfFungible::refund_weight weight: <wasm:stripped>, context: XcmContext { origin: Some(MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }), message_id: [143, 158, 177, 103, 122, 233, 162, 35, 234, 11, 70, 43, 39, 79, 250, 6, 104, 7, 82, 112, 172, 195, 84, 137, 36, 29, 174, 18, 82, 246, 144, 80], topic: None }
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::weight: [Parachain] FixedRateOfFungible::refund_weight weight: <wasm:stripped>, context: XcmContext { origin: Some(MultiLocation { parents: 1, interior: X2(Parachain(2000), AccountId32 { network: None, id: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] }) }), message_id: [143, 158, 177, 103, 122, 233, 162, 35, 234, 11, 70, 43, 39, 79, 250, 6, 104, 7, 82, 112, 172, 195, 84, 137, 36, 29, 174, 18, 82, 246, 144, 80], topic: None }
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::weight: [Parachain] AssetRegistryTrader::refund_weight weight: <wasm:stripped>
2023-11-02 05:35:24.359 TRACE tokio-runtime-worker xcm::execute_xcm_in_credit: [Parachain] Execution errored at 1: FailedToTransactAsset("InsufficientBalance") (original_origin: MultiLocation { parents: 1, interior: X1(Parachain(2000)) })
My setup is the following:
- local rococo relaychain
- parachain 2000
- parachain 2001
I send the following encoded call data XCM message from parachain 2000 to parachain 2001 as the well-known Alice account as a normal signed origin:
0x490003010100451f030c000400000106020001000000000000000000000000000000000000000000000000000000000000000b00a0724e18091300000106020001000000000000000000000000000000000000000000000000000000000000000b00a0724e1809002700000106020001000000000000000000000000000000000000000000000000000000000000000700e40b5402010200411f0100d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
I funded the sovereign account of para id 2000 and 2001 and the sibling account of parachain id 2000 and 2001 on the rococo-local relaychain.
I am currently trying out the LockAsset
functionality and what I noticed is that the well known Alice account is different on the receiving chain after sending it through XCM. It is: [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125]
, which translates to 0x003593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da200
(using substrate utilities https://www.shawntabrizi.com/substrate-js-utilities/ represented as account id 5C4ymnPah145YenQ6EAUCrt6ZssKz15hVuLMGNVxNKhDtrP2
on para 2001). Although the Alice account has the account id 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
, which should be 0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d
in hex ([0,212,53,147,199,21,253,211,28,97,20,26,189,4,169,159,214,130,44,133,88,133,76,205,227,154,86,132,231,165,109,162,125]
u8 byte array).
So my inner question is: Which account has to be funded with how much of what curreny to fix the InsufficientBalance
error?
Side fact: I am using the following XCM configuration:
Here is the full version: https://pastebin.com/7242tXkA
pub const MY_KEY: &[u8] = &[0, 1];
pub const NoneNetwork: Option<NetworkId> = None;
...
pub fn vec_to_fixed_array<const S: usize>(src: Vec<u8>) -> [u8; S] {
let mut dest = [0; S];
let len = min(src.len(), S);
dest[..len].copy_from_slice(&src.as_slice()[..len]);
dest
}
pub fn general_key(data: &[u8]) -> Junction {
GeneralKey {
length: data.len().min(32) as u8,
data: vec_to_fixed_array(data.to_vec()),
}
}
...
/// Means for transacting assets on this chain.
pub type MultiAssetTransactor = MultiCurrencyAdapter<
// All known Assets will be processed by the following MultiCurrency implementation.
Currencies,
// Any unknown Assets will be processed by the following UnknownAsset implementation.
(),
// This means that this adapter should handle any token that `AssetConvert` can convert
// using Currencies and UnknownTokens in all other cases.
IsNativeConcrete<AssetId, AssetConvert>,
// Our chain's account ID type (we can't get away without mentioning it explicitly).
AccountId,
// Convert an XCM `MultiLocation` into a local account id.
LocationToAccountId,
// The AssetId that corresponds to the native currency.
AssetId,
// Struct that provides functions to convert `Asset` <=> `MultiLocation`.
AssetConvert,
// In case of deposit failure, known assets will be placed in treasury.
DepositToAlternative<RootAccount, Currencies, AssetId, AccountId, Balance>,
>;
...
/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
/// when determining ownership of accounts for asset transacting and when attempting to use XCM
/// `Transact` in order to determine the dispatch Origin.
pub type LocationToAccountId = (
// The parent (Relay-chain) origin converts to the default `AccountId`.
ParentIsPreset<AccountId>,
// Sibling parachain origins convert to AccountId via the `ParaId::into`.
SiblingParachainConvertsVia<polkadot_parachain_primitives::primitives::Sibling, AccountId>,
// If we receive a MultiLocation of type AccountKey20, just generate a native account
AccountId32Aliases<NoneNetwork, AccountId>,
// Generate remote accounts according to polkadot standards
staging_xcm_builder::HashedDescription<
AccountId,
staging_xcm_builder::DescribeFamily<staging_xcm_builder::DescribeAllTerminal>,
>,
);
...
/// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance,
/// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can
/// biases the kind of local `Origin` it will become.
pub type XcmOriginToTransactDispatchOrigin = (
// Sovereign account converter; this attempts to derive an `AccountId` from the origin location
// using `LocationToAccountId` and then turn that into the usual `Signed` origin. Useful for
// foreign chains who want to have a local sovereign account on this chain which they control.
SovereignSignedViaLocation<LocationToAccountId, RuntimeOrigin>,
// Native converter for Relay-chain (Parent) location; will convert to a `Relay` origin when
// recognised.
RelayChainAsNative<RelayChainOrigin, RuntimeOrigin>,
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
// recognised.
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
// Native signed account converter; this just converts an `AccountId32` origin into a normal
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
SignedAccountId32AsNative<NoneNetwork, RuntimeOrigin>,
// Xcm origins can be represented natively under the Xcm pallet's Xcm origin.
XcmPassthrough<RuntimeOrigin>,
);
...
/// Convert an incoming `MultiLocation` into a `Asset` if possible.
/// Here we need to know the canonical representation of all the tokens we handle in order to
/// correctly convert their `MultiLocation` representation into our internal `Asset` type.
impl Convert<MultiLocation, Option<AssetId>> for AssetConvert {
fn convert(location: MultiLocation) -> Option<AssetId> {
if location == MultiLocation::parent() {
return Some(1u32);
}
match location {
MultiLocation {
parents: 0,
interior: X1(GeneralKey { data, length }),
} => {
let key = &data[..data.len().min(length as usize)];
if key == MY_KEY {
return Some(0u32);
}
None
}
MultiLocation {
parents: 1,
interior: X2(Parachain(para_id), GeneralKey { data, length }),
} => {
let key = &data[..data.len().min(length as usize)];
if para_id == u32::from(ParachainInfo::parachain_id()) && key == MY_KEY {
return Some(0u32);
}
AssetRegistry::location_to_asset_id(location)
}
_ => AssetRegistry::location_to_asset_id(location),
}
}
}
0x76f80ba707bc6d37e0a1403c995b3cba9d424ed6ab87262b0e9a30d5dc5822c5
I am already figuring this out for 3 days.. It does not make any sense and I would really love some help now.
Thanks!