-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ICS 027: Interchain account #278
ICS 027: Interchain account #278
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had the first iteration on the specification, thanks for proposing the interchain accounts. Comments are mostly on the chain-specific parts. Multimsg transaction is also Cosmos specific concept, will look into that and review.
// because attackers can distrupt to create an ibc managed account | ||
// by sending some assets to estimated address in advance. | ||
// And IBC managed account has no public key, but its sequence is 1. | ||
// It can be mark for Interchain account, becuase normal account can't be sequence 1 without publish public key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This assumption seems a bit Cosmos specific. Can we change address = sha256(path + packet.salt)
to arbitrary address generation logic, so the receiving chain can generate a non-conflicting address? In Cosmos, the receiving chain can generate a new address with that hashing logic, with different bech32 prefix, and returns it, and in other chains, for example in Ethereum, the receiving chain can generate a new contract that works as a proxy for the origin chain and returns its address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, we should avoid Cosmos SDK specific assumptions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. So, is it better to change the determining address login to function interface? For example, make function typetype CreateAddress = funtion(packet:Packet):Uint8Array
and use it for determining address. But, I think there is no need to consider bech32, because the address is just byte address and we can interact by byte address in the codebase.
// It can be mark for Interchain account, becuase normal account can't be sequence 1 without publish public key. | ||
account = accountKeeper.getAccount(account) | ||
if (account != null) { | ||
abortTransactionUnless(account.sequence === 1 && account.pubKey == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sequence
an pubkey
field of the account is Cosmos specific
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that sequence (or nonce) and a public key are very general in the blockchain. So, I think using sequence and public key is not Cosmos specific. But, in the above discussion, I agree it is better to make account keeper and account as the interface so, I think, it is good to define the account interface that has the sequence (or nonce) and public key and use those variables from the interface.
addressesRegisteredChannel[signer] = path | ||
|
||
// set account's sequence to 1 | ||
accountKeeper.setAccount(address, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also accountKeeper
seems Cosmos specific
// by sending some assets to estimated address in advance. | ||
// And IBC managed account has no public key, but its sequence is 1. | ||
// It can be mark for Interchain account, becuase normal account can't be sequence 1 without publish public key. | ||
account = accountKeeper.getAccount(account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also accountKeeper
seems Cosmos specific. As an alternative you declare an interface named accountKeeper
with a set of functions with some constraints(which will be inspired from Cosmos' accountKeeper
design, but works chain agnostic)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is where I would like to see a runTx
function.
..., | ||
}) | ||
|
||
// Return acknowledgement byte as 0x0 if account creation succeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the address generation works arbitrary(as commented above) the return ack should include generated address
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
function onAcknowledgePacket( | ||
packet: Packet, | ||
acknowledgement: bytes) { | ||
// Receiving chain should handle this event as if the tx in packet has failed if ack bytes is not 0x0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the address generation works arbitrary(as commented above) the ack receiving should store the controlling interchain accounts(or send the address information to the requested entity for the account generation)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm trying to define interface for the host chain to handle counterparty chain's interchain account.
} | ||
|
||
// Get handler from router | ||
handler = router(msg.route()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
router
and type msg
should be defined somewhere, however I am in favor of using router/handler here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I think this is too Cosmos SDK specific. I think we should abstract what it means to "run a transaction", at least so that the Cosmos SDK specific bits can be an example implementation of the runTx
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I will try to abstract running tx and account keeper as interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK, a lot of the pseudocode is too SDK-specific I think, we should abstract it a bit more.
Do you think interchain multisignature accounts are out of scope of this specification or not?
### **Desired Properties** | ||
|
||
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its dwelling chain, even in times of byzantine behavior by the counterparty chain (the chain that manages the account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Swap "dwelling" for "host"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
|
||
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its dwelling chain, even in times of byzantine behavior by the counterparty chain (the chain that manages the account) | ||
- The chain(that controls the account) requesting a specific transaction from must process the results asynchronously and according to the chain's logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
requesting a specific transaction from where or what?
} | ||
``` | ||
|
||
`RunTxPacketData` is used to run tx for interchain account. Tx bytes is dependent on app, and it is formed with minimal data set except data for validating signatures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean without the signatures, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I think that application logic can know what chain requests transaction and whether that chain has the right permission. So, there is no need to include a signature to the interchain account.
type Path = string | ||
|
||
interface ModuleState { | ||
addressesRegisteredChannel: Map<string, Path> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should Address
be a declared type (instead of a string)?
} | ||
``` | ||
```typescript | ||
function onSendPacket(packet: Packet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function no longer exists, see the latest version of ICS 20.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will recheck.
|
||
## **Backwards Compatibility** | ||
|
||
(discussion of compatibility or lack thereof with previous standards) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is nothing here, just put N/A
.
|
||
## **Forwards Compatibility** | ||
|
||
(discussion of compatibility or lack thereof with expected future standards) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is nothing here, just put N/A
.
|
||
## **Example Implementation** | ||
|
||
(link to or description of concrete example implementation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is nothing here, just put N/A
.
|
||
## **Other Implementations** | ||
|
||
(links to or descriptions of other implementations) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is nothing here, just put N/A
.
|
||
## **History** | ||
|
||
(changelog and notable inspirations / references) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put a date and the first draft version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what the interchain multisignature accounts mean. But, I guess it means that the interchain multisignature accounts are handled by multiple chains. It will be interesting feature, however, I don't know how it can be used in a real environment. I think it is better to discuss that feature in post-launch.
### **Desired Properties** | ||
|
||
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its dwelling chain, even in times of byzantine behavior by the counterparty chain (the chain that manages the account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
} | ||
``` | ||
|
||
`RunTxPacketData` is used to run tx for interchain account. Tx bytes is dependent on app, and it is formed with minimal data set except data for validating signatures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right. I think that application logic can know what chain requests transaction and whether that chain has the right permission. So, there is no need to include a signature to the interchain account.
} | ||
``` | ||
```typescript | ||
function onSendPacket(packet: Packet) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will recheck.
if (packet.data is RunTxPacketData) { | ||
ChainAccountTx data = {} | ||
// Decode transaction request | ||
codec.unmarshal(packet.data.txBytes, &data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok
// because attackers can distrupt to create an ibc managed account | ||
// by sending some assets to estimated address in advance. | ||
// And IBC managed account has no public key, but its sequence is 1. | ||
// It can be mark for Interchain account, becuase normal account can't be sequence 1 without publish public key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. So, is it better to change the determining address login to function interface? For example, make function typetype CreateAddress = funtion(packet:Packet):Uint8Array
and use it for determining address. But, I think there is no need to consider bech32, because the address is just byte address and we can interact by byte address in the codebase.
// It can be mark for Interchain account, becuase normal account can't be sequence 1 without publish public key. | ||
account = accountKeeper.getAccount(account) | ||
if (account != null) { | ||
abortTransactionUnless(account.sequence === 1 && account.pubKey == null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that sequence (or nonce) and a public key are very general in the blockchain. So, I think using sequence and public key is not Cosmos specific. But, in the above discussion, I agree it is better to make account keeper and account as the interface so, I think, it is good to define the account interface that has the sequence (or nonce) and public key and use those variables from the interface.
} | ||
|
||
// Get handler from router | ||
handler = router(msg.route()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I will try to abstract running tx and account keeper as interface.
..., | ||
}) | ||
|
||
// Return acknowledgement byte as 0x0 if account creation succeeds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
function onAcknowledgePacket( | ||
packet: Packet, | ||
acknowledgement: bytes) { | ||
// Receiving chain should handle this event as if the tx in packet has failed if ack bytes is not 0x0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm trying to define interface for the host chain to handle counterparty chain's interchain account.
Fair enough, probably better to keep the first version of this standard simple. |
Bump. If there's anything we can do on our end to help out here let me know. I really like this proposal. |
7da7631
to
a502088
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partway through reviewing, I will finish later today.
modified: 2019-11-08 | ||
--- | ||
|
||
## **Synopsis** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need both the header & bold, it will format correctly in a Markdown render with just '##'. (this comment also applies to other headers in this document)
|
||
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its host chain, even in times of byzantine behavior by the counterparty chain (the chain that manages the account) | ||
- The chain that controls the account must process the results asynchronously and according to the chain's logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which results? Results of executing transactions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, executed transactions will return the result code such as cosmos-sdk's sdk.Result
type. I think runTx
should return 0x if interchain tx is succeeded, or return an error code which is not 0x if interchain tx is failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(your response makes sense but can you clarify this in the document?)
|
||
## **Technical Specification** | ||
|
||
The implementation of interchain account is non symmetric. This means that each chain must define the way to create a interchain account for counterparty chain deterministically. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also I'm a little confused. Does different logic have to be defined for each counterparty chain? Do you mean that the transaction bytes will be different?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means that each chain can have a different way to deserialize transaction bytes and a different set of transactions that they can execute. For example, chains that use cosmos-sdk will deserialize tx bytes by amino, but if counterparty chain is a smart contract on Ethereum, it may deserialize tx bytes by ABI that is minimal serialize algorithm for smart contract. And a smart contract on Ethereum can't execute the staking, governance transaction if it doesn't support such feature. So, I think interchain account defines the general way to register interchain account and transfer tx bytes, and counterparty chain is responsible to deserialize and execute the tx bytes, and sending chain should know how counterparty chain handle tx bytes in advance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, just include the above paragraph in the spec so that it's clear.
The chain must reject the transaction and must not make a state transition in the following cases: | ||
|
||
- The IBC transaction fails to be deserialized. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(remove empty line)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments. Generally looking pretty good.
|
||
## **Example Implementation** | ||
|
||
Pseudocode for cosmos-sdk: https://github.com/everett-protocol/everett-hackathon/tree/master/x/interchain-account |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would also be helpful to reason about how this would work on Ethereum, which has a sufficiently programmable system that it should be able to implement this spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it can be implemented in a smart contract level with using CALL, DELEGATECALL, CALLCODE opcode that are used to delegate call to some function in callee. I will research more and try to implement pseudocode in Solidity.
ed1e77e
to
8db2fc5
Compare
Co-Authored-By: Christopher Goes <cwgoes@pluranimity.org>
8db2fc5
to
654882e
Compare
I fixed the misspelling and added some more specific description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there, a few final requested changes. cc @mossid, two reviews would be prudent.
|
||
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its host chain, even in times of byzantine behavior by the counterparty chain (the chain that manages the account) | ||
- The chain that controls the account must process the results asynchronously and according to the chain's logic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(your response makes sense but can you clarify this in the document?)
- Permissionless | ||
- Fault containment: Interchain account must follow rules of its host chain, even in times of Byzantine behavior by the counterparty chain (the chain that manages the account) | ||
- The chain that controls the account must process the results asynchronously and according to the chain's logic. | ||
- Sending and receiving transactions will be processed in an ordered manner. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As in, first in first out? Be specific (there could be many kinds of orderings).
Co-Authored-By: Christopher Goes <cwgoes@pluranimity.org>
0238a3c
to
12d797e
Compare
@cwgoes Thank you for your advice and for fixing the grammar and misspelling. I fixed it. Please check again. |
I think there are still a few outstanding comments, please check. (I would fix them, but I can't commit to your branch) |
Co-Authored-By: Christopher Goes <cwgoes@pluranimity.org>
4e58084
to
06d9359
Compare
@cwgoes I handled missed comments. Do I have anything left? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, commented minor changes
Co-Authored-By: Joon <torecursedivine@gmail.com>
Co-Authored-By: Christopher Goes <cwgoes@pluranimity.org>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK (as draft). Thanks & nice job 🎉 !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your contribution, great job! 💯
From #251
Changes