Skip to content

Commit 5cc829e

Browse files
committed
draft for adr-010
1 parent 79c911c commit 5cc829e

File tree

2 files changed

+145
-11
lines changed

2 files changed

+145
-11
lines changed

docs/architecture/README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ To suggest an ADR, please make use of the [ADR template](./adr-template.md) prov
2525

2626
## Table of Contents
2727

28-
| ADR \# | Description | Status |
29-
|---------------------|----------------------------------------------------------------------------|----------|
30-
| [001](./adr-001.md) | Disable Gravity Bridge at Genesis | Accepted |
31-
| [002](./adr-002.md) | Use a custom fork of ibc-go | Accepted |
32-
| [003](./adr-003.md) | Add Fee Market Module | Accepted |
33-
| [004](./adr-004.md) | Tokens conversion in Cronos | Accepted |
34-
| [005](./adr-005.md) | Cross-chain Validation for Gravity Bridge | Rejected |
35-
| [006](./adr-006.md) | Migrating CRC20 contract to CRC21 standard | Rejected |
36-
| [007](./adr-007.md) | Generic event format for evm-hook actions | Accepted |
37-
| [008](./adr-008.md) | Denom and Contract Mapping Enhancement for Bi-Directional Token Conversion | Accepted |
38-
| [009](./adr-009.md) | Permissioned addresses in Cronos | Accepted |
28+
| ADR \# | Description | Status |
29+
|----------------------|----------------------------------------------------------------------------|----------|
30+
| [001](./adr-001.md) | Disable Gravity Bridge at Genesis | Accepted |
31+
| [002](./adr-002.md) | Use a custom fork of ibc-go | Accepted |
32+
| [003](./adr-003.md) | Add Fee Market Module | Accepted |
33+
| [004](./adr-004.md) | Tokens conversion in Cronos | Accepted |
34+
| [005](./adr-005.md) | Cross-chain Validation for Gravity Bridge | Rejected |
35+
| [006](./adr-006.md) | Migrating CRC20 contract to CRC21 standard | Rejected |
36+
| [007](./adr-007.md) | Generic event format for evm-hook actions | Accepted |
37+
| [008](./adr-008.md) | Denom and Contract Mapping Enhancement for Bi-Directional Token Conversion | Accepted |
38+
| [009](./adr-009.md) | Permissioned addresses in Cronos | Accepted |
39+
| [0010](./adr-010.md) | Precompiled for app-chain | Accepted |

docs/architecture/adr-010.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# ADR 01-: Precompiled for app-chain
2+
3+
## Changelog
4+
* 2023-10-02: first draft
5+
6+
## Context
7+
8+
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)
9+
as end-users are not able to access them through an ethereum transaction format. The solution is to provide precompile, allowing users to access to cosmos features through smart contract.
10+
A precompiled behave like smart contracts, it is designed by an addressed and can be invoked by other smart contracts. The difference is that its execution is not inside a smart contract.
11+
App-chain logic can be embedded to the pre-compiled so that it could be used to expose cosmos native feature to the EVM layer.
12+
13+
14+
## Decision
15+
16+
### Fork go-ethereum for stateful precompiled support
17+
18+
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.
19+
We made the choice of forking geth and implement additional interfaces and logic so that app-chain can define its own precompiled.
20+
21+
The PR [#7](https://github.com/evmos/go-ethereum/pull/7) implements the ability to set custom precompiled to the EVM.
22+
while this PR [#10](https://github.com/evmos/go-ethereum/pull/10) allows the precompiled to modify the state (for stateful precompiled)
23+
24+
### Implement pre-compiled for cosmos native module
25+
26+
We provide pre-compile for cosmos native module such as bank or staking.
27+
28+
The input and output of methods are mapped with those defined cosmos native transactions
29+
30+
```solidity
31+
32+
interface IBankModule {
33+
function mint(address,uint256) external payable returns (bool);
34+
function balanceOf(address,address) external view returns (uint256);
35+
function burn(address,uint256) external payable returns (bool);
36+
function transfer(address,address,uint256) external payable returns (bool);
37+
}
38+
39+
40+
41+
interface IStakingModule {
42+
# to be completed
43+
}
44+
```
45+
46+
To call a precompiled, create an instance of the module interface with the precompiled address.
47+
The methods are ABI encoded, and can be called directly as calling the function through the interface:
48+
49+
50+
```solidity
51+
52+
address constant bankContract = 0x0000000000000000000000000000000000000064;
53+
IBankModule bank = IBankModule(bankContract);
54+
bank.transfer(msg.sender, recipient, amount);
55+
56+
```
57+
58+
59+
### Implement pre-compiled for cosmos interchain communication
60+
61+
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.
62+
63+
For that reason we are exposing all relayer related actions to the evm layer. An action is defined by a 4 bytes prefix.
64+
65+
```go
66+
67+
const (
68+
prefixSize4Bytes = 4
69+
// Client
70+
prefixCreateClient = iota + 1
71+
prefixUpdateClient
72+
prefixUpgradeClient
73+
prefixSubmitMisbehaviour
74+
// Connection
75+
prefixConnectionOpenInit
76+
prefixConnectionOpenTry
77+
prefixConnectionOpenAck
78+
prefixConnectionOpenConfirm
79+
// Channel
80+
prefixChannelOpenInit
81+
prefixChannelOpenTry
82+
prefixChannelOpenAck
83+
prefixChannelOpenConfirm
84+
prefixChannelCloseInit
85+
prefixChannelCloseConfirm
86+
prefixRecvPacket
87+
prefixAcknowledgement
88+
prefixTimeout
89+
prefixTimeoutOnClose
90+
)
91+
92+
```
93+
94+
-> go relayer changes
95+
96+
For ICA, we are following the same standard as for the cosmos module
97+
98+
The ICA precompiled interface is defined by:
99+
100+
```solidity
101+
interface IICAModule {
102+
event SubmitMsgsResult(uint64 seq);
103+
function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool);
104+
function queryAccount(string calldata connectionID, address addr) external view returns (string memory);
105+
function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64);
106+
}
107+
```
108+
109+
In case of ICA, it is important to receives the result of the transaction `submitMsgs` for the user or the smart contract to respond accordingly.
110+
The function `submitMsgs` return a sequence number that can be used by the user or smart contract to track the state of the msg using the ICA callback precompiled.
111+
112+
113+
```solidity
114+
interface IICACallback {
115+
function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool);
116+
}
117+
118+
```
119+
120+
121+
### Precompiled gas cost
122+
123+
A precompiled acts as an op-code in the evm layer and has a constant cost. Because a stateful precompiled can change the state, it is much harder to define a specific cost for an action.
124+
To be fair, we are evaluating the cost of a pre-compile based on the past history and we are planning to tune the cost further in the future.
125+
126+
## Further discussions
127+
128+
129+
## References
130+
131+
* https://github.com/crypto-org-chain/cronos/pull/837
132+
* https://github.com/crypto-org-chain/cronos/pull/1163
133+
* https://github.com/crypto-org-chain/cronos/pull/1014

0 commit comments

Comments
 (0)