Skip to content

Commit 9d26c3a

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

File tree

2 files changed

+150
-11
lines changed

2 files changed

+150
-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: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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+
In the future, we are planning to maintain the following fork permanently
25+
`github.com/evmos/go-ethereum`
26+
27+
### Implement pre-compiled for cosmos native module
28+
29+
We provide pre-compile for cosmos native module such as bank or staking.
30+
31+
The input and output of methods are mapped with those defined cosmos native transactions
32+
33+
```solidity
34+
35+
interface IBankModule {
36+
function mint(address,uint256) external payable returns (bool);
37+
function balanceOf(address,address) external view returns (uint256);
38+
function burn(address,uint256) external payable returns (bool);
39+
function transfer(address,address,uint256) external payable returns (bool);
40+
}
41+
42+
43+
44+
interface IStakingModule {
45+
# to be completed
46+
}
47+
```
48+
49+
To call a precompiled, create an instance of the module interface with the precompiled address.
50+
The methods are ABI encoded, and can be called directly as calling the function through the interface:
51+
52+
53+
```solidity
54+
55+
address constant bankContract = 0x0000000000000000000000000000000000000064;
56+
IBankModule bank = IBankModule(bankContract);
57+
bank.transfer(msg.sender, recipient, amount);
58+
59+
```
60+
61+
62+
### Implement pre-compiled for cosmos interchain communication
63+
64+
#### Relayer
65+
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.
66+
67+
For that reason we are exposing all relayer related actions to the evm layer. An action is defined by a 4 bytes prefix.
68+
69+
```go
70+
71+
const (
72+
prefixSize4Bytes = 4
73+
// Client
74+
prefixCreateClient = iota + 1
75+
prefixUpdateClient
76+
prefixUpgradeClient
77+
prefixSubmitMisbehaviour
78+
// Connection
79+
prefixConnectionOpenInit
80+
prefixConnectionOpenTry
81+
prefixConnectionOpenAck
82+
prefixConnectionOpenConfirm
83+
// Channel
84+
prefixChannelOpenInit
85+
prefixChannelOpenTry
86+
prefixChannelOpenAck
87+
prefixChannelOpenConfirm
88+
prefixChannelCloseInit
89+
prefixChannelCloseConfirm
90+
prefixRecvPacket
91+
prefixAcknowledgement
92+
prefixTimeout
93+
prefixTimeoutOnClose
94+
)
95+
96+
```
97+
98+
-> TODO describe the change in go-relayer
99+
100+
#### ICA
101+
For ICA, we are following the same standard as for the cosmos module.
102+
The ICA precompiled interface is defined by:
103+
104+
```solidity
105+
interface IICAModule {
106+
event SubmitMsgsResult(uint64 seq);
107+
function registerAccount(string calldata connectionID, string calldata version) external payable returns (bool);
108+
function queryAccount(string calldata connectionID, address addr) external view returns (string memory);
109+
function submitMsgs(string calldata connectionID, bytes calldata data, uint256 timeout) external payable returns (uint64);
110+
}
111+
```
112+
113+
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.
114+
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`.
115+
116+
117+
```solidity
118+
interface IICACallback {
119+
function onPacketResultCallback(uint64 seq, bool ack) external payable returns (bool);
120+
}
121+
122+
```
123+
124+
125+
### Precompiled gas cost
126+
127+
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.
128+
To be fair, we are evaluating the cost of a pre-compile based on the past history.
129+
We are planning to tune the costs further in the future.
130+
131+
## Further discussions
132+
133+
134+
## References
135+
136+
* https://github.com/crypto-org-chain/cronos/pull/837
137+
* https://github.com/crypto-org-chain/cronos/pull/1163
138+
* https://github.com/crypto-org-chain/cronos/pull/1014

0 commit comments

Comments
 (0)