diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 505d8a914..299f24a08 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # Default owners for repository # 2/n quorum required for merge -* @mpoke @adityasripal @cwgoes @colin-axner +* @mpoke @adityasripal @cwgoes @colin-axner \ No newline at end of file diff --git a/README.md b/README.md index 47a261c70..1ee55529f 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,7 @@ All standards at or past the "Draft" stage are listed here in order of their ICS | -------------------------------------------------------- | ----------------------- | ----- | --------------- | | [20](spec/app/ics-020-fungible-token-transfer/README.md) | Fungible Token Transfer | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/transfer) | | [27](spec/app/ics-027-interchain-accounts/README.md) | Interchain Accounts | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/27-interchain-accounts) | +| [28](spec/app/ics-028-cross-chain-validation/README.md) | Cross-Chain Validation | Draft | | | [29](spec/app/ics-029-fee-payment) | General Relayer Incentivisation Mechanism | Candidate | [ibc-go](https://github.com/cosmos/ibc-go/tree/main/modules/apps/29-fee) | | [30](spec/app/ics-030-middleware) | IBC Application Middleware | N/A | N/A | | [721](spec/app/ics-721-nft-transfer) | Non-Fungible Token Transfer | Candidate | [bianjieai](https://github.com/bianjieai/ibc-go/tree/ics-721-nft-transfer) | diff --git a/spec/app/ics-028-cross-chain-validation/README.md b/spec/app/ics-028-cross-chain-validation/README.md new file mode 100644 index 000000000..41830b5f0 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/README.md @@ -0,0 +1,60 @@ +--- +ics: 28 +title: Cross-Chain Validation +stage: draft +category: IBC/APP +requires: 25, 26, 20 +author: Marius Poke , Aditya Sripal , Jovan Komatovic , Cezara Dragoi , Josef Widder +created: 2022-06-27 +modified: 2022-08-03 +--- + + +# Synopsis + +This standard document specifies packet data structure, state machine handling logic, and encoding details for Cross-Chain Validation (CCV). CCV is the specific IBC level protocol that enables *Interchain Security*, a Cosmos-specific category of *Shared Security*. + +At a high level, CCV enables a *provider chain* (e.g., the Cosmos Hub) to provide *security* to multiple *consumer chains*. This means that the validator sets on the consumer chains are chosen from the validator set of the provider chain (for more details, see the [Security Model](./overview_and_basic_concepts.md#security-model) section). + +The communication between the provider and the consumer chains is done through the IBC protocol over a *unique*, *ordered* channel (one for each consumer chain). + +> Throughout this document, we will use the terms chain and blockchain interchangeably. + +## Contents +- [Overview and Basic Concepts](./overview_and_basic_concepts.md) +- [System Model and Properties](./system_model_and_properties.md) +- [Technical Specification: Data Structures and Methods](./technical_specification.md) + - [Data Structures](./data_structures.md) + - [Methods](./methods.md) + + + +## Example Implementation + +Interchain Security [Go implementation](https://github.com/cosmos/interchain-security). + + + + +## History + +Jun 27, 2022 - Draft written + +Aug 3, 2022 - Revision of *Bond-Based Consumer Voting Power* property + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/spec/app/ics-028-cross-chain-validation/data_structures.md b/spec/app/ics-028-cross-chain-validation/data_structures.md new file mode 100644 index 000000000..5c724be5e --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/data_structures.md @@ -0,0 +1,295 @@ + +# CCV: Technical Specification - Data Structures +[↑ Back to main document](./README.md) + +[↑ Back to technical specification](./technical_specification.md) + + +## Outline +- [External Data Structures](#external-data-structures) +- [CCV Data Structures](#ccv-data-structures) +- [CCV Packets](#ccv-packets) +- [CCV State](#ccv-state) + - [State on Provider Chain](#state-on-provider-chain) + - [State on Consumer Chain](#state-on-consumer-chain) + +## External Data Structures +[↑ Back to Outline](#outline) + +This section describes external data structures used by the CCV module. + +The CCV module uses the ABCI `ValidatorUpdate` data structure, which consists of a validator and its power (for more details, take a look at the [ABCI specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/abci/abci.md#data-types)), i.e., +```typescript +interface ValidatorUpdate { + pubKey: PublicKey + power: int64 +} +``` +The provider chain sends to the consumer chain a list of `ValidatorUpdate`s, containing an entry for every validator that had its power updated. + +The data structures required for creating clients (i.e., `ClientState`, `ConsensusState`) are defined in [ICS 2](../../core/ics-002-client-semantics). +In the context of CCV, every chain is uniquely defined by their chain ID and the validator set. +Thus, CCV requires the `ClientState` to contain the chain ID and the `ConsensusState` for a particular height to contain the validator set at that height. +In addition, the `ClientState` should contain the `UnbondingPeriod`. +For an example, take a look at the `ClientState` and `ConsensusState` defined in [ICS 7](../../client/ics-007-tendermint-client). + +## CCV Data Structures +[↑ Back to Outline](#outline) + +The CCV module is initialized through the `InitGenesis` method when the chain is first started. The initialization is done from a genesis state. This is the case for both provider and consumer chains: +- On the provider chain, the genesis state is described by the following interface: + ```typescript + interface ProviderGenesisState { + // a list of existing consumer chains + consumerStates: [ConsumerState] + } + ``` + with `ConsumerState` defined as + ```typescript + interface ConsumerState { + chainId: string + channelId: Identifier + } + ``` +- On the consumer chain, the genesis state is described by the following interface: + ```typescript + interface ConsumerGenesisState { + providerClientState: ClientState + providerConsensusState: ConsensusState + initialValSet: [ValidatorUpdate] + } + ``` + +The provider CCV module handles governance proposals to spawn new consumer chains and to stop existing consumer chains. +While the structure of governance proposals is specific to every ABCI application (for an example, see the `Proposal` interface in the [Governance module documentation](https://docs.cosmos.network/v0.44/modules/gov/) of Cosmos SDK), +this specification expects the following fields to be part of the proposals to spawn new consumer chains (i.e., `SpawnConsumerChainProposal`) and to stop existing ones (i.e., `StopConsumerChainProposal`): + ```typescript + interface SpawnConsumerChainProposal { + chainId: string + initialHeight: Height + spawnTime: Timestamp + lockUnbondingOnTimeout: Bool + } + ``` + - `chainId` is the proposed chain ID of the new consumer chain. It must be different from all other consumer chain IDs of the executing provider chain. + - `initialHeight` is the proposed initial height of new consumer chain. + For an example, take a look at the `Height` defined in [ICS 7](../../client/ics-007-tendermint-client). + - `spawnTime` is the time on the provider chain at which the consumer chain genesis is finalized and all validators are responsible to start their consumer chain validator node. + - `lockUnbondingOnTimeout` is a boolean value that indicates whether the funds corresponding to the outstanding unbonding operations are to be released in case of a timeout. In case `lockUnbondingOnTimeout == true`, a governance proposal to stop the timed out consumer chain would be necessary to release the locked funds. + ```typescript + interface StopConsumerChainProposal { + chainId: string + stopTime: Timestamp + } + ``` + - `chainId` is the chain ID of the consumer chain to be removed. It must be the ID of an existing consumer chain of the executing provider chain. + - `stopTime` is the time on the provider chain at which all validators are responsible to stop their consumer chain validator node. + +During the CCV channel opening handshake, the provider chain adds the address of its distribution module account to the channel version as metadata (as described in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README.md#definitions)). +The metadata structure is described by the following interface: +```typescript +interface CCVHandshakeMetadata { + providerDistributionAccount: string // the account's address + version: string +} +``` +This specification assumes that the provider CCV module has access to the address of the distribution module account through the `GetDistributionAccountAddress()` method. For an example, take a look at the [auth module](https://docs.cosmos.network/v0.44/modules/auth/) of Cosmos SDK. + +During the CCV channel opening handshake, the provider chain adds the address of its distribution module account to the channel version as metadata (as described in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README.md#definitions)). +The metadata structure is described by the following interface: +```typescript +interface CCVHandshakeMetadata { + providerDistributionAccount: string // the account's address + version: string +} +``` +This specification assumes that the provider CCV module has access to the address of the distribution module account through the `GetDistributionAccountAddress()` method. For an example, take a look at the [auth module](https://docs.cosmos.network/v0.44/modules/auth/) of Cosmos SDK. + +## CCV Packets +[↑ Back to Outline](#outline) + +The structure of the packets sent through the CCV channel is defined by the `Packet` interface in [ICS 4](../../core/ics-004-channel-and-packet-semantics). +The following packet data types are required by the CCV module: +- `VSCPacketData` contains a list of validator updates, i.e., + ```typescript + interface VSCPacketData { + // the id of this VSC + id: uint64 + // validator updates + updates: [ValidatorUpdate] + // downtime slash requests acknowledgements, + // i.e., list of validator addresses + downtimeSlashAcks: [string] + } + ``` +- `VSCMaturedPacketData` contains the ID of the VSC that reached maturity, i.e., + ```typescript + interface VSCMaturedPacketData { + id: uint64 // the id of the VSC that reached maturity + } + ``` +- `SlashPacketData` contains a request to slash a validator, i.e., + ```typescript + interface SlashPacketData { + valAddress: string // validator address, i.e., the hash of its public key + valPower: int64 + vscId: uint64 + downtime: Bool + } + ``` +> Note that for brevity we use e.g., `VSCPacket` to refer to a packet with `VSCPacketData` as its data. + +Packets are acknowledged by the remote side by sending back an `Acknowledgement` that contains either a result (in case of success) or an error (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README.md#acknowledgement-envelope)). +The following acknowledgement types are required by the CCV module: +```typescript +type VSCPacketAcknowledgement = VSCPacketSuccess | VSCPacketError; +type VSCMaturedPacketAcknowledgement = VSCMaturedPacketSuccess | VSCMaturedPacketError; +type SlashPacketAcknowledgement = SlashPacketSuccess | SlashPacketError; +type PacketAcknowledgement = PacketSuccess | PacketError; // general ack +``` + +## CCV State +[↑ Back to Outline](#outline) + +This section describes the internal state of the CCV module. For simplicity, the state is described by a set of variables; for each variable, both the type and a brief description is provided. In practice, all the state (except for hardcoded constants, e.g., `ProviderPortId`) is stored in a key/value store (KVS). The host state machine provides a KVS interface with three functions, i.e., `get()`, `set()`, and `delete()` (as defined in [ICS 24](../../core/ics-024-host-requirements)). + +- `ccvVersion = "ccv-1"` is the CCV expected version. Both the provider and the consumer chains need to agree on this version. +- `zeroTimeoutHeight = {0,0}` is the `timeoutHeight` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) used by CCV for sending packets. Note that CCV uses `ccvTimeoutTimestamp` for sending CCV packets and `transferTimeoutTimestamp` for transferring tokens. +- `ccvTimeoutTimestamp: uint64` is the `timeoutTimestamp` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) for sending CCV packets. The CCV protocol is responsible of setting `ccvTimeoutTimestamp` such that the *Correct Relayer* assumption is feasible. +- `transferTimeoutTimestamp: uint64` is the `timeoutTimestamp` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) for transferring tokens. + +### State on Provider Chain +[↑ Back to Outline](#outline) + +- `ProviderPortId = "provider"` is the port ID the provider CCV module is expected to bind to. +- `pendingSpawnProposals: [SpawnConsumerChainProposal]` is a list of pending governance proposals to spawn new consumer chains. +- `pendingStopProposals: [StopConsumerChainProposal]` is a list of pending governance proposals to stop existing consumer chains. + Both lists of pending governance proposals expose the following interface: +```typescript + interface [Proposal] { + // append a proposal to the list; the list is modified + Append(p: Proposal) + + // remove a proposal from the list; the list is modified + Remove(p: Proposal) + } + ``` +- `lockUnbondingOnTimeout: Map` is a mapping from consumer chain IDs to the boolean values indicating whether the funds corresponding to the in progress unbonding operations are to be released in case of a timeout. +- `chainToClient: Map` is a mapping from consumer chain IDs to the associated client IDs. +- `chainToChannel: Map` is a mapping from consumer chain IDs to the CCV channel IDs. +- `channelToChain: Map` is a mapping from CCV channel IDs to consumer chain IDs. +- `pendingVSCPackets: Map` is a mapping from consumer chain IDs to a list of pending `VSCPacketData`s that must be sent to the consumer chain once the CCV channel is established. The map exposes the following interface: + ```typescript + interface Map { + // append a VSCPacketData to the list mapped to chainId; + // the list is modified + Append(chainId: string, data: VSCPacketData) + + // remove all the VSCPacketData mapped to chainId; + // the list is modified + Remove(chainId: string) + } +- `vscId: uint64` is a monotonic strictly increasing and positive ID that is used to uniquely identify the VSCs sent to the consumer chains. + Note that `0` is used as a special ID for the mapping from consumer heights to provider heights. +- `initialHeights: Map` is a mapping from consumer chain IDs to the heights on the provider chain. + For every consumer chain, the mapping stores the height when the CCV channel to that consumer chain is established. + Note that the provider validator set at this height matches the validator set at the height when the first VSC is provided to that consumer chain. + It enables the mapping from consumer heights to provider heights. +- `VSCtoH: Map` is a mapping from VSC IDs to heights on the provider chain. It enables the mapping from consumer heights to provider heights, + i.e., the voting power at height `VSCtoH[id]` on the provider chain was last updated by the validator updates contained in the VSC with ID `id`. +- `unbondingOps: Map` is a mapping that enables accessing for every unbonding operation the list of consumer chains that are still unbonding. When unbonding operations are initiated, the Staking module calls the `AfterUnbondingInitiated()` [hook](#ccv-pcf-hook-afubopcr1); this leads to the creation of a new `UnbondingOperation`, which is defined as + ```typescript + interface UnbondingOperation { + id: uint64 + // list of consumer chain IDs that are still unbonding + unbondingChainIds: [string] + } + ``` +- `vscToUnbondingOps: Map<(string, uint64), [uint64]>` is a mapping from `(chainId, vscId)` tuples to a list of unbonding operation IDs. + It enables the provider CCV module to match a `VSCMaturedPacket{vscId}`, received from a consumer chain with `chainId`, with the corresponding unbonding operations. + As a result, `chainId` can be removed from the list of consumer chains that are still unbonding these operations. + For more details see how received `VSCMaturedPacket`s [are handled](#ccv-pcf-rcvmat1). +- `downtimeSlashRequests: Map` is a mapping from `chainId`s to lists of validator addresses, + i.e., `downtimeSlashRequests[chainId]` contains all the validator addresses for which the provider chain received slash requests for downtime from the consumer chain with `chainId`. + +### State on Consumer Chain +[↑ Back to Outline](#outline) + +- `ConsumerPortId = "consumer"` is the port ID the consumer CCV module is expected to bind to. +- `consumerUnbondingPeriod: Duration"` is the unbonding period on the consumer chain. +- `providerClient: Identifier` identifies the client of the provider chain (on the consumer chain) that the CCV channel is build upon. +- `providerChannel: Identifier` identifies the consumer's channel end of the CCV channel. +- `validatorSet: ` is a mapping that stores the validators in the validator set of the consumer chain. Each validator is described by a `CrossChainValidator` data structure, which is defined as + ```typescript + interface CrossChainValidator { + address: string // validator address, i.e., the hash of its public key + power: int64 + } + ``` +- `pendingChanges: [ValidatorUpdate]` is a list of `ValidatorUpdate`s received, but not yet applied to the validator set. + It is emptied on every `EndBlock()`. The list exposes the following interface: + ```typescript + interface [ValidatorUpdate] { + // append updates to the list; + // the list is modified + Append(updates: [ValidatorUpdate]) + + // return an aggregated list of updates, i.e., + // keep only the latest update per validator; + // the original list is not modified + Aggregate(): [ValidatorUpdate] + + // remove all the updates from the list; + // the list is modified + RemoveAll() + } + ``` +- `HtoVSC: Map` is a mapping from consumer chain heights to VSC IDs. It enables the mapping from consumer heights to provider heights., i.e., + - if `HtoVSC[h] == 0`, then the voting power on the consumer chain at height `h` was setup at genesis during Channel Initialization; + - otherwise, the voting power on the consumer chain at height `h` was updated by the VSC with ID `HtoVSC[h]`. +- `maturingVSCs: [(uint64, uint64)]` is a list of `(id, ts)` tuples, where `id` is the ID of a VSC received via a `VSCPacket` and `ts` is the timestamp at which the VSC reaches maturity on the consumer chain. + The list is used to keep track of when unbonding operations are matured on the consumer chain. It exposes the following interface: + ```typescript + interface [(uint64, uint64)] { + // add a VSC id with its maturity timestamp to the list; + // the list is modified + Add(id: uint64, ts: uint64) + + // return the list sorted by the maturity timestamps; + // the original list is not modified + SortedByMaturityTime(): [(uint64, uint64)] + + // remove (id, ts) from the list; + // the list is modified + Remove(id: uint64, ts: uint64) + } + ``` +- `pendingSlashRequests: [SlashRequest]` is a list of pending `SlashRequest`s that must be sent to the provider chain once the CCV channel is established. A `SlashRequest` consist of a `SlashPacketData` and a flag indicating whether the request is for downtime slashing. The list exposes the following interface: + ```typescript + interface SlashRequest { + data: SlashPacketData + downtime: Bool + } + interface [SlashRequest] { + // append a SlashRequest to the list; + // the list is modified + Append(data: SlashRequest) + + // return the reverse list, i.e., latest SlashRequest first; + // the original list is not modified + Reverse(): [SlashRequest] + + // remove all the SlashRequest; + // the list is modified + RemoveAll() + } + ``` +- `outstandingDowntime: ` is a mapping from validator addresses to boolean values. + `outstandingDowntime[valAddr] == TRUE` entails that the consumer chain sent a request to slash for downtime the validator with address `valAddr`. + `outstandingDowntime[valAddr]` is set to false once the consumer chain receives a confirmation that the downtime slash request was received by the provider chain, i.e., a `VSCPacket` that contains `valAddr` in `downtimeSlashAcks`. + The mapping enables the consumer CCV module to avoid sending to the provider chain multiple slashing requests for the same downtime infraction. +- `providerDistributionAccount: string` is the address of the distribution module account on the provider chain. It enables the consumer chain to transfer rewards to the provider chain. +- `distributionChannelId: Identifier` is the ID of the distribution token transfer channel used for sending rewards to the provider chain. +- `BlocksPerDistributionTransfer: int64` is the interval (in number of blocks) between two distribution token transfers. +- `lastDistributionTransferHeight: Height` is the block height of the last distribution token transfer. +- `ccvAccount: string` is the address of the CCV module account where a fraction of the consumer chain rewards are collected before being transferred to the provider chain. \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw new file mode 100644 index 000000000..9a4cf8517 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw @@ -0,0 +1,1448 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "text", + "version": 1005, + "versionNonce": 942012557, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1391.0634920634916, + "y": 1852.9047619047617, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 361, + "height": 35, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717847398, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "CCV - Reward Distribution", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV - Reward Distribution" + }, + { + "type": "text", + "version": 1473, + "versionNonce": 1279271715, + "isDeleted": false, + "id": "yqi6dzvpzblq17ysowkTo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1184.1995040738243, + "y": 1919.7150027318748, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 138, + "height": 26, + "seed": 578772677, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717830267, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1700, + "versionNonce": 380537603, + "isDeleted": false, + "id": "Y19fC1uuzabCFyV0s97Ip", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1774.6009368748905, + "y": 1919.7150027318748, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 148, + "height": 26, + "seed": 1161289003, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717824957, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chain" + }, + { + "type": "text", + "version": 1418, + "versionNonce": 856000099, + "isDeleted": false, + "id": "A_uPQosGByCb18jg5F8J3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1608.6178858721328, + "y": 1957.1879109167996, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 1240462166, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648717754192, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "arrow", + "version": 3989, + "versionNonce": 2125688557, + "isDeleted": false, + "id": "vpFHq3t2ppDoZ0A65BDZu", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1551.1900175267103, + "y": 2344.842556707134, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 128.79181255561082, + "height": 0.08876270859309443, + "seed": 564068565, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -128.79181255561082, + -0.08876270859309443 + ] + ] + }, + { + "type": "text", + "version": 2037, + "versionNonce": 196149859, + "isDeleted": false, + "id": "REPxg78R4E5rz3sm5KHSv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1409.5528637544644, + "y": 2302.708121633686, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 146, + "height": 25, + "seed": 208528123, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "TokenTransfer", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "TokenTransfer" + }, + { + "id": "IjbvMm7oV9sVgP7WlGh5E", + "type": "line", + "x": 1799.9264992474484, + "y": 2096.174492510282, + "width": 0.4985622223937298, + "height": 33.65304102189839, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 806893027, + "version": 108, + "versionNonce": 348679437, + "isDeleted": false, + "boundElements": null, + "updated": 1648718383497, + "link": null, + "points": [ + [ + 0, + 0 + ], + [ + 0.4985622223937298, + 33.65304102189839 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "type": "rectangle", + "version": 3280, + "versionNonce": 1529278413, + "isDeleted": false, + "id": "34mJiRUfZv_whlGRmiJJO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 1993.826747397683, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 90.41269841269803, + "seed": 906912827, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "type": "text", + "version": 1668, + "versionNonce": 47873923, + "isDeleted": false, + "id": "m_vQSEBRga8RR7VuL27UY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1821.73693349118, + "y": 1999.4973823183186, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 109, + "height": 50, + "seed": 765969819, + "groupIds": [ + "lNYd5uxp6Xm5xLMU-zrby", + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "tvGd783eUc39eNWP1L7-j", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of\nrewards", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of\nrewards" + }, + { + "type": "arrow", + "version": 3963, + "versionNonce": 229731885, + "isDeleted": false, + "id": "tvGd783eUc39eNWP1L7-j", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1932.8019559784343, + "y": 2060.997674669792, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 125.15697875770252, + "height": 1.0514920517930477, + "seed": 321384565, + "groupIds": [ + "Uvbj_Wiv_4OirTlk_pHjj", + "lNYd5uxp6Xm5xLMU-zrby", + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "startBinding": { + "elementId": "m_vQSEBRga8RR7VuL27UY", + "focus": -1.415085392769348, + "gap": 11.50029235147349 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -125.15697875770252, + -1.0514920517930477 + ] + ] + }, + { + "id": "xbQJbKMN6ij9ve7OviLr7", + "type": "rectangle", + "x": 1599.902692012232, + "y": 2035.4081490120375, + "width": 188, + "height": 35, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "seed": 210145315, + "version": 332, + "versionNonce": 1528635533, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "CYcPnlANLHU04SN9990JF" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "id": "CYcPnlANLHU04SN9990JF", + "type": "text", + "x": 1604.902692012232, + "y": 2041.4081490120375, + "width": 178, + "height": 23, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "seed": 15459693, + "version": 299, + "versionNonce": 1227668163, + "isDeleted": false, + "boundElements": null, + "updated": 1648718365618, + "link": null, + "text": "$ CCV account", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 17, + "containerId": "xbQJbKMN6ij9ve7OviLr7", + "originalText": "$ CCV account" + }, + { + "type": "text", + "version": 1938, + "versionNonce": 958629613, + "isDeleted": false, + "id": "Oz5lUjmcWXSCVOUr-aDA6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1960.8164836480091, + "y": 1999.0985727945085, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 756640341, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc" + }, + { + "type": "rectangle", + "version": 3445, + "versionNonce": 32402019, + "isDeleted": false, + "id": "smdUW8hJpPhBv4aV5ay_q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 2266.901858466779, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 90.41269841269803, + "seed": 1103023629, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "type": "text", + "version": 1833, + "versionNonce": 709763405, + "isDeleted": false, + "id": "F6tHqrlehaqv4NgVfyYod", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1821.73693349118, + "y": 2272.5724933874144, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 109, + "height": 50, + "seed": 1491510595, + "groupIds": [ + "iVaTc7j72nXI1Q2rCU61q", + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "J8lhUtkiur7yuJP0IVsWe", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of\nrewards", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of\nrewards" + }, + { + "type": "arrow", + "version": 4359, + "versionNonce": 35202563, + "isDeleted": false, + "id": "J8lhUtkiur7yuJP0IVsWe", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1932.8019559784343, + "y": 2334.072785738888, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 125.15697875770252, + "height": 1.0514920517930477, + "seed": 171148397, + "groupIds": [ + "pplowjM61J9zLv8WW_Iet", + "iVaTc7j72nXI1Q2rCU61q", + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "startBinding": { + "elementId": "F6tHqrlehaqv4NgVfyYod", + "focus": -1.415085392769348, + "gap": 11.50029235147349 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -125.15697875770252, + -1.0514920517930477 + ] + ] + }, + { + "type": "rectangle", + "version": 494, + "versionNonce": 279670179, + "isDeleted": false, + "id": "Alaps4d4CIl7xNCwR5rzQ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1599.902692012232, + "y": 2308.4832600811333, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 35, + "seed": 134677731, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "ew0ofctlhOyFp3fOfssPc", + "type": "text" + }, + { + "type": "text", + "id": "ew0ofctlhOyFp3fOfssPc" + } + ], + "updated": 1648718365619, + "link": null + }, + { + "type": "text", + "version": 464, + "versionNonce": 876999181, + "isDeleted": false, + "id": "ew0ofctlhOyFp3fOfssPc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1604.902692012232, + "y": 2314.4832600811333, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 23, + "seed": 595750605, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365619, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ CCV account", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Alaps4d4CIl7xNCwR5rzQ", + "originalText": "$ CCV account" + }, + { + "type": "text", + "version": 2105, + "versionNonce": 282313027, + "isDeleted": false, + "id": "qKtTARj56MbaSPbxOCPJk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1959.8164836480091, + "y": 2272.1736838636043, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 523923587, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365619, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc+x", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc+x" + }, + { + "type": "rectangle", + "version": 576, + "versionNonce": 598161635, + "isDeleted": false, + "id": "GLbhbcWSEyuebylqDnpU2", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1187.9667306872643, + "y": 2288.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 57, + "seed": 1340530701, + "groupIds": [ + "VtmzX2Iudw6NpYzBxjnOR", + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "v7H0D2SFSeTqd98kFr9Tn", + "type": "text" + }, + { + "id": "v7H0D2SFSeTqd98kFr9Tn", + "type": "text" + }, + { + "type": "text", + "id": "v7H0D2SFSeTqd98kFr9Tn" + } + ], + "updated": 1648718352186, + "link": null + }, + { + "type": "text", + "version": 550, + "versionNonce": 942635725, + "isDeleted": false, + "id": "v7H0D2SFSeTqd98kFr9Tn", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1192.9667306872643, + "y": 2293.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 46, + "seed": 780186435, + "groupIds": [ + "VtmzX2Iudw6NpYzBxjnOR", + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ distribution \naccount", + "baseline": 40, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "GLbhbcWSEyuebylqDnpU2", + "originalText": "$ distribution account" + }, + { + "type": "rectangle", + "version": 3481, + "versionNonce": 1085547651, + "isDeleted": false, + "id": "AkC-Q6AHwm6Ua2co050XG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1105.9667306872643, + "y": 2267.868466472355, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 288.25, + "height": 88.57936507936469, + "seed": 1841008003, + "groupIds": [ + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1648718352186, + "link": null + }, + { + "type": "text", + "version": 1836, + "versionNonce": 1869650221, + "isDeleted": false, + "id": "ukJYsO2TyJCEXc5fyeEt_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1111.4667306872643, + "y": 2275.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1647435235, + "groupIds": [ + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp2", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp2" + }, + { + "type": "arrow", + "version": 3920, + "versionNonce": 563157581, + "isDeleted": false, + "id": "t6EBWr_9oI5RhHG2G77KC", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1557.4055642998305, + "y": 2074.3425567071336, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 128.79181255561082, + "height": 0.08876270859309443, + "seed": 1421736451, + "groupIds": [ + "jL3JwgrGJGsJ9iKIcLo8U" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648717806780, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -128.79181255561082, + -0.08876270859309443 + ] + ] + }, + { + "type": "text", + "version": 1968, + "versionNonce": 1331576067, + "isDeleted": false, + "id": "Q1QsNgKGpkQte_Ty3Gq5x", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1415.7684105275844, + "y": 2032.2081216336865, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 146, + "height": 25, + "seed": 1505287085, + "groupIds": [ + "jL3JwgrGJGsJ9iKIcLo8U" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717806780, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "TokenTransfer", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "TokenTransfer" + }, + { + "type": "rectangle", + "version": 509, + "versionNonce": 932698541, + "isDeleted": false, + "id": "s_dUdYMbfAgY-wx64-cZy", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1187.9667306872643, + "y": 2017.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 57, + "seed": 1603649955, + "groupIds": [ + "XrGNgTVaQYbbqnVbqe1WW", + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "type": "text", + "id": "HgpbjFpWkkElb6JHK30jf" + } + ], + "updated": 1648717890359, + "link": null + }, + { + "type": "text", + "version": 482, + "versionNonce": 296592291, + "isDeleted": false, + "id": "HgpbjFpWkkElb6JHK30jf", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1192.9667306872643, + "y": 2022.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 46, + "seed": 1591401997, + "groupIds": [ + "XrGNgTVaQYbbqnVbqe1WW", + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717890359, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ distribution \naccount", + "baseline": 40, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s_dUdYMbfAgY-wx64-cZy", + "originalText": "$ distribution account" + }, + { + "type": "rectangle", + "version": 3413, + "versionNonce": 1680481293, + "isDeleted": false, + "id": "nAD6yE-Il7_lA6MHEDRRU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1105.9667306872643, + "y": 1997.368466472355, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 288.25, + "height": 88.57936507936469, + "seed": 928224579, + "groupIds": [ + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1648717890359, + "link": null + }, + { + "type": "text", + "version": 1765, + "versionNonce": 1612658499, + "isDeleted": false, + "id": "24NFD0EAJBhRkLJaPjCB7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1111.4667306872643, + "y": 2005.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1229821037, + "groupIds": [ + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717890359, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp1", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp1" + }, + { + "type": "rectangle", + "version": 3523, + "versionNonce": 1093005251, + "isDeleted": false, + "id": "5UhO9vf3ic8tfV-ct-H4a", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 2141.4520030011813, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 67.91269841269799, + "seed": 1223050061, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718382746, + "link": null + }, + { + "type": "text", + "version": 1929, + "versionNonce": 1078206957, + "isDeleted": false, + "id": "ORXBeHtSMUVrEyiFaIik_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1804.48693349118, + "y": 2149.6226379218165, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 196, + "height": 25, + "seed": 1376527363, + "groupIds": [ + "EZZbZ1FR2RI1InChFO1wi", + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "0hQr8j4kqSD8M3pL0Qbq9", + "type": "arrow" + } + ], + "updated": 1648718382746, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of rewards", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of rewards" + }, + { + "type": "arrow", + "version": 4612, + "versionNonce": 1861812067, + "isDeleted": false, + "id": "0hQr8j4kqSD8M3pL0Qbq9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1985.0603540692218, + "y": 2190.3258903405326, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 177.41537684849004, + "height": 0.2544521190352498, + "seed": 1060786605, + "groupIds": [ + "fPmYjanoLwZxiv--xyo7a", + "EZZbZ1FR2RI1InChFO1wi", + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718382746, + "link": null, + "startBinding": { + "elementId": "ORXBeHtSMUVrEyiFaIik_", + "focus": -2.221803403364259, + "gap": 15.703252418716147 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -177.41537684849004, + -0.2544521190352498 + ] + ] + }, + { + "type": "rectangle", + "version": 563, + "versionNonce": 2064194307, + "isDeleted": false, + "id": "AaZnP-uk9pLjwUgVCuPxX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1599.902692012232, + "y": 2160.5334046155363, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 35, + "seed": 630107043, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "y72sz2bjJqP1nhMBGOJmw", + "type": "text" + }, + { + "id": "y72sz2bjJqP1nhMBGOJmw", + "type": "text" + }, + { + "type": "text", + "id": "y72sz2bjJqP1nhMBGOJmw" + } + ], + "updated": 1648718382747, + "link": null + }, + { + "type": "text", + "version": 532, + "versionNonce": 1777093293, + "isDeleted": false, + "id": "y72sz2bjJqP1nhMBGOJmw", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1604.902692012232, + "y": 2166.5334046155363, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 23, + "seed": 1086166029, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718382747, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ CCV account", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "AaZnP-uk9pLjwUgVCuPxX", + "originalText": "$ CCV account" + }, + { + "type": "line", + "version": 162, + "versionNonce": 1275754051, + "isDeleted": false, + "id": "LWfeCA_MHMz7HlX7Nl_HY", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1799.471492174934, + "y": 2221.3874474682207, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.4985622223937298, + "height": 33.65304102189839, + "seed": 809602285, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718383497, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0.4985622223937298, + 33.65304102189839 + ] + ] + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png new file mode 100644 index 000000000..40f740d5b Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.excalidraw new file mode 100644 index 000000000..735b8dbbe --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.excalidraw @@ -0,0 +1,1325 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "text", + "version": 928, + "versionNonce": 148875698, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1097.0634920634916, + "y": 1862.9047619047617, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 469, + "height": 35, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998586809, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "CCV - Consumer Initiated Slashing", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV - Consumer Initiated Slashing" + }, + { + "type": "text", + "version": 1321, + "versionNonce": 1900012082, + "isDeleted": false, + "id": "yqi6dzvpzblq17ysowkTo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 827.4977622717156, + "y": 1970.1534947953671, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 138, + "height": 26, + "seed": 578772677, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490055, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1697, + "versionNonce": 323391662, + "isDeleted": false, + "id": "Y19fC1uuzabCFyV0s97Ip", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1774.6009368748905, + "y": 1920.5265106683828, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 148, + "height": 26, + "seed": 1161289003, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998572152, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chain" + }, + { + "type": "text", + "version": 1378, + "versionNonce": 1663618034, + "isDeleted": false, + "id": "hE0ZFKm5e3BFhfSAr_icT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1019.6178858721332, + "y": 2020.711720440609, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 711940170, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490055, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "text", + "version": 1593, + "versionNonce": 1502585902, + "isDeleted": false, + "id": "wTqYd1LVy1RtivTHEtctU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 440.04645730070445, + "y": 2014.7831490120375, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 147, + "height": 25, + "seed": 1503717526, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490055, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Staking Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Staking Module" + }, + { + "type": "text", + "version": 1416, + "versionNonce": 380279090, + "isDeleted": false, + "id": "A_uPQosGByCb18jg5F8J3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1608.6178858721328, + "y": 1957.1879109167996, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 1240462166, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998572152, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "rectangle", + "version": 3147, + "versionNonce": 1238376046, + "isDeleted": false, + "id": "34mJiRUfZv_whlGRmiJJO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1578.8152225891768, + "y": 1991.326747397683, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 560.3095238095233, + "height": 152.91269841269806, + "seed": 906912827, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1646998579671, + "link": null + }, + { + "type": "rectangle", + "version": 2729, + "versionNonce": 1427746414, + "isDeleted": false, + "id": "XvKZ52HBgSZoisoCgiom8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1604.4348764712604, + "y": 2092.2076997786344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 271, + "height": 39, + "seed": 1134907637, + "groupIds": [ + "PxynHKdbXOZO1gzKY2WrJ" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "id": "b3SzkJI0k_8z9gcpTqmUE", + "type": "text" + }, + { + "type": "text", + "id": "b3SzkJI0k_8z9gcpTqmUE" + } + ], + "updated": 1646998652727, + "link": null + }, + { + "type": "text", + "version": 2886, + "versionNonce": 1701918578, + "isDeleted": false, + "id": "b3SzkJI0k_8z9gcpTqmUE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1609.4348764712604, + "y": 2097.2076997786344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 261, + "height": 25, + "seed": 818685147, + "groupIds": [ + "PxynHKdbXOZO1gzKY2WrJ" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998652727, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "XvKZ52HBgSZoisoCgiom8", + "originalText": "EndBlock" + }, + { + "type": "text", + "version": 1743, + "versionNonce": 2033677490, + "isDeleted": false, + "id": "Oz5lUjmcWXSCVOUr-aDA6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2082.892603541556, + "y": 1996.5985727945085, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 756640341, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998572152, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc2", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc2" + }, + { + "type": "text", + "version": 1535, + "versionNonce": 1873602414, + "isDeleted": false, + "id": "m_vQSEBRga8RR7VuL27UY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1921.2556987796524, + "y": 2014.4973823183186, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 146, + "height": 25, + "seed": 765969819, + "groupIds": [ + "lNYd5uxp6Xm5xLMU-zrby" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998572152, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "evidence(V, Hc1)", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "evidence(V, Hc1)" + }, + { + "type": "arrow", + "version": 3778, + "versionNonce": 1535774322, + "isDeleted": false, + "id": "tvGd783eUc39eNWP1L7-j", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2040.8207212669067, + "y": 2058.497674669792, + "strokeColor": "#c92a2a", + "backgroundColor": "#ced4da", + "width": 125.15697875770252, + "height": 1.0514920517930477, + "seed": 321384565, + "groupIds": [ + "Uvbj_Wiv_4OirTlk_pHjj", + "lNYd5uxp6Xm5xLMU-zrby" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998572152, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -125.15697875770252, + -1.0514920517930477 + ] + ] + }, + { + "type": "arrow", + "version": 3577, + "versionNonce": 487214514, + "isDeleted": false, + "id": "vpFHq3t2ppDoZ0A65BDZu", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1553.7271634489994, + "y": 2061.6224232101013, + "strokeColor": "#c92a2a", + "backgroundColor": "#ced4da", + "width": 124.1975520241399, + "height": 1.8686292115605738, + "seed": 564068565, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998579670, + "link": null, + "startBinding": { + "elementId": "34mJiRUfZv_whlGRmiJJO", + "focus": 0.019438175195012165, + "gap": 25.088059140177393 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -124.1975520241399, + -1.8686292115605738 + ] + ] + }, + { + "type": "text", + "version": 1715, + "versionNonce": 404673582, + "isDeleted": false, + "id": "REPxg78R4E5rz3sm5KHSv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1429.1842702082242, + "y": 2017.708121633686, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 121, + "height": 25, + "seed": 208528123, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1646998578518, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "SlashPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "SlashPacket" + }, + { + "type": "rectangle", + "version": 2926, + "versionNonce": 656230254, + "isDeleted": false, + "id": "XDYLAXX2W3oqW1A2aQPWE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 362.7914130653671, + "y": 2049.49341406435, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1034.5, + "height": 188.57936507936463, + "seed": 521115163, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1646998490056, + "link": null + }, + { + "type": "arrow", + "version": 3877, + "versionNonce": 1506782834, + "isDeleted": false, + "id": "EVouO_KhDhhn4Dc-QBpIO", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 692.4977855419893, + "y": 2212.456760921986, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 272.89269154785916, + "height": 1.091620121523647, + "seed": 1274064149, + "groupIds": [ + "YitB1O3hLStSm9d0ji7t9" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 272.89269154785916, + -1.091620121523647 + ] + ] + }, + { + "type": "text", + "version": 2701, + "versionNonce": 790505902, + "isDeleted": false, + "id": "qsmfvn2HY2RHLwEOsOUzi", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 714.8028231842457, + "y": 2168.99302141663, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 25, + "seed": 713824955, + "groupIds": [ + "YitB1O3hLStSm9d0ji7t9" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates" + }, + { + "type": "rectangle", + "version": 2463, + "versionNonce": 2020937778, + "isDeleted": false, + "id": "qk20Z3SITwZB_fsRciLni", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1011.0420193284037, + "y": 2122.124366445302, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 311, + "height": 100.00000000000001, + "seed": 669270645, + "groupIds": [ + "oDeq5vVUsHhsfwNK8oF5f" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "type": "text" + }, + { + "type": "text", + "id": "gOlzS2a5Jqr0i8pKHSLv7" + } + ], + "updated": 1646998490056, + "link": null + }, + { + "type": "text", + "version": 2629, + "versionNonce": 1095287790, + "isDeleted": false, + "id": "gOlzS2a5Jqr0i8pKHSLv7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1016.0420193284037, + "y": 2134.624366445302, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 301, + "height": 75, + "seed": 1766787931, + "groupIds": [ + "oDeq5vVUsHhsfwNK8oF5f" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- VSC := {updates}\n- provide VSC", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "qk20Z3SITwZB_fsRciLni", + "originalText": "EndBlock\n- VSC := {updates}\n- provide VSC" + }, + { + "type": "rectangle", + "version": 2242, + "versionNonce": 1736980978, + "isDeleted": false, + "id": "Z8iTG7LRXktwbfyN2PngJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 433.6791974944824, + "y": 2153.112461683397, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 202, + "height": 73, + "seed": 1602104277, + "groupIds": [ + "OjN-e-BfocNTU6MSi9MH2" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "id": "ic_T2XDT20pmVr-i6K6mT", + "type": "text" + }, + { + "type": "text", + "id": "ic_T2XDT20pmVr-i6K6mT" + } + ], + "updated": 1646998490056, + "link": null + }, + { + "type": "text", + "version": 2299, + "versionNonce": 1604720174, + "isDeleted": false, + "id": "ic_T2XDT20pmVr-i6K6mT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 438.6791974944824, + "y": 2166.612461683397, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 192, + "height": 46, + "seed": 2141906939, + "groupIds": [ + "OjN-e-BfocNTU6MSi9MH2" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- compute updates", + "baseline": 40, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "Z8iTG7LRXktwbfyN2PngJ", + "originalText": "EndBlock\n- compute updates" + }, + { + "type": "text", + "version": 1569, + "versionNonce": 1712335794, + "isDeleted": false, + "id": "qWsxcIYo6PitI0T_lOAGZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 370.01165116060577, + "y": 2056.5509537468897, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1389619509, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp" + }, + { + "type": "arrow", + "version": 2743, + "versionNonce": 1662984302, + "isDeleted": false, + "id": "cDFbJ0gJjmHMqsUWmcRHo", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1439.909579382777, + "y": 2189.5700102244327, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 92.50326616584789, + "height": 1.2513122634102274, + "seed": 534734293, + "groupIds": [ + "dE16wt7NaL6vKkhA161Rq" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 92.50326616584789, + -1.2513122634102274 + ] + ] + }, + { + "type": "text", + "version": 1351, + "versionNonce": 976479602, + "isDeleted": false, + "id": "xOTca9VBswKVU42Gp8Rf4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1432.4699844939385, + "y": 2146.5676115550605, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 25, + "seed": 1553092091, + "groupIds": [ + "dE16wt7NaL6vKkhA161Rq" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket" + }, + { + "type": "text", + "version": 143, + "versionNonce": 528278190, + "isDeleted": false, + "id": "Q4K_DBLw6Q2OCljBU7Wuz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1011.3985559225102, + "y": 2066.640239461175, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 382, + "height": 25, + "seed": 361141403, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "request Slash(V, VSCtoH[HtoVSC[Hc1]])", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "request Slash(V, VSCtoH[HtoVSC[Hc1]])" + }, + { + "type": "arrow", + "version": 3915, + "versionNonce": 1295673138, + "isDeleted": false, + "id": "7x2vU_cDTbkEtKs9PHzx4", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 968.2018376263626, + "y": 2079.364743828038, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 96.46370626484804, + "height": 0.26527698055974724, + "seed": 451933083, + "groupIds": [ + "8RY6Q6u1gjiJW9pVBSA-G" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -96.46370626484804, + 0.26527698055974724 + ] + ] + }, + { + "type": "text", + "version": 152, + "versionNonce": 124280046, + "isDeleted": false, + "id": "G-kvSnhuwz_o8zVNMnRfw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 743.755698779653, + "y": 2070.640239461175, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 78, + "height": 25, + "seed": 124916443, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Slash(V)", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Slash(V)" + }, + { + "type": "text", + "version": 1552, + "versionNonce": 1200271602, + "isDeleted": false, + "id": "C8kWqIDQW5MX6a6ah4kSq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 705.7080797320335, + "y": 2014.9887705242381, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 152, + "height": 25, + "seed": 1595117284, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Slashing Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Slashing Module" + }, + { + "type": "text", + "version": 183, + "versionNonce": 1349160750, + "isDeleted": false, + "id": "RR6VdNWjbLRrErohTTbBm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 746.8330797320335, + "y": 2103.863770524238, + "strokeColor": "#c92a2a", + "backgroundColor": "transparent", + "width": 62, + "height": 25, + "seed": 1521074404, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Jail(V)", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Jail(V)" + }, + { + "type": "arrow", + "version": 4054, + "versionNonce": 749454002, + "isDeleted": false, + "id": "klgx4MBotg1iyiCI49QGG", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 711.5649328644578, + "y": 2099.981132033958, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 58.481294157559205, + "height": 0.48010792003151437, + "seed": 1400894308, + "groupIds": [ + "9GTuKCxQp5kiE4U_bEtRe" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -58.481294157559205, + 0.48010792003151437 + ] + ] + }, + { + "type": "text", + "version": 281, + "versionNonce": 384596334, + "isDeleted": false, + "id": "aafBj4XUKtz6lcnF74kwy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 438.0830797320335, + "y": 2107.613770524238, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 168, + "height": 25, + "seed": 1959541340, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646998490056, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "update V's power", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "update V's power" + }, + { + "id": "WXzZGFSNUEGRrF93YWfRx", + "type": "text", + "x": 1605.0464573007043, + "y": 2040.7831490120375, + "width": 293, + "height": 25, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 948907054, + "version": 184, + "versionNonce": 79284654, + "isDeleted": false, + "boundElements": null, + "updated": 1646998572152, + "link": null, + "text": "request Slash(V, HtoVSC[Hc1])", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "request Slash(V, HtoVSC[Hc1])" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.png new file mode 100644 index 000000000..8534d5674 Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.excalidraw new file mode 100644 index 000000000..940adcafc --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.excalidraw @@ -0,0 +1,1661 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 2837, + "versionNonce": 965340827, + "isDeleted": false, + "id": "62Yt6MeweG9N-ggINnoIf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 907.6511117600413, + "y": 5030.324182124006, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 390.16666666666634, + "height": 168.34126984126968, + "seed": 2045471701, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103271356, + "link": null + }, + { + "type": "rectangle", + "version": 2287, + "versionNonce": 454151494, + "isDeleted": false, + "id": "-1fHuzFIcWdo4pLFPrcu7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 984.4731465945056, + "y": 5073.193229743054, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 300, + "height": 110, + "seed": 2108794875, + "groupIds": [ + "99ydYVD5vvH65vuufG0Wv" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "id": "W2uPzsED7tDrwRJZQrV1T", + "type": "text" + }, + { + "type": "text", + "id": "W2uPzsED7tDrwRJZQrV1T" + } + ], + "updated": 1645816545687, + "link": null + }, + { + "type": "text", + "version": 2435, + "versionNonce": 1263719322, + "isDeleted": false, + "id": "W2uPzsED7tDrwRJZQrV1T", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 989.4731465945056, + "y": 5090.693229743054, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 290, + "height": 75, + "seed": 765012277, + "groupIds": [ + "99ydYVD5vvH65vuufG0Wv" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816549808, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- provide VSC1\n- VSCtoH[VSC1.id] := Hp1 + 1 ", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "-1fHuzFIcWdo4pLFPrcu7", + "originalText": "EndBlock\n- provide VSC1\n- VSCtoH[VSC1.id] := Hp1 + 1 " + }, + { + "type": "text", + "version": 1384, + "versionNonce": 348557877, + "isDeleted": false, + "id": "E6CeNc4P-6BSf8ozSW8TU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 918.7403974743271, + "y": 5040.417436092261, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1926295707, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103204661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp1", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp1" + }, + { + "type": "arrow", + "version": 2464, + "versionNonce": 2057876987, + "isDeleted": false, + "id": "cXxMrIS5bJqBIcnvcsjjy", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1334.6677848860563, + "y": 5183.186288924198, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 92.50326616584789, + "height": 1.2513122634102274, + "seed": 325597845, + "groupIds": [ + "I1Ed_dtSoESPK0KEygHw1" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1644948503913, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 92.50326616584789, + -1.2513122634102274 + ] + ] + }, + { + "type": "text", + "version": 1062, + "versionNonce": 1776417589, + "isDeleted": false, + "id": "CBELU9TME1J6PtfJ3TJHw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1320.2281899972177, + "y": 5140.183890254825, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 119, + "height": 25, + "seed": 1648239931, + "groupIds": [ + "I1Ed_dtSoESPK0KEygHw1" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1644948503913, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-1" + }, + { + "type": "rectangle", + "version": 3059, + "versionNonce": 1554198261, + "isDeleted": false, + "id": "No1W5o5O4PpPljGn9CEwz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1465.6686661876934, + "y": 5169.846588667523, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 372.119047619048, + "height": 184.0555555555555, + "seed": 68034549, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103152506, + "link": null + }, + { + "type": "rectangle", + "version": 2414, + "versionNonce": 1123039765, + "isDeleted": false, + "id": "I-j-k0NQxt5NOw6eGqehh", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1479.0978438793, + "y": 5235.9180172389515, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 285.00000000000006, + "height": 110, + "seed": 593216987, + "groupIds": [ + "T1BKmx5mYFD-4DOophhvO" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "id": "cAQkbVPZOpkElVNE8Kqn2", + "type": "text" + }, + { + "type": "text", + "id": "cAQkbVPZOpkElVNE8Kqn2" + } + ], + "updated": 1645103123299, + "link": null + }, + { + "type": "text", + "version": 2538, + "versionNonce": 735075418, + "isDeleted": false, + "id": "cAQkbVPZOpkElVNE8Kqn2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1484.0978438793, + "y": 5253.4180172389515, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 275, + "height": 75, + "seed": 630217045, + "groupIds": [ + "T1BKmx5mYFD-4DOophhvO" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816576806, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- apply VSC1\n- HtoVSC[Hc1 + 1] := VSC1.id", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "I-j-k0NQxt5NOw6eGqehh", + "originalText": "EndBlock\n- apply VSC1\n- HtoVSC[Hc1 + 1] := VSC1.id" + }, + { + "type": "text", + "version": 1632, + "versionNonce": 1007559509, + "isDeleted": false, + "id": "3oZfSAsXDf5sWpf01s4pI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1782.98414237817, + "y": 5172.166033111967, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 2101105275, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103156577, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc1", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc1" + }, + { + "type": "text", + "version": 2421, + "versionNonce": 1898682427, + "isDeleted": false, + "id": "19WoaZ7J-S1If0NfPs9PH", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1484.3948566638837, + "y": 5188.541033111967, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 25, + "seed": 1095001781, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1644948639110, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "receive VSC1", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "receive VSC1" + }, + { + "type": "text", + "version": 984, + "versionNonce": 911500597, + "isDeleted": false, + "id": "i-n6SyZpNPXPUJu9taI5s", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1089.7313175452955, + "y": 4947.662064857999, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 616, + "height": 35, + "seed": 815942427, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103108298, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "Mapping consumer heights to provider heights", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Mapping consumer heights to provider heights" + }, + { + "type": "text", + "version": 1441, + "versionNonce": 1850382235, + "isDeleted": false, + "id": "U5v5aBN1bBklzL2e_E3Qh", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 913.3821111960893, + "y": 4999.713652159587, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 201, + "height": 25, + "seed": 1506789397, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103204661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider CCV Module" + }, + { + "type": "text", + "version": 1796, + "versionNonce": 849408123, + "isDeleted": false, + "id": "cxrPxyXpJAc0rH5HBCRkX", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1470.866238180216, + "y": 5138.110477556412, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 210, + "height": 25, + "seed": 1107308475, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645025980238, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer CCV Module" + }, + { + "type": "rectangle", + "version": 3211, + "versionNonce": 154302235, + "isDeleted": false, + "id": "kUudVyZSNvGqQYifXHGGh", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1466.8146508786285, + "y": 5385.3128585087925, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 373.11904761904765, + "height": 129.7698412698417, + "seed": 19398005, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103148937, + "link": null + }, + { + "type": "rectangle", + "version": 2509, + "versionNonce": 1493429, + "isDeleted": false, + "id": "rXsCSaTB72BKPYUmggGQY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1479.2438285702356, + "y": 5414.241429937365, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 290.0000000000001, + "height": 85, + "seed": 58228827, + "groupIds": [ + "51DYqIRaI9heMJM5SgRPU" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "id": "rpdi-BunExE9XZbf1DVUP", + "type": "text" + }, + { + "type": "text", + "id": "rpdi-BunExE9XZbf1DVUP" + } + ], + "updated": 1645103136093, + "link": null + }, + { + "type": "text", + "version": 2635, + "versionNonce": 255941446, + "isDeleted": false, + "id": "rpdi-BunExE9XZbf1DVUP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1484.2438285702356, + "y": 5431.741429937365, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 280, + "height": 75, + "seed": 1855096533, + "groupIds": [ + "51DYqIRaI9heMJM5SgRPU" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816584697, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- HtoVSC[Hc2 + 1] := VSC1.id", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "rXsCSaTB72BKPYUmggGQY", + "originalText": "EndBlock\n- HtoVSC[Hc2 + 1] := VSC1.id" + }, + { + "type": "text", + "version": 1750, + "versionNonce": 1257390005, + "isDeleted": false, + "id": "Fe-cxg4fKpsT136FN6Qzn", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1785.1301270691047, + "y": 5389.489445810381, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1591590139, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103142648, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc2", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc2" + }, + { + "type": "rectangle", + "version": 2863, + "versionNonce": 1773168277, + "isDeleted": false, + "id": "Tr2B0fvNTq7R29rb6VFGS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 905.5856355695652, + "y": 5314.027144223079, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 393.83333333333303, + "height": 168.34126984126968, + "seed": 1420092469, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103260214, + "link": null + }, + { + "type": "rectangle", + "version": 2371, + "versionNonce": 2094327803, + "isDeleted": false, + "id": "PMQGUy1YOdyiI8lgmIEiG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 982.407670404029, + "y": 5357.896191842126, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 303.33333333333337, + "height": 110, + "seed": 1605526939, + "groupIds": [ + "N6hgWfxNSZpIjH1COoQX1" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "id": "SNoe2XrPwmu5wOZWdd3nR", + "type": "text" + }, + { + "type": "text", + "id": "SNoe2XrPwmu5wOZWdd3nR" + } + ], + "updated": 1645103248439, + "link": null + }, + { + "type": "text", + "version": 2520, + "versionNonce": 977917978, + "isDeleted": false, + "id": "SNoe2XrPwmu5wOZWdd3nR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 987.407670404029, + "y": 5375.396191842126, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 293, + "height": 100, + "seed": 2000983445, + "groupIds": [ + "N6hgWfxNSZpIjH1COoQX1" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816558928, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- provide VSC2\n- VSCtoH[VSC2.id] := Hp2 + 1\n", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "PMQGUy1YOdyiI8lgmIEiG", + "originalText": "EndBlock\n- provide VSC2\n- VSCtoH[VSC2.id] := Hp2 + 1 " + }, + { + "type": "text", + "version": 1446, + "versionNonce": 198683867, + "isDeleted": false, + "id": "ScFnW2Jx_OZLAciQ4_FIW", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 916.6749212838505, + "y": 5324.120398191333, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 2099837499, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103204661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp2", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp2" + }, + { + "type": "arrow", + "version": 2525, + "versionNonce": 1865653877, + "isDeleted": false, + "id": "lw6S8rWrOfXpLFOCnJpvh", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1332.6023086955797, + "y": 5468.317822451842, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 92.50326616584789, + "height": 1.2513122634102274, + "seed": 27728629, + "groupIds": [ + "pIcEEnE-tG25_rcW4Tqbs" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1644948503914, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 92.50326616584789, + -1.2513122634102274 + ] + ] + }, + { + "type": "text", + "version": 1125, + "versionNonce": 1438487707, + "isDeleted": false, + "id": "gBLwsoJXj_hprEaAnsQ1P", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1314.162713806741, + "y": 5425.315423782469, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 25, + "seed": 606337755, + "groupIds": [ + "pIcEEnE-tG25_rcW4Tqbs" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1644948503914, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-2" + }, + { + "type": "rectangle", + "version": 2936, + "versionNonce": 1648125013, + "isDeleted": false, + "id": "gQmWRjeS-ocYAYaflLEgA", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 908.8713498552792, + "y": 5529.3128585087925, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 390.83333333333314, + "height": 168.34126984126968, + "seed": 475133013, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103299246, + "link": null + }, + { + "type": "rectangle", + "version": 2389, + "versionNonce": 283315654, + "isDeleted": false, + "id": "dokEAn1FQ_oVlBA8J7ItM", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 981.6933846897432, + "y": 5572.18190612784, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 302.44444444444457, + "height": 110, + "seed": 20309883, + "groupIds": [ + "n6z4skjXjB172Ld2SykcH" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "id": "JkqonPURMZvYfLdV_1F7j", + "type": "text" + }, + { + "type": "text", + "id": "JkqonPURMZvYfLdV_1F7j" + } + ], + "updated": 1645816561041, + "link": null + }, + { + "type": "text", + "version": 2539, + "versionNonce": 1112767642, + "isDeleted": false, + "id": "JkqonPURMZvYfLdV_1F7j", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 986.6933846897432, + "y": 5589.68190612784, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 292, + "height": 100, + "seed": 1125818805, + "groupIds": [ + "n6z4skjXjB172Ld2SykcH" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816565864, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- provide VSC3\n- VSCtoH[VSC3.id] := Hp3 + 1\n", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "dokEAn1FQ_oVlBA8J7ItM", + "originalText": "EndBlock\n- provide VSC3\n- VSCtoH[VSC3.id] := Hp3 + 1 " + }, + { + "type": "text", + "version": 1526, + "versionNonce": 1519415835, + "isDeleted": false, + "id": "4YehNfHqd3bVc0R21JU7D", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 918.9606355695645, + "y": 5538.406112477047, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 178339867, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103204661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp3", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp3" + }, + { + "type": "arrow", + "version": 2603, + "versionNonce": 1398862779, + "isDeleted": false, + "id": "vDGT6MZoRqrttkMOjZWFy", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1334.888022981294, + "y": 5682.603536737557, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 92.50326616584789, + "height": 1.2513122634102274, + "seed": 1529258773, + "groupIds": [ + "be6eOt5A0GPdwHwuPmwqF" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1644948503914, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 92.50326616584789, + -1.2513122634102274 + ] + ] + }, + { + "type": "text", + "version": 1205, + "versionNonce": 41456117, + "isDeleted": false, + "id": "lmLsw4wlozylYSiHWv8Bj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1316.4484280924553, + "y": 5639.601138068183, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 25, + "seed": 1247315131, + "groupIds": [ + "be6eOt5A0GPdwHwuPmwqF" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1644948503914, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-3", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-3" + }, + { + "type": "rectangle", + "version": 3227, + "versionNonce": 1617677147, + "isDeleted": false, + "id": "cRlMLHw5bynb5zCrfYJ7P", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1466.9575080214863, + "y": 5636.455715651651, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 374.1190476190478, + "height": 230.48412698412702, + "seed": 149649525, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1645103174042, + "link": null + }, + { + "type": "rectangle", + "version": 2565, + "versionNonce": 1697772853, + "isDeleted": false, + "id": "wui2IuqDrnmdzga3MFffG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1483.243828570236, + "y": 5746.812858508794, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 315, + "height": 103.57142857142843, + "seed": 1744713051, + "groupIds": [ + "b9iSJpY4i7SIaYvj3lPVr" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "id": "1bmuay5KcLdBGV2XpFahr", + "type": "text" + }, + { + "type": "text", + "id": "1bmuay5KcLdBGV2XpFahr" + } + ], + "updated": 1645025812420, + "link": null + }, + { + "type": "text", + "version": 2705, + "versionNonce": 1085376282, + "isDeleted": false, + "id": "1bmuay5KcLdBGV2XpFahr", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1488.243828570236, + "y": 5761.098572794508, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 305, + "height": 75, + "seed": 1177461205, + "groupIds": [ + "b9iSJpY4i7SIaYvj3lPVr" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645816592497, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- apply aggregate(VSC2,VSC3)\n- HtoVSC[Hc3 + 1] := VSC3.id", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "wui2IuqDrnmdzga3MFffG", + "originalText": "EndBlock\n- apply aggregate(VSC2,VSC3)\n- HtoVSC[Hc3 + 1] := VSC3.id" + }, + { + "type": "text", + "version": 1686, + "versionNonce": 1345476949, + "isDeleted": false, + "id": "UhygML5dIR0UtW1cF-vNV", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1784.2729842119625, + "y": 5641.7751600960955, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1927598587, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645103177428, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc3", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc3" + }, + { + "type": "text", + "version": 2482, + "versionNonce": 1963563323, + "isDeleted": false, + "id": "5mV4y7gVFN-4cXn883mq0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1485.6836984976762, + "y": 5655.1501600960955, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 25, + "seed": 939892533, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645025812420, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "receive VSC2", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "receive VSC2" + }, + { + "type": "text", + "version": 2511, + "versionNonce": 1826876405, + "isDeleted": false, + "id": "juYb5ZBjHocY6Dbqx0CDO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1488.0170318310097, + "y": 5698.840636286572, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 126, + "height": 25, + "seed": 1812912795, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645025812420, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "receive VSC3", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "receive VSC3" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.png new file mode 100644 index 000000000..bfbc0987c Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.excalidraw new file mode 100644 index 000000000..4c7c61ca8 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.excalidraw @@ -0,0 +1,2517 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 1719, + "versionNonce": 106411363, + "isDeleted": false, + "id": "VyRoLp37OULOh8PtwSL1o", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 322.05701296942993, + "y": 783.9233360652088, + "strokeColor": "#ced4da", + "backgroundColor": "#ced4da", + "width": 1247.666666666667, + "height": 187.4444444444444, + "seed": 1900272787, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + } + ], + "updated": 1648718665013, + "link": null + }, + { + "type": "rectangle", + "version": 1518, + "versionNonce": 409607789, + "isDeleted": false, + "id": "bV3e1QXlGeho4mNT0Md4J", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 323.168124080541, + "y": 652.8122249540979, + "strokeColor": "#ced4da", + "backgroundColor": "#ced4da", + "width": 1245.5555555555554, + "height": 112.99999999999996, + "seed": 524846941, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "rectangle", + "version": 1426, + "versionNonce": 295635683, + "isDeleted": false, + "id": "cIdDFggUL2V75qBzn7_1U", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 325.7236796360967, + "y": 517.3677805096532, + "strokeColor": "#ced4da", + "backgroundColor": "#ced4da", + "width": 1241.11111111111, + "height": 112.99999999999996, + "seed": 602414589, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "text", + "version": 1009, + "versionNonce": 601213133, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 733.3333333333333, + "y": 363.55555555555554, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 377, + "height": 36, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "CCV - Channel Initialization", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV - Channel Initialization" + }, + { + "type": "text", + "version": 508, + "versionNonce": 65123971, + "isDeleted": false, + "id": "ghfMBQkamou-QJWwVrzMO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 355.88888888888886, + "y": 400.5, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 138, + "height": 26, + "seed": 1747022505, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1029, + "versionNonce": 1830627117, + "isDeleted": false, + "id": "ONYRFM5fo0s39BeH4ty3j", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1115.333333333333, + "y": 481.8888888888889, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 148, + "height": 26, + "seed": 129325673, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chain" + }, + { + "type": "diamond", + "version": 693, + "versionNonce": 1544416803, + "isDeleted": false, + "id": "D9UpDlJvj-vqduCyp6YiL", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 892.3095382219559, + "y": 679.2011138429862, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 84.27272727272718, + "height": 71.99999999999996, + "seed": 1864416436, + "groupIds": [ + "HpIe0q_ivXIeva3ZeZcXq" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "text", + "version": 613, + "versionNonce": 648657293, + "isDeleted": false, + "id": "olDFMzwulEulDGtmwqPUT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 904.9913564037735, + "y": 704.5647502066226, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 58.90909090909091, + "height": 21.272727272727266, + "seed": 856808204, + "groupIds": [ + "HpIe0q_ivXIeva3ZeZcXq" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 16.363636363636367, + "fontFamily": 1, + "text": "Relayer", + "baseline": 14.272727272727266, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Relayer" + }, + { + "type": "arrow", + "version": 2983, + "versionNonce": 1024602563, + "isDeleted": false, + "id": "umXKeqaL3A2gsELJxrAno", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 979.3018074865438, + "y": 716.4013836813763, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 122.34783859303411, + "height": 0.13529418971859286, + "seed": 671433780, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "startBinding": { + "elementId": "D9UpDlJvj-vqduCyp6YiL", + "gap": 2.9726345773475673, + "focus": 0.03196298231576972 + }, + "endBinding": { + "elementId": "Li4WakMROOrh4VO9QnPFJ", + "gap": 5.796255778740726, + "focus": 0.36269934220064703 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 122.34783859303411, + 0.13529418971859286 + ] + ] + }, + { + "type": "arrow", + "version": 2921, + "versionNonce": 2041905133, + "isDeleted": false, + "id": "DURyamuWvIhE5o-GLqnvp", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 892.3033491011067, + "y": 719.0079234494531, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 127.11210337471994, + "height": 1.3074457047832766, + "seed": 1573053876, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "startBinding": { + "elementId": "olDFMzwulEulDGtmwqPUT", + "gap": 12.688007302666689, + "focus": -0.3959249210105361 + }, + "endBinding": { + "elementId": "8j6p54tqGlb2RxbOlwOCj", + "gap": 10.412010534734593, + "focus": -0.195742017137245 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -127.11210337471994, + -1.3074457047832766 + ] + ] + }, + { + "type": "text", + "version": 1760, + "versionNonce": 1745682787, + "isDeleted": false, + "id": "BfihjIK4S9ZseoXjeT71N", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 833.4459018583196, + "y": 661.2011138429866, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 206, + "height": 26, + "seed": 1202279692, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "connection handshake", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "connection handshake" + }, + { + "type": "rectangle", + "version": 599, + "versionNonce": 742947405, + "isDeleted": false, + "id": "8j6p54tqGlb2RxbOlwOCj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 346.668124080541, + "y": 435.978891620764, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 408.1111111111111, + "height": 698.3333333333335, + "seed": 38506771, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "rectangle", + "version": 736, + "versionNonce": 1984748803, + "isDeleted": false, + "id": "Li4WakMROOrh4VO9QnPFJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1107.4459018583188, + "y": 519.0900027318751, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 382.1111111111107, + "height": 620.5555555555559, + "seed": 1423042963, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "Hg015OniyGFjM7QYWPufU", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "rectangle", + "version": 2364, + "versionNonce": 121481389, + "isDeleted": false, + "id": "cN8JVC0YU7ylsJMNyoLMx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1283.4459018583188, + "y": 554.2011138429866, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 193.00000000000009, + "height": 557.7777777777777, + "seed": 1979822931, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "dXiPD3WzFtcIXoXAUQVpo", + "type": "arrow" + }, + { + "id": "dyJw9z0fJ3VE34NAIchq_", + "type": "arrow" + }, + { + "id": "0imTdwpoy104tRk4pp9Cf", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null + }, + { + "type": "text", + "version": 984, + "versionNonce": 1397769379, + "isDeleted": false, + "id": "Iw9eosLogOHYo9M8Jsbr3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1317.4459018583188, + "y": 528.2011138429866, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 378901469, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "text", + "version": 2073, + "versionNonce": 2084440845, + "isDeleted": false, + "id": "QU6RqfKS-_y9s-kS2v306", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1294.612568524986, + "y": 576.3122249540977, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 65, + "height": 26, + "seed": 1163898717, + "groupIds": [ + "ajix7t8vF1k67Cs7w6vm6" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "create", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "create" + }, + { + "type": "text", + "version": 2193, + "versionNonce": 1992669251, + "isDeleted": false, + "id": "ClT976yNQ_fMatiXU52On", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1368.112568524986, + "y": 576.3122249540977, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 52, + "height": 26, + "seed": 87769331, + "groupIds": [ + "ajix7t8vF1k67Cs7w6vm6" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "client", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "client" + }, + { + "type": "arrow", + "version": 3841, + "versionNonce": 197337453, + "isDeleted": false, + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 573.0773727047458, + "y": 560.5201044659368, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 526.6257709231932, + "height": 12.692037475908023, + "seed": 1757145171, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658299, + "link": null, + "startBinding": { + "elementId": "fatyAFozygc0HN-v5nRU0", + "gap": 13.298137513093426, + "focus": -0.7510735329284931 + }, + "endBinding": { + "elementId": "Li4WakMROOrh4VO9QnPFJ", + "gap": 7.742758230379694, + "focus": 0.7983494108465463 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 526.6257709231932, + 12.692037475908023 + ] + ] + }, + { + "type": "text", + "version": 1679, + "versionNonce": 1586214883, + "isDeleted": false, + "id": "obb5_vEy0bQhgCVmGyg2U", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 822.9165850810258, + "y": 541.8677805096532, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 217, + "height": 26, + "seed": 1080124915, + "groupIds": [ + "3L8N_qI1cIkTh8PTodA99" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "start consumer chain ", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "start consumer chain " + }, + { + "type": "text", + "version": 1779, + "versionNonce": 1796631501, + "isDeleted": false, + "id": "Y8isoLMncxer7kjVuxmbv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 776.4165850810263, + "y": 572.8677805096532, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 132, + "height": 26, + "seed": 2101765821, + "groupIds": [ + "3L8N_qI1cIkTh8PTodA99" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "validator set", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "validator set" + }, + { + "type": "text", + "version": 1783, + "versionNonce": 1219543939, + "isDeleted": false, + "id": "gEd9zB-Zfifc6sNT9rzro", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 942.3054739699143, + "y": 572.7566693985422, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 132, + "height": 26, + "seed": 767963027, + "groupIds": [ + "3L8N_qI1cIkTh8PTodA99" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "validator set", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "validator set" + }, + { + "type": "text", + "version": 1768, + "versionNonce": 1783720493, + "isDeleted": false, + "id": "brcIV75-78ydMBBS09vp6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 916.4165850810258, + "y": 568.8677805096532, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 17, + "height": 36, + "seed": 480544541, + "groupIds": [ + "3L8N_qI1cIkTh8PTodA99" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658299, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "=", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "=" + }, + { + "type": "rectangle", + "version": 2019, + "versionNonce": 762534691, + "isDeleted": false, + "id": "fatyAFozygc0HN-v5nRU0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 376.4459018583192, + "y": 483.3122249540977, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 183.3333333333332, + "height": 613.3333333333335, + "seed": 135825021, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "jz87Jfblhql4prXUNauec", + "type": "arrow" + }, + { + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null + }, + { + "type": "arrow", + "version": 2906, + "versionNonce": 442342541, + "isDeleted": false, + "id": "UqXi4k7D7LBkElLUl9bRY", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 263.12712540922803, + "y": 546.9045895841169, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 104.20635802675358, + "height": 2.070126621603208, + "seed": 679224755, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "AH2OVrsDWHqzavMP7Tnh1", + "focus": -1.569688502462398, + "gap": 15.970878263057813 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 104.20635802675358, + -2.070126621603208 + ] + ] + }, + { + "type": "text", + "version": 1493, + "versionNonce": 2034368195, + "isDeleted": false, + "id": "AH2OVrsDWHqzavMP7Tnh1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 141.72367963609685, + "y": 476.863584699456, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 221, + "height": 52, + "seed": 1225294589, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Governance Proposal \n\"spawn consumer chain\"", + "baseline": 44, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Governance Proposal \n\"spawn consumer chain\"" + }, + { + "type": "text", + "version": 1585, + "versionNonce": 854885101, + "isDeleted": false, + "id": "U0Bl8vDZOyZGGb-5ZZTLb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 387.72367963609713, + "y": 543.4233360652089, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 65, + "height": 26, + "seed": 1174218099, + "groupIds": [ + "WKHwDuPMLSCmZygHZrpto" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "create", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "create" + }, + { + "type": "text", + "version": 1665, + "versionNonce": 112930403, + "isDeleted": false, + "id": "OuxN9IY6BSSbtbdmqHSto", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 460.22367963609713, + "y": 543.4233360652089, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 52, + "height": 26, + "seed": 2145935165, + "groupIds": [ + "WKHwDuPMLSCmZygHZrpto" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "client", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "client" + }, + { + "type": "text", + "version": 923, + "versionNonce": 949984589, + "isDeleted": false, + "id": "DqEozYcKYxDC28R2NnxW0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 411.5570129694301, + "y": 446.2011138429867, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 279128861, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "text", + "version": 2068, + "versionNonce": 1487759875, + "isDeleted": false, + "id": "T1izXFIsp7tDrPbX0eIxf", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1499.9736796360964, + "y": 566.3122249540976, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 59, + "height": 26, + "seed": 586769011, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "ICS-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "ICS-2" + }, + { + "type": "text", + "version": 2113, + "versionNonce": 1656253357, + "isDeleted": false, + "id": "t_J1VfmHv9u7EE-WzNnYj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1499.9736796360964, + "y": 695.2011138429867, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 59, + "height": 26, + "seed": 561448477, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "ICS-3", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "ICS-3" + }, + { + "type": "text", + "version": 1955, + "versionNonce": 337064355, + "isDeleted": false, + "id": "6aTTvXXhRp_Om_uUJ18Yj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 864.2434333771513, + "y": 816.9788916207647, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 26, + "seed": 180182749, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "channel handshake", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "channel handshake" + }, + { + "type": "text", + "version": 1077, + "versionNonce": 1097362957, + "isDeleted": false, + "id": "ZUY3S70EAhRzG6opdy45g", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1110.5152089590333, + "y": 792.3373046083263, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 151, + "height": 26, + "seed": 1975458397, + "groupIds": [ + "MKCuh3Ezvdojoiw9C9BJi" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "OnChanOpenInit", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "OnChanOpenInit" + }, + { + "type": "arrow", + "version": 3807, + "versionNonce": 975635779, + "isDeleted": false, + "id": "dyJw9z0fJ3VE34NAIchq_", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1113.8275853573923, + "y": 835.3690346047606, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 159.7789284780024, + "height": 0.8821154837639824, + "seed": 488375795, + "groupIds": [ + "MKCuh3Ezvdojoiw9C9BJi" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "cN8JVC0YU7ylsJMNyoLMx", + "gap": 9.839388022924165, + "focus": -0.002898245662532866 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 159.7789284780024, + -0.8821154837639824 + ] + ] + }, + { + "type": "text", + "version": 942, + "versionNonce": 598287469, + "isDeleted": false, + "id": "OLVnAm75K0c9kLnrUS8a3", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1112.881446312339, + "y": 875.6852488447693, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 148, + "height": 26, + "seed": 1042999091, + "groupIds": [ + "zm2GFhRP96ueQ_yNG_kXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "OnChanOpenAck", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "OnChanOpenAck" + }, + { + "type": "arrow", + "version": 3429, + "versionNonce": 574317795, + "isDeleted": false, + "id": "0imTdwpoy104tRk4pp9Cf", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1114.693822710698, + "y": 918.7169788412034, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 159.18843185701462, + "height": 0.4104277873721003, + "seed": 1002477949, + "groupIds": [ + "zm2GFhRP96ueQ_yNG_kXo" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "cN8JVC0YU7ylsJMNyoLMx", + "gap": 9.563647290606246, + "focus": -0.3092053337297252 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 159.18843185701462, + 0.4104277873721003 + ] + ] + }, + { + "type": "text", + "version": 883, + "versionNonce": 1027870413, + "isDeleted": false, + "id": "1i9SM2FmlaLGLKGuMadr3", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 566.4522437933846, + "y": 899.8135754416973, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 184, + "height": 26, + "seed": 23310525, + "groupIds": [ + "CNZ2bx0Kmyw6NZbWgff33" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "OnChanOpenConfirm", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "OnChanOpenConfirm" + }, + { + "type": "arrow", + "version": 3211, + "versionNonce": 870502531, + "isDeleted": false, + "id": "jz87Jfblhql4prXUNauec", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 749.1827595896756, + "y": 943.83156341232, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 178.93092685289037, + "height": 1.1889953727586544, + "seed": 2088404371, + "groupIds": [ + "CNZ2bx0Kmyw6NZbWgff33" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "fatyAFozygc0HN-v5nRU0", + "focus": 0.4946206816622181, + "gap": 10.472597545132885 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -178.93092685289037, + -1.1889953727586544 + ] + ] + }, + { + "type": "text", + "version": 904, + "versionNonce": 215133485, + "isDeleted": false, + "id": "tFHjTvU-Pd7PxTc9LTr4w", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 596.945901858319, + "y": 815.5254531910084, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 149, + "height": 26, + "seed": 19313843, + "groupIds": [ + "vXfReGIEP1cvs4DENwZ3s" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "OnChanOpenTry", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "OnChanOpenTry" + }, + { + "type": "arrow", + "version": 3247, + "versionNonce": 1625016355, + "isDeleted": false, + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 753.0653065434987, + "y": 859.5434411616313, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 178.69352318632787, + "height": 2.0139876494251894, + "seed": 290612221, + "groupIds": [ + "vXfReGIEP1cvs4DENwZ3s" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "fatyAFozygc0HN-v5nRU0", + "focus": 0.21564184502015712, + "gap": 14.592548165518451 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -178.69352318632787, + -2.0139876494251894 + ] + ] + }, + { + "type": "text", + "version": 1097, + "versionNonce": 29261709, + "isDeleted": false, + "id": "NMo9QrIPRXbhU3R-JdTPp", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1117.4966157758395, + "y": 532.240804400325, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 109.23098275619242, + "height": 25.818232287827296, + "seed": 1048478237, + "groupIds": [ + "qkwovs2kx-e3xwC2tuyLC" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 19.860178682944078, + "fontFamily": 1, + "text": "InitGenesis", + "baseline": 17.818232287827296, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "InitGenesis" + }, + { + "type": "arrow", + "version": 3865, + "versionNonce": 1595198403, + "isDeleted": false, + "id": "dXiPD3WzFtcIXoXAUQVpo", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1111.360489377364, + "y": 574.978794786868, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 159.2604262870193, + "height": 1.7259264495249909, + "seed": 1345845811, + "groupIds": [ + "qkwovs2kx-e3xwC2tuyLC" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": null, + "endBinding": { + "elementId": "cN8JVC0YU7ylsJMNyoLMx", + "gap": 12.824986193935452, + "focus": 0.9324386355587645 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 159.2604262870193, + -1.7259264495249909 + ] + ] + }, + { + "type": "diamond", + "version": 949, + "versionNonce": 1648428525, + "isDeleted": false, + "id": "ufedJ6N2PtgoNmILgLeR9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 892.7539826664, + "y": 843.3122249540979, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 84.27272727272718, + "height": 71.99999999999996, + "seed": 1428807773, + "groupIds": [ + "IcSLxZ0ZPqcKuPbEB_1Pa" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null + }, + { + "type": "text", + "version": 872, + "versionNonce": 581720931, + "isDeleted": false, + "id": "s7XdvhPQZXbsLet4haeHa", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 905.4358008482176, + "y": 868.6758613177344, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 58.90909090909091, + "height": 21.272727272727266, + "seed": 1395171315, + "groupIds": [ + "IcSLxZ0ZPqcKuPbEB_1Pa" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 16.363636363636367, + "fontFamily": 1, + "text": "Relayer", + "baseline": 14.272727272727266, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": null, + "originalText": "Relayer" + }, + { + "type": "arrow", + "version": 3243, + "versionNonce": 1902362701, + "isDeleted": false, + "id": "1qXvD7xEgjTf4VUM5wDV3", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 978.8509683779258, + "y": 880.6164419465526, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 123.14836393048347, + "height": 2.306473690228586, + "seed": 1799383101, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": { + "elementId": "s7XdvhPQZXbsLet4haeHa", + "gap": 14.506076620617439, + "focus": 0.04298058670290918 + }, + "endBinding": { + "elementId": "Li4WakMROOrh4VO9QnPFJ", + "gap": 5.446569549909378, + "focus": -0.18233773650121993 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 123.14836393048347, + 2.306473690228586 + ] + ] + }, + { + "type": "arrow", + "version": 3195, + "versionNonce": 401667843, + "isDeleted": false, + "id": "gMMtc7H_hFXaSquI_JbUz", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 891.4192255211542, + "y": 879.8675078950861, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 128.6227925647902, + "height": 1.7720335439950077, + "seed": 1850003037, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": { + "elementId": "s7XdvhPQZXbsLet4haeHa", + "gap": 14.016575327063348, + "focus": -0.016408382124069115 + }, + "endBinding": { + "elementId": "8j6p54tqGlb2RxbOlwOCj", + "gap": 8.017197764711954, + "focus": 0.28650989237142727 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -128.6227925647902, + 1.7720335439950077 + ] + ] + }, + { + "type": "text", + "version": 2127, + "versionNonce": 1426075309, + "isDeleted": false, + "id": "ZzAiVIq7d_EX6jT-x-V8F", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1500.4736796360964, + "y": 856.3122249540979, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 58, + "height": 26, + "seed": 11980573, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "ICS-4", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "ICS-4" + }, + { + "type": "text", + "version": 2740, + "versionNonce": 492904099, + "isDeleted": false, + "id": "0rLEyoXAuW-fiLkQc16EL", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1294.612568524986, + "y": 1031.5344471763203, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 139, + "height": 50, + "seed": 1106024147, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV channel is\nestablished", + "baseline": 43, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV channel is\nestablished" + }, + { + "type": "arrow", + "version": 1583, + "versionNonce": 1002426637, + "isDeleted": false, + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 564.9265124039028, + "y": 1005.6177642585774, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 717.1644795672581, + "height": 0.00005507198477516795, + "seed": 618800925, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": { + "elementId": "fatyAFozygc0HN-v5nRU0", + "gap": 5.147277212250443, + "focus": 0.703170244964692 + }, + "endBinding": { + "elementId": "cN8JVC0YU7ylsJMNyoLMx", + "gap": 1.354909887157832, + "focus": -0.618625198886333 + }, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 717.1644795672581, + -0.00005507198477516795 + ] + ] + }, + { + "type": "arrow", + "version": 1642, + "versionNonce": 1034637891, + "isDeleted": false, + "id": "qUiA0J-sfT84YpVQWlEot", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 569.3761222807636, + "y": 1038.8648760777369, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 704.8602749570216, + "height": 20.167457786461, + "seed": 11275571, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "startBinding": { + "elementId": "fatyAFozygc0HN-v5nRU0", + "gap": 9.59688708911132, + "focus": 0.7953347606778761 + }, + "endBinding": { + "elementId": "cN8JVC0YU7ylsJMNyoLMx", + "gap": 9.209504620533616, + "focus": -0.812948462577421 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 704.8602749570216, + 20.167457786461 + ] + ] + }, + { + "type": "text", + "version": 830, + "versionNonce": 1125918573, + "isDeleted": false, + "id": "EbcfOtMt-Y6UtduNdcfzz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 767.112568524986, + "y": 1059.6455582874312, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 160, + "height": 26, + "seed": 1448330877, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "first VSCPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "first VSCPacket" + }, + { + "type": "text", + "version": 392, + "versionNonce": 699273699, + "isDeleted": false, + "id": "-Xq5mD2Jj21BEPy1zjD4F", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 884.7792351916523, + "y": 974.4233360652095, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 26, + "seed": 1370762163, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Channel", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Channel" + }, + { + "type": "text", + "version": 2499, + "versionNonce": 492745165, + "isDeleted": false, + "id": "HQSTyus42WtiUMx7P8B2w", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1294.612568524986, + "y": 795.1005569214933, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 161, + "height": 75, + "seed": 419778963, + "groupIds": [ + "HoMXcPrQkkxUk2lcjsIgs" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "verify that\nunderlying client \nis ", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "verify that\nunderlying client \nis " + }, + { + "type": "text", + "version": 2656, + "versionNonce": 1920458115, + "isDeleted": false, + "id": "r9Ob2NWj9-BSluAY_s8xJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1320.612568524986, + "y": 847.1005569214933, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 52, + "height": 26, + "seed": 1642104093, + "groupIds": [ + "HoMXcPrQkkxUk2lcjsIgs" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "client", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "client" + }, + { + "type": "text", + "version": 2579, + "versionNonce": 2007035949, + "isDeleted": false, + "id": "JuSJvOu_FnBmNVdp_eRD9", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 387.72367963609713, + "y": 812.1005569214933, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 161, + "height": 75, + "seed": 238396435, + "groupIds": [ + "ty8fZRuUHvndHArhAo-GY" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "verify that\nunderlying client \nis ", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "verify that\nunderlying client \nis " + }, + { + "type": "text", + "version": 2737, + "versionNonce": 54998307, + "isDeleted": false, + "id": "PzxRjY9RfeJDTFHPi-mxg", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 413.72367963609713, + "y": 864.1005569214933, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 52, + "height": 26, + "seed": 1416927901, + "groupIds": [ + "ty8fZRuUHvndHArhAo-GY" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "client", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "client" + }, + { + "type": "text", + "version": 2789, + "versionNonce": 533488269, + "isDeleted": false, + "id": "VLOsPFs0wdBnJa4SDNUYt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 387.72367963609713, + "y": 915.1005569214933, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 139, + "height": 50, + "seed": 1131642451, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV channel is\nestablished", + "baseline": 43, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV channel is\nestablished" + }, + { + "type": "text", + "version": 2933, + "versionNonce": 1535809731, + "isDeleted": false, + "id": "yDlrCkt69Ox28Fd3JSBLU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1293.8486796360967, + "y": 895.9755569214933, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 187, + "height": 75, + "seed": 1470041133, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "MUNWjeP_k1E_jhbGobXH1", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1648718658300, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "init transfer \nchannel handshake \n(ICS-20)", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "init transfer \nchannel handshake \n(ICS-20)" + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.png new file mode 100644 index 000000000..abaa9096d Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.excalidraw new file mode 100644 index 000000000..0151bc205 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.excalidraw @@ -0,0 +1,1228 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "id": "dXGJbtsNjdX6vZM0RiO1T", + "type": "rectangle", + "x": 366, + "y": 496.25, + "width": 41, + "height": 29, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 2017127294, + "version": 106, + "versionNonce": 1870083490, + "isDeleted": false, + "boundElements": [ + { + "id": "Lm4nyf2jtOzfTy2WKx1ry", + "type": "arrow" + }, + { + "id": "2HX-46T1-oqbz1Mc9hw2S", + "type": "arrow" + } + ], + "updated": 1646077161417, + "link": null + }, + { + "type": "rectangle", + "version": 63, + "versionNonce": 1325002110, + "isDeleted": false, + "id": "giy7HVJulxkK5HDVUafCR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 511.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#fa5252", + "width": 41, + "height": 29, + "seed": 1636143522, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "0d1ff2WhpECdZM_G9B2dL", + "type": "arrow" + }, + { + "id": "2HX-46T1-oqbz1Mc9hw2S", + "type": "arrow" + }, + { + "id": "cRZCXc7Ob7Rt09-20pjsQ", + "type": "arrow" + } + ], + "updated": 1646077161417, + "link": null + }, + { + "type": "rectangle", + "version": 119, + "versionNonce": 640420862, + "isDeleted": false, + "id": "PGgh4NbRuMsEPsNitvOe7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 604.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "width": 41, + "height": 29, + "seed": 587616034, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "cRZCXc7Ob7Rt09-20pjsQ", + "type": "arrow" + } + ], + "updated": 1646077253368, + "link": null + }, + { + "id": "FO-6rY7Tmc6PCy_7VvHcN", + "type": "text", + "x": 119, + "y": 390, + "width": 133, + "height": 25, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 2100651682, + "version": 155, + "versionNonce": 2098336674, + "isDeleted": false, + "boundElements": null, + "updated": 1646077127396, + "link": null, + "text": "provider chain", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "provider chain" + }, + { + "type": "arrow", + "version": 449, + "versionNonce": 2031774462, + "isDeleted": false, + "id": "Lm4nyf2jtOzfTy2WKx1ry", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.9158370835549663, + "x": 324.87753769206023, + "y": 451.9621486101987, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80.40773254541557, + "height": 12.045428727381761, + "seed": 526143522, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646076973097, + "link": null, + "startBinding": { + "elementId": "f3rhcRwGwsc5cF6ZHFK1U", + "focus": -0.26362793863884676, + "gap": 6.068468469446316 + }, + "endBinding": { + "elementId": "dXGJbtsNjdX6vZM0RiO1T", + "focus": 0.2905303456986677, + "gap": 4.325154663594503 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 80.40773254541557, + 12.045428727381761 + ] + ] + }, + { + "type": "rectangle", + "version": 155, + "versionNonce": 1034958526, + "isDeleted": false, + "id": "f3rhcRwGwsc5cF6ZHFK1U", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 305.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 41, + "height": 29, + "seed": 1771322750, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Lm4nyf2jtOzfTy2WKx1ry", + "type": "arrow" + }, + { + "id": "kVHmz2iFaAgRy7VJ0HLxb", + "type": "arrow" + } + ], + "updated": 1646077157742, + "link": null + }, + { + "type": "rectangle", + "version": 110, + "versionNonce": 1570905122, + "isDeleted": false, + "id": "JQXAIk3s3ohRpLTk0afD1", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 448.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "#fa5252", + "width": 41, + "height": 29, + "seed": 336765822, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "0d1ff2WhpECdZM_G9B2dL", + "type": "arrow" + }, + { + "id": "kVHmz2iFaAgRy7VJ0HLxb", + "type": "arrow" + } + ], + "updated": 1646077157743, + "link": null + }, + { + "type": "arrow", + "version": 285, + "versionNonce": 668320098, + "isDeleted": false, + "id": "0d1ff2WhpECdZM_G9B2dL", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.9158370835549663, + "x": 469.2794757705825, + "y": 448.36084173002894, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 81.96259899829863, + "height": 14.147356569534566, + "seed": 715544994, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646076838899, + "link": null, + "startBinding": { + "elementId": "JQXAIk3s3ohRpLTk0afD1", + "focus": -0.4270673438242542, + "gap": 3.6957376563468074 + }, + "endBinding": { + "elementId": "giy7HVJulxkK5HDVUafCR", + "focus": 0.28071837566818364, + "gap": 5.684422421410943 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 81.96259899829863, + 14.147356569534566 + ] + ] + }, + { + "type": "rectangle", + "version": 146, + "versionNonce": 117824574, + "isDeleted": false, + "id": "xN2B--65W20EQnnK9zqk4", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 686.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "width": 41, + "height": 29, + "seed": 520560318, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077256534, + "link": null + }, + { + "type": "rectangle", + "version": 168, + "versionNonce": 79406206, + "isDeleted": false, + "id": "QmOH7gGmVbeNry8NY-CF5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 768.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "width": 41, + "height": 29, + "seed": 1284517922, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "aDjtcoHVjozFY7WuJY0yR", + "type": "arrow" + } + ], + "updated": 1646077259418, + "link": null + }, + { + "type": "rectangle", + "version": 170, + "versionNonce": 206386110, + "isDeleted": false, + "id": "2sTlmHj03RqCUvX54nQTm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 565.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "width": 41, + "height": 29, + "seed": 212191074, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "aDjtcoHVjozFY7WuJY0yR", + "type": "arrow" + } + ], + "updated": 1646077249965, + "link": null + }, + { + "type": "arrow", + "version": 655, + "versionNonce": 1972673890, + "isDeleted": false, + "id": "aDjtcoHVjozFY7WuJY0yR", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.9158370835549663, + "x": 614.0734386587635, + "y": 500.30233235763797, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 163.46403792632998, + "height": 95.49037375842022, + "seed": 1707943586, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646076996810, + "link": null, + "startBinding": { + "elementId": "2sTlmHj03RqCUvX54nQTm", + "focus": 0.40404651949226894, + "gap": 3.6785331236621346 + }, + "endBinding": { + "elementId": "QmOH7gGmVbeNry8NY-CF5", + "focus": 0.8311181170846009, + "gap": 6.848349336980618 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 163.46403792632998, + -95.49037375842022 + ] + ] + }, + { + "type": "rectangle", + "version": 188, + "versionNonce": 1499557794, + "isDeleted": false, + "id": "IReRqSBbnbZztnt9Rd6PP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 638.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 41, + "height": 29, + "seed": 131138238, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077243457, + "link": null + }, + { + "type": "rectangle", + "version": 179, + "versionNonce": 1204035390, + "isDeleted": false, + "id": "J0L7vWo7k58u3h-EgFZYO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 708.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 41, + "height": 29, + "seed": 370009698, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077157743, + "link": null + }, + { + "type": "rectangle", + "version": 160, + "versionNonce": 494861218, + "isDeleted": false, + "id": "pIR-13bhdFhlezC9u8eLD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 777.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 41, + "height": 29, + "seed": 2145813154, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077157743, + "link": null + }, + { + "type": "rectangle", + "version": 176, + "versionNonce": 1400361122, + "isDeleted": false, + "id": "S5Xetp1_fDLpeKenxgEpl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 832.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 41, + "height": 29, + "seed": 1978641122, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077226732, + "link": null + }, + { + "type": "rectangle", + "version": 173, + "versionNonce": 288308194, + "isDeleted": false, + "id": "t39A2oiw8FWgi_H03Fd1i", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 895.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#40c057", + "width": 41, + "height": 29, + "seed": 149853538, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "TJmI4fIZLIR63b40ULmAH", + "type": "arrow" + } + ], + "updated": 1646077239499, + "link": null + }, + { + "type": "rectangle", + "version": 158, + "versionNonce": 985237374, + "isDeleted": false, + "id": "d-ddNSH6LMpq3uA2yh0kI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 844.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 41, + "height": 29, + "seed": 1586090082, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "TJmI4fIZLIR63b40ULmAH", + "type": "arrow" + } + ], + "updated": 1646077157743, + "link": null + }, + { + "type": "arrow", + "version": 494, + "versionNonce": 496935202, + "isDeleted": false, + "id": "TJmI4fIZLIR63b40ULmAH", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.9158370835549663, + "x": 861.8739718628682, + "y": 440.4738823475756, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 73.16785906553775, + "height": 22.046516861368502, + "seed": 1346903266, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646076996811, + "link": null, + "startBinding": { + "elementId": "d-ddNSH6LMpq3uA2yh0kI", + "focus": -0.47506714799687233, + "gap": 4.102264548837752 + }, + "endBinding": { + "elementId": "t39A2oiw8FWgi_H03Fd1i", + "focus": 0.1462118275130385, + "gap": 7.441172969995762 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 73.16785906553775, + 22.046516861368502 + ] + ] + }, + { + "type": "rectangle", + "version": 159, + "versionNonce": 389639266, + "isDeleted": false, + "id": "fCVwLr6MRiUMi5yjg2BCP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 956.5, + "y": 496.25, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 41, + "height": 29, + "seed": 1698265954, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077231622, + "link": null + }, + { + "type": "rectangle", + "version": 138, + "versionNonce": 1876004898, + "isDeleted": false, + "id": "cfkjSfrhUWSYi6gAYJynw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 909.5, + "y": 385, + "strokeColor": "#000000", + "backgroundColor": "#fab005", + "width": 41, + "height": 29, + "seed": 938269822, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077235024, + "link": null + }, + { + "type": "text", + "version": 288, + "versionNonce": 1369336382, + "isDeleted": false, + "id": "KFcHQtQ4HSMxl-tDMFmTk", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 311.5, + "y": 443.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 42, + "height": 25, + "seed": 1604739042, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646076972349, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSC1", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSC1" + }, + { + "type": "text", + "version": 292, + "versionNonce": 282378082, + "isDeleted": false, + "id": "BCvm6sdk2bzmPHsPNg8rV", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 517, + "y": 444.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 25, + "seed": 1354420734, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646076838899, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSC2", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSC2" + }, + { + "type": "text", + "version": 260, + "versionNonce": 2134716606, + "isDeleted": false, + "id": "IOJKXj77Mtw2wYY-J8egl", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 705, + "y": 434.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 50, + "height": 25, + "seed": 608588670, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646076996661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSC3", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSC3" + }, + { + "type": "text", + "version": 241, + "versionNonce": 49922594, + "isDeleted": false, + "id": "jNIyXk3mgir_5nfCyHtlq", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 909, + "y": 436.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 49, + "height": 25, + "seed": 1324593634, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646076996661, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSC4", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSC4" + }, + { + "type": "arrow", + "version": 419, + "versionNonce": 1749536354, + "isDeleted": false, + "id": "7Xh5sJZCt--M6HS0iLol7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.25438768430974, + "x": 325.8098335597477, + "y": 329.8859185932823, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.8096700170103759, + "height": 41.59500930334184, + "seed": 42424930, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646077020419, + "link": null, + "startBinding": { + "elementId": "eSzN3tC3e2MVTc49PxUdR", + "focus": -0.33520536080054925, + "gap": 13.369584039732558 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.8096700170103759, + 41.59500930334184 + ] + ] + }, + { + "type": "text", + "version": 413, + "versionNonce": 337859298, + "isDeleted": false, + "id": "eSzN3tC3e2MVTc49PxUdR", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 245.5, + "y": 289.519524154067, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 119, + "height": 25, + "seed": 1799097762, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "7Xh5sJZCt--M6HS0iLol7", + "type": "arrow" + } + ], + "updated": 1646077148172, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-1", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-1" + }, + { + "type": "arrow", + "version": 388, + "versionNonce": 1244962786, + "isDeleted": false, + "id": "D6FMHkxWilLihXdUuF1l5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 465.4336507169435, + "y": 326.23964063810354, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.4289559332560202, + "height": 41.22131105376235, + "seed": 1559910050, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646077017569, + "link": null, + "startBinding": { + "elementId": "34CMnXniITHjgUQkEwWxO", + "focus": -0.003216876081784181, + "gap": 13.700592329969481 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.4289559332560202, + 41.22131105376235 + ] + ] + }, + { + "type": "text", + "version": 433, + "versionNonce": 815350846, + "isDeleted": false, + "id": "34CMnXniITHjgUQkEwWxO", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 401.5, + "y": 289.519524154067, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 25, + "seed": 1198873726, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "D6FMHkxWilLihXdUuF1l5", + "type": "arrow" + } + ], + "updated": 1646077148172, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-2", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-2" + }, + { + "type": "arrow", + "version": 332, + "versionNonce": 74209854, + "isDeleted": false, + "id": "vx1ePYG_g6Niz68an3RX0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 589.4336507169435, + "y": 327.23964063810354, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.4289559332560202, + "height": 41.22131105376235, + "seed": 12318690, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646077141123, + "link": null, + "startBinding": { + "elementId": "WbHIHHbvZbFgZy4t1BRL_", + "focus": 0.5428734128179646, + "gap": 11.700592329969481 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.4289559332560202, + 41.22131105376235 + ] + ] + }, + { + "type": "text", + "version": 403, + "versionNonce": 867870370, + "isDeleted": false, + "id": "WbHIHHbvZbFgZy4t1BRL_", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 560.5, + "y": 289.519524154067, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 128, + "height": 25, + "seed": 1929998142, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "vx1ePYG_g6Niz68an3RX0", + "type": "arrow" + } + ], + "updated": 1646077148172, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-3", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-3" + }, + { + "type": "arrow", + "version": 332, + "versionNonce": 900042658, + "isDeleted": false, + "id": "BD71nC83W4ZTghFu8otbB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 864.4336507169435, + "y": 325.23964063810354, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.4289559332560202, + "height": 41.22131105376235, + "seed": 555091106, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1646077142981, + "link": null, + "startBinding": { + "elementId": "LxjWLi54P0ijxSwaGt3_w", + "focus": 0.31909607184067174, + "gap": 12.700592329969481 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -0.4289559332560202, + 41.22131105376235 + ] + ] + }, + { + "type": "text", + "version": 332, + "versionNonce": 2007108734, + "isDeleted": false, + "id": "LxjWLi54P0ijxSwaGt3_w", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 821.5, + "y": 289.519524154067, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 25, + "seed": 649301630, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "BD71nC83W4ZTghFu8otbB", + "type": "arrow" + } + ], + "updated": 1646077148172, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-4", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-4" + }, + { + "type": "text", + "version": 233, + "versionNonce": 2120715874, + "isDeleted": false, + "id": "uSebukr-eizrDRBECjcYu", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 162.5, + "y": 500.5, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 143, + "height": 25, + "seed": 1143774590, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1646077130915, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "consumer chain", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "consumer chain" + }, + { + "id": "fHJhTCuZjkQbKYo1h-GSG", + "type": "text", + "x": 154, + "y": 229, + "width": 800, + "height": 35, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "#4c6ef5", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "sharp", + "seed": 286155966, + "version": 190, + "versionNonce": 1460853410, + "isDeleted": false, + "boundElements": null, + "updated": 1646077420994, + "link": null, + "text": "Intuition of mapping consumer heights to provider heights ", + "fontSize": 28, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 25, + "containerId": null, + "originalText": "Intuition of mapping consumer heights to provider heights " + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.png new file mode 100644 index 000000000..2cefc6dda Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.excalidraw new file mode 100644 index 000000000..c52be9507 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.excalidraw @@ -0,0 +1,4367 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 2397, + "versionNonce": 829974083, + "isDeleted": false, + "id": "288dISSfHCk2NOu4muYto", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 424.92702425970924, + "y": 1437.7493664453027, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1005.0833333333333, + "height": 169.87698412698418, + "seed": 1089140909, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1642600840865, + "link": null + }, + { + "type": "rectangle", + "version": 2115, + "versionNonce": 1733232131, + "isDeleted": false, + "id": "OfGfoX6AzJGTbsVLECmyB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 423.05202425970924, + "y": 621.3743664453026, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1008.8333333333333, + "height": 305.0555555555555, + "seed": 797809709, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1642600635405, + "link": null + }, + { + "type": "text", + "version": 913, + "versionNonce": 1708840852, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 833.5555555555553, + "y": 344.063492063492, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 481, + "height": 35, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619523356, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "Completion of Unbonding Operations", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Completion of Unbonding Operations" + }, + { + "type": "text", + "version": 1324, + "versionNonce": 462363564, + "isDeleted": false, + "id": "yqi6dzvpzblq17ysowkTo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 431.16839719235065, + "y": 448.03444717631976, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 139, + "height": 25, + "seed": 578772677, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619523356, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1659, + "versionNonce": 2101527828, + "isDeleted": false, + "id": "Y19fC1uuzabCFyV0s97Ip", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1607.2239527479067, + "y": 448.32412971600235, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 159, + "height": 25, + "seed": 1161289003, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619523356, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chains", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chains" + }, + { + "type": "rectangle", + "version": 1759, + "versionNonce": 625632333, + "isDeleted": false, + "id": "io7ctwpVbQY3h06icqEIP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 418.9045083034623, + "y": 486.804922000858, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1012.5833333333331, + "height": 100.05555555555551, + "seed": 1043647324, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + } + ], + "updated": 1642600635406, + "link": null + }, + { + "type": "rectangle", + "version": 2927, + "versionNonce": 1983288067, + "isDeleted": false, + "id": "niGq9B1KH3f2JGEXfsVWR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1082.654508303462, + "y": 457.6660331119692, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 326.3333333333336, + "height": 1533.0833333333328, + "seed": 1857158372, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "jz87Jfblhql4prXUNauec", + "type": "arrow" + }, + { + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + }, + { + "id": "WEyZi3lMqkJ8FhlR5xFl1", + "type": "arrow" + }, + { + "id": "soJdQZVXQySCwfBjVwVtd", + "type": "arrow" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + } + ], + "updated": 1642600635406, + "link": null + }, + { + "type": "text", + "version": 1277, + "versionNonce": 477254317, + "isDeleted": false, + "id": "mKQR2MU2I6RaZxHleDOeo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1181.5711749701286, + "y": 420.33269977863563, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 461936988, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635406, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "rectangle", + "version": 3293, + "versionNonce": 1486043811, + "isDeleted": false, + "id": "ZBGOYMeC4-MdhYaPJ-0IB", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 580.9045083034619, + "y": 456.58269977863574, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 304.33333333333326, + "height": 1531.083333333333, + "seed": 1937775204, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "jz87Jfblhql4prXUNauec", + "type": "arrow" + }, + { + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + }, + { + "id": "WEyZi3lMqkJ8FhlR5xFl1", + "type": "arrow" + }, + { + "id": "soJdQZVXQySCwfBjVwVtd", + "type": "arrow" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + }, + { + "id": "zRzvyJHLJcGNoyUqNi09v", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1642600635406, + "link": null + }, + { + "type": "text", + "version": 1255, + "versionNonce": 424506637, + "isDeleted": false, + "id": "8MWo4aqmMRZ_6M0R-fqTm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 665.321174970128, + "y": 420.24936644530237, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 147, + "height": 25, + "seed": 401616348, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635406, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Staking Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Staking Module" + }, + { + "type": "text", + "version": 1854, + "versionNonce": 1545651469, + "isDeleted": false, + "id": "v3aZhl7kBQN_LlwRZKca8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 656.2882878336204, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 159, + "height": 25, + "seed": 806156493, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "dYJRFcc1PLcSHVaOF3szx", + "type": "arrow" + } + ], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "init undelegate-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "init undelegate-1" + }, + { + "type": "rectangle", + "version": 1107, + "versionNonce": 117677635, + "isDeleted": false, + "id": "mjb-z7j9KAQicoyLxGdMD", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 521.3326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 217.00000000000003, + "height": 43.75, + "seed": 102106061, + "groupIds": [ + "VIocaW0VwoAK-tEMbwF6i" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Ygx86iuovd0TmthLMHcRq", + "type": "text" + }, + { + "id": "Ygx86iuovd0TmthLMHcRq", + "type": "text" + }, + { + "id": "Ygx86iuovd0TmthLMHcRq", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "type": "text", + "id": "Ygx86iuovd0TmthLMHcRq" + } + ], + "updated": 1642600868111, + "link": null + }, + { + "type": "text", + "version": 1079, + "versionNonce": 322870125, + "isDeleted": false, + "id": "Ygx86iuovd0TmthLMHcRq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 611.6064753554905, + "y": 530.7076997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 207.00000000000003, + "height": 25, + "seed": 286698371, + "groupIds": [ + "VIocaW0VwoAK-tEMbwF6i" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "mjb-z7j9KAQicoyLxGdMD", + "originalText": "EndBlock" + }, + { + "type": "rectangle", + "version": 1592, + "versionNonce": 1215885933, + "isDeleted": false, + "id": "bsvuNHc8NDse8ddQcKZVC", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 520.7076997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 282, + "height": 44.99999999999999, + "seed": 171907533, + "groupIds": [ + "gfLFyjEdxp9zQoBw_3SqN" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "gf9fplNPnrE2fF2kM1scl", + "type": "text" + }, + { + "type": "text", + "id": "gf9fplNPnrE2fF2kM1scl" + } + ], + "updated": 1642600919620, + "link": null + }, + { + "type": "text", + "version": 1635, + "versionNonce": 1301772003, + "isDeleted": false, + "id": "gf9fplNPnrE2fF2kM1scl", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1104.9216781417922, + "y": 530.7076997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 272, + "height": 25, + "seed": 271709571, + "groupIds": [ + "gfLFyjEdxp9zQoBw_3SqN" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "bsvuNHc8NDse8ddQcKZVC", + "originalText": "EndBlock" + }, + { + "type": "text", + "version": 1944, + "versionNonce": 317332685, + "isDeleted": false, + "id": "2XMg0yRe96WOesVqiCQQ-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 656.2882878336204, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 220, + "height": 25, + "seed": 1796815331, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "" + }, + { + "type": "arrow", + "version": 2810, + "versionNonce": 239004045, + "isDeleted": false, + "id": "3SeouFV8muGxqHUkL0Vc8", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 918.1530852701657, + "y": 552.5973901947737, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 131.8240708739196, + "height": 1.0224628362805106, + "seed": 626176963, + "groupIds": [ + "vexHwxQT-Qwn1_fQ4WMZu" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635406, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 131.8240708739196, + -1.0224628362805106 + ] + ] + }, + { + "type": "text", + "version": 1647, + "versionNonce": 682099139, + "isDeleted": false, + "id": "qdAEsThxT6FSsrS7Kt4pK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 944.8321512501689, + "y": 509.81800936249795, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 80, + "height": 25, + "seed": 355835373, + "groupIds": [ + "vexHwxQT-Qwn1_fQ4WMZu" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635406, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates" + }, + { + "type": "arrow", + "version": 2888, + "versionNonce": 388247533, + "isDeleted": false, + "id": "JnqmaagVJuwrk_54IKvQ8", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 920.9151937961719, + "y": 680.7060229665822, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 129.0619623479132, + "height": 0.27011154965987316, + "seed": 976668835, + "groupIds": [ + "65A-wNjKwxPx9Z6rx72Qa" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635406, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 129.0619623479132, + -0.27011154965987316 + ] + ] + }, + { + "type": "text", + "version": 1327, + "versionNonce": 379639981, + "isDeleted": false, + "id": "ZhWLObdAQ7DNXYE3H3QBZ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1461.445910951049, + "y": 804.7276573363806, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 119, + "height": 25, + "seed": 1497949645, + "groupIds": [ + "OBrDlmfGyuZF1MjnQMPCx" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-1" + }, + { + "type": "arrow", + "version": 2257, + "versionNonce": 1123554467, + "isDeleted": false, + "id": "jjmd9OK2eou689hzpSx2D", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1464.6319416280771, + "y": 850.1877422208913, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 121.62386851542169, + "height": 1.693510304863139, + "seed": 1752885635, + "groupIds": [ + "OBrDlmfGyuZF1MjnQMPCx" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 121.62386851542169, + -1.693510304863139 + ] + ] + }, + { + "type": "rectangle", + "version": 1846, + "versionNonce": 974970339, + "isDeleted": false, + "id": "zrerEZvkoppdLgVEr-HAR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 1462.9576997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 253.24999999999997, + "height": 124.28571428571442, + "seed": 737507619, + "groupIds": [ + "ac8_hZSpXUKuuvN3hcNoN" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "type": "text" + }, + { + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "type": "text" + }, + { + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "type": "text" + }, + { + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "type": "text" + }, + { + "type": "text", + "id": "ZiI3_vPGpIcZ3QZEd-jZ-" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1642600868111, + "link": null + }, + { + "type": "text", + "version": 1918, + "versionNonce": 590162307, + "isDeleted": false, + "id": "ZiI3_vPGpIcZ3QZEd-jZ-", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 611.6064753554905, + "y": 1475.1005569214929, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 243.24999999999997, + "height": 100, + "seed": 1393843853, + "groupIds": [ + "ac8_hZSpXUKuuvN3hcNoN" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- compute updates-j\n- complete undelegate-1\n- complete redelegate-1", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "zrerEZvkoppdLgVEr-HAR", + "originalText": "EndBlock\n- compute updates-j\n- complete undelegate-1\n- complete redelegate-1" + }, + { + "type": "arrow", + "version": 3017, + "versionNonce": 538595693, + "isDeleted": false, + "id": "s4m9JE4Ws5SNKruUeKciX", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 919.0426513063876, + "y": 867.6329216669907, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 130.99912129944914, + "height": 0.47416060277919314, + "seed": 1145786371, + "groupIds": [ + "yGSu-GF2cmHnrANMW04OV" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 130.99912129944914, + 0.47416060277919314 + ] + ] + }, + { + "type": "text", + "version": 1841, + "versionNonce": 1115654115, + "isDeleted": false, + "id": "PJ7or8MkoB5Ta3Ijgl2nS", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 937.8967677119203, + "y": 826.3501642737743, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 94, + "height": 25, + "seed": 1960043949, + "groupIds": [ + "yGSu-GF2cmHnrANMW04OV" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-1" + }, + { + "type": "rectangle", + "version": 1737, + "versionNonce": 2112660099, + "isDeleted": false, + "id": "xUOhnu2c7zi5RcZBJm9_0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 780.9576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 289.49999999999994, + "height": 135, + "seed": 1594382243, + "groupIds": [ + "t4kjRFeOj_Zv00-6NfpW0" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "type": "text" + }, + { + "type": "text", + "id": "xJ9MQG4krLBiVC1J-n9Cd" + } + ], + "updated": 1642600919620, + "link": null + }, + { + "type": "text", + "version": 1779, + "versionNonce": 512162605, + "isDeleted": false, + "id": "xJ9MQG4krLBiVC1J-n9Cd", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1104.9216781417922, + "y": 798.4576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 279.49999999999994, + "height": 100, + "seed": 906274829, + "groupIds": [ + "t4kjRFeOj_Zv00-6NfpW0" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- VSC1:={vscId, updates-1}\n- provide VSC1\n- vscId++", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "xUOhnu2c7zi5RcZBJm9_0", + "originalText": "EndBlock\n- VSC1:={vscId, updates-1}\n- provide VSC1\n- vscId++" + }, + { + "type": "rectangle", + "version": 1465, + "versionNonce": 1354130477, + "isDeleted": false, + "id": "FWaH8-7qhZ3CCEqeqDGDE", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 816.9576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 217.00000000000003, + "height": 85, + "seed": 402877251, + "groupIds": [ + "UTPDgVuWHHgewtd7yku-H" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "QtScPVLIHX_XpCTGNl19E", + "type": "text" + }, + { + "id": "QtScPVLIHX_XpCTGNl19E", + "type": "text" + }, + { + "id": "QtScPVLIHX_XpCTGNl19E", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "QtScPVLIHX_XpCTGNl19E", + "type": "text" + }, + { + "id": "QtScPVLIHX_XpCTGNl19E", + "type": "text" + }, + { + "type": "text", + "id": "QtScPVLIHX_XpCTGNl19E" + } + ], + "updated": 1642600868111, + "link": null + }, + { + "type": "text", + "version": 1435, + "versionNonce": 124977443, + "isDeleted": false, + "id": "QtScPVLIHX_XpCTGNl19E", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 611.6064753554905, + "y": 834.4576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 207, + "height": 50, + "seed": 1823350381, + "groupIds": [ + "UTPDgVuWHHgewtd7yku-H" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- compute updates-1", + "baseline": 43, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "FWaH8-7qhZ3CCEqeqDGDE", + "originalText": "EndBlock\n- compute updates-1" + }, + { + "type": "diamond", + "version": 1564, + "versionNonce": 901958797, + "isDeleted": false, + "id": "8FSwgT1wTNXMVwek31Zcj", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 253.22826628158566, + "y": 818.4576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 145, + "height": 105, + "seed": 328927971, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "b9turHYT8j_iZlkRmUQJd", + "type": "text" + }, + { + "id": "b9turHYT8j_iZlkRmUQJd", + "type": "text" + }, + { + "id": "b9turHYT8j_iZlkRmUQJd", + "type": "text" + }, + { + "id": "-r0GObbpXNWzCa57TLWTv", + "type": "arrow" + }, + { + "id": "b9turHYT8j_iZlkRmUQJd", + "type": "text" + }, + { + "type": "text", + "id": "b9turHYT8j_iZlkRmUQJd" + } + ], + "updated": 1642600635407, + "link": null + }, + { + "type": "text", + "version": 1521, + "versionNonce": 369610435, + "isDeleted": false, + "id": "b9turHYT8j_iZlkRmUQJd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 258.22826628158566, + "y": 858.4576997786359, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 135, + "height": 25, + "seed": 1335478477, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Tendermint", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "8FSwgT1wTNXMVwek31Zcj", + "originalText": "Tendermint" + }, + { + "type": "arrow", + "version": 3988, + "versionNonce": 171160301, + "isDeleted": false, + "id": "tRsPeghC6Larxxo1-cOHT", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 548.8499010357573, + "y": 872.4379527210932, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 117.80814515172608, + "height": 1.2723534635447322, + "seed": 1717417603, + "groupIds": [ + "QwYvAiHAt3q-R51TmsfOS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -117.80814515172608, + 1.2723534635447322 + ] + ] + }, + { + "type": "text", + "version": 2322, + "versionNonce": 709295715, + "isDeleted": false, + "id": "isS-yd5bGYUz8MEWFM5RH", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 441.0476489368832, + "y": 828.3501642737748, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 94, + "height": 25, + "seed": 6367021, + "groupIds": [ + "QwYvAiHAt3q-R51TmsfOS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-1" + }, + { + "type": "text", + "version": 1406, + "versionNonce": 1570798380, + "isDeleted": false, + "id": "SzCr9Evju7A0-EI2hAVan", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1418.2446702401855, + "y": 1304.2543789965198, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 212, + "height": 25, + "seed": 800354189, + "groupIds": [ + "nKurdQH5Lw4OmdxDJxyCg" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + } + ], + "updated": 1645619661897, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCMaturedPackets-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCMaturedPackets-1" + }, + { + "type": "arrow", + "version": 2228, + "versionNonce": 655957396, + "isDeleted": false, + "id": "qxQQDOIb_6yBAx_VEeb37", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1583.4002884726644, + "y": 1348.8511166031087, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 123.56280714681475, + "height": 0.8260181955356529, + "seed": 666229699, + "groupIds": [ + "nKurdQH5Lw4OmdxDJxyCg" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619661897, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -123.56280714681475, + 0.8260181955356529 + ] + ] + }, + { + "type": "text", + "version": 855, + "versionNonce": 2036282595, + "isDeleted": false, + "id": "dHBZb2RdXqXsUyWx3KiOq", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 467.468690926376, + "y": 527.1521442230803, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 52, + "height": 25, + "seed": 135797549, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block" + }, + { + "type": "rectangle", + "version": 2124, + "versionNonce": 369926275, + "isDeleted": false, + "id": "kdNbiNehK3QVI1DL8BGYt", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 425.5275274313726, + "y": 961.9993664453024, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1006.3333333333335, + "height": 246.30555555555554, + "seed": 618253869, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "M5sZD3idFu959njYfEyeu", + "type": "arrow" + } + ], + "updated": 1642600635407, + "link": null + }, + { + "type": "text", + "version": 1869, + "versionNonce": 504583821, + "isDeleted": false, + "id": "mhqdDomzdSXgWXV-WcaDJ", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 997.1632878336203, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 168, + "height": 25, + "seed": 152254243, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "dYJRFcc1PLcSHVaOF3szx", + "type": "arrow" + } + ], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "init undelegate-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "init undelegate-2" + }, + { + "type": "text", + "version": 1965, + "versionNonce": 769350179, + "isDeleted": false, + "id": "phK7bzOTf8HJPVnfLFghy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 997.1632878336203, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 229, + "height": 25, + "seed": 775520397, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "" + }, + { + "type": "arrow", + "version": 2971, + "versionNonce": 335434900, + "isDeleted": false, + "id": "3NrrQafWyNKIVHetasLgc", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 918.2121255392635, + "y": 1006.0427804953314, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 130.31196234791332, + "height": 0.2711443590825411, + "seed": 210131651, + "groupIds": [ + "cB6bFsaKlgxurLpKAbJKw" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619787666, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 130.31196234791332, + -0.2711443590825411 + ] + ] + }, + { + "type": "text", + "version": 1411, + "versionNonce": 592459245, + "isDeleted": false, + "id": "PLhcueSSD57kWN6Qi-0hy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1461.445910951049, + "y": 1086.6026573363806, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 25, + "seed": 1762921059, + "groupIds": [ + "E8OZCCeBcSVKKnXG7XX_J" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-2" + }, + { + "type": "arrow", + "version": 2336, + "versionNonce": 560474979, + "isDeleted": false, + "id": "hmUXP0GIWwIo13Y3ulP7V", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1468.6319416280767, + "y": 1132.0627422208913, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 121.62386851542169, + "height": 1.693510304863139, + "seed": 1775403341, + "groupIds": [ + "E8OZCCeBcSVKKnXG7XX_J" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 121.62386851542169, + -1.693510304863139 + ] + ] + }, + { + "type": "arrow", + "version": 3146, + "versionNonce": 688713805, + "isDeleted": false, + "id": "jMOzMGNmj6p2YM8NwCj4-", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 920.9214990138784, + "y": 1149.093477787134, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 127.59577676362153, + "height": 0.3613955173641443, + "seed": 864732675, + "groupIds": [ + "STwyOVqEMrli0DcBTproc" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 127.59577676362153, + -0.3613955173641443 + ] + ] + }, + { + "type": "text", + "version": 1942, + "versionNonce": 1857210115, + "isDeleted": false, + "id": "KyCMqbrlIZV3ujG0FLBh0", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 931.8722708835835, + "y": 1106.9751642737742, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 103, + "height": 25, + "seed": 871288749, + "groupIds": [ + "STwyOVqEMrli0DcBTproc" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635407, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-2" + }, + { + "type": "rectangle", + "version": 1822, + "versionNonce": 867765645, + "isDeleted": false, + "id": "RB0NFxq5enBSn_1g0Rs1M", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 1062.8326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 292, + "height": 135, + "seed": 1659440547, + "groupIds": [ + "1Ml5oLQaWc-g3mG6AtEjs" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "id": "zwf74_KbAfyIn5CmMaEpU", + "type": "text" + }, + { + "type": "text", + "id": "zwf74_KbAfyIn5CmMaEpU" + } + ], + "updated": 1642600919620, + "link": null + }, + { + "type": "text", + "version": 1870, + "versionNonce": 1246895555, + "isDeleted": false, + "id": "zwf74_KbAfyIn5CmMaEpU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1104.9216781417922, + "y": 1080.3326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 282, + "height": 100, + "seed": 1714573837, + "groupIds": [ + "1Ml5oLQaWc-g3mG6AtEjs" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- VSC2:={vscId, updates-2}\n- provide VSC2\n- vscId++", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "RB0NFxq5enBSn_1g0Rs1M", + "originalText": "EndBlock\n- VSC2:={vscId, updates-2}\n- provide VSC2\n- vscId++" + }, + { + "type": "rectangle", + "version": 1549, + "versionNonce": 6087875, + "isDeleted": false, + "id": "BWRQRfnJRP2bLO56TV_Xk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 1098.8326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 217.00000000000003, + "height": 85, + "seed": 173891907, + "groupIds": [ + "54R2JrsB_ogK-ZKI5BQYv" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "id": "6n_oBuNMDsal_ABzyahFz", + "type": "text" + }, + { + "type": "text", + "id": "6n_oBuNMDsal_ABzyahFz" + } + ], + "updated": 1642600868111, + "link": null + }, + { + "type": "text", + "version": 1520, + "versionNonce": 1810037997, + "isDeleted": false, + "id": "6n_oBuNMDsal_ABzyahFz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 611.6064753554905, + "y": 1116.3326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 207, + "height": 75, + "seed": 1570146413, + "groupIds": [ + "54R2JrsB_ogK-ZKI5BQYv" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- compute updates-2", + "baseline": 68, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "BWRQRfnJRP2bLO56TV_Xk", + "originalText": "EndBlock\n- compute updates-2" + }, + { + "type": "diamond", + "version": 1648, + "versionNonce": 722687853, + "isDeleted": false, + "id": "JopS_hj-ZXS5fwF8ERp6u", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 253.20376945324915, + "y": 1100.3326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 145, + "height": 105, + "seed": 1397113059, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "MzLtWftrAv0s7667yRuHn", + "type": "text" + }, + { + "id": "MzLtWftrAv0s7667yRuHn", + "type": "text" + }, + { + "id": "MzLtWftrAv0s7667yRuHn", + "type": "text" + }, + { + "id": "-r0GObbpXNWzCa57TLWTv", + "type": "arrow" + }, + { + "id": "MzLtWftrAv0s7667yRuHn", + "type": "text" + }, + { + "id": "MzLtWftrAv0s7667yRuHn", + "type": "text" + }, + { + "type": "text", + "id": "MzLtWftrAv0s7667yRuHn" + } + ], + "updated": 1642600635408, + "link": null + }, + { + "type": "text", + "version": 1604, + "versionNonce": 1140974051, + "isDeleted": false, + "id": "MzLtWftrAv0s7667yRuHn", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 258.20376945324915, + "y": 1140.3326997786357, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 135, + "height": 25, + "seed": 467989197, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Tendermint", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "JopS_hj-ZXS5fwF8ERp6u", + "originalText": "Tendermint" + }, + { + "type": "arrow", + "version": 4224, + "versionNonce": 1592779213, + "isDeleted": false, + "id": "U1GKh2Ic0h0HFt8GEtuaT", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 547.8840752672525, + "y": 1151.2236818704496, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 115.6168162115581, + "height": 0.6116243141882478, + "seed": 926035075, + "groupIds": [ + "ItvOetjnwy_YHQhWlMVXp" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -115.6168162115581, + 0.6116243141882478 + ] + ] + }, + { + "type": "text", + "version": 2427, + "versionNonce": 835825027, + "isDeleted": false, + "id": "zBOyUTJljULnw2kI-Qufe", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 437.77315210854516, + "y": 1106.4751642737747, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 103, + "height": 25, + "seed": 766972205, + "groupIds": [ + "ItvOetjnwy_YHQhWlMVXp" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-2" + }, + { + "type": "arrow", + "version": 4638, + "versionNonce": 1399606211, + "isDeleted": false, + "id": "cFz81tlJ2NMZiYzWVMuf6", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 6.277329793107594, + "x": 596.0928834941102, + "y": 927.8334623501592, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 2.9100524049084697, + "height": 507.68956239314696, + "seed": 134041987, + "groupIds": [ + "CqF-dAVHfY77Yn6VmbWfc" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600877592, + "link": null, + "startBinding": { + "elementId": "OfGfoX6AzJGTbsVLECmyB", + "focus": 0.6599084118084031, + "gap": 1.3993722528743433 + }, + "endBinding": { + "elementId": "zrerEZvkoppdLgVEr-HAR", + "focus": -1.094118517194332, + "gap": 27.43050693890325 + }, + "lastCommittedPoint": null, + "startArrowhead": "bar", + "endArrowhead": "bar", + "points": [ + [ + 0, + 0 + ], + [ + -2.9100524049084697, + 507.68956239314696 + ] + ] + }, + { + "type": "text", + "version": 2004, + "versionNonce": 28235597, + "isDeleted": false, + "id": "dlq-LCddvyv9rW9vWOnen", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 1282.6521442230803, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 86, + "height": 50, + "seed": 1619373805, + "groupIds": [ + "AxP1pTUQVIrrnNNvwelgT" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "unbonding\nperiod", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "unbonding\nperiod" + }, + { + "type": "text", + "version": 2010, + "versionNonce": 1371132909, + "isDeleted": false, + "id": "JE7v3fw6Lo-vnwABTfGUW", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 1298.1521442230805, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 240, + "height": 50, + "seed": 1500007565, + "groupIds": [ + "SsR2cRbMRkeYQVfLbQQFK" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "register VSC1 maturity\nfrom all consumer chains", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "register VSC1 maturity\nfrom all consumer chains" + }, + { + "type": "arrow", + "version": 3361, + "versionNonce": 1026647053, + "isDeleted": false, + "id": "epRmOkOvZWfXiLqu0Qlge", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1049.1877097524193, + "y": 1308.7643114112332, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 126.96037696966164, + "height": 0.24647998429350082, + "seed": 773091331, + "groupIds": [ + "f4ho76RQ9mWQGX32Ab5Md" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -126.96037696966164, + 0.24647998429350082 + ] + ] + }, + { + "type": "text", + "version": 2312, + "versionNonce": 1947234115, + "isDeleted": false, + "id": "gASwr2kKuNorBYPW6PB7B", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 933.8546672064161, + "y": 1241.7430748057857, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 50, + "seed": 1068287405, + "groupIds": [ + "f4ho76RQ9mWQGX32Ab5Md" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-1\nmatured", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-1\nmatured" + }, + { + "type": "arrow", + "version": 3101, + "versionNonce": 1726175853, + "isDeleted": false, + "id": "Qaof0appxyTfGqOyPimeM", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 921.6877097524193, + "y": 1540.6646169450064, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 128.06196234791332, + "height": 0.2680274478566389, + "seed": 744054659, + "groupIds": [ + "trbBqTUQZ8hVyEHwhsPIS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 128.06196234791332, + -0.2680274478566389 + ] + ] + }, + { + "type": "text", + "version": 2022, + "versionNonce": 1869057763, + "isDeleted": false, + "id": "pWe_TqLEWak9ZMs-2H7zz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 937.1046672064163, + "y": 1498.6396715011538, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 95, + "height": 25, + "seed": 1745915437, + "groupIds": [ + "trbBqTUQZ8hVyEHwhsPIS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-j", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-j" + }, + { + "type": "diamond", + "version": 1776, + "versionNonce": 2047568397, + "isDeleted": false, + "id": "CxowGLLYEeGhRaFOmUk4P", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 251.5328735492903, + "y": 1507.15214422308, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 145, + "height": 105, + "seed": 510627181, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "id": "-r0GObbpXNWzCa57TLWTv", + "type": "arrow" + }, + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "id": "wUVhER-pspmKNFqCwFdDW", + "type": "text" + }, + { + "type": "text", + "id": "wUVhER-pspmKNFqCwFdDW" + } + ], + "updated": 1642601376438, + "link": null + }, + { + "type": "text", + "version": 1731, + "versionNonce": 239192387, + "isDeleted": false, + "id": "wUVhER-pspmKNFqCwFdDW", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 256.5328735492903, + "y": 1547.15214422308, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 135, + "height": 25, + "seed": 1814825955, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601376438, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Tendermint", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "CxowGLLYEeGhRaFOmUk4P", + "originalText": "Tendermint" + }, + { + "type": "arrow", + "version": 4199, + "versionNonce": 2046117219, + "isDeleted": false, + "id": "3ImxJI5H1IhgvS85qKlh1", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 548.4045083034616, + "y": 1560.3823971655374, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 117.80814515172608, + "height": 1.2723534635447322, + "seed": 1163220941, + "groupIds": [ + "LrWRbUyeQLT9OV6pnT1k8" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601371578, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -117.80814515172608, + 1.2723534635447322 + ] + ] + }, + { + "type": "text", + "version": 2558, + "versionNonce": 1056339533, + "isDeleted": false, + "id": "6GQox3CC4___t_Car9og8", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 440.1022562045864, + "y": 1516.294608718219, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 95, + "height": 25, + "seed": 1730582403, + "groupIds": [ + "LrWRbUyeQLT9OV6pnT1k8" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601371578, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-j", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-j" + }, + { + "type": "text", + "version": 1926, + "versionNonce": 1455869955, + "isDeleted": false, + "id": "n_apeqqeSuAXb8Aa_VqFx", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 733.2067914294267, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 158, + "height": 25, + "seed": 785185293, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "dYJRFcc1PLcSHVaOF3szx", + "type": "arrow" + } + ], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "init redelegate-1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "init redelegate-1" + }, + { + "type": "text", + "version": 2005, + "versionNonce": 510618979, + "isDeleted": false, + "id": "yuH8tjvqZiQpXEO6g4Dfb", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 733.2067914294267, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 219, + "height": 25, + "seed": 740374851, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "" + }, + { + "type": "arrow", + "version": 2947, + "versionNonce": 2036279444, + "isDeleted": false, + "id": "M5qfHpuAKGd2joPo_LidE", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 921.4377097524193, + "y": 747.6245265623885, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 129.0619623479132, + "height": 0.27011154965987316, + "seed": 211562605, + "groupIds": [ + "52U-6lK1W6brXq10aCVDA" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619775590, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 129.0619623479132, + -0.27011154965987316 + ] + ] + }, + { + "type": "arrow", + "version": 3485, + "versionNonce": 306372867, + "isDeleted": false, + "id": "0v7hh7uxixdfVpYjaX0IN", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1047.8654006842082, + "y": 1404.7895225336572, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 126.96037696966164, + "height": 0.24647998429350082, + "seed": 1121770893, + "groupIds": [ + "bzgS7UIMLtmHiz7NOxjpS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -126.96037696966164, + 0.24647998429350082 + ] + ] + }, + { + "type": "text", + "version": 2446, + "versionNonce": 1352262829, + "isDeleted": false, + "id": "2gQDdpyI5F1fliwPoB914", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 933.0323581382052, + "y": 1337.7682859282097, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 117, + "height": 50, + "seed": 202591683, + "groupIds": [ + "bzgS7UIMLtmHiz7NOxjpS" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "redelegate-1\nmatured", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "redelegate-1\nmatured" + }, + { + "type": "rectangle", + "version": 1652, + "versionNonce": 1418907213, + "isDeleted": false, + "id": "-L4r_-m6RbrGgavC67Rjk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 1526.40214422308, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 282, + "height": 44.99999999999999, + "seed": 101774467, + "groupIds": [ + "BIN_XiQ90fjv_AvqHTY2r" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "type": "text" + }, + { + "type": "text", + "id": "Xsb8ZrPkxJ7fF3p7A30aR" + } + ], + "updated": 1642600919620, + "link": null + }, + { + "type": "text", + "version": 1694, + "versionNonce": 226609411, + "isDeleted": false, + "id": "Xsb8ZrPkxJ7fF3p7A30aR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1104.9216781417922, + "y": 1536.40214422308, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 272, + "height": 25, + "seed": 1460193581, + "groupIds": [ + "BIN_XiQ90fjv_AvqHTY2r" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "-L4r_-m6RbrGgavC67Rjk", + "originalText": "EndBlock" + }, + { + "type": "arrow", + "version": 4832, + "versionNonce": 541089133, + "isDeleted": false, + "id": "M5sZD3idFu959njYfEyeu", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 6.277329793107594, + "x": 876.2468575020056, + "y": 1214.4108870905281, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 0.04088500122713867, + "height": 446.6102100653302, + "seed": 1822069859, + "groupIds": [ + "F-MSJHdtVFQVUvZCVH0mb" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635408, + "link": null, + "startBinding": { + "elementId": "kdNbiNehK3QVI1DL8BGYt", + "focus": 0.10816135727922097, + "gap": 6.109673614163796 + }, + "endBinding": { + "elementId": "QXlbO191aqO2Ebca6nJSm", + "focus": -0.09325154026316189, + "gap": 4.731977813937419 + }, + "lastCommittedPoint": null, + "startArrowhead": "bar", + "endArrowhead": "bar", + "points": [ + [ + 0, + 0 + ], + [ + -0.04088500122713867, + 446.6102100653302 + ] + ] + }, + { + "type": "text", + "version": 2094, + "versionNonce": 2010451693, + "isDeleted": false, + "id": "BsxGg6VO6rGscqezmTejP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 770.8921896412048, + "y": 1367.6521442230799, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 86, + "height": 50, + "seed": 1038528611, + "groupIds": [ + "_3gCHPt_YFY_m1npu2XJ5" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600882925, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "unbonding\nperiod", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "unbonding\nperiod" + }, + { + "type": "rectangle", + "version": 2490, + "versionNonce": 126142339, + "isDeleted": false, + "id": "QXlbO191aqO2Ebca6nJSm", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 422.37409961491886, + "y": 1665.7493664453023, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 1005.0833333333333, + "height": 162.5555555555557, + "seed": 27175747, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "M5sZD3idFu959njYfEyeu", + "type": "arrow" + } + ], + "updated": 1642600635408, + "link": null + }, + { + "type": "rectangle", + "version": 1941, + "versionNonce": 370399139, + "isDeleted": false, + "id": "mpRpGxyyho1lobPdtJ75y", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 1690.9576997786353, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 253.24999999999997, + "height": 117.50000000000001, + "seed": 1835458157, + "groupIds": [ + "JrgL8elQW7Dq3Q6PWzPuU" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "pIw5JMoColGr9m_qovMhF", + "type": "text" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "type": "text", + "id": "pIw5JMoColGr9m_qovMhF" + } + ], + "updated": 1642600868111, + "link": null + }, + { + "type": "text", + "version": 2042, + "versionNonce": 1735469069, + "isDeleted": false, + "id": "pIw5JMoColGr9m_qovMhF", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 611.6064753554905, + "y": 1699.7076997786353, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 243.24999999999997, + "height": 100, + "seed": 667831011, + "groupIds": [ + "JrgL8elQW7Dq3Q6PWzPuU" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock\n- compute updates-k\n- ! cannot complete \nundelegate-2", + "baseline": 93, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "mpRpGxyyho1lobPdtJ75y", + "originalText": "EndBlock\n- compute updates-k\n- ! cannot complete undelegate-2" + }, + { + "type": "arrow", + "version": 3196, + "versionNonce": 1452562573, + "isDeleted": false, + "id": "UC5ZzJxhmHYCs7KEr8mvo", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 919.134785107629, + "y": 1768.664616945006, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 128.06196234791332, + "height": 0.2680274478566389, + "seed": 993691853, + "groupIds": [ + "GK0iuN3yOAXSK5NbTvgTY" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 128.06196234791332, + -0.2680274478566389 + ] + ] + }, + { + "type": "text", + "version": 2119, + "versionNonce": 1306854083, + "isDeleted": false, + "id": "73rDFdHpWyiGnIX69Rmqj", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 933.0517425616258, + "y": 1726.6396715011533, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98, + "height": 25, + "seed": 304674435, + "groupIds": [ + "GK0iuN3yOAXSK5NbTvgTY" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-k", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-k" + }, + { + "type": "diamond", + "version": 1876, + "versionNonce": 1474429581, + "isDeleted": false, + "id": "_ebS12dRowA_tQI8j45CY", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 248.9799489044999, + "y": 1738.1521442230796, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 145, + "height": 105, + "seed": 971630381, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [ + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "-r0GObbpXNWzCa57TLWTv", + "type": "arrow" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "id": "E673Ak76SUOSt77Qi8bsE", + "type": "text" + }, + { + "type": "text", + "id": "E673Ak76SUOSt77Qi8bsE" + } + ], + "updated": 1642601420357, + "link": null + }, + { + "type": "text", + "version": 1830, + "versionNonce": 287242435, + "isDeleted": false, + "id": "E673Ak76SUOSt77Qi8bsE", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 253.9799489044999, + "y": 1778.1521442230796, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 135, + "height": 25, + "seed": 527248931, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601420358, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Tendermint", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "_ebS12dRowA_tQI8j45CY", + "originalText": "Tendermint" + }, + { + "type": "arrow", + "version": 4294, + "versionNonce": 1325148397, + "isDeleted": false, + "id": "jRnLv9fNuoznNAaRsNZgk", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 545.8515836586712, + "y": 1788.382397165537, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 117.80814515172608, + "height": 1.2723534635447322, + "seed": 1004435853, + "groupIds": [ + "YrqVjtQGzKIAhQyl39Kp9" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601420358, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -117.80814515172608, + 1.2723534635447322 + ] + ] + }, + { + "type": "text", + "version": 2655, + "versionNonce": 1290332259, + "isDeleted": false, + "id": "wB_7P6AInvDavIoMbkl8E", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 436.04933155979603, + "y": 1744.2946087182186, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 98, + "height": 25, + "seed": 1384739267, + "groupIds": [ + "YrqVjtQGzKIAhQyl39Kp9" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601420358, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "updates-k", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "updates-k" + }, + { + "type": "rectangle", + "version": 1749, + "versionNonce": 1528659117, + "isDeleted": false, + "id": "jFpSjGFb3cu0a0QbNucLK", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 1754.4021442230796, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 282, + "height": 44.99999999999999, + "seed": 173129709, + "groupIds": [ + "6OEOlibeQD_u8MFuWagZW" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "9c_Yl7A91iXAKKFtnu4tQ", + "type": "arrow" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "wiNk7YxLC6w3qcdxfA5HM", + "type": "arrow" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "id": "XTAVne28eQ084ExAjqSpY", + "type": "text" + }, + { + "type": "text", + "id": "XTAVne28eQ084ExAjqSpY" + } + ], + "updated": 1642600919620, + "link": null + }, + { + "type": "text", + "version": 1790, + "versionNonce": 218607779, + "isDeleted": false, + "id": "XTAVne28eQ084ExAjqSpY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1104.9216781417922, + "y": 1764.4021442230796, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 272, + "height": 25, + "seed": 1285308771, + "groupIds": [ + "6OEOlibeQD_u8MFuWagZW" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "EndBlock", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": "jFpSjGFb3cu0a0QbNucLK", + "originalText": "EndBlock" + }, + { + "type": "text", + "version": 2080, + "versionNonce": 1828937485, + "isDeleted": false, + "id": "QSiOaQm7YoHL3FHb5xGQR", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1099.9216781417922, + "y": 1888.90214422308, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 240, + "height": 50, + "seed": 239799565, + "groupIds": [ + "DpRuLZsRaxufqGOHn5Hhe" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1642600919620, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "register VSC2 maturity\nfrom all consumer chains", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "register VSC2 maturity\nfrom all consumer chains" + }, + { + "type": "arrow", + "version": 3429, + "versionNonce": 460510339, + "isDeleted": false, + "id": "S32vBZg5ju-5zAgb6D7qY", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1047.8654006842082, + "y": 1937.8097612767697, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 126.96037696966164, + "height": 0.24647998429350082, + "seed": 1358265827, + "groupIds": [ + "O0RfEkM6R98ddCqKabsm1" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -126.96037696966164, + 0.24647998429350082 + ] + ] + }, + { + "type": "text", + "version": 2382, + "versionNonce": 691333421, + "isDeleted": false, + "id": "NJ3kaRH3ykxaEPbuL6kwI", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 928.0323581382052, + "y": 1870.7885246713222, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 127, + "height": 50, + "seed": 26478029, + "groupIds": [ + "O0RfEkM6R98ddCqKabsm1" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "undelegate-2\nmatured", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "undelegate-2\nmatured" + }, + { + "type": "text", + "version": 81, + "versionNonce": 1637804867, + "isDeleted": false, + "id": "FlycApHxvNhc7EzTtDfVw", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "dashed", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 606.6064753554905, + "y": 1913.90214422308, + "strokeColor": "#000000", + "backgroundColor": "#fa5252", + "width": 220, + "height": 25, + "seed": 334653923, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600868111, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "complete undelegate-2", + "baseline": 18, + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "complete undelegate-2" + }, + { + "type": "text", + "version": 1473, + "versionNonce": 1078215149, + "isDeleted": false, + "id": "4uwRrBf63CyHdZgytHPgP", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1461.445910951049, + "y": 1508.7613874951103, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 120, + "height": 25, + "seed": 1561641411, + "groupIds": [ + "v10k9qiCW2ZlkFRAoU0v7" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-j", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-j" + }, + { + "type": "arrow", + "version": 2396, + "versionNonce": 109764451, + "isDeleted": false, + "id": "LAJit7p8fwSjpli354rmQ", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1465.1319416280767, + "y": 1554.2214723796214, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 121.62386851542169, + "height": 1.693510304863139, + "seed": 1021538285, + "groupIds": [ + "v10k9qiCW2ZlkFRAoU0v7" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 121.62386851542169, + -1.693510304863139 + ] + ] + }, + { + "type": "text", + "version": 1528, + "versionNonce": 597654605, + "isDeleted": false, + "id": "LcE9oP3jo0SV72kN6WVl7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1461.445910951049, + "y": 1735.9042446379674, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 123, + "height": 25, + "seed": 2051265795, + "groupIds": [ + "bCkx_NwLyCOUyNPR2c83i" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket-k", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket-k" + }, + { + "type": "arrow", + "version": 2449, + "versionNonce": 90110723, + "isDeleted": false, + "id": "aiXbgSJSQTjiViNaUGmMf", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1466.6319416280767, + "y": 1781.3643295224786, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 121.62386851542169, + "height": 1.693510304863139, + "seed": 475148461, + "groupIds": [ + "bCkx_NwLyCOUyNPR2c83i" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642600635409, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 121.62386851542169, + -1.693510304863139 + ] + ] + }, + { + "type": "rectangle", + "version": 1951, + "versionNonce": 1359653507, + "isDeleted": false, + "id": "lWhZF3KHnueXQn1g7preT", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1632.307976640662, + "y": 488.6342870802232, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 22.857142857142406, + "height": 1489.2857142857147, + "seed": 1833606115, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "Hg015OniyGFjM7QYWPufU", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + }, + { + "id": "HHI5Vc7fqPn6VuRzXoIaY", + "type": "arrow" + } + ], + "updated": 1642601108975, + "link": null + }, + { + "type": "text", + "version": 1364, + "versionNonce": 450358979, + "isDeleted": false, + "id": "lvwKtrmcLxqDV3LzwuTSz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1472.9030270444368, + "y": 511.61853035225386, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 105, + "height": 25, + "seed": 771374435, + "groupIds": [ + "Qi942Aq3vXaCC_NBM6xKv" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642601084994, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket" + }, + { + "type": "arrow", + "version": 2292, + "versionNonce": 1465624547, + "isDeleted": false, + "id": "5zz8ESfQcxy3owCiP9VT3", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1469.089057721465, + "y": 557.0786152367646, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 121.62386851542169, + "height": 1.693510304863139, + "seed": 1943862861, + "groupIds": [ + "Qi942Aq3vXaCC_NBM6xKv" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1642601080289, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 121.62386851542169, + -1.693510304863139 + ] + ] + }, + { + "type": "rectangle", + "version": 2071, + "versionNonce": 439186221, + "isDeleted": false, + "id": "Ov7Nt-iR2V6wD_0fP-mUY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1672.593690926376, + "y": 488.6342870802232, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 22.857142857142406, + "height": 1489.2857142857147, + "seed": 692385091, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "Hg015OniyGFjM7QYWPufU", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + }, + { + "id": "HHI5Vc7fqPn6VuRzXoIaY", + "type": "arrow" + } + ], + "updated": 1642601108975, + "link": null + }, + { + "type": "rectangle", + "version": 2044, + "versionNonce": 2146984483, + "isDeleted": false, + "id": "zDLZUtrO8Lij6Z4ctMo67", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1711.1651194978049, + "y": 488.6342870802231, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 22.857142857142406, + "height": 1489.2857142857147, + "seed": 1478186211, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "Hg015OniyGFjM7QYWPufU", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + }, + { + "id": "HHI5Vc7fqPn6VuRzXoIaY", + "type": "arrow" + } + ], + "updated": 1642601108975, + "link": null + }, + { + "type": "text", + "version": 933, + "versionNonce": 257253005, + "isDeleted": false, + "id": "BF8omtpN5J817AOrrJinc", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 465.5222623549474, + "y": 637.8485727945094, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 67, + "height": 25, + "seed": 156612141, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642601398863, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block 1", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block 1" + }, + { + "type": "text", + "version": 904, + "versionNonce": 1034784707, + "isDeleted": false, + "id": "EXAbJSyrRTJfdeB6ZeE9e", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 461.7365480692332, + "y": 978.8485727945097, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 76, + "height": 25, + "seed": 284738093, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642601384686, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block 2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block 2" + }, + { + "type": "text", + "version": 944, + "versionNonce": 186422403, + "isDeleted": false, + "id": "EeggQ3YD-incj8Aa12fst", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 458.5936909263761, + "y": 1453.4200013659383, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 68, + "height": 25, + "seed": 1671725389, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642601379543, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block j", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block j" + }, + { + "type": "text", + "version": 992, + "versionNonce": 268758787, + "isDeleted": false, + "id": "dmYqu29T9lOTUDFFjP5dR", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 464.2365480692332, + "y": 1683.2771442230812, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 71, + "height": 25, + "seed": 2007237869, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1642601409906, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block k", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block k" + }, + { + "type": "text", + "version": 1455, + "versionNonce": 1639310996, + "isDeleted": false, + "id": "neyeN0wmFK2sHMHSi1Cyv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1412.3112543352074, + "y": 1885.6802121324004, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 221, + "height": 25, + "seed": 1220556204, + "groupIds": [ + "f6V1v01vZdzSr0UWMa1V0" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + } + ], + "updated": 1645619672989, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCMaturedPackets-2", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCMaturedPackets-2" + }, + { + "type": "arrow", + "version": 2274, + "versionNonce": 703626412, + "isDeleted": false, + "id": "NWLK_Lfb3vSSeX03apdO3", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1581.9668725676863, + "y": 1930.276949738989, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 123.56280714681475, + "height": 0.8260181955356529, + "seed": 1254640404, + "groupIds": [ + "f6V1v01vZdzSr0UWMa1V0" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619672989, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -123.56280714681475, + 0.8260181955356529 + ] + ] + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.png new file mode 100644 index 000000000..30455eb84 Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.excalidraw b/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.excalidraw new file mode 100644 index 000000000..1eae53f86 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.excalidraw @@ -0,0 +1,946 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "rectangle", + "version": 844, + "versionNonce": 725100588, + "isDeleted": false, + "id": "Lzfre0sNq-j_kaO2bid-V", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1033.80728608124, + "y": 370.7566693985417, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 236.99999999999977, + "height": 425.0000000000002, + "seed": 875787883, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "umXKeqaL3A2gsELJxrAno", + "type": "arrow" + }, + { + "id": "JdK3ZV05Kgdm0t1Wbwel3", + "type": "arrow" + }, + { + "id": "Hg015OniyGFjM7QYWPufU", + "type": "arrow" + }, + { + "id": "1qXvD7xEgjTf4VUM5wDV3", + "type": "arrow" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + } + ], + "updated": 1645619130251, + "link": null + }, + { + "type": "rectangle", + "version": 822, + "versionNonce": 1641988244, + "isDeleted": false, + "id": "tiEtkt2XHCbZp9ZIwwoVN", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 631.0850638590175, + "y": 364.8677805096529, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 221.33333333333323, + "height": 430.55555555555543, + "seed": 1114932363, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null + }, + { + "type": "text", + "version": 912, + "versionNonce": 1088045740, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 780.5555555555554, + "y": 266.77777777777777, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 391, + "height": 36, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "CCV - Validator Set Update", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV - Validator Set Update" + }, + { + "type": "rectangle", + "version": 2333, + "versionNonce": 48336404, + "isDeleted": false, + "id": "LZ-zpiSZrRKjK21SSB5me", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 664.6961749701286, + "y": 420.36778050965296, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 154.3333333333333, + "height": 343.3333333333332, + "seed": 689622821, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "jz87Jfblhql4prXUNauec", + "type": "arrow" + }, + { + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + }, + { + "id": "WEyZi3lMqkJ8FhlR5xFl1", + "type": "arrow" + }, + { + "id": "soJdQZVXQySCwfBjVwVtd", + "type": "arrow" + }, + { + "id": "pFUtKITgaRpYy9le7pyUv", + "type": "arrow" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null + }, + { + "type": "rectangle", + "version": 2383, + "versionNonce": 1079315756, + "isDeleted": false, + "id": "bV7tck2JEoFVq7rV8HSWu", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1070.9739527479064, + "y": 426.03444717631953, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 172.33333333333331, + "height": 344.4444444444449, + "seed": 1430831243, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "gdGzxModJaJKV9kGsQ0lN" + }, + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "type": "arrow", + "id": "L-m2OjIz_DM9FZL_aw8q1" + }, + { + "type": "arrow", + "id": "MUNWjeP_k1E_jhbGobXH1" + }, + { + "type": "arrow", + "id": "Z366__sEfBTh-UkidbmWs" + }, + { + "id": "L-SUQMkaBFUSpHYaSKHI8", + "type": "arrow" + }, + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "jz87Jfblhql4prXUNauec", + "type": "arrow" + }, + { + "id": "XqKtKE8gPBp_eAGHN-Ucc", + "type": "arrow" + }, + { + "id": "Uv1Gs8hixSdQGVRH6KLVi", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "UqXi4k7D7LBkElLUl9bRY", + "type": "arrow" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + }, + { + "id": "HHI5Vc7fqPn6VuRzXoIaY", + "type": "arrow" + }, + { + "id": "pFUtKITgaRpYy9le7pyUv", + "type": "arrow" + }, + { + "id": "soJdQZVXQySCwfBjVwVtd", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null + }, + { + "type": "text", + "version": 334, + "versionNonce": 1697557396, + "isDeleted": false, + "id": "Tk2sS1hhVtDPd_0ZZPV5A", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 883.6961749701285, + "y": 418.9233360652086, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 118, + "height": 26, + "seed": 1397655621, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Channel", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Channel" + }, + { + "type": "arrow", + "version": 2174, + "versionNonce": 1259505580, + "isDeleted": false, + "id": "soJdQZVXQySCwfBjVwVtd", + "fillStyle": "hachure", + "strokeWidth": 4, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 824.4912274560614, + "y": 456.28099618447334, + "strokeColor": "#495057", + "backgroundColor": "transparent", + "width": 239.85269160961423, + "height": 0.4292804414828879, + "seed": 888195723, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "startBinding": { + "elementId": "LZ-zpiSZrRKjK21SSB5me", + "gap": 5.461719152599573, + "focus": -0.7893003201774047 + }, + "endBinding": { + "elementId": "bV7tck2JEoFVq7rV8HSWu", + "gap": 6.630033682230661, + "focus": 0.8270921041462953 + }, + "lastCommittedPoint": null, + "startArrowhead": "triangle", + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 239.85269160961423, + -0.4292804414828879 + ] + ] + }, + { + "type": "text", + "version": 1457, + "versionNonce": 184293652, + "isDeleted": false, + "id": "fYIVRw6i_u72mXigtRsA1", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 677.7013096558908, + "y": 501.7765630941593, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 113, + "height": 25, + "seed": 112951915, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null, + "fontSize": 19.860178682944078, + "fontFamily": 1, + "text": "provide VSC", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "provide VSC" + }, + { + "type": "text", + "version": 1228, + "versionNonce": 1161605676, + "isDeleted": false, + "id": "SX9_IjHVCeJsw5zjihNjk", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 677.7013096558908, + "y": 684.3587865243416, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 129, + "height": 52, + "seed": 786765227, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "register \nVSC maturity", + "baseline": 44, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "register \nVSC maturity" + }, + { + "type": "text", + "version": 1489, + "versionNonce": 1069536916, + "isDeleted": false, + "id": "NQpfW4a7Hwtvr-8EPhJwk", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1085.2505196648644, + "y": 532.2210075386038, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 93, + "height": 26, + "seed": 38614437, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "dYJRFcc1PLcSHVaOF3szx", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null, + "fontSize": 19.860178682944078, + "fontFamily": 1, + "text": "apply VSC", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "apply VSC" + }, + { + "type": "text", + "version": 974, + "versionNonce": 2109574316, + "isDeleted": false, + "id": "hlLx6LN5_BUDJUO2t7mzz", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 686.3628416367951, + "y": 383.0344471763196, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 1737169669, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "text", + "version": 1323, + "versionNonce": 1882186772, + "isDeleted": false, + "id": "yqi6dzvpzblq17ysowkTo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 639.9183971923508, + "y": 334.03444717631965, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 138, + "height": 26, + "seed": 578772677, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1059, + "versionNonce": 1446975276, + "isDeleted": false, + "id": "tLJ6siXC9VChVdOcHR37l", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1101.2517305256843, + "y": 391.1455582874308, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 2057296357, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "text", + "version": 1658, + "versionNonce": 37896596, + "isDeleted": false, + "id": "Y19fC1uuzabCFyV0s97Ip", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1045.4739527479067, + "y": 338.14555828743073, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 148, + "height": 26, + "seed": 1161289003, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chain" + }, + { + "type": "text", + "version": 1482, + "versionNonce": 1798001068, + "isDeleted": false, + "id": "_72T1dsBHZpELeZ7ogywj", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1085.2505196648644, + "y": 672.2274627737531, + "strokeColor": "#000000", + "backgroundColor": "#e67700", + "width": 129, + "height": 50, + "seed": 1106855979, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "dYJRFcc1PLcSHVaOF3szx", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "notify \nVSC maturity", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "notify \nVSC maturity" + }, + { + "type": "text", + "version": 935, + "versionNonce": 757919508, + "isDeleted": false, + "id": "USOjGct8Q4FclCqyREAjw", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1091.4180655283808, + "y": 592.8332539375602, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 86, + "height": 52, + "seed": 1928733029, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "unbonding\nperiod", + "baseline": 44, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "unbonding\nperiod" + }, + { + "type": "arrow", + "version": 1472, + "versionNonce": 1001143340, + "isDeleted": false, + "id": "dYJRFcc1PLcSHVaOF3szx", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "dashed", + "roughness": 0, + "opacity": 100, + "angle": 0, + "x": 1083.9873273042986, + "y": 674.787472319473, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 0.2423078102508498, + "height": 109.44664752881295, + "seed": 47081765, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "startBinding": { + "elementId": "_72T1dsBHZpELeZ7ogywj", + "focus": -1.0179406248132712, + "gap": 1.2631923605658812 + }, + "endBinding": { + "elementId": "NQpfW4a7Hwtvr-8EPhJwk", + "focus": 1.0326950964223782, + "gap": 7.119817252056237 + }, + "lastCommittedPoint": null, + "startArrowhead": "bar", + "endArrowhead": "bar", + "points": [ + [ + 0, + 0 + ], + [ + -0.2423078102508498, + -109.44664752881295 + ] + ] + }, + { + "type": "text", + "version": 727, + "versionNonce": 1365634196, + "isDeleted": false, + "id": "RzN1Ejg0DNhbMX38KakLy", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 875.5850638590175, + "y": 490.923336065209, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 104, + "height": 26, + "seed": 253438597, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "VSCPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "VSCPacket" + }, + { + "type": "text", + "version": 793, + "versionNonce": 1370216108, + "isDeleted": false, + "id": "sQR88kHWeEXVsXgq8udT2", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 846.6406194145729, + "y": 656.5900027318755, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 197, + "height": 25, + "seed": 894891877, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [ + { + "type": "arrow", + "id": "UdbNDUj-KimwGAw0JZmAm" + }, + { + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "type": "arrow" + } + ], + "updated": 1645619130252, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": " VSCMaturedPacket", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": " VSCMaturedPacket" + }, + { + "type": "arrow", + "version": 1903, + "versionNonce": 1352874516, + "isDeleted": false, + "id": "pFUtKITgaRpYy9le7pyUv", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 824.0249181995255, + "y": 516.6028911169248, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 242.12081022232314, + "height": 30.99520266125478, + "seed": 1819697989, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130252, + "link": null, + "startBinding": { + "elementId": "LZ-zpiSZrRKjK21SSB5me", + "gap": 4.995409896063598, + "focus": -0.47343333675257726 + }, + "endBinding": { + "elementId": "bV7tck2JEoFVq7rV8HSWu", + "gap": 4.8282243260578035, + "focus": 0.21245077762725106 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + 242.12081022232314, + 30.99520266125478 + ] + ] + }, + { + "type": "arrow", + "version": 2365, + "versionNonce": 1775509804, + "isDeleted": false, + "id": "0s6Gf0lhs4RxTdpZNUqsV", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1063.5472546745837, + "y": 684.0659396918977, + "strokeColor": "#495057", + "backgroundColor": "#ced4da", + "width": 237.96419827484328, + "height": 23.35329422599807, + "seed": 105495787, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1645619130253, + "link": null, + "startBinding": { + "elementId": "bV7tck2JEoFVq7rV8HSWu", + "gap": 7.426698073322591, + "focus": -0.4237049945547797 + }, + "endBinding": { + "elementId": "LZ-zpiSZrRKjK21SSB5me", + "gap": 6.553548096278409, + "focus": 0.6895846829562841 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -237.96419827484328, + 23.35329422599807 + ] + ] + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.png b/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.png new file mode 100644 index 000000000..55eb3247a Binary files /dev/null and b/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.png differ diff --git a/spec/app/ics-028-cross-chain-validation/methods.md b/spec/app/ics-028-cross-chain-validation/methods.md new file mode 100644 index 000000000..9bdcee783 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/methods.md @@ -0,0 +1,1975 @@ + +# CCV: Technical Specification - Methods +[↑ Back to main document](./README.md) + +[↑ Back to technical specification](./technical_specification.md) + + +## Outline +- [General Methods](#general-methods) + - [BeginBlock and EndBlock](#beginblock-and-endblock) + - [Packet Relay](#packet-relay) + - [Utility Methods](#utility-methods) +- [Sub-protocols](#sub-protocols) + - [Initialization](#initialization) + - [Consumer Chain Removal](#consumer-chain-removal) + - [Validator Set Update](#validator-set-update) + - [Consumer Initiated Slashing](#consumer-initiated-slashing) + - [Reward Distribution](#reward-distribution) + +## General Methods +[↑ Back to Outline](#outline) + +To express the error conditions, the following specification of the sub-protocols uses the exception system of the host state machine, which is exposed through two functions (as defined in [ICS 24](../../core/ics-024-host-requirements)): `abortTransactionUnless` and `abortSystemUnless`. + +### BeginBlock and EndBlock +[↑ Back to Outline](#outline) + +The functions `BeginBlock()` and `EndBlock()` (see [Implemented Interfaces](./technical_specification.md#implemented-interfaces)) are split across the CCV sub-protocols. + + +#### **[CCV-PCF-BBLOCK.1]** +```typescript +// PCF: Provider Chain Function +// implements the AppModule interface +function BeginBlock() { + BeginBlockInit() + BeginBlockCCR() +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `BeginBlockInit()` is invoked (see [[CCV-PCF-BBLOCK-INIT.1]](#ccv-pcf-bblock-init1), i.e., it contains the `BeginBlock()` logic needed for the Initialization sub-protocol). + - `BeginBlockCCR()` is invoked (see [[CCV-PCF-BBLOCK-CCR.1]](#ccv-pcf-bblock-ccr1), i.e., it contains the `BeginBlock()` logic needed for the Consumer Chain Removal sub-protocol). +- **Error Condition** + - None. + + +#### **[CCV-PCF-EBLOCK.1]** +```typescript +// PCF: Provider Chain Function +// implements the AppModule interface +function EndBlock(): [ValidatorUpdate] { + EndBlockCIS() + EndBlockVSU() + + // do not return anything to the consensus engine + return [] +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `EndBlockCIS()` is invoked (see [[CCV-PCF-EBLOCK-CIS.1]](#ccv-pcf-eblock-cis1), i.e., it contains the `EndBlock()` logic needed for the Consumer Initiated Slashing sub-protocol). + - `EndBlockVSU()` is invoked (see [[CCV-PCF-EBLOCK-VSU.1]](#ccv-pcf-eblock-vsu1), i.e., it contains the `EndBlock()` logic needed for the Validator Set Update sub-protocol). +- **Error Condition** + - None. + +> **Note**: The provider CCV module expects the provider Staking module to update its view of the validator set before the `EndBlock()` of the provider CCV module is invoked. +> A solution is for the provider Staking module to update its view during `EndBlock()` and then, the `EndBlock()` of the provider Staking module to be executed before the `EndBlock()` of the provider CCV module. + +--- + + +#### **[CCV-CCF-BBLOCK.1]** +```typescript +// CCF: Consumer Chain Function +// implements the AppModule interface +function BeginBlock() { + BeginBlockCCR() + BeginBlockCIS() +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `BeginBlockCCR()` is invoked (see [[CCV-CCF-BBLOCK-CCR.1]](#ccv-ccf-bblock-ccr1), i.e., it contains the `BeginBlock()` logic needed for the Consumer Chain Removal sub-protocol). + - `BeginBlockCIS()` is invoked (see [[CCV-CCF-BBLOCK-CIS.1]](#ccv-ccf-bblock-cis1), i.e., it contains the `BeginBlock()` logic needed for the Consumer Initiated Slashing sub-protocol). +- **Error Condition** + - None. + + +#### **[CCV-CCF-EBLOCK.1]** +```typescript +// CCF: Consumer Chain Function +// implements the AppModule interface +function EndBlock(): [ValidatorUpdate] { + EndBlockRD() + + // return the validator set updates to the consensus engine + return EndBlockVSU() +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `EndBlockRD()` is invoked (see [[CCV-PCF-EBLOCK-RD.1]](#ccv-pcf-eblock-rd1), i.e., it contains the `EndBlock()` logic needed for the Reward Distribution sub-protocol). + - `EndBlockVSU()` is invoked and the return value is returned to the consensus engine (see [[CCV-CCF-EBLOCK-VSU.1]](#ccv-ccf-eblock-vsu1), i.e., it contains the `EndBlock()` logic needed for the Validator Set Update sub-protocol). +- **Error Condition** + - None. + +### Packet Relay +[↑ Back to Outline](#outline) + + +#### **[CCV-PCF-RCVP.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onRecvPacket(packet: Packet): bytes { + switch typeof(packet.data) { + case VSCMaturedPacketData: + return onRecvVSCMaturedPacket(packet) + case SlashPacketData: + return onRecvSlashPacket(packet) + default: + // unexpected packet type + return PacketError + } +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a packet on a channel owned by the provider CCV module. +- **Precondition** + - True. +- **Postcondition** + - If the packet is a `VSCMaturedPacket`, the acknowledgement obtained from invoking the `onRecvVSCMaturedPacket` method is returned. + - If the packet is a `SlashPacket`, the acknowledgement obtained from invoking the `onRecvSlashPacket` method is returned. + - Otherwise, an error acknowledgement is returned. +- **Error Condition** + - None. + + +#### **[CCV-PCF-ACKP.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onAcknowledgePacket(packet: Packet, ack: bytes) { + switch typeof(packet.data) { + case VSCPacketData: + onAcknowledgeVSCPacket(packet, ack) + default: + // unexpected packet type + abortTransactionUnless(FALSE) + } +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives an acknowledgement on a channel owned by the provider CCV module. +- **Precondition** + - True. +- **Postcondition** + - If the acknowledgement is for a `VSCPacket`, the `onAcknowledgeVSCPacket` method is invoked. + - Otherwise, the transaction is aborted. +- **Error Condition** + - None. + + +#### **[CCV-PCF-TOP.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onTimeoutPacket(packet Packet) { + switch typeof(packet.data) { + case VSCPacketData: + onTimeoutVSCPacket(packet) + default: + // unexpected packet type + abortTransactionUnless(FALSE) + } +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - A packet sent on a channel owned by the provider CCV module timed out as a result of either + - the timeout height or timeout timestamp passing on the consumer chain without the packet being received (see `timeoutPacket` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#sending-end)); + - or the channel being closed without the packet being received (see `timeoutOnClose` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#timing-out-on-close)). +- **Precondition** + - The *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +- **Postcondition** + - If the timeout is for a `VSCPacket`, the `onTimeoutVSCPacket` method is invoked. + - Otherwise, the transaction is aborted. +- **Error Condition** + - None. + +--- + + +#### **[CCV-CCF-RCVP.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onRecvPacket(packet: Packet): bytes { + switch typeof(packet.data) { + case VSCPacketData: + return onRecvVSCPacket(packet) + default: + // unexpected packet type + return PacketError + } +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a packet on a channel owned by the consumer CCV module. +- **Precondition** + - True. +- **Postcondition** + - If the packet is a `VSCPacket`, the acknowledgement obtained from invoking the `onRecvVSCPacket` method is returned. + - Otherwise, an error acknowledgement is returned. +- **Error Condition** + - None. + + +#### **[CCV-CCF-ACKP.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onAcknowledgePacket(packet: Packet, ack: bytes) { + switch typeof(packet.data) { + case VSCMaturedPacketData: + onAcknowledgeVSCMaturedPacket(packet, ack) + case SlashPacketData: + onAcknowledgeSlashPacket(packet, ack) + default: + // unexpected packet type + abortTransactionUnless(FALSE) + } +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives an acknowledgement on a channel owned by the consumer CCV module. +- **Precondition** + - True. +- **Postcondition** + - If the acknowledgement is for a `VSCMaturedPacket`, the `onAcknowledgeVSCMaturedPacket` method is invoked. + - If the acknowledgement is for a `SlashPacket`, the `onAcknowledgeSlashPacket` method is invoked. + - Otherwise, the transaction is aborted. +- **Error Condition** + - None. + + +#### **[CCV-CCF-TOP.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onTimeoutPacket(packet Packet) { + switch typeof(packet.data) { + case VSCMaturedPacketData: + onTimeoutVSCMaturedPacket(packet) + case SlashPacketData: + onTimeoutSlashPacket(packet) + default: + // unexpected packet type + abortTransactionUnless(FALSE) + } +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - A packet sent on a channel owned by the consumer CCV module timed out as a result of either + - the timeout height or timeout timestamp passing on the provider chain without the packet being received (see `timeoutPacket` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#sending-end)); + - or the channel being closed without the packet being received (see `timeoutOnClose` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#timing-out-on-close)). +- **Precondition** + - The *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +- **Postcondition** + - If the timeout is for a `VSCMaturedPacket`, the `onTimeoutVSCMaturedPacket` method is invoked. + - If the timeout is for a `SlashPacket`, the `onTimeoutSlashPacket` method is invoked. + - Otherwise, the transaction is aborted. +- **Error Condition** + - None. + +### Utility Methods +[↑ Back to Outline](#outline) + + +#### **[CCV-UTIL-CCUBPER.1]** +```typescript +// computes the unbonding period on the consumer +// from the unbonding period on the provider +function ComputeConsumerUnbondingPeriod(delta: Duration): Duration { + if delta > 7*24*Hour { + return delta - 24*Hour // one day less + } + else if delta >= 24*Hour { + return delta - Hour // one hour less + } + return delta +} +``` +- **Caller** + - Either `CreateConsumerClient` (see [[CCV-PCF-CRCLIENT.1]](#ccv-pcf-crclient1)) or `InitGenesis` (see [[CCV-CCF-INITG.1]](#ccv-ccf-initg1)) +- **Trigger Event** + - A new consumer chain is created. +- **Precondition** + - None. +- **Postcondition** + - None. +- **Error Condition** + - None. + +## Sub-protocols + +### Initialization +[↑ Back to Outline](#outline) + +The *initialization* sub-protocol enables a provider chain and a consumer chain to create a CCV channel -- a unique, ordered IBC channel for exchanging packets. As a prerequisite, the initialization sub-protocol MUST create two IBC clients, one on the provider chain to the consumer chain and one on the consumer chain to the provider chain. This is necessary to verify the identity of the two chains (as long as the clients are trusted). + + +#### **[CCV-PCF-INITG.1]** +```typescript +// PCF: Provider Chain Function +// implements the AppModule interface +function InitGenesis(state: ProviderGenesisState): [ValidatorUpdate] { + // bind to ProviderPortId port + err = portKeeper.bindPort(ProviderPortId) + // check whether the capability for the port can be claimed + abortSystemUnless(err == nil) + + foreach cs in state.consumerStates { + abortSystemUnless(validateChannelIdentifier(cs.channelId)) + chainToChannel[cs.chainId] = cs.channelId + channelToChain[cs.channelId] = cc.chainId + } + + // do not return anything to the consensus engine + return [] +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - An `InitChain` message is received from the consensus engine; the `InitChain` message is sent when the provider chain is first started. +- **Precondition** + - The provider CCV module is in the initial state. +- **Postcondition** + - The capability for the port `ProviderPortId` is claimed. + - For each consumer state in the `ProviderGenesisState`, the initial state is set, i.e., the following mappings `chainToChannel`, `channelToChain` are set. +- **Error Condition** + - The capability for the port `ProviderPortId` cannot be claimed. + - For any consumer state in the `ProviderGenesisState`, the channel ID is not valid (cf. the validation function defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)). + + +#### **[CCV-PCF-SPCCPROP.1]** +```typescript +// PCF: Provider Chain Function +// implements governance proposal Handler +function SpawnConsumerChainProposalHandler(p: SpawnConsumerChainProposal) { + if currentTimestamp() > p.spawnTime { + CreateConsumerClient(p) + } + else { + // store the proposal as a pending spawn proposal + pendingSpawnProposals.Append(p) + } +} +``` +- **Caller** + - `EndBlock()` method of Governance module. +- **Trigger Event** + - A governance proposal `SpawnConsumerChainProposal` has passed (i.e., it got the necessary votes). +- **Precondition** + - True. +- **Postcondition** + - If the spawn time has already passed, `CreateConsumerClient(p)` is invoked, with `p` the `SpawnConsumerChainProposal`. + - Otherwise, the proposal is appended to the list of pending spawn proposals, i.e., `pendingSpawnProposals`. +- **Error Condition** + - None. + + +#### **[CCV-PCF-CRCLIENT.1]** +```typescript +// PCF: Provider Chain Function +// Utility method +function CreateConsumerClient(p: SpawnConsumerChainProposal) { + // check that a client for this chain does not exist + if p.chainId IN chainToClient.Keys() { + return + } + + // create client state + clientState = ClientState{ + chainId: p.chainId, + // use the unbonding period on the provider to compute + // the unbonding period on the consumer + unbondingPeriod: ComputeConsumerUnbondingPeriod(stakingKeeper.UnbondingTime()), + latestHeight: p.initialHeight, // the height when the client was last updated + } + + // create consensus state; + // the validator set is the same as the validator set + // from own consensus state at current height + ownConsensusState = getConsensusState(getCurrentHeight()) + consensusState = ConsensusState{ + validatorSet: ownConsensusState.validatorSet, + } + + // create consumer chain client and store it + clientId = clientKeeper.CreateClient(clientState, consensusState) + chainToClient[p.chainId] = clientId + + // store lockUnbondingOnTimeout flag + lockUnbondingOnTimeout[p.chainId] = p.lockUnbondingOnTimeout +} +``` +- **Caller** + - Either `SpawnConsumerChainProposalHandler` (see [CCV-PCF-SPCCPROP.1](#ccv-pcf-spccprop1)) or `BeginBlockInit()` (see [CCV-PCF-BBLOCK-INIT.1](#ccv-pcf-bblock-init1)). +- **Trigger Event** + - A governance proposal `SpawnConsumerChainProposal` `p` has passed (i.e., it got the necessary votes). +- **Precondition** + - `currentTimestamp() > p.spawnTime`. +- **Postcondition** + - If a client for `p.chainId` already exists, the state is not changed. + - Otherwise, + - a client state is created with `chainId = p.chainId` and `unbondingPeriod` set to `ComputeConsumerUnbondingPeriod(stakingKeeper.UnbondingTime())`; + - a consensus state is created with `validatorSet` set to the validator set the provider chain own consensus state at current height; + - a client of the consumer chain is created and the client ID is added to `chainToClient`; + - `lockUnbondingOnTimeout[p.chainId]` is set to `p.lockUnbondingOnTimeout`. +- **Error Condition** + - None. + +> **Note:** Creating a client of a remote chain requires a `ClientState` and a `ConsensusState` (for an example, take a look at [ICS 7](../../client/ics-007-tendermint-client)). +> `ConsensusState` requires setting a validator set of the remote chain. +> The provider chain uses the fact that the validator set of the consumer chain is the same as its own validator set. +> The rest of information to create a `ClientState` it receives through the governance proposal. + + +#### **[CCV-PCF-BBLOCK-INIT.1]** +```typescript +// PCF: Provider Chain Function +function BeginBlockInit() { + // iterate over the pending spawn proposals and create + // the consumer client if the spawn time has passed + foreach p IN pendingSpawnProposals { + if currentTimestamp() > p.spawnTime { + CreateConsumerClient(p) + pendingSpawnProposals.Remove(p) + } + } +} +``` +- **Caller** + - The `BeginBlock()` method. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - For each `SpawnConsumerChainProposal` `p` in the list of pending spawn proposals `pendingSpawnProposals`, if `currentTimestamp() > p.spawnTime`, then + - `CreateConsumerClient(p)` is invoked; + - `p` is removed from `pendingSpawnProposals`. +- **Error Condition** + - None. + + +#### **[CCV-PCF-COINIT.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenInit( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + version: string): string { + // the channel handshake MUST be initiated by consumer chain + abortTransactionUnless(FALSE) +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanOpenInit` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is always aborted; hence, the state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-PCF-COTRY.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenTry( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string): string { + // validate parameters: + // - only ordered channels allowed + abortTransactionUnless(order == ORDERED) + // - require the portIdentifier to be the port ID the CCV module is bound to + abortTransactionUnless(portIdentifier == ProviderPortId) + + // assert that the counterpartyPortIdentifier matches + // the expected consumer port ID + abortTransactionUnless(counterpartyPortIdentifier == ConsumerPortId) + + // assert that the counterpartyVersion matches the expected version + abortTransactionUnless(counterpartyVersion == ccvVersion) + + // get the client state associated with this client ID in order + // to get access to the consumer chain ID + clientId = getClient(channelIdentifier) + clientState = clientKeeper.GetClientState(clientId) + + // require the CCV channel to be built on top + // of the expected client of the consumer chain + abortTransactionUnless(chainToClient[clientState.chainId] == clientId) + + // require that no other CCV channel exists for this consumer chain + abortTransactionUnless(clientState.chainId NOTIN chainToChannel.Keys()) + + return CCVHandshakeMetadata{ + providerDistributionAccount: GetDistributionAccountAddress(), + version: ccvVersion + } +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanOpenTry` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is aborted if any of the following conditions are true: + - the channel is not ordered; + - `portIdentifier != ProviderPortId`; + - `counterpartyPortIdentifier != ConsumerPortId`; + - `counterpartyVersion != ccvVersion`; + - the channel is not built on top of the client created for this consumer chain; + - another CCV channel for this consumer chain already exists. + - A `CCVHandshakeMetadata` is returned, with `providerDistributionAccount` set to the the address of the distribution module account on the provider chain and `version` set to `ccvVersion`. + - The state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-PCF-COACK.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyVersion: string) { + // the channel handshake MUST be initiated by consumer chain + abortTransactionUnless(FALSE) +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanOpenAck` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is always aborted; hence, the state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-PCF-COCONFIRM.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // get the client state associated with this client ID in order + // to get access to the consumer chain ID + clientId = getClient(channelIdentifier) + clientState = clientKeeper.GetClientState(clientId) + + // Verify that there isn't already a CCV channel for the consumer chain + // If there is, then close the channel. + if clientState.chainId IN chainToChannel { + channelKeeper.ChanCloseInit(channelIdentifier) + abortTransactionUnless(FALSE) + } + + // set channel mappings + chainToChannel[clientState.chainId] = channelIdentifier + channelToChain[channelIdentifier] = clientState.chainId + // set initialHeights for this consumer chain + initialHeights[chainId] = getCurrentHeight() +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanOpenConfirm` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - If a CCV channel for this consumer chain already exists, then + - the channel closing handshake is initiated for the underlying channel; + - the transaction is aborted. + - Otherwise, + - the channel mappings are set, i.e., `chainToChannel` and `channelToChain`; + - `initialHeights[chainId]` is set to the current height. +- **Error Condition** + - None. + +--- + + +#### **[CCV-CCF-INITG.1]** +```typescript +// CCF: Consumer Chain Function +// implements the AppModule interface +function InitGenesis(gs: ConsumerGenesisState): [ValidatorUpdate] { + // ValidateGenesis + // - contains a valid providerClientState + abortSystemUnless(gs.providerClientState != nil AND gs.providerClientState.Valid()) + // - contains a valid providerConsensusState + abortSystemUnless(gs.providerConsensusState != nil AND gs.providerConsensusState.Valid()) + // - contains a non-empty initial validator set + abortSystemUnless(gs.initialValSet NOT empty) + // - contains an initial validator set that matches + // the validator set in the providerConsensusState (e.g., ICS 7) + abortSystemUnless(gs.initialValSet == gs.providerConsensusState.validatorSet) + + // bind to ConsumerPortId port + err = portKeeper.bindPort(ConsumerPortId) + // check whether the capability for the port can be claimed + abortSystemUnless(err == nil) + + // create client of the provider chain + clientId = clientKeeper.CreateClient(gs.providerClientState, gs.providerConsensusState) + + // store the ID of the client of the provider chain + providerClient = clientId + + // compute (and store) the consumer unbonding period from the provider unbonding period + consumerUnbondingPeriod = ComputeConsumerUnbondingPeriod(gs.providerClientState.unbondingTime) + + // set default value for HtoVSC + HtoVSC[getCurrentHeight()] = 0 + + // set the initial validator set for the consumer chain + foreach val IN gs.initialValSet { + ccVal := CrossChainValidator{ + address: hash(val.pubKey), + power: val.power + } + validatorSet[ccVal.address] = ccVal + } + + return gs.initialValSet +} +``` +- **Caller** + - The ABCI application. +- **Trigger Event** + - An `InitChain` message is received from the consensus engine; the `InitChain` message is sent when the consumer chain is first started. +- **Precondition** + - The consumer CCV module is in the initial state. +- **Postcondition** + - The capability for the port `ConsumerPortId` is claimed. + - A client of the provider chain is created and the client ID is stored into `providerClient`. + - `consumerUnbondingPeriod` is set to `ComputeConsumerUnbondingPeriod(gs.providerClientState.unbondingTime)`. + - `HtoVSC` for the current block is set to `0`. + - The `validatorSet` mapping is populated with the initial validator set. + - The initial validator set is returned to the consensus engine. +- **Error Condition** + - The genesis state contains no valid provider client state, where the validity is defined in the corresponding client specification (e.g., [ICS 7](../../client/ics-007-tendermint-client)). + - The genesis state contains no valid provider consensus state, where the validity is defined in the corresponding client specification (e.g., [ICS 7](../../client/ics-007-tendermint-client)).. + - The genesis state contains an empty initial validator set. + - The genesis state contains an initial validator set that does not match the validator set in the provider consensus state. + - The capability for the port `ConsumerPortId` cannot be claimed. + +> **Note**: CCV assumes that all the correct validators in the initial validator set of the consumer chain receive the _same_ consumer chain binary and consumer chain genesis state. +> Although the mechanism of disseminating the binary and the genesis state is outside the scope of this specification, a possible approach would entail including this information in the governance proposal on the provider chain. + + +#### **[CCV-CCF-COINIT.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenInit( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + version: string): string { + // ensure provider channel hasn't already been created + abortTransactionUnless(providerChannel == "") + + // validate parameters: + // - only ordered channels allowed + abortTransactionUnless(order == ORDERED) + // - require the portIdentifier to be the port ID the CCV module is bound to + abortTransactionUnless(portIdentifier == ConsumerPortId) + // - require the version to be the expected version + abortTransactionUnless(version == "" OR version == ccvVersion) + + // assert that the counterpartyPortIdentifier matches + // the expected consumer port ID + abortTransactionUnless(counterpartyPortIdentifier == ProviderPortId) + + // require that the client ID of the client associated + // with this channel matches the expected provider client id + clientId = getClient(channelIdentifier) + abortTransactionUnless(providerClient != clientId) + + return ccvVersion +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanOpenInit` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is aborted if any of the following conditions are true: + - `providerChannel` is already set; + - `portIdentifier != ConsumerPortId`; + - `version` is set but not to the expected version; + - `counterpartyPortIdentifier != ProviderPortId`; + - the client associated with this channel is not the expected provider client. + - `ccvVersion` is returned. + - The state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-CCF-COTRY.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenTry( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string): string { + // the channel handshake MUST be initiated by consumer chain + abortTransactionUnless(FALSE) +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanOpenTry` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is always aborted; hence, the state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-CCF-COACK.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyVersion: string) { + // ensure provider channel hasn't already been created + abortTransactionUnless(providerChannel == "") + + // the version must be encoded in JSON format (as defined in ICS4) + md = UnmarshalJSON(counterpartyVersion) + + // assert that the counterpartyVersion matches the expected version + abortTransactionUnless(md.version == ccvVersion) + + // set the address of the distribution module account on the provider chain + providerDistributionAccount = md.providerDistributionAccount + + // initiate opening handshake for the distribution token transfer channel + // over the same connection as the CCV channel + // i.e., ChanOpenInit (as required by ICS20) + distributionChannelId = channelKeeper.ChanOpenInit( + UNORDERED, // order + channelKeeper.GetConnectionHops(channelIdentifier), // connectionHops: same as the CCV channel + "transfer", // portIdentifier + "transfer", // counterpartyPortIdentifier + "ics20-1" // version + ) +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanOpenAck` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - `counterpartyVersion` is unmarshaled into a `CCVHandshakeMetadata` structure `md`. + - The transaction is aborted if any of the following conditions are true: + - `providerChannel` is already set; + - `md.version != ccvVersion`. + - The address of the distribution module account on the provider chain is set to `md.providerDistributionAccount`. + - The distribution token transfer channel opening handshake is initiated and `distributionChannelId` is set to the resulting channel ID. +- **Error Condition** + - None. + +> **Note:** The initialization sub-protocol on the consumer chain finalizes on receiving the first `VSCPacket` and setting `providerChannel` to the ID of the channel on which it receives the packet (see `onRecvVSCPacket` method). + + +#### **[CCV-CCF-COCONFIRM.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanOpenConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // the channel handshake MUST be initiated by consumer chain + abortTransactionUnless(FALSE) +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanOpenConfirm` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is always aborted; hence, the state is not changed. +- **Error Condition** + - None. + +### Consumer Chain Removal +[↑ Back to Outline](#outline) + + +#### **[CCV-PCF-STCCPROP.1]** +```typescript +// PCF: Provider Chain Function +// implements governance proposal Handler +function StopConsumerChainProposalHandler(p: StopConsumerChainProposal) { + if currentTimestamp() >= p.stopTime { + // stop the consumer chain and do not lock the unbonding + StopConsumerChain(p.chainId, false) + } + else { + // store the proposal as a pending stop proposal + pendingStopProposals.Append(p) + } +} +``` +- **Caller** + - `EndBlock()` method of Governance module. +- **Trigger Event** + - A governance proposal `StopConsumerChainProposal` has passed (i.e., it got the necessary votes). +- **Precondition** + - True. +- **Postcondition** + - If the spawn time has already passed, `StopConsumerChain(p.chainId, false)` is invoked, with `p` the `StopConsumerChainProposal`. + - Otherwise, the proposal is appended to the list of pending stop proposals, i.e., `pendingStopProposals`. +- **Error Condition** + - None. + + +#### **[CCV-PCF-STCC.1]** +```typescript +// PCF: Provider Chain Function +function StopConsumerChain(chainId: string, lockUnbonding: Bool) { + // check that a client for chainId exists + if chainId NOT IN chainToClient.Keys() { + return + } + + // cleanup state + chainToClient.Remove(chainId) + lockUnbondingOnTimeout.Remove(chainId) + if chainId IN chainToChannel.Keys() { + // CCV channel is established + channelToChain.Remove(chainToChannel[chainId]) + channelKeeper.ChanCloseInit(chainToChannel[chainId]) + chainToChannel.Remove(chainId) + } + pendingVSCPackets.Remove(chainId) + initialHeights.Remove(chainId) + downtimeSlashRequests.Remove(chainId) + + if !lockUnbonding { + // remove chainId form all outstanding unbonding operations + foreach id IN vscToUnbondingOps[(chainId, _)] { + unbondingOps[id].unbondingChainIds.Remove(chainId) + // if the unbonding operation has unbonded on all consumer chains + if unbondingOps[id].unbondingChainIds.IsEmpty() { + // notify the Staking module that the unbonding can complete + stakingKeeper.UnbondingCanComplete(id) + // remove unbonding operation + unbondingOps.Remove(id) + } + } + // clean up vscToUnbondingOps mapping + vscToUnbondingOps.Remove((chainId, _)) + } +} +``` +- **Caller** + - `StopConsumerChainProposalHandler` (see [CCV-PCF-STCCPROP.1](#ccv-pcf-stccprop1)) + or `BeginBlockCCR()` (see [CCV-PCF-BBLOCK-CCR.1](#ccv-pcf-bblock-ccr1)) + or `onTimeoutVSCPacket()` (see [CCV-PCF-TOVSC.1](#ccv-pcf-tovsc1)). +- **Trigger Event** + - Either a governance proposal to stop the consumer chain with `chainId` has passed (i.e., it got the necessary votes) or a packet sent on the CCV channel to the consumer chain with `chainId` has timed out. +- **Precondition** + - True. +- **Postcondition** + - If a client for `p.chainId` does not exist, the state is not changed. + - Otherwise, + - the client ID mapped to `chainId` in `chainToClient` is removed; + - the value mapped to `chainId` in `lockUnbondingOnTimeout` is removed; + - if the CCV channel to the consumer chain with `chainId` is established, then + - the chain ID mapped to `chainToChannel[chainId]` in `channelToChain` is removed; + - the channel closing handshake is initiated for the CCV channel; + - the channel ID mapped to `chainId` in `chainToChannel` is removed. + - all the `VSCPacketData` mapped to `chainId` in `pendingVSCPackets` are removed; + - the height mapped to `chainId` in `initialHeights` is removed; + - `downtimeSlashRequests[chainId]` is emptied; + - if `lockUnbonding == false`, then + - `chainId` is removed from all outstanding unbonding operations; + - if an outstanding unbonding operation has matured on all consumer chains, + - the `UnbondingCanComplete()` method of the Staking module is invoked; + - the unbonding operation is removed from `unbondingOps`; + - all the entries with `chainId` are removed from the `vscToUnbondingOps` mapping. +- **Error Condition** + - None + +> **Note**: Invoking `StopConsumerChain(chainId, lockUnbonding)` with `lockUnbonding == FALSE` entails that all outstanding unbonding operations can complete before `consumerUnbondingPeriod` elapses on the consumer chain with `chainId`. +> Thus, invoking `StopConsumerChain(chainId, false)` for any `chainId` MAY violate the *Bond-Based Consumer Voting Power* and *Slashable Consumer Misbehavior* properties (see the [System Properties](./system_model_and_properties.md#system-properties) section). +> +> `StopConsumerChain(chainId, false)` is invoked in two scenarios (see Trigger Event above). +> - In the first scenario (i.e., a governance proposal to stop the consumer chain with `chainId`), the validators on the provider chain MUST make sure that it is safe to stop the consumer chain. +> Since a governance proposal needs a majority of the voting power to pass, the safety of invoking `StopConsumerChain(chainId, false)` is ensured by the *Safe Blockchain* assumption (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +> +> - The second scenario (i.e., a timeout) is only possible if the *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section), +> which is necessary to guarantee both the *Bond-Based Consumer Voting Power* and *Slashable Consumer Misbehavior* properties (see the [Assumptions](./system_model_and_properties.md#correctness-reasoning) section). + + +#### **[CCV-PCF-BBLOCK-CCR.1]** +```typescript +// PCF: Provider Chain Function +function BeginBlockCCR() { + // iterate over the pending stop proposals + // and stop the consumer chain + foreach p IN pendingStopProposals { + if currentTimestamp() > p.stopTime { + // stop the consumer chain and do not lock the unbonding + StopConsumerChain(p.chainId, false) + pendingStopProposals.Remove(p) + } + } +} +``` +- **Caller** + - The `BeginBlock()` method. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - For each `StopConsumerChainProposal` `p` in the list of pending spawn proposals `pendingStopProposals`, if `currentTimestamp() > p.stopTime`, then + - `StopConsumerChain(p.chainId, false)` is invoked; + - `p` is removed from `pendingStopProposals`. +- **Error Condition** + - None. + + +#### **[CCV-PCF-CCINIT.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanCloseInit( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // Disallow user-initiated channel closing + abortTransactionUnless(FALSE) +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanCloseInit` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The transaction is always aborted; hence, the state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-PCF-CCCONFIRM.1]** +```typescript +// PCF: Provider Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanCloseConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // do nothing +} +``` +- **Caller** + - The provider IBC routing module. +- **Trigger Event** + - The provider IBC routing module receives a `ChanCloseConfirm` message on a port the provider CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The state is not changed. +- **Error Condition** + - None. + +--- + + +#### **[CCV-CCF-BBLOCK-CCR.1]** +```typescript +// CCF: Consumer Chain Function +function BeginBlockCCR() { + if providerChannel != "" AND channelKeeper.GetChannelState(providerChannel) == CLOSED { + // the CCV channel was established, but it was then closed; + // the consumer chain is no longer safe + + // cleanup state, e.g., + // providerChannel = "" + + // shut down consumer chain + abortSystemUnless(FALSE) + } + } +} +``` +- **Caller** + - The `BeginBlock()` method. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - If the CCV was established, but then was moved to the `CLOSED` state, then the state of the consumer CCV module is cleaned up, e.g., the `providerChannel` is unset. +- **Error Condition** + - If the CCV was established, but then was moved to the `CLOSED` state. + +> **Note**: Once the CCV channel is closed, the provider chain can no longer provider security. As a result, the consumer chain MUST be shut down. +> For an example of how to do this in practice, see the Cosmos SDK [implementation](https://github.com/cosmos/cosmos-sdk/blob/0c0b4da114cf73ef5ae1ac5268241d69e8595a60/x/upgrade/abci.go#L71). + + +#### **[CCV-CCF-CCINIT.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanCloseInit( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // allow relayers to close duplicate OPEN channels, + // if the provider channel has already been established + if providerChannel == "" || providerChannel == channelIdentifier { + // user cannot close channel + abortTransactionUnless(FALSE) + } +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanCloseInit` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - If `providerChannel` is not set or `providerChannel` matches the ID of the channel the `ChanCloseInit` message was received on, then the transaction is aborted. + - The state is not changed. +- **Error Condition** + - None. + + +#### **[CCV-CCF-CCCONFIRM.1]** +```typescript +// CCF: Consumer Chain Function +// implements the ModuleCallbacks interface defined in ICS26 +function onChanCloseConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // do nothing +} +``` +- **Caller** + - The consumer IBC routing module. +- **Trigger Event** + - The consumer IBC routing module receives a `ChanCloseConfirm` message on a port the consumer CCV module is bounded to. +- **Precondition** + - True. +- **Postcondition** + - The state is not changed. +- **Error Condition** + - None. + + + +### Validator Set Update +[↑ Back to Outline](#outline) + +The *validator set update* sub-protocol enables the provider chain +- to update the consumer chain on the voting power granted to validators on the provider chain +- and to ensure the correct completion of unbonding operations for validators that produce blocks on the consumer chain. + + +#### **[CCV-PCF-EBLOCK-VSU.1]** +```typescript +// PCF: Provider Chain Function +function EndBlockVSU() { + // get list of validator updates from the provider Staking module + valUpdates = stakingKeeper.GetValidatorUpdates() + + // iterate over all consumer chains registered with this provider chain + foreach chainId in chainToClient.Keys() { + // check whether there are changes in the validator set; + // note that this also entails unbonding operations + // w/o changes in the voting power of the validators in the validator set + if len(valUpdates) != 0 OR len(vscToUnbondingOps[(chainId, vscId)]) != 0 { + // create VSCPacket data + data = VSCPacketData{ + id: vscId, + updates: valUpdates, + downtimeSlashAcks: downtimeSlashRequests[chainId] + } + downtimeSlashRequests.Remove(chainId) + + // add VSCPacket data to the list of pending VSCPackets + pendingVSCPackets.Append(chainId, data) + } + + // check whether there is an established CCV channel to the consumer chain + if chainId IN chainToChannel.Keys() { + // get the channel ID for the given consumer chain ID + channelId = chainToChannel[chainId] + + foreach data IN pendingVSCPackets[chainId] { + // send data using the interface exposed by ICS-4 + channelKeeper.sendPacket( + portKeeper.getCapability(portKeeper.portPath(ProviderPortId)), + ProviderPortId, // source port ID + channelId, // source channel ID + zeroTimeoutHeight, + ccvTimeoutTimestamp, + data + ) + } + + // remove pending VSCPackets + pendingVSCPackets.Remove(chainId) + } + } + // increment VSC ID + vscId++ +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - A list of validator updates `valUpdates` is obtained from the provider Staking module. + - For every consumer chain with `chainId` + - If either `valUpdates` is not empty or there were unbonding operations initiated during this block, then + - a `VSCPacket` data `data` is created such that `data.id = vscId`, `data.updates = valUpdates`, and `data.downtimeSlashAcks = downtimeSlashRequests[chainId]`; + - `downtimeSlashRequests[chainId]` is emptied; + - `packetData` is appended to the list of pending `VSCPacket`s associated to `chainId`, i.e., `pendingVSCPackets[chainId]`. + - If there is an established CCV channel for the the consumer chain with `chainId`, then + - for each `VSCPacketData` in the list of pending VSCPackets associated to `chainId` + - a packet with the `VSCPacketData` is sent on the channel associated with the consumer chain with `chainId`; + - all the pending VSCPackets associated to `chainId` are removed. + - `vscId` is incremented. +- **Error Condition** + - None. + + +#### **[CCV-PCF-ACKVSC.1]** +```typescript +// PCF: Provider Chain Function +function onAcknowledgeVSCPacket(packet: Packet, ack: bytes) { + // providing the VSC with id packet.data.id can fail, + // i.e., ack == VSCPacketError, + // only if the VSCPacket was sent on a channel + // other than the established CCV channel; + // that should never happen, see EndBlock() + abortSystemUnless(ack != VSCPacketError) +} +``` +- **Caller** + - The `onAcknowledgePacket()` method. +- **Trigger Event** + - The provider IBC routing module receives an acknowledgement of a `VSCPacket` on a channel owned by the provider CCV module. +- **Precondition** + - True. +- **Postcondition** + - The state is not changed. +- **Error Condition** + - The acknowledgement is `VSCPacketError`. + + +#### **[CCV-PCF-TOVSC.1]** +```typescript +// PCF: Provider Chain Function +function onTimeoutVSCPacket(packet: Packet) { + // cleanup state + abortTransactionUnless(packet.getDestinationChannel() IN channelToChain.Keys()) + chainId = channelToChain[packet.getDestinationChannel()] + // stop the consumer chain and use lockUnbondingOnTimeout + // to decide whether to lock the unbonding + StopConsumerChain(chainId, lockUnbondingOnTimeout[chainId]) +} +``` +- **Caller** + - The `onTimeoutPacket()` method. +- **Trigger Event** + - A `VSCPacket` sent on a channel owned by the provider CCV module timed out as a result of either + - the timeout height or timeout timestamp passing on the consumer chain without the packet being received (see `timeoutPacket` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#sending-end)); + - or the channel being closed without the packet being received (see `timeoutOnClose` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#timing-out-on-close)). +- **Precondition** + - The *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +- **Postcondition** + - The transaction is aborted if the ID of the channel on which the packet was sent is not mapped to a chain ID (in `channelToChain`). + - `StopConsumerChain(chainId, lockUnbondingOnTimeout[chainId])` is invoked, where `chainId = channelToChain[packet.getDestinationChannel()]`. +- **Error Condition** + - None + + +#### **[CCV-PCF-RCVMAT.1]** +```typescript +// PCF: Provider Chain Function +function onRecvVSCMaturedPacket(packet: Packet): bytes { + // get the ID of the consumer chain mapped to this channel ID + abortTransactionUnless(packet.getDestinationChannel() IN channelToChain.Keys()) + chainId = channelToChain[packet.getDestinationChannel()] + + // iterate over the unbonding operations mapped to + // this chainId and vscId (i.e., packet.data.id) + foreach op in GetUnbondingsFromVSC(chainId, packet.data.id) { + // remove the consumer chain from + // the list of consumer chain that are still unbonding + op.unbondingChainIds.Remove(chainId) + // if the unbonding operation has unbonded on all consumer chains + if op.unbondingChainIds.IsEmpty() { + // notify the Staking module that the unbonding can complete + stakingKeeper.UnbondingCanComplete(op.id) + // remove unbonding operation + unbondingOps.Remove(op.id) + } + } + // clean up vscToUnbondingOps mapping + vscToUnbondingOps.Remove((chainId, vscId)) + + return VSCMaturedPacketSuccess +} +``` +- **Caller** + - The `onRecvPacket()` method. +- **Trigger Event** + - The provider IBC routing module receives a `VSCMaturedPacket` on a channel owned by the provider CCV module. +- **Precondition** + - True. +- **Postcondition** + - The transaction is aborted if the channel on which the packet was received is not an established CCV channel (i.e., not in `channelToChain`). + - `chainId` is set to the ID of the consumer chain mapped to the channel on which the packet was received. + - For each unbonding operation `op` returned by `GetUnbondingsFromVSC(chainId, packet.data.id)` + - `chainId` is removed from `op.unbondingChainIds`; + - if `op.unbondingChainIds` is empty, + - the `UnbondingCanComplete()` method of the Staking module is invoked; + - the entry `op` is removed from `unbondingOps`. + - `(chainId, vscId)` is removed from `vscToUnbondingOps`. + - A successful acknowledgment is returned. +- **Error Condition** + - None. + + +#### **[CCV-PCF-GETUBS.1]** +```typescript +// PCF: Provider Chain Function +// Utility method +function GetUnbondingsFromVSC( + chainId: Identifier, + _vscId: uint64): [UnbondingOperation] { + // get all unbonding operations associated with (chainId, _vscId) + ops = [] + foreach id in vscToUnbondingOps[(chainId, _vscId)] { + // get the unbonding operation with this ID + op = unbondingOps[id] + // append the operation to the list of operations to be returned + ops.Append(op) + } + return ops +} +``` +- **Caller** + - The `onRecvVSCMaturedPacket()` method. +- **Trigger Event** + - The provider IBC routing module receives a `VSCMaturedPacket` on a channel owned by the provider CCV module. +- **Precondition** + - The provider CCV module received a `VSCMaturedPacket` `P` from a consumer chain with ID `chainId`, such that `P.data.id == _vscId`. +- **Postcondition** + - Return the list of unbonding operations mapped to `(chainId, _vscId)`. +- **Error Condition** + - None. + + +#### **[CCV-PCF-HOOK-AFUBOPCR.1]** +```typescript +// PCF: Provider Chain Function +// implements a Staking module hook +function AfterUnbondingInitiated(opId: uint64) { + // get the IDs of all consumer chains registered with this provider chain + chainIds = chainToClient.Keys() + if len(chainIds) > 0 { + // create and store a new unbonding operation + unbondingOps[opId] = UnbondingOperation{ + id: opId, + unbondingChainIds: chainIds + } + // add the unbonding operation id to vscToUnbondingOps + foreach chainId in chainIds { + vscToUnbondingOps[(chainId, vscId)].Append(opId) + } + + // ask the Staking module to wait for this operation + // to reach maturity on the consumer chains + stakingKeeper.PutUnbondingOnHold(opId) + } +} +``` +- **Caller** + - The Staking module. +- **Trigger Event** + - An unbonding operation with id `opId` is initiated. +- **Precondition** + - True. +- **Postcondition** + - `chainIds` is set to the list of all consumer chains registered with this provider chain, i.e., `chainToClient.Keys()`. + - If there is at least one consumer chain in `chainIds`, then + - an `UnbondingOperation` `op` is created and added to `unbondingOps`, such that `op.id = opId` and `op.unbondingChainIds = chainIds`. + - `opId` is appended to every list in `vscToUnbondingOps[(chainId, vscId)]`, where `chainId` is an ID of a consumer chains registered with this provider chain and `vscId` is the current VSC ID. + - the `PutUnbondingOnHold(opId)` of the Staking module is invoked. +- **Error Condition** + - None. + +--- + + +#### **[CCV-CCF-RCVVSC.1]** +```typescript +// CCF: Consumer Chain Function +function onRecvVSCPacket(packet: Packet): bytes { + // check whether the packet was sent on the CCV channel + if providerChannel != "" && providerChannel != packet.getDestinationChannel() { + // packet sent on a channel other than the established provider channel; + // close channel and return error acknowledgement + channelKeeper.ChanCloseInit(packet.getDestinationChannel()) + return VSCPacketError + } + + // set HtoVSC mapping + HtoVSC[getCurrentHeight() + 1] = packet.data.id + + // check whether the CCV channel is established + if providerChannel == "" { + // set the channel as the provider channel + providerChannel = packet.getDestinationChannel() + // send pending slash requests + SendPendingSlashRequests() + } + + // store the list of updates from the packet + pendingChanges.Append(packet.data.updates) + + // calculate and store the maturity timestamp for the VSC + maturityTimestamp = currentTimestamp().Add(consumerUnbondingPeriod) + maturingVSCs.Add(packet.data.id, maturityTimestamp) + + // reset outstandingDowntime for validators in packet.data.downtimeSlashAcks + foreach valAddr IN packet.data.downtimeSlashAcks { + outstandingDowntime[valAddr] = FALSE + } + + return VSCPacketSuccess +} +``` +- **Caller** + - The `onRecvPacket()` method. +- **Trigger Event** + - The consumer IBC routing module receives a `VSCPacket` on a channel owned by the consumer CCV module. +- **Precondition** + - True. +- **Postcondition** + - If `providerChannel` is set and does not match the channel (with ID `packet.getDestinationChannel()`) on which the packet was received, then + - the closing handshake for the channel with ID `packet.getDestinationChannel()` is initiated; + - an error acknowledgement is returned. + - Otherwise, + - the height of the subsequent block is mapped to `packet.data.id` (i.e., the `HtoVSC` mapping) ; + - if `providerChannel` is not set, then + - the CCV channel is marked as established, i.e., `providerChannel = packet.getDestinationChannel()`; + - the pending slash requests are sent to the provider chain (see [CCV-CCF-SNDPESLASH.1](#ccv-ccf-sndpeslash1)); + - `packet.data.updates` are appended to `pendingChanges`; + - `(packet.data.id, maturityTimestamp)` is added to `maturingVSCs`, where `maturityTimestamp = currentTimestamp() + consumerUnbondingPeriod`; + - for each `valAddr` in the slash acknowledgments received from the provider chain, `outstandingDowntime[valAddr]` is set to false; + - a successful acknowledgement is returned. +- **Error Condition** + - None. + + +#### **[CCV-CCF-ACKMAT.1]** +```typescript +// CCF: Consumer Chain Function +function onAcknowledgeVSCMaturedPacket(packet: Packet, ack: bytes) { + // notifications of VSC maturity cannot fail by construction + abortSystemUnless(ack != VSCMaturedPacketError) +} +``` +- **Caller** + - The `onAcknowledgePacket()` method. +- **Trigger Event** + - The consumer IBC routing module receives an acknowledgement of a `VSCMaturedPacket` on a channel owned by the consumer CCV module. +- **Precondition** + - True. +- **Postcondition** + - The state is not changed. +- **Error Condition** + - The acknowledgement is `VSCMaturedPacketError`. + + +#### **[CCV-CCF-TOMAT.1]** +```typescript +// CCF: Consumer Chain Function +function onTimeoutVSCMaturedPacket(packet Packet) { + // the CCV channel state is changed to CLOSED + // by the IBC handler (since the channel is ORDERED) +} +``` +- **Caller** + - The `onTimeoutPacket()` method. +- **Trigger Event** + - A `VSCMaturedPacket` sent on a channel owned by the consumer CCV module timed out as a result of either + - the timeout height or timeout timestamp passing on the provider chain without the packet being received (see `timeoutPacket` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#sending-end)); + - or the channel being closed without the packet being received (see `timeoutOnClose` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#timing-out-on-close)). +- **Precondition** + - The *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +- **Postcondition** + - The state is not changed. +- **Error Condition** + - None + + +#### **[CCV-CCF-EBLOCK-VSU.1]** +```typescript +// CCF: Consumer Chain Function +function EndBlockVSU(): [ValidatorUpdate] { + // unbond mature packets if the CCV channel is established + if providerChannel != "" { + UnbondMaturePackets() + } + + if pendingChanges.IsEmpty() { + // do nothing + return [] + } + // aggregate the pending changes + changes = pendingChanges.Aggregate() + // Note: in the implementation, the aggregation is done directly + // when receiving a VSCPacket via the AccumulateChanges method. + + // remove all pending changes + pendingChanges.RemoveAll() + + // update validatorSet + UpdateValidatorSet(changes) + + // return the validator set updates + return changes +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - If `providerChannel != ""`, `UnbondMaturePackets()` is invoked; + - If `pendingChanges` is empty, the state is not changed. + - Otherwise, + - the pending changes are aggregated and stored in `changes`; + - `pendingChanges` is emptied; + - `UpdateValidatorSet(changes)` is invoked; + - `changes` is returned. +- **Error Condition** + - None. + + +#### **[CCV-CCF-UPVALS.1]** +```typescript +// CCF: Consumer Chain Function +function UpdateValidatorSet(changes: [ValidatorUpdate]) { + foreach update IN changes { + addr := hash(update.pubKey) + if addr NOT IN validatorSet.Keys() { + // new validator bonded; + // note that due pendingChanges.Aggregate(), + // a validator can be added to the valset and + // then removed in the subsequent block, + // resulting in update.power == 0 + if update.power > 0 { + // add new CrossChainValidator to validator set + val := CrossChainValidator{ + address: addr, + power: update.power + } + validatorSet[addr] = val + // call AfterCCValidatorBonded hook + AfterCCValidatorBonded(addr) + } + } + else if update.power == 0 { + // existing validator begins unbonding + validatorSet.Remove(addr) + // call AfterCCValidatorBeginUnbonding hook + AfterCCValidatorBeginUnbonding(addr) + } + else { + validatorSet[addr].power = update.power + } + } +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine. +- **Precondition** + - `changes` contains the aggregated validator updates from `pendingChanges` before it was emptied. +- **Postcondition** + - For each validator `update` in `changes`, + - if the validator is not in the validator set and `update.power > 0`, then + - a new `CrossChainValidator` is added to `validatorSet`; + - the `AfterCCValidatorBonded` hook is called; + - otherwise, if the validator's new power is `0`, then, + - the validator is removed from `validatorSet`; + - the `AfterCCValidatorBeginUnbonding` hook is called; + - otherwise, the validator's power is updated. +- **Error Condition** + - None. + + +#### **[CCV-CCF-UMP.1]** +```typescript +// CCF: Consumer Chain Function +function UnbondMaturePackets() { + foreach (id, ts) in maturingVSCs.SortedByMaturityTime() { + if currentTimestamp() < ts { + break // stop loop + } + // create VSCMaturedPacketData + packetData = VSCMaturedPacketData{id: id} + + // send VSCMaturedPacketData using the interface exposed by ICS-4 + channelKeeper.sendPacket( + portKeeper.getCapability(portKeeper.portPath(ConsumerPortId)), + ConsumerPortId, // source port ID + providerChannel, // source channel ID + zeroTimeoutHeight, + ccvTimeoutTimestamp, + packetData + ) + + // remove entry from the list + maturingVSCs.Remove(id, ts) + } +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine. +- **Precondition** + - The CCV channel to the provider chain is established, i.e., `providerChannel != ""`. +- **Postcondition** + - For each `(id, ts)` in the list of maturing VSCs sorted by maturity timestamps + - if `currentTimestamp() < ts`, the loop is stopped; + - a `VSCMaturedPacketData` packet data is created; + - a packet with the created `VSCMaturedPacketData` is sent to the provider chain; + - the tuple `(id, ts)` is removed from `maturingVSCs`. +- **Error Condition** + - None. + +### Consumer Initiated Slashing +[↑ Back to Outline](#outline) + + +#### **[CCV-PCF-EBLOCK-CIS.1]** +```typescript +// PCF: Provider Chain Function +function EndBlockCIS() { + // set VSCtoH mapping + VSCtoH[vscId] = getCurrentHeight() + 1 +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `vscId` is mapped to the height of the subsequent block. +- **Error Condition** + - None. + + +#### **[CCV-PCF-RCVSLASH.1]** +```typescript +// PCF: Provider Chain Function +function onRecvSlashPacket(packet: Packet): bytes { + // check whether the packet was received on an established CCV channel + if packet.getDestinationChannel() NOT IN channelToChain.Keys() { + // packet received on a non-established channel; incorrect behavior + channelKeeper.ChanCloseInit(packet.getDestinationChannel()) + return SlashPacketError + } + + // get the height that maps to the VSC ID in the packet data + if packet.data.vscId == 0 { + // the infraction happened before sending any VSC to this chain + chainId = channelToChain[packet.getDestinationChannel()] + infractionHeight = initialHeights[chainId] + } + else { + infractionHeight = VSCtoH[packet.data.vscId] + } + + // request the Slashing module to slash the validator + // using the slashFactor set on the provider chain + slashFactor = slashingKeeper.GetSlashFactor(packet.data.downtime) + slashingKeeper.Slash( + packet.data.valAddress, + infractionHeight, + packet.data.valPower, + slashFactor)) + + // request the Slashing module to jail the validator + // using the jailTime set on the provider chain + jailTime = slashingKeeper.GetJailTime(packet.data.downtime) + slashingKeeper.JailUntil(packet.data.valAddress, currentTimestamp() + jailTime) + + if packet.data.downtime { + // add validator to list of downtime slash requests for chainId + downtimeSlashRequests[chainId].Append(packet.data.valAddress) + } + + return SlashPacketSuccess +} +``` +- **Caller** + - The `onRecvPacket()` method. +- **Trigger Event** + - The provider IBC routing module receives a `SlashPacket` on a channel owned by the provider CCV module. +- **Precondition** + - True. +- **Postcondition** + - If the channel the packet was received on is not an established CCV channel, then + - the channel closing handshake is initiated; + - an error acknowledgment is returned. + - Otherwise, + - if `packet.data.vscId == 0`, `infractionHeight` is set to `initialHeights[chainId]`, with `chainId = channelToChain[packet.getDestinationChannel()]`, i.e., the height when the CCV channel to this consumer chain is established; + - otherwise, `infractionHeight` is set to `VSCtoH[packet.data.vscId]`, i.e., the height at which the voting power was last updated by the validator updates in the VSC with ID `packet.data.vscId`; + - a request is made to the Slashing module to slash `slashFactor` of the tokens bonded at `infractionHeight` by the validator with address `packet.data.valAddress`, where `slashFactor` is the slashing factor set on the provider chain; + - a request is made to the Slashing module to jail the validator with address `packet.data.valAddress` for a period `jailTime`, where `jailTime` is the jailing time set on the provider chain; + - if the slash request is for downtime, the validator's address `packet.data.valAddress` is added to the list of downtime slash requests from this `chainId`; + - a successful acknowledgment is returned. +- **Error Condition** + - None. + +--- + + +#### **[CCV-CCF-BBLOCK-CIS.1]** +```typescript +// CCF: Consumer Chain Function +function BeginBlockCIS() { + HtoVSC[getCurrentHeight() + 1] = HtoVSC[getCurrentHeight()] +} +``` +- **Caller** + - The `BeginBlock()` method. +- **Trigger Event** + - A `BeginBlock` message is received from the consensus engine; `BeginBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - `HtoVSC` for the subsequent block height is set to the same VSC ID as the current block height. +- **Error Condition** + - None. + + +#### **[CCV-CCF-ACKSLASH.1]** +```typescript +// CCF: Consumer Chain Function +function onAcknowledgeSlashPacket(packet: Packet, ack: bytes) { + // slash request fail, i.e., ack == SlashPacketError, + // only if the SlashPacket was sent on a channel + // other than the established CCV channel; + // that should never happen, + // see SendSlashRequest() and SendPendingSlashRequests() + abortSystemUnless(ack != SlashPacketError) +} +``` +- **Caller** + - The `onAcknowledgePacket()` method. +- **Trigger Event** + - The consumer IBC routing module receives an acknowledgement of a `SlashPacket` on a channel owned by the consumer CCV module. +- **Precondition** + - True. +- **Postcondition** + - The state is not changed. +- **Error Condition** + - The acknowledgement is `SlashPacketError`. + + +#### **[CCV-CCF-TOSLASH.1]** +```typescript +// CCF: Consumer Chain Function +function onTimeoutSlashPacket(packet Packet) { + // the CCV channel state is changed to CLOSED + // by the IBC handler (since the channel is ORDERED) +} +``` +- **Caller** + - The `onTimeoutPacket()` method. +- **Trigger Event** + - A `SlashPacket` sent on a channel owned by the consumer CCV module timed out as a result of either + - the timeout height or timeout timestamp passing on the provider chain without the packet being received (see `timeoutPacket` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#sending-end)); + - or the channel being closed without the packet being received (see `timeoutOnClose` defined in [ICS4](../../core/ics-004-channel-and-packet-semantics/README.md#timing-out-on-close)). +- **Precondition** + - The *Correct Relayer* assumption is violated (see the [Assumptions](./system_model_and_properties.md#assumptions) section). +- **Postcondition** + - The state is not changed. +- **Error Condition** + - None + + +#### **[CCV-CCF-SNDSLASH.1]** +```typescript +// CCF: Consumer Chain Function +// Enables consumer initiated slashing +function SendSlashRequest( + valAddress: string, + power: int64, + infractionHeight: Height, + downtime: Bool) { + if downtime AND outstandingDowntime[data.valAddress] { + // do not send multiple requests for the same downtime + return + } + + // create SlashPacket data + packetData = SlashPacketData{ + valAddress: valAddress, + valPower: power, + vscId: HtoVSC[infractionHeight], + downtime: downtime + } + + // check whether the CCV channel to the provider chain is established + if providerChannel != "" { + // send SlashPacket data using the interface exposed by ICS-4 + channelKeeper.sendPacket( + portKeeper.getCapability(portKeeper.portPath(ConsumerPortId)), + ConsumerPortId, // source port ID + providerChannel, // source channel ID + zeroTimeoutHeight, + ccvTimeoutTimestamp, + packetData + ) + + if downtime { + // set outstandingDowntime for this validator + outstandingDowntime[data.valAddress] = TRUE + } + } + else { + // add SlashPacket data to the list of pending SlashPackets + req := SlashRequest{data: packetData, downtime: downtime} + pendingSlashRequests.Append(req) + } +} +``` +- **Caller** + - The ABCI application (e.g., the Slashing module). +- **Trigger Event** + - Evidence of misbehavior for a validator with address `valAddress` was received. +- **Precondition** + - True. +- **Postcondition** + - If the request is for downtime and there is an outstanding request to slash this validator for downtime, then the state is not changed. + - Otherwise, + - a `SlashPacket` data `packetData` is created, such that `packetData.vscId = VSCtoH[infractionHeight]`; + - if the CCV channel to the provider chain is established, then + - a packet with the `packetData` is sent to the provider chain; + - if the request is for downtime, `outstandingDowntime[data.valAddress]` is set to true; + - otherwise `SlashRequest{data: packetData, downtime: downtime}` is appended to `pendingSlashRequests`. +- **Error Condition** + - None. + +> **Note**: The ABCI application MUST subtract `ValidatorUpdateDelay` from the infraction height before invoking `SendSlashRequest`, +> where `ValidatorUpdateDelay` is a delay (in blocks) between when validator updates are returned to the consensus-engine and when they are applied. +> For example, if `ValidatorUpdateDelay = x` and a validator set update is returned with new validators at the end of block `10`, +> then the new validators are expected to sign blocks beginning at block `11+x` +> (for more details, take a look at the [ABCI specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/abci/abci.md#endblock)). +> +> Consequently, the consumer CCV module expects the `infractionHeight` parameter of the `SendSlashRequest()` to be set accordingly. + +> **Note**: In the context of single-chain validation, slashing for downtime is an **_atomic operation_**, i.e., once the downtime is detected, the misbehaving validator is slashed and jailed immediately. +> Consequently, once a validator is punished for downtime, it is removed from the validator set and cannot be punished again for downtime. +> Since validators are not automatically added back to the validator set, it entails that the validator is aware of the punishment before it can rejoin and be potentially punished again. +> +> In the context of CCV, slashing for downtime is no longer atomic, i.e., downtime is detected on the consumer chain, but the jailing happens on the provider chain. +> To avoid sending multiple slash requests for the same downtime infraction, the consumer CCV module uses an `outstandingDowntime` flag per validator. +> CCV assumes that the consumer ABCI application (e.g., the slashing module) is not including the downtime of a validator with `outstandingDowntime == TRUE` in the evidence for downtime. + + +#### **[CCV-CCF-SNDPESLASH.1]** +```typescript +// CCF: Consumer Chain Function +// Utility method +function SendPendingSlashRequests() { + // iterate over every pending SlashRequest in reverse order + foreach req IN pendingSlashRequests.Reverse() { + if !req.downtime OR !outstandingDowntime[req.data.valAddress] { + // send req.data using the interface exposed by ICS-4 + channelKeeper.sendPacket( + portKeeper.getCapability(portKeeper.portPath(ConsumerPortId)), + ConsumerPortId, // source port ID + providerChannel, // source channel ID + zeroTimeoutHeight, + ccvTimeoutTimestamp, + req.data + ) + + if req.downtime { + // set outstandingDowntime for this validator + outstandingDowntime[req.data.valAddress] = TRUE + } + } + } + // remove pending SlashRequest + pendingSlashRequests.RemoveAll() +} +``` +- **Caller** + - The `onRecvVSCPacket()` method (see [CCV-CCF-RCVVSC.1](#ccv-ccf-rcvvsc1)). +- **Trigger Event** + - The first `VSCPacket` is received from the provider chain. +- **Precondition** + - `providerChannel != ""`. +- **Postcondition** + - For each slash request `req` in `pendingSlashRequests` in reverse order, such that either the slash request is not for downtime or there is no outstanding slash request for downtime, + - a packet with the data `req.data` is sent to the provider chain; + - if the request is for downtime, `outstandingDowntime[req.data.valAddress]` is set to true. + - All the pending `SlashRequest`s are removed. +- **Error Condition** + - None. + +> **Note**: Iterating over pending `SlashRequest`s in reverse order ensures that validators that are down for multiple blocks during channel initialization will be slashed for the latest downtime evidence. + +### Reward Distribution +[↑ Back to Outline](#outline) + + +#### **[CCV-CCF-EBLOCK-RD.1]** +```typescript +// CCF: Consumer Chain Function +function EndBlockRD() { + if getCurrentHeight() - lastDistributionTransferHeight >= BlocksPerDistributionTransfer { + DistributeRewards() + } +} +``` +- **Caller** + - The `EndBlock()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine; `EndBlock` messages are sent once per block. +- **Precondition** + - True. +- **Postcondition** + - If `getCurrentHeight() - lastDistributionTransferHeight >= BlocksPerDistributionTransfer`, the `DistributeRewards()` method is invoked. +- **Error Condition** + - None. + + +#### **[CCV-CCF-DISTRREW.1]** +```typescript +// CCF: Consumer Chain Function +function DistributeRewards() { + // iterate over all different tokens in ccvAccount + foreach (denomination, amount) IN ccvAccount.GetAllBalances() { + // transfer token using ICS20 + transferKeeper.sendFungibleTokens( + denomination, + amount, + ccvAccount, // sender + providerDistributionAccount, // receiver + "transfer", // transfer port + distributionChannelId, // transfer channel ID + zeroTimeoutHeight, // timeoutHeight + transferTimeoutTimestamp // timeoutTimestamp + ) + } + lastDistributionTransferHeight = getCurrentHeight() +} +``` +- **Caller** + - The `EndBlockRD()` method. +- **Trigger Event** + - An `EndBlock` message is received from the consensus engine. +- **Precondition** + - `getCurrentHeight() - lastDistributionTransferHeight >= BlocksPerDistributionTransfer` +- **Postcondition** + - For each token type defined as a pair `(denomination, amount)` in `ccvAccount`, a transfer token (as defined in [ICS 20](../ics-020-fungible-token-transfer/README.md)) is initiated. + - `lastDistributionTransferHeight` is set to the current height. +- **Error Condition** + - None. diff --git a/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md b/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md new file mode 100644 index 000000000..55df003a9 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md @@ -0,0 +1,310 @@ + +# CCV: Overview and Basic Concepts +[↑ Back to main document](./README.md) + + +## Outline +- [Security Model](#security-model) +- [Motivation](#motivation) +- [Definition](#definition) +- [Overview](#overview) + - [Channel Initialization](#channel-initialization) + - [Validator Set Update](#validator-set-update) + - [Completion of Unbonding Operations](#completion-of-unbonding-operations) + - [Consumer Initiated Slashing](#consumer-initiated-slashing) + - [Reward Distribution](#reward-distribution) + + + +## Security Model +[↑ Back to Outline](#outline) + +We consider chains that use a proof of stake mechanism based on the model of [weak subjectivity](https://blog.ethereum.org/2014/11/25/proof-stake-learned-love-weak-subjectivity/) +in order to strengthen the assumptions required by the underlying consensus engine +(e.g., [Tendermint](https://arxiv.org/pdf/1807.04938.pdf) requires that less than a third of the voting power is Byzantine). + +> **Background**: The next block in a blockchain is *validated* and *voted* upon by a set of pre-determined *full nodes*; these pre-determined full nodes are also known as *validators*. +We refer to the validators eligible to validate a block as that block's *validator set*. +To be part of the validator set, a validator needs to *bond* (i.e., lock, stake) an amount of tokens for a (minimum) period of time, known as the *unbonding period*. +The amount of tokens bonded gives a validator's *voting power*. +When a validator starts unbonding some of its tokens, its voting power is reduced immediately, +but the tokens are unbonded (i.e., unlocked) only after the unbonding period has elapsed. +If a validator misbehaves (e.g., validates two different blocks at the same height), then the system can slash the validator's bonded tokens that gave its voting power during the misbehavior. +This prevents validators from misbehaving and immediately exiting with their tokens, +i.e., the unbonding period enables the system to punish misbehaving validators after the misbehaviors are committed. +For more details, take a look at the [Tendermint Specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/core/data_structures.md) +and the [Light Client Specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/light-client/verification/verification_002_draft.md#part-i---tendermint-blockchain). + +In the context of CCV, the validator sets of the consumer chains are chosen based on the tokens validators bonded on the provider chain, +i.e., are chosen from the validator set of the provider chain. +When validators misbehave on the consumer chains, their tokens bonded on the provider chain are slashed. +As a result, the security gained from the value of the tokens bonded on the provider chain is shared with the consumer chains. + +Similarly to the single-chain approach, when a validator starts unbonding some of its bonded tokens, its voting power is reduced on all chains (i.e., provider chain and consumer chains); +yet, due to delays in the communication over the IBC protocol (e.g., due to relaying packets), the voting power is not reduced immediately on the consumer chains. +A further consequence of CCV is that the tokens are unbonded only after the unbonding period has elapsed on all chains starting from the moment the corresponding voting power was reduced. +Thus, CCV may delay the unbonding of tokens validators bonded on the provider chain. + +## Motivation +[↑ Back to Outline](#outline) + +CCV is a primitive (i.e., a building block) that enables arbitrary shared security models: The security of a chain can be composed of security transferred from multiple provider chains including the chain itself (a consumer chain can be its own provider). As a result, CCV enables chains to borrow security from more established chains (e.g., Cosmos Hub), in order to boost their own security, i.e., increase the cost of attacking their networks. +> **Intuition**: For example, for chains based on Tendermint consensus, a variety of attacks against the network are possible if an attacker acquire 1/3+ or 2/3+ of all bonded tokens. Since the market cap of newly created chains could be relatively low, an attacker could realistically acquire sufficient tokens to pass these thresholds. As a solution, CCV allows the newly created chains to use validators that have stake on chains with a much larger market cap and, as a result, increase the cost an attacker would have to pay. + +Moreover, CCV enables *hub minimalism*. In a nutshell, hub minimalism entails keeping a hub in the Cosmos network (e.g., the Cosmos Hub) as simple as possible, with as few features as possible in order to decrease the attack surface. CCV enables moving distinct features (e.g., DEX) to independent chains that are validated by the same set of validators as the hub. + +> **Versioning**: Note that CCV will be developed progressively. +> This standard document specifies the V1 release, which will require the validator set of a consumer chain to be entirely provided by the provider chain. +> In other words, once a provider chain agrees to provide security to a consumer chain, the entire validator set of the provider chain MUST validate also on the consumer chain. +> +> For more details on the planned releases, take a look at the [Interchain Security light paper](https://github.com/cosmos/gaia/blob/main/docs/interchain-security.md#the-interchain-security-stack). + +## Definition +[↑ Back to Outline](#outline) + +This section defines the new terms and concepts introduced by CCV. + +- **Provider Chain**: The blockchain that provides security, i.e., manages the validator set of the consumer chain. + +- **Consumer Chain**: The blockchain that consumes security, i.e., enables the provider chain to manage its validator set. + +> **Note**: In this specification, the validator set of the consumer chain is entirely provided by the provider chain. + +Both the provider and the consumer chains are [application-specific blockchains](https://docs.cosmos.network/v0.44/intro/why-app-specific.html), +i.e., each blockchain's state machine is typically connected to the underlying consensus engine via a *blockchain interface*, such as [ABCI](https://github.com/tendermint/spec/tree/v0.7.1/spec/abci). +The blockchain interface MUST enable the state machine to provide to the underlying consensus engine a set of validator updates, i.e., changes in the voting power granted to validators. +Although this specification is not dependent on ABCI, for ease of presentation, we refer to the state machines as ABCI applications. +Also, this specification considers a modular paradigm, +i.e., the functionality of each ABCI application is separated into multiple modules, like the approach adopted by [Cosmos SDK](https://docs.cosmos.network/v0.44/basics/app-anatomy.html#modules). + + +- **CCV Module**: The module that implements the CCV protocol. Both the provider and the consumer chains have each their own CCV module. +Furthermore, the functionalities provided by the CCV module differ between the provider chain and the consumer chains. +For brevity, we use *provider CCV module* and *consumer CCV module* to refer to the CCV modules on the provider chain and on the consumer chains, respectively. + +- **CCV Channel**: A unique, ordered IBC channel that is used by the provider CCV module to exchange IBC packets with a consumer CCV module. +Note that there is a separate CCV channel for every consumer chain. + +The IBC handler interface, the IBC relayer module interface, and both IBC channels and IBC packets are as defined in [ICS 25](../../core/ics-025-handler-interface), [ICS 26](../../core/ics-026-routing-module), and [ICS 4](../../core/ics-004-channel-and-packet-semantics), respectively. + +- **Validator Set Change (VSC)**: A change in the validator set of the provider chain that must be reflected in the validator sets of the consumer chains. +Every VSC consists of a batch of validator updates provided to the consensus engine of the provider chain. + +> **Background**: In the context of single-chain validation, the changes of the validator set are triggered by the *Staking module*, +> i.e., a module of the ABCI application that implements the proof of stake mechanism needed by the [security model](#security-model). +> For an example, take a look at the [Staking module documentation](https://docs.cosmos.network/v0.44/modules/staking/) of Cosmos SDK. + +Some of the validator updates can decrease the voting power granted to validators. +These decreases may be a consequence of unbonding operations (e.g., unbonding delegations) on the provider chain. +which MUST NOT complete before reaching maturity on both the provider and all the consumer chains, +i.e., the *unbonding period* (denoted as `UnbondingPeriod`) has elapsed on both the provider and all the consumer chains. +Thus, a *VSC reaching maturity* on a consumer chain means that all the unbonding operations that resulted in validator updates included in that VSC have matured on the consumer chain. + +> **Background**: An *unbonding operation* is any operation of unbonding an amount of the tokens a validator bonded. Note that the bonded tokens correspond to the validator's voting power. We distinguish between three types of unbonding operations: +> - *undelegation* - a delegator unbonds tokens it previously delegated to a validator; +> - *redelegation* - a delegator instantly redelegates tokens from a source validator to a different validator (the destination validator); +> - *validator unbonding* - a validator is removed from the validator set; note that although validator unbondings do not entail unbonding tokens, they behave similarly to other unbonding operations. +> +> Regardless of the type, unbonding operations have two components: +> - The *initiation*, e.g., a delegator requests their delegated tokens to be unbonded. The initiation of an operation of unbonding an amount of the tokens a validator bonded results in a change in the voting power of that validator. +> - The *completion*, e.g., the tokens are actually unbonded and transferred back to the delegator. To complete, unbonding operations must reach *maturity*, i.e., `UnbondingPeriod` must elapse since the operations were initiated. +> +> For more details, take a look at the [Cosmos SDK documentation](https://docs.cosmos.network/v0.44/modules/staking/). + +> **Note**: Time periods are measured in terms of the block time, i.e., `currentTimestamp()` (as defined in [ICS 24](../../core/ics-024-host-requirements)). +> As a result, a consumer chain MAY start the unbonding period for every VSC that it applies in a block at any point during that block. + +- **Slash Request**: A request by a consumer chain to *slash* the tokens bonded by a validator on the provider chain as a consequence of that validator misbehavior on the consumer chain. A slash request MAY also result in the misbehaving validator being *jailed* for a period of time, during which it cannot be part of the validator set. + +> **Background**: In the context of single-chain validation, slashing and jailing misbehaving validators is handled by the *Slashing module*, +> i.e., a module of the ABCI application that enables the application to discourage misbehaving validators. +> For an example, take a look at the [Slashing module documentation](https://docs.cosmos.network/v0.44/modules/slashing/) of Cosmos SDK. + +## Overview +[↑ Back to Outline](#outline) + +CCV must handle the following types of operations: +- **Channel Initialization**: Create unique, ordered IBC channels between the provider chain and every consumer chain. +- **Validator Set Update**: It is a two-part operation, i.e., + - update the validator sets of all the consumer chains based on the information obtained from the *provider Staking module* (i.e., the Staking module on the provider chain) on the amount of tokens bonded by validators on the provider chain; + - and enable the timely completion (cf. the unbonding periods on the consumer chains) of unbonding operations (i.e., operations of unbonding bonded tokens). +- **Consumer Initiated Slashing**: Enable the provider chain to slash and jail bonded validators that misbehave while validating on the consumer chain. +- **Reward Distribution**: Enable the distribution of block production rewards and transaction fees from the consumer chains to the validators on the provider chain. + +### Channel Initialization +[↑ Back to Outline](#outline) + +The following figure shows an overview of the CCV Channel initialization. + +![Channel Initialization Overview](./figures/ccv-init-overview.png?raw=true) + +Consumer chains are created through governance proposals. For an example of how governance proposals work, take a look at the [Governance module documentation](https://docs.cosmos.network/v0.44/modules/gov/) of Cosmos SDK. + +The channel initialization consists of four phases: +- **Create clients**: The provider CCV module handles every passed proposal to spawn a new consumer chain. + Once it receives a proposal, it creates a client of the consumer chain (as defined in [ICS 2](../../core/ics-002-client-semantics)). + Then, the operators of validators in the validator set of the provider chain must each start a full node (i.e., a validator) of the consumer chain. + Once the consumer chain starts, the application receives an `InitChain` message from the consensus engine + (for more details, take a look at the [ABCI specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/abci/abci.md#initchain)). + The `InitChain` message triggers the call to the `InitGenesis()` method of the consumer CCV module, which creates a client of the provider chain. + For client creation, both a `ClientState` and a `ConsensusState` are necessary (as defined in [ICS 2](../../core/ics-002-client-semantics)); + both are contained in the `GenesisState` of the consumer CCV module. + The `GenesisState` is distributed to all operators that need to start a full node of the consumer chain + (the mechanism of distributing the `GenesisState` is outside the scope of this specification). + > Note that at genesis, the validator set of the consumer chain matches the validator set of the provider chain. +- **Connection handshake**: A relayer (as defined in [ICS 18](../../relayer/ics-018-relayer-algorithms)) is responsible for initiating the connection handshake (as defined in [ICS 3](../../core/ics-003-connection-semantics)). +- **Channel handshake**: A relayer is responsible for initiating the channel handshake (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)). + The channel handshake MUST be initiated on the consumer chain. + The handshake consists of four messages that need to be received for a channel built on top of the expected clients. + - *OnChanOpenInit*: On receiving a `ChanOpenInit` message, the consumer CCV module verifies that the underlying client associated with this channel is the expected client of the provider chain (i.e., created during genesis). + - *OnChanOpenTry*: On receiving a `ChanOpenTry` message, the provider CCV module verifies that the underlying client associated with this channel is the expected client of the consumer chain (i.e., created when handling the governance proposal). + - *OnChanOpenAck*: On receiving a `ChanOpenAck` message, the consumer CCV module initiates the opening handshake for the token transfer channel required by the Reward Distribution operation (see the [Reward Distribution](#reward-distribution) section). + - *OnChanOpenConfirm*: On receiving the *FIRST* `ChanOpenConfirm` message, the provider CCV module considers its side of the CCV channel to be established. +- **Channel completion**: Once the provider chain side of the CCV channel is established, + the provider CCV module provides VSCs (i.e., validator set changes) to the consumer chain (see the [Validator Set Update](#validator-set-update) section). + On receiving the *FIRST* `VSCPacket`, the consumer CCV module considers its side of the CCV channel to be established. + From this moment onwards, the consumer chain is secured by the provider chain. + +> **Note**: As long as the [assumptions required by CCV](./system_model_and_properties.md#assumptions) hold (e.g., *Correct Relayer*), every governance proposal to spawn a new consumer chain that passes on the provider chain results eventually in a CCV channel being created. +> Furthermore, the "*FIRST*" keyword in the above description ensures the uniqueness of the CCV channel, i.e., all subsequent attempts to create another CCV channel to the same consumer chain will fail. + +> **Note**: Until the CCV channel is established, the initial validator set of the consumer chain cannot be updated (see the [Validator Set Update](#validator-set-update) section) and the validators from this initial set cannot be slashed (see the [Consumer Initiated Slashing](#consumer-initiated-slashing) section). +> This means that the consumer chain is *not yet secured* by the provider chain. +> Thus, to reduce the attack surface during channel initialization, the consumer chain SHOULD enable user transactions only after the CCV channel is established (i.e., after receiving the first VSC). +> As a consequence, a malicious initial validator set can only influence the initialization of the CCV channel. + +For a more detailed description of Channel Initialization, take a look at the [technical specification](./methods.md#initialization). + +### Validator Set Update +[↑ Back to Outline](#outline) + +In the context of VSCs, the CCV module enables the following functionalities: + - On the provider chain, + - **provide** VSCs to the consumer chains, for them to update their validator sets according to the validator set of the provider chain; + providing VSCs entails sending `VSCPacket`s to all consumer chains; + - **register** VSC maturity notifications from the consumer chain. + - On every consumer chain, + - **apply** the VSCs provided by the provider chain to the validator set of the consumer chain; + - **notify** the provider chain that the provided VSCs have matured on this consumer chain; + notifying of VSCs maturity entails sending `VSCMaturedPacket`s to the provider chain. + +These functionalities are depicted in the following figure that shows an overview of the Validator Set Update operation of CCV. +For a more detailed description of Validator Set Update, take a look at the [technical specification](./methods.md#validator-set-update). + +![Validator Set Update Overview](./figures/ccv-vsc-overview.png?raw=true) + +#### Completion of Unbonding Operations + +In the context of single-chain validation, the completion of any unbonding operation requires the `UnbondingPeriod` to elapse since the operations was initiated (i.e., the operation MUST reach maturity). +In the context of CCV, the completion MUST require also the unbonding operation to reach maturity on **all** consumer chains (for the [Security Model](#security-model) to be preserved). +Therefore, the provider Staking module needs to be aware of the VSC maturity notifications registered by the provider CCV module. + +The ***provider chain*** achieves this through the following approach: +- The Staking module is notifying the CCV module when any unbonding operation is initiated. + As a result, the CCV module maps all the unbonding operations to the corresponding VSCs. +- When the CCV module registers maturity notifications for a VSC from all consumer chains, it notifies the Staking module of the maturity of all unbonding operations mapped to this VSC. + This enables the Staking module to complete the unbonding operations only when they reach maturity on both the provider chain and on all the consumer chains. + +This approach is depicted in the following figure that shows an overview of the interface between the provider CCV module and the provider Staking module in the context of the Validator Set Update operation of CCV: +- In `Block 1`, two unbonding operations are initiated (i.e., `undelegate-1` and `redelegate-1`) in the provider Staking module. + For each operation, the provider Staking module notifies the provider CCV module. + As a result, the provider CCV module maps these to operation to `vscId`, which is the ID of the following VSC (i.e., `VSC1`). + The provider CCV module provides `VSC1` to all consumer chains. +- In `Block 2`, the same approach is used for `undelegate-2`. +- In `Block j`, `UnbondingPeriod` has elapsed since `Block 1`. + In the meantime, the provider CCV module registered maturity notifications for `VSC1` from all consumer chains + and, consequently, notified the provider Staking module of the maturity of both `undelegate-1` and `redelegate-1`. + As a result, the provider Staking module completes both unbonding operations in `Block j`. +- In `Block k`, `UnbondingPeriod` has elapsed since `Block 2`. + In the meantime, the provider CCV module has NOT yet registered maturity notifications for `VSC2` from all consumer chains. + As a result, the provider Staking module CANNOT complete `undelegate-2` in `Block k`. + The unbonding operation is completed later once the provider CCV module registered maturity notifications for `VSC2` from all consumer chains. + +![Completion of Unbonding Operations](./figures/ccv-unbonding-overview.png?raw=true) + +### Consumer Initiated Slashing +[↑ Back to Outline](#outline) + +For the [Security Model](#security-model) to be preserved, misbehaving validators MUST be slashed (and MAY be jailed, i.e., removed from the validator set). +A prerequisite to slashing validators is to receive valid evidence of their misbehavior. +Thus, when slashing a validator, we distinguish between three events and the heights when they occur: +- `infractionHeight`, the height at which the misbehavior (or infraction) happened; +- `evidenceHeight`, the height at which the evidence of misbehavior is received; +- `slashingHeight`, the height at which the validator is slashed (and jailed). + +> **Note**: In the context of single-chain validation, usually `evidenceHeight = slashingHeight`. + +The [Security Model](#security-model) guarantees that any misbehaving validator can be slashed for at least the unbonding period, +i.e., as long as that validator's tokens are not unbonded yet, they can be slashed. +However, if the tokens start unbonding before `infractionHeight` (i.e., the tokens did not contribute to the voting power that committed the infraction) then the tokens MUST NOT be slashed. + +In the context of CCV, validators (with tokens bonded on the provider chain) MUST be slashed for infractions committed on the consumer chains at heights for which they have voting power. +Thus, although the infractions are committed on the consumer chains and evidence of these infractions is submitted to the consumer chains, the slashing happens on the provider chain. As a result, the Consumer Initiated Slashing operation requires, for every consumer chain, a mapping from consumer chain block heights to provider chain block heights. + +The following figure shows the intuition behind such a mapping using the provided VSCs. +The four unbonding operations (i.e., undelegations) occur on the provider chain and, as a consequence, the provider chain provides VSCs to the consumer chain, e.g., `undelegate-3` results in `VSC3` being provided. +The four colors (i.e., red, blue, green, and yellow) indicate the mapping of consumer chain heights to provider chain heights. +Note that on the provider chain there is only one block of a given color. +Also, note that the three white blocks between the green and the yellow blocks on the provider chain have the same validator set. +As a result, a validator misbehaving on the consumer chain, e.g., in either of the two green blocks, is slashed the same as if misbehaving on the provider chain, e.g., in the green block. +This ensures that once unbonding operations are initiated, the corresponding unbonding tokens are not slashed for infractions committed in the subsequent blocks, e.g., the tokens unbonding due to `undelegate-3` are not slashed for infractions committed in or after the green blocks. + +![Intuition of Mapping Between Provider and Consumer Heights](./figures/ccv-mapping-intuition.png?raw=true) + +The following figure shows describes how CCV creates the mapping from consumer chain heights to provider chain heights. +For clarity, we use `Hp*` and `Hc*` to denote block heights on the provider chain and consumer chain, respectively. + +![Mapping Between Provider and Consumer Heights](./figures/ccv-height-mapping-overview.png?raw=true) + +- For every block, the provider CCV module maps the ID of the VSC it provides to the consumer chains to the height of the subsequent block, i.e., `VSCtoH[VSC.id] = Hp + 1`, for a VSC provided at height `Hp`. + Intuitively, this means that the validator updates in a provided VSC will update the voting power at height `VSCtoH[VSC.id]`. +- For every block, every consumer CCV module maps the height of the subsequent block to the ID of the latest received VSC, e.g., `HtoVSC[Hc2 + 1] = VSC1.id`. + Intuitively, this means that the voting power on the consumer chain during a block `Hc` was updated by the VSC with ID `HtoVSC[Hc]`. + > **Note**: It is possible for multiple VSCs to be received by the consumer chain within the same block. For more details, take a look at the [Validator sets, validator updates and VSCs](./system_model_and_properties.md#validator-sets-validator-updates-and-vscs) section. +- By default, every consumer CCV module maps any block height to `0` (i.e., VSC IDs start from `1`). + Intuitively, this means that the voting power on the consumer chain at height `Hc` with `HtoVSC(Hc) = 0` was setup at genesis during Channel Initialization. +- For every consumer chain, the provider CCV module sets `VSCtoH[0]` to the height when it establishes the CCV channel to this consumer chain. + Note that the validator set on the provider chain at height `VSCtoH[0]` matches the validator set at the height when the first VSC is provided to this consumer chain. + This means that this validator set on the provider chain matches the validator set on the consumer chain at all heights `Hc` with `HtoVSC[Hc] = 0`. + +The following figure shows an overview of the Consumer Initiated Slashing operation of CCV. + +![Consumer Initiated Slashing](./figures/ccv-evidence-overview.png?raw=true) + +- At (evidence) height `Hc2`, the consumer chain receives evidence that a validator `V` misbehaved at (infraction) height `Hc1`. + As a result, the consumer CCV module sends a `SlashPacket` to the provider chain: + It makes a request to slash `V`, but it replaces the infraction height `Hc1` with `HtoVSC[Hc1]`, + i.e., the ID of the VSC that updated the "misbehaving voting power" or `0` if such a VSC does not exist. +- The provider CCV module receives at (slashing) height `Hp1` the `SlashPacket` with `vscId = HtoVSC[Hc1]`. + As a result, it requests the provider Slashing module to slash `V`, but it set the infraction height to `VSCtoH[vscId]`, i.e., + - if `vscId != 0`, the height on the provider chain where the voting power was updated by the VSC with ID `vscId`; + - otherwise, the height at which the CCV channel to this consumer chain was established. + > **Note**: As a consequence of slashing (and potentially jailing) `V`, the Staking module updates accordingly `V`'s voting power. This update MUST be visible in the next VSC provided to the consumer chains. + +For a more detailed description of Consumer Initiated Slashing, take a look at the [technical specification](./methods.md#consumer-initiated-slashing). + +### Reward Distribution +[↑ Back to Outline](#outline) + +In the context of single-chain validation, the *Distribution module*, i.e., a module of the ABCI application, handles the distribution of rewards (i.e., block production rewards and transaction fees) to every validator account based on their total voting power; +these rewards are then further distributed to the delegators. +For an example, take a look at the [Distribution module documentation](https://docs.cosmos.network/v0.44/modules/distribution/) of Cosmos SDK. + +At the beginning of every block, the rewards for the previous block are pooled into a distribution module account. +The Reward Distribution operation of CCV enables every consumer chain to transfer a fraction of these rewards to the provider chain. +The operation consists of two steps that are depicted in the following figure: + +![Reward Distribution](./figures/ccv-distribution-overview.png?raw=true) + +- At the beginning of every block on the consumer chain, a fraction of the rewards are transferred to an account on the consumer CCV module. +- At regular intervals (e.g., every `1000` blocks), the consumer CCV module sends the accumulated rewards to the distribution module account on the provider chain through an IBC token transfer packet (as defined in [ICS 20](../ics-020-fungible-token-transfer/README.md)). + Note that the IBC transfer packet is sent over a separate unordered channel. + As a result, the reward distribution is not synchronized with the other CCV operations, + e.g., some validators may miss out on some rewards by unbonding before an IBC transfer packet is received, + while other validators may get some extra rewards by bonding before an IBC transfer packet is received. + +> **Note**: From the perspective of the distribution module account on the provider chain, the rewards coming from the consumer chains are indistinguishable from locally collected rewards and thus, are distributed to all the validators and their delegators. + +As a prerequisite of this approach, every consumer chain must open a token transfer channel to the provider chain and be made aware of the address of the distribution module account on the provider chain, both of which happen during channel initialization. +- On receiving a `ChanOpenAck` message, the consumer CCV module initiates the opening handshake for the token transfer channel using the same client and connection as for the CCV channel. +- On receiving a `ChanOpenTry` message, the provider CCV module adds the address of the distribution module account to the channel version as metadata (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README.md#definitions)). \ No newline at end of file diff --git a/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md b/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md new file mode 100644 index 000000000..f621b6064 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/system_model_and_properties.md @@ -0,0 +1,400 @@ + +# CCV: System Model and Properties +[↑ Back to main document](./README.md) + + +## Outline +- [Assumptions](#assumptions) +- [Desired Properties](#desired-properties) + - [System Properties](#system-properties) + - [CCV Channel](#ccv-channel) + - [Validator Sets, Validator Updates and VSCs](#validator-sets-validator-updates-and-vscs) + - [Staking Module Interface](#staking-module-interface) + - [Validator Set Update](#validator-set-update) + - [Consumer Initiated Slashing](#consumer-initiated-slashing) + - [Reward Distribution](#reward-distribution) +- [Correctness Reasoning](#correctness-reasoning) + +## Assumptions +[↑ Back to Outline](#outline) + +As part of a modular ABCI application, CCV interacts with both the consensus engine (via ABCI) and other application modules (e.g, the Staking module). +As an IBC application, CCV interacts with external relayers (defined in [ICS 18](../../relayer/ics-018-relayer-algorithms)). +In this section we specify what we assume about these other components. +A more thorough discussion of the environment in which CCV operates is given in the section [Placing CCV within an ABCI Application](./technical_specification.md#placing-ccv-within-an-abci-application). + +> **Intuition**: +> +> CCV safety relies on the *Safe Blockchain* assumption, +i.e., neither *Live Blockchain* and *Correct Relayer* are required for safety. +Note though that CCV liveness relies on both *Live Blockchain* and *Correct Relayer* assumptions; +furthermore, the *Correct Relayer* assumption relies on both *Safe Blockchain* and *Live Blockchain* assumptions. +> +> The *Validator Update Provision*, *Unbonding Safety*, *Slashing Warranty*, and *Distribution Warranty* assumptions define what is needed from the ABCI application of the provider chain. +> +> The *Evidence Provision* assumptions defines what is needed from the ABCI application of the consumer chains. + +- ***Safe Blockchain***: Both the provider and the consumer chains are *safe*. This means that, for every chain, the underlying consensus engine satisfies safety (e.g., the chain does not fork) and the execution of the state machine follows the described protocol. +- ***Live Blockchain***: Both the provider and the consumer chains are *live*. This means that, for every chain, the underlying consensus engine satisfies liveness (i.e., new blocks are eventually added to the chain). + > **Note**: Both *Safe Blockchain* and *Live Blockchain* assumptions require the consensus engine's assumptions to hold, e.g., less than a third of the voting power is Byzantine. For an example, take a look at the [Tendermint Paper](https://arxiv.org/pdf/1807.04938.pdf). + +- ***Correct Relayer***: There is at least one *correct*, *live* relayer between the provider and consumer chains. This assumption has two implications. + - First, every packet sent on the CCV channel is relayed to the receiving end before the packet timeout elapses. + - Second, a correct relayer will eventually relay packets on the token transfer channel. + + Clearly, the CCV protocol is responsible of setting the timeouts (i.e., `timeoutHeight` and `timeoutTimestamp`), for the packets sent on the CCV channel, such that the *Correct Relayer* assumption is feasible. + > **Discussion**: IBC relies on timeouts to signal that a sent packet is not going to be received on the other end. + > Once an ordered IBC channel timeouts, the channel is closed (see [ICS 4](../../core/ics-004-channel-and-packet-semantics)). + > The *Correct Relayer* assumption is necessary to ensure that the CCV channel **cannot** ever timeout and, as a result, cannot transit to the closed state. + > + > **In practice**, the *Correct Relayer* assumption is realistic since any validator could play the role of the relayer and it is in the best interest of correct validators to successfully relay packets. + > + > The following strategy is a practical example of how to ensure the *Correct Relayer* assumption holds. + > Let S denote the sending chain and D the destination chain; + > and let `drift(S,D)` be the time drift between S and D, + > i.e., `drift(S,D) = S.currentTimestamp() - D.currentTimestamp()` (`drift(S,D) > 0` means that S is "ahead" of D). + > For every packet, S only sets `timeoutTimestamp = S.currentTimestamp() + to`, with `to` an application-level parameter. + > The `timeoutTimestamp` indicates *a timestamp on the destination chain* after which the packet will no longer be processed (cf. [ICS 4](../../core/ics-004-channel-and-packet-semantics)). + > Therefore, the packet MUST be relayed within a time period of `to - drift(S,D)`, + > i.e., `to - drift(S,D) > RTmax`, where `RTmax` is the maximum relaying time across all packet. + > Theoretically, choosing the value of `to` requires knowing the value of `drift(S,D)` (i.e., `to > drift(S,D)`); + > yet, `drift(S,D)` is not known at a chain level. + > In practice, choosing `to` such that `to >> drift(S,D)` and `to >> RTmax`, e.g., `to = 4 weeks`, makes the *Correct Relayer* assumption feasible. + +- ***Validator Update Provision***: Let `{U1, U2, ..., Ui}` be a batch of validator updates applied (by the provider Staking module) to the validator set of the provider chain at block height `h`. + Then, the batch of validator updates obtained (by the provider CCV module) from the provider Staking module at height `h` MUST be exactly the batch `{U1, U2, ..., Ui}`. + +- ***Unbonding Safety***: Let `uo` be any unbonding operation that starts with an unbonding transaction being executed + and completes with the event that returns the corresponding stake; + let `U(uo)` be the validator update caused by initiating `uo`; + let `vsc(uo)` be the VSC that contains `U(uo)`. + Then, + - (*unbonding initiation*) the provider CCV module MUST be notified of `uo`'s initiation before receiving `U(uo)`; + - (*unbonding completion*) `uo` MUST NOT complete on the provider chain before the provider chain registers notifications of `vsc(uo)`'s maturity from all consumer chains. + > **Note**: Depending on the implementation, the (*unbonding initiation*) part of the *Unbonding Safety* MAY NOT be necessary for validator unbonding operations. + +- ***Slashing Warranty***: If the provider ABCI application (e.g., the Slashing module) receives a request to slash a validator `val` that misbehaved at block height `h`, then it slashes the amount of tokens `val` had bonded at height `h` except the amount that has already completely unbonded. + +- ***Evidence Provision***: If the consumer ABCI application receives a valid evidence of misbehavior at block height `h`, then it MUST submit it to the consumer CCV module *exactly once* and at the same height `h`. + Furthermore, the consumer ABCI application MUST NOT submit invalid evidence to the consumer CCV module. + > **Note**: What constitutes a valid evidence of misbehavior depends on the type of misbehavior and it is outside the scope of this specification. + +- ***Distribution Warranty***: The provider ABCI application (e.g., the Distribution module) distributes the tokens from the distribution module account among the validators that are part of the validator set. + +## Desired Properties + +The following properties are concerned with **one provider chain** providing security to **multiple consumer chains**. +Between the provider chain and each consumer chain, a separate (unique) CCV channel is established. + +> **Note**: Except for liveness properties -- *Channel Liveness*, *Apply VSC Liveness*, *Register Maturity Liveness*, and *Distribution Liveness* -- none of the properties of CCV require the *Correct Relayer* assumption to hold. +> Nonetheless, the *Correct Relayer* assumption is necessary to guarantee the systems properties (except for *Validator Set Replication*) -- *Bond-Based Consumer Voting Power*, *Slashable Consumer Misbehavior*, and *Consumer Rewards Distribution*. + +### System Properties +[↑ Back to Outline](#outline) + +We use the following notations: +- `ts(h)` is the timestamp of a block with height `h`, i.e., `ts(h) = B.currentTimestamp()`, where `B` is the block at height `h`; +- `pBonded(h,val)` is the number of tokens bonded by validator `val` on the provider chain at block height `h`; +- `pUnbonding(h,val)` is the number of tokens a validator `val` starts unbonding on the provider at at block height `h`; +- `VP(T)` is the voting power associated to a number `T` of tokens; +- `Power(c,h,val)` is the voting power granted to a validator `val` on a chain `c` at block height `h`; +- `Token(power)` is the amount of tokens necessary to be bonded (on the provider chain) by a validator to be granted `power` voting power, + i.e., `Token(VP(T)) = T`; +- `slash(val, h, hi, sf)` is the amount of token slashed from a validator `val` on the provider chain (i.e., `pc`) at height `h` for an infraction (with a slashing fraction of `sf`) committed at (provider) height `hi`, + i.e., `slash(val, h, hi, sf) = sf * Token(Power(pc,hi,val))`; + note that the infraction can be committed also on a consumer chain, in which case `hi` is the corresponding height on the provider chain. + +Also, we use `ha << hb` to denote an order relation between heights, i.e., the block at height `ha` *happens before* the block at height `hb`. +For heights on the same chain, `<<` is equivalent to `<`, i.e., `ha << hb` entails `hb` is larger than `ha`. +For heights on two different chains, `<<` is establish by the packets sent over an order channel between two chains, +i.e., if a chain `A` sends at height `ha` a packet to a chain `B` and `B` receives it at height `hb`, then `ha << hb`. +> **Note**: `<<` is transitive, i.e., `ha << hb` and `hb << hc` entail `ha << hc`. +> +> **Note**: The block on the proposer chain that handles a governance proposal to spawn a new consumer chain `cc` *happens before* all the blocks of `cc`. + +CCV provides the following system properties. +- ***Validator Set Replication***: Every validator set on any consumer chain MUST either be or have been a validator set on the provider chain. + +- ***Bond-Based Consumer Voting Power***: Let `val` be a validator, `cc` be a consumer chain, both `hc` and `hc'` be heights on `cc`, and both `hp` and `hp'` be heights on the provider chain, such that + - `val` has `Power(cc,hc,val)` voting power on `cc` at height `hc`; + - `hc'` is the smallest height on `cc` that satisfies `ts(hc') >= ts(hc) + UnbondingPeriod`, i.e., `val` cannot completely unbond on `cc` before `hc'`; + - `hp` is the largest height on the provider chain that satisfies `hp << hc`, i.e., `Power(pc,hp,val) = Power(cc,hc,val)`, where `pc` is the provider chain; + - `hp'` is the smallest height on the provider chain that satisfies `hc' << hp'`, i.e., `val` cannot completely unbond on the provider chain before `hp'`; + - `sumUnbonding(hp, h, val)` is the sum of all tokens `val` start unbonding on the provider at all heights `hu`, such that `hp < hu <= h`; + - `sumSlash(hp, h, val)` is the sum of the slashes of `val` at all heights `hs` for infractions committed at `hp`, such that `hp < hs <= h`. + + Then for all heights `h` on the provider chain, + ``` + hp <= h < hp': + Power(cc,hc,val) <= VP( pBonded(h,val) + sumUnbonding(hp, h, val) + sumSlash(hp, h, val) ) + ``` + + > **Note**: The reason for `+ sumUnbonding(hp, h, val)` in the above inequality is that tokens that `val` start unbonding after `hp` have contributed to the power granted to `val` at height `hc` on `cc` (i.e., `Power(cc,hc,val)`). + > As a result, these tokens should be available for slashing until `hp'`. + + > **Note**: The reason for `+ sumSlash(hp, h, val)` in the above inequality is that slashing `val` reduces its locked tokens (i.e., `pBonded(h,val)` and `sumUnbonding(hp, h, val)`), however it does not reduce the power already granted to it at height `hc` on `cc` (i.e., `Power(cc,hc,val)`). + + > **Intuition**: The *Bond-Based Consumer Voting Power* property ensures that validators that validate on the consumer chains have enough tokens bonded on the provider chain for a sufficient amount of time such that the security model holds. + > This means that if the validators misbehave on the consumer chains, their tokens bonded on the provider chain can be slashed during the unbonding period. + > For example, if one unit of voting power requires `1.000.000` bonded tokens (i.e., `VP(1.000.000)=1`), + > then a validator that gets one unit of voting power on a consumer chain must have at least `1.000.000` tokens bonded on the provider chain until the unbonding period elapses on the consumer chain. + +- ***Slashable Consumer Misbehavior***: If a validator `val` commits an infraction, with a slashing fraction of `sf`, on a consumer chain `cc` at a block height `hi`, + then any evidence of misbehavior that is received by `cc` at height `he`, such that `ts(he) < ts(hi) + UnbondingPeriod`, + MUST results in *exactly* the amount of tokens `sf*Token(Power(cc,hi,val))` to be slashed on the provider chain. + Furthermore, `val` MUST NOT be slashed more than once for the same misbehavior. + > **Note:** Unlike in single-chain validation, in CCV the tokens `sf*Token(Power(cc,hi,val))` MAY be slashed even if the evidence of misbehavior is received at height `he` such that `ts(he) >= ts(hi) + UnbondingPeriod`, + since unbonding operations need to reach maturity on both the provider and all the consumer chains. + > + > **Note:** The *Slashable Consumer Misbehavior* property also ensures that if a delegator starts unbonding an amount `x` of tokens from `val` before height `hi`, then `x` will not be slashed, since `x` is not part of `Token(Power(c,hi,val))`. + +- ***Consumer Rewards Distribution***: If a consumer chain sends to the provider chain an amount `T` of tokens as reward for providing security, then + - `T` (equivalent) tokens MUST be eventually minted on the provider chain and then distributed among the validators that are part of the validator set; + - the total supply of tokens MUST be preserved, i.e., the `T` (original) tokens are escrowed on the consumer chain. + +### CCV Channel +[↑ Back to Outline](#outline) + +- ***Channel Uniqueness***: The channel between the provider chain and a consumer chain MUST be unique. +- ***Channel Validity***: If a packet `P` is received by one end of a CCV channel, then `P` MUST have been sent by the other end of the channel. +- ***Channel Order***: If a packet `P1` is sent over a CCV channel before a packet `P2`, then `P2` MUST NOT be received by the other end of the channel before `P1`. +- ***Channel Liveness***: Every packet sent over a CCV channel MUST eventually be received by the other end of the channel. + +### Validator Sets, Validator Updates and VSCs +[↑ Back to Outline](#outline) + +In this section, we provide a short discussion on how the validator set, the validator updates, and the VSCs relates in the context of multiple chains. + +Every chain consists of a sequence of blocks. +At the end of each block, validator updates (i.e., changes in the validators voting power) results in changes in the validator set of the next block. +Thus, the sequence of blocks produces a sequence of validator updates and a sequence of validator sets. +Furthermore, the sequence of validator updates on the provider chain results in a sequence of VSCs to all consumer chains. +Ideally, this sequence of VSCs is applied by every consumer chain, resulting in a sequence of validator sets identical to the one on the provider chain. +However, in general this need not be the case. The reason is twofold: +- first, given any two chains `A` and `B`, we cannot assume that `A`'s rate of adding new block is the same as `B`'s rate + (i.e., we consider the sequences of blocks of any two chains to be completely asynchronous); +- and second, due to relaying delays, we cannot assume that the rate of sending VSCs matches the rate of receiving VSCs. + +As a result, it is possible for multiple VSCs to be received by a consumer chain within the same block and be applied together at the end of the block, +i.e., the validator updates within the VSCs are being *aggregated* by keeping only the latest update per validator. +As a consequence, some validator sets on the provider chain are not existing on all consumer chains. +In other words, the validator sets on each consumer chain form a *subsequence* of the validator sets on the provider chain. +Nonetheless, as a **requirement of CCV**, *all the validator updates on the provider chain MUST be included in the sequence of validator sets on all consumer chains*. + +This is possible since every validator update contains *the absolute voting power* of that validator. +Given a validator `val`, the sequence of validator updates targeting `val` (i.e., updates of the voting power of `val`) is the prefix sum of the sequence of relative changes of the voting power of `val`. +Thus, given a validator update `U` targeting `val` that occurs at a block height `h`, +`U` *sums up* all the relative changes of the voting power of `val` that occur until height `h`, +i.e., `U = c_1+c_2+...+c_i`, such that `c_i` is the last relative change that occurs by `h`. +Note that relative changes are integer values. + +As a consequence, CCV can rely on the following property: +- ***Validator Update Inclusion***: Let `U1` and `U2` be two validator updates targeting the same validator `val`. + If `U1` occurs before `U2`, then `U2` sums up all the changes of the voting power of `val` that are summed up by `U1`, i.e., + - `U1 = c_1+c_2+...+c_i` and + - `U2 = c_1+c_2+...+c_i+c_(i+1)+...+c_j`. + +The *Validator Update Inclusion* property enables CCV to aggregate multiple VSCs. +It is sufficient for the consumer chains to apply only the last update per validator. +Since the last update of a validator *includes* all the previous updates of that validator, once it is applied, all the previous updates are also applied. + +### Staking Module Interface +[↑ Back to Outline](#outline) + +The following properties define the guarantees of CCV on *providing* VSCs to the consumer chains as a consequence of validator updates on the provider chain. +- ***Validator Update To VSC Validity***: Every VSC provided to a consumer chain MUST contain only validator updates that were applied to the validator set of the provider chain (i.e., resulted from a change in the amount of bonded tokens on the provider chain). +- ***Validator Update To VSC Order***: Let `U1` and `U2` be two validator updates on the provider chain. If `U1` occurs before `U2`, then `U2` MUST NOT be included in a provided VSC before `U1`. Note that the order within a single VSC is not relevant. +- ***Validator Update To VSC Liveness***: Every update of a validator in the validator set of the provider chain MUST eventually be included in a VSC provided to all consumer chains. + +Note that as a consequence of the *Validator Update To VSC Liveness* property, CCV guarantees the following property: +- **Provide VSC uniformity**: If the provider chain provides a VSC to a consumer chain, then it MUST eventually provide that VSC to all consumer chains. + +### Validator Set Update +[↑ Back to Outline](#outline) + +The provider chain providing VSCs to the consumer chains has two desired outcomes: the consumer chains apply the VSCs; and the provider chain registers VSC maturity notifications from every consumer chain. +Thus, for clarity, we split the properties of VSCs in two: properties of applying provided VSCs on the consumer chains; and properties of registering VSC maturity notifications on the provider chain. +For simplicity, we focus on a single consumer chain. + +The following properties define the guarantees of CCV on *applying* on the consumer chain VSCs *provided* by the provider chain. +- ***Apply VSC Validity***: Every VSC applied by the consumer chain MUST be provided by the provider chain. +- ***Apply VSC Order***: If a VSC `vsc1` is provided by the provider chain before a VSC `vsc2`, then the consumer chain MUST NOT apply the validator updates included in `vsc2` before the validator updates included in `vsc1`. +- ***Apply VSC Liveness***: If the provider chain provides a VSC `vsc`, then the consumer chain MUST eventually apply all validator updates included in `vsc`. + +The following properties define the guarantees of CCV on *registering* on the provider chain maturity notifications (from the consumer chain) of VSCs *provided* by the provider chain to the consumer chain. +- ***Register Maturity Validity***: If the provider chain registers a maturity notification of a VSC from the consumer chain, then the provider chain MUST have provided that VSC to the consumer chain. +- ***Register Maturity Timeliness***: The provider chain MUST NOT register a maturity notification of a VSC `vsc` before `UnbondingPeriod` has elapsed on the consumer chain since the consumer chain applied `vsc`. +- ***Register Maturity Order***: If a VSC `vsc1` was provided by the provider chain before another VSC `vsc2`, then the provider chain MUST NOT register the maturity notification of `vsc2` before the maturity notification of `vsc1`. +- ***Register Maturity Liveness***: If the provider chain provides a VSC `vsc` to the consumer chain, then the provider chain MUST eventually register a maturity notification of `vsc` from the consumer chain. + +### Consumer Initiated Slashing +[↑ Back to Outline](#outline) + +- ***Consumer Slashing Warranty***: Let `cc` be a consumer chain, such that its CCV module receives at height `he` evidence that a validator `val` misbehaved on `cc` at height `hi`. + Let `hv` be the height when the CCV module of `cc` receives the first VSC from the provider CCV module, i.e., the height when the CCV channel is established. + Then, the CCV module of `cc` MUST send (to the provider CCV module) *exactly one* `SlashPacket` `P`, such that + - `P` is sent at height `h = max(he, hv)`; + - `P.val = val` and `P.id = HtoVSC[hi]`, + i.e., the ID of the latest VSC that updated the validator set on `cc` at height `hi` or `0` if such a VSC does not exist (if `hi < hv`). + > **Note**: A consequence of the *Consumer Slashing Warranty* property is that the initial validator set on a consumer chain cannot be slashed during the initialization of the CCV channel. + Therefore, consumer chains *SHOULD NOT allow user transactions before the CCV channel is established*. + Note that once the CCV channel is established (i.e., a VSC is received from the provider CCV module), CCV enables the slashing of the initial validator set for infractions committed during channel initialization. + +- ***Provider Slashing Warranty***: If the provider CCV module receives at height `hs` from a consumer chain `cc` a `SlashPacket` containing a validator `val` and a VSC ID `vscId`, + then it MUST make at height `hs` *exactly one* request to the provider Slashing module to slash `val` for misbehaving at height `h`, such that + - if `vscId = 0`, `h` is the height of the block when the provider chain established a CCV channel to `cc`; + - otherwise, `h` is the height of the block immediately subsequent to the block when the provider chain provided to `cc` the VSC with ID `vscId`. + +- ***VSC Maturity and Slashing Order***: If a consumer chain sends to the provider chain a `SlashPacket` before a maturity notification of a VSC, then the provider chain MUST NOT receive the maturity notification before the `SlashPacket`. + > **Note**: *VSC Maturity and Slashing Order* requires the VSC maturity notifications to be sent through their own IBC packets (i.e., `VSCMaturedPacket`s) instead of e.g., through acknowledgements of `VSCPacket`s. + +### Reward Distribution +[↑ Back to Outline](#outline) + +- ***Distribution Liveness***: If the CCV module on a consumer chain sends to the distribution module account on the provider chain an amount `T` of tokens as reward for providing security, then `T` (equivalent) tokens are eventually minted in the distribution module account on the provider chain. + +## Correctness Reasoning +[↑ Back to Outline](#outline) + +In this section we argue the correctness of the CCV protocol described in the [Technical Specification](./technical_specification.md), +i.e., we informally prove the properties described in the [previous section](#desired-properties). + +- ***Channel Uniqueness***: The provider chain side of the CCV channel is established when the provider CCV module receives the first `ChanOpenConfirm` message; all subsequent `ChanOpenConfirm` messages result in the underlying channel being closed (cf. *Safe Blockchain*). + Similarly, the consumer chain side of the CCV channel is established when the consumer CCV module receives the first `VSCPacket` and ignores any packets received on different channels (cf. *Safe Blockchain*). + +- ***Channel Validity***: Follows directly from the *Safe Blockchain* assumption. + +- ***Channel Order***: The provider chain accepts only ordered channels when receiving a `ChanOpenTry` message (cf. *Safe Blockchain*). + Similarly, the consumer chain accepts only ordered channels when receiving `ChanOpenInit` messages (cf. *Safe Blockchain*). + Thus, the property follows directly from the fact that the CCV channel is ordered. + +- ***Channel Liveness***: The property follows from the *Correct Relayer* assumption. + +- ***Validator Update To VSC Validity***: The provider CCV module provides only VSCs that contain validator updates obtained from the Staking module, + i.e., by calling the `GetValidatorUpdates()` method (cf. *Safe Blockchain*). + Furthermore, these validator updates were applied to the validator set of the provider chain (cf. *Validator Update Provision*). + +- ***Validator Update To VSC Order***: We prove the property through contradiction. + Given two validator updates `U1` and `U2`, with `U1` occurring on the provider chain before `U2`, we assume `U2` is included in a provided VSC before `U1`. + However, `U2` could not have been obtained by the provider CCV module before `U1` (cf. *Validator Update Provision*). + Thus, the provider CCV module could not have provided a VSC that contains `U2` before a VSC that contains `U1` (cf. *Safe Blockchain*), which contradicts the initial assumption. + +- ***Validator Update To VSC Liveness***: The provider CCV module eventually provides to all consumer chains VSCs containing all validator updates obtained from the provider Staking module (cf. *Safe Blockchain*, *Life Blockchain*). + Thus, it is sufficient to prove that every update of a validator in the validator set of the provider chain MUST eventually be obtained from the provider Staking module. + We prove this through contradiction. Given a validator update `U` that is applied to the validator set of the provider chain at the end of a block `B` with height `h`, we assume `U` is never obtained by the provider CCV module. + However, at height `h`, the provider CCV module tries to obtain a new batch of validator updates from the provider Staking module (cf. *Safe Blockchain*). + Thus, this batch of validator updates MUST contain all validator updates applied to the validator set of the provider chain at the end of block `B`, including `U` (cf. *Validator Update Provision*), which contradicts the initial assumption. + +- ***Apply VSC Validity***: The property follows from the following two assertions. + - The consumer chain only applies VSCs received in `VSCPacket`s through the CCV channel (cf. *Safe Blockchain*). + - The provider chain only sends `VSCPacket`s containing provided VSCs (cf. *Safe Blockchain*). + +- ***Apply VSC Order***: We prove the property through contradiction. + Given two VSCs `vsc1` and `vsc2` such that the provider chain provides `vsc1` before `vsc2`, we assume the consumer chain applies the validator updates included in `vsc2` before the validator updates included in `vsc1`. + The following sequence of assertions leads to a contradiction. + - The provider chain could not have sent a `VSCPacket` `P2` containing `vsc2` before a `VSCPacket` `P1` containing `vsc1` (cf. *Safe Blockchain*). + - The consumer chain could not have received `P2` before `P1` (cf. *Channel Order*). + - Given the *Safe Blockchain* assumption, we distinguish two cases. + - First, the consumer chain receives `P1` during block `B1` and `P2` during block `B2` (with `B1` < `B2`). + Then, it applies the validator updates included in `vsc1` at the end of `B1` and the validator updates included in `vsc2` at the end of `B2` (cf. *Validator Update Inclusion*), which contradicts the initial assumption. + - Second, the consumer chain receives both `P1` and `P2` during the same block. + Then, it applies the validator updates included in both `vsc1` and `vsc2` at the end of the block. + Thus, it could not have apply the validator updates included in `vsc2` before. + +- ***Apply VSC Liveness***: The provider chain eventually sends over the CCV channel a `VSCPacket` containing `vsc` (cf. *Safe Blockchain*, *Life Blockchain*). + As a result, the consumer chain eventually receives this packet (cf. *Channel Liveness*). + Then, the consumer chain aggregates all received VSCs at the end of the block and applies all the aggregated updates (cf. *Safe Blockchain*, *Life Blockchain*). + As a result, the consumer chain applies all validator updates in `vsc` (cf. *Validator Update Inclusion*). + +- ***Register Maturity Validity***: The property follows from the following sequence of assertions. + - The provider chain only registers VSC maturity notifications when receiving on the CCV channel a `VSCMaturedPacket`s notifying the maturity of those VSCs (cf. *Safe Blockchain*). + - The provider chain receives on the CCV channel only packets sent by the consumer chain (cf. *Channel Validity*). + - The consumer chain only sends `VSCMaturedPacket`s matching the `VSCPacket`s it receives on the CCV channel (cf. *Safe Blockchain*). + - The consumer chain receives on the CCV channel only packets sent by the provider chain (cf. *Channel Validity*). + - The provider chain only sends `VSCPacket`s containing provided VSCs (cf. *Safe Blockchain*). + +- ***Register Maturity Timeliness***: We prove the property through contradiction. + Given a VSC `vsc` provided by the provider chain to the consumer chain, we assume that the provider chain registers a maturity notification of `vsc` before `UnbondingPeriod` has elapsed on the consumer chain since the consumer chain applied `vsc`. + The following sequence of assertions leads to a contradiction. + - The provider chain could not have register a maturity notification of `vsc` before receiving on the CCV channel a `VSCMaturedPacket` `P` with `P.id = vsc.id` (cf. *Safe Blockchain*). + - The provider chain could not have received `P` on the CCV channel before the consumer chain sent it (cf. *Channel Validity*). + - The consumer chain could not have sent `P` before at least `UnbondingPeriod` has elapsed since receiving a `VSCPacket` `P'` with `P'.id = P.id` on the CCV channel (cf. *Safe Blockchain*). + Note that since time is measured in terms of the block time, the time of receiving `P'` is the same as the time of applying `vsc`. + - The consumer chain could not have received `P'` on the CCV channel before the provider chain sent it (cf. *Channel Validity*). + - The provider chain could not have sent `P'` before providing `vsc`. + - Since the duration of sending packets through the CCV channel cannot be negative, the provider chain could not have registered a maturity notification of `vsc` before `UnbondingPeriod` has elapsed on the consumer chain since the consumer chain applied `vsc`. + +- ***Register Maturity Order***: We prove the property through contradiction. Given two VSCs `vsc1` and `vsc2` such that the provider chain provides `vsc1` before `vsc2`, we assume the provider chain registers the maturity notification of `vsc2` before the maturity notification of `vsc1`. + The following sequence of assertions leads to a contradiction. + - The provider chain could not have sent a `VSCPacket` `P2`, with `P2.updates = C2`, before a `VSCPacket` `P1`, with `P1.updates = C1` (cf. *Safe Blockchain*). + - The consumer chain could not have received `P2` before `P1` (cf. *Channel Order*). + - The consumer chain could not have sent a `VSCMaturedPacket` `P2'`, with `P2'.id = P2.id`, before a `VSCMaturedPacket` `P1'`, with `P1'.id = P1.id` (cf. *Safe Blockchain*). + - The provider chain could not have received `P2'` before `P1'` (cf. *Channel Order*). + - The provider chain could not have registered the maturity notification of `vsc2` before the maturity notification of `vsc1` (cf. *Safe Blockchain*). + +- ***Register Maturity Liveness***: The property follows from the following sequence of assertions. + - The provider chain eventually sends on the CCV channel a `VSCPacket` `P`, with `P.updates = C` (cf. *Safe Blockchain*, *Life Blockchain*). + - The consumer chain eventually receives `P` on the CCV channel (cf. *Channel Liveness*). + - The consumer chain eventually sends on the CCV channel a `VSCMaturedPacket` `P'`, with `P'.id = P.id` (cf. *Safe Blockchain*, *Life Blockchain*). + - The provider chain eventually receives `P'` on the CCV channel (cf. *Channel Liveness*). + - The provider chain eventually registers the maturity notification of `vsc` (cf. *Safe Blockchain*, *Life Blockchain*). + +- ***Consumer Slashing Warranty***: Follows directly from *Safe Blockchain*. + +- ***Provider Slashing Warranty***: Follows directly from *Safe Blockchain*. + +- ***VSC Maturity and Slashing Order***: Follows directly from *Channel Order*. + +- ***Distribution Liveness***: The CCV module on the consumer chain sends to the provider chain an amount `T` of tokens through an IBC token transfer packet (as defined in [ICS 20](../ics-020-fungible-token-transfer/README.md)). + Thus, if the packet is relayed within the timeout period, then `T` (equivalent) tokens are minted on the provider chain. + Otherwise, the `T` tokens are refunded to the consumer CCV module account. + In this case, the `T` tokens will be part of the next token transfer packet. + Eventually, a correct relayer will relay a token transfer packet containing the `T` tokens (cf. *Correct Relayer*, *Life Blockchain*). + As a result, `T` (equivalent) tokens are eventually minted on the provider chain. + +- ***Validator Set Replication***: The property follows from the *Safe Blockchain* assumption and both the *Apply VSC Validity* and *Validator Update To VSC Validity* properties. + +- ***Bond-Based Consumer Voting Power***: The existence of `hp` is given by construction, i.e., the block on the proposer chain that handles a governance proposal to spawn a new consumer chain `cc` *happens before* all the blocks of `cc`. + The existence of `hc'` and `hp'` is given by *Life Blockchain* and *Channel Liveness*. + + To prove the *Bond-Based Consumer Voting Power* property, we use the following property that follows directly from the design of the protocol (cf. *Safe Blockchain*, *Life Blockchain*). + - *Property1*: Let `val` be a validator; let `Ua` and `Ub` be two updates of `val` that are applied subsequently by a consumer chain `cc`, at block heights `ha` and `hb`, respectively (i.e., no other updates of `val` are applied in between). + Then, `Power(cc,ha,val) = Power(cc,h,val)`, for all block heights `h`, such that `ha <= h < hb` (i.e., the voting power granted to `val` on `cc` in the period between `ts(ha)` and `ts(hb)` is constant). + + We prove the *Bond-Based Consumer Voting Power* property through contradiction. + We assume there exist a height `h` on the provider chain between `hp` and `hp'` such that `Power(cc,hc,val) > VP( pBonded(h,val) + sumUnbonding(hp, h, val) + sumSlash(hp, h, val) )`. + The following sequence of assertions leads to a contradiction. + - Let `U1` be the latest update of `val` that is applied by `cc` before or not later than block height `hc` + (i.e., `U1` is the update that sets `Power(cc,hc,val)` for `val`). + Let `hp1` be the height at which `U1` occurs on the provider chain; let `hc1` be the height at which `U1` is applied on `cc`. + Then, `hp1 << hc1 <= hc`, `hp1 <= hp`, and `Power(cc,hc,val) = Power(cc,hc1,val) = VP(pBonded(hp1,val))`. + This means that some of the tokens bonded by `val` at height `hp1` were *completely* unbonded before or not later than height `hp'` (cf. `Power(cc,hc,val) > VP( pBonded(h,val) + sumUnbonding(hp, h, val) + sumSlash(hp, h, val) )`). + - Let `uo` be the first such unbonding operation that is initiated on the provider chain at height `hp2`, such that `hp1 < hp2 <= hp'`. + Note that at height `hp2`, the tokens unbonded by `uo` are part of `pUnbonding(hp2,val)`. + Let `U2` be the validator update caused by initiating `uo`. + Let `hc2` be the height at which `U2` is applied on `cc`; clearly, `Power(cc,hc2,val) < Power(cc,hc,val)`. + Note that the existence of `hc2` is ensured by *Validator Update To VSC Liveness* and *Apply VSC Liveness*. + Then, `hc2 > hc1` (cf. `hp2 > hp1`, *Validator Update To VSC Order*, *Apply VSC Order*). + - `Power(cc,hc,val) = Power(cc,hc1,val) = Power(cc,h,val)`, for all heights `h`, such that `hc1 <= h < hc2` (cf. *Property1*). + Thus, `hc2 > hc` (cf. `Power(cc,hc2,val) < Power(cc,hc,val)`). + - `uo` cannot complete before `ts(hc2) + UnbondingPeriod`, which means it cannot complete before `hc'` and thus it cannot complete before `hp'` (cf. `hc' << hp'`). + +- ***Slashable Consumer Misbehavior***: The second part of the *Slashable Consumer Misbehavior* property (i.e., `val` is not slashed more than once for the same misbehavior) follows directly from *Evidence Provision*, *Channel Validity*, *Consumer Slashing Warranty*, *Provider Slashing Warranty*. + To prove the first part of the *Slashable Consumer Misbehavior* property (i.e., exactly the amount of tokens `sf*Token(Power(cc,hi,val))` are slashed on the provider chain), we consider the following sequence of statements. + - The CCV module of `cc` receives at height `he` the evidence that `val` misbehaved on `cc` at height `hi` (cf. *Evidence Provision*, *Safe Blockchain*, *Life Blockchain*). + - Let `hv` be the height when the CCV module of `cc` receives the first VSC from the provider CCV module. + Then, the CCV module of `cc` sends at height `h = max(he, hv)` to the provider chain a `SlashPacket` `P`, such that `P.val = val` and `P.id = HtoVSC[hi]` (cf. *Consumer Slashing Warranty*). + - The provider CCV module eventually receives `P` in a block `B` (cf. *Channel Liveness*). + - The provider CCV module requests (in the same block `B`) the provider Slashing module to slash `val` for misbehaving at height `hp = VSCtoH[P.id]` (cf. *Provider Slashing Warranty*). + - The provider Slashing module slashes the amount of tokens `val` had bonded at height `hp` except the amount that has already completely unbonded (cf. *Slashing Warranty*). + + Thus, it remains to be proven that `Token(Power(cc,hi,val)) = pBonded(hp,val)`, with `hp = VSCtoH[HtoVSC[hi]]`. We distinguish two cases: + - `HtoVSC[hi] != 0`, which means that by definition `HtoVSC[hi]` is the ID of the last VSC that update `Power(cc,hi,val)`. + Also by definition, this VSC contains the last updates to the voting power at height `VSCtoH[HtoVSC[hi]]` on the provider. + Thus, `Token(Power(cc,hi,val)) = pBonded(hp,val)`. + - `HtoVSC[hi] == 0`, which means that by definition `Power(cc,hi,val)` was setup at genesis during Channel Initialization. + Also by definition, this is the same voting power of the provider chain block when the first VSC was provided to that consumer chain, i.e., `VSCtoH[HtoVSC[hi]]`. + Thus, `Token(Power(cc,hi,val)) = pBonded(hp,val)`. + +- ***Consumer Rewards Distribution***: The first part of the *Consumer Rewards Distribution* property (i.e., the tokens are eventually minted on the provider chain and then distributed among the validators) follows directly from *Distribution Liveness* and *Distribution Warranty*. + The second part of the *Consumer Rewards Distribution* property (i.e., the total supply of tokens is preserved) follows directly from the *Supply* property of the Fungible Token Transfer protocol (see [ICS 20](../ics-020-fungible-token-transfer/README.md)). diff --git a/spec/app/ics-028-cross-chain-validation/technical_specification.md b/spec/app/ics-028-cross-chain-validation/technical_specification.md new file mode 100644 index 000000000..1fc5c26f7 --- /dev/null +++ b/spec/app/ics-028-cross-chain-validation/technical_specification.md @@ -0,0 +1,120 @@ + +# CCV: Technical Specification +[↑ Back to main document](./README.md) + + +## Outline +- [Placing CCV within an ABCI Application](#placing-ccv-within-an-abci-application) + - [Implemented Interfaces](#implemented-interfaces) + - [Interfacing Other Modules](#interfacing-other-modules) +- [Data Structures and Methods](#data-structures-and-methods) + +## Placing CCV within an ABCI Application +[↑ Back to Outline](#outline) + +Before describing the data structures and sub-protocols of the CCV protocol, we provide a short overview of the interfaces the CCV module implements and the interactions with the other ABCI application modules. + +### Implemented Interfaces + +- CCV is an **ABCI application module**, which means it MUST implement the logic to handle some of the messages received from the consensus engine via ABCI, + e.g., `InitChain`, `BeginBlock`, `EndBlock` (for more details, take a look at the [ABCI specification](https://github.com/tendermint/spec/tree/v0.7.1/spec/abci)). + In this specification we define the following methods that handle messages that are of particular interest to the CCV protocol: + - `InitGenesis()` -- Called when the chain is first started, on receiving an `InitChain` message from the consensus engine. + This is also where the application can inform the underlying consensus engine of the initial validator set. + - `BeginBlock()` -- Contains logic that is automatically triggered at the beginning of each block. + - `EndBlock()` -- Contains logic that is automatically triggered at the end of each block. + This is also where the application can inform the underlying consensus engine of changes in the validator set. + +- CCV is an **IBC module**, which means it MUST implement the module callbacks interface defined in [ICS 26](../../core/ics-026-routing-module/README.md#module-callback-interface). The interface consists of a set of callbacks for + - channel opening handshake, which we describe in the [Initialization](./methods.md#initialization) section; + - channel closing handshake, which we describe in the [Consumer Chain Removal](./methods.md#consumer-chain-removal) section; + - and packet relay, which we describe in the [Packet Relay](./methods.md#packet-relay) section. + +### Interfacing Other Modules + +- As an ABCI application module, the CCV module interacts with the underlying consensus engine through ABCI: + - On the provider chain, + - it initializes the application (e.g., binds to the expected IBC port) in the `InitGenesis()` method. + - On the consumer chain, + - it initializes the application (e.g., binds to the expected IBC port, creates a client of the provider chain) in the `InitGenesis()` method; + - it provides the validator updates in the `EndBlock()` method. + +- As an IBC module, the CCV module interacts with Core IBC for functionalities regarding + - port allocation ([ICS 5](../../core/ics-005-port-allocation)) via `portKeeper`; + - channels and packet semantics ([ICS 4](../../core/ics-004-channel-and-packet-semantics)) via `channelKeeper`; + - connection semantics ([ICS 3](../../core/ics-003-connection-semantics)) via `connectionKeeper`; + - client semantics ([ICS 2](../../core/ics-002-client-semantics)) via `clientKeeper`. + +- The consumer CCV module interacts with the IBC Token Transfer module ([ICS 20](../ics-020-fungible-token-transfer/README.md)) via `transferKeeper`. + +- For the [Initialization sub-protocol](#initialization), the provider CCV module interacts with a Governance module by handling governance proposals to spawn new consumer chains. + If such proposals pass, then all validators on the provider chain MUST validate the consumer chain at spawn time; + otherwise they get slashed. + For an example of how governance proposals work, take a look at the [Governance module documentation](https://docs.cosmos.network/v0.44/modules/gov/) of Cosmos SDK. + +- The provider CCV module interacts with a Staking module on the provider chain. + For an example of how staking works, take a look at the [Staking module documentation](https://docs.cosmos.network/v0.44/modules/staking/) of Cosmos SDK. + The interaction is defined by the following interface: + ```typescript + interface StakingKeeper { + // get UnbondingPeriod from the provider Staking module + UnbondingTime(): Duration + + // get validator updates from the provider Staking module + GetValidatorUpdates(): [ValidatorUpdate] + + // request the Staking module to put on hold + // the completion of an unbonding operation + PutUnbondingOnHold(id: uint64) + + // notify the Staking module of an unboding operation that + // has matured from the perspective of the consumer chains + UnbondingCanComplete(id: uint64) + } + ``` + +- The provider CCV module interacts with a Slashing module on the provider chain. + For an example of how slashing works, take a look at the [Slashing module documentation](https://docs.cosmos.network/v0.44/modules/slashing/) of Cosmos SDK. + The interaction is defined by the following interface: + ```typescript + interface SlashingKeeper { + // query the Slashing module for the slashing factor, + // which may be different for downtime infractions + GetSlashFactor(downtime: Bool): int64 + + // request the Slashing module to slash a validator + Slash(valAddress: string, + infractionHeight: int64, + power: int64, + slashFactor: int64) + + // query the Slashing module for the jailing time, + // which may be different for downtime infractions + GetJailTime(downtime: Bool): int64 + + // request the Slashing module to jail a validator until time + JailUntil(valAddress: string, time: uint64) + } + ``` + +- The following hook enables the provider CCV module to register operations to be execute when certain events occur within the provider Staking module: + ```typescript + // invoked by the Staking module after + // initiating an unbonding operation + function AfterUnbondingInitiated(opId: uint64); + ``` + +- The consumer CCV module defines the following hooks that enable other modules to register operations to execute when certain events have occurred within CCV: + ```typescript + // invoked after a new validator is added to the validator set + function AfterCCValidatorBonded(valAddress: string); + + // invoked after a validator is removed from the validator set + function AfterCCValidatorBeginUnbonding(valAddress: string); + ``` + +## Data Structures and Methods +[↑ Back to Outline](#outline) + +The remainder of this technical specification is split into [Data Structures](./data_structures.md) and [Methods](./methods.md). +