Skip to content

Commit a4e2523

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

File tree

2 files changed

+147
-11
lines changed

2 files changed

+147
-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) | Custom precompiled for app-chain | Accepted |

docs/architecture/adr-010.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# ADR 010: Custom 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 contracts.
10+
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.
11+
App-chain specific logics can be embedded to the pre-compiled so that it could be used to expose cosmos native features 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 logics 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+
#### Relayer
62+
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.
63+
64+
For that reason we are exposing all relayer related actions to the evm layer. An action is defined by a 4 bytes prefix.
65+
66+
```go
67+
68+
const (
69+
prefixSize4Bytes = 4
70+
// Client
71+
prefixCreateClient = iota + 1
72+
prefixUpdateClient
73+
prefixUpgradeClient
74+
prefixSubmitMisbehaviour
75+
// Connection
76+
prefixConnectionOpenInit
77+
prefixConnectionOpenTry
78+
prefixConnectionOpenAck
79+
prefixConnectionOpenConfirm
80+
// Channel
81+
prefixChannelOpenInit
82+
prefixChannelOpenTry
83+
prefixChannelOpenAck
84+
prefixChannelOpenConfirm
85+
prefixChannelCloseInit
86+
prefixChannelCloseConfirm
87+
prefixRecvPacket
88+
prefixAcknowledgement
89+
prefixTimeout
90+
prefixTimeoutOnClose
91+
)
92+
93+
```
94+
95+
-> TODO describe the change in go-relayer
96+
97+
#### ICA
98+
For ICA, we are following the same standard as for the cosmos module.
99+
The ICA precompiled interface is defined by:
100+
101+
```solidity
102+
interface IICAModule {
103+
event SubmitMsgsResult(uint64 seq);
104+
function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool);
105+
function queryAccount(string calldata connectionID, address addr) external view returns (string memory);
106+
function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64);
107+
}
108+
```
109+
110+
In case of ICA, it is important to be able to track the result of the transaction `submitMsgs` so that the user or the smart contract can respond accordingly.
111+
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`.
112+
113+
114+
```solidity
115+
interface IICACallback {
116+
function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool);
117+
}
118+
119+
```
120+
121+
122+
### Precompiled gas cost
123+
124+
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 it.
125+
To be fair, we are evaluating the cost of a pre-compile based on the past history.
126+
We are planning to tune the costs further in the future.
127+
128+
## Further discussions
129+
130+
131+
## References
132+
133+
* https://github.com/crypto-org-chain/cronos/pull/837
134+
* https://github.com/crypto-org-chain/cronos/pull/1163
135+
* https://github.com/crypto-org-chain/cronos/pull/1014

0 commit comments

Comments
 (0)