diff --git a/.gitignore b/.gitignore index e24dd0d2ac..a8961a7111 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,10 @@ examples/basecoin/app/data baseapp/data/* docs/_build .DS_Store +coverage.txt +profile.out .vscode - ### Vagrant ### .vagrant/ *.box diff --git a/docs/spec/ibc/ibc.md b/docs/spec/ibc/ibc.md new file mode 100644 index 0000000000..dedbdc3016 --- /dev/null +++ b/docs/spec/ibc/ibc.md @@ -0,0 +1,31 @@ +# IBC Specification + +IBC(Inter-Blockchain Communication) protocol is used by multiple zones on Cosmos. Using IBC, the zones can send coins or arbitrary data to other zones. + +## Terms + +How IBC module treats incoming IBC packets is simillar with how BaseApp treats incoming transactions. Therefore, the components of IBC module have their corresponding pair in BaseApp. + +| BaseApp Terms | IBC Terms | +| ------------- | ---------- | +| Router | Dispatcher | +| Tx | Packet | +| Msg | Payload | + +## MVP Specifications + +### [MVP1](./mvp1.md) + +MVP1 will contain the basic functionalities, including packet generation and packet receivement. There will be no security check for incoming packets. + +### [MVP2](./mvp2.md) + +IBC module will be more modular in MVP2. Indivisual modules can register custom handlers to IBC module. + +### [MVP3](./mvp3.md) + +Light client verification is added to verify the message from the other chain. Registering chains with their ROT(Root Of Trust) is needed. + +### [MVP4](./mvp4.md) + +ACK verification / timeout handler helper functions and messaging queue are implemented to make it failsafe. Callbacks will be registered to the dispatcher to handle failure when they register handlers. diff --git a/docs/spec/ibc/mvp1.md b/docs/spec/ibc/mvp1.md new file mode 100644 index 0000000000..3cfaf88ce8 --- /dev/null +++ b/docs/spec/ibc/mvp1.md @@ -0,0 +1,64 @@ +# IBC Spec + +*This is a living document and should be edited as the IBC spec and implementation change* + +## MVP1 + +The initial implementation of IBC will include just enough for simple coin transfers between chains, with safety features such as ACK messages being added later. + +### IBC Module + +```golang +// User facing API + +type IBCPacket struct { + DestAddr sdk.Address + Coins sdk.Coins + SrcChain string + DestChain string +} + +// Implements sdk.Msg +type IBCTransferMsg struct { + IBCPacket +} + +// Implements sdk.Msg +type IBCReceiveMsg struct { + IBCPacket +} + +// Internal API + +type IBCMapper struct { + ibcKey sdk.StoreKey // IngressKey / EgressKey => Value + // Ingress: Source Chain ID => last income msg's sequence + // Egress: (Dest chain ID, Msg index) => length / indexed msg +} + +type IngressKey struct { + SrcChain string +} + +type EgressKey struct { + DestChain string + Index int64 +} + +``` + +`egressKey` stores the outgoing `IBCTransfer`s as a list. Its getter takes an `EgressKey` and returns the length if `egressKey.Index == -1`, an element if `egressKey.Index > 0`. + +`ingressKey` stores the last income `IBCTransfer`'s sequence. Its getter takes an `IngressKey`. + +## Relayer + +**Packets** +- Connect to 2 Tendermint RPC endpoints +- Query for IBC outgoing `IBCOutMsg` queue (can poll on a certain time interval, or check after each new block, etc) +- For any new `IBCOutMsg`, build `IBCInMsg` and post to destination chain + +## CLI + +- Load relay process +- Execute `IBCOutMsg` diff --git a/docs/spec/ibc/mvp2.md b/docs/spec/ibc/mvp2.md new file mode 100644 index 0000000000..6cada51cc0 --- /dev/null +++ b/docs/spec/ibc/mvp2.md @@ -0,0 +1,86 @@ +# IBC Spec + +*This is a living document and should be edited as the IBC spec and implementation change* + +## MVP2 + +IBC module will store its own router for handling custom incoming msgs. `IBCPush` are made for inter-module communication. `IBCRegisterMsg` adds a handler in the router of the module. + +### IBC Module + +```golang +// User facing API + +type Packet struct { + Data Payload + SrcChain string + DestChain string +} + +type Payload interface { + Type() string + ValidateBasic() sdk.Error +} + +type TransferPayload struct { + DestAddr sdk.Address + Coins sdk.Coins +} + +// Implements sdk.Msg +type IBCTransferMsg struct { + Packet +} + +// Implements sdk.Msg +type IBCReceiveMsg struct { + Packet +} + +// Internal API + +type rule struct { + r string + f func(sdk.Context, IBCPacket) sdk.Result +} + +type Dispatcher struct { + rules []rule +} + +func NewHandler(dispatcher Dispatcher, ibcm IBCMapper) sdk.Handler + +type IBCMapper struct { + ibcKey sdk.StoreKey // IngressKey / EgressKey => Value + // Ingress: Source Chain ID => last income msg's sequence + // Egress: (Dest chain ID, Msg index) => length / indexed msg +} + +type IngressKey struct { + SrcChain string +} + +type EgressKey struct { + DestChain string + Index int64 +} + +// Used by other modules +func (ibcm IBCMapper) PushPacket(ctx sdk.Context, dest string, payload Payload) +``` + +`egressKey` stores the outgoing `IBCTransfer`s as a list. Its getter takes an `EgressKey` and returns the length if `egressKey.Index == -1`, an element if `egressKey.Index > 0`. + +`ingressKey` stores the last income `IBCTransfer`'s sequence. Its getter takes an `IngressKey`. + +## Relayer + +**Packets** +- Connect to 2 Tendermint RPC endpoints +- Query for IBC outgoing `IBCOutMsg` queue (can poll on a certain time interval, or check after each new block, etc) +- For any new `IBCOutMsg`, build `IBCInMsg` and post to destination chain + +## CLI + +- Load relay process +- Execute `IBCOutMsg` diff --git a/docs/spec/ibc/mvp3.md b/docs/spec/ibc/mvp3.md new file mode 100644 index 0000000000..bcbf39a921 --- /dev/null +++ b/docs/spec/ibc/mvp3.md @@ -0,0 +1,111 @@ +# IBC Spec + +## MVP3 + +`IBCOpenMsg` is added to open the connection between two chains. Also, `IBCUpdateMsg` is added, making it able to prove the header. + +### IBC Module + + +// Implements sdk.Msg +type IBCTransferMsg struct { + Packet +} + +// Implements sdk.Msg +type IBCReceiveMsg struct { + Packet +} + +// Internal API + + + +```golang +// User facing API + +type Packet struct { + Data Payload + SrcChain string + DestChain string +} + +type Payload interface { + Type() string + ValidateBasic() sdk.Error +} + +type TransferPayload struct { + SrcAddr sdk.Address + DestAddr sdk.Address + Coins sdk.Coins +} + +// Implements sdk.Msg +type IBCTransferMsg struct { + Packet +} + +// Implements sdk.Msg +type IBCReceiveMsg struct { + Packet + Proof iavl.Proof + FromChainID string + FromChainHeight uint64 +} + +type RootOfTrust struct { + // +} + +// Implements sdk.Msg +type IBCOpenMsg struct { + ROT RootOfTrust + Chain string +} + +// Implements sdk.Msg +type IBCUpdateMsg struct { + Header tm.Header + Commit tm.Commit +} + +// Internal API + +type rule struct { + r string + f func(sdk.Context, IBCPacket) sdk.Result +} + +type Dispatcher struct { + rules []rule +} + +func NewHandler(dispatcher Dispatcher, ibcm IBCMapper) sdk.Handler + +type IBCMapper struct { + ibcKey sdk.StoreKey // IngressKey / EgressKey / HeaderKey => Value + // ChannelID => last income msg's sequence + // (ChannelID, Msg index) => length / indexed msg + // ChannelID => last known header +} + +type IngressKey struct { + ChannelID uint64 +} + +type EgressKey struct { + ChannelID uint64 + Index int64 +} + +type HeaderKey struct { + ChannelID uint64 +} + +// Used by other modules +func (ibcm IBCMapper) PushPacket(ctx sdk.Context, dest string, payload Payload) + +``` + +