From b70c32f82276f992778f4190b03c38cb8ce3d17f Mon Sep 17 00:00:00 2001 From: rachid Date: Tue, 22 Nov 2022 15:25:10 +0100 Subject: [PATCH 01/12] docs: add qgb module readme --- x/qgb/README.md | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 x/qgb/README.md diff --git a/x/qgb/README.md b/x/qgb/README.md new file mode 100644 index 0000000000..575a597046 --- /dev/null +++ b/x/qgb/README.md @@ -0,0 +1,168 @@ +# Quantum gravity bridge state machine + +This module contains the [Quantum gravity bridge](https://blog.celestia.org/celestiums/) state machine implementation. + +## State machine + +The QGB state machine handles the creation of the attestations requests: + +https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/types/attestation.go#L15-L23 + +These latter is either data commitments: + +```proto +// DataCommitment is the data commitment request message that will be signed +// using orchestrators. +// It does not contain a `commitment` field as this message will be created +// inside the state machine and it doesn't make sense to ask tendermint for the +// commitment there. +message DataCommitment { + option (cosmos_proto.implements_interface) = "AttestationRequestI"; + // Universal nonce defined under: + // https://github.com/celestiaorg/celestia-app/pull/464 uint64 nonce = 1; + // First block defining the ordered set of blocks used to create the + // commitment. uint64 begin_block = 2; + // Last block defining the ordered set of blocks used to create the + // commitment. uint64 end_block = 3; +} +``` + +Or, valsets: + +```proto +// Valset is the EVM Bridge Multsig Set, each qgb validator also +// maintains an ETH key to sign messages, these are used to check signatures on +// ETH because of the significant gas savings +message Valset { + option (cosmos_proto.implements_interface) = "AttestationRequestI"; + // Universal nonce defined under: + // https://github.com/celestiaorg/celestia-app/pull/464 uint64 nonce = 1; + // List of BridgeValidator containing the current validator set. + repeated BridgeValidator members = 2 [ (gogoproto.nullable) = false ]; + // Current chain height + uint64 height = 3; +} +``` + +During their creation, the state machine might panic due to an unexpected behavior or event. These panics will be discussed below. + +### Conditions of generating a new attestation + +#### New valset creation + +A new valset is created in the following situations: + +https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/abci.go#L74 + +- No valset exist in store, so a new valset will be created. This happens mostly after genesis, or after a hard fork. +- The current block height is the last unbonding height, i.e. when a validator is leaving the validator set. A new valset will need to be created to accommodate that change. +- A significant power difference happened since the last valset. This could happen if a validator has way more staking power or the opposite. The significant power difference threshold is defined by the constant `SignificantPowerDifferenceThreshold`, and it is set to 5% currently. + +#### New data commitment creation + +A new data commitment is created in the following situation: + +https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/abci.go#L23 + +I.e. the current block height is not 0, and we're at a data commitment window height. + +The data commitment window is defined as a governance parameter that can be changed. Currently, it is set to 400. + +### Panics + +During EndBlock step, the state machine generates new attestations if needed. During this generation, the state machine could panic. + +#### Data commitment panics + +During EndBlock, if the block height corresponds to a `DataCommitmentWindow`, it will generate a new data commitment, during which, the state machine can panic in the following case: + +- An unexpected behavior happened while getting the current data commitment: + +```golang +dataCommitment, err := k.GetCurrentDataCommitment(ctx) +if err != nil { + panic(sdkerrors.Wrap(err, "coudln't get current data commitment")) +} +``` + +#### Valset panics + +Similar to data commitments, when checking if the state machine needs to generate a new valset, it might panic in the following cases: + +- When checking that a previous valset has been emitted, but it is unable to get it: + +```golang +if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx) != 0 { + var err error + latestValset, err = k.GetLatestValset(ctx) + if err != nil { + panic(err) + } +} +``` + +- When getting the current valset: + +```golang +vs, err := k.GetCurrentValset(ctx) +if err != nil { + // this condition should only occur in the simulator + // ref : https://github.com/Gravity-Bridge/Gravity-Bridge/issues/35 if errors.Is(err, types.ErrNoValidators) { + ctx.Logger().Error("no bonded validators", + "cause", err.Error(), + ) + return + } + panic(err) +} +``` + +- When creating the internal validator struct, i.e. mapping the validators EVM addresses to their powers: + +```golang +intLatestMembers, err := types.BridgeValidators(latestValset.Members).ToInternal() +if err != nil { + panic(sdkerrors.Wrap(err, "invalid latest valset members")) +} +``` + +#### Attestations panics + +When storing a new attestation, which is either a data commitment or a valset, the state machine can panic for in the following cases: + +- The attestation request created from the data commitment is a duplicate of an existing attestation: + +```golang +key := []byte(types.GetAttestationKey(nonce)) +store := ctx.KVStore(k.storeKey) + +if store.Has(key) { + panic("trying to overwrite existing attestation request") +} +``` + +- An error happened while marshalling the interface: + +```golang +b, err := k.cdc.MarshalInterface(at) +if err != nil { + panic(err) +} +``` + +- The universal nonce was not incremented correctly by 1: + +```golang +if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx)+1 != nonce { + panic("not incrementing latest attestation nonce correctly") +} +``` + + +## Useful links + +The smart contract implementation is in [quantum-gravity-bridge](https://github.com/celestiaorg/quantum-gravity-bridge/). + +The orchestrator and relayer implementations are in [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer/). + +QGB v1 implementation, including the orchestrator and relayer, is in the [qgb-integration](https://github.com/celestiaorg/celestia-app/tree/qgb-integration) branch. From 9aa034783109cd6293cffa69ddceb56cf535e014 Mon Sep 17 00:00:00 2001 From: rachid Date: Tue, 22 Nov 2022 15:32:16 +0100 Subject: [PATCH 02/12] docs: use links instead of code --- x/qgb/README.md | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 575a597046..0bfbf3ed35 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -10,39 +10,11 @@ https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb6 These latter is either data commitments: -```proto -// DataCommitment is the data commitment request message that will be signed -// using orchestrators. -// It does not contain a `commitment` field as this message will be created -// inside the state machine and it doesn't make sense to ask tendermint for the -// commitment there. -message DataCommitment { - option (cosmos_proto.implements_interface) = "AttestationRequestI"; - // Universal nonce defined under: - // https://github.com/celestiaorg/celestia-app/pull/464 uint64 nonce = 1; - // First block defining the ordered set of blocks used to create the - // commitment. uint64 begin_block = 2; - // Last block defining the ordered set of blocks used to create the - // commitment. uint64 end_block = 3; -} -``` +https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L31-L47 Or, valsets: -```proto -// Valset is the EVM Bridge Multsig Set, each qgb validator also -// maintains an ETH key to sign messages, these are used to check signatures on -// ETH because of the significant gas savings -message Valset { - option (cosmos_proto.implements_interface) = "AttestationRequestI"; - // Universal nonce defined under: - // https://github.com/celestiaorg/celestia-app/pull/464 uint64 nonce = 1; - // List of BridgeValidator containing the current validator set. - repeated BridgeValidator members = 2 [ (gogoproto.nullable) = false ]; - // Current chain height - uint64 height = 3; -} -``` +https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L17-L29 During their creation, the state machine might panic due to an unexpected behavior or event. These panics will be discussed below. @@ -56,7 +28,7 @@ https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb6 - No valset exist in store, so a new valset will be created. This happens mostly after genesis, or after a hard fork. - The current block height is the last unbonding height, i.e. when a validator is leaving the validator set. A new valset will need to be created to accommodate that change. -- A significant power difference happened since the last valset. This could happen if a validator has way more staking power or the opposite. The significant power difference threshold is defined by the constant `SignificantPowerDifferenceThreshold`, and it is set to 5% currently. +- A significant power difference happened since the last valset. This could happen if a validator has way more staking power or the opposite. The significant power difference threshold is defined by the constant `SignificantPowerDifferenceThreshold`, and is set to 5% currently. #### New data commitment creation From 0cc804b90968376c2dca127add2f91f50b287766 Mon Sep 17 00:00:00 2001 From: rachid Date: Tue, 22 Nov 2022 15:34:40 +0100 Subject: [PATCH 03/12] docs: cosmetics --- x/qgb/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 0bfbf3ed35..da7581a7f2 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -1,4 +1,4 @@ -# Quantum gravity bridge state machine +# Quantum gravity bridge state machine This module contains the [Quantum gravity bridge](https://blog.celestia.org/celestiums/) state machine implementation. @@ -130,7 +130,6 @@ if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx)+1 != n } ``` - ## Useful links The smart contract implementation is in [quantum-gravity-bridge](https://github.com/celestiaorg/quantum-gravity-bridge/). From 4ee43370c5ea6d9cc50bb6593e46c835b755e323 Mon Sep 17 00:00:00 2001 From: rachid Date: Tue, 22 Nov 2022 15:41:55 +0100 Subject: [PATCH 04/12] docs: cosmetics --- x/qgb/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index da7581a7f2..05dc111ffe 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -79,7 +79,8 @@ if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx) != 0 { vs, err := k.GetCurrentValset(ctx) if err != nil { // this condition should only occur in the simulator - // ref : https://github.com/Gravity-Bridge/Gravity-Bridge/issues/35 if errors.Is(err, types.ErrNoValidators) { + // ref : https://github.com/Gravity-Bridge/Gravity-Bridge/issues/35 + if errors.Is(err, types.ErrNoValidators) { ctx.Logger().Error("no bonded validators", "cause", err.Error(), ) From c075fa2aa7bbd51b4dbcdc3422310869dc7a8153 Mon Sep 17 00:00:00 2001 From: CHAMI Rachid Date: Tue, 22 Nov 2022 17:38:01 +0100 Subject: [PATCH 05/12] Update x/qgb/README.md Co-authored-by: Rootul P --- x/qgb/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 05dc111ffe..522d9d5ed6 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -1,6 +1,7 @@ # Quantum gravity bridge state machine -This module contains the [Quantum gravity bridge](https://blog.celestia.org/celestiums/) state machine implementation. +## Abstract +This module contains the [Quantum Gravity Bridge](https://blog.celestia.org/celestiums/) (QGB) state machine implementation. ## State machine From 4ef6ee413b7bbc8f16fe9cad414d5d17c160f025 Mon Sep 17 00:00:00 2001 From: CHAMI Rachid Date: Tue, 22 Nov 2022 17:38:29 +0100 Subject: [PATCH 06/12] Update x/qgb/README.md Co-authored-by: Rootul P --- x/qgb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 522d9d5ed6..fd7786c9cd 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -1,4 +1,4 @@ -# Quantum gravity bridge state machine +# `x/qgb` ## Abstract This module contains the [Quantum Gravity Bridge](https://blog.celestia.org/celestiums/) (QGB) state machine implementation. From 1a75526438f1e2b268d588615cab7970e15e7dbf Mon Sep 17 00:00:00 2001 From: CHAMI Rachid Date: Tue, 22 Nov 2022 17:38:48 +0100 Subject: [PATCH 07/12] Update x/qgb/README.md Co-authored-by: Rootul P --- x/qgb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index fd7786c9cd..e03b3e62cc 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -102,7 +102,7 @@ if err != nil { #### Attestations panics -When storing a new attestation, which is either a data commitment or a valset, the state machine can panic for in the following cases: +When storing a new attestation, which is either a data commitment or a valset, the state machine can panic in the following cases: - The attestation request created from the data commitment is a duplicate of an existing attestation: From 13e6376199508e32ec8c5524c7d96869b69a028e Mon Sep 17 00:00:00 2001 From: rachid Date: Wed, 23 Nov 2022 10:59:55 +0100 Subject: [PATCH 08/12] docs: @evan-forbes suggestions --- x/qgb/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index e03b3e62cc..5ea708a0f8 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -47,7 +47,7 @@ During EndBlock step, the state machine generates new attestations if needed. Du #### Data commitment panics -During EndBlock, if the block height corresponds to a `DataCommitmentWindow`, it will generate a new data commitment, during which, the state machine can panic in the following case: +During EndBlock, if the block height corresponds to a `DataCommitmentWindow`, it will generate a new data commitment, during which, the state machine can panic, if it finds invalid state, in the following case: - An unexpected behavior happened while getting the current data commitment: @@ -60,7 +60,7 @@ if err != nil { #### Valset panics -Similar to data commitments, when checking if the state machine needs to generate a new valset, it might panic in the following cases: +Similar to data commitments, when checking if the state machine needs to generate a new valset, it might panic, if it finds invalid state, in the following cases: - When checking that a previous valset has been emitted, but it is unable to get it: @@ -102,7 +102,7 @@ if err != nil { #### Attestations panics -When storing a new attestation, which is either a data commitment or a valset, the state machine can panic in the following cases: +When storing a new attestation, which is either a data commitment or a valset, the state machine can panic, if it finds invalid state, in the following cases: - The attestation request created from the data commitment is a duplicate of an existing attestation: @@ -139,3 +139,5 @@ The smart contract implementation is in [quantum-gravity-bridge](https://github. The orchestrator and relayer implementations are in [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer/). QGB v1 implementation, including the orchestrator and relayer, is in the [qgb-integration](https://github.com/celestiaorg/celestia-app/tree/qgb-integration) branch. + +QGB ADRs are in the [docs](https://github.com/celestiaorg/celestia-app/tree/main/docs/architecture). From 7f28cb9584fe4cd7eba0eaf2dc9f4b75757c87f0 Mon Sep 17 00:00:00 2001 From: rachid Date: Wed, 23 Nov 2022 12:31:30 +0100 Subject: [PATCH 09/12] docs: cosmetics from feedback by @rootulp --- x/qgb/README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 5ea708a0f8..3a55813be5 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -1,21 +1,12 @@ # `x/qgb` ## Abstract + This module contains the [Quantum Gravity Bridge](https://blog.celestia.org/celestiums/) (QGB) state machine implementation. ## State machine -The QGB state machine handles the creation of the attestations requests: - -https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/types/attestation.go#L15-L23 - -These latter is either data commitments: - -https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L31-L47 - -Or, valsets: - -https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L17-L29 +The QGB state machine handles the creation of [`AttestationRequestI`](https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/types/attestation.go#L15-L23) which can be either a [`DataCommitment`](https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L31-L47) or a [`Valset`](https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/proto/qgb/types.proto#L17-L29). During their creation, the state machine might panic due to an unexpected behavior or event. These panics will be discussed below. @@ -25,9 +16,13 @@ During their creation, the state machine might panic due to an unexpected behavi A new valset is created in the following situations: -https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/abci.go#L74 +```golang +if (latestValset == nil) || (lastUnbondingHeight == uint64(ctx.BlockHeight())) || significantPowerDiff { + ... +} +``` -- No valset exist in store, so a new valset will be created. This happens mostly after genesis, or after a hard fork. +- No valset exists in store, so a new valset will be created. This happens mostly after genesis, or after a hard fork. - The current block height is the last unbonding height, i.e. when a validator is leaving the validator set. A new valset will need to be created to accommodate that change. - A significant power difference happened since the last valset. This could happen if a validator has way more staking power or the opposite. The significant power difference threshold is defined by the constant `SignificantPowerDifferenceThreshold`, and is set to 5% currently. @@ -35,7 +30,11 @@ https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb6 A new data commitment is created in the following situation: -https://github.com/celestiaorg/celestia-app/blob/801a0d412631989ce97748badbd7bb676982db16/x/qgb/abci.go#L23 +```golang +if ctx.BlockHeight() != 0 && ctx.BlockHeight()%int64(k.GetDataCommitmentWindowParam(ctx)) == 0 { + ... +} +``` I.e. the current block height is not 0, and we're at a data commitment window height. @@ -52,7 +51,8 @@ During EndBlock, if the block height corresponds to a `DataCommitmentWindow`, it - An unexpected behavior happened while getting the current data commitment: ```golang -dataCommitment, err := k.GetCurrentDataCommitment(ctx) +dataCommitment +}, err := k.GetCurrentDataCommitment(ctx) if err != nil { panic(sdkerrors.Wrap(err, "coudln't get current data commitment")) } From 47c8679e6bb1c482da8a5e7ca091d7685f7a410d Mon Sep 17 00:00:00 2001 From: rachid Date: Wed, 23 Nov 2022 12:34:37 +0100 Subject: [PATCH 10/12] docs: remove dead link --- x/qgb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 3a55813be5..7a705ebf89 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -136,7 +136,7 @@ if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx)+1 != n The smart contract implementation is in [quantum-gravity-bridge](https://github.com/celestiaorg/quantum-gravity-bridge/). -The orchestrator and relayer implementations are in [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer/). +For QGB v2, the orchestrator and relayer implementations will be in a separate repository. Links will be added subsequently. QGB v1 implementation, including the orchestrator and relayer, is in the [qgb-integration](https://github.com/celestiaorg/celestia-app/tree/qgb-integration) branch. From fd5a5d082b3cf34d9e42ded2c3082f1265768529 Mon Sep 17 00:00:00 2001 From: rachid Date: Thu, 24 Nov 2022 10:57:20 +0100 Subject: [PATCH 11/12] docs: @evan-forbes suggestions --- x/qgb/README.md | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 7a705ebf89..601ce34299 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -44,23 +44,9 @@ The data commitment window is defined as a governance parameter that can be chan During EndBlock step, the state machine generates new attestations if needed. During this generation, the state machine could panic. -#### Data commitment panics - -During EndBlock, if the block height corresponds to a `DataCommitmentWindow`, it will generate a new data commitment, during which, the state machine can panic, if it finds invalid state, in the following case: - -- An unexpected behavior happened while getting the current data commitment: - -```golang -dataCommitment -}, err := k.GetCurrentDataCommitment(ctx) -if err != nil { - panic(sdkerrors.Wrap(err, "coudln't get current data commitment")) -} -``` - #### Valset panics -Similar to data commitments, when checking if the state machine needs to generate a new valset, it might panic, if it finds invalid state, in the following cases: +When checking if the state machine needs to generate a new valset, the state machine might panic if it finds invalid state. This can happen in the following cases: - When checking that a previous valset has been emitted, but it is unable to get it: @@ -102,7 +88,7 @@ if err != nil { #### Attestations panics -When storing a new attestation, which is either a data commitment or a valset, the state machine can panic, if it finds invalid state, in the following cases: +When storing a new attestation, the state machine can panic if it finds invalid state. This latter can happen in the following cases: - The attestation request created from the data commitment is a duplicate of an existing attestation: From b10caf92ddf8de66d6174c79d0c1339c230471fb Mon Sep 17 00:00:00 2001 From: rachid Date: Thu, 24 Nov 2022 11:01:57 +0100 Subject: [PATCH 12/12] docs: @evan-forbes suggestions --- x/qgb/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/qgb/README.md b/x/qgb/README.md index 601ce34299..9e13a86637 100644 --- a/x/qgb/README.md +++ b/x/qgb/README.md @@ -90,7 +90,7 @@ if err != nil { When storing a new attestation, the state machine can panic if it finds invalid state. This latter can happen in the following cases: -- The attestation request created from the data commitment is a duplicate of an existing attestation: +- The attestation request created is a duplicate of an existing attestation: ```golang key := []byte(types.GetAttestationKey(nonce))