I'm encountering an issue where a contract is only able to called functions in my chain extension if they are enumerated with function ids 0 and 1.
My chain extension has four functions, lets say func1, func2, func3, and func4, with function ids enumerated as 1, 2, 3, 4 (1 -> func1, ..., 4 -> func4). Accordingly, in my contract I registered the chain extension with the appropriate function ids. With this configuration (see code below), I was only able to execute the function associated with function id 1, with function ids 2, 3, and 4 resulting in the contract being trapped when invoked from the contract. I have verified that the functions work and are callable by modifying the contract and extension and testing with func1 as func id = 1, func2 as func id = 1, and so on (i.e. when mapping 1 => funcN it works without getting trapped, but x > 1 => funcN does is always trapped).
The chain extension:
impl ChainExtension<Runtime> for IrisExtension {
fn call<E: Ext>(
func_id: u32,
env: Environment<E, InitState>,
) -> Result<RetVal, DispatchError>
where
<E::T as SysConfig>::AccountId:
UncheckedFrom<<E::T as SysConfig>::Hash> + AsRef<[u8]>,
{
match func_id {
1 => {
// read args and call extrinsic 1
Ok(RetVal::Converging(func_id))
},
2 => {
// read args and call extrinsic 2
Ok(RetVal::Converging(func_id))
},
3 => {
...
},
4 => {
...
},
_ => {
error!("Called an unregistered `func_id`: {:}", func_id);
return Err(DispatchError::Other("Unimplemented func_id"))
}
}
}
and in the contract:
#[ink(extension = 1, returns_result = false)]
fn func1(caller: ink_env::AccountId, target: ink_env::AccountId, asset_id: u32, amount: u64) -> [u8; 32];
#[ink(extension = 2, returns_result = false)]
fn func2(caller: ink_env::AccountId, target: ink_env::AccountId, asset_id: u32, amount: u64) -> [u8; 32];
#[ink(extension = 3, returns_result = false)]
fn func3(amount: u64) -> [u8; 32];
#[ink(extension = 4, returns_result = false)]
fn func4(target: ink_env::AccountId) -> [u8; 32];
}
Further, I updated the enumeration to start from 0, so 0, 1, 2, 3, and now I'm able to execute functions with func id 0 or 1, but 2 and 3 result in contract trapped (but if I update the configuration so those functions that results in contract trapped are enumerated with 0 and 1, they work, but the previously functioning functions which are now enumerated with 2 and 3 become trapped, i.e. (0 => funcN, 1 => funcM both work, but 2 => funcN results in COntractTrapped). I tried enumerating as 0, 1, 10, 100 as well, with the same behavior. Only func id 0 and 1 allow me to call the chain extension, all others result in ContractTrapped.
My contract: https://github.com/driemworks/contracts/blob/dev/iris_asset_exchange/lib.rs
My chain extension: https://github.com/driemworks/substrate/blob/4d001219e3c8ac41c15bd646d25e3b9caccc8e3b/bin/node-template/runtime/src/lib.rs#L847