archway-network / archway

Archway Network
https://archway.io
Other
73 stars 99 forks source link

AIP: x/errors module #544

Closed zanicar closed 6 months ago

zanicar commented 7 months ago

Discussed in https://github.com/orgs/archway-network/discussions/35

Originally posted by **spoo-bar** February 22, 2024 ## Abstract With custom modules like x/callback, x/cwfees and x/custodian, Archway has a big enough surface area where the protocol calls a smart contract. In case of any error, we need a way for the contract to learn that an error has occurred and to act on it, if it wishes. We propose the x/errors module which would be the error handling mechanism for the protocol to let the contract know of errors encountered. ## Background The following custom Archway modules invoke a contract execution at various times. In case, the execution call failed, currently there is no way to share this information with the contract or the og user. x/callback - On error in callback execution, whether due to out-of-gas error or contract logic error, the only way the error is shared is via on-chain events. This would require an event monitoring system from the contract devs and is an off-chain way to notify error. x/custodian - In case of IBC interactions, there are multiple ways an error can arise. Sending a tx with a msg which is invalid on the counterparty chain, packet timeout, msg processing logic error. Currently, there are multiple sudo endpoints exposed by the module to address these situations. The error endpoints are called when the relayer submits the packet and it ends up being the relayer who pays for the sudo execution. For a contract relying on all these modules, the number of Sudo endpoints to support would be six in total. With the growth of protocol features over time, this might increase further. With error handling for every feature handled in a different way, it makes dapp dev more complex. ## Proposal We propose a new module x/errors which will be the error handling mechanism for the above mentioned modules. In case of any error from the x/callback or x/custodian, the errors will be forwarded to x/errors module where it can be shared with the contract. ```protobuf message Error { // module_name is the module which encountered this error string module_name = 1; // error_code is any module specified error code which will help distinguish the error type string error_code = 2; // contract_address is the address of the contract which caused the error string contract_address = 3; // payload is the relevant payload input which lead to the error string payload = 4; // error_message is the actual error which needs to be shared with the contract. // NOTE: This could be a json value. Where based on `error_code` the contract will know how to deserialize. Could involve details like block height, gas used or ibc packet seq id string error_message = 5; } ``` There are two ways the errors can now be handled. 1. **Pull Mechanism** Store the error on-chain for `x` number of blocks. Allow a stargate query where the contract can fetch any errors relevant to it during that time. After the time has passed, the errors are purged from the state to not cause state bloat. 2. **Push Mechanism** This would involve creating another sudo endpoint, where as soon as an error is encountered, it is stored for the duration of the block. At the end of the block, the contract Sudo endpoint would be hit with the error details. ```rust pub enum SudoMsg { Error { module_name: String, error_code: String, payload: String, error_message: String } } ``` This does involve more complexity, so this invocation would have to be kept simple. Such as, very conservative gas limit for the invocation of this endpoint. Any error from this Sudo execution would be ignored, to not perpetuate an error cycle. 👉🏻 **Bit of both approach** Having the pull mechanism as the default allows us to use the push mechanism more explicitly. A contract can choose to sign up for the push mechanism of error handling, This could further be monetized as a subscription or pay-per-use if needed. ## Consequences ### Backwards Compatibility This depends on the release of the dependent modules. If x/errors is to be released in a separate release, it would break backwards compatibility as the error handling for the x/custodian module has already been implemented in a different way. ### Positive - Future proofing against the growing codebase and having a dedicated error handling mechanism for sudo calls. - Gives easier and higher control to the dapp devs on their usage of custom archway features by simplifying the archway-cw-sdk - Potential source of protocol revenue ### Negative - Introduces a layer of complexity to the protocol architecture - Would need to delay the current release timeline ## Future ideas Other potential features which could be part of the module in the future: ### Group subscription Subscribe to errors from other contracts E.g a dapp/multisig consists of many contracts working together. One contract can chose to receive errors about all its dependent contracts in one place ### Custom error subscription Customize which error codes a contract wants a sudo call for, and which error codes its fine reading via stargate query. E.g 1. a ica tx fail, the contract might wanna know immediately with a sudo call, but if its a cron job contract, it might not care much about x/callback fail as it will get called back again soon E.g 2. A contract might want a custom error mechanism where it wants sudo call only if there are > n error in x blocks. etc