From 29b27e36fcbc0743fecea87898e06270502335ae Mon Sep 17 00:00:00 2001 From: Thomas Nguy Date: Mon, 2 Oct 2023 18:02:38 +0900 Subject: [PATCH 1/4] draft for adr-010 --- docs/architecture/README.md | 23 +++--- docs/architecture/adr-010.md | 150 +++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 11 deletions(-) create mode 100644 docs/architecture/adr-010.md diff --git a/docs/architecture/README.md b/docs/architecture/README.md index f12322b321..eb8004837a 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -25,14 +25,15 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov ## Table of Contents -| ADR \# | Description | Status | -|---------------------|----------------------------------------------------------------------------|----------| -| [001](./adr-001.md) | Disable Gravity Bridge at Genesis | Accepted | -| [002](./adr-002.md) | Use a custom fork of ibc-go | Accepted | -| [003](./adr-003.md) | Add Fee Market Module | Accepted | -| [004](./adr-004.md) | Tokens conversion in Cronos | Accepted | -| [005](./adr-005.md) | Cross-chain Validation for Gravity Bridge | Rejected | -| [006](./adr-006.md) | Migrating CRC20 contract to CRC21 standard | Rejected | -| [007](./adr-007.md) | Generic event format for evm-hook actions | Accepted | -| [008](./adr-008.md) | Denom and Contract Mapping Enhancement for Bi-Directional Token Conversion | Accepted | -| [009](./adr-009.md) | Permissioned addresses in Cronos | Accepted | +| ADR \# | Description | Status | +|----------------------|----------------------------------------------------------------------------|----------| +| [001](./adr-001.md) | Disable Gravity Bridge at Genesis | Accepted | +| [002](./adr-002.md) | Use a custom fork of ibc-go | Accepted | +| [003](./adr-003.md) | Add Fee Market Module | Accepted | +| [004](./adr-004.md) | Tokens conversion in Cronos | Accepted | +| [005](./adr-005.md) | Cross-chain Validation for Gravity Bridge | Rejected | +| [006](./adr-006.md) | Migrating CRC20 contract to CRC21 standard | Rejected | +| [007](./adr-007.md) | Generic event format for evm-hook actions | Accepted | +| [008](./adr-008.md) | Denom and Contract Mapping Enhancement for Bi-Directional Token Conversion | Accepted | +| [009](./adr-009.md) | Permissioned addresses in Cronos | Accepted | +| [0010](./adr-010.md) | Custom precompiled for app-chain | Accepted | diff --git a/docs/architecture/adr-010.md b/docs/architecture/adr-010.md new file mode 100644 index 0000000000..f677503eff --- /dev/null +++ b/docs/architecture/adr-010.md @@ -0,0 +1,150 @@ +# ADR 010: Custom precompiled for app-chain + +## Changelog +* 2023-10-02: first draft + +## Context + +Cronos is an EVM-compatible built on Cosmos SDK. The "ethermint" module allows a full compatibility and interoperability with Ethereum. However, it comes with the sacrifice of cosmos native features or cosmos interchain features (IBC) +as end-users are not able to access them through an ethereum transaction. The solution is to provide precompile, allowing users to access to cosmos features through smart contracts. +A precompiled behave like a smart contract, it is designed by an address and can be invoked by other smart contracts. The difference is that its execution is not inside a smart contract. +App-chain specific logics can be embedded to the pre-compiled so that it could be used to expose cosmos native features at the EVM layer. + + +## Decision + +### Fork go-ethereum for stateful precompiled support + +One of the major difficulties in supporting pre-compiled is the lack of flexibility in geth for defining custom precompiled and its non-ability to modify the state. +We made the choice of forking geth and implement additional interfaces and logics so that app-chain can define its own precompiled. + +The PR [#7](https://github.com/evmos/go-ethereum/pull/7) implements the ability to set custom precompiled to the EVM. +while this PR [#10](https://github.com/evmos/go-ethereum/pull/10) allows the precompiled to modify the state (for stateful precompiled) + +In the future, we are planning to maintain the following fork permanently +`github.com/evmos/go-ethereum` + +### Implement pre-compiled for cosmos native module + +We provide pre-compile for cosmos native module such as bank or staking. + +The input and output of methods are mapped with those defined cosmos native transactions + +```solidity + +interface IBankModule { + function mint(address,uint256) external payable returns (bool); + function balanceOf(address,address) external view returns (uint256); + function burn(address,uint256) external payable returns (bool); + function transfer(address,address,uint256) external payable returns (bool); +} + + + +interface IStakingModule { + # to be completed +} +``` + +To call a precompiled, create an instance of the module interface with the precompiled address. +The methods are ABI encoded, and can be called directly as calling the function through the interface: + + +```solidity + +address constant bankContract = 0x0000000000000000000000000000000000000064; +IBankModule bank = IBankModule(bankContract); +bank.transfer(msg.sender, recipient, amount); + +``` + + +### Implement pre-compiled for cosmos interchain communication + +#### Relayer +One of the benefits of supporting precompiled for IBC is that it would be possible to track the change of state triggered by the ibc transaction with ethereum receipts. + +For that reason we are exposing all relayer related actions to the evm layer. An action is defined by a 4 bytes prefix. + +```go + +const ( + prefixSize4Bytes = 4 + // Client + prefixCreateClient = iota + 1 + prefixUpdateClient + prefixUpgradeClient + prefixSubmitMisbehaviour + // Connection + prefixConnectionOpenInit + prefixConnectionOpenTry + prefixConnectionOpenAck + prefixConnectionOpenConfirm + // Channel + prefixChannelOpenInit + prefixChannelOpenTry + prefixChannelOpenAck + prefixChannelOpenConfirm + prefixChannelCloseInit + prefixChannelCloseConfirm + prefixRecvPacket + prefixAcknowledgement + prefixTimeout + prefixTimeoutOnClose +) + +``` + +-> TODO describe the change in go-relayer + +#### ICA +For ICA, we are following the same standard as for the cosmos module. +The ICA precompiled interface is defined by: + +```solidity +interface IICAModule { + event SubmitMsgsResult(uint64 seq); + function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); + function queryAccount(string calldata connectionID, address addr) external view returns (string memory); + function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); +} +``` + +The calldata in `submitMsgs` represents the cosmos proto-encoded msg to be sent to the destination app-chain. Only one msg is supported at the moment. + +For example to call a bank transaction to another app-chain + +```solidity +#todo +``` + + +In case of ICA, it is also important to be able to track the result of the transaction `submitMsgs` so that the user or the smart contract can respond accordingly. +The function `submitMsgs` returns a sequence number that can be used by the user or smart contract to track the state of the msg using the precompiled `ICACallback`. + + +```solidity +interface IICACallback { + function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool); +} + +``` + + +### Precompiled gas cost + +A precompiled is basically an op-code at the evm layer thus, it has a constant cost. Because a stateful precompiled can change the state, it is much harder to define a specific cost. +To be fair, we are evaluating the cost of a pre-compile based on the average cost of the cosmos transaction in the past history. +Future work aim to provide a more accurate cost on the pre-compiled + +## Further discussions + +- Disabling cosmos native modules in cronos +- Establishing a standard for ibc for evm based chain (relayer) +- Extending the usage of pre-compile for broader use cases + +## References + +* https://github.com/crypto-org-chain/cronos/pull/837 +* https://github.com/crypto-org-chain/cronos/pull/1163 +* https://github.com/crypto-org-chain/cronos/pull/1014 \ No newline at end of file From 300fac3587e2569c8b4a9af7cc5dc4e1c1c0516a Mon Sep 17 00:00:00 2001 From: Thomas Nguy Date: Tue, 3 Oct 2023 10:20:23 +0900 Subject: [PATCH 2/4] remove staking --- docs/architecture/adr-010.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/architecture/adr-010.md b/docs/architecture/adr-010.md index f677503eff..49ef38d7cf 100644 --- a/docs/architecture/adr-010.md +++ b/docs/architecture/adr-010.md @@ -26,7 +26,7 @@ In the future, we are planning to maintain the following fork permanently ### Implement pre-compiled for cosmos native module -We provide pre-compile for cosmos native module such as bank or staking. +We provide pre-compile for cosmos native module such as bank module. The input and output of methods are mapped with those defined cosmos native transactions @@ -40,10 +40,6 @@ interface IBankModule { } - -interface IStakingModule { - # to be completed -} ``` To call a precompiled, create an instance of the module interface with the precompiled address. From 47daa4e8cc2a2b0409682425a0a2f15340d3e4cc Mon Sep 17 00:00:00 2001 From: Thomas Nguy Date: Tue, 3 Oct 2023 14:43:07 +0900 Subject: [PATCH 3/4] add authentication details --- docs/architecture/adr-010.md | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/architecture/adr-010.md b/docs/architecture/adr-010.md index 49ef38d7cf..678d3d01e8 100644 --- a/docs/architecture/adr-010.md +++ b/docs/architecture/adr-010.md @@ -16,7 +16,7 @@ App-chain specific logics can be embedded to the pre-compiled so that it could b ### Fork go-ethereum for stateful precompiled support One of the major difficulties in supporting pre-compiled is the lack of flexibility in geth for defining custom precompiled and its non-ability to modify the state. -We made the choice of forking geth and implement additional interfaces and logics so that app-chain can define its own precompiled. +We made the choice of forking geth and implement additional interfaces so that app-chain can define its own precompiled. The PR [#7](https://github.com/evmos/go-ethereum/pull/7) implements the ability to set custom precompiled to the EVM. while this PR [#10](https://github.com/evmos/go-ethereum/pull/10) allows the precompiled to modify the state (for stateful precompiled) @@ -26,9 +26,7 @@ In the future, we are planning to maintain the following fork permanently ### Implement pre-compiled for cosmos native module -We provide pre-compile for cosmos native module such as bank module. - -The input and output of methods are mapped with those defined cosmos native transactions +We provide pre-compiles for cosmos native module such as bank module. ```solidity @@ -41,10 +39,14 @@ interface IBankModule { ``` +The input and output of methods are mapped with those defined cosmos native transactions. +Because the precompiled is called at the evm layer, it uses the evm authentication instead of the cosmos authentication for transactions. +It is important to define for each precompiled module the range of action "authorized" for each request. +For the bank module, the precompiled is authenticated with `msg.sender` address. The smart contracts or users can only mint/burn cosmos coins denoted by the denom `evm/0x{msg.sender}` or transfer coins from the `0x{msg.sender}` account. -To call a precompiled, create an instance of the module interface with the precompiled address. -The methods are ABI encoded, and can be called directly as calling the function through the interface: +To call a precompiled from a smart contract, create an instance of the module interface with the precompiled address. +The methods are ABI encoded, and can be called directly as calling the function through the interface: ```solidity @@ -94,26 +96,33 @@ const ( -> TODO describe the change in go-relayer #### ICA -For ICA, we are following the same standard as for the cosmos module. -The ICA precompiled interface is defined by: + +The ICA precompiled interface is defined by : ```solidity interface IICAModule { event SubmitMsgsResult(uint64 seq); + function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool); function queryAccount(string calldata connectionID, address addr) external view returns (string memory); function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64); } ``` +The request is authenticated by `msg.sender` and it can only send request on behalf of this account. -The calldata in `submitMsgs` represents the cosmos proto-encoded msg to be sent to the destination app-chain. Only one msg is supported at the moment. +The calldata in `submitMsgs` represents the cosmos proto-encoded message to be sent to the destination app-chain. Only one message can be sent at the moment. -For example to call a bank transaction to another app-chain +For example to call a bank transaction to another app-chain : ```solidity -#todo -``` + function ICACallBank(string memory connectionID, uint256 timeout, params.....) public returns (uint64) { + msg = bankMsgSendProto.encode(params) + lastSeq = ica.submitMsgs(connectionID, msg, timeout); + return lastSeq; + } + +``` In case of ICA, it is also important to be able to track the result of the transaction `submitMsgs` so that the user or the smart contract can respond accordingly. The function `submitMsgs` returns a sequence number that can be used by the user or smart contract to track the state of the msg using the precompiled `ICACallback`. From 0e1f1d598dbcdc7c0fa93e721b5799b77f062c5c Mon Sep 17 00:00:00 2001 From: Thomas Nguy Date: Tue, 3 Oct 2023 14:48:28 +0900 Subject: [PATCH 4/4] remove dead link --- docs/architecture/adr-008.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/architecture/adr-008.md b/docs/architecture/adr-008.md index 73bd1a78a6..05b4b11e22 100644 --- a/docs/architecture/adr-008.md +++ b/docs/architecture/adr-008.md @@ -169,6 +169,3 @@ Accepted - Multi-sourced token is not supported. This is a deliberate design decision to avoid complicated supply management logic. ## References - -### x/erc20 module -- https://github.com/evmos/evmos/tree/main/x/erc20/spec