use-ink/ink-examples

Multisig example - invoke_transaction/eval_transaction does not work when calling Multisig functions

haydenyoung opened this issue · 1 comments

I have implemented the Multisig wallet and have successfully created an e2e test to check the functionality.

My e2e flow:

  • Deploy the multisig with a requirement = 2
  • submit_transaction where Multisig's change_requirement is the function being called with a new requirement of 1,
  • confirm_transaction
  • invoke_transaction
  • read the requirements value (is still 2 not the new value 1)

invoke_transaction does not error but requirement does not update either.

eval_transaction errors with:

Calling `eval_transaction` failed: CallExtrinsic(Module(ModuleError(<Contracts::ContractReverted>)))

This problem only occurs when calling functions on Multisig. Calling functions on external contracts works.

Further to the above post, I was able to get the invoke_tx function to work on fn calls on multisig by setting the CallFlags::TAIL_CALL call flag.

I'm not entirely sure why this works but according to the Ink documentation:

it is advised to use &self receiver with a mutating delegate call, or .set_tail_call(true) to flag that any changes made by delegate call should be flushed into storage.

I don't understand what "&self receiver with a mutating delegate call means" but, if set_tail_call forces the storage to update on the delegate call (i.e. the inner call being invoked by invoke_tx), it would make sense why this solves the problem.

I can't think why an external fn would update storage but a call back into multisig would not (without set_tail_call). Is it because storage doesn't update on the multisig until invoke_tx completes, and, because the delegate call falls out of scope, its changes aren't stored?