diff --git a/Makefile b/Makefile index a2cc0f3159..b7d1f179a8 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ test-race: # TODO: Remove the -skip flag once the following tests no longer contain data races. # https://github.com/celestiaorg/celestia-app/issues/1369 @echo "--> Running tests in race mode" - @go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestBlobStreamRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestBlobStreamCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext" + @go test ./... -v -race -skip "TestPrepareProposalConsistency|TestIntegrationTestSuite|TestBlobstreamRPCQueries|TestSquareSizeIntegrationTest|TestStandardSDKIntegrationTestSuite|TestTxsimCommandFlags|TestTxsimCommandEnvVar|TestMintIntegrationTestSuite|TestBlobstreamCLI|TestUpgrade|TestMaliciousTestNode|TestMaxTotalBlobSizeSuite|TestQGBIntegrationSuite|TestSignerTestSuite|TestPriorityTestSuite|TestTimeInPrepareProposalContext" .PHONY: test-race ## test-bench: Run unit tests in bench mode. diff --git a/app/test/qgb_rpc_test.go b/app/test/qgb_rpc_test.go index 07eb3f75f2..e7d4157627 100644 --- a/app/test/qgb_rpc_test.go +++ b/app/test/qgb_rpc_test.go @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestBlobStreamRPCQueries(t *testing.T) { +func TestBlobstreamRPCQueries(t *testing.T) { if testing.Short() { t.Skip("skipping blob stream integration test in short mode.") } diff --git a/proto/celestia/qgb/v1/genesis.proto b/proto/celestia/qgb/v1/genesis.proto index 08beebce0f..f574d88e4b 100644 --- a/proto/celestia/qgb/v1/genesis.proto +++ b/proto/celestia/qgb/v1/genesis.proto @@ -6,13 +6,13 @@ import "celestia/qgb/v1/types.proto"; option go_package = "github.com/celestiaorg/celestia-app/x/blobstream/types"; -// Params represent the BlobStream genesis and store parameters. +// Params represent Blobstream genesis and store parameters. message Params { option (gogoproto.stringer) = false; uint64 data_commitment_window = 1; } -// GenesisState struct, containing all persistent data required by BlobStream +// GenesisState struct, containing all persistent data required by Blobstream // module message GenesisState { Params params = 1; } diff --git a/proto/celestia/qgb/v1/tx.proto b/proto/celestia/qgb/v1/tx.proto index c9dc5c2373..b9c4fe1e58 100644 --- a/proto/celestia/qgb/v1/tx.proto +++ b/proto/celestia/qgb/v1/tx.proto @@ -7,7 +7,7 @@ import "google/api/annotations.proto"; option go_package = "github.com/celestiaorg/celestia-app/x/blobstream/types"; -// Msg is the message server for receiving BlobStream transactions +// Msg is the message server for receiving Blobstream transactions service Msg { // RegisterEVMAddress records an evm address for the validator which is used // by the relayer to aggregate signatures. A validator can only register a diff --git a/proto/celestia/qgb/v1/types.proto b/proto/celestia/qgb/v1/types.proto index 1cd3338b63..266788e2ab 100644 --- a/proto/celestia/qgb/v1/types.proto +++ b/proto/celestia/qgb/v1/types.proto @@ -15,7 +15,7 @@ message BridgeValidator { string evm_address = 2; } -// Valset is the EVM Bridge Multsig Set, each BlobStream validator also +// Valset is the EVM Bridge Multsig Set, each Blobstream 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 { diff --git a/test/util/common.go b/test/util/common.go index 82e1176002..a609c962b1 100644 --- a/test/util/common.go +++ b/test/util/common.go @@ -135,9 +135,9 @@ func initEVMAddrs(count int) []gethcommon.Address { return addresses } -// TestInput stores the various keepers required to test BlobStream +// TestInput stores the various keepers required to test Blobstream type TestInput struct { - BStreamKeeper keeper.Keeper + BstreamKeeper keeper.Keeper AccountKeeper authkeeper.AccountKeeper StakingKeeper stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper @@ -148,8 +148,8 @@ type TestInput struct { LegacyAmino *codec.LegacyAmino } -// CreateTestEnvWithoutBlobStreamKeysInit creates the keeper testing environment for BlobStream -func CreateTestEnvWithoutBlobStreamKeysInit(t *testing.T) TestInput { +// CreateTestEnvWithoutBlobstreamKeysInit creates the keeper testing environment for Blobstream +func CreateTestEnvWithoutBlobstreamKeysInit(t *testing.T) TestInput { t.Helper() // Initialize store keys @@ -294,8 +294,8 @@ func CreateTestEnvWithoutBlobStreamKeysInit(t *testing.T) TestInput { ) k := keeper.NewKeeper(marshaler, bsKey, getSubspace(paramsKeeper, bstypes.DefaultParamspace), &stakingKeeper) - testBlobStreamParams := bstypes.DefaultGenesis().Params - k.SetParams(ctx, *testBlobStreamParams) + testBlobstreamParams := bstypes.DefaultGenesis().Params + k.SetParams(ctx, *testBlobstreamParams) stakingKeeper = *stakingKeeper.SetHooks( stakingtypes.NewMultiStakingHooks( @@ -305,7 +305,7 @@ func CreateTestEnvWithoutBlobStreamKeysInit(t *testing.T) TestInput { ), ) return TestInput{ - BStreamKeeper: *k, + BstreamKeeper: *k, AccountKeeper: accountKeeper, BankKeeper: bankKeeper, StakingKeeper: stakingKeeper, @@ -317,11 +317,11 @@ func CreateTestEnvWithoutBlobStreamKeysInit(t *testing.T) TestInput { } } -// CreateTestEnv creates the keeper testing environment for BlobStream +// CreateTestEnv creates the keeper testing environment for Blobstream func CreateTestEnv(t *testing.T) TestInput { - input := CreateTestEnvWithoutBlobStreamKeysInit(t) - input.BStreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) - input.BStreamKeeper.SetEarliestAvailableAttestationNonce(input.Context, blobstream.InitialEarliestAvailableAttestationNonce) + input := CreateTestEnvWithoutBlobstreamKeysInit(t) + input.BstreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) + input.BstreamKeeper.SetEarliestAvailableAttestationNonce(input.Context, blobstream.InitialEarliestAvailableAttestationNonce) return input } @@ -412,7 +412,7 @@ func RegisterEVMAddress( valAddr sdk.ValAddress, evmAddr gethcommon.Address, ) { - bsMsgServer := keeper.NewMsgServerImpl(input.BStreamKeeper) + bsMsgServer := keeper.NewMsgServerImpl(input.BstreamKeeper) registerMsg := bstypes.NewMsgRegisterEVMAddress(valAddr, evmAddr) _, err := bsMsgServer.RegisterEVMAddress(input.Context, registerMsg) require.NoError(t, err) @@ -451,7 +451,7 @@ func SetupTestChain(t *testing.T, weights []uint64) (TestInput, sdk.Context) { // Initialize each of the validators stakingMsgServer := stakingkeeper.NewMsgServerImpl(input.StakingKeeper) - bsMsgServer := keeper.NewMsgServerImpl(input.BStreamKeeper) + bsMsgServer := keeper.NewMsgServerImpl(input.BstreamKeeper) for i, weight := range weights { consPrivKey := ed25519.GenPrivKey() consPubKey := consPrivKey.PubKey() @@ -504,10 +504,10 @@ func NewTestMsgUnDelegateValidator(address sdk.ValAddress, amt cosmosmath.Int) * return msg } -// ExecuteBlobStreamHeights executes the end exclusive range of heights specified by beginHeight and endHeight -// along with the BlobStream abci.EndBlocker on each one of them. +// ExecuteBlobstreamHeights executes the end exclusive range of heights specified by beginHeight and endHeight +// along with the Blobstream abci.EndBlocker on each one of them. // Returns the updated context with block height advanced to endHeight. -func ExecuteBlobStreamHeights(ctx sdk.Context, bsKeeper keeper.Keeper, beginHeight int64, endHeight int64) sdk.Context { +func ExecuteBlobstreamHeights(ctx sdk.Context, bsKeeper keeper.Keeper, beginHeight int64, endHeight int64) sdk.Context { for i := beginHeight; i < endHeight; i++ { ctx = ctx.WithBlockHeight(i) blobstream.EndBlocker(ctx, bsKeeper) @@ -515,10 +515,10 @@ func ExecuteBlobStreamHeights(ctx sdk.Context, bsKeeper keeper.Keeper, beginHeig return ctx } -// ExecuteBlobStreamHeightsWithTime executes the end exclusive range of heights specified by beginHeight and endHeight -// along with the BlobStream abci.EndBlocker on each one of them. +// ExecuteBlobstreamHeightsWithTime executes the end exclusive range of heights specified by beginHeight and endHeight +// along with the Blobstream abci.EndBlocker on each one of them. // Uses the interval to calculate the block header time. -func ExecuteBlobStreamHeightsWithTime(ctx sdk.Context, bsKeeper keeper.Keeper, beginHeight int64, endHeight int64, blockInterval time.Duration) sdk.Context { +func ExecuteBlobstreamHeightsWithTime(ctx sdk.Context, bsKeeper keeper.Keeper, beginHeight int64, endHeight int64, blockInterval time.Duration) sdk.Context { blockTime := ctx.BlockTime() for i := beginHeight; i < endHeight; i++ { ctx = ctx.WithBlockHeight(i).WithBlockTime(blockTime) diff --git a/x/blobstream/README.md b/x/blobstream/README.md index 89511ec587..f040e3a0ba 100644 --- a/x/blobstream/README.md +++ b/x/blobstream/README.md @@ -2,9 +2,9 @@ ## Concepts -This module contains the [BlobStream](https://blog.celestia.org/celestiums/) state machine implementation. +This module contains the [Blobstream](https://blog.celestia.org/celestiums/) state machine implementation. -The BlobStream state machine is responsible for creating attestations which are signed by [orchestrators](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md), and submitted to EVM chains by [relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md). +The Blobstream state machine is responsible for creating attestations which are signed by [orchestrators](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md), and submitted to EVM chains by [relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md). ### Attestations types @@ -16,7 +16,7 @@ There are two types of attestations, [valsets](https://github.com/celestiaorg/ce A valset is an attestation type representing a validator set change. It allows for the validator set to change over heights which in turn defines which orchestrator should sign the attestations. -When an orchestrator sees a newly generated valset published by the Celestia state machine, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new valset and submits that signature to the [BlobStream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. +When an orchestrator sees a newly generated valset published by the Celestia state machine, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new valset and submits that signature to the [Blobstream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. A valset is comprised of the following fields: @@ -51,16 +51,16 @@ message BridgeValidator { } ``` -1. `nonce`: is the universal nonce of the attestation. It is used to prevent front running attacks in the BlobStream smart contract. More details can be found in [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md). +1. `nonce`: is the universal nonce of the attestation. It is used to prevent front running attacks in the Blobstream smart contract. More details can be found in [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md). 2. `members`: contains the current validator set. 3. `height`: is the height at which the valset was created. 4. `time`: is the timestamp of the height at which the valset was created. #### Validator power normalization -The [BlobStream bridge power](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/proto/celestia/qgb/v1/types.proto#L12-L13) is obtained by [normalizing](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/x/qgb/keeper/keeper_valset.go#L125-L150) the validators' voting power using the [min-max normalization](https://en.wikipedia.org/wiki/Feature_scaling) formula. This formula takes into account the ratio of each validator's voting power to the total voting power in the block and scales it to a value between `0` and `2^32`. +The [Blobstream bridge power](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/proto/celestia/qgb/v1/types.proto#L12-L13) is obtained by [normalizing](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/x/qgb/keeper/keeper_valset.go#L125-L150) the validators' voting power using the [min-max normalization](https://en.wikipedia.org/wiki/Feature_scaling) formula. This formula takes into account the ratio of each validator's voting power to the total voting power in the block and scales it to a value between `0` and `2^32`. -By normalizing the voting power, we can significantly reduce the frequency of generating new validator set updates. For example, if there is a small increase in the total on-chain voting power due to inflation, there is no need to create a new validator set. This is because the relative proportions of the validators remain the same, and the normalized BlobStream power doesn't show any significant difference. +By normalizing the voting power, we can significantly reduce the frequency of generating new validator set updates. For example, if there is a small increase in the total on-chain voting power due to inflation, there is no need to create a new validator set. This is because the relative proportions of the validators remain the same, and the normalized Blobstream power doesn't show any significant difference. To ensure that the normalization process doesn't encounter overflow errors, the function normalizeValidatorPower uses [`BigInt`](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/x/qgb/keeper/keeper_valset.go#LL142C1-L142C1) operations. It scales the raw power value with respect to the total validator power, making sure the result falls within the range of 0 to `2^32`. @@ -68,13 +68,13 @@ This mechanism allows to increase/decrease the frequency at which validator set #### Power diff -[`PowerDiff(...)`](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/x/qgb/types/validator.go#L100-L141) is a function that calculates the difference in power between two sets of bridge validators. It's important to note that the power being compared is not the regular voting power in the Celestia consensus network, but a specific type called BlobStream bridge power (explained above). +[`PowerDiff(...)`](https://github.com/celestiaorg/celestia-app/blob/6243f26fc419c32940d5dc4eb60b0e0aaf08eaa7/x/qgb/types/validator.go#L100-L141) is a function that calculates the difference in power between two sets of bridge validators. It's important to note that the power being compared is not the regular voting power in the Celestia consensus network, but a specific type called Blobstream bridge power (explained above). ### Data commitments -A data commitment is an attestation type representing a request to commit over a set of blocks. It provides an end exclusive range of blocks for orchestrators to sign over and propagate in the BlobStream P2P network. The range is defined by the param [`DataCommitmentWindow`](https://github.com/celestiaorg/celestia-app/blob/fc83b04c3a5638ac8d415770e38a4046b84fa128/x/qgb/keeper/keeper_data_commitment.go#L44-L50), more on this below. +A data commitment is an attestation type representing a request to commit over a set of blocks. It provides an end exclusive range of blocks for orchestrators to sign over and propagate in the Blobstream P2P network. The range is defined by the param [`DataCommitmentWindow`](https://github.com/celestiaorg/celestia-app/blob/fc83b04c3a5638ac8d415770e38a4046b84fa128/x/qgb/keeper/keeper_data_commitment.go#L44-L50), more on this below. -When an orchestrator sees a newly generated data commitment, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new data commitment and submits that signature to the [BlobStream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. +When an orchestrator sees a newly generated data commitment, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new data commitment and submits that signature to the [Blobstream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. A data commitment is comprised of the following fields: @@ -102,7 +102,7 @@ message DataCommitment { } ``` -1. `nonce`: is the universal nonce of the attestation. It is used to prevent front running attacks in the BlobStream smart contract. More details can be found in [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md). +1. `nonce`: is the universal nonce of the attestation. It is used to prevent front running attacks in the Blobstream smart contract. More details can be found in [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md). 2. `begin_block`: the data commitment range first block. 3. `end_block`: the data commitment range last block. The range is end exclusive. Thus, the commitment will be over the set of blocks defined by `[begin_block, end_block)`. 4. `time`: is the timestamp of the height at which the data commitment was created. @@ -132,7 +132,7 @@ struct DataRootTuple { 2. `dataRoot`: the data root, aka data hash, of the block. 3. `squareSize`: the [square](https://celestiaorg.github.io/celestia-app/specs/data_structures.html#arranging-available-data-into-shares) size of the block. -These commitments are queried by orchestrators from [Celestia-core](https://github.com/celestiaorg/celestia-core/blob/d280f37a8376ed54ae03b10896fa25a4cbbc6d5b/rpc/core/blocks.go#L178-L195), signed, then submitted to the BlobStream P2P network as described [here](https://github.com/celestiaorg/orchestrator-relayer/blob/35b5df94c1602eb5e93a32d1bc6e5c8a4b5861e5/orchestrator/orchestrator.go#L331-L357). +These commitments are queried by orchestrators from [Celestia-core](https://github.com/celestiaorg/celestia-core/blob/d280f37a8376ed54ae03b10896fa25a4cbbc6d5b/rpc/core/blocks.go#L178-L195), signed, then submitted to the Blobstream P2P network as described [here](https://github.com/celestiaorg/orchestrator-relayer/blob/35b5df94c1602eb5e93a32d1bc6e5c8a4b5861e5/orchestrator/orchestrator.go#L331-L357). ## State @@ -147,13 +147,13 @@ Both types of attestations are set using the [`SetAttestationRequest(...)`](http ### Latest attestation nonce -The latest attestation nonce represents the most recently generated nonce in the BlobStream state machine store. It is [initialized to 0](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/genesis.go#L12) in genesis, and gets incremented at block 1. +The latest attestation nonce represents the most recently generated nonce in the Blobstream state machine store. It is [initialized to 0](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/genesis.go#L12) in genesis, and gets incremented at block 1. | Name | Key | |------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| | LatestAttestationNonce | [`[LatestAttestationNonce]`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/types/keys.go#L32-L33) | -The latest attestation nonce can be set to the BlobStream state machine store using the [`SetLatestAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/keeper/keeper_attestation.go#L44-L57) method and retrieved using the [`GetLatestAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/keeper/keeper_attestation.go#L67-L79). +The latest attestation nonce can be set to the Blobstream state machine store using the [`SetLatestAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/keeper/keeper_attestation.go#L44-L57) method and retrieved using the [`GetLatestAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/keeper/keeper_attestation.go#L67-L79). To check if the latest attestation nonce is defined in store, use the [`CheckLatestAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/x/qgb/keeper/keeper_attestation.go#L59-L65) method. @@ -166,17 +166,17 @@ The latest unbonding height indicates the most recent height at which some valid |------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| | LatestUnBondingBlockHeight | [`[LatestUnBondingBlockHeight]`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/types/keys.go#L28-L30) | -The latest unbonding height can be set to the BlobStream state machine store using the [`SetLatestUnBondingBlockHeight(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_valset.go#L58-L64) method, and it is called in a `hook` when a validator starts unbonding. More details on hooks are below. +The latest unbonding height can be set to the Blobstream state machine store using the [`SetLatestUnBondingBlockHeight(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_valset.go#L58-L64) method, and it is called in a `hook` when a validator starts unbonding. More details on hooks are below. ### Earliest attestation nonce -The earliest attestation nonce corresponds to the nonce of the earliest generated attestation in the BlobStream state machine store. It is [initialized to 1](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/genesis.go#L13-L17) in genesis, and gets incremented updated when [pruning](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/abci.go#L184-L185). +The earliest attestation nonce corresponds to the nonce of the earliest generated attestation in the Blobstream state machine store. It is [initialized to 1](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/genesis.go#L13-L17) in genesis, and gets incremented updated when [pruning](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/abci.go#L184-L185). | Name | Key | |------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| | EarliestAvailableAttestationNonce | [`[EarliestAvailableAttestationNonce]`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/types/keys.go#L35-L37) | -The earliest attestation nonce can be set to the BlobStream state machine store using the [`SetEarliestAvailableAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_attestation.go#L104-L110) method, and retrieved using the [`GetEarliestAvailableAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_attestation.go#L89-L102). +The earliest attestation nonce can be set to the Blobstream state machine store using the [`SetEarliestAvailableAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_attestation.go#L104-L110) method, and retrieved using the [`GetEarliestAvailableAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_attestation.go#L89-L102). To check if the earliest attestation nonce is defined in store, use the [`CheckEarliestAvailableAttestationNonce(...)`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/keeper/keeper_attestation.go#L81-L87) method. @@ -216,13 +216,13 @@ After a range update, the [`handler`](https://github.com/celestiaorg/celestia-ap ### Pruning -The third action done during the BlobStream [`EndBlock`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/abci.go#L28-L35) step is pruning. +The third action done during the Blobstream [`EndBlock`](https://github.com/celestiaorg/celestia-app/blob/9bf0cf1dd9ce31a3fecb51310c3913820b21a8c2/x/qgb/abci.go#L28-L35) step is pruning. -The BlobStream state machine prunes old attestations up to the specified [`AttestationExpiryTime`](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L22-L25), which is currently set to 3 weeks, matching the consensus unbonding time. +The Blobstream state machine prunes old attestations up to the specified [`AttestationExpiryTime`](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L22-L25), which is currently set to 3 weeks, matching the consensus unbonding time. So, on every block height, the state machine [checks](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L140-L157) whether there are any [`expired`](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L22-L25) attestations. Then, it starts [pruning](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L161-L182) via calling the [`DeleteAttestation(...)`](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/keeper/keeper_attestation.go#L128-L139) method. Then, it [`prints`](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L186-L194) a log message specifying the number of pruned attestations. -If the all the attestations in store are expired, which is an edge case that should never occur, the BlobStream state machine [doesn't prune](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L161) the latest attestation. +If the all the attestations in store are expired, which is an edge case that should never occur, the Blobstream state machine [doesn't prune](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/abci.go#L161) the latest attestation. ### Hooks @@ -234,13 +234,13 @@ When a validator starts unbonding, a [hook](https://github.com/celestiaorg/celes ### New attestation event -After creating a new attestation, and adding it to the BlobStream store, an event is [emitted](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/keeper/keeper_attestation.go#L16-L22) containing its nonce. +After creating a new attestation, and adding it to the Blobstream store, an event is [emitted](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/keeper/keeper_attestation.go#L16-L22) containing its nonce. ## Client ### Query attestation command -The BlobStream query attestation command is part of the `celestia-appd` binary. It allows the user to query specific attestations by their corresponding nonce. +The Blobstream query attestation command is part of the `celestia-appd` binary. It allows the user to query specific attestations by their corresponding nonce. ```shell $ celestia-appd query blobstream attestation --help @@ -255,20 +255,20 @@ Aliases: ### Verification command -The BlobStream 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 BlobStream contract. +The Blobstream 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 Blobstream contract. ```shell $ 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 BlobStream contract +Verifies that a transaction hash, a range of shares, or a blob referenced by its transaction hash were committed to by the Blobstream 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 BlobStream contract. - shares Verifies that a range of shares has been committed to by the BlobStream contract - tx Verifies that a transaction hash, in hex format, has been committed to by the BlobStream contract + blob Verifies that a blob, referenced by its transaction hash, in hex format, has been committed to by the Blobstream contract. + shares Verifies that a range of shares has been committed to by the Blobstream contract + tx Verifies that a transaction hash, in hex format, has been committed to by the Blobstream contract Flags: -h, --help help for verify @@ -278,9 +278,9 @@ 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 BlobStream 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 BlobStream contract. -- `tx`: Takes a transaction hash, in hex format, and verifies that it has been committed to by the BlobStream contract. +- `blob`: Takes a transaction hash, in hex format, and verifies that the blob paid for by the transaction has been committed to by the Blobstream 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 Blobstream contract. +- `tx`: Takes a transaction hash, in hex format, and verifies that it has been committed to by the Blobstream contract. ## Params @@ -370,13 +370,13 @@ if k.CheckLatestAttestationNonce(ctx) && k.GetLatestAttestationNonce(ctx)+1 != n ### Hooks initialization panic -When initializing the BlobStream hooks, if the BlobStream store key is not setup correctly, the state machine will [panic](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/keeper/hooks.go#L14-L19): +When initializing the Blobstream hooks, if the Blobstream store key is not setup correctly, the state machine will [panic](https://github.com/celestiaorg/celestia-app/blob/0629c757ef35a24187a8d7a4c706c7cdc894c8b6/x/qgb/keeper/hooks.go#L14-L19): ```golang // if startup is mis-ordered in app.go this hook will halt the chain when // called. Keep this check to make such a mistake obvious if k.storeKey == nil { - panic("hooks initialized before BlobStreamKeeper") + panic("hooks initialized before BlobstreamKeeper") } ``` @@ -386,4 +386,4 @@ The smart contract implementation is in [quantum-gravity-bridge](https://github. The orchestrator and relayer implementations are in the [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer) repo. -BlobStream ADRs are in the [docs](https://github.com/celestiaorg/celestia-app/tree/main/docs/architecture). +Blobstream ADRs are in the [docs](https://github.com/celestiaorg/celestia-app/tree/main/docs/architecture). diff --git a/x/blobstream/abci.go b/x/blobstream/abci.go index e7c42a5d55..f537e19fd9 100644 --- a/x/blobstream/abci.go +++ b/x/blobstream/abci.go @@ -184,7 +184,7 @@ func pruneAttestations(ctx sdk.Context, k keeper.Keeper) { // some attestations were pruned and we need to update the state for it k.SetEarliestAvailableAttestationNonce(ctx, newEarliestAvailableNonce) ctx.Logger().Debug( - "pruned attestations from BlobStream store", + "pruned attestations from Blobstream store", "count", newEarliestAvailableNonce-earliestAttestation.GetNonce(), "new_earliest_available_nonce", diff --git a/x/blobstream/abci_test.go b/x/blobstream/abci_test.go index 9f7e0f8921..7d8c18010f 100644 --- a/x/blobstream/abci_test.go +++ b/x/blobstream/abci_test.go @@ -19,7 +19,7 @@ import ( func TestFirstAttestationIsValset(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - pk := input.BStreamKeeper + pk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) expectedTime := ctx.BlockTime() @@ -42,7 +42,7 @@ func TestFirstAttestationIsValset(t *testing.T) { func TestValsetCreationWhenValidatorUnbonds(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - pk := input.BStreamKeeper + pk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) // run abci methods after chain init @@ -68,7 +68,7 @@ func TestValsetCreationWhenValidatorUnbonds(t *testing.T) { func TestValsetCreationWhenEditingEVMAddr(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - pk := input.BStreamKeeper + pk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) @@ -81,7 +81,7 @@ func TestValsetCreationWhenEditingEVMAddr(t *testing.T) { require.Equal(t, uint64(1), currentAttestationNonce) ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) - msgServer := keeper.NewMsgServerImpl(input.BStreamKeeper) + msgServer := keeper.NewMsgServerImpl(input.BstreamKeeper) newEVMAddr := testfactory.RandomEVMAddress() registerMsg := types.NewMsgRegisterEVMAddress( @@ -99,7 +99,7 @@ func TestValsetCreationWhenEditingEVMAddr(t *testing.T) { func TestSetValset(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - pk := input.BStreamKeeper + pk := input.BstreamKeeper vs, err := pk.GetCurrentValset(ctx) require.Nil(t, err) @@ -111,7 +111,7 @@ func TestSetValset(t *testing.T) { func TestSetDataCommitment(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper ctx = ctx.WithBlockHeight(int64(qk.GetDataCommitmentWindowParam(ctx))) expectedTime := ctx.BlockTime() @@ -149,7 +149,7 @@ func TestSetDataCommitment(t *testing.T) { // table structure is to make it easy to understand the test flow. func TestGetDataCommitment(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper tests := []struct { name string @@ -224,7 +224,7 @@ func TestGetDataCommitment(t *testing.T) { func TestDataCommitmentCreation(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) @@ -248,7 +248,7 @@ func TestDataCommitmentCreation(t *testing.T) { func TestDataCommitmentRange(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) // run abci methods after chain init @@ -294,7 +294,7 @@ func TestDataCommitmentRange(t *testing.T) { func TestHasDataCommitmentInStore(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper // set the data commitment window qk.SetParams(ctx, types.Params{DataCommitmentWindow: 400}) require.Equal(t, uint64(400), qk.GetDataCommitmentWindowParam(ctx)) @@ -357,24 +357,24 @@ func TestHasDataCommitmentInStore(t *testing.T) { // end of the test, the data commitments cover all the needed ranges. func TestDataCommitmentCreationCatchup(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - qk := input.BStreamKeeper + qk := input.BstreamKeeper ctx = ctx.WithBlockHeight(1) // from height 1 to 1500 with a window of 400 qk.SetParams(ctx, types.Params{DataCommitmentWindow: 400}) - ctx = testutil.ExecuteBlobStreamHeights(ctx, qk, 1, 1501) + ctx = testutil.ExecuteBlobstreamHeights(ctx, qk, 1, 1501) // change window to 100 and execute up to 1920 qk.SetParams(ctx, types.Params{DataCommitmentWindow: 100}) - ctx = testutil.ExecuteBlobStreamHeights(ctx, qk, 1501, 1921) + ctx = testutil.ExecuteBlobstreamHeights(ctx, qk, 1501, 1921) // change window to 1000 and execute up to 3500 qk.SetParams(ctx, types.Params{DataCommitmentWindow: 1000}) - ctx = testutil.ExecuteBlobStreamHeights(ctx, qk, 1921, 3501) + ctx = testutil.ExecuteBlobstreamHeights(ctx, qk, 1921, 3501) // change window to 111 and execute up to 3800 qk.SetParams(ctx, types.Params{DataCommitmentWindow: 111}) - ctx = testutil.ExecuteBlobStreamHeights(ctx, qk, 3501, 3801) + ctx = testutil.ExecuteBlobstreamHeights(ctx, qk, 3501, 3801) // check if a data commitment was created hasDataCommitment, err := qk.HasDataCommitmentInStore(ctx) @@ -517,17 +517,17 @@ func TestDataCommitmentCreationCatchup(t *testing.T) { } // TestPruning tests the pruning mechanism by: 1. Generating a set of -// attestations 2. Running the BlobStream EndBlocker 3. Verifying that the expired +// attestations 2. Running the Blobstream EndBlocker 3. Verifying that the expired // attestations are pruned func TestPruning(t *testing.T) { input, ctx := testutil.SetupFiveValChain(t) - bsKeeper := input.BStreamKeeper + bsKeeper := input.BstreamKeeper // set the data commitment window window := uint64(101) bsKeeper.SetParams(ctx, types.Params{DataCommitmentWindow: window}) initialBlockTime := ctx.BlockTime() blockInterval := 10 * time.Minute - ctx = testutil.ExecuteBlobStreamHeightsWithTime(ctx, bsKeeper, 1, 1626, blockInterval) + ctx = testutil.ExecuteBlobstreamHeightsWithTime(ctx, bsKeeper, 1, 1626, blockInterval) // check that we created a number of attestations assert.Equal(t, uint64(17), bsKeeper.GetLatestAttestationNonce(ctx)) @@ -540,7 +540,7 @@ func TestPruning(t *testing.T) { } // continue executing heights - ctx = testutil.ExecuteBlobStreamHeightsWithTime(ctx, bsKeeper, 1626, 5000, blockInterval) + ctx = testutil.ExecuteBlobstreamHeightsWithTime(ctx, bsKeeper, 1626, 5000, blockInterval) earliestAttestationNonce := bsKeeper.GetEarliestAvailableAttestationNonce(ctx) assert.Equal(t, uint64(21), earliestAttestationNonce) @@ -577,5 +577,5 @@ func TestPruning(t *testing.T) { // continue running the chain for a few more blocks to be sure no // inconsistency happens after pruning - testutil.ExecuteBlobStreamHeightsWithTime(ctx, bsKeeper, 5000, 6000, blockInterval) + testutil.ExecuteBlobstreamHeightsWithTime(ctx, bsKeeper, 5000, 6000, blockInterval) } diff --git a/x/blobstream/client/config.go b/x/blobstream/client/config.go index 0f67258d7b..c5b9c088b5 100644 --- a/x/blobstream/client/config.go +++ b/x/blobstream/client/config.go @@ -21,7 +21,7 @@ func addVerifyFlags(cmd *cobra.Command) *cobra.Command { cmd.Flags().Uint64P(evmChainIDFlag, "z", 5, "The EVM chain ID") cmd.Flags().StringP(flags.FlagNode, "t", "http://localhost:26657", ": to Tendermint RPC interface for this chain") cmd.Flags().StringP(evmRPCFlag, "e", "http://localhost:8545", "The EVM RPC address") - cmd.Flags().StringP(contractAddressFlag, "a", "", "The contract address at which the BlobStream is deployed") + cmd.Flags().StringP(contractAddressFlag, "a", "", "The contract address at which Blobstream is deployed") cmd.Flags().StringP(celesGRPCFlag, "c", "localhost:9090", ": To Celestia GRPC address") return cmd diff --git a/x/blobstream/client/query.go b/x/blobstream/client/query.go index 95ab18c81f..9e696f3eb6 100644 --- a/x/blobstream/client/query.go +++ b/x/blobstream/client/query.go @@ -15,7 +15,7 @@ import ( // GetQueryCmd returns the CLI query commands for this module func GetQueryCmd() *cobra.Command { - // Group BlobStream queries under a subcommand + // Group Blobstream queries under a subcommand cmd := &cobra.Command{ Use: types.ModuleName, Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), @@ -115,7 +115,7 @@ func unmarshallAttestation(attestation *codectypes.Any) (types.AttestationReques return unmarshalledAttestation, nil } -// makeInterfaceRegistry creates the interface registry containing the BlobStream interfaces +// makeInterfaceRegistry creates the interface registry containing the Blobstream interfaces func makeInterfaceRegistry() codectypes.InterfaceRegistry { // create the codec interfaceRegistry := codectypes.NewInterfaceRegistry() diff --git a/x/blobstream/client/suite_test.go b/x/blobstream/client/suite_test.go index 4ab7f4f24f..327a2ce440 100644 --- a/x/blobstream/client/suite_test.go +++ b/x/blobstream/client/suite_test.go @@ -20,9 +20,9 @@ type CLITestSuite struct { func (s *CLITestSuite) SetupSuite() { if testing.Short() { - s.T().Skip("skipping BlobStream CLI tests in short mode.") + s.T().Skip("skipping Blobstream CLI tests in short mode.") } - s.T().Log("setting up BlobStream CLI test suite") + s.T().Log("setting up Blobstream CLI test suite") cfg := network.DefaultConfig() cfg.EnableTMLogging = false @@ -46,10 +46,10 @@ func (s *CLITestSuite) SetupSuite() { } func (s *CLITestSuite) TearDownSuite() { - s.T().Log("tearing down BlobStream CLI test suite") + s.T().Log("tearing down Blobstream CLI test suite") s.network.Cleanup() } -func TestBlobStreamCLI(t *testing.T) { +func TestBlobstreamCLI(t *testing.T) { suite.Run(t, new(CLITestSuite)) } diff --git a/x/blobstream/client/tx.go b/x/blobstream/client/tx.go index 38672cd85c..45309fe689 100644 --- a/x/blobstream/client/tx.go +++ b/x/blobstream/client/tx.go @@ -30,7 +30,7 @@ func CmdRegisterEVMAddress() *cobra.Command { Use: "register [valAddress] [evmAddress]", Short: "Register an EVM address for a validator", Long: `Registers an EVM address for a validator. This address will be used to -sign attestations as part of the BlobStream protocol. Only the validator, as the signer, +sign attestations as part of Blobstream protocol. Only the validator, as the signer, can register an EVM address. To change the EVM address, the validator can simply send a new message overriding the previous one. `, diff --git a/x/blobstream/client/verify.go b/x/blobstream/client/verify.go index 42f845c565..9baa9b4d19 100644 --- a/x/blobstream/client/verify.go +++ b/x/blobstream/client/verify.go @@ -24,7 +24,7 @@ import ( func VerifyCmd() *cobra.Command { command := &cobra.Command{ Use: "verify", - Short: "Verifies that a transaction hash, a range of shares, or a blob referenced by its transaction hash were committed to by the BlobStream contract", + Short: "Verifies that a transaction hash, a range of shares, or a blob referenced by its transaction hash were committed to by the Blobstream contract", } command.AddCommand( txCmd(), @@ -38,7 +38,7 @@ func txCmd() *cobra.Command { command := &cobra.Command{ Use: "tx ", Args: cobra.ExactArgs(1), - Short: "Verifies that a transaction hash, in hex format, has been committed to by the BlobStream contract", + Short: "Verifies that a transaction hash, in hex format, has been committed to by the Blobstream contract", RunE: func(cmd *cobra.Command, args []string) error { txHash, err := hex.DecodeString(args[0]) if err != nil { @@ -72,7 +72,7 @@ func txCmd() *cobra.Command { return err } - logger.Info("verifying that the transaction was committed to by the BlobStream", "tx_hash", args[0], "height", tx.Height) + logger.Info("verifying that the transaction was committed to by the Blobstream", "tx_hash", args[0], "height", tx.Height) blockRes, err := trpc.Block(cmd.Context(), &tx.Height) if err != nil { @@ -95,7 +95,7 @@ func blobCmd() *cobra.Command { command := &cobra.Command{ Use: "blob ", Args: cobra.ExactArgs(2), - Short: "Verifies that a blob, referenced by its transaction hash, in hex format, has been committed to by the BlobStream contract", + Short: "Verifies that a blob, referenced by its transaction hash, in hex format, has been committed to by the Blobstream contract", RunE: func(cmd *cobra.Command, args []string) error { txHash, err := hex.DecodeString(args[0]) if err != nil { @@ -134,7 +134,7 @@ func blobCmd() *cobra.Command { return err } - logger.Info("verifying that the blob was committed to by the BlobStream", "tx_hash", args[0], "height", tx.Height) + logger.Info("verifying that the blob was committed to by the Blobstream", "tx_hash", args[0], "height", tx.Height) blockRes, err := trpc.Block(cmd.Context(), &tx.Height) if err != nil { @@ -157,7 +157,7 @@ func sharesCmd() *cobra.Command { command := &cobra.Command{ Use: "shares ", Args: cobra.ExactArgs(3), - Short: "Verifies that a range of shares has been committed to by the BlobStream contract. The range should be end exclusive.", + Short: "Verifies that a range of shares has been committed to by the Blobstream contract. The range should be end exclusive.", RunE: func(cmd *cobra.Command, args []string) error { height, err := strconv.ParseUint(args[0], 10, 0) if err != nil { @@ -251,7 +251,7 @@ func VerifyShares(ctx context.Context, logger tmlog.Logger, config VerifyConfig, } logger.Info( - "proving that the data root was committed to in the BlobStream contract", + "proving that the data root was committed to in the Blobstream contract", "contract_address", config.ContractAddr, "fist_block", @@ -285,7 +285,7 @@ func VerifyShares(ctx context.Context, logger tmlog.Logger, config VerifyConfig, return false, err } - logger.Info("verifying that the data root was committed to in the BlobStream contract") + logger.Info("verifying that the data root was committed to in the Blobstream contract") isCommittedTo, err = VerifyDataRootInclusion( ctx, bsWrapper, @@ -299,9 +299,9 @@ func VerifyShares(ctx context.Context, logger tmlog.Logger, config VerifyConfig, } if isCommittedTo { - logger.Info("the BlobStream contract has committed to the provided shares") + logger.Info("the Blobstream contract has committed to the provided shares") } else { - logger.Info("the BlobStream contract didn't commit to the provided shares") + logger.Info("the Blobstream contract didn't commit to the provided shares") } return isCommittedTo, nil diff --git a/x/blobstream/integration_test.go b/x/blobstream/integration_test.go index 97117b3171..398999c676 100644 --- a/x/blobstream/integration_test.go +++ b/x/blobstream/integration_test.go @@ -18,14 +18,14 @@ import ( abci "github.com/tendermint/tendermint/abci/types" ) -func TestBlobStreamIntegrationSuite(t *testing.T) { +func TestBlobstreamIntegrationSuite(t *testing.T) { if testing.Short() { t.Skip("skipping blob stream integration test in short mode.") } - suite.Run(t, new(BlobStreamIntegrationSuite)) + suite.Run(t, new(BlobstreamIntegrationSuite)) } -type BlobStreamIntegrationSuite struct { +type BlobstreamIntegrationSuite struct { suite.Suite accounts []string @@ -33,7 +33,7 @@ type BlobStreamIntegrationSuite struct { ecfg encoding.Config } -func (s *BlobStreamIntegrationSuite) SetupSuite() { +func (s *BlobstreamIntegrationSuite) SetupSuite() { t := s.T() t.Log("setting up integration test suite") @@ -45,7 +45,7 @@ func (s *BlobStreamIntegrationSuite) SetupSuite() { s.cctx = cctx } -func (s *BlobStreamIntegrationSuite) TestBlobStream() { +func (s *BlobstreamIntegrationSuite) TestBlobstream() { t := s.T() type test struct { name string diff --git a/x/blobstream/keeper/hooks.go b/x/blobstream/keeper/hooks.go index 5e9199d5bc..2bd1776c7a 100644 --- a/x/blobstream/keeper/hooks.go +++ b/x/blobstream/keeper/hooks.go @@ -11,12 +11,12 @@ type Hooks struct { k Keeper } -// Create new BlobStream hooks +// Hooks Create new Blobstream hooks func (k Keeper) Hooks() Hooks { // if startup is mis-ordered in app.go this hook will halt the chain when // called. Keep this check to make such a mistake obvious if k.storeKey == nil { - panic("hooks initialized before BlobStreamKeeper") + panic("hooks initialized before BlobstreamKeeper") } return Hooks{k} } diff --git a/x/blobstream/keeper/keeper.go b/x/blobstream/keeper/keeper.go index 2de1bb8fa2..e87f1398fb 100644 --- a/x/blobstream/keeper/keeper.go +++ b/x/blobstream/keeper/keeper.go @@ -47,7 +47,7 @@ func (k Keeper) SetParams(ctx sdk.Context, ps types.Params) { } // DeserializeValidatorIterator returns validators from the validator iterator. -// Adding here in BlobStream keeper as cdc is not available inside endblocker. +// Adding here in Blobstream keeper as cdc is not available inside endblocker. func (k Keeper) DeserializeValidatorIterator(vals []byte) stakingtypes.ValAddresses { validators := stakingtypes.ValAddresses{ Addresses: []string{}, @@ -56,7 +56,7 @@ func (k Keeper) DeserializeValidatorIterator(vals []byte) stakingtypes.ValAddres return validators } -// StakingKeeper restricts the functionality of the bank keeper used in the BlobStream +// StakingKeeper restricts the functionality of the bank keeper used in the Blobstream // keeper type StakingKeeper interface { GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) diff --git a/x/blobstream/keeper/keeper_attestation_test.go b/x/blobstream/keeper/keeper_attestation_test.go index dccd02038a..3dcaed4e26 100644 --- a/x/blobstream/keeper/keeper_attestation_test.go +++ b/x/blobstream/keeper/keeper_attestation_test.go @@ -9,33 +9,33 @@ import ( ) func TestCheckLatestAttestationNonce(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper // check if the latest attestation nonce is init exists := k.CheckLatestAttestationNonce(input.Context) assert.False(t, exists) // init the latest attestation nonce - input.BStreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) + input.BstreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) // check if the latest attestation nonce value was initialized correctly - input.BStreamKeeper.CheckLatestAttestationNonce(input.Context) - assert.Equal(t, blobstream.InitialLatestAttestationNonce, input.BStreamKeeper.GetLatestAttestationNonce(input.Context)) + input.BstreamKeeper.CheckLatestAttestationNonce(input.Context) + assert.Equal(t, blobstream.InitialLatestAttestationNonce, input.BstreamKeeper.GetLatestAttestationNonce(input.Context)) } func TestCheckEarliestAvailableAttestationNonce(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper // check if the earliest available attestation nonce is init exists := k.CheckEarliestAvailableAttestationNonce(input.Context) assert.False(t, exists) // init the earliest available attestation nonce - input.BStreamKeeper.SetEarliestAvailableAttestationNonce(input.Context, blobstream.InitialEarliestAvailableAttestationNonce) + input.BstreamKeeper.SetEarliestAvailableAttestationNonce(input.Context, blobstream.InitialEarliestAvailableAttestationNonce) // check if the earliest attestation nonce value was initialized correctly - input.BStreamKeeper.CheckEarliestAvailableAttestationNonce(input.Context) - assert.Equal(t, blobstream.InitialEarliestAvailableAttestationNonce, input.BStreamKeeper.GetEarliestAvailableAttestationNonce(input.Context)) + input.BstreamKeeper.CheckEarliestAvailableAttestationNonce(input.Context) + assert.Equal(t, blobstream.InitialEarliestAvailableAttestationNonce, input.BstreamKeeper.GetEarliestAvailableAttestationNonce(input.Context)) } diff --git a/x/blobstream/keeper/keeper_data_commitment_test.go b/x/blobstream/keeper/keeper_data_commitment_test.go index cb246b6e73..9b811121e2 100644 --- a/x/blobstream/keeper/keeper_data_commitment_test.go +++ b/x/blobstream/keeper/keeper_data_commitment_test.go @@ -13,7 +13,7 @@ import ( func TestGetDataCommitmentForHeight(t *testing.T) { input, sdkCtx := testutil.SetupFiveValChain(t) - k := input.BStreamKeeper + k := input.BstreamKeeper initialValset, err := k.GetCurrentValset(sdkCtx) require.NoError(t, err) @@ -111,7 +111,7 @@ func TestGetDataCommitmentForHeight(t *testing.T) { func TestLatestDataCommitment(t *testing.T) { input, sdkCtx := testutil.SetupFiveValChain(t) - k := input.BStreamKeeper + k := input.BstreamKeeper initialValset, err := k.GetCurrentValset(sdkCtx) require.NoError(t, err) @@ -148,8 +148,8 @@ func TestLatestDataCommitment(t *testing.T) { } func TestCheckingLatestAttestationNonceInDataCommitments(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper tests := []struct { name string @@ -190,11 +190,11 @@ func TestCheckingLatestAttestationNonceInDataCommitments(t *testing.T) { } func TestCheckingEarliestAvailableAttestationNonceInDataCommitments(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper // init the latest attestation nonce - input.BStreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) + input.BstreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) tests := []struct { name string diff --git a/x/blobstream/keeper/keeper_valset_test.go b/x/blobstream/keeper/keeper_valset_test.go index 0d7cd773b1..53c235360e 100644 --- a/x/blobstream/keeper/keeper_valset_test.go +++ b/x/blobstream/keeper/keeper_valset_test.go @@ -60,7 +60,7 @@ func TestCurrentValsetNormalization(t *testing.T) { spec := spec t.Run(msg, func(t *testing.T) { input, ctx := testutil.SetupTestChain(t, spec.srcPowers) - r, err := input.BStreamKeeper.GetCurrentValset(ctx) + r, err := input.BstreamKeeper.GetCurrentValset(ctx) require.NoError(t, err) rMembers, err := types.BridgeValidators(r.Members).ToInternal() require.NoError(t, err) @@ -70,8 +70,8 @@ func TestCurrentValsetNormalization(t *testing.T) { } func TestCheckingEarliestAvailableAttestationNonceInValsets(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper // create a validator to have a realistic scenario testutil.CreateValidator( t, @@ -87,7 +87,7 @@ func TestCheckingEarliestAvailableAttestationNonceInValsets(t *testing.T) { staking.EndBlocker(input.Context, input.StakingKeeper) // init the latest attestation nonce - input.BStreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) + input.BstreamKeeper.SetLatestAttestationNonce(input.Context, blobstream.InitialLatestAttestationNonce) tests := []struct { name string @@ -120,8 +120,8 @@ func TestCheckingEarliestAvailableAttestationNonceInValsets(t *testing.T) { } func TestCheckingAttestationNonceInValsets(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper // create a validator to have a realistic scenario testutil.CreateValidator( t, @@ -174,8 +174,8 @@ func TestCheckingAttestationNonceInValsets(t *testing.T) { } func TestEVMAddresses(t *testing.T) { - input := testutil.CreateTestEnvWithoutBlobStreamKeysInit(t) - k := input.BStreamKeeper + input := testutil.CreateTestEnvWithoutBlobstreamKeysInit(t) + k := input.BstreamKeeper _, exists := k.GetEVMAddress(input.Context, testutil.ValAddrs[0]) require.False(t, exists) diff --git a/x/blobstream/keeper/msg_server.go b/x/blobstream/keeper/msg_server.go index 7cdda965c7..a9ecab5253 100644 --- a/x/blobstream/keeper/msg_server.go +++ b/x/blobstream/keeper/msg_server.go @@ -16,7 +16,7 @@ type msgServer struct { Keeper } -// NewMsgServerImpl returns an implementation of the BlobStream MsgServer interface +// NewMsgServerImpl returns an implementation of the Blobstream MsgServer interface // for the provided Keeper. func NewMsgServerImpl(keeper Keeper) types.MsgServer { return &msgServer{Keeper: keeper} diff --git a/x/blobstream/keeper/msg_server_test.go b/x/blobstream/keeper/msg_server_test.go index dc25127e57..56fe7a2875 100644 --- a/x/blobstream/keeper/msg_server_test.go +++ b/x/blobstream/keeper/msg_server_test.go @@ -12,7 +12,7 @@ import ( func TestRegisterEVMAddress(t *testing.T) { input, sdkCtx := testutil.SetupFiveValChain(t) - k := input.BStreamKeeper + k := input.BstreamKeeper vals := input.StakingKeeper.GetValidators(sdkCtx, 100) require.GreaterOrEqual(t, len(vals), 1) val := vals[0] diff --git a/x/blobstream/overview.md b/x/blobstream/overview.md index 808d4233e4..4b8666a255 100644 --- a/x/blobstream/overview.md +++ b/x/blobstream/overview.md @@ -1,42 +1,42 @@ # Overview -BlobStream is a one way bridge from Celestia to EVM chains. It provides a way for rollups using Celestia for Data Availability (DA), and an EVM chain as a settlement layer, to prove on-chain that the rollup data was correctly posted to Celestia and verify fraud proofs otherwise. These types of rollups are discussed in the [Quantum Gravity Bridge: Secure Off-Chain Data Availability for Ethereum L2s with Celestia](https://blog.celestia.org/celestiums) blog post. +Blobstream is a one way bridge from Celestia to EVM chains. It provides a way for rollups using Celestia for Data Availability (DA), and an EVM chain as a settlement layer, to prove on-chain that the rollup data was correctly posted to Celestia and verify fraud proofs otherwise. These types of rollups are discussed in the [Quantum Gravity Bridge: Secure Off-Chain Data Availability for Ethereum L2s with Celestia](https://blog.celestia.org/celestiums) blog post. -BlobStream implementation consists of three components: The [state machine](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream), the [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer), and the [BlobStream smart contract](https://github.com/celestiaorg/blobstream-contracts). +Blobstream implementation consists of three components: The [state machine](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream), the [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer), and the [Blobstream smart contract](https://github.com/celestiaorg/blobstream-contracts). ## [State machine](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream) -The state machine is the `blobstream` module implementation. It is responsible for creating [attestations](https://github.com/celestiaorg/celestia-app/blob/main/x/blobstream/types/attestation.go#L10-L18) which are signed by [orchestrators](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md). Each Celestia validator is expected to also run an orchestrator. [Relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) periodically query the Celestia state for attestations and submit them to the BlobStream smart contract deployed on some EVM chain. +The state machine is the `blobstream` module implementation. It is responsible for creating [attestations](https://github.com/celestiaorg/celestia-app/blob/main/x/blobstream/types/attestation.go#L10-L18) which are signed by [orchestrators](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md). Each Celestia validator is expected to also run an orchestrator. [Relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) periodically query the Celestia state for attestations and submit them to the Blobstream smart contract deployed on some EVM chain. There are two types of [attestations](https://github.com/celestiaorg/celestia-app/blob/main/x/blobstream/types/attestation.go#L10-L18): [valsets](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/proto/celestia/qgb/v1/types.proto#L18-L33) and [data commitments](https://github.com/celestiaorg/celestia-app/blob/376a1d4c0f321f12ba78279d2bd34fc6cb5e6dc2/proto/celestia/qgb/v1/types.proto#L35-L55). -All attestations have a [`nonce`](https://github.com/celestiaorg/celestia-app/blob/8ae6a84b2c99e55625bbe99f70db1e5a985c9675/x/qgb/types/attestation.go#L16) field that defines the order in which the attestations are generated. This nonce is stored in the BlobStream smart contract as per [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md#decision), and is used to order attestation submissions on the EVM chain. +All attestations have a [`nonce`](https://github.com/celestiaorg/celestia-app/blob/8ae6a84b2c99e55625bbe99f70db1e5a985c9675/x/qgb/types/attestation.go#L16) field that defines the order in which the attestations are generated. This nonce is stored in the Blobstream smart contract as per [ADR-004](https://github.com/celestiaorg/celestia-app/blob/main/docs/architecture/adr-004-qgb-relayer-security.md#decision), and is used to order attestation submissions on the EVM chain. ### [Valsets](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#valsets) -A [valset](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#valsets) represents a validator set snapshot. It contains a list of validators' EVM addresses along with their [BlobStream staking power](https://github.com/celestiaorg/celestia-app/tree/main/x/qgb#validator-power-normalization). It enables the BlobStream smart contract to track the state of the Celestia validator set. This is necessary so that the BlobStream smart contract can determine when a 2/3 threshold has signed that a particular data hash has been made available on Celestia. +A [valset](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#valsets) represents a validator set snapshot. It contains a list of validators' EVM addresses along with their [Blobstream staking power](https://github.com/celestiaorg/celestia-app/tree/main/x/qgb#validator-power-normalization). It enables the Blobstream smart contract to track the state of the Celestia validator set. This is necessary so that the Blobstream smart contract can determine when a 2/3 threshold has signed that a particular data hash has been made available on Celestia. -A valset is [generated](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#valset-handler) inside the state machine. It is then queried, signed, and submitted to the [BlobStream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66) by orchestrators. After more than 2/3rds of the Celestia validator set have submitted their signatures, [relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) relay the attestation to the BlobStream smart contract along with the signatures to be [verified](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L172-L211) and eventually [stored](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L266-L268). +A valset is [generated](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#valset-handler) inside the state machine. It is then queried, signed, and submitted to the [Blobstream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66) by orchestrators. After more than 2/3rds of the Celestia validator set have submitted their signatures, [relayers](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) relay the attestation to the Blobstream smart contract along with the signatures to be [verified](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L172-L211) and eventually [stored](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L266-L268). -The BlobStream smart contract keeps track of the [last validator set hash](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L44-L45) and its corresponding [power threshold](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L46-L47). This way, the contract will always be able to verify if attestations were signed using the correct Celestia validator set, and if the provided signatures represent a majority. +The Blobstream smart contract keeps track of the [last validator set hash](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L44-L45) and its corresponding [power threshold](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L46-L47). This way, the contract will always be able to verify if attestations were signed using the correct Celestia validator set, and if the provided signatures represent a majority. ### [Data commitments](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#data-commitments) -A [data commitment](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#data-commitments) is an attestation type representing a request to commit over a set of blocks. It provides an end exclusive range of blocks for orchestrators to sign over and propagate in the BlobStream P2P network. The range is defined by the param [`DataCommitmentWindow`](https://github.com/celestiaorg/celestia-app/blob/fc83b04c3a5638ac8d415770e38a4046b84fa128/x/qgb/keeper/keeper_data_commitment.go#L44-L50). +A [data commitment](https://github.com/celestiaorg/celestia-app/tree/main/x/blobstream#data-commitments) is an attestation type representing a request to commit over a set of blocks. It provides an end exclusive range of blocks for orchestrators to sign over and propagate in the Blobstream P2P network. The range is defined by the param [`DataCommitmentWindow`](https://github.com/celestiaorg/celestia-app/blob/fc83b04c3a5638ac8d415770e38a4046b84fa128/x/qgb/keeper/keeper_data_commitment.go#L44-L50). The data commitment is a Merkle tree over a sequential set of blocks. These blocks are represented as a tuple of the [data root](https://github.com/celestiaorg/celestia-core/blob/6933af1ead0ddf4a8c7516690e3674c6cdfa7bd8/rpc/core/blocks.go#L549), and the [height](https://github.com/celestiaorg/celestia-core/blob/6933af1ead0ddf4a8c7516690e3674c6cdfa7bd8/rpc/core/blocks.go#L548). This commitment can be queried from core using the [`DataCommitment`](https://github.com/celestiaorg/celestia-core/blob/6933af1ead0ddf4a8c7516690e3674c6cdfa7bd8/rpc/core/blocks.go#L210-L227) query and allows generating Merkle inclusion proofs for any blob in any block in the set. -When an orchestrator sees a newly generated data commitment, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new data commitment and submits that signature to the [BlobStream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. +When an orchestrator sees a newly generated data commitment, it queries the previous valset and checks whether it's part of its validator set. Then, the orchestrator signs the new data commitment and submits that signature to the [Blobstream P2P network](https://github.com/celestiaorg/orchestrator-relayer/pull/66). Otherwise, it ignores it and waits for new attestations. -After the relayer finds more than 2/3rd signatures of that data commitment, it relays the commitment along with the signatures to the BlobStream smart contract where they get [verified](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L172-L211). Then, the smart contract [saves](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L331-L332) the commitment to the [state](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L50-L51) thus allowing for Merkle-based inclusion proof verification for any blob posted to any committed block. +After the relayer finds more than 2/3rd signatures of that data commitment, it relays the commitment along with the signatures to the Blobstream smart contract where they get [verified](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L172-L211). Then, the smart contract [saves](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L331-L332) the commitment to the [state](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L50-L51) thus allowing for Merkle-based inclusion proof verification for any blob posted to any committed block. ## [Orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer) -The [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer) contains the implementation of the BlobStream orchestrator and relayer. +The [orchestrator-relayer](https://github.com/celestiaorg/orchestrator-relayer) contains the implementation of the Blobstream orchestrator and relayer. ### [Orchestrator](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md) -An [orchestrator](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md) is the software responsible for querying the state machine for new attestations, signs them, and then submits them to the BlobStream P2P network. +An [orchestrator](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md) is the software responsible for querying the state machine for new attestations, signs them, and then submits them to the Blobstream P2P network. At startup, it [loads](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/orchestrator.md#evm-key) the EVM private key corresponding to the address used when creating the validator. Then, it uses it to sign the attestations digests before submitting them to the P2P network. @@ -46,31 +46,31 @@ The orchestrator generally needs access to the validator's RPC/gRPC endpoints. H ### [Relayer](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) -A [relayer](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) is the software responsible for querying the signatures of a validator set from the P2P network and aggregating them into a format that the [BlobStream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) understands. +A [relayer](https://github.com/celestiaorg/orchestrator-relayer/blob/main/docs/relayer.md) is the software responsible for querying the signatures of a validator set from the P2P network and aggregating them into a format that the [Blobstream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) understands. It uses the previous valset to that attestation to know which validators should sign. Then, it looks for all of those signatures. -When the relayer finds more than 2/3rds of the signatures, it immediately relays them to the BlobStream smart contract to be persisted, and starts again. +When the relayer finds more than 2/3rds of the signatures, it immediately relays them to the Blobstream smart contract to be persisted, and starts again. -For a [BlobStream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) to not halt, it needs at least one relayer relaying signatures to it regularly. Otherwise, the BlobStream contract will be out of sync and will not be able to commit to new data. +For a [Blobstream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) to not halt, it needs at least one relayer relaying signatures to it regularly. Otherwise, the Blobstream contract will be out of sync and will not be able to commit to new data. -## [BlobStream smart contract](https://github.com/celestiaorg/blobstream-contracts) +## [Blobstream smart contract](https://github.com/celestiaorg/blobstream-contracts) -The [BlobStream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) is the source of truth for the rollups using Celestia as DA. It allows proving/verifying that data was posted to the Celestia blockchain. +The [Blobstream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) is the source of truth for the rollups using Celestia as DA. It allows proving/verifying that data was posted to the Celestia blockchain. -In order to reflect the Celestia chain data, the [BlobStream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) keeps track of the validator set changes, via valset updates, and commits to batches of block information, via data commitments. +In order to reflect the Celestia chain data, the [Blobstream smart contract](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol) keeps track of the validator set changes, via valset updates, and commits to batches of block information, via data commitments. ### Validator set changes -In order to submit a validator set change, the BlobStream smart contract provides the [`updateValidatorSet()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L213-L273) `external` method that takes the previous valset nonce, the new one's nonce, its power threshold and its hash, along with the actual validator set and the corresponding signatures, as `calldata` to be verified. Then, it [persists](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L266-L268) the nonce, the valset hash and the threshold in state so they can be used for future valset and data commitment updates. +In order to submit a validator set change, the Blobstream smart contract provides the [`updateValidatorSet()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L213-L273) `external` method that takes the previous valset nonce, the new one's nonce, its power threshold and its hash, along with the actual validator set and the corresponding signatures, as `calldata` to be verified. Then, it [persists](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L266-L268) the nonce, the valset hash and the threshold in state so they can be used for future valset and data commitment updates. ### Batches -The batches in the BlobStream smart contract refer to the `data root tuple root`s described above. These are submitted using the [`submitDataRootTupleRoot()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L275-L337) `external` method. This latter takes the new batch nonce, its corresponding valset, the `data root tuple root`, along with the actual validator set and their corresponding signatures as `calldata`. Then, it verifies the signature and [persists](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L331-L332) the new data root tuple root to the state along with the new nonce. +The batches in the Blobstream smart contract refer to the `data root tuple root`s described above. These are submitted using the [`submitDataRootTupleRoot()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L275-L337) `external` method. This latter takes the new batch nonce, its corresponding valset, the `data root tuple root`, along with the actual validator set and their corresponding signatures as `calldata`. Then, it verifies the signature and [persists](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L331-L332) the new data root tuple root to the state along with the new nonce. ### Hashes format -The digest created/verified in the BlobStream smart contract follow the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) standard for hashing data. +The digest created/verified in the Blobstream smart contract follow the [EIP-712](https://eips.ethereum.org/EIPS/eip-712) standard for hashing data. #### Valset digest @@ -93,24 +93,24 @@ A data commitment digest is created inside the [`domainSeparateDataRootTupleRoot The signature scheme used for signing the above hashes follow the [EIP-191](https://eips.ethereum.org/EIPS/eip-191) signing standard. It uses the `ECDSA` algorithm with the `secp256k1` curve. So, the orchestrator uses the keystore to [generate](https://github.com/celestiaorg/orchestrator-relayer/blob/09ebfdc312c0d9e08856fb98cfd089e956ab7f3a/evm/ethereum_signature.go#L18-L28) these signatures. -The output signature is in the `[R || S || V]` format where `V` is `0` or `1`. This is defined in the BlobStream smart contract using the [Signature](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L17-L21) struct. +The output signature is in the `[R || S || V]` format where `V` is `0` or `1`. This is defined in the Blobstream smart contract using the [Signature](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L17-L21) struct. These signatures are then verified in the smart contract using the [`verifySig()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L124-L129) method. ## Security assumptions -The security of the BlobStream relies on an honest majority of the Celestia validator set. This assumption indicates that more than 2/3s of the voting power follows each [block validity rule](../../specs/src/specs/block_validity_rules.md). Additionally, over 2/3s of the voting power sign valid validator set updates and data commitments, as outlined above. +The security of the Blobstream relies on an honest majority of the Celestia validator set. This assumption indicates that more than 2/3s of the voting power follows each [block validity rule](../../specs/src/specs/block_validity_rules.md). Additionally, over 2/3s of the voting power sign valid validator set updates and data commitments, as outlined above. -If more than 1/3rd of the validator set stops running their orchestrators, then the BlobStream halts. And, if more than 2/3rds sign invalid data, then the BlobStream contract will commit to invalid data. The only recovery from such a state is to revert to social consensus, potentially slashing the guilty validators and redeploying the smart contracts. +If more than 1/3rd of the validator set stops running their orchestrators, then the Blobstream halts. And, if more than 2/3rds sign invalid data, then the Blobstream contract will commit to invalid data. The only recovery from such a state is to revert to social consensus, potentially slashing the guilty validators and redeploying the smart contracts. ## Slashing We still don't support slashing for equivocation, liveness or invalid signatures. However, if anything were to happen to the bridge, we would be able to social slash the corrupt validators and redeploy the contract. -Future versions of the BlobStream will support slashing. It will be enforced via the use of [vote extensions](https://github.com/cometbft/cometbft/blob/v0.38.0/spec/abci/abci%2B%2B_methods.md#extendvote). +Future versions of the Blobstream will support slashing. It will be enforced via the use of [vote extensions](https://github.com/cometbft/cometbft/blob/v0.38.0/spec/abci/abci%2B%2B_methods.md#extendvote). ## Proofs -To prove that data was posted to an EVM chain, we have the following method: [`verifyAttestation()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L339-L358). This allows to verify that a data root tuple was committed to by the BlobStream smart contract. +To prove that data was posted to an EVM chain, we have the following method: [`verifyAttestation()`](https://github.com/celestiaorg/quantum-gravity-bridge/blob/3cef3f5dfd37c3086fa40a6324f144595726dc16/src/QuantumGravityBridge.sol#L339-L358). This allows to verify that a data root tuple was committed to by the Blobstream smart contract. For the remaining proofs, i.e. shares to data root tuples proofs, the app is currently able to generate and verify them. However, these are still not supported at the smart contract level. Future works will focus on this. diff --git a/x/blobstream/types/abi_consts.go b/x/blobstream/types/abi_consts.go index f8072c28cc..a5bbc6638e 100644 --- a/x/blobstream/types/abi_consts.go +++ b/x/blobstream/types/abi_consts.go @@ -10,10 +10,10 @@ import ( ) const ( - // InternalBlobStreamABIJSON is the json encoded abi for private functions in the - // BlobStream contract. This is needed to encode data that is signed over in a way + // InternalBlobstreamABIJSON is the json encoded abi for private functions in the + // Blobstream contract. This is needed to encode data that is signed over in a way // that the contracts can easily verify. - InternalBlobStreamABIJSON = `[ + InternalBlobstreamABIJSON = `[ { "inputs": [ { @@ -116,8 +116,8 @@ const ( ) var ( - ExternalBlobStreamABI abi.ABI - InternalBlobStreamABI abi.ABI + ExternalBlobstreamABI abi.ABI + InternalBlobstreamABI abi.ABI BridgeValidatorAbi abi.Arguments VsDomainSeparator ethcmn.Hash @@ -129,13 +129,13 @@ func init() { if err != nil { log.Fatalln("bad ABI constant", err) } - ExternalBlobStreamABI = contractAbi + ExternalBlobstreamABI = contractAbi - internalABI, err := abi.JSON(strings.NewReader(InternalBlobStreamABIJSON)) + internalABI, err := abi.JSON(strings.NewReader(InternalBlobstreamABIJSON)) if err != nil { log.Fatalln("bad internal ABI constant", err) } - InternalBlobStreamABI = internalABI + InternalBlobstreamABI = internalABI solValidatorType, err := abi.NewType("tuple", "validator", []abi.ArgumentMarshaling{ {Name: "Addr", Type: "address"}, diff --git a/x/blobstream/types/genesis.go b/x/blobstream/types/genesis.go index 5bc84959b9..6d8f5cc334 100644 --- a/x/blobstream/types/genesis.go +++ b/x/blobstream/types/genesis.go @@ -14,7 +14,7 @@ const ( DefaultParamspace = ModuleName // MinimumDataCommitmentWindow is a constant that defines the minimum - // allowable window for the BlobStream data commitments. + // allowable window for the Blobstream data commitments. MinimumDataCommitmentWindow = 100 ) diff --git a/x/blobstream/types/genesis.pb.go b/x/blobstream/types/genesis.pb.go index 12137c7360..58d29c7ccd 100644 --- a/x/blobstream/types/genesis.pb.go +++ b/x/blobstream/types/genesis.pb.go @@ -23,7 +23,7 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// Params represent the BlobStream genesis and store parameters. +// Params represent Blobstream genesis and store parameters. type Params struct { DataCommitmentWindow uint64 `protobuf:"varint,1,opt,name=data_commitment_window,json=dataCommitmentWindow,proto3" json:"data_commitment_window,omitempty"` } @@ -68,7 +68,7 @@ func (m *Params) GetDataCommitmentWindow() uint64 { return 0 } -// GenesisState struct, containing all persistent data required by BlobStream +// GenesisState struct, containing all persistent data required by Blobstream // module type GenesisState struct { Params *Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params,omitempty"` diff --git a/x/blobstream/types/types.pb.go b/x/blobstream/types/types.pb.go index 1f94eb431d..34078b961b 100644 --- a/x/blobstream/types/types.pb.go +++ b/x/blobstream/types/types.pb.go @@ -83,7 +83,7 @@ func (m *BridgeValidator) GetEvmAddress() string { return "" } -// Valset is the EVM Bridge Multsig Set, each BlobStream validator also +// Valset is the EVM Bridge Multsig Set, each Blobstream validator also // maintains an ETH key to sign messages, these are used to check signatures on // ETH because of the significant gas savings type Valset struct { diff --git a/x/blobstream/types/validator.go b/x/blobstream/types/validator.go index 8d3724d70c..ece35f70c7 100644 --- a/x/blobstream/types/validator.go +++ b/x/blobstream/types/validator.go @@ -96,22 +96,22 @@ func EVMAddrLessThan(e common.Address, o common.Address) bool { } // PowerDiff returns the difference in power between two bridge validator sets. -// Note this is BlobStream bridge power *not* Cosmos voting power. +// Note this is Blobstream bridge power *not* Cosmos voting power. // Cosmos voting power is based on the absolute number of tokens in the staking // pool at any given time. -// BlobStream bridge power is normalized using the equation. +// Blobstream bridge power is normalized using the equation. // // validators cosmos voting power / total cosmos voting power in this block = -// BlobStream bridge power / u32_max +// Blobstream bridge power / u32_max // // As an example if someone has 52% of the Cosmos voting power when a validator -// set is created their BlobStream bridge voting power is u32_max * .52 +// set is created their Blobstream bridge voting power is u32_max * .52 // // Normalized voting power dramatically reduces how often we have to produce new // validator set updates. For example if the total on chain voting power // increases by 1% due to inflation, we shouldn't have to generate a new // validator set, after all the validators retained their relative percentages -// during inflation and normalized BlobStream power shows no difference. +// during inflation and normalized Blobstream power shows no difference. func (ibv InternalBridgeValidators) PowerDiff(c InternalBridgeValidators) float64 { powers := map[string]int64{} // loop over ibv and initialize the map with their powers diff --git a/x/blobstream/types/valset.go b/x/blobstream/types/valset.go index bbfac00f26..da9229b1d6 100644 --- a/x/blobstream/types/valset.go +++ b/x/blobstream/types/valset.go @@ -39,7 +39,7 @@ func (v *Valset) SignBytes() (ethcmn.Hash, error) { // checkpointAbiJson but other than that it's a constant that has no impact // on the output. This is because it gets encoded as a function name which // we must then discard. - bytes, err := InternalBlobStreamABI.Pack( + bytes, err := InternalBlobstreamABI.Pack( "domainSeparateValidatorSetHash", VsDomainSeparator, big.NewInt(int64(v.Nonce)), @@ -67,7 +67,7 @@ func (v *Valset) Hash() (ethcmn.Hash, error) { } } - encodedVals, err := InternalBlobStreamABI.Pack("computeValidatorSetHash", ethVals) + encodedVals, err := InternalBlobstreamABI.Pack("computeValidatorSetHash", ethVals) if err != nil { return ethcmn.Hash{}, err }