This module contains the Quantum Gravity Bridge (QGB) state machine implementation.
The QGB state machine handles the creation of AttestationRequestI
which can be either a DataCommitment
or a Valset
.
During their creation, the state machine might panic due to an unexpected behavior or event. These panics will be discussed below.
A new valset is created in the following situations:
if (latestValset == nil) || (lastUnbondingHeight == uint64(ctx.BlockHeight())) || significantPowerDiff {
...
}
- 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.
A new data commitment is created in the following situation:
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.
The data commitment window is defined as a governance parameter that can be changed. Currently, it is set to 400.
During EndBlock step, the state machine generates new attestations if needed. During this generation, the state machine could panic.
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:
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:
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:
intLatestMembers, err := types.BridgeValidators(latestValset.Members).ToInternal()
if err != nil {
panic(sdkerrors.Wrap(err, "invalid latest valset members"))
}
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 is a duplicate of an existing attestation:
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:
b, err := k.cdc.MarshalInterface(at)
if err != nil {
panic(err)
}
- The universal nonce was not incremented correctly by 1:
if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx)+1 != nonce {
panic("not incrementing latest attestation nonce correctly")
}
The QGB verification command is part of the celestia-appd
binary. It allows the user to verify that a set of shares has been posted to a specific QGB contract.
$ celestia-appd verify --help
Verifies that a transaction hash, a range of shares, or a blob referenced by its transaction hash were committed to by the QGB contract
Usage:
celestia-appd verify [command]
Available Commands:
blob Verifies that a blob, referenced by its transaction hash, in hex format, has been committed to by the QGB contract.
shares Verifies that a range of shares has been committed to by the QGB contract
tx Verifies that a transaction hash, in hex format, has been committed to by the QGB contract
Flags:
-h, --help help for verify
Global Flags:
--home string directory for config and data (default "/home/midnight/.celestia-app")
--log_format string The logging format (json|plain) (default "plain")
--log_level string The logging level (trace|debug|info|warn|error|fatal|panic) (default "info")
--trace print out full stack trace on errors
Use "celestia-appd verify [command] --help" for more information about a command.
It currently supports three sub-commands:
blob
: Takes a transaction hash, in hex format, and verifies that the blob paid for by the transaction has been committed to by the QGB contract. It only supports one blob for now.shares
: Takes a range of shares and a height, and verifies that these shares have been committed to by the QGB contract.tx
: Takes a transaction hash, in hex format, and verifies that it has been committed to by the QGB contract.
The smart contract implementation is in quantum-gravity-bridge.
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 branch.
QGB ADRs are in the docs.