From 80e1f6704c987712b98273a5e68a638d5399a9b3 Mon Sep 17 00:00:00 2001 From: tac0turtle Date: Mon, 9 Jun 2025 17:09:13 +0200 Subject: [PATCH 01/21] add network module --- modules/network/autocli.go | 78 + modules/network/client/cli/query.go | 197 ++ modules/network/client/cli/tx.go | 128 + modules/network/depinject.go | 76 + modules/network/genesis.go | 86 + modules/network/keeper/abci.go | 176 ++ modules/network/keeper/bitmap.go | 98 + modules/network/keeper/grpc_query.go | 165 ++ modules/network/keeper/keeper.go | 322 +++ modules/network/keeper/msg_server.go | 177 ++ modules/network/module.go | 213 ++ modules/network/types/codec.go | 38 + modules/network/types/expected_keepers.go | 25 + modules/network/types/genesis.go | 48 + modules/network/types/genesis.pb.go | 457 ++++ modules/network/types/keys.go | 71 + modules/network/types/msgs.go | 196 ++ modules/network/types/params.go | 186 ++ modules/network/types/query.pb.go | 2349 +++++++++++++++++ modules/network/types/query.pb.gw.go | 557 ++++ modules/network/types/tx.pb.go | 1635 ++++++++++++ modules/network/types/types.pb.go | 1154 ++++++++ .../rollkitsdk/network/module/v1/module.proto | 15 + .../proto/rollkitsdk/network/v1/genesis.proto | 20 + .../proto/rollkitsdk/network/v1/query.proto | 95 + modules/proto/rollkitsdk/network/v1/tx.proto | 88 + .../proto/rollkitsdk/network/v1/types.proto | 75 + 27 files changed, 8725 insertions(+) create mode 100644 modules/network/autocli.go create mode 100644 modules/network/client/cli/query.go create mode 100644 modules/network/client/cli/tx.go create mode 100644 modules/network/depinject.go create mode 100644 modules/network/genesis.go create mode 100644 modules/network/keeper/abci.go create mode 100644 modules/network/keeper/bitmap.go create mode 100644 modules/network/keeper/grpc_query.go create mode 100644 modules/network/keeper/keeper.go create mode 100644 modules/network/keeper/msg_server.go create mode 100644 modules/network/module.go create mode 100644 modules/network/types/codec.go create mode 100644 modules/network/types/expected_keepers.go create mode 100644 modules/network/types/genesis.go create mode 100644 modules/network/types/genesis.pb.go create mode 100644 modules/network/types/keys.go create mode 100644 modules/network/types/msgs.go create mode 100644 modules/network/types/params.go create mode 100644 modules/network/types/query.pb.go create mode 100644 modules/network/types/query.pb.gw.go create mode 100644 modules/network/types/tx.pb.go create mode 100644 modules/network/types/types.pb.go create mode 100644 modules/proto/rollkitsdk/network/module/v1/module.proto create mode 100644 modules/proto/rollkitsdk/network/v1/genesis.proto create mode 100644 modules/proto/rollkitsdk/network/v1/query.proto create mode 100644 modules/proto/rollkitsdk/network/v1/tx.proto create mode 100644 modules/proto/rollkitsdk/network/v1/types.proto diff --git a/modules/network/autocli.go b/modules/network/autocli.go new file mode 100644 index 00000000..7669a198 --- /dev/null +++ b/modules/network/autocli.go @@ -0,0 +1,78 @@ +package network + +import ( + autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + networkv1 "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// AutoCLIOptions implements the autocli.HasAutoCLIConfig interface. +func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { + return &autocliv1.ModuleOptions{ + Query: &autocliv1.ServiceCommandDescriptor{ + Service: networkv1.Query_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Params", + Use: "params", + Short: "Query the current network parameters", + }, + { + RpcMethod: "AttestationBitmap", + Use: "attestation [height]", + Short: "Query the attestation bitmap for a specific height", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "height"}, + }, + }, + { + RpcMethod: "EpochInfo", + Use: "epoch [epoch-number]", + Short: "Query information about a specific epoch", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "epoch"}, + }, + }, + { + RpcMethod: "ValidatorIndex", + Use: "validator-index [address]", + Short: "Query the bitmap index for a validator", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "address"}, + }, + }, + { + RpcMethod: "SoftConfirmationStatus", + Use: "soft-confirmation [height]", + Short: "Query if a height is soft-confirmed", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "height"}, + }, + }, + }, + }, + Tx: &autocliv1.ServiceCommandDescriptor{ + Service: networkv1.Msg_ServiceDesc.ServiceName, + RpcCommandOptions: []*autocliv1.RpcCommandOptions{ + { + RpcMethod: "Attest", + Use: "attest [height] [vote-base64]", + Short: "Submit an attestation for a checkpoint height", + PositionalArgs: []*autocliv1.PositionalArgDescriptor{ + {ProtoField: "height"}, + {ProtoField: "vote"}, + }, + }, + { + RpcMethod: "JoinAttesterSet", + Use: "join-attester", + Short: "Join the attester set as a validator", + }, + { + RpcMethod: "LeaveAttesterSet", + Use: "leave-attester", + Short: "Leave the attester set as a validator", + }, + }, + }, + } +} \ No newline at end of file diff --git a/modules/network/client/cli/query.go b/modules/network/client/cli/query.go new file mode 100644 index 00000000..c5906696 --- /dev/null +++ b/modules/network/client/cli/query.go @@ -0,0 +1,197 @@ +package cli + +import ( + "context" + "fmt" + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/spf13/cobra" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd(queryRoute string) *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + CmdQueryParams(), + CmdQueryAttestationBitmap(), + CmdQueryEpochInfo(), + CmdQueryValidatorIndex(), + CmdQuerySoftConfirmationStatus(), + ) + + return cmd +} + +// CmdQueryParams implements the params query command +func CmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "Query the current network parameters", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// CmdQueryAttestationBitmap queries the attestation bitmap for a height +func CmdQueryAttestationBitmap() *cobra.Command { + cmd := &cobra.Command{ + Use: "attestation [height]", + Short: "Query the attestation bitmap for a specific height", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + height, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid height: %w", err) + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.AttestationBitmap(context.Background(), &types.QueryAttestationBitmapRequest{ + Height: height, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// CmdQueryEpochInfo queries information about an epoch +func CmdQueryEpochInfo() *cobra.Command { + cmd := &cobra.Command{ + Use: "epoch [epoch-number]", + Short: "Query information about a specific epoch", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + epoch, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid epoch: %w", err) + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.EpochInfo(context.Background(), &types.QueryEpochInfoRequest{ + Epoch: epoch, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// CmdQueryValidatorIndex queries the bitmap index for a validator +func CmdQueryValidatorIndex() *cobra.Command { + cmd := &cobra.Command{ + Use: "validator-index [address]", + Short: "Query the bitmap index for a validator", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.ValidatorIndex(context.Background(), &types.QueryValidatorIndexRequest{ + Address: args[0], + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// CmdQuerySoftConfirmationStatus queries if a height is soft-confirmed +func CmdQuerySoftConfirmationStatus() *cobra.Command { + cmd := &cobra.Command{ + Use: "soft-confirmation [height]", + Short: "Query if a height is soft-confirmed", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + + height, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid height: %w", err) + } + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.SoftConfirmationStatus(context.Background(), &types.QuerySoftConfirmationStatusRequest{ + Height: height, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} \ No newline at end of file diff --git a/modules/network/client/cli/tx.go b/modules/network/client/cli/tx.go new file mode 100644 index 00000000..252654a4 --- /dev/null +++ b/modules/network/client/cli/tx.go @@ -0,0 +1,128 @@ +package cli + +import ( + "fmt" + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/spf13/cobra" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand( + CmdAttest(), + CmdJoinAttesterSet(), + CmdLeaveAttesterSet(), + ) + + return cmd +} + +// CmdAttest returns a CLI command for creating a MsgAttest transaction +func CmdAttest() *cobra.Command { + cmd := &cobra.Command{ + Use: "attest [height] [vote-base64]", + Short: "Submit an attestation for a checkpoint height", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + height, err := strconv.ParseInt(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid height: %w", err) + } + + vote := []byte(args[1]) + + msg := types.NewMsgAttest( + clientCtx.GetFromAddress().String(), + height, + vote, + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// CmdJoinAttesterSet returns a CLI command for creating a MsgJoinAttesterSet transaction +func CmdJoinAttesterSet() *cobra.Command { + cmd := &cobra.Command{ + Use: "join-attester", + Short: "Join the attester set as a validator", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgJoinAttesterSet( + clientCtx.GetFromAddress().String(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// CmdLeaveAttesterSet returns a CLI command for creating a MsgLeaveAttesterSet transaction +func CmdLeaveAttesterSet() *cobra.Command { + cmd := &cobra.Command{ + Use: "leave-attester", + Short: "Leave the attester set as a validator", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgLeaveAttesterSet( + clientCtx.GetFromAddress().String(), + ) + + if err := msg.ValidateBasic(); err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} \ No newline at end of file diff --git a/modules/network/depinject.go b/modules/network/depinject.go new file mode 100644 index 00000000..98972216 --- /dev/null +++ b/modules/network/depinject.go @@ -0,0 +1,76 @@ +package network + +import ( + "cosmossdk.io/core/appmodule" + "cosmossdk.io/depinject" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + "github.com/rollkit/go-execution-abci/modules/network/keeper" + modulev1 "github.com/rollkit/go-execution-abci/modules/network/module/v1" + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +var _ appmodule.AppModule = AppModule{} + +// IsOnePerModuleType implements the depinject.OnePerModuleType interface. +func (am AppModule) IsOnePerModuleType() {} + +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} + +func init() { + appmodule.Register( + &modulev1.Module{}, + appmodule.Provide(ProvideModule), + ) +} + +type ModuleInputs struct { + depinject.In + + Config *modulev1.Module + Cdc codec.Codec + Key *sdk.KVStoreKey + ParamsSubspace paramtypes.Subspace + StakingKeeper types.StakingKeeper + AccountKeeper types.AccountKeeper + BankKeeper types.BankKeeper +} + +type ModuleOutputs struct { + depinject.Out + + NetworkKeeper keeper.Keeper + Module appmodule.AppModule +} + +func ProvideModule(in ModuleInputs) ModuleOutputs { + // default to governance authority if not provided + authority := authtypes.NewModuleAddress(govtypes.ModuleName) + if in.Config.Authority != "" { + authority = authtypes.NewModuleAddressOrBech32Address(in.Config.Authority) + } + + k := keeper.NewKeeper( + in.Cdc, + in.Key, + in.ParamsSubspace, + in.StakingKeeper, + in.AccountKeeper, + in.BankKeeper, + authority.String(), + ) + m := NewAppModule( + in.Cdc, + k, + in.AccountKeeper, + in.BankKeeper, + ) + + return ModuleOutputs{NetworkKeeper: k, Module: m} +} diff --git a/modules/network/genesis.go b/modules/network/genesis.go new file mode 100644 index 00000000..3764073b --- /dev/null +++ b/modules/network/genesis.go @@ -0,0 +1,86 @@ +package network + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/codec" + + "github.com/rollkit/go-execution-abci/modules/network/keeper" + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// InitGenesis initializes the network module's state from a provided genesis state. +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { + // Set module params + k.SetParams(ctx, genState.Params) + + // Set validator indices + for _, vi := range genState.ValidatorIndices { + k.SetValidatorIndex(ctx, vi.Address, uint16(vi.Index), vi.Power) + // Also add to attester set + k.SetAttesterSetMember(ctx, vi.Address) + } + + // Set attestation bitmaps + for _, ab := range genState.AttestationBitmaps { + k.SetAttestationBitmap(ctx, ab.Height, ab.Bitmap) + // Store full attestation info + store := ctx.KVStore(k.GetStoreKey()) + key := append([]byte("attestation_info/"), sdk.Uint64ToBigEndian(uint64(ab.Height))...) + bz := k.GetCodec().MustMarshal(&ab) + store.Set(key, bz) + + if ab.SoftConfirmed { + setSoftConfirmed(ctx, k, ab.Height) + } + } +} + +// ExportGenesis returns the network module's exported genesis. +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + genesis := types.DefaultGenesisState() + genesis.Params = k.GetParams(ctx) + + // Export validator indices + store := ctx.KVStore(k.GetStoreKey()) + iterator := sdk.KVStorePrefixIterator(store, types.ValidatorIndexPrefix) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + addr := string(iterator.Key()[len(types.ValidatorIndexPrefix):]) + index, _ := k.GetValidatorIndex(ctx, addr) + power := k.GetValidatorPower(ctx, index) + + genesis.ValidatorIndices = append(genesis.ValidatorIndices, types.ValidatorIndex{ + Address: addr, + Index: uint32(index), + Power: power, + }) + } + + // Export attestation bitmaps + attIterator := sdk.KVStorePrefixIterator(store, []byte("attestation_info/")) + defer attIterator.Close() + + for ; attIterator.Valid(); attIterator.Next() { + var ab types.AttestationBitmap + k.GetCodec().MustUnmarshal(attIterator.Value(), &ab) + genesis.AttestationBitmaps = append(genesis.AttestationBitmaps, ab) + } + + return genesis +} + +// Helper functions +func (k keeper.Keeper) GetStoreKey() sdk.StoreKey { + return k.storeKey +} + +func (k keeper.Keeper) GetCodec() codec.BinaryCodec { + return k.cdc +} + +func setSoftConfirmed(ctx sdk.Context, k keeper.Keeper, height int64) { + store := ctx.KVStore(k.GetStoreKey()) + key := append([]byte("soft_confirmed/"), sdk.Uint64ToBigEndian(uint64(height))...) + store.Set(key, []byte{1}) +} \ No newline at end of file diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go new file mode 100644 index 00000000..5ce9b276 --- /dev/null +++ b/modules/network/keeper/abci.go @@ -0,0 +1,176 @@ +package keeper + +import ( + "crypto/sha256" + "encoding/base64" + + // For error wrapping if needed + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// BeginBlocker handles begin block logic for the network module +func (k Keeper) BeginBlocker(ctx sdk.Context) { + params := k.GetParams(ctx) + + // Only process if sign mode is IBC_ONLY and we have outbound IBC packets + if params.SignMode == types.SignMode_SIGN_MODE_IBC_ONLY { + // TODO: Check for outbound IBC packets + // For now, this is a placeholder + } +} + +// EndBlocker handles end block logic for the network module +func (k Keeper) EndBlocker(ctx sdk.Context) { + height := ctx.BlockHeight() + params := k.GetParams(ctx) + + // Handle checkpoint heights + if k.IsCheckpointHeight(ctx, height) { + k.processCheckpoint(ctx, height) + } + + // Handle epoch end + epoch := k.GetCurrentEpoch(ctx) + nextHeight := height + 1 + nextEpoch := uint64(nextHeight) / params.EpochLength + + if epoch != nextEpoch { + k.processEpochEnd(ctx, epoch) + } +} + +// processCheckpoint handles checkpoint processing +func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) { + bitmapBytes := k.GetAttestationBitmap(ctx, height) + if bitmapBytes == nil { + return + } + + votedPower := k.CalculateVotedPower(ctx, bitmapBytes) + totalPower := k.GetTotalPower(ctx) + + validatorHash := sha256.Sum256(bitmapBytes) + + commitHash := sha256.Sum256([]byte("placeholder")) + + softConfirmed := k.CheckQuorum(ctx, votedPower, totalPower) + + attestationInfoToStore := types.AttestationBitmap{ + Height: height, + Bitmap: bitmapBytes, + VotedPower: votedPower, + TotalPower: totalPower, + SoftConfirmed: softConfirmed, + } + + if err := k.StoredAttestationInfo.Set(ctx, height, attestationInfoToStore); err != nil { + k.Logger(ctx).Error("failed to store attestation info", "height", height, "error", err) + } + + // Emit hashes + k.emitCheckpointHashes(ctx, height, validatorHash[:], commitHash[:], softConfirmed) +} + +func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) { + params := k.GetParams(ctx) + epochBitmap := k.GetEpochBitmap(ctx, epoch) + + if epochBitmap != nil { + validators := k.stakingKeeper.GetLastValidators(ctx) + totalBondedValidators := 0 + for _, v := range validators { + if v.IsBonded() { + totalBondedValidators++ + } + } + + if totalBondedValidators > 0 { + participated := k.bitmapHelper.PopCount(epochBitmap) + minParticipation, err := math.LegacyNewDecFromStr(params.MinParticipation) + if err != nil { + k.Logger(ctx).Error("failed to parse MinParticipation", "error", err) + } else { + participationRate := math.LegacyNewDec(int64(participated)).QuoInt64(int64(totalBondedValidators)) + if participationRate.LT(minParticipation) { + k.ejectLowParticipants(ctx, epochBitmap) + } + } + } + } + + if !params.EmergencyMode { + epochStartHeight := int64(epoch * params.EpochLength) + checkpointsInEpoch := 0 + softConfirmedCheckpoints := 0 + + for h := epochStartHeight; h < epochStartHeight+int64(params.EpochLength); h++ { + if h > ctx.BlockHeight() { + break + } + if k.IsCheckpointHeight(ctx, h) { + checkpointsInEpoch++ + if k.IsSoftConfirmed(ctx, h) { + softConfirmedCheckpoints++ + } + } + } + + if checkpointsInEpoch > 0 && softConfirmedCheckpoints == 0 { + panic("Network module: No checkpoints achieved quorum in epoch") + } + } + + if err := k.PruneOldBitmaps(ctx, epoch); err != nil { + k.Logger(ctx).Error("failed to prune old data at epoch end", "epoch", epoch, "error", err) + } + + if err := k.BuildValidatorIndexMap(ctx); err != nil { + k.Logger(ctx).Error("failed to rebuild validator index map at epoch end", "epoch", epoch, "error", err) + } +} + +// ejectLowParticipants ejects validators with low participation +func (k Keeper) ejectLowParticipants(ctx sdk.Context, epochBitmap []byte) { + // TODO: Implement validator ejection logic + k.Logger(ctx).Info("Low participation detected, ejection logic not yet implemented") +} + +// emitCheckpointHashes emits checkpoint hashes +func (k Keeper) emitCheckpointHashes(ctx sdk.Context, height int64, validatorHash, commitHash []byte, softConfirmed bool) { + var softConfirmedSt string + + if softConfirmed { + softConfirmedSt = "true" + } else { + softConfirmedSt = "false" + } + ctx.EventManager().EmitEvent( + sdk.NewEvent( + "checkpoint", + sdk.NewAttribute("height", math.NewInt(height).String()), + sdk.NewAttribute("validator_hash", base64.StdEncoding.EncodeToString(validatorHash)), + sdk.NewAttribute("commit_hash", base64.StdEncoding.EncodeToString(commitHash)), + sdk.NewAttribute("soft_confirmed", softConfirmedSt), + ), + ) +} + +func (k Keeper) emitZeroHashes(ctx sdk.Context, height int64) { + zeroHash := make([]byte, 32) + ctx.EventManager().EmitEvent( + sdk.NewEvent( + "checkpoint", + sdk.NewAttribute("height", math.NewInt(height).String()), + sdk.NewAttribute("validator_hash", base64.StdEncoding.EncodeToString(zeroHash)), + sdk.NewAttribute("commit_hash", base64.StdEncoding.EncodeToString(zeroHash)), + sdk.NewAttribute("soft_confirmed", "false"), + ), + ) +} + +func (k Keeper) AfterValidatorSetUpdates(ctx sdk.Context) { + k.BuildValidatorIndexMap(ctx) +} diff --git a/modules/network/keeper/bitmap.go b/modules/network/keeper/bitmap.go new file mode 100644 index 00000000..f60c3a8b --- /dev/null +++ b/modules/network/keeper/bitmap.go @@ -0,0 +1,98 @@ +package keeper + +import ( + "math/bits" +) + +// BitmapHelper provides utility functions for bitmap operations +type BitmapHelper struct{} + +// NewBitmapHelper creates a new bitmap helper +func NewBitmapHelper() *BitmapHelper { + return &BitmapHelper{} +} + +// NewBitmap creates a new bitmap for n validators +func (bh *BitmapHelper) NewBitmap(n int) []byte { + size := (n + 7) / 8 + return make([]byte, size) +} + +// SetBit sets the bit at index to 1 +func (bh *BitmapHelper) SetBit(bitmap []byte, index int) { + if index < 0 || index >= len(bitmap)*8 { + return + } + byteIndex := index / 8 + bitIndex := uint(index % 8) + bitmap[byteIndex] |= 1 << bitIndex +} + +// IsSet checks if the bit at index is set +func (bh *BitmapHelper) IsSet(bitmap []byte, index int) bool { + if index < 0 || index >= len(bitmap)*8 { + return false + } + byteIndex := index / 8 + bitIndex := uint(index % 8) + return (bitmap[byteIndex] & (1 << bitIndex)) != 0 +} + +// PopCount returns the number of set bits +func (bh *BitmapHelper) PopCount(bitmap []byte) int { + count := 0 + for _, b := range bitmap { + count += bits.OnesCount8(b) + } + return count +} + +// OR performs bitwise OR of two bitmaps +func (bh *BitmapHelper) OR(dst, src []byte) { + minLen := len(dst) + if len(src) < minLen { + minLen = len(src) + } + for i := 0; i < minLen; i++ { + dst[i] |= src[i] + } +} + +// AND performs bitwise AND of two bitmaps +func (bh *BitmapHelper) AND(dst, src []byte) { + minLen := len(dst) + if len(src) < minLen { + minLen = len(src) + } + for i := 0; i < minLen; i++ { + dst[i] &= src[i] + } +} + +// Copy creates a copy of the bitmap +func (bh *BitmapHelper) Copy(bitmap []byte) []byte { + if bitmap == nil { + return nil + } + cp := make([]byte, len(bitmap)) + copy(cp, bitmap) + return cp +} + +// Clear sets all bits to 0 +func (bh *BitmapHelper) Clear(bitmap []byte) { + for i := range bitmap { + bitmap[i] = 0 + } +} + +// CountInRange counts set bits in a range [start, end) +func (bh *BitmapHelper) CountInRange(bitmap []byte, start, end int) int { + count := 0 + for i := start; i < end && i < len(bitmap)*8; i++ { + if bh.IsSet(bitmap, i) { + count++ + } + } + return count +} \ No newline at end of file diff --git a/modules/network/keeper/grpc_query.go b/modules/network/keeper/grpc_query.go new file mode 100644 index 00000000..8a961542 --- /dev/null +++ b/modules/network/keeper/grpc_query.go @@ -0,0 +1,165 @@ +package keeper + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// queryServer is a wrapper around the network module's keeper providing gRPC query +// functionalities. +type queryServer struct { + keeper Keeper +} + +// NewQueryServer creates a new gRPC query server. +func NewQueryServer(k Keeper) types.QueryServer { + return &queryServer{keeper: k} +} + +var _ types.QueryServer = (*queryServer)(nil) + +// Params queries the module parameters +func (q *queryServer) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + return &types.QueryParamsResponse{Params: q.keeper.GetParams(ctx)}, nil +} + +// AttestationBitmap queries the attestation bitmap for a specific height +func (q *queryServer) AttestationBitmap(c context.Context, req *types.QueryAttestationBitmapRequest) (*types.QueryAttestationBitmapResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + bitmapBytes := q.keeper.GetAttestationBitmap(ctx, req.Height) + if bitmapBytes == nil { + return nil, status.Error(codes.NotFound, "attestation bitmap not found for height") + } + + // Reconstruct attestation info using keeper methods + votedPower := q.keeper.CalculateVotedPower(ctx, bitmapBytes) + totalPower := q.keeper.GetTotalPower(ctx) + // Assuming IsSoftConfirmed is a method on the Keeper + // If not, you might need to add it or compute it here using keeper.CheckQuorum + softConfirmed := q.keeper.IsSoftConfirmed(ctx, req.Height) + + return &types.QueryAttestationBitmapResponse{ + Bitmap: &types.AttestationBitmap{ + Height: req.Height, + Bitmap: bitmapBytes, + VotedPower: votedPower, + TotalPower: totalPower, + SoftConfirmed: softConfirmed, + }, + }, nil +} + +// EpochInfo queries information about a specific epoch +func (q *queryServer) EpochInfo(c context.Context, req *types.QueryEpochInfoRequest) (*types.QueryEpochInfoResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + params := q.keeper.GetParams(ctx) + + startHeight := int64(req.Epoch * params.EpochLength) + endHeight := int64((req.Epoch+1)*params.EpochLength - 1) + + epochBitmap := q.keeper.GetEpochBitmap(ctx, req.Epoch) + if epochBitmap == nil { + // Return info even if bitmap is not present, as per original logic + return &types.QueryEpochInfoResponse{ + Epoch: req.Epoch, + StartHeight: startHeight, + EndHeight: endHeight, + ParticipationBitmap: []byte{}, + ActiveValidators: 0, // Consider calculating active validators even if bitmap is nil + ParticipatingValidators: 0, + }, nil + } + + validators := q.keeper.stakingKeeper.GetLastValidators(ctx) + activeValidators := uint64(0) + for _, v := range validators { + if v.IsBonded() { + activeValidators++ + } + } + + participatingValidators := uint64(q.keeper.bitmapHelper.PopCount(epochBitmap)) + + return &types.QueryEpochInfoResponse{ + Epoch: req.Epoch, + StartHeight: startHeight, + EndHeight: endHeight, + ParticipationBitmap: epochBitmap, + ActiveValidators: activeValidators, + ParticipatingValidators: participatingValidators, + }, nil +} + +// ValidatorIndex queries the bitmap index for a validator +func (q *queryServer) ValidatorIndex(c context.Context, req *types.QueryValidatorIndexRequest) (*types.QueryValidatorIndexResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + index, found := q.keeper.GetValidatorIndex(ctx, req.Address) + if !found { + return nil, status.Error(codes.NotFound, "validator index not found") + } + + power := q.keeper.GetValidatorPower(ctx, index) + + return &types.QueryValidatorIndexResponse{ + Index: &types.ValidatorIndex{ + Address: req.Address, + Index: uint32(index), + Power: power, + }, + }, nil +} + +// SoftConfirmationStatus queries if a height is soft-confirmed +func (q *queryServer) SoftConfirmationStatus(c context.Context, req *types.QuerySoftConfirmationStatusRequest) (*types.QuerySoftConfirmationStatusResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + params := q.keeper.GetParams(ctx) + + bitmap := q.keeper.GetAttestationBitmap(ctx, req.Height) + if bitmap == nil { + return &types.QuerySoftConfirmationStatusResponse{ + IsSoftConfirmed: false, + VotedPower: 0, + TotalPower: q.keeper.GetTotalPower(ctx), + QuorumFraction: params.QuorumFraction, + }, nil + } + + votedPower := q.keeper.CalculateVotedPower(ctx, bitmap) + totalPower := q.keeper.GetTotalPower(ctx) + isSoftConfirmed := q.keeper.CheckQuorum(ctx, votedPower, totalPower) + + return &types.QuerySoftConfirmationStatusResponse{ + IsSoftConfirmed: isSoftConfirmed, + VotedPower: votedPower, + TotalPower: totalPower, + QuorumFraction: params.QuorumFraction, + }, nil +} diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go new file mode 100644 index 00000000..9bf12f42 --- /dev/null +++ b/modules/network/keeper/keeper.go @@ -0,0 +1,322 @@ +package keeper + +import ( + "cosmossdk.io/collections" + "cosmossdk.io/core/store" + "cosmossdk.io/log" + "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// Keeper of the network store +type Keeper struct { + cdc codec.BinaryCodec + paramstore paramtypes.Subspace + stakingKeeper types.StakingKeeper + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + authority string + bitmapHelper *BitmapHelper + schema collections.Schema + + // Collections for state management + ValidatorIndex collections.Map[string, uint16] + ValidatorPower collections.Map[uint16, uint64] + AttestationBitmap collections.Map[int64, []byte] + EpochBitmap collections.Map[uint64, []byte] + AttesterSet collections.KeySet[string] + Signatures collections.Map[collections.Pair[int64, string], []byte] + StoredAttestationInfo collections.Map[int64, types.AttestationBitmap] +} + +// NewKeeper creates a new network Keeper instance +func NewKeeper( + cdc codec.BinaryCodec, + storeService store.KVStoreService, // Changed from sdk.StoreKey + ps paramtypes.Subspace, + sk types.StakingKeeper, + ak types.AccountKeeper, + bk types.BankKeeper, + authority string, +) Keeper { + // set KeyTable if it has not already been set + if !ps.HasKeyTable() { + ps = ps.WithKeyTable(types.ParamKeyTable()) + } + + sb := collections.NewSchemaBuilder(storeService) + keeper := Keeper{ + cdc: cdc, + paramstore: ps, + stakingKeeper: sk, + accountKeeper: ak, + bankKeeper: bk, + authority: authority, + bitmapHelper: NewBitmapHelper(), + + ValidatorIndex: collections.NewMap(sb, types.ValidatorIndexPrefix, "validator_index", collections.StringKey, collections.Uint16Value), + ValidatorPower: collections.NewMap(sb, types.ValidatorPowerPrefix, "validator_power", collections.Uint16Key, collections.Uint64Value), + AttestationBitmap: collections.NewMap(sb, types.AttestationBitmapPrefix, "attestation_bitmap", collections.Int64Key, collections.BytesValue), + EpochBitmap: collections.NewMap(sb, types.EpochBitmapPrefix, "epoch_bitmap", collections.Uint64Key, collections.BytesValue), + AttesterSet: collections.NewKeySet(sb, types.AttesterSetPrefix, "attester_set", collections.StringKey), + Signatures: collections.NewMap(sb, types.SignaturePrefix, "signatures", collections.PairKeyCodec(collections.Int64Key, collections.StringKey), collections.BytesValue), + StoredAttestationInfo: collections.NewMap(sb, types.StoredAttestationInfoPrefix, "stored_attestation_info", collections.Int64Key, codec.CollValue[types.AttestationBitmap](cdc)), // Initialize new collection + } + + // The schema is built implicitly when the first collection is created or can be explicitly built. + // schema, err := sb.Build() + // if err != nil { + // panic(err) + // } + // keeper.schema = schema + + return keeper +} + +// GetAuthority returns the module authority +func (k Keeper) GetAuthority() string { + return k.authority +} + +// Logger returns a module-specific logger +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", "network") +} + +// GetParams get all parameters as types.Params +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + var params types.Params + k.paramstore.GetParamSet(ctx, ¶ms) + return params +} + +// SetParams set the params +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + k.paramstore.SetParamSet(ctx, ¶ms) +} + +// SetValidatorIndex stores the validator index mapping and power +func (k Keeper) SetValidatorIndex(ctx sdk.Context, addr string, index uint16, power uint64) error { + if err := k.ValidatorIndex.Set(ctx, addr, index); err != nil { + return err + } + return k.ValidatorPower.Set(ctx, index, power) +} + +// GetValidatorIndex retrieves the validator index +func (k Keeper) GetValidatorIndex(ctx sdk.Context, addr string) (uint16, bool) { + index, err := k.ValidatorIndex.Get(ctx, addr) + if err != nil { + // For 'not found', collections.ErrNotFound can be checked specifically if needed. + return 0, false + } + return index, true +} + +// GetValidatorPower retrieves the validator power by index +func (k Keeper) GetValidatorPower(ctx sdk.Context, index uint16) uint64 { + power, err := k.ValidatorPower.Get(ctx, index) + if err != nil { + // Consider logging the error or returning an error if 0 is a valid power value. + return 0 + } + return power +} + +// SetAttestationBitmap stores the attestation bitmap for a height +func (k Keeper) SetAttestationBitmap(ctx sdk.Context, height int64, bitmap []byte) error { + return k.AttestationBitmap.Set(ctx, height, bitmap) +} + +// GetAttestationBitmap retrieves the attestation bitmap for a height +func (k Keeper) GetAttestationBitmap(ctx sdk.Context, height int64) []byte { + bitmap, err := k.AttestationBitmap.Get(ctx, height) + if err != nil { + // Consider logging err or returning (nil, error) + return nil + } + return bitmap +} + +// SetEpochBitmap stores the epoch participation bitmap +func (k Keeper) SetEpochBitmap(ctx sdk.Context, epoch uint64, bitmap []byte) error { + return k.EpochBitmap.Set(ctx, epoch, bitmap) +} + +// GetEpochBitmap retrieves the epoch participation bitmap +func (k Keeper) GetEpochBitmap(ctx sdk.Context, epoch uint64) []byte { + bitmap, err := k.EpochBitmap.Get(ctx, epoch) + if err != nil { + // Consider logging err or returning (nil, error) + return nil + } + return bitmap +} + +// IsInAttesterSet checks if a validator is in the attester set +func (k Keeper) IsInAttesterSet(ctx sdk.Context, addr string) bool { + has, err := k.AttesterSet.Has(ctx, addr) + if err != nil { + k.Logger(ctx).Error("failed to check attester set", "address", addr, "error", err) + return false + } + return has +} + +// SetAttesterSetMember adds a validator to the attester set +func (k Keeper) SetAttesterSetMember(ctx sdk.Context, addr string) error { + return k.AttesterSet.Set(ctx, addr) +} + +// RemoveAttesterSetMember removes a validator from the attester set +func (k Keeper) RemoveAttesterSetMember(ctx sdk.Context, addr string) error { + return k.AttesterSet.Remove(ctx, addr) +} + +// BuildValidatorIndexMap rebuilds the validator index mapping +func (k Keeper) BuildValidatorIndexMap(ctx sdk.Context) error { + validators := k.stakingKeeper.GetAllValidators(ctx) + + // Clear existing indices and powers + // The `nil` range clears all entries in the collection. + if err := k.ValidatorIndex.Clear(ctx, nil); err != nil { + k.Logger(ctx).Error("failed to clear validator index", "error", err) + return err + } + if err := k.ValidatorPower.Clear(ctx, nil); err != nil { + k.Logger(ctx).Error("failed to clear validator power", "error", err) + return err + } + + // Build new indices for bonded validators + index := uint16(0) + for _, val := range validators { + if val.IsBonded() { + power := uint64(val.GetConsensusPower(sdk.DefaultPowerReduction)) + if err := k.SetValidatorIndex(ctx, val.OperatorAddress, index, power); err != nil { + // Consider how to handle partial failures; potentially log and continue or return error. + k.Logger(ctx).Error("failed to set validator index during build", "validator", val.OperatorAddress, "error", err) + return err + } + index++ + } + } + return nil +} + +// GetCurrentEpoch returns the current epoch number +func (k Keeper) GetCurrentEpoch(ctx sdk.Context) uint64 { + params := k.GetParams(ctx) + height := uint64(ctx.BlockHeight()) + return height / params.EpochLength +} + +// IsCheckpointHeight checks if a height is a checkpoint +func (k Keeper) IsCheckpointHeight(ctx sdk.Context, height int64) bool { + params := k.GetParams(ctx) + return uint64(height)%params.EpochLength == 0 +} + +// CalculateVotedPower calculates the total voted power from a bitmap +func (k Keeper) CalculateVotedPower(ctx sdk.Context, bitmap []byte) uint64 { + var votedPower uint64 + for i := 0; i < len(bitmap)*8; i++ { + if k.bitmapHelper.IsSet(bitmap, i) { + power := k.GetValidatorPower(ctx, uint16(i)) + votedPower += power + } + } + return votedPower +} + +// GetTotalPower returns the total staking power +func (k Keeper) GetTotalPower(ctx sdk.Context) uint64 { + return uint64(k.stakingKeeper.GetLastTotalPower(ctx).Int64()) +} + +// CheckQuorum checks if the voted power meets quorum +func (k Keeper) CheckQuorum(ctx sdk.Context, votedPower, totalPower uint64) bool { + params := k.GetParams(ctx) + quorumFrac, err := math.LegacyNewDecFromStr(params.QuorumFraction) + if err != nil { + return false + } + + requiredPower := math.LegacyNewDec(int64(totalPower)).Mul(quorumFrac).TruncateInt().Uint64() + return votedPower >= requiredPower +} + +// IsSoftConfirmed checks if a block at a given height is soft-confirmed +// based on the attestation bitmap and quorum rules. +func (k Keeper) IsSoftConfirmed(ctx sdk.Context, height int64) bool { + bitmap := k.GetAttestationBitmap(ctx, height) + if bitmap == nil { + return false // No bitmap, so cannot be soft-confirmed + } + + votedPower := k.CalculateVotedPower(ctx, bitmap) + totalPower := k.GetTotalPower(ctx) // Assuming this gets the relevant total power for the height + + return k.CheckQuorum(ctx, votedPower, totalPower) +} + +// PruneOldBitmaps removes bitmaps older than PruneAfter epochs +func (k Keeper) PruneOldBitmaps(ctx sdk.Context, currentEpoch uint64) error { + params := k.GetParams(ctx) + if params.PruneAfter == 0 { // Avoid pruning if PruneAfter is zero or not set + return nil + } + if currentEpoch <= params.PruneAfter { + return nil + } + + pruneBeforeEpoch := currentEpoch - params.PruneAfter + pruneHeight := int64(pruneBeforeEpoch * params.EpochLength) // Assuming EpochLength defines blocks per epoch + + // Prune attestation bitmaps (raw bitmaps) + attestationRange := collections.NewRange[int64]().EndExclusive(pruneHeight) + if err := k.AttestationBitmap.Clear(ctx, attestationRange); err != nil { + k.Logger(ctx).Error("failed to prune old attestation bitmaps", "pruneHeight", pruneHeight, "error", err) + return err + } + + // Prune stored attestation info (full AttestationBitmap objects) + storedAttestationInfoRange := collections.NewRange[int64]().EndExclusive(pruneHeight) + if err := k.StoredAttestationInfo.Clear(ctx, storedAttestationInfoRange); err != nil { + k.Logger(ctx).Error("failed to prune old stored attestation info", "pruneHeight", pruneHeight, "error", err) + return err + } + + // Prune epoch bitmaps + epochRange := collections.NewRange[uint64]().EndExclusive(pruneBeforeEpoch) + if err := k.EpochBitmap.Clear(ctx, epochRange); err != nil { + k.Logger(ctx).Error("failed to prune old epoch bitmaps", "pruneBeforeEpoch", pruneBeforeEpoch, "error", err) + return err + } + + // TODO: Consider pruning signatures associated with pruned heights. + // This would involve iterating k.Signatures and removing entries where height < pruneHeight. + + k.Logger(ctx).Info("Pruned old bitmaps and attestation info", "prunedBeforeEpoch", pruneBeforeEpoch, "prunedBeforeHeight", pruneHeight) + return nil +} + +// SetSignature stores the vote signature for a given height and validator +func (k Keeper) SetSignature(ctx sdk.Context, height int64, validatorAddr string, signature []byte) error { + return k.Signatures.Set(ctx, collections.Join(height, validatorAddr), signature) +} + +// GetSignature retrieves the vote signature for a given height and validator +func (k Keeper) GetSignature(ctx sdk.Context, height int64, validatorAddr string) ([]byte, error) { + return k.Signatures.Get(ctx, collections.Join(height, validatorAddr)) +} + +// HasSignature checks if a signature exists for a given height and validator +func (k Keeper) HasSignature(ctx sdk.Context, height int64, validatorAddr string) (bool, error) { + return k.Signatures.Has(ctx, collections.Join(height, validatorAddr)) +} diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go new file mode 100644 index 00000000..ad334333 --- /dev/null +++ b/modules/network/keeper/msg_server.go @@ -0,0 +1,177 @@ +package keeper + +import ( + "context" + + "cosmossdk.io/errors" + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +func NewMsgServerImpl(keeper Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} + +// Attest handles MsgAttest +func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.MsgAttestResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if !k.IsCheckpointHeight(ctx, msg.Height) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "height %d is not a checkpoint", msg.Height) + } + + if !k.IsInAttesterSet(ctx, msg.Validator) { + return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "validator %s not in attester set", msg.Validator) + } + + index, found := k.GetValidatorIndex(ctx, msg.Validator) + if !found { + return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator index not found for %s", msg.Validator) + } + + bitmap := k.GetAttestationBitmap(ctx, msg.Height) + if bitmap == nil { + validators := k.stakingKeeper.GetLastValidators(ctx) + numValidators := 0 + for _, v := range validators { + if v.IsBonded() { + numValidators++ + } + } + bitmap = k.bitmapHelper.NewBitmap(numValidators) + } + + if k.bitmapHelper.IsSet(bitmap, int(index)) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator %s already attested for height %d", msg.Validator, msg.Height) + } + + // TODO: Verify the vote signature here once we implement vote parsing + + // Set the bit + k.bitmapHelper.SetBit(bitmap, int(index)) + if err := k.SetAttestationBitmap(ctx, msg.Height, bitmap); err != nil { + return nil, errors.Wrap(err, "failed to set attestation bitmap") + } + + // Store signature using the new collection method + if err := k.SetSignature(ctx, msg.Height, msg.Validator, msg.Vote); err != nil { + return nil, errors.Wrap(err, "failed to store signature") + } + + epoch := k.GetCurrentEpoch(ctx) + epochBitmap := k.GetEpochBitmap(ctx, epoch) + if epochBitmap == nil { + validators := k.stakingKeeper.GetLastValidators(ctx) + numValidators := 0 + for _, v := range validators { + if v.IsBonded() { + numValidators++ + } + } + epochBitmap = k.bitmapHelper.NewBitmap(numValidators) + } + k.bitmapHelper.SetBit(epochBitmap, int(index)) + if err := k.SetEpochBitmap(ctx, epoch, epochBitmap); err != nil { + return nil, errors.Wrap(err, "failed to set epoch bitmap") + } + + // Emit event + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.TypeMsgAttest, + sdk.NewAttribute("validator", msg.Validator), + sdk.NewAttribute("height", math.NewInt(msg.Height).String()), + ), + ) + + return &types.MsgAttestResponse{}, nil +} + +// JoinAttesterSet handles MsgJoinAttesterSet +func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAttesterSet) (*types.MsgJoinAttesterSetResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + valAddr, err := sdk.ValAddressFromBech32(msg.Validator) + if err != nil { + return nil, errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address: %s", err) + } + + validator, found := k.stakingKeeper.GetValidator(ctx, valAddr) + if !found { + return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator not found: %s", msg.Validator) + } + + if !validator.IsBonded() { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator must be bonded to join attester set") + } + + if k.IsInAttesterSet(ctx, msg.Validator) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator already in attester set") + } + + k.SetAttesterSetMember(ctx, msg.Validator) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.TypeMsgJoinAttesterSet, + sdk.NewAttribute("validator", msg.Validator), + ), + ) + + return &types.MsgJoinAttesterSetResponse{}, nil +} + +// LeaveAttesterSet handles MsgLeaveAttesterSet +func (k msgServer) LeaveAttesterSet(goCtx context.Context, msg *types.MsgLeaveAttesterSet) (*types.MsgLeaveAttesterSetResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if !k.IsInAttesterSet(ctx, msg.Validator) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator not in attester set") + } + + k.RemoveAttesterSetMember(ctx, msg.Validator) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.TypeMsgLeaveAttesterSet, + sdk.NewAttribute("validator", msg.Validator), + ), + ) + + return &types.MsgLeaveAttesterSetResponse{}, nil +} + +// UpdateParams handles MsgUpdateParams +func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParams) (*types.MsgUpdateParamsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if k.GetAuthority() != msg.Authority { + return nil, errors.Wrapf(govtypes.ErrInvalidSigner, "invalid authority; expected %s, got %s", k.GetAuthority(), msg.Authority) + } + + if err := msg.Params.Validate(); err != nil { + return nil, err + } + + k.SetParams(ctx, msg.Params) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.TypeMsgUpdateParams, + sdk.NewAttribute("authority", msg.Authority), + ), + ) + + return &types.MsgUpdateParamsResponse{}, nil +} diff --git a/modules/network/module.go b/modules/network/module.go new file mode 100644 index 00000000..92c5f84a --- /dev/null +++ b/modules/network/module.go @@ -0,0 +1,213 @@ +package network + +import ( + "context" + "encoding/json" + "fmt" + + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/rollkit/go-execution-abci/modules/network/client/cli" + "github.com/rollkit/go-execution-abci/modules/network/keeper" + "github.com/rollkit/go-execution-abci/modules/network/types" + "math/rand" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleSimulation = AppModule{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the network module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// NewAppModuleBasic creates a new AppModuleBasic object +func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the network module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the network module's types on the LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the network module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the network module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// RegisterRESTRoutes registers the network module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { + // REST routes are deprecated +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) +} + +// GetTxCmd returns the network module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.GetTxCmd() +} + +// GetQueryCmd returns the network module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd(types.StoreKey) +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the network module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper +} + +// NewAppModule creates a new AppModule object +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + } +} + +// Name returns the network module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the network module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) +} + +// QuerierRoute returns the network module's query routing key. +func (AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// LegacyQuerierHandler returns the network module's Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers a gRPC query service to respond to the +// module-specific gRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// RegisterInvariants registers the network module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the network module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + cdc.MustUnmarshalJSON(gs, &genState) + InitGenesis(ctx, am.keeper, genState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the network module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion implements AppModule/ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 1 } + +// BeginBlock executes all ABCI BeginBlock logic respective to the network module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + am.keeper.BeginBlocker(ctx) +} + +// EndBlock executes all ABCI EndBlock logic respective to the network module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + am.keeper.EndBlocker(ctx) + return []abci.ValidatorUpdate{} +} + +// ---------------------------------------------------------------------------- +// AppModuleSimulation +// ---------------------------------------------------------------------------- + +// GenerateGenesisState creates a randomized GenState of the network module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + // TODO: Implement simulation +} + +// ProposalContents doesn't return any content functions for governance proposals. +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RandomizedParams creates randomized network param changes for the simulator. +func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { + // TODO: Implement simulation + return nil +} + +// RegisterStoreDecoder registers a decoder for network module's types +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { + // TODO: Implement simulation +} + +// WeightedOperations returns the all the network module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + // TODO: Implement simulation + return nil +} \ No newline at end of file diff --git a/modules/network/types/codec.go b/modules/network/types/codec.go new file mode 100644 index 00000000..91ba2fa8 --- /dev/null +++ b/modules/network/types/codec.go @@ -0,0 +1,38 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +// RegisterCodec registers the necessary types and interfaces with the codec +func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgAttest{}, "network/Attest", nil) + cdc.RegisterConcrete(&MsgJoinAttesterSet{}, "network/JoinAttesterSet", nil) + cdc.RegisterConcrete(&MsgLeaveAttesterSet{}, "network/LeaveAttesterSet", nil) + cdc.RegisterConcrete(&MsgUpdateParams{}, "network/UpdateParams", nil) +} + +// RegisterInterfaces registers the module interface types +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgAttest{}, + &MsgJoinAttesterSet{}, + &MsgLeaveAttesterSet{}, + &MsgUpdateParams{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) + +func init() { + RegisterCodec(Amino) + Amino.Seal() +} \ No newline at end of file diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go new file mode 100644 index 00000000..c1a99579 --- /dev/null +++ b/modules/network/types/expected_keepers.go @@ -0,0 +1,25 @@ +package types + +import ( + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// StakingKeeper defines the expected staking keeper interface +type StakingKeeper interface { + GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) + GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) + GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) + GetLastTotalPower(ctx sdk.Context) math.Int +} + +// AccountKeeper defines the expected account keeper interface +type AccountKeeper interface { + GetAccount(ctx sdk.Context, addr sdk.AccAddress) sdk.AccountI +} + +// BankKeeper defines the expected bank keeper interface +type BankKeeper interface { + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins +} diff --git a/modules/network/types/genesis.go b/modules/network/types/genesis.go new file mode 100644 index 00000000..1993af4a --- /dev/null +++ b/modules/network/types/genesis.go @@ -0,0 +1,48 @@ +package types + +import ( + "fmt" +) + +// DefaultGenesisState returns the default genesis state +func DefaultGenesisState() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + ValidatorIndices: []ValidatorIndex{}, + AttestationBitmaps: []AttestationBitmap{}, + } +} + +// Validate performs basic genesis state validation +func (gs GenesisState) Validate() error { + if err := gs.Params.Validate(); err != nil { + return fmt.Errorf("invalid params: %w", err) + } + + // Check for duplicate validator indices + indexMap := make(map[string]bool) + usedIndices := make(map[uint32]bool) + + for _, vi := range gs.ValidatorIndices { + if indexMap[vi.Address] { + return fmt.Errorf("duplicate validator address: %s", vi.Address) + } + if usedIndices[vi.Index] { + return fmt.Errorf("duplicate index: %d", vi.Index) + } + indexMap[vi.Address] = true + usedIndices[vi.Index] = true + } + + // Validate attestation bitmaps + for _, ab := range gs.AttestationBitmaps { + if ab.Height <= 0 { + return fmt.Errorf("invalid attestation height: %d", ab.Height) + } + if ab.VotedPower > ab.TotalPower { + return fmt.Errorf("voted power exceeds total power at height %d", ab.Height) + } + } + + return nil +} \ No newline at end of file diff --git a/modules/network/types/genesis.pb.go b/modules/network/types/genesis.pb.go new file mode 100644 index 00000000..1de93571 --- /dev/null +++ b/modules/network/types/genesis.pb.go @@ -0,0 +1,457 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState defines the network module's genesis state. +type GenesisState struct { + // params defines the module parameters at genesis + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + // validator_indices contains the initial validator index mappings + ValidatorIndices []ValidatorIndex `protobuf:"bytes,2,rep,name=validator_indices,json=validatorIndices,proto3" json:"validator_indices"` + // attestation_bitmaps contains historical attestation data + AttestationBitmaps []AttestationBitmap `protobuf:"bytes,3,rep,name=attestation_bitmaps,json=attestationBitmaps,proto3" json:"attestation_bitmaps"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_4576a54d81982ba5, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetValidatorIndices() []ValidatorIndex { + if m != nil { + return m.ValidatorIndices + } + return nil +} + +func (m *GenesisState) GetAttestationBitmaps() []AttestationBitmap { + if m != nil { + return m.AttestationBitmaps + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "rollkitsdk.network.v1.GenesisState") +} + +func init() { + proto.RegisterFile("rollkitsdk/network/v1/genesis.proto", fileDescriptor_4576a54d81982ba5) +} + +var fileDescriptor_4576a54d81982ba5 = []byte{ + // 308 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0x3f, 0x4b, 0xfb, 0x40, + 0x1c, 0xc6, 0x93, 0xf6, 0x47, 0x87, 0xf4, 0x37, 0x68, 0x54, 0x28, 0x05, 0xcf, 0xaa, 0x08, 0x59, + 0x7a, 0x47, 0xeb, 0xa6, 0x93, 0x59, 0xc4, 0x4d, 0x54, 0x44, 0x5c, 0xc2, 0x25, 0x39, 0xe2, 0x91, + 0x3f, 0x17, 0x72, 0xdf, 0xc4, 0xfa, 0x06, 0x9c, 0x7d, 0x59, 0x1d, 0x3b, 0x3a, 0x89, 0x24, 0x6f, + 0x44, 0x72, 0x3d, 0xad, 0x48, 0xbb, 0x1d, 0xf7, 0xfd, 0x3c, 0x9f, 0x07, 0x1e, 0xeb, 0xb8, 0x10, + 0x49, 0x12, 0x73, 0x90, 0x61, 0x4c, 0x32, 0x06, 0xcf, 0xa2, 0x88, 0x49, 0x35, 0x21, 0x11, 0xcb, + 0x98, 0xe4, 0x12, 0xe7, 0x85, 0x00, 0x61, 0xef, 0xad, 0x20, 0xac, 0x21, 0x5c, 0x4d, 0x86, 0xbb, + 0x91, 0x88, 0x84, 0x22, 0x48, 0xfb, 0x5a, 0xc2, 0xc3, 0xc3, 0xf5, 0x46, 0x78, 0xc9, 0x99, 0xf6, + 0x1d, 0xbd, 0x76, 0xac, 0xff, 0x97, 0xcb, 0x86, 0x5b, 0xa0, 0xc0, 0xec, 0x73, 0xab, 0x97, 0xd3, + 0x82, 0xa6, 0x72, 0x60, 0x8e, 0x4c, 0xa7, 0x3f, 0xdd, 0xc7, 0x6b, 0x1b, 0xf1, 0xb5, 0x82, 0xdc, + 0x7f, 0xf3, 0x8f, 0x03, 0xe3, 0x46, 0x47, 0xec, 0x07, 0x6b, 0xbb, 0xa2, 0x09, 0x0f, 0x29, 0x88, + 0xc2, 0xe3, 0x59, 0xc8, 0x03, 0x26, 0x07, 0x9d, 0x51, 0xd7, 0xe9, 0x4f, 0x4f, 0x36, 0x78, 0xee, + 0xbf, 0xf9, 0xab, 0x2c, 0x64, 0x33, 0xed, 0xdb, 0xaa, 0x7e, 0xfd, 0xb6, 0x12, 0xdb, 0xb3, 0x76, + 0x28, 0x00, 0x93, 0x40, 0x81, 0x8b, 0xcc, 0xf3, 0x39, 0xa4, 0x34, 0x97, 0x83, 0xae, 0x72, 0x3b, + 0x1b, 0xdc, 0x17, 0xab, 0x84, 0xab, 0x02, 0x5a, 0x6f, 0xd3, 0xbf, 0x07, 0xe9, 0xde, 0xcd, 0x6b, + 0x64, 0x2e, 0x6a, 0x64, 0x7e, 0xd6, 0xc8, 0x7c, 0x6b, 0x90, 0xb1, 0x68, 0x90, 0xf1, 0xde, 0x20, + 0xe3, 0xf1, 0x2c, 0xe2, 0xf0, 0x54, 0xfa, 0x38, 0x10, 0x29, 0xd1, 0x3d, 0x24, 0x12, 0x63, 0x36, + 0x63, 0x41, 0xd9, 0x1a, 0xc6, 0xd4, 0x0f, 0x38, 0x49, 0x45, 0x58, 0x26, 0x4c, 0xfe, 0xec, 0xac, + 0x46, 0xf6, 0x7b, 0x6a, 0xe5, 0xd3, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc8, 0x54, 0xfb, 0xbf, + 0xdc, 0x01, 0x00, 0x00, +} + +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AttestationBitmaps) > 0 { + for iNdEx := len(m.AttestationBitmaps) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AttestationBitmaps[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.ValidatorIndices) > 0 { + for iNdEx := len(m.ValidatorIndices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ValidatorIndices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.ValidatorIndices) > 0 { + for _, e := range m.ValidatorIndices { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.AttestationBitmaps) > 0 { + for _, e := range m.AttestationBitmaps { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ValidatorIndices", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ValidatorIndices = append(m.ValidatorIndices, ValidatorIndex{}) + if err := m.ValidatorIndices[len(m.ValidatorIndices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AttestationBitmaps", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AttestationBitmaps = append(m.AttestationBitmaps, AttestationBitmap{}) + if err := m.AttestationBitmaps[len(m.AttestationBitmaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/network/types/keys.go b/modules/network/types/keys.go new file mode 100644 index 00000000..7b008645 --- /dev/null +++ b/modules/network/types/keys.go @@ -0,0 +1,71 @@ +package types + +import ( + "encoding/binary" + + "cosmossdk.io/collections" +) + +const ( + // ModuleName defines the module name + ModuleName = "network" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey defines the module's message routing key + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName +) + +// KVStore key prefixes +var ( + // Prefixes for collections + ValidatorIndexPrefix = collections.NewPrefix("validator_index") + ValidatorPowerPrefix = collections.NewPrefix("validator_power") + AttestationBitmapPrefix = collections.NewPrefix("attestation_bitmap") + EpochBitmapPrefix = collections.NewPrefix("epoch_bitmap") + AttesterSetPrefix = collections.NewPrefix("attester_set") + SignaturePrefix = collections.NewPrefix("signature") + StoredAttestationInfoPrefix = collections.NewPrefix("stored_attestation_info") +) + +// GetValidatorIndexKey returns the key for validator index mapping +func GetValidatorIndexKey(addr string) []byte { + return append(ValidatorIndexPrefix, []byte(addr)...) +} + +// GetValidatorPowerKey returns the key for validator power by index +func GetValidatorPowerKey(index uint16) []byte { + bz := make([]byte, 2) + binary.BigEndian.PutUint16(bz, index) + return append(ValidatorPowerPrefix, bz...) +} + +// GetAttestationKey returns the key for attestation bitmap at height +func GetAttestationKey(height int64) []byte { + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, uint64(height)) + return append(AttestationBitmapPrefix, bz...) +} + +// GetSignatureKey returns the key for validator signature at height +func GetSignatureKey(height int64, addr string) []byte { + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, uint64(height)) + return append(append(SignaturePrefix, bz...), []byte(addr)...) +} + +// GetEpochBitmapKey returns the key for epoch participation bitmap +func GetEpochBitmapKey(epoch uint64) []byte { + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, epoch) + return append(EpochBitmapPrefix, bz...) +} + +// GetAttesterSetKey returns the key for attester set membership +func GetAttesterSetKey(addr string) []byte { + return append(AttesterSetPrefix, []byte(addr)...) +} diff --git a/modules/network/types/msgs.go b/modules/network/types/msgs.go new file mode 100644 index 00000000..cb90200a --- /dev/null +++ b/modules/network/types/msgs.go @@ -0,0 +1,196 @@ +package types + +import ( + "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgAttest = "attest" +const TypeMsgJoinAttesterSet = "join_attester_set" +const TypeMsgLeaveAttesterSet = "leave_attester_set" +const TypeMsgUpdateParams = "update_params" + +var _ sdk.Msg = &MsgAttest{} +var _ sdk.Msg = &MsgJoinAttesterSet{} +var _ sdk.Msg = &MsgLeaveAttesterSet{} +var _ sdk.Msg = &MsgUpdateParams{} + +// NewMsgAttest creates a new MsgAttest instance +func NewMsgAttest(validator string, height int64, vote []byte) *MsgAttest { + return &MsgAttest{ + Validator: validator, + Height: height, + Vote: vote, + } +} + +// Route returns the message route +func (msg *MsgAttest) Route() string { + return RouterKey +} + +// Type returns the message type +func (msg *MsgAttest) Type() string { + return TypeMsgAttest +} + +// GetSigners returns the expected signers +func (msg *MsgAttest) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +// GetSignBytes returns the bytes for signing +func (msg *MsgAttest) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic performs basic validation +func (msg *MsgAttest) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) + } + + if msg.Height <= 0 { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "height must be positive") + } + + if len(msg.Vote) == 0 { + return errors.Wrap(sdkerrors.ErrInvalidRequest, "vote cannot be empty") + } + + return nil +} + +// NewMsgJoinAttesterSet creates a new MsgJoinAttesterSet instance +func NewMsgJoinAttesterSet(validator string) *MsgJoinAttesterSet { + return &MsgJoinAttesterSet{ + Validator: validator, + } +} + +// Route returns the message route +func (msg *MsgJoinAttesterSet) Route() string { + return RouterKey +} + +// Type returns the message type +func (msg *MsgJoinAttesterSet) Type() string { + return TypeMsgJoinAttesterSet +} + +// GetSigners returns the expected signers +func (msg *MsgJoinAttesterSet) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +// GetSignBytes returns the bytes for signing +func (msg *MsgJoinAttesterSet) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic performs basic validation +func (msg *MsgJoinAttesterSet) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) + } + + return nil +} + +// NewMsgLeaveAttesterSet creates a new MsgLeaveAttesterSet instance +func NewMsgLeaveAttesterSet(validator string) *MsgLeaveAttesterSet { + return &MsgLeaveAttesterSet{ + Validator: validator, + } +} + +// Route returns the message route +func (msg *MsgLeaveAttesterSet) Route() string { + return RouterKey +} + +// Type returns the message type +func (msg *MsgLeaveAttesterSet) Type() string { + return TypeMsgLeaveAttesterSet +} + +// GetSigners returns the expected signers +func (msg *MsgLeaveAttesterSet) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +// GetSignBytes returns the bytes for signing +func (msg *MsgLeaveAttesterSet) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic performs basic validation +func (msg *MsgLeaveAttesterSet) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Validator) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) + } + + return nil +} + +// NewMsgUpdateParams creates a new MsgUpdateParams instance +func NewMsgUpdateParams(authority string, params Params) *MsgUpdateParams { + return &MsgUpdateParams{ + Authority: authority, + Params: params, + } +} + +// Route returns the message route +func (msg *MsgUpdateParams) Route() string { + return RouterKey +} + +// Type returns the message type +func (msg *MsgUpdateParams) Type() string { + return TypeMsgUpdateParams +} + +// GetSigners returns the expected signers +func (msg *MsgUpdateParams) GetSigners() []sdk.AccAddress { + addr, err := sdk.AccAddressFromBech32(msg.Authority) + if err != nil { + panic(err) + } + return []sdk.AccAddress{addr} +} + +// GetSignBytes returns the bytes for signing +func (msg *MsgUpdateParams) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// ValidateBasic performs basic validation +func (msg *MsgUpdateParams) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Authority) + if err != nil { + return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid authority address (%s)", err) + } + + return msg.Params.Validate() +} diff --git a/modules/network/types/params.go b/modules/network/types/params.go new file mode 100644 index 00000000..6d1bc183 --- /dev/null +++ b/modules/network/types/params.go @@ -0,0 +1,186 @@ +package types + +import ( + "fmt" + + "cosmossdk.io/math" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" +) + +var ( + KeyEpochLength = []byte("EpochLength") + KeyQuorumFraction = []byte("QuorumFraction") + KeyMinParticipation = []byte("MinParticipation") + KeyPruneAfter = []byte("PruneAfter") + KeyEmergencyMode = []byte("EmergencyMode") + KeySignMode = []byte("SignMode") +) + +// Default parameter values +var ( + DefaultEpochLength = uint64(100) + DefaultQuorumFraction = math.LegacyNewDecWithPrec(667, 3) // 2/3 + DefaultMinParticipation = math.LegacyNewDecWithPrec(5, 1) // 1/2 + DefaultPruneAfter = uint64(7) + DefaultEmergencyMode = false + DefaultSignMode = SignMode_SIGN_MODE_CHECKPOINT +) + +// NewParams creates a new Params instance +func NewParams( + epochLength uint64, + quorumFraction math.LegacyDec, + minParticipation math.LegacyDec, + pruneAfter uint64, + emergencyMode bool, + signMode SignMode, +) Params { + return Params{ + EpochLength: epochLength, + QuorumFraction: quorumFraction.String(), + MinParticipation: minParticipation.String(), + PruneAfter: pruneAfter, + EmergencyMode: emergencyMode, + SignMode: signMode, + } +} + +// DefaultParams returns default parameters +func DefaultParams() Params { + return NewParams( + DefaultEpochLength, + DefaultQuorumFraction, + DefaultMinParticipation, + DefaultPruneAfter, + DefaultEmergencyMode, + DefaultSignMode, + ) +} + +// ParamSetPairs implements params.ParamSet +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyEpochLength, &p.EpochLength, validateEpochLength), + paramtypes.NewParamSetPair(KeyQuorumFraction, &p.QuorumFraction, validateQuorumFraction), + paramtypes.NewParamSetPair(KeyMinParticipation, &p.MinParticipation, validateMinParticipation), + paramtypes.NewParamSetPair(KeyPruneAfter, &p.PruneAfter, validatePruneAfter), + paramtypes.NewParamSetPair(KeyEmergencyMode, &p.EmergencyMode, validateEmergencyMode), + paramtypes.NewParamSetPair(KeySignMode, &p.SignMode, validateSignMode), + } +} + +// Validate validates the parameter set +func (p Params) Validate() error { + if err := validateEpochLength(p.EpochLength); err != nil { + return err + } + if err := validateQuorumFraction(p.QuorumFraction); err != nil { + return err + } + if err := validateMinParticipation(p.MinParticipation); err != nil { + return err + } + if err := validatePruneAfter(p.PruneAfter); err != nil { + return err + } + if err := validateEmergencyMode(p.EmergencyMode); err != nil { + return err + } + if err := validateSignMode(p.SignMode); err != nil { + return err + } + return nil +} + +func validateEpochLength(i interface{}) error { + v, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v == 0 { + return fmt.Errorf("epoch length must be positive: %d", v) + } + + return nil +} + +func validateQuorumFraction(i interface{}) error { + v, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + dec, err := math.LegacyNewDecFromStr(v) + if err != nil { + return fmt.Errorf("invalid decimal string: %w", err) + } + + if dec.LTE(math.LegacyZeroDec()) || dec.GT(math.LegacyOneDec()) { + return fmt.Errorf("quorum fraction must be between 0 and 1: %s", v) + } + + return nil +} + +func validateMinParticipation(i interface{}) error { + v, ok := i.(string) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + dec, err := math.LegacyNewDecFromStr(v) + if err != nil { + return fmt.Errorf("invalid decimal string: %w", err) + } + + if dec.LTE(math.LegacyZeroDec()) || dec.GT(math.LegacyOneDec()) { + return fmt.Errorf("min participation must be between 0 and 1: %s", v) + } + + return nil +} + +func validatePruneAfter(i interface{}) error { + v, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v == 0 { + return fmt.Errorf("prune after must be positive: %d", v) + } + + return nil +} + +func validateEmergencyMode(i interface{}) error { + _, ok := i.(bool) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} + +func validateSignMode(i interface{}) error { + v, ok := i.(SignMode) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v == SignMode_SIGN_MODE_UNSPECIFIED { + return fmt.Errorf("sign mode cannot be unspecified") + } + + if v < SignMode_SIGN_MODE_CHECKPOINT || v > SignMode_SIGN_MODE_IBC_ONLY { + return fmt.Errorf("invalid sign mode: %d", v) + } + + return nil +} + +// ParamKeyTable returns the parameter key table +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} diff --git a/modules/network/types/query.pb.go b/modules/network/types/query.pb.go new file mode 100644 index 00000000..0428c662 --- /dev/null +++ b/modules/network/types/query.pb.go @@ -0,0 +1,2349 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryParamsRequest is the request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is the response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params holds all the parameters of this module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +// QueryAttestationBitmapRequest is the request type for the Query/AttestationBitmap RPC method. +type QueryAttestationBitmapRequest struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *QueryAttestationBitmapRequest) Reset() { *m = QueryAttestationBitmapRequest{} } +func (m *QueryAttestationBitmapRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAttestationBitmapRequest) ProtoMessage() {} +func (*QueryAttestationBitmapRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{2} +} +func (m *QueryAttestationBitmapRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAttestationBitmapRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAttestationBitmapRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAttestationBitmapRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAttestationBitmapRequest.Merge(m, src) +} +func (m *QueryAttestationBitmapRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAttestationBitmapRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAttestationBitmapRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAttestationBitmapRequest proto.InternalMessageInfo + +func (m *QueryAttestationBitmapRequest) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +// QueryAttestationBitmapResponse is the response type for the Query/AttestationBitmap RPC method. +type QueryAttestationBitmapResponse struct { + Bitmap *AttestationBitmap `protobuf:"bytes,1,opt,name=bitmap,proto3" json:"bitmap,omitempty"` +} + +func (m *QueryAttestationBitmapResponse) Reset() { *m = QueryAttestationBitmapResponse{} } +func (m *QueryAttestationBitmapResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAttestationBitmapResponse) ProtoMessage() {} +func (*QueryAttestationBitmapResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{3} +} +func (m *QueryAttestationBitmapResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAttestationBitmapResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAttestationBitmapResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryAttestationBitmapResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAttestationBitmapResponse.Merge(m, src) +} +func (m *QueryAttestationBitmapResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAttestationBitmapResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAttestationBitmapResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAttestationBitmapResponse proto.InternalMessageInfo + +func (m *QueryAttestationBitmapResponse) GetBitmap() *AttestationBitmap { + if m != nil { + return m.Bitmap + } + return nil +} + +// QueryEpochInfoRequest is the request type for the Query/EpochInfo RPC method. +type QueryEpochInfoRequest struct { + Epoch uint64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch,omitempty"` +} + +func (m *QueryEpochInfoRequest) Reset() { *m = QueryEpochInfoRequest{} } +func (m *QueryEpochInfoRequest) String() string { return proto.CompactTextString(m) } +func (*QueryEpochInfoRequest) ProtoMessage() {} +func (*QueryEpochInfoRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{4} +} +func (m *QueryEpochInfoRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryEpochInfoRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryEpochInfoRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryEpochInfoRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEpochInfoRequest.Merge(m, src) +} +func (m *QueryEpochInfoRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryEpochInfoRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEpochInfoRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryEpochInfoRequest proto.InternalMessageInfo + +func (m *QueryEpochInfoRequest) GetEpoch() uint64 { + if m != nil { + return m.Epoch + } + return 0 +} + +// QueryEpochInfoResponse is the response type for the Query/EpochInfo RPC method. +type QueryEpochInfoResponse struct { + Epoch uint64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch,omitempty"` + StartHeight int64 `protobuf:"varint,2,opt,name=start_height,json=startHeight,proto3" json:"start_height,omitempty"` + EndHeight int64 `protobuf:"varint,3,opt,name=end_height,json=endHeight,proto3" json:"end_height,omitempty"` + ParticipationBitmap []byte `protobuf:"bytes,4,opt,name=participation_bitmap,json=participationBitmap,proto3" json:"participation_bitmap,omitempty"` + ActiveValidators uint64 `protobuf:"varint,5,opt,name=active_validators,json=activeValidators,proto3" json:"active_validators,omitempty"` + ParticipatingValidators uint64 `protobuf:"varint,6,opt,name=participating_validators,json=participatingValidators,proto3" json:"participating_validators,omitempty"` +} + +func (m *QueryEpochInfoResponse) Reset() { *m = QueryEpochInfoResponse{} } +func (m *QueryEpochInfoResponse) String() string { return proto.CompactTextString(m) } +func (*QueryEpochInfoResponse) ProtoMessage() {} +func (*QueryEpochInfoResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{5} +} +func (m *QueryEpochInfoResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryEpochInfoResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryEpochInfoResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryEpochInfoResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryEpochInfoResponse.Merge(m, src) +} +func (m *QueryEpochInfoResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryEpochInfoResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryEpochInfoResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryEpochInfoResponse proto.InternalMessageInfo + +func (m *QueryEpochInfoResponse) GetEpoch() uint64 { + if m != nil { + return m.Epoch + } + return 0 +} + +func (m *QueryEpochInfoResponse) GetStartHeight() int64 { + if m != nil { + return m.StartHeight + } + return 0 +} + +func (m *QueryEpochInfoResponse) GetEndHeight() int64 { + if m != nil { + return m.EndHeight + } + return 0 +} + +func (m *QueryEpochInfoResponse) GetParticipationBitmap() []byte { + if m != nil { + return m.ParticipationBitmap + } + return nil +} + +func (m *QueryEpochInfoResponse) GetActiveValidators() uint64 { + if m != nil { + return m.ActiveValidators + } + return 0 +} + +func (m *QueryEpochInfoResponse) GetParticipatingValidators() uint64 { + if m != nil { + return m.ParticipatingValidators + } + return 0 +} + +// QueryValidatorIndexRequest is the request type for the Query/ValidatorIndex RPC method. +type QueryValidatorIndexRequest struct { + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` +} + +func (m *QueryValidatorIndexRequest) Reset() { *m = QueryValidatorIndexRequest{} } +func (m *QueryValidatorIndexRequest) String() string { return proto.CompactTextString(m) } +func (*QueryValidatorIndexRequest) ProtoMessage() {} +func (*QueryValidatorIndexRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{6} +} +func (m *QueryValidatorIndexRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryValidatorIndexRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryValidatorIndexRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryValidatorIndexRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryValidatorIndexRequest.Merge(m, src) +} +func (m *QueryValidatorIndexRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryValidatorIndexRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryValidatorIndexRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryValidatorIndexRequest proto.InternalMessageInfo + +func (m *QueryValidatorIndexRequest) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +// QueryValidatorIndexResponse is the response type for the Query/ValidatorIndex RPC method. +type QueryValidatorIndexResponse struct { + Index *ValidatorIndex `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` +} + +func (m *QueryValidatorIndexResponse) Reset() { *m = QueryValidatorIndexResponse{} } +func (m *QueryValidatorIndexResponse) String() string { return proto.CompactTextString(m) } +func (*QueryValidatorIndexResponse) ProtoMessage() {} +func (*QueryValidatorIndexResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{7} +} +func (m *QueryValidatorIndexResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryValidatorIndexResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryValidatorIndexResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryValidatorIndexResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryValidatorIndexResponse.Merge(m, src) +} +func (m *QueryValidatorIndexResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryValidatorIndexResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryValidatorIndexResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryValidatorIndexResponse proto.InternalMessageInfo + +func (m *QueryValidatorIndexResponse) GetIndex() *ValidatorIndex { + if m != nil { + return m.Index + } + return nil +} + +// QuerySoftConfirmationStatusRequest is the request type for the Query/SoftConfirmationStatus RPC method. +type QuerySoftConfirmationStatusRequest struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *QuerySoftConfirmationStatusRequest) Reset() { *m = QuerySoftConfirmationStatusRequest{} } +func (m *QuerySoftConfirmationStatusRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySoftConfirmationStatusRequest) ProtoMessage() {} +func (*QuerySoftConfirmationStatusRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{8} +} +func (m *QuerySoftConfirmationStatusRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySoftConfirmationStatusRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySoftConfirmationStatusRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySoftConfirmationStatusRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySoftConfirmationStatusRequest.Merge(m, src) +} +func (m *QuerySoftConfirmationStatusRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySoftConfirmationStatusRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySoftConfirmationStatusRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySoftConfirmationStatusRequest proto.InternalMessageInfo + +func (m *QuerySoftConfirmationStatusRequest) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +// QuerySoftConfirmationStatusResponse is the response type for the Query/SoftConfirmationStatus RPC method. +type QuerySoftConfirmationStatusResponse struct { + IsSoftConfirmed bool `protobuf:"varint,1,opt,name=is_soft_confirmed,json=isSoftConfirmed,proto3" json:"is_soft_confirmed,omitempty"` + VotedPower uint64 `protobuf:"varint,2,opt,name=voted_power,json=votedPower,proto3" json:"voted_power,omitempty"` + TotalPower uint64 `protobuf:"varint,3,opt,name=total_power,json=totalPower,proto3" json:"total_power,omitempty"` + QuorumFraction string `protobuf:"bytes,4,opt,name=quorum_fraction,json=quorumFraction,proto3" json:"quorum_fraction,omitempty"` +} + +func (m *QuerySoftConfirmationStatusResponse) Reset() { *m = QuerySoftConfirmationStatusResponse{} } +func (m *QuerySoftConfirmationStatusResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySoftConfirmationStatusResponse) ProtoMessage() {} +func (*QuerySoftConfirmationStatusResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_bae17cb7b1e48f90, []int{9} +} +func (m *QuerySoftConfirmationStatusResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySoftConfirmationStatusResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySoftConfirmationStatusResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySoftConfirmationStatusResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySoftConfirmationStatusResponse.Merge(m, src) +} +func (m *QuerySoftConfirmationStatusResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySoftConfirmationStatusResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySoftConfirmationStatusResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySoftConfirmationStatusResponse proto.InternalMessageInfo + +func (m *QuerySoftConfirmationStatusResponse) GetIsSoftConfirmed() bool { + if m != nil { + return m.IsSoftConfirmed + } + return false +} + +func (m *QuerySoftConfirmationStatusResponse) GetVotedPower() uint64 { + if m != nil { + return m.VotedPower + } + return 0 +} + +func (m *QuerySoftConfirmationStatusResponse) GetTotalPower() uint64 { + if m != nil { + return m.TotalPower + } + return 0 +} + +func (m *QuerySoftConfirmationStatusResponse) GetQuorumFraction() string { + if m != nil { + return m.QuorumFraction + } + return "" +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "rollkitsdk.network.v1.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "rollkitsdk.network.v1.QueryParamsResponse") + proto.RegisterType((*QueryAttestationBitmapRequest)(nil), "rollkitsdk.network.v1.QueryAttestationBitmapRequest") + proto.RegisterType((*QueryAttestationBitmapResponse)(nil), "rollkitsdk.network.v1.QueryAttestationBitmapResponse") + proto.RegisterType((*QueryEpochInfoRequest)(nil), "rollkitsdk.network.v1.QueryEpochInfoRequest") + proto.RegisterType((*QueryEpochInfoResponse)(nil), "rollkitsdk.network.v1.QueryEpochInfoResponse") + proto.RegisterType((*QueryValidatorIndexRequest)(nil), "rollkitsdk.network.v1.QueryValidatorIndexRequest") + proto.RegisterType((*QueryValidatorIndexResponse)(nil), "rollkitsdk.network.v1.QueryValidatorIndexResponse") + proto.RegisterType((*QuerySoftConfirmationStatusRequest)(nil), "rollkitsdk.network.v1.QuerySoftConfirmationStatusRequest") + proto.RegisterType((*QuerySoftConfirmationStatusResponse)(nil), "rollkitsdk.network.v1.QuerySoftConfirmationStatusResponse") +} + +func init() { proto.RegisterFile("rollkitsdk/network/v1/query.proto", fileDescriptor_bae17cb7b1e48f90) } + +var fileDescriptor_bae17cb7b1e48f90 = []byte{ + // 831 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x55, 0x41, 0x6f, 0x1b, 0x45, + 0x14, 0xf6, 0x26, 0xb6, 0xc1, 0x2f, 0x55, 0x4b, 0xa6, 0x6e, 0xb0, 0x96, 0xc6, 0x6d, 0xb6, 0x42, + 0x75, 0x0c, 0xf6, 0xd6, 0x01, 0x8a, 0x5a, 0x38, 0x40, 0x10, 0x88, 0xde, 0xca, 0x16, 0x71, 0xe8, + 0xc5, 0x1a, 0xef, 0x8e, 0xd7, 0xa3, 0xd8, 0x3b, 0x9b, 0x9d, 0x59, 0xb7, 0x55, 0x94, 0x0b, 0x1c, + 0xb9, 0x20, 0xf5, 0x4f, 0x70, 0xe6, 0xcc, 0x9d, 0x5e, 0x90, 0x2a, 0x71, 0xe1, 0x84, 0x50, 0xc2, + 0x0f, 0x41, 0xfb, 0x66, 0xbc, 0xb1, 0x93, 0xb5, 0x69, 0x39, 0xd9, 0xf3, 0xcd, 0xf7, 0xbd, 0xf7, + 0xbd, 0x99, 0xf7, 0x66, 0x61, 0x27, 0x11, 0xe3, 0xf1, 0x01, 0x57, 0x32, 0x38, 0x70, 0x23, 0xa6, + 0x9e, 0x88, 0xe4, 0xc0, 0x9d, 0xf6, 0xdc, 0xc3, 0x94, 0x25, 0xcf, 0xba, 0x71, 0x22, 0x94, 0x20, + 0xd7, 0xce, 0x28, 0x5d, 0x43, 0xe9, 0x4e, 0x7b, 0x76, 0x3d, 0x14, 0xa1, 0x40, 0x86, 0x9b, 0xfd, + 0xd3, 0x64, 0xfb, 0x7a, 0x28, 0x44, 0x38, 0x66, 0x2e, 0x8d, 0xb9, 0x4b, 0xa3, 0x48, 0x28, 0xaa, + 0xb8, 0x88, 0xa4, 0xd9, 0x6d, 0xfb, 0x42, 0x4e, 0x84, 0x74, 0x07, 0x54, 0x32, 0x9d, 0xc3, 0x9d, + 0xf6, 0x06, 0x4c, 0xd1, 0x9e, 0x1b, 0xd3, 0x90, 0x47, 0x48, 0x36, 0xdc, 0x25, 0xce, 0xd4, 0xb3, + 0x98, 0x99, 0x70, 0x4e, 0x1d, 0xc8, 0x37, 0x59, 0x90, 0x87, 0x34, 0xa1, 0x13, 0xe9, 0xb1, 0xc3, + 0x94, 0x49, 0xe5, 0x78, 0x70, 0x75, 0x01, 0x95, 0xb1, 0x88, 0x24, 0x23, 0x9f, 0x40, 0x35, 0x46, + 0xa4, 0x61, 0xdd, 0xb4, 0x5a, 0x1b, 0x7b, 0xdb, 0xdd, 0xc2, 0xba, 0xba, 0x5a, 0xb6, 0x5f, 0x7e, + 0xf1, 0xd7, 0x8d, 0x92, 0x67, 0x24, 0xce, 0xc7, 0xb0, 0x8d, 0x31, 0x3f, 0x57, 0x8a, 0x49, 0x5d, + 0xd3, 0x3e, 0x57, 0x13, 0x1a, 0x9b, 0xa4, 0x64, 0x0b, 0xaa, 0x23, 0xc6, 0xc3, 0x91, 0xc2, 0xe8, + 0xeb, 0x9e, 0x59, 0x39, 0x03, 0x68, 0x2e, 0x13, 0x1a, 0x5f, 0x9f, 0x41, 0x75, 0x80, 0x88, 0xf1, + 0xd5, 0x5a, 0xe2, 0xeb, 0x62, 0x04, 0xa3, 0x73, 0x3a, 0x70, 0x0d, 0x73, 0x7c, 0x19, 0x0b, 0x7f, + 0xf4, 0x20, 0x1a, 0x8a, 0x99, 0xa9, 0x3a, 0x54, 0x58, 0x86, 0x61, 0xe4, 0xb2, 0xa7, 0x17, 0xce, + 0x8f, 0x6b, 0xb0, 0x75, 0x9e, 0x6f, 0xbc, 0x14, 0x0a, 0xc8, 0x0e, 0x5c, 0x92, 0x8a, 0x26, 0xaa, + 0x6f, 0x2a, 0x5c, 0xc3, 0x0a, 0x37, 0x10, 0xfb, 0x1a, 0x21, 0xb2, 0x0d, 0xc0, 0xa2, 0x60, 0x46, + 0x58, 0x47, 0x42, 0x8d, 0x45, 0x81, 0xd9, 0xee, 0x41, 0x3d, 0xa6, 0x89, 0xe2, 0x3e, 0x8f, 0xb1, + 0x80, 0xbe, 0xa9, 0xb8, 0x7c, 0xd3, 0x6a, 0x5d, 0xf2, 0xae, 0x2e, 0xec, 0xe9, 0xe2, 0xc8, 0x7b, + 0xb0, 0x49, 0x7d, 0xc5, 0xa7, 0xac, 0x3f, 0xa5, 0x63, 0x1e, 0x50, 0x25, 0x12, 0xd9, 0xa8, 0xa0, + 0xad, 0xb7, 0xf4, 0xc6, 0x77, 0x39, 0x4e, 0xee, 0x41, 0x63, 0x2e, 0x46, 0x14, 0xce, 0x6b, 0xaa, + 0xa8, 0x79, 0x7b, 0x61, 0xff, 0x4c, 0xea, 0xdc, 0x05, 0x1b, 0x0f, 0x23, 0x87, 0x1e, 0x44, 0x01, + 0x7b, 0x3a, 0x3b, 0xc1, 0x06, 0xbc, 0x41, 0x83, 0x20, 0x61, 0x52, 0x77, 0x4d, 0xcd, 0x9b, 0x2d, + 0x9d, 0xc7, 0xf0, 0x4e, 0xa1, 0x2e, 0xef, 0xb6, 0x0a, 0xcf, 0x00, 0x73, 0xa9, 0xef, 0x2e, 0xb9, + 0xd4, 0x73, 0x6a, 0xad, 0x71, 0x3e, 0x05, 0x07, 0x63, 0x3f, 0x12, 0x43, 0xf5, 0x85, 0x88, 0x86, + 0x3c, 0x99, 0xe0, 0xd1, 0x3c, 0x52, 0x54, 0xa5, 0xf2, 0xbf, 0x5a, 0xee, 0x57, 0x0b, 0x6e, 0xad, + 0x94, 0x1b, 0x8b, 0x6d, 0xd8, 0xe4, 0xb2, 0x2f, 0xc5, 0x50, 0xf5, 0x7d, 0xcd, 0x62, 0x01, 0x86, + 0x7a, 0xd3, 0xbb, 0xc2, 0xe5, 0x9c, 0x98, 0x05, 0xe4, 0x06, 0x6c, 0x4c, 0x85, 0x62, 0x41, 0x3f, + 0x16, 0x4f, 0x58, 0x82, 0x1d, 0x50, 0xf6, 0x00, 0xa1, 0x87, 0x19, 0x92, 0x11, 0x94, 0x50, 0x74, + 0x6c, 0x08, 0xeb, 0x9a, 0x80, 0x90, 0x26, 0xdc, 0x86, 0x2b, 0x87, 0xa9, 0x48, 0xd2, 0x49, 0x7f, + 0x98, 0x64, 0xf7, 0x27, 0x22, 0xbc, 0xfd, 0x9a, 0x77, 0x59, 0xc3, 0x5f, 0x19, 0x74, 0xef, 0xf7, + 0x2a, 0x54, 0xd0, 0x3e, 0xf9, 0xc1, 0x82, 0xaa, 0x9e, 0x46, 0xb2, 0xbb, 0xe4, 0xfc, 0x2e, 0x8e, + 0xbf, 0xdd, 0x7e, 0x15, 0xaa, 0x3e, 0x02, 0xc7, 0xf9, 0xfe, 0x8f, 0x7f, 0x9e, 0xaf, 0x5d, 0x27, + 0xb6, 0x6b, 0x34, 0xf3, 0x2f, 0x8d, 0x1e, 0x7d, 0xf2, 0x8b, 0x05, 0x9b, 0x17, 0x66, 0x8f, 0x7c, + 0xb8, 0x2a, 0xcb, 0xb2, 0x57, 0xc2, 0xfe, 0xe8, 0x35, 0x55, 0xc6, 0xe6, 0x1d, 0xb4, 0xd9, 0x26, + 0xad, 0x22, 0x9b, 0xf4, 0x4c, 0xe6, 0x1e, 0xe9, 0x16, 0x38, 0x26, 0xcf, 0x2d, 0xa8, 0xe5, 0xe3, + 0x4d, 0xde, 0x5f, 0x95, 0xf6, 0xfc, 0xab, 0x61, 0x77, 0x5e, 0x91, 0x6d, 0xcc, 0xed, 0xa2, 0xb9, + 0x5b, 0x64, 0xa7, 0xc8, 0x1c, 0x3e, 0x20, 0xee, 0x11, 0xfe, 0x1c, 0x93, 0x9f, 0x2d, 0xb8, 0xbc, + 0xd8, 0xf1, 0xa4, 0xb7, 0x2a, 0x59, 0xe1, 0x4c, 0xda, 0x7b, 0xaf, 0x23, 0x31, 0x26, 0x5d, 0x34, + 0xb9, 0x4b, 0x6e, 0x17, 0x99, 0xcc, 0x1f, 0x0b, 0xf7, 0xc8, 0x4c, 0xf7, 0x31, 0xf9, 0xcd, 0x82, + 0xad, 0xe2, 0xf9, 0x21, 0xf7, 0x56, 0xe5, 0x5f, 0x39, 0xb2, 0xf6, 0xfd, 0xff, 0x23, 0x35, 0x25, + 0xdc, 0xc5, 0x12, 0xee, 0x90, 0x6e, 0x51, 0x09, 0xd9, 0x14, 0x77, 0xfc, 0x39, 0x71, 0xde, 0x0a, + 0xfb, 0xdf, 0xbe, 0x38, 0x69, 0x5a, 0x2f, 0x4f, 0x9a, 0xd6, 0xdf, 0x27, 0x4d, 0xeb, 0xa7, 0xd3, + 0x66, 0xe9, 0xe5, 0x69, 0xb3, 0xf4, 0xe7, 0x69, 0xb3, 0xf4, 0xf8, 0x7e, 0xc8, 0xd5, 0x28, 0x1d, + 0x74, 0x7d, 0x31, 0xc9, 0x63, 0x86, 0xa2, 0xc3, 0x9e, 0x32, 0x3f, 0xcd, 0x62, 0x74, 0xe8, 0xc0, + 0xe7, 0xee, 0x44, 0x04, 0xe9, 0x98, 0xc9, 0x3c, 0x1b, 0x7e, 0x80, 0x07, 0x55, 0xfc, 0x02, 0x7f, + 0xf0, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe2, 0x10, 0xc6, 0x5b, 0x40, 0x08, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Params queries the module parameters + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // AttestationBitmap queries the attestation bitmap for a specific height + AttestationBitmap(ctx context.Context, in *QueryAttestationBitmapRequest, opts ...grpc.CallOption) (*QueryAttestationBitmapResponse, error) + // EpochInfo queries information about a specific epoch + EpochInfo(ctx context.Context, in *QueryEpochInfoRequest, opts ...grpc.CallOption) (*QueryEpochInfoResponse, error) + // ValidatorIndex queries the bitmap index for a validator + ValidatorIndex(ctx context.Context, in *QueryValidatorIndexRequest, opts ...grpc.CallOption) (*QueryValidatorIndexResponse, error) + // SoftConfirmationStatus queries if a height is soft-confirmed + SoftConfirmationStatus(ctx context.Context, in *QuerySoftConfirmationStatusRequest, opts ...grpc.CallOption) (*QuerySoftConfirmationStatusResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AttestationBitmap(ctx context.Context, in *QueryAttestationBitmapRequest, opts ...grpc.CallOption) (*QueryAttestationBitmapResponse, error) { + out := new(QueryAttestationBitmapResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Query/AttestationBitmap", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) EpochInfo(ctx context.Context, in *QueryEpochInfoRequest, opts ...grpc.CallOption) (*QueryEpochInfoResponse, error) { + out := new(QueryEpochInfoResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Query/EpochInfo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ValidatorIndex(ctx context.Context, in *QueryValidatorIndexRequest, opts ...grpc.CallOption) (*QueryValidatorIndexResponse, error) { + out := new(QueryValidatorIndexResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Query/ValidatorIndex", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) SoftConfirmationStatus(ctx context.Context, in *QuerySoftConfirmationStatusRequest, opts ...grpc.CallOption) (*QuerySoftConfirmationStatusResponse, error) { + out := new(QuerySoftConfirmationStatusResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Query/SoftConfirmationStatus", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Params queries the module parameters + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // AttestationBitmap queries the attestation bitmap for a specific height + AttestationBitmap(context.Context, *QueryAttestationBitmapRequest) (*QueryAttestationBitmapResponse, error) + // EpochInfo queries information about a specific epoch + EpochInfo(context.Context, *QueryEpochInfoRequest) (*QueryEpochInfoResponse, error) + // ValidatorIndex queries the bitmap index for a validator + ValidatorIndex(context.Context, *QueryValidatorIndexRequest) (*QueryValidatorIndexResponse, error) + // SoftConfirmationStatus queries if a height is soft-confirmed + SoftConfirmationStatus(context.Context, *QuerySoftConfirmationStatusRequest) (*QuerySoftConfirmationStatusResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) AttestationBitmap(ctx context.Context, req *QueryAttestationBitmapRequest) (*QueryAttestationBitmapResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AttestationBitmap not implemented") +} +func (*UnimplementedQueryServer) EpochInfo(ctx context.Context, req *QueryEpochInfoRequest) (*QueryEpochInfoResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EpochInfo not implemented") +} +func (*UnimplementedQueryServer) ValidatorIndex(ctx context.Context, req *QueryValidatorIndexRequest) (*QueryValidatorIndexResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ValidatorIndex not implemented") +} +func (*UnimplementedQueryServer) SoftConfirmationStatus(ctx context.Context, req *QuerySoftConfirmationStatusRequest) (*QuerySoftConfirmationStatusResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SoftConfirmationStatus not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AttestationBitmap_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAttestationBitmapRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AttestationBitmap(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Query/AttestationBitmap", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AttestationBitmap(ctx, req.(*QueryAttestationBitmapRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_EpochInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryEpochInfoRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).EpochInfo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Query/EpochInfo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).EpochInfo(ctx, req.(*QueryEpochInfoRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ValidatorIndex_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryValidatorIndexRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ValidatorIndex(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Query/ValidatorIndex", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ValidatorIndex(ctx, req.(*QueryValidatorIndexRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_SoftConfirmationStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySoftConfirmationStatusRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).SoftConfirmationStatus(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Query/SoftConfirmationStatus", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).SoftConfirmationStatus(ctx, req.(*QuerySoftConfirmationStatusRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var Query_serviceDesc = _Query_serviceDesc +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rollkitsdk.network.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "AttestationBitmap", + Handler: _Query_AttestationBitmap_Handler, + }, + { + MethodName: "EpochInfo", + Handler: _Query_EpochInfo_Handler, + }, + { + MethodName: "ValidatorIndex", + Handler: _Query_ValidatorIndex_Handler, + }, + { + MethodName: "SoftConfirmationStatus", + Handler: _Query_SoftConfirmationStatus_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "rollkitsdk/network/v1/query.proto", +} + +func (m *QueryParamsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAttestationBitmapRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAttestationBitmapRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAttestationBitmapRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryAttestationBitmapResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryAttestationBitmapResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAttestationBitmapResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Bitmap != nil { + { + size, err := m.Bitmap.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryEpochInfoRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryEpochInfoRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryEpochInfoRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Epoch != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Epoch)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryEpochInfoResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryEpochInfoResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryEpochInfoResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ParticipatingValidators != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ParticipatingValidators)) + i-- + dAtA[i] = 0x30 + } + if m.ActiveValidators != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.ActiveValidators)) + i-- + dAtA[i] = 0x28 + } + if len(m.ParticipationBitmap) > 0 { + i -= len(m.ParticipationBitmap) + copy(dAtA[i:], m.ParticipationBitmap) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ParticipationBitmap))) + i-- + dAtA[i] = 0x22 + } + if m.EndHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.EndHeight)) + i-- + dAtA[i] = 0x18 + } + if m.StartHeight != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.StartHeight)) + i-- + dAtA[i] = 0x10 + } + if m.Epoch != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Epoch)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryValidatorIndexRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryValidatorIndexRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorIndexRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryValidatorIndexResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryValidatorIndexResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryValidatorIndexResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Index != nil { + { + size, err := m.Index.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySoftConfirmationStatusRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySoftConfirmationStatusRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySoftConfirmationStatusRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Height != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QuerySoftConfirmationStatusResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySoftConfirmationStatusResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySoftConfirmationStatusResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.QuorumFraction) > 0 { + i -= len(m.QuorumFraction) + copy(dAtA[i:], m.QuorumFraction) + i = encodeVarintQuery(dAtA, i, uint64(len(m.QuorumFraction))) + i-- + dAtA[i] = 0x22 + } + if m.TotalPower != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.TotalPower)) + i-- + dAtA[i] = 0x18 + } + if m.VotedPower != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.VotedPower)) + i-- + dAtA[i] = 0x10 + } + if m.IsSoftConfirmed { + i-- + if m.IsSoftConfirmed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAttestationBitmapRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + return n +} + +func (m *QueryAttestationBitmapResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Bitmap != nil { + l = m.Bitmap.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryEpochInfoRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Epoch != 0 { + n += 1 + sovQuery(uint64(m.Epoch)) + } + return n +} + +func (m *QueryEpochInfoResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Epoch != 0 { + n += 1 + sovQuery(uint64(m.Epoch)) + } + if m.StartHeight != 0 { + n += 1 + sovQuery(uint64(m.StartHeight)) + } + if m.EndHeight != 0 { + n += 1 + sovQuery(uint64(m.EndHeight)) + } + l = len(m.ParticipationBitmap) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.ActiveValidators != 0 { + n += 1 + sovQuery(uint64(m.ActiveValidators)) + } + if m.ParticipatingValidators != 0 { + n += 1 + sovQuery(uint64(m.ParticipatingValidators)) + } + return n +} + +func (m *QueryValidatorIndexRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryValidatorIndexResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Index != nil { + l = m.Index.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySoftConfirmationStatusRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovQuery(uint64(m.Height)) + } + return n +} + +func (m *QuerySoftConfirmationStatusResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IsSoftConfirmed { + n += 2 + } + if m.VotedPower != 0 { + n += 1 + sovQuery(uint64(m.VotedPower)) + } + if m.TotalPower != 0 { + n += 1 + sovQuery(uint64(m.TotalPower)) + } + l = len(m.QuorumFraction) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAttestationBitmapRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAttestationBitmapRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAttestationBitmapRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAttestationBitmapResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryAttestationBitmapResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAttestationBitmapResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Bitmap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Bitmap == nil { + m.Bitmap = &AttestationBitmap{} + } + if err := m.Bitmap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryEpochInfoRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryEpochInfoRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryEpochInfoRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + m.Epoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Epoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryEpochInfoResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryEpochInfoResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryEpochInfoResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + m.Epoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Epoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StartHeight", wireType) + } + m.StartHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StartHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndHeight", wireType) + } + m.EndHeight = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndHeight |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ParticipationBitmap", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ParticipationBitmap = append(m.ParticipationBitmap[:0], dAtA[iNdEx:postIndex]...) + if m.ParticipationBitmap == nil { + m.ParticipationBitmap = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveValidators", wireType) + } + m.ActiveValidators = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ActiveValidators |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ParticipatingValidators", wireType) + } + m.ParticipatingValidators = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ParticipatingValidators |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryValidatorIndexRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryValidatorIndexRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryValidatorIndexRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryValidatorIndexResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryValidatorIndexResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryValidatorIndexResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Index == nil { + m.Index = &ValidatorIndex{} + } + if err := m.Index.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySoftConfirmationStatusRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySoftConfirmationStatusRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySoftConfirmationStatusRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySoftConfirmationStatusResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySoftConfirmationStatusResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySoftConfirmationStatusResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsSoftConfirmed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsSoftConfirmed = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotedPower", wireType) + } + m.VotedPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotedPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPower", wireType) + } + m.TotalPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QuorumFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QuorumFraction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/network/types/query.pb.gw.go b/modules/network/types/query.pb.gw.go new file mode 100644 index 00000000..ca6c1a74 --- /dev/null +++ b/modules/network/types/query.pb.gw.go @@ -0,0 +1,557 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: rollkitsdk/network/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AttestationBitmap_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAttestationBitmapRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := client.AttestationBitmap(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AttestationBitmap_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAttestationBitmapRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := server.AttestationBitmap(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_EpochInfo_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEpochInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["epoch"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "epoch") + } + + protoReq.Epoch, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "epoch", err) + } + + msg, err := client.EpochInfo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_EpochInfo_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryEpochInfoRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["epoch"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "epoch") + } + + protoReq.Epoch, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "epoch", err) + } + + msg, err := server.EpochInfo(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_ValidatorIndex_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryValidatorIndexRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := client.ValidatorIndex(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ValidatorIndex_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryValidatorIndexRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["address"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "address") + } + + protoReq.Address, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "address", err) + } + + msg, err := server.ValidatorIndex(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_SoftConfirmationStatus_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySoftConfirmationStatusRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := client.SoftConfirmationStatus(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_SoftConfirmationStatus_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySoftConfirmationStatusRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["height"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "height") + } + + protoReq.Height, err = runtime.Int64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "height", err) + } + + msg, err := server.SoftConfirmationStatus(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AttestationBitmap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AttestationBitmap_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AttestationBitmap_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_EpochInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_EpochInfo_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_EpochInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ValidatorIndex_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ValidatorIndex_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ValidatorIndex_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_SoftConfirmationStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_SoftConfirmationStatus_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SoftConfirmationStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AttestationBitmap_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AttestationBitmap_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AttestationBitmap_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_EpochInfo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_EpochInfo_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_EpochInfo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ValidatorIndex_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ValidatorIndex_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ValidatorIndex_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_SoftConfirmationStatus_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_SoftConfirmationStatus_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_SoftConfirmationStatus_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"rollkit", "network", "v1", "params"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_AttestationBitmap_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"rollkit", "network", "v1", "attestation", "height"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_EpochInfo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 3}, []string{"rollkit", "network", "v1", "epoch"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_ValidatorIndex_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"rollkit", "network", "v1", "validator", "address"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_SoftConfirmationStatus_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"rollkit", "network", "v1", "soft-confirmation", "height"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_AttestationBitmap_0 = runtime.ForwardResponseMessage + + forward_Query_EpochInfo_0 = runtime.ForwardResponseMessage + + forward_Query_ValidatorIndex_0 = runtime.ForwardResponseMessage + + forward_Query_SoftConfirmationStatus_0 = runtime.ForwardResponseMessage +) diff --git a/modules/network/types/tx.pb.go b/modules/network/types/tx.pb.go new file mode 100644 index 00000000..5323919d --- /dev/null +++ b/modules/network/types/tx.pb.go @@ -0,0 +1,1635 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/v1/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/cosmos-sdk/types/msgservice" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgAttest submits a signed vote for a checkpoint +type MsgAttest struct { + // validator is the address of the validator submitting the attestation + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` + // height is the checkpoint height being attested + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + // vote is the base64-encoded canonical Comet vote + Vote []byte `protobuf:"bytes,3,opt,name=vote,proto3" json:"vote,omitempty"` +} + +func (m *MsgAttest) Reset() { *m = MsgAttest{} } +func (m *MsgAttest) String() string { return proto.CompactTextString(m) } +func (*MsgAttest) ProtoMessage() {} +func (*MsgAttest) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{0} +} +func (m *MsgAttest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAttest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAttest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAttest) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAttest.Merge(m, src) +} +func (m *MsgAttest) XXX_Size() int { + return m.Size() +} +func (m *MsgAttest) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAttest.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAttest proto.InternalMessageInfo + +// MsgAttestResponse is the response type for the Attest RPC +type MsgAttestResponse struct { +} + +func (m *MsgAttestResponse) Reset() { *m = MsgAttestResponse{} } +func (m *MsgAttestResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAttestResponse) ProtoMessage() {} +func (*MsgAttestResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{1} +} +func (m *MsgAttestResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAttestResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAttestResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAttestResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAttestResponse.Merge(m, src) +} +func (m *MsgAttestResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAttestResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAttestResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAttestResponse proto.InternalMessageInfo + +// MsgJoinAttesterSet opts a validator into the attester set +type MsgJoinAttesterSet struct { + // validator is the address of the validator joining + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` +} + +func (m *MsgJoinAttesterSet) Reset() { *m = MsgJoinAttesterSet{} } +func (m *MsgJoinAttesterSet) String() string { return proto.CompactTextString(m) } +func (*MsgJoinAttesterSet) ProtoMessage() {} +func (*MsgJoinAttesterSet) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{2} +} +func (m *MsgJoinAttesterSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgJoinAttesterSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgJoinAttesterSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgJoinAttesterSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgJoinAttesterSet.Merge(m, src) +} +func (m *MsgJoinAttesterSet) XXX_Size() int { + return m.Size() +} +func (m *MsgJoinAttesterSet) XXX_DiscardUnknown() { + xxx_messageInfo_MsgJoinAttesterSet.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgJoinAttesterSet proto.InternalMessageInfo + +// MsgJoinAttesterSetResponse is the response type for the JoinAttesterSet RPC +type MsgJoinAttesterSetResponse struct { +} + +func (m *MsgJoinAttesterSetResponse) Reset() { *m = MsgJoinAttesterSetResponse{} } +func (m *MsgJoinAttesterSetResponse) String() string { return proto.CompactTextString(m) } +func (*MsgJoinAttesterSetResponse) ProtoMessage() {} +func (*MsgJoinAttesterSetResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{3} +} +func (m *MsgJoinAttesterSetResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgJoinAttesterSetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgJoinAttesterSetResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgJoinAttesterSetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgJoinAttesterSetResponse.Merge(m, src) +} +func (m *MsgJoinAttesterSetResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgJoinAttesterSetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgJoinAttesterSetResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgJoinAttesterSetResponse proto.InternalMessageInfo + +// MsgLeaveAttesterSet opts a validator out of the attester set +type MsgLeaveAttesterSet struct { + // validator is the address of the validator leaving + Validator string `protobuf:"bytes,1,opt,name=validator,proto3" json:"validator,omitempty"` +} + +func (m *MsgLeaveAttesterSet) Reset() { *m = MsgLeaveAttesterSet{} } +func (m *MsgLeaveAttesterSet) String() string { return proto.CompactTextString(m) } +func (*MsgLeaveAttesterSet) ProtoMessage() {} +func (*MsgLeaveAttesterSet) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{4} +} +func (m *MsgLeaveAttesterSet) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLeaveAttesterSet) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLeaveAttesterSet.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLeaveAttesterSet) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLeaveAttesterSet.Merge(m, src) +} +func (m *MsgLeaveAttesterSet) XXX_Size() int { + return m.Size() +} +func (m *MsgLeaveAttesterSet) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLeaveAttesterSet.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLeaveAttesterSet proto.InternalMessageInfo + +// MsgLeaveAttesterSetResponse is the response type for the LeaveAttesterSet RPC +type MsgLeaveAttesterSetResponse struct { +} + +func (m *MsgLeaveAttesterSetResponse) Reset() { *m = MsgLeaveAttesterSetResponse{} } +func (m *MsgLeaveAttesterSetResponse) String() string { return proto.CompactTextString(m) } +func (*MsgLeaveAttesterSetResponse) ProtoMessage() {} +func (*MsgLeaveAttesterSetResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{5} +} +func (m *MsgLeaveAttesterSetResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgLeaveAttesterSetResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgLeaveAttesterSetResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgLeaveAttesterSetResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgLeaveAttesterSetResponse.Merge(m, src) +} +func (m *MsgLeaveAttesterSetResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgLeaveAttesterSetResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgLeaveAttesterSetResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgLeaveAttesterSetResponse proto.InternalMessageInfo + +// MsgUpdateParams updates the network module parameters +type MsgUpdateParams struct { + // authority is the address that controls the module + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` + // params defines the module parameters to update + Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params"` +} + +func (m *MsgUpdateParams) Reset() { *m = MsgUpdateParams{} } +func (m *MsgUpdateParams) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParams) ProtoMessage() {} +func (*MsgUpdateParams) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{6} +} +func (m *MsgUpdateParams) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParams) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParams.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParams) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParams.Merge(m, src) +} +func (m *MsgUpdateParams) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParams) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParams.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParams proto.InternalMessageInfo + +// MsgUpdateParamsResponse is the response type for the UpdateParams RPC +type MsgUpdateParamsResponse struct { +} + +func (m *MsgUpdateParamsResponse) Reset() { *m = MsgUpdateParamsResponse{} } +func (m *MsgUpdateParamsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateParamsResponse) ProtoMessage() {} +func (*MsgUpdateParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_cad4541892a6f0bf, []int{7} +} +func (m *MsgUpdateParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateParamsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgUpdateParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateParamsResponse.Merge(m, src) +} +func (m *MsgUpdateParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateParamsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgAttest)(nil), "rollkitsdk.network.v1.MsgAttest") + proto.RegisterType((*MsgAttestResponse)(nil), "rollkitsdk.network.v1.MsgAttestResponse") + proto.RegisterType((*MsgJoinAttesterSet)(nil), "rollkitsdk.network.v1.MsgJoinAttesterSet") + proto.RegisterType((*MsgJoinAttesterSetResponse)(nil), "rollkitsdk.network.v1.MsgJoinAttesterSetResponse") + proto.RegisterType((*MsgLeaveAttesterSet)(nil), "rollkitsdk.network.v1.MsgLeaveAttesterSet") + proto.RegisterType((*MsgLeaveAttesterSetResponse)(nil), "rollkitsdk.network.v1.MsgLeaveAttesterSetResponse") + proto.RegisterType((*MsgUpdateParams)(nil), "rollkitsdk.network.v1.MsgUpdateParams") + proto.RegisterType((*MsgUpdateParamsResponse)(nil), "rollkitsdk.network.v1.MsgUpdateParamsResponse") +} + +func init() { proto.RegisterFile("rollkitsdk/network/v1/tx.proto", fileDescriptor_cad4541892a6f0bf) } + +var fileDescriptor_cad4541892a6f0bf = []byte{ + // 521 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xc7, 0x7d, 0xa4, 0x44, 0xea, 0xa3, 0x52, 0xc1, 0x2d, 0x6d, 0x6a, 0xa8, 0x13, 0x32, 0xa0, + 0x10, 0x29, 0xb6, 0x12, 0x24, 0x86, 0x32, 0x35, 0x23, 0xc2, 0x12, 0x72, 0xcb, 0xc2, 0x82, 0x9c, + 0xf8, 0xb8, 0x58, 0x89, 0xfd, 0xac, 0xbb, 0x8b, 0x69, 0x37, 0xc4, 0x02, 0x23, 0x9f, 0x00, 0xf5, + 0x1b, 0xd0, 0x81, 0x0f, 0xd1, 0xb1, 0x62, 0x62, 0x42, 0x28, 0x19, 0xca, 0xc7, 0x40, 0xb1, 0x1d, + 0x07, 0xdc, 0x5a, 0x8d, 0x90, 0xd8, 0xee, 0xee, 0xfd, 0xdf, 0xff, 0xff, 0x93, 0xee, 0xe9, 0x81, + 0xce, 0x71, 0x34, 0x1a, 0x7a, 0x52, 0xb8, 0x43, 0x33, 0xa0, 0xf2, 0x2d, 0xf2, 0xa1, 0x19, 0xb5, + 0x4d, 0x79, 0x64, 0x84, 0x1c, 0x25, 0xaa, 0x77, 0x17, 0x75, 0x23, 0xad, 0x1b, 0x51, 0x5b, 0xdb, + 0xee, 0xa3, 0xf0, 0x51, 0x98, 0xbe, 0x60, 0x33, 0xb9, 0x2f, 0x58, 0xa2, 0xd7, 0x76, 0x92, 0xc2, + 0xeb, 0xf8, 0x66, 0x26, 0x97, 0xb4, 0xb4, 0xc9, 0x90, 0x61, 0xf2, 0x3e, 0x3b, 0xa5, 0xaf, 0x0f, + 0x0a, 0x00, 0x8e, 0x43, 0x9a, 0x36, 0xd6, 0x3f, 0x10, 0x58, 0xb5, 0x04, 0xdb, 0x97, 0x92, 0x0a, + 0xa9, 0x3e, 0x81, 0xd5, 0xc8, 0x19, 0x79, 0xae, 0x23, 0x91, 0x57, 0x48, 0x8d, 0x34, 0x56, 0xbb, + 0x95, 0x6f, 0x5f, 0x5b, 0x9b, 0x69, 0xd6, 0xbe, 0xeb, 0x72, 0x2a, 0xc4, 0x81, 0xe4, 0x5e, 0xc0, + 0xec, 0x85, 0x54, 0xdd, 0x82, 0xf2, 0x80, 0x7a, 0x6c, 0x20, 0x2b, 0x37, 0x6a, 0xa4, 0x51, 0xb2, + 0xd3, 0x9b, 0xaa, 0xc2, 0x4a, 0x84, 0x92, 0x56, 0x4a, 0x35, 0xd2, 0x58, 0xb3, 0xe3, 0xf3, 0xde, + 0xd6, 0xc7, 0x93, 0xaa, 0xf2, 0xeb, 0xa4, 0xaa, 0xbc, 0xbf, 0x38, 0x6d, 0x2e, 0x3c, 0xea, 0x1b, + 0x70, 0x27, 0x03, 0xb1, 0xa9, 0x08, 0x31, 0x10, 0xb4, 0xee, 0x82, 0x6a, 0x09, 0xf6, 0x0c, 0xbd, + 0x20, 0x29, 0x50, 0x7e, 0x40, 0xff, 0x19, 0xb3, 0x30, 0xfa, 0x3e, 0x68, 0x97, 0x53, 0x32, 0x06, + 0x0a, 0x1b, 0x96, 0x60, 0xcf, 0xa9, 0x13, 0xd1, 0xff, 0x09, 0xb1, 0x0b, 0xf7, 0xae, 0x88, 0xc9, + 0x28, 0x3e, 0x13, 0x58, 0xb7, 0x04, 0x7b, 0x19, 0xba, 0x8e, 0xa4, 0x2f, 0x1c, 0xee, 0xf8, 0x62, + 0x86, 0xe0, 0x8c, 0xe5, 0x00, 0xb9, 0x27, 0x8f, 0xaf, 0x47, 0xc8, 0xa4, 0xea, 0x53, 0x28, 0x87, + 0xb1, 0x43, 0xfc, 0x5d, 0xb7, 0x3a, 0xbb, 0xc6, 0x95, 0x93, 0x68, 0x24, 0x31, 0xdd, 0x95, 0xb3, + 0x1f, 0x55, 0xc5, 0x4e, 0x5b, 0x72, 0xfc, 0x99, 0x69, 0x7d, 0x07, 0xb6, 0x73, 0x7c, 0x73, 0xf6, + 0xce, 0x97, 0x12, 0x94, 0x2c, 0xc1, 0xd4, 0x43, 0x28, 0xa7, 0x83, 0x56, 0x2b, 0x48, 0xcc, 0x26, + 0x40, 0x6b, 0x5c, 0xa7, 0x98, 0xbb, 0xab, 0x08, 0xeb, 0xf9, 0x01, 0x79, 0x54, 0xdc, 0x9c, 0x93, + 0x6a, 0xed, 0xa5, 0xa5, 0x59, 0x20, 0x87, 0xdb, 0x97, 0xa6, 0xa1, 0x59, 0x6c, 0x93, 0xd7, 0x6a, + 0x9d, 0xe5, 0xb5, 0x59, 0xe6, 0x1b, 0x58, 0xfb, 0xeb, 0xeb, 0x1f, 0x16, 0x7b, 0xfc, 0xa9, 0xd3, + 0x8c, 0xe5, 0x74, 0xf3, 0x1c, 0xed, 0xe6, 0xbb, 0x8b, 0xd3, 0x26, 0xe9, 0x1e, 0x9e, 0x4d, 0x74, + 0x72, 0x3e, 0xd1, 0xc9, 0xcf, 0x89, 0x4e, 0x3e, 0x4d, 0x75, 0xe5, 0x7c, 0xaa, 0x2b, 0xdf, 0xa7, + 0xba, 0xf2, 0x6a, 0x8f, 0x79, 0x72, 0x30, 0xee, 0x19, 0x7d, 0xf4, 0xcd, 0xd4, 0xda, 0x64, 0xd8, + 0xa2, 0x47, 0xb4, 0x3f, 0x96, 0x1e, 0x06, 0x2d, 0xa7, 0xd7, 0xf7, 0x4c, 0x1f, 0xdd, 0xf1, 0x88, + 0x8a, 0x6c, 0xeb, 0xc4, 0x2b, 0xa7, 0x57, 0x8e, 0x77, 0xce, 0xe3, 0xdf, 0x01, 0x00, 0x00, 0xff, + 0xff, 0x40, 0xf9, 0x36, 0x1c, 0x19, 0x05, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // Attest submits a signed vote for a checkpoint + Attest(ctx context.Context, in *MsgAttest, opts ...grpc.CallOption) (*MsgAttestResponse, error) + // JoinAttesterSet opts a validator into the attester set + JoinAttesterSet(ctx context.Context, in *MsgJoinAttesterSet, opts ...grpc.CallOption) (*MsgJoinAttesterSetResponse, error) + // LeaveAttesterSet opts a validator out of the attester set + LeaveAttesterSet(ctx context.Context, in *MsgLeaveAttesterSet, opts ...grpc.CallOption) (*MsgLeaveAttesterSetResponse, error) + // UpdateParams updates the module parameters + UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) Attest(ctx context.Context, in *MsgAttest, opts ...grpc.CallOption) (*MsgAttestResponse, error) { + out := new(MsgAttestResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Msg/Attest", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) JoinAttesterSet(ctx context.Context, in *MsgJoinAttesterSet, opts ...grpc.CallOption) (*MsgJoinAttesterSetResponse, error) { + out := new(MsgJoinAttesterSetResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Msg/JoinAttesterSet", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) LeaveAttesterSet(ctx context.Context, in *MsgLeaveAttesterSet, opts ...grpc.CallOption) (*MsgLeaveAttesterSetResponse, error) { + out := new(MsgLeaveAttesterSetResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Msg/LeaveAttesterSet", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateParams(ctx context.Context, in *MsgUpdateParams, opts ...grpc.CallOption) (*MsgUpdateParamsResponse, error) { + out := new(MsgUpdateParamsResponse) + err := c.cc.Invoke(ctx, "/rollkitsdk.network.v1.Msg/UpdateParams", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // Attest submits a signed vote for a checkpoint + Attest(context.Context, *MsgAttest) (*MsgAttestResponse, error) + // JoinAttesterSet opts a validator into the attester set + JoinAttesterSet(context.Context, *MsgJoinAttesterSet) (*MsgJoinAttesterSetResponse, error) + // LeaveAttesterSet opts a validator out of the attester set + LeaveAttesterSet(context.Context, *MsgLeaveAttesterSet) (*MsgLeaveAttesterSetResponse, error) + // UpdateParams updates the module parameters + UpdateParams(context.Context, *MsgUpdateParams) (*MsgUpdateParamsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) Attest(ctx context.Context, req *MsgAttest) (*MsgAttestResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Attest not implemented") +} +func (*UnimplementedMsgServer) JoinAttesterSet(ctx context.Context, req *MsgJoinAttesterSet) (*MsgJoinAttesterSetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method JoinAttesterSet not implemented") +} +func (*UnimplementedMsgServer) LeaveAttesterSet(ctx context.Context, req *MsgLeaveAttesterSet) (*MsgLeaveAttesterSetResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LeaveAttesterSet not implemented") +} +func (*UnimplementedMsgServer) UpdateParams(ctx context.Context, req *MsgUpdateParams) (*MsgUpdateParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateParams not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_Attest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAttest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).Attest(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Msg/Attest", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).Attest(ctx, req.(*MsgAttest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_JoinAttesterSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgJoinAttesterSet) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).JoinAttesterSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Msg/JoinAttesterSet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).JoinAttesterSet(ctx, req.(*MsgJoinAttesterSet)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_LeaveAttesterSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgLeaveAttesterSet) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).LeaveAttesterSet(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Msg/LeaveAttesterSet", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).LeaveAttesterSet(ctx, req.(*MsgLeaveAttesterSet)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateParams_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateParams(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/rollkitsdk.network.v1.Msg/UpdateParams", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateParams(ctx, req.(*MsgUpdateParams)) + } + return interceptor(ctx, in, info, handler) +} + +var Msg_serviceDesc = _Msg_serviceDesc +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "rollkitsdk.network.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Attest", + Handler: _Msg_Attest_Handler, + }, + { + MethodName: "JoinAttesterSet", + Handler: _Msg_JoinAttesterSet_Handler, + }, + { + MethodName: "LeaveAttesterSet", + Handler: _Msg_LeaveAttesterSet_Handler, + }, + { + MethodName: "UpdateParams", + Handler: _Msg_UpdateParams_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "rollkitsdk/network/v1/tx.proto", +} + +func (m *MsgAttest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAttest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAttest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Vote) > 0 { + i -= len(m.Vote) + copy(dAtA[i:], m.Vote) + i = encodeVarintTx(dAtA, i, uint64(len(m.Vote))) + i-- + dAtA[i] = 0x1a + } + if m.Height != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x10 + } + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgAttestResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAttestResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAttestResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgJoinAttesterSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgJoinAttesterSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgJoinAttesterSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgJoinAttesterSetResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgJoinAttesterSetResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgJoinAttesterSetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgLeaveAttesterSet) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLeaveAttesterSet) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLeaveAttesterSet) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Validator) > 0 { + i -= len(m.Validator) + copy(dAtA[i:], m.Validator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Validator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgLeaveAttesterSetResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgLeaveAttesterSetResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgLeaveAttesterSetResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParams) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParams) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParams) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintTx(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateParamsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgUpdateParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgAttest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Height != 0 { + n += 1 + sovTx(uint64(m.Height)) + } + l = len(m.Vote) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgAttestResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgJoinAttesterSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgJoinAttesterSetResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgLeaveAttesterSet) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Validator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgLeaveAttesterSetResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdateParams) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = m.Params.Size() + n += 1 + l + sovTx(uint64(l)) + return n +} + +func (m *MsgUpdateParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgAttest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAttest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAttest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Vote", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Vote = append(m.Vote[:0], dAtA[iNdEx:postIndex]...) + if m.Vote == nil { + m.Vote = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAttestResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAttestResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAttestResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgJoinAttesterSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgJoinAttesterSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgJoinAttesterSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgJoinAttesterSetResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgJoinAttesterSetResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgJoinAttesterSetResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgLeaveAttesterSet) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLeaveAttesterSet: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLeaveAttesterSet: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgLeaveAttesterSetResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgLeaveAttesterSetResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgLeaveAttesterSetResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParams) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParams: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParams: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateParamsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTx + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/network/types/types.pb.go b/modules/network/types/types.pb.go new file mode 100644 index 00000000..eda96ff0 --- /dev/null +++ b/modules/network/types/types.pb.go @@ -0,0 +1,1154 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/v1/types.proto + +package types + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-proto" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/protobuf/types/known/durationpb" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// SignMode defines when validators must sign +type SignMode int32 + +const ( + // SIGN_MODE_UNSPECIFIED is invalid + SignMode_SIGN_MODE_UNSPECIFIED SignMode = 0 + // SIGN_MODE_CHECKPOINT means validators sign only at checkpoint heights + SignMode_SIGN_MODE_CHECKPOINT SignMode = 1 + // SIGN_MODE_ALL means validators sign every block + SignMode_SIGN_MODE_ALL SignMode = 2 + // SIGN_MODE_IBC_ONLY means validators sign only blocks with outbound IBC + SignMode_SIGN_MODE_IBC_ONLY SignMode = 3 +) + +var SignMode_name = map[int32]string{ + 0: "SIGN_MODE_UNSPECIFIED", + 1: "SIGN_MODE_CHECKPOINT", + 2: "SIGN_MODE_ALL", + 3: "SIGN_MODE_IBC_ONLY", +} + +var SignMode_value = map[string]int32{ + "SIGN_MODE_UNSPECIFIED": 0, + "SIGN_MODE_CHECKPOINT": 1, + "SIGN_MODE_ALL": 2, + "SIGN_MODE_IBC_ONLY": 3, +} + +func (x SignMode) String() string { + return proto.EnumName(SignMode_name, int32(x)) +} + +func (SignMode) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_6ae6db90f9054c5e, []int{0} +} + +// Params defines the parameters for the network module. +type Params struct { + // epoch_length is the number of blocks per attestation window + EpochLength uint64 `protobuf:"varint,1,opt,name=epoch_length,json=epochLength,proto3" json:"epoch_length,omitempty"` + // quorum_fraction is the voting power needed for soft-finality (e.g., "2/3") + QuorumFraction string `protobuf:"bytes,2,opt,name=quorum_fraction,json=quorumFraction,proto3" json:"quorum_fraction,omitempty"` + // min_participation is the ejection threshold inside an epoch (e.g., "1/2") + MinParticipation string `protobuf:"bytes,3,opt,name=min_participation,json=minParticipation,proto3" json:"min_participation,omitempty"` + // prune_after is the number of epochs to retain attestation bitmaps + PruneAfter uint64 `protobuf:"varint,4,opt,name=prune_after,json=pruneAfter,proto3" json:"prune_after,omitempty"` + // emergency_mode is a governance switch to bypass quorum + EmergencyMode bool `protobuf:"varint,5,opt,name=emergency_mode,json=emergencyMode,proto3" json:"emergency_mode,omitempty"` + // sign_mode determines when validators must sign + SignMode SignMode `protobuf:"varint,6,opt,name=sign_mode,json=signMode,proto3,enum=rollkitsdk.network.v1.SignMode" json:"sign_mode,omitempty"` +} + +func (m *Params) Reset() { *m = Params{} } +func (m *Params) String() string { return proto.CompactTextString(m) } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_6ae6db90f9054c5e, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetEpochLength() uint64 { + if m != nil { + return m.EpochLength + } + return 0 +} + +func (m *Params) GetQuorumFraction() string { + if m != nil { + return m.QuorumFraction + } + return "" +} + +func (m *Params) GetMinParticipation() string { + if m != nil { + return m.MinParticipation + } + return "" +} + +func (m *Params) GetPruneAfter() uint64 { + if m != nil { + return m.PruneAfter + } + return 0 +} + +func (m *Params) GetEmergencyMode() bool { + if m != nil { + return m.EmergencyMode + } + return false +} + +func (m *Params) GetSignMode() SignMode { + if m != nil { + return m.SignMode + } + return SignMode_SIGN_MODE_UNSPECIFIED +} + +// AttestationBitmap stores the bitmap and metadata for a checkpoint +type AttestationBitmap struct { + // height is the checkpoint height + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` + // bitmap is the validator participation bitmap + Bitmap []byte `protobuf:"bytes,2,opt,name=bitmap,proto3" json:"bitmap,omitempty"` + // voted_power is the total voting power that attested + VotedPower uint64 `protobuf:"varint,3,opt,name=voted_power,json=votedPower,proto3" json:"voted_power,omitempty"` + // total_power is the total voting power at this height + TotalPower uint64 `protobuf:"varint,4,opt,name=total_power,json=totalPower,proto3" json:"total_power,omitempty"` + // soft_confirmed indicates if quorum was reached + SoftConfirmed bool `protobuf:"varint,5,opt,name=soft_confirmed,json=softConfirmed,proto3" json:"soft_confirmed,omitempty"` +} + +func (m *AttestationBitmap) Reset() { *m = AttestationBitmap{} } +func (m *AttestationBitmap) String() string { return proto.CompactTextString(m) } +func (*AttestationBitmap) ProtoMessage() {} +func (*AttestationBitmap) Descriptor() ([]byte, []int) { + return fileDescriptor_6ae6db90f9054c5e, []int{1} +} +func (m *AttestationBitmap) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AttestationBitmap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AttestationBitmap.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *AttestationBitmap) XXX_Merge(src proto.Message) { + xxx_messageInfo_AttestationBitmap.Merge(m, src) +} +func (m *AttestationBitmap) XXX_Size() int { + return m.Size() +} +func (m *AttestationBitmap) XXX_DiscardUnknown() { + xxx_messageInfo_AttestationBitmap.DiscardUnknown(m) +} + +var xxx_messageInfo_AttestationBitmap proto.InternalMessageInfo + +func (m *AttestationBitmap) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *AttestationBitmap) GetBitmap() []byte { + if m != nil { + return m.Bitmap + } + return nil +} + +func (m *AttestationBitmap) GetVotedPower() uint64 { + if m != nil { + return m.VotedPower + } + return 0 +} + +func (m *AttestationBitmap) GetTotalPower() uint64 { + if m != nil { + return m.TotalPower + } + return 0 +} + +func (m *AttestationBitmap) GetSoftConfirmed() bool { + if m != nil { + return m.SoftConfirmed + } + return false +} + +// ValidatorIndex maps a validator address to its bitmap index +type ValidatorIndex struct { + // address is the validator operator address + Address string `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"` + // index is the position in the bitmap + Index uint32 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` + // power is the cached voting power + Power uint64 `protobuf:"varint,3,opt,name=power,proto3" json:"power,omitempty"` +} + +func (m *ValidatorIndex) Reset() { *m = ValidatorIndex{} } +func (m *ValidatorIndex) String() string { return proto.CompactTextString(m) } +func (*ValidatorIndex) ProtoMessage() {} +func (*ValidatorIndex) Descriptor() ([]byte, []int) { + return fileDescriptor_6ae6db90f9054c5e, []int{2} +} +func (m *ValidatorIndex) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ValidatorIndex) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ValidatorIndex.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ValidatorIndex) XXX_Merge(src proto.Message) { + xxx_messageInfo_ValidatorIndex.Merge(m, src) +} +func (m *ValidatorIndex) XXX_Size() int { + return m.Size() +} +func (m *ValidatorIndex) XXX_DiscardUnknown() { + xxx_messageInfo_ValidatorIndex.DiscardUnknown(m) +} + +var xxx_messageInfo_ValidatorIndex proto.InternalMessageInfo + +func (m *ValidatorIndex) GetAddress() string { + if m != nil { + return m.Address + } + return "" +} + +func (m *ValidatorIndex) GetIndex() uint32 { + if m != nil { + return m.Index + } + return 0 +} + +func (m *ValidatorIndex) GetPower() uint64 { + if m != nil { + return m.Power + } + return 0 +} + +func init() { + proto.RegisterEnum("rollkitsdk.network.v1.SignMode", SignMode_name, SignMode_value) + proto.RegisterType((*Params)(nil), "rollkitsdk.network.v1.Params") + proto.RegisterType((*AttestationBitmap)(nil), "rollkitsdk.network.v1.AttestationBitmap") + proto.RegisterType((*ValidatorIndex)(nil), "rollkitsdk.network.v1.ValidatorIndex") +} + +func init() { proto.RegisterFile("rollkitsdk/network/v1/types.proto", fileDescriptor_6ae6db90f9054c5e) } + +var fileDescriptor_6ae6db90f9054c5e = []byte{ + // 604 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0xcd, 0x4e, 0xdb, 0x40, + 0x10, 0x80, 0x63, 0x7e, 0x52, 0x58, 0x20, 0x0d, 0xab, 0x80, 0x0c, 0x07, 0x13, 0x90, 0x90, 0xa2, + 0x4a, 0x89, 0x05, 0x3d, 0x54, 0x6a, 0x7b, 0x49, 0x42, 0x68, 0xa3, 0x86, 0x10, 0x39, 0xb4, 0x52, + 0x7b, 0xb1, 0x1c, 0x7b, 0xe3, 0x6c, 0xb1, 0x77, 0xdc, 0xdd, 0x35, 0x3f, 0x6f, 0xd1, 0xb7, 0xe8, + 0xa5, 0x47, 0x1e, 0xa2, 0x47, 0xc4, 0xa9, 0xc7, 0x0a, 0x5e, 0xa4, 0xda, 0xb5, 0x43, 0x38, 0x70, + 0xdb, 0xf9, 0xe6, 0x5b, 0x7b, 0x66, 0x56, 0x83, 0x76, 0x39, 0x44, 0xd1, 0x39, 0x95, 0x22, 0x38, + 0xb7, 0x19, 0x91, 0x97, 0xc0, 0xcf, 0xed, 0x8b, 0x03, 0x5b, 0x5e, 0x27, 0x44, 0x34, 0x12, 0x0e, + 0x12, 0xf0, 0xc6, 0x4c, 0x69, 0xe4, 0x4a, 0xe3, 0xe2, 0x60, 0xbb, 0x12, 0x42, 0x08, 0xda, 0xb0, + 0xd5, 0x29, 0x93, 0xb7, 0xb7, 0x7c, 0x10, 0x31, 0x08, 0x37, 0x4b, 0x64, 0x41, 0x9e, 0xb2, 0x42, + 0x80, 0x30, 0x22, 0xb6, 0x8e, 0x46, 0xe9, 0xd8, 0x0e, 0x52, 0xee, 0x49, 0x0a, 0x2c, 0xcb, 0xef, + 0xfd, 0x9a, 0x43, 0xc5, 0x81, 0xc7, 0xbd, 0x58, 0xe0, 0x5d, 0xb4, 0x4a, 0x12, 0xf0, 0x27, 0x6e, + 0x44, 0x58, 0x28, 0x27, 0xa6, 0x51, 0x35, 0x6a, 0x0b, 0xce, 0x8a, 0x66, 0x3d, 0x8d, 0xf0, 0x1b, + 0xf4, 0xf2, 0x47, 0x0a, 0x3c, 0x8d, 0xdd, 0x31, 0xf7, 0x7c, 0xf5, 0x19, 0x73, 0xae, 0x6a, 0xd4, + 0x96, 0x5b, 0xa5, 0xbb, 0x9b, 0x3a, 0xca, 0x7f, 0x7c, 0x44, 0x7c, 0xa7, 0x94, 0x69, 0xc7, 0xb9, + 0x85, 0xdf, 0xa1, 0xf5, 0x98, 0x32, 0x37, 0xf1, 0xb8, 0xa4, 0x3e, 0x4d, 0x74, 0x05, 0xe6, 0xfc, + 0xb3, 0x57, 0xcb, 0x31, 0x65, 0x83, 0xa7, 0x1e, 0xde, 0x41, 0x2b, 0x09, 0x4f, 0x19, 0x71, 0xbd, + 0xb1, 0x24, 0xdc, 0x5c, 0xd0, 0x75, 0x21, 0x8d, 0x9a, 0x8a, 0xe0, 0x7d, 0x54, 0x22, 0x31, 0xe1, + 0x21, 0x61, 0xfe, 0xb5, 0x1b, 0x43, 0x40, 0xcc, 0xc5, 0xaa, 0x51, 0x5b, 0x72, 0xd6, 0x1e, 0xe9, + 0x09, 0x04, 0x04, 0xbf, 0x47, 0xcb, 0x82, 0x86, 0x2c, 0x33, 0x8a, 0x55, 0xa3, 0x56, 0x3a, 0xdc, + 0x69, 0x3c, 0x3b, 0xe7, 0xc6, 0x90, 0x86, 0x4c, 0xdd, 0x71, 0x96, 0x44, 0x7e, 0xda, 0xfb, 0x6d, + 0xa0, 0xf5, 0xa6, 0x94, 0x44, 0x48, 0x5d, 0x55, 0x8b, 0xca, 0xd8, 0x4b, 0xf0, 0x26, 0x2a, 0x4e, + 0x08, 0x0d, 0x27, 0x52, 0x8f, 0x6b, 0xde, 0xc9, 0x23, 0xc5, 0x47, 0xda, 0xd0, 0x03, 0x5a, 0x75, + 0xf2, 0x48, 0xf5, 0x72, 0x01, 0x92, 0x04, 0x6e, 0x02, 0x97, 0x84, 0xeb, 0x11, 0x2c, 0x38, 0x48, + 0xa3, 0x81, 0x22, 0x4a, 0x90, 0x20, 0xbd, 0x28, 0x17, 0xf2, 0x66, 0x35, 0xca, 0x84, 0x7d, 0x54, + 0x12, 0x30, 0x96, 0xae, 0x0f, 0x6c, 0x4c, 0x79, 0x4c, 0x82, 0x69, 0xb3, 0x8a, 0xb6, 0xa7, 0x70, + 0x2f, 0x41, 0xa5, 0x2f, 0x5e, 0x44, 0x03, 0x4f, 0x02, 0xef, 0xb2, 0x80, 0x5c, 0xe1, 0x43, 0xf4, + 0xc2, 0x0b, 0x02, 0x4e, 0x84, 0xd0, 0xb5, 0x2e, 0xb7, 0xcc, 0xbb, 0x9b, 0x7a, 0x25, 0x9f, 0x7c, + 0x33, 0xcb, 0x0c, 0x25, 0xa7, 0x2c, 0x74, 0xa6, 0x22, 0xae, 0xa0, 0x45, 0xaa, 0x2e, 0xeb, 0x2e, + 0xd6, 0x9c, 0x2c, 0x50, 0xf4, 0x69, 0xf9, 0x59, 0xf0, 0xea, 0x3b, 0x5a, 0x9a, 0x8e, 0x0d, 0x6f, + 0xa1, 0x8d, 0x61, 0xf7, 0x43, 0xdf, 0x3d, 0x39, 0x3d, 0xea, 0xb8, 0x9f, 0xfb, 0xc3, 0x41, 0xa7, + 0xdd, 0x3d, 0xee, 0x76, 0x8e, 0xca, 0x05, 0x6c, 0xa2, 0xca, 0x2c, 0xd5, 0xfe, 0xd8, 0x69, 0x7f, + 0x1a, 0x9c, 0x76, 0xfb, 0x67, 0x65, 0x03, 0xaf, 0xa3, 0xb5, 0x59, 0xa6, 0xd9, 0xeb, 0x95, 0xe7, + 0xf0, 0x26, 0xc2, 0x33, 0xd4, 0x6d, 0xb5, 0xdd, 0xd3, 0x7e, 0xef, 0x6b, 0x79, 0xbe, 0x75, 0xf6, + 0xe7, 0xde, 0x32, 0x6e, 0xef, 0x2d, 0xe3, 0xdf, 0xbd, 0x65, 0xfc, 0x7c, 0xb0, 0x0a, 0xb7, 0x0f, + 0x56, 0xe1, 0xef, 0x83, 0x55, 0xf8, 0xf6, 0x36, 0xa4, 0x72, 0x92, 0x8e, 0x1a, 0x3e, 0xc4, 0x76, + 0xfe, 0xb6, 0x76, 0x08, 0x75, 0x72, 0x45, 0xfc, 0x54, 0xbd, 0x5b, 0xdd, 0x1b, 0xf9, 0xd4, 0x8e, + 0x21, 0x48, 0x23, 0x22, 0x1e, 0xb7, 0x4f, 0xaf, 0xde, 0xa8, 0xa8, 0x77, 0xe2, 0xf5, 0xff, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x10, 0x23, 0x89, 0x7d, 0xa0, 0x03, 0x00, 0x00, +} + +func (m *Params) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SignMode != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.SignMode)) + i-- + dAtA[i] = 0x30 + } + if m.EmergencyMode { + i-- + if m.EmergencyMode { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if m.PruneAfter != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.PruneAfter)) + i-- + dAtA[i] = 0x20 + } + if len(m.MinParticipation) > 0 { + i -= len(m.MinParticipation) + copy(dAtA[i:], m.MinParticipation) + i = encodeVarintTypes(dAtA, i, uint64(len(m.MinParticipation))) + i-- + dAtA[i] = 0x1a + } + if len(m.QuorumFraction) > 0 { + i -= len(m.QuorumFraction) + copy(dAtA[i:], m.QuorumFraction) + i = encodeVarintTypes(dAtA, i, uint64(len(m.QuorumFraction))) + i-- + dAtA[i] = 0x12 + } + if m.EpochLength != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.EpochLength)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *AttestationBitmap) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *AttestationBitmap) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AttestationBitmap) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SoftConfirmed { + i-- + if m.SoftConfirmed { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if m.TotalPower != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.TotalPower)) + i-- + dAtA[i] = 0x20 + } + if m.VotedPower != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.VotedPower)) + i-- + dAtA[i] = 0x18 + } + if len(m.Bitmap) > 0 { + i -= len(m.Bitmap) + copy(dAtA[i:], m.Bitmap) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Bitmap))) + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ValidatorIndex) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ValidatorIndex) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ValidatorIndex) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Power != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Power)) + i-- + dAtA[i] = 0x18 + } + if m.Index != 0 { + i = encodeVarintTypes(dAtA, i, uint64(m.Index)) + i-- + dAtA[i] = 0x10 + } + if len(m.Address) > 0 { + i -= len(m.Address) + copy(dAtA[i:], m.Address) + i = encodeVarintTypes(dAtA, i, uint64(len(m.Address))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTypes(dAtA []byte, offset int, v uint64) int { + offset -= sovTypes(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.EpochLength != 0 { + n += 1 + sovTypes(uint64(m.EpochLength)) + } + l = len(m.QuorumFraction) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + l = len(m.MinParticipation) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.PruneAfter != 0 { + n += 1 + sovTypes(uint64(m.PruneAfter)) + } + if m.EmergencyMode { + n += 2 + } + if m.SignMode != 0 { + n += 1 + sovTypes(uint64(m.SignMode)) + } + return n +} + +func (m *AttestationBitmap) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovTypes(uint64(m.Height)) + } + l = len(m.Bitmap) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.VotedPower != 0 { + n += 1 + sovTypes(uint64(m.VotedPower)) + } + if m.TotalPower != 0 { + n += 1 + sovTypes(uint64(m.TotalPower)) + } + if m.SoftConfirmed { + n += 2 + } + return n +} + +func (m *ValidatorIndex) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Address) + if l > 0 { + n += 1 + l + sovTypes(uint64(l)) + } + if m.Index != 0 { + n += 1 + sovTypes(uint64(m.Index)) + } + if m.Power != 0 { + n += 1 + sovTypes(uint64(m.Power)) + } + return n +} + +func sovTypes(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTypes(x uint64) (n int) { + return sovTypes(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EpochLength", wireType) + } + m.EpochLength = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EpochLength |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QuorumFraction", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.QuorumFraction = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MinParticipation", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.MinParticipation = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PruneAfter", wireType) + } + m.PruneAfter = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PruneAfter |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EmergencyMode", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EmergencyMode = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SignMode", wireType) + } + m.SignMode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SignMode |= SignMode(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AttestationBitmap) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: AttestationBitmap: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AttestationBitmap: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Bitmap", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Bitmap = append(m.Bitmap[:0], dAtA[iNdEx:postIndex]...) + if m.Bitmap == nil { + m.Bitmap = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field VotedPower", wireType) + } + m.VotedPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.VotedPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPower", wireType) + } + m.TotalPower = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPower |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SoftConfirmed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.SoftConfirmed = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ValidatorIndex) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ValidatorIndex: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ValidatorIndex: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Address", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTypes + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Address = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Index", wireType) + } + m.Index = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Index |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Power", wireType) + } + m.Power = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Power |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTypes(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTypes + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTypes + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTypes + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTypes + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTypes = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTypes = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/proto/rollkitsdk/network/module/v1/module.proto b/modules/proto/rollkitsdk/network/module/v1/module.proto new file mode 100644 index 00000000..304eef5a --- /dev/null +++ b/modules/proto/rollkitsdk/network/module/v1/module.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package rollkitsdk.network.module.v1; + +import "cosmos/app/v1alpha1/module.proto"; + +// Module is the config object for the network module. +message Module { + option (cosmos.app.v1alpha1.module) = { + go_import: "github.com/rollkit/go-execution-abci/modules/network" + }; + + // authority defines the custom module authority. If not set, defaults to the governance module. + string authority = 1; +} \ No newline at end of file diff --git a/modules/proto/rollkitsdk/network/v1/genesis.proto b/modules/proto/rollkitsdk/network/v1/genesis.proto new file mode 100644 index 00000000..805ea2a5 --- /dev/null +++ b/modules/proto/rollkitsdk/network/v1/genesis.proto @@ -0,0 +1,20 @@ +syntax = "proto3"; + +package rollkitsdk.network.v1; + +option go_package = "github.com/rollkit/go-execution-abci/modules/network/types"; + +import "gogoproto/gogo.proto"; +import "rollkitsdk/network/v1/types.proto"; + +// GenesisState defines the network module's genesis state. +message GenesisState { + // params defines the module parameters at genesis + Params params = 1 [(gogoproto.nullable) = false]; + + // validator_indices contains the initial validator index mappings + repeated ValidatorIndex validator_indices = 2 [(gogoproto.nullable) = false]; + + // attestation_bitmaps contains historical attestation data + repeated AttestationBitmap attestation_bitmaps = 3 [(gogoproto.nullable) = false]; +} \ No newline at end of file diff --git a/modules/proto/rollkitsdk/network/v1/query.proto b/modules/proto/rollkitsdk/network/v1/query.proto new file mode 100644 index 00000000..aeaf3321 --- /dev/null +++ b/modules/proto/rollkitsdk/network/v1/query.proto @@ -0,0 +1,95 @@ +syntax = "proto3"; + +package rollkitsdk.network.v1; + +option go_package = "github.com/rollkit/go-execution-abci/modules/network/types"; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "rollkitsdk/network/v1/types.proto"; + +// Query defines the gRPC querier service for the network module. +service Query { + // Params queries the module parameters + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/rollkit/network/v1/params"; + } + + // AttestationBitmap queries the attestation bitmap for a specific height + rpc AttestationBitmap(QueryAttestationBitmapRequest) returns (QueryAttestationBitmapResponse) { + option (google.api.http).get = "/rollkit/network/v1/attestation/{height}"; + } + + // EpochInfo queries information about a specific epoch + rpc EpochInfo(QueryEpochInfoRequest) returns (QueryEpochInfoResponse) { + option (google.api.http).get = "/rollkit/network/v1/epoch/{epoch}"; + } + + // ValidatorIndex queries the bitmap index for a validator + rpc ValidatorIndex(QueryValidatorIndexRequest) returns (QueryValidatorIndexResponse) { + option (google.api.http).get = "/rollkit/network/v1/validator/{address}"; + } + + // SoftConfirmationStatus queries if a height is soft-confirmed + rpc SoftConfirmationStatus(QuerySoftConfirmationStatusRequest) returns (QuerySoftConfirmationStatusResponse) { + option (google.api.http).get = "/rollkit/network/v1/soft-confirmation/{height}"; + } +} + +// QueryParamsRequest is the request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is the response type for the Query/Params RPC method. +message QueryParamsResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +// QueryAttestationBitmapRequest is the request type for the Query/AttestationBitmap RPC method. +message QueryAttestationBitmapRequest { + int64 height = 1; +} + +// QueryAttestationBitmapResponse is the response type for the Query/AttestationBitmap RPC method. +message QueryAttestationBitmapResponse { + AttestationBitmap bitmap = 1; +} + +// QueryEpochInfoRequest is the request type for the Query/EpochInfo RPC method. +message QueryEpochInfoRequest { + uint64 epoch = 1; +} + +// QueryEpochInfoResponse is the response type for the Query/EpochInfo RPC method. +message QueryEpochInfoResponse { + uint64 epoch = 1; + int64 start_height = 2; + int64 end_height = 3; + bytes participation_bitmap = 4; + uint64 active_validators = 5; + uint64 participating_validators = 6; +} + +// QueryValidatorIndexRequest is the request type for the Query/ValidatorIndex RPC method. +message QueryValidatorIndexRequest { + string address = 1; +} + +// QueryValidatorIndexResponse is the response type for the Query/ValidatorIndex RPC method. +message QueryValidatorIndexResponse { + ValidatorIndex index = 1; +} + +// QuerySoftConfirmationStatusRequest is the request type for the Query/SoftConfirmationStatus RPC method. +message QuerySoftConfirmationStatusRequest { + int64 height = 1; +} + +// QuerySoftConfirmationStatusResponse is the response type for the Query/SoftConfirmationStatus RPC method. +message QuerySoftConfirmationStatusResponse { + bool is_soft_confirmed = 1; + uint64 voted_power = 2; + uint64 total_power = 3; + string quorum_fraction = 4; +} \ No newline at end of file diff --git a/modules/proto/rollkitsdk/network/v1/tx.proto b/modules/proto/rollkitsdk/network/v1/tx.proto new file mode 100644 index 00000000..b794f736 --- /dev/null +++ b/modules/proto/rollkitsdk/network/v1/tx.proto @@ -0,0 +1,88 @@ +syntax = "proto3"; + +package rollkitsdk.network.v1; + +option go_package = "github.com/rollkit/go-execution-abci/modules/network/types"; + +import "cosmos/msg/v1/msg.proto"; +import "cosmos_proto/cosmos.proto"; +import "gogoproto/gogo.proto"; +import "rollkitsdk/network/v1/types.proto"; + +// Msg defines the network module's gRPC message service. +service Msg { + option (cosmos.msg.v1.service) = true; + + // Attest submits a signed vote for a checkpoint + rpc Attest(MsgAttest) returns (MsgAttestResponse); + + // JoinAttesterSet opts a validator into the attester set + rpc JoinAttesterSet(MsgJoinAttesterSet) returns (MsgJoinAttesterSetResponse); + + // LeaveAttesterSet opts a validator out of the attester set + rpc LeaveAttesterSet(MsgLeaveAttesterSet) returns (MsgLeaveAttesterSetResponse); + + // UpdateParams updates the module parameters + rpc UpdateParams(MsgUpdateParams) returns (MsgUpdateParamsResponse); +} + +// MsgAttest submits a signed vote for a checkpoint +message MsgAttest { + option (cosmos.msg.v1.signer) = "validator"; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator is the address of the validator submitting the attestation + string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // height is the checkpoint height being attested + int64 height = 2; + + // vote is the base64-encoded canonical Comet vote + bytes vote = 3; +} + +// MsgAttestResponse is the response type for the Attest RPC +message MsgAttestResponse {} + +// MsgJoinAttesterSet opts a validator into the attester set +message MsgJoinAttesterSet { + option (cosmos.msg.v1.signer) = "validator"; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator is the address of the validator joining + string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} + +// MsgJoinAttesterSetResponse is the response type for the JoinAttesterSet RPC +message MsgJoinAttesterSetResponse {} + +// MsgLeaveAttesterSet opts a validator out of the attester set +message MsgLeaveAttesterSet { + option (cosmos.msg.v1.signer) = "validator"; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // validator is the address of the validator leaving + string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; +} + +// MsgLeaveAttesterSetResponse is the response type for the LeaveAttesterSet RPC +message MsgLeaveAttesterSetResponse {} + +// MsgUpdateParams updates the network module parameters +message MsgUpdateParams { + option (cosmos.msg.v1.signer) = "authority"; + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + // authority is the address that controls the module + string authority = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // params defines the module parameters to update + Params params = 2 [(gogoproto.nullable) = false]; +} + +// MsgUpdateParamsResponse is the response type for the UpdateParams RPC +message MsgUpdateParamsResponse {} \ No newline at end of file diff --git a/modules/proto/rollkitsdk/network/v1/types.proto b/modules/proto/rollkitsdk/network/v1/types.proto new file mode 100644 index 00000000..a09f2262 --- /dev/null +++ b/modules/proto/rollkitsdk/network/v1/types.proto @@ -0,0 +1,75 @@ +syntax = "proto3"; + +package rollkitsdk.network.v1; + +option go_package = "github.com/rollkit/go-execution-abci/modules/network/types"; + +import "gogoproto/gogo.proto"; +import "cosmos_proto/cosmos.proto"; +import "google/protobuf/duration.proto"; + +// Params defines the parameters for the network module. +message Params { + // epoch_length is the number of blocks per attestation window + uint64 epoch_length = 1; + + // quorum_fraction is the voting power needed for soft-finality (e.g., "2/3") + string quorum_fraction = 2 [(cosmos_proto.scalar) = "cosmos.Dec"]; + + // min_participation is the ejection threshold inside an epoch (e.g., "1/2") + string min_participation = 3 [(cosmos_proto.scalar) = "cosmos.Dec"]; + + // prune_after is the number of epochs to retain attestation bitmaps + uint64 prune_after = 4; + + // emergency_mode is a governance switch to bypass quorum + bool emergency_mode = 5; + + // sign_mode determines when validators must sign + SignMode sign_mode = 6; +} + +// SignMode defines when validators must sign +enum SignMode { + // SIGN_MODE_UNSPECIFIED is invalid + SIGN_MODE_UNSPECIFIED = 0; + + // SIGN_MODE_CHECKPOINT means validators sign only at checkpoint heights + SIGN_MODE_CHECKPOINT = 1; + + // SIGN_MODE_ALL means validators sign every block + SIGN_MODE_ALL = 2; + + // SIGN_MODE_IBC_ONLY means validators sign only blocks with outbound IBC + SIGN_MODE_IBC_ONLY = 3; +} + +// AttestationBitmap stores the bitmap and metadata for a checkpoint +message AttestationBitmap { + // height is the checkpoint height + int64 height = 1; + + // bitmap is the validator participation bitmap + bytes bitmap = 2; + + // voted_power is the total voting power that attested + uint64 voted_power = 3; + + // total_power is the total voting power at this height + uint64 total_power = 4; + + // soft_confirmed indicates if quorum was reached + bool soft_confirmed = 5; +} + +// ValidatorIndex maps a validator address to its bitmap index +message ValidatorIndex { + // address is the validator operator address + string address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + + // index is the position in the bitmap + uint32 index = 2; + + // power is the cached voting power + uint64 power = 3; +} \ No newline at end of file From f30396bbc376a2b691b3a3cb6b02ec6d6b58e1bf Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 12 Jun 2025 17:00:53 +0200 Subject: [PATCH 02/21] Mkake compile --- Makefile | 6 +- modules/network/autocli.go | 7 +- modules/network/client/cli/query.go | 2 +- modules/network/client/cli/tx.go | 2 +- modules/network/depinject.go | 17 +- modules/network/genesis.go | 95 +++---- modules/network/keeper/abci.go | 40 +-- modules/network/keeper/keeper.go | 19 +- modules/network/module.go | 209 ++++------------ modules/network/module/v1/module.pb.go | 329 +++++++++++++++++++++++++ modules/network/types/codec.go | 2 +- modules/network/types/genesis.pb.go | 5 +- modules/network/types/query.pb.go | 7 +- modules/network/types/tx.pb.go | 7 +- modules/network/types/types.pb.go | 7 +- 15 files changed, 497 insertions(+), 257 deletions(-) create mode 100644 modules/network/module/v1/module.pb.go diff --git a/Makefile b/Makefile index 7f650f75..ac6720b8 100644 --- a/Makefile +++ b/Makefile @@ -70,8 +70,10 @@ proto-gen: go tool github.com/bufbuild/buf/cmd/buf dep update @cd modules/proto && \ go tool github.com/bufbuild/buf/cmd/buf generate + @mkdir -p modules/network/module/v1 @mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/types/** modules/rollkitmngr/types/ && \ - mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/module/* modules/rollkitmngr/module/ + mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/module/* modules/rollkitmngr/module/ && \ + mv modules/github.com/rollkit/go-execution-abci/modules/network/module/v1/* modules/network/module/v1/ @rm -r modules/github.com -.PHONY: proto-gen \ No newline at end of file +.PHONY: proto-gen diff --git a/modules/network/autocli.go b/modules/network/autocli.go index 7669a198..27eefe8f 100644 --- a/modules/network/autocli.go +++ b/modules/network/autocli.go @@ -2,6 +2,7 @@ package network import ( autocliv1 "cosmossdk.io/api/cosmos/autocli/v1" + networkv1 "github.com/rollkit/go-execution-abci/modules/network/types" ) @@ -9,7 +10,7 @@ import ( func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { return &autocliv1.ModuleOptions{ Query: &autocliv1.ServiceCommandDescriptor{ - Service: networkv1.Query_ServiceDesc.ServiceName, + Service: networkv1.Query_serviceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { RpcMethod: "Params", @@ -51,7 +52,7 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { }, }, Tx: &autocliv1.ServiceCommandDescriptor{ - Service: networkv1.Msg_ServiceDesc.ServiceName, + Service: networkv1.Msg_serviceDesc.ServiceName, RpcCommandOptions: []*autocliv1.RpcCommandOptions{ { RpcMethod: "Attest", @@ -75,4 +76,4 @@ func (am AppModule) AutoCLIOptions() *autocliv1.ModuleOptions { }, }, } -} \ No newline at end of file +} diff --git a/modules/network/client/cli/query.go b/modules/network/client/cli/query.go index c5906696..a866115e 100644 --- a/modules/network/client/cli/query.go +++ b/modules/network/client/cli/query.go @@ -194,4 +194,4 @@ func CmdQuerySoftConfirmationStatus() *cobra.Command { flags.AddQueryFlagsToCmd(cmd) return cmd -} \ No newline at end of file +} diff --git a/modules/network/client/cli/tx.go b/modules/network/client/cli/tx.go index 252654a4..267de6bf 100644 --- a/modules/network/client/cli/tx.go +++ b/modules/network/client/cli/tx.go @@ -125,4 +125,4 @@ func CmdLeaveAttesterSet() *cobra.Command { flags.AddTxFlagsToCmd(cmd) return cmd -} \ No newline at end of file +} diff --git a/modules/network/depinject.go b/modules/network/depinject.go index 98972216..ba2ec52c 100644 --- a/modules/network/depinject.go +++ b/modules/network/depinject.go @@ -2,10 +2,10 @@ package network import ( "cosmossdk.io/core/appmodule" + "cosmossdk.io/core/store" "cosmossdk.io/depinject" - + "cosmossdk.io/depinject/appconfig" "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -20,13 +20,10 @@ var _ appmodule.AppModule = AppModule{} // IsOnePerModuleType implements the depinject.OnePerModuleType interface. func (am AppModule) IsOnePerModuleType() {} -// IsAppModule implements the appmodule.AppModule interface. -func (am AppModule) IsAppModule() {} - func init() { - appmodule.Register( + appconfig.Register( &modulev1.Module{}, - appmodule.Provide(ProvideModule), + appconfig.Provide(ProvideModule), ) } @@ -35,7 +32,7 @@ type ModuleInputs struct { Config *modulev1.Module Cdc codec.Codec - Key *sdk.KVStoreKey + StoreService store.KVStoreService ParamsSubspace paramtypes.Subspace StakingKeeper types.StakingKeeper AccountKeeper types.AccountKeeper @@ -58,7 +55,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { k := keeper.NewKeeper( in.Cdc, - in.Key, + in.StoreService, in.ParamsSubspace, in.StakingKeeper, in.AccountKeeper, @@ -68,8 +65,6 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { m := NewAppModule( in.Cdc, k, - in.AccountKeeper, - in.BankKeeper, ) return ModuleOutputs{NetworkKeeper: k, Module: m} diff --git a/modules/network/genesis.go b/modules/network/genesis.go index 3764073b..54415d5a 100644 --- a/modules/network/genesis.go +++ b/modules/network/genesis.go @@ -2,37 +2,44 @@ package network import ( sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/codec" "github.com/rollkit/go-execution-abci/modules/network/keeper" "github.com/rollkit/go-execution-abci/modules/network/types" ) // InitGenesis initializes the network module's state from a provided genesis state. -func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) error { // Set module params k.SetParams(ctx, genState.Params) // Set validator indices for _, vi := range genState.ValidatorIndices { - k.SetValidatorIndex(ctx, vi.Address, uint16(vi.Index), vi.Power) + if err := k.SetValidatorIndex(ctx, vi.Address, uint16(vi.Index), vi.Power); err != nil { + return err + } // Also add to attester set - k.SetAttesterSetMember(ctx, vi.Address) + if err := k.SetAttesterSetMember(ctx, vi.Address); err != nil { + return err + } } // Set attestation bitmaps for _, ab := range genState.AttestationBitmaps { - k.SetAttestationBitmap(ctx, ab.Height, ab.Bitmap) - // Store full attestation info - store := ctx.KVStore(k.GetStoreKey()) - key := append([]byte("attestation_info/"), sdk.Uint64ToBigEndian(uint64(ab.Height))...) - bz := k.GetCodec().MustMarshal(&ab) - store.Set(key, bz) - + if err := k.SetAttestationBitmap(ctx, ab.Height, ab.Bitmap); err != nil { + return err + } + // Store full attestation info using collections API + if err := k.StoredAttestationInfo.Set(ctx, ab.Height, ab); err != nil { + return err + } + if ab.SoftConfirmed { - setSoftConfirmed(ctx, k, ab.Height) + if err := setSoftConfirmed(ctx, k, ab.Height); err != nil { + return err + } } } + return nil } // ExportGenesis returns the network module's exported genesis. @@ -40,47 +47,51 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { genesis := types.DefaultGenesisState() genesis.Params = k.GetParams(ctx) - // Export validator indices - store := ctx.KVStore(k.GetStoreKey()) - iterator := sdk.KVStorePrefixIterator(store, types.ValidatorIndexPrefix) - defer iterator.Close() - - for ; iterator.Valid(); iterator.Next() { - addr := string(iterator.Key()[len(types.ValidatorIndexPrefix):]) - index, _ := k.GetValidatorIndex(ctx, addr) + // Export validator indices using collections API + var validatorIndices []types.ValidatorIndex + // Iterate through all validator indices + if err := k.ValidatorIndex.Walk(ctx, nil, func(addr string, index uint16) (bool, error) { power := k.GetValidatorPower(ctx, index) - - genesis.ValidatorIndices = append(genesis.ValidatorIndices, types.ValidatorIndex{ + validatorIndices = append(validatorIndices, types.ValidatorIndex{ Address: addr, Index: uint32(index), Power: power, }) + return false, nil + }); err != nil { + panic(err) } + genesis.ValidatorIndices = validatorIndices - // Export attestation bitmaps - attIterator := sdk.KVStorePrefixIterator(store, []byte("attestation_info/")) - defer attIterator.Close() - - for ; attIterator.Valid(); attIterator.Next() { - var ab types.AttestationBitmap - k.GetCodec().MustUnmarshal(attIterator.Value(), &ab) - genesis.AttestationBitmaps = append(genesis.AttestationBitmaps, ab) + // Export attestation bitmaps using collections API + var attestationBitmaps []types.AttestationBitmap + // Iterate through all stored attestation info + if err := k.StoredAttestationInfo.Walk(ctx, nil, func(height int64, ab types.AttestationBitmap) (bool, error) { + attestationBitmaps = append(attestationBitmaps, ab) + return false, nil + }); err != nil { + panic(err) } + genesis.AttestationBitmaps = attestationBitmaps return genesis } -// Helper functions -func (k keeper.Keeper) GetStoreKey() sdk.StoreKey { - return k.storeKey -} +// Helper function to set soft confirmed status +func setSoftConfirmed(ctx sdk.Context, k keeper.Keeper, height int64) error { + // Get the existing attestation bitmap + ab, err := k.StoredAttestationInfo.Get(ctx, height) + if err != nil { + // If there's no existing attestation bitmap, we can't set it as soft confirmed + return err + } -func (k keeper.Keeper) GetCodec() codec.BinaryCodec { - return k.cdc -} + // Set the SoftConfirmed field to true + ab.SoftConfirmed = true -func setSoftConfirmed(ctx sdk.Context, k keeper.Keeper, height int64) { - store := ctx.KVStore(k.GetStoreKey()) - key := append([]byte("soft_confirmed/"), sdk.Uint64ToBigEndian(uint64(height))...) - store.Set(key, []byte{1}) -} \ No newline at end of file + // Update the attestation bitmap in the collection + if err := k.StoredAttestationInfo.Set(ctx, height, ab); err != nil { + return err + } + return nil +} diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index 5ce9b276..9bf41ff3 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -3,6 +3,7 @@ package keeper import ( "crypto/sha256" "encoding/base64" + "fmt" // For error wrapping if needed "cosmossdk.io/math" @@ -12,7 +13,7 @@ import ( ) // BeginBlocker handles begin block logic for the network module -func (k Keeper) BeginBlocker(ctx sdk.Context) { +func (k Keeper) BeginBlocker(ctx sdk.Context) error { params := k.GetParams(ctx) // Only process if sign mode is IBC_ONLY and we have outbound IBC packets @@ -20,16 +21,19 @@ func (k Keeper) BeginBlocker(ctx sdk.Context) { // TODO: Check for outbound IBC packets // For now, this is a placeholder } + return nil } // EndBlocker handles end block logic for the network module -func (k Keeper) EndBlocker(ctx sdk.Context) { +func (k Keeper) EndBlocker(ctx sdk.Context) error { height := ctx.BlockHeight() params := k.GetParams(ctx) // Handle checkpoint heights if k.IsCheckpointHeight(ctx, height) { - k.processCheckpoint(ctx, height) + if err := k.processCheckpoint(ctx, height); err != nil { + return fmt.Errorf("processing checkpoint at height %d: %w", height, err) + } } // Handle epoch end @@ -38,15 +42,18 @@ func (k Keeper) EndBlocker(ctx sdk.Context) { nextEpoch := uint64(nextHeight) / params.EpochLength if epoch != nextEpoch { - k.processEpochEnd(ctx, epoch) + if err := k.processEpochEnd(ctx, epoch); err != nil { + return fmt.Errorf("processing epoch end %d: %w", epoch, err) + } } + return nil } // processCheckpoint handles checkpoint processing -func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) { +func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) error { bitmapBytes := k.GetAttestationBitmap(ctx, height) if bitmapBytes == nil { - return + return nil } votedPower := k.CalculateVotedPower(ctx, bitmapBytes) @@ -67,14 +74,15 @@ func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) { } if err := k.StoredAttestationInfo.Set(ctx, height, attestationInfoToStore); err != nil { - k.Logger(ctx).Error("failed to store attestation info", "height", height, "error", err) + return fmt.Errorf("storing attestation info at height %d: %w", height, err) } // Emit hashes k.emitCheckpointHashes(ctx, height, validatorHash[:], commitHash[:], softConfirmed) + return nil } -func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) { +func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { params := k.GetParams(ctx) epochBitmap := k.GetEpochBitmap(ctx, epoch) @@ -91,12 +99,11 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) { participated := k.bitmapHelper.PopCount(epochBitmap) minParticipation, err := math.LegacyNewDecFromStr(params.MinParticipation) if err != nil { - k.Logger(ctx).Error("failed to parse MinParticipation", "error", err) - } else { - participationRate := math.LegacyNewDec(int64(participated)).QuoInt64(int64(totalBondedValidators)) - if participationRate.LT(minParticipation) { - k.ejectLowParticipants(ctx, epochBitmap) - } + return fmt.Errorf("parsing MinParticipation parameter: %w", err) + } + participationRate := math.LegacyNewDec(int64(participated)).QuoInt64(int64(totalBondedValidators)) + if participationRate.LT(minParticipation) { + k.ejectLowParticipants(ctx, epochBitmap) } } } @@ -124,12 +131,13 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) { } if err := k.PruneOldBitmaps(ctx, epoch); err != nil { - k.Logger(ctx).Error("failed to prune old data at epoch end", "epoch", epoch, "error", err) + return fmt.Errorf("pruning old data at epoch %d: %w", epoch, err) } if err := k.BuildValidatorIndexMap(ctx); err != nil { - k.Logger(ctx).Error("failed to rebuild validator index map at epoch end", "epoch", epoch, "error", err) + return fmt.Errorf("rebuilding validator index map at epoch %d: %w", epoch, err) } + return nil } // ejectLowParticipants ejects validators with low participation diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index 9bf12f42..0be83b4d 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -1,11 +1,12 @@ package keeper import ( + "fmt" + "cosmossdk.io/collections" "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/math" - "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" @@ -279,24 +280,20 @@ func (k Keeper) PruneOldBitmaps(ctx sdk.Context, currentEpoch uint64) error { pruneHeight := int64(pruneBeforeEpoch * params.EpochLength) // Assuming EpochLength defines blocks per epoch // Prune attestation bitmaps (raw bitmaps) - attestationRange := collections.NewRange[int64]().EndExclusive(pruneHeight) + attestationRange := new(collections.Range[int64]).StartInclusive(0).EndExclusive(pruneHeight) if err := k.AttestationBitmap.Clear(ctx, attestationRange); err != nil { - k.Logger(ctx).Error("failed to prune old attestation bitmaps", "pruneHeight", pruneHeight, "error", err) - return err + return fmt.Errorf("clearing attestation bitmaps before height %d: %w", pruneHeight, err) } - // Prune stored attestation info (full AttestationBitmap objects) - storedAttestationInfoRange := collections.NewRange[int64]().EndExclusive(pruneHeight) + storedAttestationInfoRange := new(collections.Range[int64]).StartInclusive(0).EndExclusive(pruneHeight) if err := k.StoredAttestationInfo.Clear(ctx, storedAttestationInfoRange); err != nil { - k.Logger(ctx).Error("failed to prune old stored attestation info", "pruneHeight", pruneHeight, "error", err) - return err + return fmt.Errorf("clearing stored attestation info before height %d: %w", pruneHeight, err) } // Prune epoch bitmaps - epochRange := collections.NewRange[uint64]().EndExclusive(pruneBeforeEpoch) + epochRange := new(collections.Range[uint64]).StartInclusive(0).EndExclusive(pruneBeforeEpoch) if err := k.EpochBitmap.Clear(ctx, epochRange); err != nil { - k.Logger(ctx).Error("failed to prune old epoch bitmaps", "pruneBeforeEpoch", pruneBeforeEpoch, "error", err) - return err + return fmt.Errorf("clearing epoch bitmaps before epoch %d: %w", pruneBeforeEpoch, err) } // TODO: Consider pruning signatures associated with pruned heights. diff --git a/modules/network/module.go b/modules/network/module.go index 92c5f84a..d7b5fa40 100644 --- a/modules/network/module.go +++ b/modules/network/module.go @@ -5,209 +5,102 @@ import ( "encoding/json" "fmt" - "github.com/gorilla/mux" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/spf13/cobra" - - abci "github.com/tendermint/tendermint/abci/types" - + "cosmossdk.io/core/appmodule" + abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/rollkit/go-execution-abci/modules/network/client/cli" "github.com/rollkit/go-execution-abci/modules/network/keeper" "github.com/rollkit/go-execution-abci/modules/network/types" - "math/rand" ) var ( - _ module.AppModule = AppModule{} - _ module.AppModuleBasic = AppModuleBasic{} - _ module.AppModuleSimulation = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ appmodule.AppModule = AppModule{} + _ module.HasServices = AppModule{} + _ appmodule.HasBeginBlocker = AppModule{} + _ appmodule.HasEndBlocker = AppModule{} ) -// ---------------------------------------------------------------------------- -// AppModuleBasic -// ---------------------------------------------------------------------------- - -// AppModuleBasic implements the AppModuleBasic interface for the network module. type AppModuleBasic struct { cdc codec.Codec } -// NewAppModuleBasic creates a new AppModuleBasic object -func NewAppModuleBasic(cdc codec.Codec) AppModuleBasic { - return AppModuleBasic{cdc: cdc} -} - -// Name returns the network module's name. -func (AppModuleBasic) Name() string { - return types.ModuleName -} - -// RegisterLegacyAminoCodec registers the network module's types on the LegacyAmino codec. -func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { - types.RegisterCodec(cdc) -} - -// RegisterInterfaces registers the module's interface types -func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { - types.RegisterInterfaces(reg) -} - -// DefaultGenesis returns the network module's default genesis state. -func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { - return cdc.MustMarshalJSON(types.DefaultGenesisState()) -} - -// ValidateGenesis performs genesis state validation for the network module. -func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { - var genState types.GenesisState - if err := cdc.UnmarshalJSON(bz, &genState); err != nil { - return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) - } - return genState.Validate() -} - -// RegisterRESTRoutes registers the network module's REST service handlers. -func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { - // REST routes are deprecated -} - -// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. -func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { - types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) -} - -// GetTxCmd returns the network module's root tx command. -func (a AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.GetTxCmd() -} - -// GetQueryCmd returns the network module's root query command. -func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd(types.StoreKey) -} - -// ---------------------------------------------------------------------------- -// AppModule -// ---------------------------------------------------------------------------- - -// AppModule implements the AppModule interface for the network module. -type AppModule struct { - AppModuleBasic - - keeper keeper.Keeper - accountKeeper types.AccountKeeper - bankKeeper types.BankKeeper -} - // NewAppModule creates a new AppModule object func NewAppModule( cdc codec.Codec, keeper keeper.Keeper, - accountKeeper types.AccountKeeper, - bankKeeper types.BankKeeper, ) AppModule { return AppModule{ - AppModuleBasic: NewAppModuleBasic(cdc), + AppModuleBasic: AppModuleBasic{cdc: cdc}, keeper: keeper, - accountKeeper: accountKeeper, - bankKeeper: bankKeeper, } } -// Name returns the network module's name. -func (am AppModule) Name() string { - return am.AppModuleBasic.Name() -} - -// Route returns the network module's message routing key. -func (am AppModule) Route() sdk.Route { - return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) -} +type AppModule struct { + AppModuleBasic -// QuerierRoute returns the network module's query routing key. -func (AppModule) QuerierRoute() string { - return types.QuerierRoute + keeper keeper.Keeper } -// LegacyQuerierHandler returns the network module's Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { - return nil +// Name returns the network module's name +func (am AppModuleBasic) Name() string { + return types.ModuleName } -// RegisterServices registers a gRPC query service to respond to the -// module-specific gRPC queries. -func (am AppModule) RegisterServices(cfg module.Configurator) { - types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) - types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +// RegisterLegacyAminoCodec registers the network module's types on the given LegacyAmino codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) } -// RegisterInvariants registers the network module's invariants. -func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} - -// InitGenesis performs the network module's genesis initialization It returns -// no validator updates. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { - var genState types.GenesisState - cdc.MustUnmarshalJSON(gs, &genState) - InitGenesis(ctx, am.keeper, genState) - return []abci.ValidatorUpdate{} +// RegisterInterfaces registers the module's interface types +func (AppModuleBasic) RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) } -// ExportGenesis returns the network module's exported genesis state as raw JSON bytes. -func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { - genState := ExportGenesis(ctx, am.keeper) - return cdc.MustMarshalJSON(genState) +// ValidateGenesis performs genesis state validation for the network module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error { + var genesisState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genesisState); err != nil { + return fmt.Errorf("unmarshal genesis state: %w", err) + } + return genesisState.Validate() } -// ConsensusVersion implements AppModule/ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 1 } - -// BeginBlock executes all ABCI BeginBlock logic respective to the network module. -func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - am.keeper.BeginBlocker(ctx) +// InitGenesis performs genesis initialization for the staking module. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + if err := InitGenesis(ctx, am.keeper, genesisState); err != nil { + panic(fmt.Errorf("init genesis: %w", err)) + } + return nil } -// EndBlock executes all ABCI EndBlock logic respective to the network module. It -// returns no validator updates. -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - am.keeper.EndBlocker(ctx) - return []abci.ValidatorUpdate{} +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the network module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) { + if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil { + panic(err) + } } -// ---------------------------------------------------------------------------- -// AppModuleSimulation -// ---------------------------------------------------------------------------- +// IsAppModule implements the appmodule.AppModule interface. +func (am AppModule) IsAppModule() {} -// GenerateGenesisState creates a randomized GenState of the network module. -func (AppModule) GenerateGenesisState(simState *module.SimulationState) { - // TODO: Implement simulation -} - -// ProposalContents doesn't return any content functions for governance proposals. -func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { - return nil +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServer(am.keeper)) } -// RandomizedParams creates randomized network param changes for the simulator. -func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { - // TODO: Implement simulation - return nil +func (am AppModule) EndBlock(ctx context.Context) error { + return am.keeper.EndBlocker(sdk.UnwrapSDKContext(ctx)) } -// RegisterStoreDecoder registers a decoder for network module's types -func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) { - // TODO: Implement simulation +func (am AppModule) BeginBlock(ctx context.Context) error { + return am.keeper.BeginBlocker(sdk.UnwrapSDKContext(ctx)) } - -// WeightedOperations returns the all the network module operations with their respective weights. -func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - // TODO: Implement simulation - return nil -} \ No newline at end of file diff --git a/modules/network/module/v1/module.pb.go b/modules/network/module/v1/module.pb.go new file mode 100644 index 00000000..7d5cf5ab --- /dev/null +++ b/modules/network/module/v1/module.pb.go @@ -0,0 +1,329 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/module/v1/module.proto + +package v1 + +import ( + fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + + _ "cosmossdk.io/depinject/appconfig/v1alpha1" + proto "github.com/cosmos/gogoproto/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Module is the config object for the module. +type Module struct { + // authority defines the custom module authority. If not set, defaults to the + // governance module. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *Module) Reset() { *m = Module{} } +func (m *Module) String() string { return proto.CompactTextString(m) } +func (*Module) ProtoMessage() {} +func (*Module) Descriptor() ([]byte, []int) { + return fileDescriptor_f19001b7f9e2e548, []int{0} +} +func (m *Module) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Module) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Module.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Module) XXX_Merge(src proto.Message) { + xxx_messageInfo_Module.Merge(m, src) +} +func (m *Module) XXX_Size() int { + return m.Size() +} +func (m *Module) XXX_DiscardUnknown() { + xxx_messageInfo_Module.DiscardUnknown(m) +} + +var xxx_messageInfo_Module proto.InternalMessageInfo + +func (m *Module) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func init() { + proto.RegisterType((*Module)(nil), "rollkitsdk.network.module.v1.Module") +} + +func init() { + proto.RegisterFile("rollkitsdk/network/module/v1/module.proto", fileDescriptor_f19001b7f9e2e548) +} + +var fileDescriptor_f19001b7f9e2e548 = []byte{ + // 209 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2d, 0xca, 0xcf, 0xc9, + 0xc9, 0xce, 0x2c, 0x29, 0x4e, 0xc9, 0xd6, 0x87, 0x32, 0x73, 0xf3, 0xd2, 0x8b, 0xf4, 0x73, 0xf3, + 0x53, 0x4a, 0x73, 0x52, 0xf5, 0xcb, 0x0c, 0xa1, 0x2c, 0xbd, 0x82, 0xa2, 0xfc, 0x92, 0x7c, 0x21, + 0x05, 0x84, 0x72, 0x3d, 0x24, 0xe5, 0x7a, 0x50, 0x45, 0x65, 0x86, 0x52, 0x0a, 0xc9, 0xf9, 0xc5, + 0xb9, 0xf9, 0xc5, 0xfa, 0x89, 0x05, 0x05, 0xfa, 0x65, 0x86, 0x89, 0x39, 0x05, 0x19, 0x89, 0xa8, + 0x66, 0x28, 0x65, 0x70, 0xb1, 0xf9, 0x82, 0xf9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0xa5, 0x25, 0x19, + 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, 0x87, + 0x5d, 0x07, 0xa6, 0xdd, 0x62, 0xb4, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, + 0xce, 0xcf, 0x85, 0x39, 0x51, 0x3f, 0x3d, 0x5f, 0x37, 0xb5, 0x22, 0x35, 0xb9, 0xb4, 0x24, 0x33, + 0x3f, 0x4f, 0x37, 0x31, 0x29, 0x39, 0x13, 0x6a, 0x45, 0x31, 0xb2, 0x27, 0x9c, 0x22, 0x4f, 0x3c, + 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, + 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x9e, 0x5c, 0x33, 0xa1, 0x62, 0x49, 0x6c, + 0x60, 0xbf, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x98, 0x4f, 0x8c, 0x77, 0x40, 0x01, 0x00, + 0x00, +} + +func (m *Module) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Module) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Module) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintModule(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintModule(dAtA []byte, offset int, v uint64) int { + offset -= sovModule(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} + +func (m *Module) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovModule(uint64(l)) + } + return n +} + +func sovModule(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} + +func sozModule(x uint64) (n int) { + return sovModule(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func (m *Module) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wireType) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModule(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModule + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} + +func skipModule(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthModule + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupModule + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthModule + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthModule = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowModule = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupModule = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/network/types/codec.go b/modules/network/types/codec.go index 91ba2fa8..a6cfbf5f 100644 --- a/modules/network/types/codec.go +++ b/modules/network/types/codec.go @@ -35,4 +35,4 @@ var ( func init() { RegisterCodec(Amino) Amino.Seal() -} \ No newline at end of file +} diff --git a/modules/network/types/genesis.pb.go b/modules/network/types/genesis.pb.go index 1de93571..ac649b91 100644 --- a/modules/network/types/genesis.pb.go +++ b/modules/network/types/genesis.pb.go @@ -5,11 +5,12 @@ package types import ( fmt "fmt" - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" + + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/query.pb.go b/modules/network/types/query.pb.go index 0428c662..3231272c 100644 --- a/modules/network/types/query.pb.go +++ b/modules/network/types/query.pb.go @@ -6,6 +6,10 @@ package types import ( context "context" fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -14,9 +18,6 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/tx.pb.go b/modules/network/types/tx.pb.go index 5323919d..c0363a32 100644 --- a/modules/network/types/tx.pb.go +++ b/modules/network/types/tx.pb.go @@ -6,6 +6,10 @@ package types import ( context "context" fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" @@ -14,9 +18,6 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" - io "io" - math "math" - math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/types.pb.go b/modules/network/types/types.pb.go index eda96ff0..c0d8c4a5 100644 --- a/modules/network/types/types.pb.go +++ b/modules/network/types/types.pb.go @@ -5,13 +5,14 @@ package types import ( fmt "fmt" + io "io" + math "math" + math_bits "math/bits" + _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/protobuf/types/known/durationpb" - io "io" - math "math" - math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. From 9f0ed2239dff252bc6053462a43520c580591c0b Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 12 Jun 2025 17:15:21 +0200 Subject: [PATCH 03/21] Make proto-gen for network module --- Makefile | 4 +- modules/network/module/module.pb.go | 323 ++++++++++++++++++ modules/network/types/genesis.pb.go | 5 +- modules/network/types/query.pb.go | 7 +- modules/network/types/tx.pb.go | 7 +- modules/network/types/types.pb.go | 7 +- modules/proto/buf.lock | 4 +- .../rollkitsdk/network/module/v1/module.proto | 4 +- 8 files changed, 341 insertions(+), 20 deletions(-) create mode 100644 modules/network/module/module.pb.go diff --git a/Makefile b/Makefile index ac6720b8..5f006d86 100644 --- a/Makefile +++ b/Makefile @@ -70,10 +70,10 @@ proto-gen: go tool github.com/bufbuild/buf/cmd/buf dep update @cd modules/proto && \ go tool github.com/bufbuild/buf/cmd/buf generate - @mkdir -p modules/network/module/v1 @mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/types/** modules/rollkitmngr/types/ && \ mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/module/* modules/rollkitmngr/module/ && \ - mv modules/github.com/rollkit/go-execution-abci/modules/network/module/v1/* modules/network/module/v1/ + mv modules/github.com/rollkit/go-execution-abci/modules/network/types/** modules/network/types/ && \ + mv modules/github.com/rollkit/go-execution-abci/modules/network/module/* modules/network/module/ @rm -r modules/github.com .PHONY: proto-gen diff --git a/modules/network/module/module.pb.go b/modules/network/module/module.pb.go new file mode 100644 index 00000000..f1b619d1 --- /dev/null +++ b/modules/network/module/module.pb.go @@ -0,0 +1,323 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: rollkitsdk/network/module/v1/module.proto + +package module + +import ( + _ "cosmossdk.io/depinject/appconfig/v1alpha1" + fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Module is the config object for the module. +type Module struct { + // authority defines the custom module authority. If not set, defaults to the governance module. + Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` +} + +func (m *Module) Reset() { *m = Module{} } +func (m *Module) String() string { return proto.CompactTextString(m) } +func (*Module) ProtoMessage() {} +func (*Module) Descriptor() ([]byte, []int) { + return fileDescriptor_fc353625fec2db0a, []int{0} +} +func (m *Module) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Module) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Module.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Module) XXX_Merge(src proto.Message) { + xxx_messageInfo_Module.Merge(m, src) +} +func (m *Module) XXX_Size() int { + return m.Size() +} +func (m *Module) XXX_DiscardUnknown() { + xxx_messageInfo_Module.DiscardUnknown(m) +} + +var xxx_messageInfo_Module proto.InternalMessageInfo + +func (m *Module) GetAuthority() string { + if m != nil { + return m.Authority + } + return "" +} + +func init() { + proto.RegisterType((*Module)(nil), "rollkitsdk.network.module.v1.Module") +} + +func init() { + proto.RegisterFile("rollkitsdk/network/module/v1/module.proto", fileDescriptor_fc353625fec2db0a) +} + +var fileDescriptor_fc353625fec2db0a = []byte{ + // 211 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0xca, 0xcf, 0xc9, + 0xc9, 0xce, 0x2c, 0x29, 0x4e, 0xc9, 0xd6, 0xcf, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, 0xcf, + 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0xd5, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, + 0x85, 0x64, 0x10, 0x4a, 0xf5, 0xa0, 0x4a, 0xf5, 0xa0, 0x0a, 0xca, 0x0c, 0xa5, 0x14, 0x92, 0xf3, + 0x8b, 0x73, 0xf3, 0x8b, 0xf5, 0x13, 0x0b, 0x0a, 0xf4, 0xcb, 0x0c, 0x13, 0x73, 0x0a, 0x32, 0x12, + 0x51, 0xf5, 0x2b, 0xa5, 0x70, 0xb1, 0xf9, 0x82, 0xf9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0xa5, 0x25, + 0x19, 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, + 0x9b, 0x5d, 0x07, 0xa6, 0xdd, 0x62, 0x34, 0xe3, 0x32, 0x49, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x5a, 0xad, 0x9f, 0x9e, 0xaf, 0x9b, 0x5a, 0x91, 0x9a, 0x5c, 0x5a, + 0x92, 0x99, 0x9f, 0xa7, 0x9b, 0x98, 0x94, 0x9c, 0x09, 0xb5, 0xa2, 0x18, 0xe6, 0x78, 0xa7, 0xd0, + 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, + 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x26, 0xc7, 0x3c, 0x28, 0x3f, + 0x89, 0x0d, 0xec, 0x07, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0xa6, 0x39, 0x5a, 0x30, + 0x01, 0x00, 0x00, +} + +func (m *Module) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Module) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Module) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Authority) > 0 { + i -= len(m.Authority) + copy(dAtA[i:], m.Authority) + i = encodeVarintModule(dAtA, i, uint64(len(m.Authority))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintModule(dAtA []byte, offset int, v uint64) int { + offset -= sovModule(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Module) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Authority) + if l > 0 { + n += 1 + l + sovModule(uint64(l)) + } + return n +} + +func sovModule(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozModule(x uint64) (n int) { + return sovModule(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Module) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Module: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModule + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModule + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModule + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Authority = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModule(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModule + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipModule(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModule + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthModule + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupModule + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthModule + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthModule = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowModule = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupModule = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/network/types/genesis.pb.go b/modules/network/types/genesis.pb.go index ac649b91..1de93571 100644 --- a/modules/network/types/genesis.pb.go +++ b/modules/network/types/genesis.pb.go @@ -5,12 +5,11 @@ package types import ( fmt "fmt" + _ "github.com/cosmos/gogoproto/gogoproto" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" - - _ "github.com/cosmos/gogoproto/gogoproto" - proto "github.com/cosmos/gogoproto/proto" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/query.pb.go b/modules/network/types/query.pb.go index 3231272c..0428c662 100644 --- a/modules/network/types/query.pb.go +++ b/modules/network/types/query.pb.go @@ -6,10 +6,6 @@ package types import ( context "context" fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - _ "github.com/cosmos/cosmos-sdk/types/query" _ "github.com/cosmos/gogoproto/gogoproto" grpc1 "github.com/cosmos/gogoproto/grpc" @@ -18,6 +14,9 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/tx.pb.go b/modules/network/types/tx.pb.go index c0363a32..5323919d 100644 --- a/modules/network/types/tx.pb.go +++ b/modules/network/types/tx.pb.go @@ -6,10 +6,6 @@ package types import ( context "context" fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/cosmos-sdk/types/msgservice" _ "github.com/cosmos/gogoproto/gogoproto" @@ -18,6 +14,9 @@ import ( grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/network/types/types.pb.go b/modules/network/types/types.pb.go index c0d8c4a5..eda96ff0 100644 --- a/modules/network/types/types.pb.go +++ b/modules/network/types/types.pb.go @@ -5,14 +5,13 @@ package types import ( fmt "fmt" - io "io" - math "math" - math_bits "math/bits" - _ "github.com/cosmos/cosmos-proto" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" _ "google.golang.org/protobuf/types/known/durationpb" + io "io" + math "math" + math_bits "math/bits" ) // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/proto/buf.lock b/modules/proto/buf.lock index 7eed7030..e3a7af0f 100644 --- a/modules/proto/buf.lock +++ b/modules/proto/buf.lock @@ -5,8 +5,8 @@ deps: commit: 04467658e59e44bbb22fe568206e1f70 digest: b5:8058c0aadbee8c9af67a9cefe86492c6c0b0bd5b4526b0ec820507b91fc9b0b5efbebca97331854576d2d279b0b3f5ed6a7abb0640cb640c4186532239c48fc4 - name: buf.build/cosmos/cosmos-sdk - commit: 34ac2e8322d44db08830e553ad21b93c - digest: b5:381f54c53f533c6ff074a440a4635af5ac4041eb6533c8234b5395465a209b1ecd2722a004f198bcdde77346e0eb789e56213364bf28600619b86a314719ddfb + commit: 650cd9ad7f7a468e8e19975269958658 + digest: b5:652a0cd9aa3c220bb12b558f29b30ca5c248b994420472c9c2a54eed3d33356b1307e51687c1909ea4f535a2a1e180895b8cda83b58a4697003009d17fdbc154 - name: buf.build/cosmos/gogo-proto commit: 88ef6483f90f478fb938c37dde52ece3 digest: b5:f0c69202c9bca9672dc72a9737ea9bc83744daaed2b3da77e3a95b0e53b86dee76b5a7405b993181d6c863fd64afaca0976a302f700d6c4912eb1692a1782c0a diff --git a/modules/proto/rollkitsdk/network/module/v1/module.proto b/modules/proto/rollkitsdk/network/module/v1/module.proto index 304eef5a..9d51c2f7 100644 --- a/modules/proto/rollkitsdk/network/module/v1/module.proto +++ b/modules/proto/rollkitsdk/network/module/v1/module.proto @@ -4,7 +4,9 @@ package rollkitsdk.network.module.v1; import "cosmos/app/v1alpha1/module.proto"; -// Module is the config object for the network module. +option go_package = "github.com/rollkit/go-execution-abci/modules/network/module"; + +// Module is the config object for the module. message Module { option (cosmos.app.v1alpha1.module) = { go_import: "github.com/rollkit/go-execution-abci/modules/network" From f41977d1ca87011b907a36e92f26b8673ef53431 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Thu, 12 Jun 2025 18:58:33 +0200 Subject: [PATCH 04/21] Polish code; add tests --- audit.md | 75 +++++++++ modules/network/keeper/abci.go | 2 +- modules/network/keeper/grpc_query.go | 5 +- modules/network/keeper/keeper.go | 6 - modules/network/keeper/msg_server.go | 13 +- modules/network/keeper/msg_server_test.go | 182 ++++++++++++++++++++++ modules/network/types/expected_keepers.go | 1 + 7 files changed, 272 insertions(+), 12 deletions(-) create mode 100644 audit.md create mode 100644 modules/network/keeper/msg_server_test.go diff --git a/audit.md b/audit.md new file mode 100644 index 00000000..e0b08362 --- /dev/null +++ b/audit.md @@ -0,0 +1,75 @@ +# Network Module Audit + +## Overview +This document presents an audit of the network module in the go-execution-abci repository. The network module appears to be responsible for managing validator attestations, checkpoints, and consensus-related functionality. + +## TODOs and Incomplete Features + +1. **Missing IBC Packet Checking** + - In `keeper/abci.go`, line 21-22: `// TODO: Check for outbound IBC packets` + - The BeginBlocker has a placeholder for checking outbound IBC packets when in IBC_ONLY sign mode, but this functionality is not implemented. + +2. **Incomplete Validator Ejection Logic** + - In `keeper/abci.go`, line 145-146: `// TODO: Implement validator ejection logic` + - The `ejectLowParticipants` function is a stub that only logs a message but doesn't actually implement the ejection logic. + +3. **Missing Vote Signature Verification** + - In `keeper/msg_server.go`, line 59: `// TODO: Verify the vote signature here once we implement vote parsing` + - The `Attest` message handler doesn't verify the signature of the vote, which is a critical security feature. + +## Security Issues + +1. **Lack of Signature Verification** + - Attestations are accepted without verifying the signature of the vote, which could allow forged attestations. + - This is a critical security vulnerability that needs to be addressed before production use. + +2. ~~**Potential Panic in Epoch Processing**~~ + - In `keeper/abci.go`, line 129: `panic("Network module: No checkpoints achieved quorum in epoch")` + - The module panics if no checkpoints achieve quorum in an epoch, which could be triggered by network issues or validator downtime, potentially causing chain halts. + +3. **Limited Genesis State Validation** + - The `InitGenesis` function in `genesis.go` doesn't perform comprehensive validation of the genesis state beyond what's in the `Params.Validate()` method. + - Invalid genesis state could potentially be provided, leading to unexpected behavior. + +4. **Bitmap Index Bounds Checking** + - While the `BitmapHelper` in `keeper/bitmap.go` does include bounds checking for index operations, there's no validation that the bitmap size matches the expected validator set size when loading from storage. + +5. **No Rate Limiting for Attestations** + - There doesn't appear to be any rate limiting for attestation submissions, which could potentially be abused in a DoS attack. + +## Missing Features + +1. **Comprehensive Testing** + - The codebase lacks comprehensive test coverage, particularly for critical functions like checkpoint processing and quorum calculation. + +2. **Metrics and Monitoring** + - There are no metrics exposed for monitoring the health and performance of the network module. + +3. **Recovery Mechanisms** + - The module lacks graceful recovery mechanisms for handling edge cases like network partitions or mass validator downtime. + +4. **Documentation** + - Inline documentation is sparse, making it difficult to understand the intended behavior and security properties of the module. + +## Recommendations + +1. **Implement Missing Features** + - Complete all TODO items, particularly the signature verification and validator ejection logic. + - Add comprehensive testing for all critical paths. + +2. **Enhance Security** + - Implement proper signature verification for attestations. + - Replace the panic with a more graceful handling of the no-quorum scenario. + - Add rate limiting for message submission. + +3. **Improve Robustness** + - Add more comprehensive validation of inputs and state transitions. + - Implement recovery mechanisms for handling network issues. + +4. **Add Observability** + - Implement metrics for monitoring the health of the network module. + - Add more detailed logging for debugging purposes. + +5. **Enhance Documentation** + - Add comprehensive inline documentation explaining the purpose and security properties of each function. + - Create external documentation describing the overall design and security model of the module. \ No newline at end of file diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index 9bf41ff3..eb1838f3 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -126,7 +126,7 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { } if checkpointsInEpoch > 0 && softConfirmedCheckpoints == 0 { - panic("Network module: No checkpoints achieved quorum in epoch") + return fmt.Errorf("no checkpoints achieved quorum in epoch: %d", epoch) } } diff --git a/modules/network/keeper/grpc_query.go b/modules/network/keeper/grpc_query.go index 8a961542..22b0d039 100644 --- a/modules/network/keeper/grpc_query.go +++ b/modules/network/keeper/grpc_query.go @@ -104,7 +104,7 @@ func (q *queryServer) EpochInfo(c context.Context, req *types.QueryEpochInfoRequ StartHeight: startHeight, EndHeight: endHeight, ParticipationBitmap: epochBitmap, - ActiveValidators: activeValidators, + ActiveValidators: activeValidators, // TODO (Alex): we need the historic validator set instead ParticipatingValidators: participatingValidators, }, nil } @@ -116,7 +116,8 @@ func (q *queryServer) ValidatorIndex(c context.Context, req *types.QueryValidato } ctx := sdk.UnwrapSDKContext(c) - + // TODO (Alex): what is the use-case for this? The valset may change every epoch. + // A request height and historic data could be useful with EpochInfo bitmap index, found := q.keeper.GetValidatorIndex(ctx, req.Address) if !found { return nil, status.Error(codes.NotFound, "validator index not found") diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index 0be83b4d..a9cd4b90 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -39,21 +39,15 @@ type Keeper struct { func NewKeeper( cdc codec.BinaryCodec, storeService store.KVStoreService, // Changed from sdk.StoreKey - ps paramtypes.Subspace, sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, authority string, ) Keeper { - // set KeyTable if it has not already been set - if !ps.HasKeyTable() { - ps = ps.WithKeyTable(types.ParamKeyTable()) - } sb := collections.NewSchemaBuilder(storeService) keeper := Keeper{ cdc: cdc, - paramstore: ps, stakingKeeper: sk, accountKeeper: ak, bankKeeper: bk, diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index ad334333..f79cd376 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -40,6 +40,8 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator index not found for %s", msg.Validator) } + // todo (Alex): we need to set a limit to not have validators attest old blocks. Also make sure that this relates with + // the retention period for pruning bitmap := k.GetAttestationBitmap(ctx, msg.Height) if bitmap == nil { validators := k.stakingKeeper.GetLastValidators(ctx) @@ -119,8 +121,10 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte if k.IsInAttesterSet(ctx, msg.Validator) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator already in attester set") } - - k.SetAttesterSetMember(ctx, msg.Validator) + // TODO (Alex): the valset should be updated at the end of an epoch only + if err := k.SetAttesterSetMember(ctx, msg.Validator); err != nil { + return nil, errors.Wrap(err, "failed to set attester set member") + } ctx.EventManager().EmitEvent( sdk.NewEvent( @@ -140,7 +144,10 @@ func (k msgServer) LeaveAttesterSet(goCtx context.Context, msg *types.MsgLeaveAt return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator not in attester set") } - k.RemoveAttesterSetMember(ctx, msg.Validator) + // TODO (Alex): the valset should be updated at the end of an epoch only + if err := k.RemoveAttesterSetMember(ctx, msg.Validator); err != nil { + return nil, errors.Wrap(err, "failed to remove attester set member") + } ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go new file mode 100644 index 00000000..8cb76564 --- /dev/null +++ b/modules/network/keeper/msg_server_test.go @@ -0,0 +1,182 @@ +package keeper + +import ( + "context" + "cosmossdk.io/log" + storetypes "cosmossdk.io/store/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil/integration" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/stretchr/testify/assert" + "maps" + "slices" + "strings" + "testing" + "time" + + "cosmossdk.io/math" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/rollkit/go-execution-abci/modules/network/types" + "github.com/stretchr/testify/require" +) + +func TestJoinAttesterSet(t *testing.T) { + myValAddr := sdk.ValAddress("validator4") + + type testCase struct { + setup func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) + msg *types.MsgJoinAttesterSet + expErr error + expSet bool + } + + tests := map[string]testCase{ + "valid": { + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) { + validator := stakingtypes.Validator{ + OperatorAddress: myValAddr.String(), + Status: stakingtypes.Bonded, + } + err := sk.SetValidator(ctx, validator) + require.NoError(t, err, "failed to set validator") + }, + msg: &types.MsgJoinAttesterSet{Validator: myValAddr.String()}, + expSet: true, + }, + "invalid_addr": { + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) {}, + msg: &types.MsgJoinAttesterSet{Validator: "invalidAddr"}, + expErr: sdkerrors.ErrInvalidAddress, + }, + "val not exists": { + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) {}, + msg: &types.MsgJoinAttesterSet{Validator: myValAddr.String()}, + expErr: sdkerrors.ErrNotFound, + }, + "val not bonded": { + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) { + validator := stakingtypes.Validator{ + OperatorAddress: myValAddr.String(), + Status: stakingtypes.Unbonded, // Validator is not bonded + } + err := sk.SetValidator(ctx, validator) + require.NoError(t, err, "failed to set validator") + }, + msg: &types.MsgJoinAttesterSet{Validator: myValAddr.String()}, + expErr: sdkerrors.ErrInvalidRequest, + }, + "already set": { + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) { + validator := stakingtypes.Validator{ + OperatorAddress: myValAddr.String(), + Status: stakingtypes.Bonded, + } + require.NoError(t, sk.SetValidator(ctx, validator)) + require.NoError(t, keeper.SetAttesterSetMember(ctx, myValAddr.String())) + }, + msg: &types.MsgJoinAttesterSet{Validator: myValAddr.String()}, + expErr: sdkerrors.ErrInvalidRequest, + expSet: true, + }, + //{ + // name: "failed to set attester set member", + // setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) { + // validatorAddr := sdk.ValAddress([]byte("validator5")) + // validator := stakingtypes.Validator{ + // OperatorAddress: validatorAddr.String(), + // Status: stakingtypes.Bonded, + // } + // err := sk.SetValidator(ctx, validator) + // require.NoError(t, err, "failed to set validator") + // keeper.forceError = true + // }, + // msg: &types.MsgJoinAttesterSet{ + // Validator: "validator5", + // }, + // expErr: sdkerrors.ErrInternal, + // expectResponse: false, + //}, + } + + for name, spec := range tests { + t.Run(name, func(t *testing.T) { + sk := NewMockStakingKeeper() + + cdc := moduletestutil.MakeTestEncodingConfig().Codec + + keys := storetypes.NewKVStoreKeys(types.StoreKey) + + logger := log.NewTestLogger(t) + cms := integration.CreateMultiStore(keys, logger) + authority := authtypes.NewModuleAddress("gov") + keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), sk, nil, nil, authority.String()) + server := msgServer{Keeper: keeper} + ctx := sdk.NewContext(cms, cmtproto.Header{ChainID: "test-chain", Time: time.Now().UTC(), Height: 10}, false, logger). + WithContext(t.Context()) + + spec.setup(t, ctx, &keeper, &sk) + + // when + rsp, err := server.JoinAttesterSet(ctx, spec.msg) + // then + if spec.expErr != nil { + require.ErrorIs(t, err, spec.expErr) + require.Nil(t, rsp) + exists, gotErr := keeper.AttesterSet.Has(ctx, spec.msg.Validator) + require.NoError(t, gotErr) + assert.Equal(t, exists, spec.expSet) + return + } + require.NoError(t, err) + require.NotNil(t, rsp) + exists, gotErr := keeper.AttesterSet.Has(ctx, spec.msg.Validator) + require.NoError(t, gotErr) + assert.True(t, exists) + }) + } +} + +var _ types.StakingKeeper = &MockStakingKeeper{} + +type MockStakingKeeper struct { + activeSet map[string]stakingtypes.Validator +} + +func NewMockStakingKeeper() MockStakingKeeper { + return MockStakingKeeper{ + activeSet: make(map[string]stakingtypes.Validator), + } +} + +func (m *MockStakingKeeper) SetValidator(ctx context.Context, validator stakingtypes.Validator) error { + m.activeSet[validator.GetOperator()] = validator + return nil + +} +func (m MockStakingKeeper) GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { + return slices.SortedFunc(maps.Values(m.activeSet), func(v1 stakingtypes.Validator, v2 stakingtypes.Validator) int { + return strings.Compare(v1.OperatorAddress, v2.OperatorAddress) + }) +} + +func (m MockStakingKeeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) { + validator, found = m.activeSet[addr.String()] + return +} + +func (m MockStakingKeeper) GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { + for _, validator := range m.activeSet { + if validator.IsBonded() { // Assuming IsBonded() identifies if a validator is in the last validators + validators = append(validators, validator) + } + } + return +} + +func (m MockStakingKeeper) GetLastTotalPower(ctx sdk.Context) math.Int { + return math.NewInt(int64(len(m.activeSet))) +} diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go index c1a99579..ddf0bcf7 100644 --- a/modules/network/types/expected_keepers.go +++ b/modules/network/types/expected_keepers.go @@ -12,6 +12,7 @@ type StakingKeeper interface { GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) GetLastTotalPower(ctx sdk.Context) math.Int + //GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, error) } // AccountKeeper defines the expected account keeper interface From ff313fd096d5423bc38df2a739f4164179528a27 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 13 Jun 2025 08:32:51 +0200 Subject: [PATCH 05/21] Compile after merge --- modules/network/depinject.go | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/network/depinject.go b/modules/network/depinject.go index ba2ec52c..8eecbad5 100644 --- a/modules/network/depinject.go +++ b/modules/network/depinject.go @@ -56,7 +56,6 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { k := keeper.NewKeeper( in.Cdc, in.StoreService, - in.ParamsSubspace, in.StakingKeeper, in.AccountKeeper, in.BankKeeper, From dafb0db163d1c9c23c820c72f6f871396f090455 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 13 Jun 2025 16:57:38 +0200 Subject: [PATCH 06/21] x --- Makefile | 2 +- README.md | 32 +- modules/network/depinject.go | 15 +- modules/network/genesis.go | 5 +- modules/network/keeper/abci.go | 10 +- modules/network/keeper/grpc_query.go | 33 +- modules/network/keeper/keeper.go | 38 ++- modules/network/keeper/msg_server.go | 16 +- modules/network/module.go | 37 +- modules/network/module/module.pb.go | 323 ------------------ modules/network/module/v1/module.pb.go | 50 ++- modules/network/types/expected_keepers.go | 14 +- modules/network/types/keys.go | 3 +- .../rollkitsdk/network/module/v1/module.proto | 4 +- pkg/adapter/adapter.go | 120 ++++--- pkg/adapter/adapter_test.go | 2 +- pkg/adapter/options.go | 74 ++++ server/start.go | 25 +- 18 files changed, 304 insertions(+), 499 deletions(-) delete mode 100644 modules/network/module/module.pb.go create mode 100644 pkg/adapter/options.go diff --git a/Makefile b/Makefile index 5f006d86..b69f16f5 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ proto-gen: @mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/types/** modules/rollkitmngr/types/ && \ mv modules/github.com/rollkit/go-execution-abci/modules/rollkitmngr/module/* modules/rollkitmngr/module/ && \ mv modules/github.com/rollkit/go-execution-abci/modules/network/types/** modules/network/types/ && \ - mv modules/github.com/rollkit/go-execution-abci/modules/network/module/* modules/network/module/ + mv modules/github.com/rollkit/go-execution-abci/modules/network/module/v1/* modules/network/module/v1 @rm -r modules/github.com .PHONY: proto-gen diff --git a/README.md b/README.md index 89914bf6..131acd86 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ graph TD E[Mempool] <--> B F[RPC Server] --> B B --> G[Store] - + subgraph "Rollkit" A end - + subgraph "go-execution-abci" B D @@ -34,11 +34,11 @@ graph TD F G end - + subgraph "Application" C end - + style B fill:#f9f,stroke:#333,stroke-width:2px style A fill:#bbf,stroke:#333,stroke-width:1px style C fill:#bfb,stroke:#333,stroke-width:1px @@ -87,6 +87,8 @@ executor := adapter.NewABCIExecutor( logger, // Logger config, // CometBFT config appGenesis, // Application genesis + nil, // Metrics (optional) + // Optional: custom block publisher, metrics,... ) // Set up mempool for transaction handling @@ -110,26 +112,26 @@ sequenceDiagram participant Mempool participant Adapter participant ABCI App - + Client->>P2P Network: Submit Tx P2P Network->>Mempool: Gossip Tx Mempool->>Adapter: CheckTx Adapter->>ABCI App: CheckTx ABCI App-->>Adapter: Response - + Note over Adapter: Block Creation Time - + Adapter->>Adapter: GetTxs Adapter->>ABCI App: PrepareProposal ABCI App-->>Adapter: Txs - + Note over Adapter: Block Execution - + Adapter->>ABCI App: ProcessProposal ABCI App-->>Adapter: Accept/Reject Adapter->>ABCI App: FinalizeBlock ABCI App-->>Adapter: AppHash - + Adapter->>ABCI App: Commit ``` @@ -172,7 +174,7 @@ classDiagram +GetTxs() +SetFinal() } - + class Executor { <> +InitChain() @@ -180,7 +182,7 @@ classDiagram +GetTxs() +SetFinal() } - + class ABCI { <> +InitChain() @@ -189,18 +191,18 @@ classDiagram +FinalizeBlock() +Commit() } - + class Mempool { +CheckTx() +ReapMaxBytesMaxGas() } - + class Store { +Get() +Set() +Height() } - + Executor <|.. Adapter : implements Adapter o-- ABCI : uses Adapter o-- Mempool : uses diff --git a/modules/network/depinject.go b/modules/network/depinject.go index 8eecbad5..f641787f 100644 --- a/modules/network/depinject.go +++ b/modules/network/depinject.go @@ -8,8 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/rollkit/go-execution-abci/modules/network/keeper" modulev1 "github.com/rollkit/go-execution-abci/modules/network/module/v1" "github.com/rollkit/go-execution-abci/modules/network/types" @@ -30,13 +28,12 @@ func init() { type ModuleInputs struct { depinject.In - Config *modulev1.Module - Cdc codec.Codec - StoreService store.KVStoreService - ParamsSubspace paramtypes.Subspace - StakingKeeper types.StakingKeeper - AccountKeeper types.AccountKeeper - BankKeeper types.BankKeeper + Config *modulev1.Module + Cdc codec.Codec + StoreService store.KVStoreService + StakingKeeper types.StakingKeeper + AccountKeeper types.AccountKeeper + BankKeeper types.BankKeeper } type ModuleOutputs struct { diff --git a/modules/network/genesis.go b/modules/network/genesis.go index 54415d5a..6c2e8f52 100644 --- a/modules/network/genesis.go +++ b/modules/network/genesis.go @@ -1,6 +1,7 @@ package network import ( + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/rollkit/go-execution-abci/modules/network/keeper" @@ -10,7 +11,9 @@ import ( // InitGenesis initializes the network module's state from a provided genesis state. func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) error { // Set module params - k.SetParams(ctx, genState.Params) + if err := k.SetParams(ctx, genState.Params); err != nil { + return fmt.Errorf("set params: %s", err) + } // Set validator indices for _, vi := range genState.ValidatorIndices { diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index eb1838f3..b2c0e262 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -57,7 +57,10 @@ func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) error { } votedPower := k.CalculateVotedPower(ctx, bitmapBytes) - totalPower := k.GetTotalPower(ctx) + totalPower, err := k.GetTotalPower(ctx) + if err != nil { + return err + } validatorHash := sha256.Sum256(bitmapBytes) @@ -87,7 +90,10 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { epochBitmap := k.GetEpochBitmap(ctx, epoch) if epochBitmap != nil { - validators := k.stakingKeeper.GetLastValidators(ctx) + validators, err := k.stakingKeeper.GetLastValidators(ctx) + if err != nil { + return fmt.Errorf("getting last validators: %w", err) + } totalBondedValidators := 0 for _, v := range validators { if v.IsBonded() { diff --git a/modules/network/keeper/grpc_query.go b/modules/network/keeper/grpc_query.go index 22b0d039..a49b1fb1 100644 --- a/modules/network/keeper/grpc_query.go +++ b/modules/network/keeper/grpc_query.go @@ -48,7 +48,11 @@ func (q *queryServer) AttestationBitmap(c context.Context, req *types.QueryAttes // Reconstruct attestation info using keeper methods votedPower := q.keeper.CalculateVotedPower(ctx, bitmapBytes) - totalPower := q.keeper.GetTotalPower(ctx) + totalPower, err := q.keeper.GetTotalPower(ctx) + if err != nil { + return nil, err + } + // Assuming IsSoftConfirmed is a method on the Keeper // If not, you might need to add it or compute it here using keeper.CheckQuorum softConfirmed := q.keeper.IsSoftConfirmed(ctx, req.Height) @@ -89,7 +93,10 @@ func (q *queryServer) EpochInfo(c context.Context, req *types.QueryEpochInfoRequ }, nil } - validators := q.keeper.stakingKeeper.GetLastValidators(ctx) + validators, err := q.keeper.stakingKeeper.GetLastValidators(ctx) + if err != nil { + return nil, err + } activeValidators := uint64(0) for _, v := range validators { if v.IsBonded() { @@ -141,26 +148,22 @@ func (q *queryServer) SoftConfirmationStatus(c context.Context, req *types.Query } ctx := sdk.UnwrapSDKContext(c) - params := q.keeper.GetParams(ctx) - + isSoftConfirmed := q.keeper.IsSoftConfirmed(ctx, req.Height) bitmap := q.keeper.GetAttestationBitmap(ctx, req.Height) - if bitmap == nil { - return &types.QuerySoftConfirmationStatusResponse{ - IsSoftConfirmed: false, - VotedPower: 0, - TotalPower: q.keeper.GetTotalPower(ctx), - QuorumFraction: params.QuorumFraction, - }, nil + totalPower, err := q.keeper.GetTotalPower(ctx) + if err != nil { + return nil, err } - votedPower := q.keeper.CalculateVotedPower(ctx, bitmap) - totalPower := q.keeper.GetTotalPower(ctx) - isSoftConfirmed := q.keeper.CheckQuorum(ctx, votedPower, totalPower) + var votedPower uint64 + if bitmap != nil { + votedPower = q.keeper.CalculateVotedPower(ctx, bitmap) + } return &types.QuerySoftConfirmationStatusResponse{ IsSoftConfirmed: isSoftConfirmed, VotedPower: votedPower, TotalPower: totalPower, - QuorumFraction: params.QuorumFraction, + QuorumFraction: q.keeper.GetParams(ctx).QuorumFraction, }, nil } diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index a9cd4b90..4fa0de95 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -9,15 +9,12 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/rollkit/go-execution-abci/modules/network/types" ) // Keeper of the network store type Keeper struct { cdc codec.BinaryCodec - paramstore paramtypes.Subspace stakingKeeper types.StakingKeeper accountKeeper types.AccountKeeper bankKeeper types.BankKeeper @@ -33,6 +30,7 @@ type Keeper struct { AttesterSet collections.KeySet[string] Signatures collections.Map[collections.Pair[int64, string], []byte] StoredAttestationInfo collections.Map[int64, types.AttestationBitmap] + Params collections.Item[types.Params] } // NewKeeper creates a new network Keeper instance @@ -61,6 +59,7 @@ func NewKeeper( AttesterSet: collections.NewKeySet(sb, types.AttesterSetPrefix, "attester_set", collections.StringKey), Signatures: collections.NewMap(sb, types.SignaturePrefix, "signatures", collections.PairKeyCodec(collections.Int64Key, collections.StringKey), collections.BytesValue), StoredAttestationInfo: collections.NewMap(sb, types.StoredAttestationInfoPrefix, "stored_attestation_info", collections.Int64Key, codec.CollValue[types.AttestationBitmap](cdc)), // Initialize new collection + Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), } // The schema is built implicitly when the first collection is created or can be explicitly built. @@ -85,14 +84,13 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { // GetParams get all parameters as types.Params func (k Keeper) GetParams(ctx sdk.Context) types.Params { - var params types.Params - k.paramstore.GetParamSet(ctx, ¶ms) - return params + p, _ := k.Params.Get(ctx) + return p } // SetParams set the params -func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { - k.paramstore.SetParamSet(ctx, ¶ms) +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) error { + return k.Params.Set(ctx, params) } // SetValidatorIndex stores the validator index mapping and power @@ -175,7 +173,10 @@ func (k Keeper) RemoveAttesterSetMember(ctx sdk.Context, addr string) error { // BuildValidatorIndexMap rebuilds the validator index mapping func (k Keeper) BuildValidatorIndexMap(ctx sdk.Context) error { - validators := k.stakingKeeper.GetAllValidators(ctx) + validators, err := k.stakingKeeper.GetAllValidators(ctx) + if err != nil { + return err + } // Clear existing indices and powers // The `nil` range clears all entries in the collection. @@ -213,7 +214,11 @@ func (k Keeper) GetCurrentEpoch(ctx sdk.Context) uint64 { // IsCheckpointHeight checks if a height is a checkpoint func (k Keeper) IsCheckpointHeight(ctx sdk.Context, height int64) bool { - params := k.GetParams(ctx) + p, err := k.Params.Get(ctx) + if err != nil { + return false + } + params := p return uint64(height)%params.EpochLength == 0 } @@ -230,8 +235,12 @@ func (k Keeper) CalculateVotedPower(ctx sdk.Context, bitmap []byte) uint64 { } // GetTotalPower returns the total staking power -func (k Keeper) GetTotalPower(ctx sdk.Context) uint64 { - return uint64(k.stakingKeeper.GetLastTotalPower(ctx).Int64()) +func (k Keeper) GetTotalPower(ctx sdk.Context) (uint64, error) { + n, err := k.stakingKeeper.GetLastTotalPower(ctx) + if err != nil { + return 0, err + } + return n.Uint64(), nil } // CheckQuorum checks if the voted power meets quorum @@ -255,7 +264,10 @@ func (k Keeper) IsSoftConfirmed(ctx sdk.Context, height int64) bool { } votedPower := k.CalculateVotedPower(ctx, bitmap) - totalPower := k.GetTotalPower(ctx) // Assuming this gets the relevant total power for the height + totalPower, err := k.GetTotalPower(ctx) // Assuming this gets the relevant total power for the height + if err != nil { + return false + } return k.CheckQuorum(ctx, votedPower, totalPower) } diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index f79cd376..5d94dde6 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -44,7 +44,10 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M // the retention period for pruning bitmap := k.GetAttestationBitmap(ctx, msg.Height) if bitmap == nil { - validators := k.stakingKeeper.GetLastValidators(ctx) + validators, err := k.stakingKeeper.GetLastValidators(ctx) + if err != nil { + return nil, err + } numValidators := 0 for _, v := range validators { if v.IsBonded() { @@ -74,7 +77,10 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M epoch := k.GetCurrentEpoch(ctx) epochBitmap := k.GetEpochBitmap(ctx, epoch) if epochBitmap == nil { - validators := k.stakingKeeper.GetLastValidators(ctx) + validators, err := k.stakingKeeper.GetLastValidators(ctx) + if err != nil { + return nil, err + } numValidators := 0 for _, v := range validators { if v.IsBonded() { @@ -109,9 +115,9 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte return nil, errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address: %s", err) } - validator, found := k.stakingKeeper.GetValidator(ctx, valAddr) - if !found { - return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator not found: %s", msg.Validator) + validator, err := k.stakingKeeper.GetValidator(ctx, valAddr) + if err != nil { + return nil, err } if !validator.IsBonded() { diff --git a/modules/network/module.go b/modules/network/module.go index d7b5fa40..aff4df5d 100644 --- a/modules/network/module.go +++ b/modules/network/module.go @@ -6,7 +6,6 @@ import ( "fmt" "cosmossdk.io/core/appmodule" - abci "github.com/cometbft/cometbft/abci/types" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" cdctypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -22,6 +21,7 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} _ appmodule.AppModule = AppModule{} _ module.HasServices = AppModule{} + _ module.HasGenesis = AppModule{} _ appmodule.HasBeginBlocker = AppModule{} _ appmodule.HasEndBlocker = AppModule{} ) @@ -41,12 +41,6 @@ func NewAppModule( } } -type AppModule struct { - AppModuleBasic - - keeper keeper.Keeper -} - // Name returns the network module's name func (am AppModuleBasic) Name() string { return types.ModuleName @@ -71,14 +65,9 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod return genesisState.Validate() } -// InitGenesis performs genesis initialization for the staking module. -func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { - var genesisState types.GenesisState - cdc.MustUnmarshalJSON(data, &genesisState) - if err := InitGenesis(ctx, am.keeper, genesisState); err != nil { - panic(fmt.Errorf("init genesis: %w", err)) - } - return nil +// DefaultGenesis returns default genesis state as raw bytes. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) } // RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the network module. @@ -88,6 +77,24 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *g } } +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper +} + +// InitGenesis performs genesis initialization for the staking module. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + if err := InitGenesis(ctx, am.keeper, genesisState); err != nil { + panic(fmt.Errorf("init genesis: %w", err)) + } +} +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(ExportGenesis(ctx, am.keeper)) +} + // IsAppModule implements the appmodule.AppModule interface. func (am AppModule) IsAppModule() {} diff --git a/modules/network/module/module.pb.go b/modules/network/module/module.pb.go deleted file mode 100644 index f1b619d1..00000000 --- a/modules/network/module/module.pb.go +++ /dev/null @@ -1,323 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: rollkitsdk/network/module/v1/module.proto - -package module - -import ( - _ "cosmossdk.io/depinject/appconfig/v1alpha1" - fmt "fmt" - proto "github.com/cosmos/gogoproto/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// Module is the config object for the module. -type Module struct { - // authority defines the custom module authority. If not set, defaults to the governance module. - Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` -} - -func (m *Module) Reset() { *m = Module{} } -func (m *Module) String() string { return proto.CompactTextString(m) } -func (*Module) ProtoMessage() {} -func (*Module) Descriptor() ([]byte, []int) { - return fileDescriptor_fc353625fec2db0a, []int{0} -} -func (m *Module) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Module) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Module.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Module) XXX_Merge(src proto.Message) { - xxx_messageInfo_Module.Merge(m, src) -} -func (m *Module) XXX_Size() int { - return m.Size() -} -func (m *Module) XXX_DiscardUnknown() { - xxx_messageInfo_Module.DiscardUnknown(m) -} - -var xxx_messageInfo_Module proto.InternalMessageInfo - -func (m *Module) GetAuthority() string { - if m != nil { - return m.Authority - } - return "" -} - -func init() { - proto.RegisterType((*Module)(nil), "rollkitsdk.network.module.v1.Module") -} - -func init() { - proto.RegisterFile("rollkitsdk/network/module/v1/module.proto", fileDescriptor_fc353625fec2db0a) -} - -var fileDescriptor_fc353625fec2db0a = []byte{ - // 211 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0xca, 0xcf, 0xc9, - 0xc9, 0xce, 0x2c, 0x29, 0x4e, 0xc9, 0xd6, 0xcf, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, 0xcf, - 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0xd5, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, - 0x85, 0x64, 0x10, 0x4a, 0xf5, 0xa0, 0x4a, 0xf5, 0xa0, 0x0a, 0xca, 0x0c, 0xa5, 0x14, 0x92, 0xf3, - 0x8b, 0x73, 0xf3, 0x8b, 0xf5, 0x13, 0x0b, 0x0a, 0xf4, 0xcb, 0x0c, 0x13, 0x73, 0x0a, 0x32, 0x12, - 0x51, 0xf5, 0x2b, 0xa5, 0x70, 0xb1, 0xf9, 0x82, 0xf9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0xa5, 0x25, - 0x19, 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, - 0x9b, 0x5d, 0x07, 0xa6, 0xdd, 0x62, 0x34, 0xe3, 0x32, 0x49, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, - 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x5a, 0xad, 0x9f, 0x9e, 0xaf, 0x9b, 0x5a, 0x91, 0x9a, 0x5c, 0x5a, - 0x92, 0x99, 0x9f, 0xa7, 0x9b, 0x98, 0x94, 0x9c, 0x09, 0xb5, 0xa2, 0x18, 0xe6, 0x78, 0xa7, 0xd0, - 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, - 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x26, 0xc7, 0x3c, 0x28, 0x3f, - 0x89, 0x0d, 0xec, 0x07, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe4, 0xa6, 0x39, 0x5a, 0x30, - 0x01, 0x00, 0x00, -} - -func (m *Module) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Module) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Module) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.Authority) > 0 { - i -= len(m.Authority) - copy(dAtA[i:], m.Authority) - i = encodeVarintModule(dAtA, i, uint64(len(m.Authority))) - i-- - dAtA[i] = 0xa - } - return len(dAtA) - i, nil -} - -func encodeVarintModule(dAtA []byte, offset int, v uint64) int { - offset -= sovModule(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Module) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - l = len(m.Authority) - if l > 0 { - n += 1 + l + sovModule(uint64(l)) - } - return n -} - -func sovModule(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozModule(x uint64) (n int) { - return sovModule(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Module) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModule - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Module: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Authority", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModule - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModule - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModule - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Authority = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipModule(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthModule - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipModule(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowModule - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowModule - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowModule - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthModule - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupModule - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthModule - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthModule = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowModule = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupModule = fmt.Errorf("proto: unexpected end of group") -) diff --git a/modules/network/module/v1/module.pb.go b/modules/network/module/v1/module.pb.go index 7d5cf5ab..fea65b08 100644 --- a/modules/network/module/v1/module.pb.go +++ b/modules/network/module/v1/module.pb.go @@ -4,13 +4,12 @@ package v1 import ( + _ "cosmossdk.io/depinject/appconfig/v1alpha1" fmt "fmt" + proto "github.com/cosmos/gogoproto/proto" io "io" math "math" math_bits "math/bits" - - _ "cosmossdk.io/depinject/appconfig/v1alpha1" - proto "github.com/cosmos/gogoproto/proto" ) // Reference imports to suppress errors if they are not otherwise used. @@ -26,8 +25,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Module is the config object for the module. type Module struct { - // authority defines the custom module authority. If not set, defaults to the - // governance module. + // authority defines the custom module authority. If not set, defaults to the governance module. Authority string `protobuf:"bytes,1,opt,name=authority,proto3" json:"authority,omitempty"` } @@ -35,7 +33,7 @@ func (m *Module) Reset() { *m = Module{} } func (m *Module) String() string { return proto.CompactTextString(m) } func (*Module) ProtoMessage() {} func (*Module) Descriptor() ([]byte, []int) { - return fileDescriptor_f19001b7f9e2e548, []int{0} + return fileDescriptor_fc353625fec2db0a, []int{0} } func (m *Module) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -76,25 +74,25 @@ func init() { } func init() { - proto.RegisterFile("rollkitsdk/network/module/v1/module.proto", fileDescriptor_f19001b7f9e2e548) + proto.RegisterFile("rollkitsdk/network/module/v1/module.proto", fileDescriptor_fc353625fec2db0a) } -var fileDescriptor_f19001b7f9e2e548 = []byte{ - // 209 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2d, 0xca, 0xcf, 0xc9, - 0xc9, 0xce, 0x2c, 0x29, 0x4e, 0xc9, 0xd6, 0x87, 0x32, 0x73, 0xf3, 0xd2, 0x8b, 0xf4, 0x73, 0xf3, - 0x53, 0x4a, 0x73, 0x52, 0xf5, 0xcb, 0x0c, 0xa1, 0x2c, 0xbd, 0x82, 0xa2, 0xfc, 0x92, 0x7c, 0x21, - 0x05, 0x84, 0x72, 0x3d, 0x24, 0xe5, 0x7a, 0x50, 0x45, 0x65, 0x86, 0x52, 0x0a, 0xc9, 0xf9, 0xc5, - 0xb9, 0xf9, 0xc5, 0xfa, 0x89, 0x05, 0x05, 0xfa, 0x65, 0x86, 0x89, 0x39, 0x05, 0x19, 0x89, 0xa8, - 0x66, 0x28, 0x65, 0x70, 0xb1, 0xf9, 0x82, 0xf9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0xa5, 0x25, 0x19, - 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, 0x87, - 0x5d, 0x07, 0xa6, 0xdd, 0x62, 0xb4, 0xe2, 0xb2, 0x48, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, - 0xce, 0xcf, 0x85, 0x39, 0x51, 0x3f, 0x3d, 0x5f, 0x37, 0xb5, 0x22, 0x35, 0xb9, 0xb4, 0x24, 0x33, - 0x3f, 0x4f, 0x37, 0x31, 0x29, 0x39, 0x13, 0x6a, 0x45, 0x31, 0xb2, 0x27, 0x9c, 0x22, 0x4f, 0x3c, - 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, - 0x3c, 0x96, 0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0xca, 0x9e, 0x5c, 0x33, 0xa1, 0x62, 0x49, 0x6c, - 0x60, 0xbf, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x98, 0x4f, 0x8c, 0x77, 0x40, 0x01, 0x00, - 0x00, +var fileDescriptor_fc353625fec2db0a = []byte{ + // 211 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x2c, 0xca, 0xcf, 0xc9, + 0xc9, 0xce, 0x2c, 0x29, 0x4e, 0xc9, 0xd6, 0xcf, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, 0xcf, + 0xcd, 0x4f, 0x29, 0xcd, 0x49, 0xd5, 0x2f, 0x33, 0x84, 0xb2, 0xf4, 0x0a, 0x8a, 0xf2, 0x4b, 0xf2, + 0x85, 0x64, 0x10, 0x4a, 0xf5, 0xa0, 0x4a, 0xf5, 0xa0, 0x0a, 0xca, 0x0c, 0xa5, 0x14, 0x92, 0xf3, + 0x8b, 0x73, 0xf3, 0x8b, 0xf5, 0x13, 0x0b, 0x0a, 0xf4, 0xcb, 0x0c, 0x13, 0x73, 0x0a, 0x32, 0x12, + 0x51, 0xf5, 0x2b, 0xa5, 0x70, 0xb1, 0xf9, 0x82, 0xf9, 0x42, 0x32, 0x5c, 0x9c, 0x89, 0xa5, 0x25, + 0x19, 0xf9, 0x45, 0x99, 0x25, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0x9c, 0x41, 0x08, 0x01, 0x2b, + 0x9b, 0x5d, 0x07, 0xa6, 0xdd, 0x62, 0x34, 0xe3, 0x32, 0x49, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, + 0x4b, 0xce, 0xcf, 0xd5, 0x87, 0x5a, 0xad, 0x9f, 0x9e, 0xaf, 0x9b, 0x5a, 0x91, 0x9a, 0x5c, 0x5a, + 0x92, 0x99, 0x9f, 0xa7, 0x9b, 0x98, 0x94, 0x9c, 0x09, 0xb5, 0xa2, 0x18, 0xe6, 0x78, 0xa7, 0x88, + 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, 0x39, + 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xb2, 0x23, 0xc7, 0x3c, 0x44, 0x60, + 0x24, 0xb1, 0x81, 0xbd, 0x61, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x63, 0x01, 0x0d, 0x5d, 0x33, + 0x01, 0x00, 0x00, } func (m *Module) Marshal() (dAtA []byte, err error) { @@ -138,7 +136,6 @@ func encodeVarintModule(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } - func (m *Module) Size() (n int) { if m == nil { return 0 @@ -155,11 +152,9 @@ func (m *Module) Size() (n int) { func sovModule(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } - func sozModule(x uint64) (n int) { return sovModule(uint64((x << 1) ^ uint64((int64(x) >> 63)))) } - func (m *Module) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -186,7 +181,7 @@ func (m *Module) Unmarshal(dAtA []byte) error { return fmt.Errorf("proto: Module: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wireType) + return fmt.Errorf("proto: Module: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -242,7 +237,6 @@ func (m *Module) Unmarshal(dAtA []byte) error { } return nil } - func skipModule(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go index ddf0bcf7..dd9e024d 100644 --- a/modules/network/types/expected_keepers.go +++ b/modules/network/types/expected_keepers.go @@ -1,6 +1,7 @@ package types import ( + "context" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -8,19 +9,18 @@ import ( // StakingKeeper defines the expected staking keeper interface type StakingKeeper interface { - GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) - GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) - GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) - GetLastTotalPower(ctx sdk.Context) math.Int - //GetHistoricalInfo(ctx sdk.Context, height int64) (stakingtypes.HistoricalInfo, error) + GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) + GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error) + GetLastValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) + GetLastTotalPower(ctx context.Context) (math.Int, error) } // AccountKeeper defines the expected account keeper interface type AccountKeeper interface { - GetAccount(ctx sdk.Context, addr sdk.AccAddress) sdk.AccountI + GetAccount(ctx context.Context, addr sdk.AccAddress) sdk.AccountI } // BankKeeper defines the expected bank keeper interface type BankKeeper interface { - SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins } diff --git a/modules/network/types/keys.go b/modules/network/types/keys.go index 7b008645..b80eb45d 100644 --- a/modules/network/types/keys.go +++ b/modules/network/types/keys.go @@ -22,7 +22,7 @@ const ( // KVStore key prefixes var ( - // Prefixes for collections + // todo (Alex): use numbers instaed of verbose keyse? ValidatorIndexPrefix = collections.NewPrefix("validator_index") ValidatorPowerPrefix = collections.NewPrefix("validator_power") AttestationBitmapPrefix = collections.NewPrefix("attestation_bitmap") @@ -30,6 +30,7 @@ var ( AttesterSetPrefix = collections.NewPrefix("attester_set") SignaturePrefix = collections.NewPrefix("signature") StoredAttestationInfoPrefix = collections.NewPrefix("stored_attestation_info") + ParamsKey = collections.NewPrefix("params") ) // GetValidatorIndexKey returns the key for validator index mapping diff --git a/modules/proto/rollkitsdk/network/module/v1/module.proto b/modules/proto/rollkitsdk/network/module/v1/module.proto index 9d51c2f7..42c8bda2 100644 --- a/modules/proto/rollkitsdk/network/module/v1/module.proto +++ b/modules/proto/rollkitsdk/network/module/v1/module.proto @@ -4,7 +4,7 @@ package rollkitsdk.network.module.v1; import "cosmos/app/v1alpha1/module.proto"; -option go_package = "github.com/rollkit/go-execution-abci/modules/network/module"; +option go_package = "github.com/rollkit/go-execution-abci/modules/network/module/v1"; // Module is the config object for the module. message Module { @@ -14,4 +14,4 @@ message Module { // authority defines the custom module authority. If not set, defaults to the governance module. string authority = 1; -} \ No newline at end of file +} diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index cd80f1cc..a1f6ac0f 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -43,6 +43,19 @@ type P2PClientInfo interface { Peers() []rollkitp2p.PeerConnection } +// BlockFilter decides if a block commit is build and published +type BlockFilter interface { + IsPublishable(ctx context.Context, height int64) bool +} + +var _ BlockFilter = BlockFilterFn(nil) + +type BlockFilterFn func(ctx context.Context, height int64) bool + +func (b BlockFilterFn) IsPublishable(ctx context.Context, height int64) bool { + return b(ctx, height) +} + // LoadGenesisDoc returns the genesis document from the provided config file. func LoadGenesisDoc(cfg *cmtcfg.Config) (*cmttypes.GenesisDoc, error) { genesisFile := cfg.GenesisFile() @@ -69,7 +82,9 @@ type Adapter struct { AppGenesis *genutiltypes.AppGenesis Logger log.Logger - Metrics *Metrics + metrics *Metrics + + blockFilter BlockFilter } // NewABCIExecutor creates a new Adapter instance that implements the go-execution.Executor interface. @@ -82,13 +97,9 @@ func NewABCIExecutor( logger log.Logger, cfg *cmtcfg.Config, appGenesis *genutiltypes.AppGenesis, - metrics *Metrics, + opts ...Option, ) *Adapter { - if metrics == nil { - metrics = NopMetrics() - } - // create rollkit prefix rollkitPrefixStore := kt.Wrap(store, &kt.PrefixTransform{ Prefix: ds.NewKey(rollnode.RollkitPrefix), }) @@ -105,7 +116,12 @@ func NewABCIExecutor( p2pMetrics: p2pMetrics, AppGenesis: appGenesis, MempoolIDs: newMempoolIDs(), - Metrics: metrics, + metrics: NopMetrics(), + blockFilter: BlockFilterFn(func(ctx context.Context, height int64) bool { return true }), + } + + for _, opt := range opts { + opt(a) } return a @@ -132,7 +148,7 @@ func (a *Adapter) Start(ctx context.Context) error { func (a *Adapter) newTxValidator(ctx context.Context) p2p.GossipValidator { return func(m *p2p.GossipMessage) bool { - a.Metrics.TxValidationTotal.Add(1) + a.metrics.TxValidationTotal.Add(1) a.Logger.Debug("transaction received", "bytes", len(m.Data)) msgBytes := m.Data @@ -154,23 +170,23 @@ func (a *Adapter) newTxValidator(ctx context.Context) p2p.GossipValidator { SenderP2PID: corep2p.ID(m.From), }) checkTxDuration := time.Since(checkTxStart).Seconds() - a.Metrics.CheckTxDurationSeconds.Observe(checkTxDuration) + a.metrics.CheckTxDurationSeconds.Observe(checkTxDuration) switch { case errors.Is(err, mempool.ErrTxInCache): - a.Metrics.TxValidationResultTotal.With("result", "rejected_in_cache").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_in_cache").Add(1) return true case errors.Is(err, mempool.ErrMempoolIsFull{}): - a.Metrics.TxValidationResultTotal.With("result", "rejected_mempool_full").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_mempool_full").Add(1) return true case errors.Is(err, mempool.ErrTxTooLarge{}): - a.Metrics.TxValidationResultTotal.With("result", "rejected_too_large").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_too_large").Add(1) return false case errors.Is(err, mempool.ErrPreCheck{}): - a.Metrics.TxValidationResultTotal.With("result", "rejected_precheck").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_precheck").Add(1) return false case err != nil: - a.Metrics.TxValidationResultTotal.With("result", "rejected_checktx_error").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_checktx_error").Add(1) a.Logger.Error("CheckTx failed with unexpected error", "err", err) return false default: @@ -178,17 +194,17 @@ func (a *Adapter) newTxValidator(ctx context.Context) p2p.GossipValidator { select { case <-ctx.Done(): - a.Metrics.TxValidationResultTotal.With("result", "rejected_context_canceled").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_context_canceled").Add(1) return false case checkTxResp := <-checkTxResCh: if checkTxResp.Code == abci.CodeTypeOK { - a.Metrics.TxValidationResultTotal.With("result", "accepted").Add(1) + a.metrics.TxValidationResultTotal.With("result", "accepted").Add(1) return true } - a.Metrics.TxValidationResultTotal.With("result", "rejected_checktx").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_checktx").Add(1) return false case <-time.After(5 * time.Second): - a.Metrics.TxValidationResultTotal.With("result", "rejected_timeout").Add(1) + a.metrics.TxValidationResultTotal.With("result", "rejected_timeout").Add(1) a.Logger.Error("CheckTx response timed out") return false } @@ -199,7 +215,7 @@ func (a *Adapter) newTxValidator(ctx context.Context) p2p.GossipValidator { func (a *Adapter) InitChain(ctx context.Context, genesisTime time.Time, initialHeight uint64, chainID string) ([]byte, uint64, error) { initChainStart := time.Now() defer func() { - a.Metrics.InitChainDurationSeconds.Observe(time.Since(initChainStart).Seconds()) + a.metrics.InitChainDurationSeconds.Observe(time.Since(initChainStart).Seconds()) }() a.Logger.Info("Initializing chain", "chainID", chainID, "initialHeight", initialHeight, "genesisTime", genesisTime) @@ -287,10 +303,10 @@ func (a *Adapter) ExecuteTxs( ) ([]byte, uint64, error) { execStart := time.Now() defer func() { - a.Metrics.BlockExecutionDurationSeconds.Observe(time.Since(execStart).Seconds()) + a.metrics.BlockExecutionDurationSeconds.Observe(time.Since(execStart).Seconds()) }() a.Logger.Info("Executing block", "height", blockHeight, "num_txs", len(txs), "timestamp", timestamp) - a.Metrics.TxsExecutedPerBlock.Observe(float64(len(txs))) + a.metrics.TxsExecutedPerBlock.Observe(float64(len(txs))) s, err := a.Store.LoadState(ctx) if err != nil { @@ -358,7 +374,7 @@ func (a *Adapter) ExecuteTxs( lastHeightValsChanged := s.LastHeightValidatorsChanged if len(validatorUpdates) > 0 { - a.Metrics.ValidatorUpdatesTotal.Add(float64(len(validatorUpdates))) + a.metrics.ValidatorUpdatesTotal.Add(float64(len(validatorUpdates))) err := nValSet.UpdateWithChangeSet(validatorUpdates) if err != nil { return nil, 0, fmt.Errorf("changing validator set: %w", err) @@ -369,7 +385,7 @@ func (a *Adapter) ExecuteTxs( nValSet.IncrementProposerPriority(1) if fbResp.ConsensusParamUpdates != nil { - a.Metrics.ConsensusParamUpdatesTotal.Add(1) + a.metrics.ConsensusParamUpdatesTotal.Add(1) nextParams := s.ConsensusParams.Update(fbResp.ConsensusParamUpdates) err := nextParams.ValidateBasic() if err != nil { @@ -427,40 +443,40 @@ func (a *Adapter) ExecuteTxs( if err != nil { return nil, 0, err } + if a.blockFilter.IsPublishable(ctx, int64(blockHeight)) { + cmtTxs := make(cmttypes.Txs, len(txs)) + for i := range txs { + cmtTxs[i] = txs[i] + } - cmtTxs := make(cmttypes.Txs, len(txs)) - for i := range txs { - cmtTxs[i] = txs[i] - } - - // if blockheight is 0, we create a signed last commit. - if blockHeight == 0 { - lastCommit.Signatures = []cmttypes.CommitSig{ - { - BlockIDFlag: cmttypes.BlockIDFlagCommit, - ValidatorAddress: s.Validators.Proposer.Address, - Timestamp: time.Now().UTC(), - Signature: []byte{}, - }, + // if blockheight is 0, we create a signed last commit. + if blockHeight == 0 { + lastCommit.Signatures = []cmttypes.CommitSig{ + { + BlockIDFlag: cmttypes.BlockIDFlagCommit, + ValidatorAddress: s.Validators.Proposer.Address, + Timestamp: time.Now().UTC(), + Signature: []byte{}, + }, + } } - } - block := s.MakeBlock(int64(blockHeight), cmtTxs, lastCommit, nil, s.Validators.Proposer.Address) + block := s.MakeBlock(int64(blockHeight), cmtTxs, lastCommit, nil, s.Validators.Proposer.Address) - currentBlockID := cmttypes.BlockID{ - Hash: block.Hash(), - PartSetHeader: cmttypes.PartSetHeader{Total: 1, Hash: block.DataHash}, - } + currentBlockID := cmttypes.BlockID{ + Hash: block.Hash(), + PartSetHeader: cmttypes.PartSetHeader{Total: 1, Hash: block.DataHash}, + } - if err := fireEvents(a.EventBus, block, currentBlockID, fbResp, validatorUpdates); err != nil { - a.Logger.Error("failed to fire events", "err", err) - } + if err := fireEvents(a.EventBus, block, currentBlockID, fbResp, validatorUpdates); err != nil { + a.Logger.Error("failed to fire events", "err", err) + } - // save the finalized block response - if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { - return nil, 0, fmt.Errorf("failed to save block response: %w", err) + // save the finalized block response + if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { + return nil, 0, fmt.Errorf("failed to save block response: %w", err) + } } - a.Logger.Info("block executed successfully", "height", blockHeight, "appHash", fmt.Sprintf("%X", fbResp.AppHash)) return fbResp.AppHash, uint64(s.ConsensusParams.Block.MaxBytes), nil } @@ -587,7 +603,7 @@ func cometCommitToABCICommitInfo(commit *cmttypes.Commit) abci.CommitInfo { func (a *Adapter) GetTxs(ctx context.Context) ([][]byte, error) { getTxsStart := time.Now() defer func() { - a.Metrics.GetTxsDurationSeconds.Observe(time.Since(getTxsStart).Seconds()) + a.metrics.GetTxsDurationSeconds.Observe(time.Since(getTxsStart).Seconds()) }() a.Logger.Debug("Getting transactions for proposal") @@ -624,7 +640,7 @@ func (a *Adapter) GetTxs(ctx context.Context) ([][]byte, error) { return nil, err } - a.Metrics.TxsProposedTotal.Add(float64(len(resp.Txs))) + a.metrics.TxsProposedTotal.Add(float64(len(resp.Txs))) return resp.Txs, nil } diff --git a/pkg/adapter/adapter_test.go b/pkg/adapter/adapter_test.go index 0d9acd9d..741e6221 100644 --- a/pkg/adapter/adapter_test.go +++ b/pkg/adapter/adapter_test.go @@ -81,7 +81,7 @@ func TestExecuteFiresEvents(t *testing.T) { myMockApp := mockApp(myExecResult, spec.mockMutator) originStore := ds.NewMapDatastore() - adapter := NewABCIExecutor(myMockApp, originStore, nil, nil, log.NewTestLogger(t), nil, nil, NopMetrics()) + adapter := NewABCIExecutor(myMockApp, originStore, nil, nil, log.NewTestLogger(t), nil, nil) adapter.EventBus = eventBus adapter.MempoolIDs = newMempoolIDs() adapter.Mempool = &mempool.NopMempool{} diff --git a/pkg/adapter/options.go b/pkg/adapter/options.go new file mode 100644 index 00000000..f37fb7c2 --- /dev/null +++ b/pkg/adapter/options.go @@ -0,0 +1,74 @@ +package adapter + +import ( + "context" + + abci "github.com/cometbft/cometbft/abci/types" + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/rollkit/go-execution-abci/modules/network/types" +) + +// Option is a functional option for configuring the Adapter. +type Option func(*Adapter) + +// WithMetrics sets custom metrics for the Adapter. +func WithMetrics(m *Metrics) Option { + return func(a *Adapter) { + a.metrics = m + } +} + +// WithBlockFilter sets a custom block publisher for the Adapter. +func WithBlockFilter(publisher BlockFilter) Option { + return func(a *Adapter) { + a.blockFilter = publisher + } +} + +// WithNetworkSoftConfirmationBlockFilter creates a BlockFilter that uses the network module's SoftConfirmationStatus. +func WithNetworkSoftConfirmationBlockFilter() Option { + return func(a *Adapter) { + a.blockFilter = &NetworkSoftConfirmationBlockFilter{ + app: a.App, + } + } +} + +// NetworkSoftConfirmationBlockFilter is a BlockFilter implementation that uses the network module's SoftConfirmationStatus. +type NetworkSoftConfirmationBlockFilter struct { + app servertypes.ABCI +} + +// IsPublishable implements the BlockFilter interface. +func (f *NetworkSoftConfirmationBlockFilter) IsPublishable(ctx context.Context, height int64) bool { + // First check if height is valid + if height < 2 { + return false + } + + req := &types.QuerySoftConfirmationStatusRequest{ + Height: height, + } + reqData, err := req.Marshal() + if err != nil { + return false + } + + // Query soft confirmation status + softConfirmReq := &abci.RequestQuery{ + Path: "/rollkitsdk.network.v1.Query/SoftConfirmationStatus", + Data: reqData, + } + + softConfirmRes, err := f.app.Query(ctx, softConfirmReq) + if err != nil || softConfirmRes.Code != 0 { + return false + } + + softConfirmResp := &types.QuerySoftConfirmationStatusResponse{} + if err := softConfirmResp.Unmarshal(softConfirmRes.Value); err != nil { + return false + } + + return softConfirmResp.IsSoftConfirmed +} diff --git a/server/start.go b/server/start.go index 2e9368f3..f899dc22 100644 --- a/server/start.go +++ b/server/start.go @@ -2,13 +2,8 @@ package server import ( "context" - "fmt" - "io" - "net" - "os" - "time" - "cosmossdk.io/log" + "fmt" cmtcfg "github.com/cometbft/cometbft/config" "github.com/cometbft/cometbft/mempool" cmtp2p "github.com/cometbft/cometbft/p2p" @@ -30,9 +25,14 @@ import ( "github.com/cosmos/cosmos-sdk/version" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/hashicorp/go-metrics" + networkkeeper "github.com/rollkit/go-execution-abci/modules/network/keeper" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "io" + "net" + "os" + "time" "github.com/rollkit/rollkit/da/jsonrpc" "github.com/rollkit/rollkit/node" @@ -355,9 +355,16 @@ func setupNodeAndExecutor( return nil, nil, cleanupFn, err } - adapterMetrics := adapter.NopMetrics() + var opts []adapter.Option if rollkitcfg.Instrumentation.IsPrometheusEnabled() { - adapterMetrics = adapter.PrometheusMetrics(config.DefaultInstrumentationConfig().Namespace, "chain_id", cmtGenDoc.ChainID) + m := adapter.PrometheusMetrics(config.DefaultInstrumentationConfig().Namespace, "chain_id", cmtGenDoc.ChainID) + opts = append(opts, adapter.WithMetrics(m)) + } + + // todo: this check is not needed. should we hae a flag instead? + if _, ok := app.(interface{ GetNetworkKeeper() networkkeeper.Keeper }); ok { + // Use the app directly instead of the keeper + opts = append(opts, adapter.WithNetworkSoftConfirmationBlockFilter()) } executor = adapter.NewABCIExecutor( @@ -368,7 +375,7 @@ func setupNodeAndExecutor( logger, cfg, appGenesis, - adapterMetrics, + opts..., ) cmtApp := server.NewCometABCIWrapper(app) From e78d75ccb6c3a8efdf99de58fa8c0353da2cd6c2 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Fri, 13 Jun 2025 17:27:14 +0200 Subject: [PATCH 07/21] Add start flag to enable the validator network --- server/flags.go | 5 +++++ server/start.go | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/server/flags.go b/server/flags.go index b650b58c..446d3165 100644 --- a/server/flags.go +++ b/server/flags.go @@ -6,6 +6,8 @@ import ( "github.com/rollkit/rollkit/pkg/config" ) +const FlagNetworkSoftConfirmation = "rollkit.network.soft-confirmation" + // AddFlags adds Rollkit specific configuration options to cobra Command. func AddFlags(cmd *cobra.Command) { def := config.DefaultConfig @@ -13,6 +15,9 @@ func AddFlags(cmd *cobra.Command) { // Add CI flag for testing cmd.Flags().Bool("ci", false, "run node for ci testing") + // Add network flags + cmd.Flags().Bool(FlagNetworkSoftConfirmation, false, "enable soft confirmation by the validator network") + // Add base flags cmd.Flags().String(config.FlagDBPath, def.DBPath, "path for the node database") cmd.Flags().String(config.FlagChainID, def.ChainID, "chain ID") diff --git a/server/start.go b/server/start.go index f899dc22..f8b666f0 100644 --- a/server/start.go +++ b/server/start.go @@ -25,7 +25,6 @@ import ( "github.com/cosmos/cosmos-sdk/version" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/hashicorp/go-metrics" - networkkeeper "github.com/rollkit/go-execution-abci/modules/network/keeper" "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" @@ -361,9 +360,7 @@ func setupNodeAndExecutor( opts = append(opts, adapter.WithMetrics(m)) } - // todo: this check is not needed. should we hae a flag instead? - if _, ok := app.(interface{ GetNetworkKeeper() networkkeeper.Keeper }); ok { - // Use the app directly instead of the keeper + if srvCtx.Viper.GetBool(FlagNetworkSoftConfirmation) { opts = append(opts, adapter.WithNetworkSoftConfirmationBlockFilter()) } From 9cd1dd3fcb55b9e372ea1c89789d2c4747272927 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 16 Jun 2025 11:15:46 +0200 Subject: [PATCH 08/21] Start local dev env --- hack/.gitignore | 2 ++ hack/README.md | 4 +++ hack/download.sh | 79 +++++++++++++++++++++++++++++++++++++++++++ hack/init-gaia.sh | 86 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 hack/.gitignore create mode 100644 hack/README.md create mode 100755 hack/download.sh create mode 100755 hack/init-gaia.sh diff --git a/hack/.gitignore b/hack/.gitignore new file mode 100644 index 00000000..d8e828ab --- /dev/null +++ b/hack/.gitignore @@ -0,0 +1,2 @@ +downloads/ +testnet/ diff --git a/hack/README.md b/hack/README.md new file mode 100644 index 00000000..6dcfa3f1 --- /dev/null +++ b/hack/README.md @@ -0,0 +1,4 @@ +```shell +./init-gaia.sh +./run_node.sh +``` \ No newline at end of file diff --git a/hack/download.sh b/hack/download.sh new file mode 100755 index 00000000..9011b3da --- /dev/null +++ b/hack/download.sh @@ -0,0 +1,79 @@ +#!/bin/bash + + +HERMES_VERSION=${1:-"v1.13.1"} +GAIAD_VERSION=${2:-"v24.0.0"} + +ARCH=$(uname -m) +OS=$(uname -s) + +case "$ARCH" in + "arm64") + ARCH_LABEL="aarch64" + ;; + "x86_64") + ARCH_LABEL="x86_64" + ;; + *) + echo "Unsupported architecture: $ARCH" + exit 1 + ;; +esac + +case "$OS" in + "Darwin") + OS_LABEL="apple-darwin" + ;; + "Linux") + OS_LABEL="unknown-linux-gnu" + ;; + *) + echo "Unsupported operating system: $OS" + exit 1 + ;; +esac + +HERMES_URL="https://github.com/informalsystems/hermes/releases/download/$HERMES_VERSION/hermes-$HERMES_VERSION-${ARCH_LABEL}-${OS_LABEL}.tar.gz" +GAIAD_URL="https://github.com/cosmos/gaia/releases/download/$GAIAD_VERSION/gaiad-$GAIAD_VERSION-darwin-$ARCH" + +if [ "$OS" == "Linux" ]; then + GAIAD_URL="https://github.com/cosmos/gaia/releases/download/$GAIAD_VERSION/gaiad-$GAIAD_VERSION-linux-amd64" +fi + +# Define output directories +DOWNLOAD_DIR="./downloads" +mkdir -p "$DOWNLOAD_DIR" + +# Function to download a file +download_file() { + local url=$1 + local output_path=$2 + + echo "Downloading: $url" + curl -L -o "$output_path" "$url" + if [ $? -ne 0 ]; then + echo "Failed to download $url" + exit 1 + fi +} + +# Download hermes +HERMES_ARCHIVE="$DOWNLOAD_DIR/hermes.tar.gz" +download_file "$HERMES_URL" "$HERMES_ARCHIVE" + +# Extract hermes if tar.gz +if [[ "$HERMES_ARCHIVE" == *.tar.gz ]]; then + echo "Extracting: $HERMES_ARCHIVE" + tar -xzvf "$HERMES_ARCHIVE" -C "$DOWNLOAD_DIR" +elif [[ "$HERMES_ARCHIVE" == *.zip ]]; then + echo "Extracting: $HERMES_ARCHIVE" + unzip "$HERMES_ARCHIVE" -d "$DOWNLOAD_DIR" +fi + +GAIAD_BINARY="$DOWNLOAD_DIR/gaiad" +download_file "$GAIAD_URL" "$GAIAD_BINARY" + +# Make gaiad binary executable +chmod +x "$GAIAD_BINARY" + +echo "Hermes and Gaiad downloaded successfully to $DOWNLOAD_DIR" \ No newline at end of file diff --git a/hack/init-gaia.sh b/hack/init-gaia.sh new file mode 100755 index 00000000..9b2b8ec6 --- /dev/null +++ b/hack/init-gaia.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +# Function for formatted logging +log() { + local color=$1 + local emoji=$2 + local message=$3 + shift 3 + printf "\e[${color}m${emoji} [$(date '+%T')] ${message}\e[0m\n" "$@" +} + +# Hardcoded mnemonic for validator account (igual que en Wordled) +VALIDATOR_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +GAIA_HOME=${1:-"${CURRENT_DIR}/testnet"} +GAIAD_BIN=${2:-"${CURRENT_DIR}/downloads/gaiad"} + +# Kill existing Gaia processes +log "31" "💀" "Checking for existing Gaia processes..." +GAIA_PID=$(pgrep gaiad) +if [ -n "$GAIA_PID" ]; then + log "31" "🔪" "Killing existing Gaia process (PID: $GAIA_PID)..." + kill -9 "$GAIA_PID" +else + log "32" "👌" "No existing Gaia process found." +fi + +# Clean previous configurations +log "32" "🔥" "Cleaning previous Gaia configurations..." +rm -rf "$GAIA_HOME" + +# 1. Initialize Gaia chain +log "36" "🆕" "Initializing Gaia chain..." +"$GAIAD_BIN" init my-node --chain-id localnet-1 --home "$GAIA_HOME" + +# 2. Create/Recover validator account usando la mnemónica fija +log "35" "👤" "Generating validator account from mnemonic..." +echo "$VALIDATOR_MNEMONIC" | "$GAIAD_BIN" keys add validator \ + --keyring-backend test \ + --home "$GAIA_HOME" \ + --recover > /dev/null 2>&1 + +# 3. Add account to genesis +log "34" "📝" "Adding account to genesis..." +"$GAIAD_BIN" genesis add-genesis-account validator 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" + +# 4. Generate gentx +log "33" "📜" "Creating validator transaction..." +"$GAIAD_BIN" genesis gentx validator 1000000000stake \ + --chain-id localnet-1 \ + --keyring-backend test \ + --home "$GAIA_HOME" + +# 5. Collect gentxs +log "32" "📦" "Collecting genesis transactions..." +"$GAIAD_BIN" genesis collect-gentxs --home "$GAIA_HOME" + +# 6. Configure minimum gas prices +log "36" "⛽" "Setting minimum gas prices..." +sed -i.bak -E 's#minimum-gas-prices = ""#minimum-gas-prices = "0stake"#g' "$GAIA_HOME/config/app.toml" + +# 7. Modify consensus timeouts +log "35" "⏱️" "Adjusting consensus timeouts..." +sed -i.bak -E 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$GAIA_HOME/config/config.toml" +sed -i.bak -E 's/timeout_propose = "3s"/timeout_propose = "1s"/g' "$GAIA_HOME/config/config.toml" + +# 8. Start Gaia chain +log "34" "🚀" "Starting Gaia node..." +"$GAIAD_BIN" start --home "$GAIA_HOME" --minimum-gas-prices "0stake" --rpc.laddr tcp://0.0.0.0:26654 --rpc.pprof_laddr localhost:6061 --p2p.laddr tcp://0.0.0.0:26653 --grpc.address 0.0.0.0:9091 | tee "$GAIA_HOME/gaia.log" & +GAIA_PID=$! + +# Wait for initialization +log "33" "⏳" "Waiting for Gaia initialization (port 26667)..." +while ! nc -z localhost 26667; do + sleep 1 +done +log "32" "✅" "Gaia chain running successfully!" + +# Show recent logs +log "36" "📄" "Last lines of Gaia log:" +tail -n 5 "$GAIA_HOME/gaia.log" + +# Keep script alive +log "35" "👀" "Monitoring Gaia chain activity..." +wait $GAIA_PID \ No newline at end of file From 48e0b76e4cbe8442cd7fc645114eb59a41569501 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 16 Jun 2025 11:16:17 +0200 Subject: [PATCH 09/21] Do not stop chain when network consensus missed --- modules/network/keeper/abci.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index b2c0e262..66d70f18 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -132,7 +132,10 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { } if checkpointsInEpoch > 0 && softConfirmedCheckpoints == 0 { - return fmt.Errorf("no checkpoints achieved quorum in epoch: %d", epoch) + // todo (Alex): show we really fail? + //return fmt.Errorf("no checkpoints achieved quorum in epoch: %d", epoch) + k.Logger(ctx).Info("No checkpoints achieved quorum in epoch", "epoch", epoch) + return nil } } From c8cc2077de4f11e4382ea25bb1de9c08a6ac3fa0 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 16 Jun 2025 15:03:32 +0200 Subject: [PATCH 10/21] Updates --- hack/.gitignore | 1 + hack/README.md | 21 +- hack/attester/README.md | 4 + hack/attester/main.go | 441 +++++++++++++++++++ hack/ibc-connection-hermes.sh | 131 ++++++ hack/ics20-token-transfer.sh | 166 +++++++ hack/init-gaia.sh | 18 +- hack/run_gmd.sh | 147 +++++++ modules/network/client/cli/tx.go | 16 +- modules/network/keeper/abci.go | 8 +- modules/network/keeper/msg_server.go | 9 +- modules/network/keeper/msg_server_test.go | 19 +- modules/network/types/msgs.go | 18 +- modules/network/types/params.go | 2 +- modules/network/types/tx.pb.go | 69 +-- modules/proto/rollkitsdk/network/v1/tx.proto | 6 +- pkg/adapter/adapter.go | 128 ++++-- pkg/adapter/options.go | 15 +- 18 files changed, 1109 insertions(+), 110 deletions(-) create mode 100644 hack/attester/README.md create mode 100644 hack/attester/main.go create mode 100755 hack/ibc-connection-hermes.sh create mode 100755 hack/ics20-token-transfer.sh create mode 100755 hack/run_gmd.sh diff --git a/hack/.gitignore b/hack/.gitignore index d8e828ab..934e3e0e 100644 --- a/hack/.gitignore +++ b/hack/.gitignore @@ -1,2 +1,3 @@ downloads/ testnet/ +config/ diff --git a/hack/README.md b/hack/README.md index 6dcfa3f1..9dfc0de1 100644 --- a/hack/README.md +++ b/hack/README.md @@ -1,4 +1,19 @@ +# Hack + +Local test scripts + +## Requirements + +* `gaiad` + `hermes` app are available. Use `download.sh` script to fetch +* Rollkit example app `gmd` is built with network integration and available in the path +* `local-da` is built and located in `../../rollkit/build/local-da` + +## Run local setup + ```shell -./init-gaia.sh -./run_node.sh -``` \ No newline at end of file +./init-gaia.sh # setup and start gaia app +./run_node.sh # setup and start gmd example app + local da +go run ./attester --chain-id=rollkitnet-1 --home=$(pwd)/testnet/gm --from=validator +./ibc-connection-hermes.sh # relayer +./ics20-token-transfer.sh # token transfer +``` diff --git a/hack/attester/README.md b/hack/attester/README.md new file mode 100644 index 00000000..940c2be4 --- /dev/null +++ b/hack/attester/README.md @@ -0,0 +1,4 @@ +# Attest everything attester + +little helper that pulls new blocks from the rpc node and submits (fake) attestations after each epoch + diff --git a/hack/attester/main.go b/hack/attester/main.go new file mode 100644 index 00000000..861974da --- /dev/null +++ b/hack/attester/main.go @@ -0,0 +1,441 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "os" + "os/exec" + "os/signal" + "strconv" + "syscall" + "time" + + "github.com/gorilla/websocket" + "github.com/spf13/cobra" +) + +const ( + flagFrom = "from" + flagChainID = "chain-id" + flagNode = "node" + flagAPIAddr = "api-addr" + flagHome = "home" + flagVerbose = "verbose" +) + +func main() { + rootCmd := &cobra.Command{ + Use: "attester_ws", + Short: "Attester client for Rollkit using websocket", + Long: `Attester client for Rollkit that joins the attester set and attests to blocks at the end of each epoch.`, + DisableFlagParsing: false, + SuggestionsMinimumDistance: 2, + RunE: runAttester, + } + + // Add flags + rootCmd.Flags().String(flagFrom, "validator", "Name or address of the account to sign with") + rootCmd.Flags().String(flagChainID, "", "Chain ID of the blockchain") + rootCmd.Flags().String(flagNode, "tcp://localhost:26657", "RPC node address") + rootCmd.Flags().String(flagAPIAddr, "http://localhost:1317", "API node address") + rootCmd.Flags().String(flagHome, "", "Directory for config and data") + rootCmd.Flags().Bool(flagVerbose, false, "Enable verbose output") + + rootCmd.MarkFlagRequired(flagChainID) + rootCmd.MarkFlagRequired(flagHome) + + // Execute + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func runAttester(cmd *cobra.Command, args []string) error { + // Get flags + from, err := cmd.Flags().GetString(flagFrom) + if err != nil { + return err + } + + chainID, err := cmd.Flags().GetString(flagChainID) + if err != nil { + return err + } + + node, err := cmd.Flags().GetString(flagNode) + if err != nil { + return err + } + apiAddr, err := cmd.Flags().GetString(flagAPIAddr) + if err != nil { + return err + } + + home, err := cmd.Flags().GetString(flagHome) + if err != nil { + return err + } + + verbose, err := cmd.Flags().GetBool(flagVerbose) + if err != nil { + return err + } + + // Create context with cancellation + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Handle OS signals for graceful shutdown + sigCh := make(chan os.Signal, 1) + signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-sigCh + fmt.Println("Received signal, shutting down...") + cancel() + }() + + // Step 1: Join attester set + fmt.Println("Joining attester set...") + if err := joinAttesterSet(from, chainID, node, home, verbose); err != nil { + return fmt.Errorf("join attester set: %w", err) + } + + // Step 2: Query network parameters to get epoch length + fmt.Println("Querying network parameters...") + epochLength, err := getEpochLength(apiAddr) + if err != nil { + return fmt.Errorf("get epoch length: %w", err) + } + fmt.Printf("Epoch length: %d blocks\n", epochLength) + + // Step 3 & 4: Watch new block events via websocket and attest at the end of each epoch + fmt.Println("Starting to watch for new blocks...") + if err := pullBlocksAndAttest(ctx, from, chainID, node, home, epochLength, verbose); err != nil { + return fmt.Errorf("error watching blocks: %w", err) + } + + return nil +} + +// joinAttesterSet executes the gmd tx network join-attester command +func joinAttesterSet(from, chainID, node, home string, verbose bool) error { + // Prepare gmd command + args := []string{ + "tx", "network", "join-attester", + "--from", from, + "--chain-id", chainID, + "--node", node, + "--home", home, + "--keyring-backend=test", + "-y", // auto-confirm + } + gmdCmd := exec.Command("gmd", args...) + + // Set output to current process stdout and stderr + gmdCmd.Stdout = os.Stdout + gmdCmd.Stderr = os.Stderr + + // Execute command + if verbose { + fmt.Println("Executing command with all parameters:") + fmt.Printf("gmd %s\n", formatCommandArgs(args)) + } else { + fmt.Println("Executing:", gmdCmd.String()) + } + + if err := gmdCmd.Run(); err != nil { + return fmt.Errorf("execute gmd command: %w", err) + } + + fmt.Println("Successfully joined attester set") + return nil +} + +// getEpochLength queries the network parameters to get the epoch length +func getEpochLength(apiAddr string) (uint64, error) { + // Create a simple HTTP client to query the node + httpClient := &http.Client{ + Timeout: 10 * time.Second, + } + + // Get epoch parameters + paramsResp, err := httpClient.Get(fmt.Sprintf("%s/rollkit/network/v1/params", apiAddr)) + if err != nil { + return 0, fmt.Errorf("error getting params: %w", err) + } + defer paramsResp.Body.Close() + + var paramsResult struct { + Params struct { + EpochLength string `json:"epoch_length"` + } `json:"params"` + } + var buf bytes.Buffer + + if err := json.NewDecoder(io.TeeReader(paramsResp.Body, &buf)).Decode(¶msResult); err != nil { + return 0, fmt.Errorf("error decoding params: %w: got %s", err, buf.String()) + } + + epochLength, err := strconv.ParseUint(paramsResult.Params.EpochLength, 10, 64) + if err != nil { + return 0, fmt.Errorf("epoch length: %w", err) + } + if epochLength == 0 { + return 0, fmt.Errorf("epoch length is 0") + } + + return epochLength, nil +} + +// pullBlocksAndAttest polls for new blocks via HTTP and attests at the end of each epoch +func pullBlocksAndAttest(ctx context.Context, from, chainID, node, home string, epochLength uint64, verbose bool) error { + // Parse node URL + parsed, err := url.Parse(node) + if err != nil { + return fmt.Errorf("parse node URL: %w", err) + } + + httpClient := &http.Client{ + Timeout: 10 * time.Second, + } + + var lastAttested int64 = 0 + + // Poll for new blocks + for { + select { + case <-ctx.Done(): + return nil + default: + // Query latest block + resp, err := httpClient.Get(fmt.Sprintf("http://%s/block", parsed.Host)) + if err != nil { + fmt.Printf("Error querying block: %v\n", err) + time.Sleep(time.Second / 10) + continue + } + + var blockResponse struct { + Result struct { + Block struct { + Header struct { + Height string `json:"height"` + } `json:"header"` + } `json:"block"` + } `json:"result"` + } + + if err := json.NewDecoder(resp.Body).Decode(&blockResponse); err != nil { + fmt.Printf("Error parsing response: %v\n", err) + resp.Body.Close() + time.Sleep(time.Second / 10) + continue + } + resp.Body.Close() + + // Extract block height + height, err := strconv.ParseInt(blockResponse.Result.Block.Header.Height, 10, 64) + if err != nil { + fmt.Printf("Error parsing height: %v\n", err) + time.Sleep(time.Second / 10) + continue + } + + fmt.Printf("Current block: %d\n", height) + + // Check if this is the end of an epoch and we haven't attested to it yet + if height > 1 && height%int64(epochLength) == 0 && height > lastAttested { + fmt.Printf("End of epoch at height %d, submitting attestation\n", height) + + // Submit attestation with "0x00" as the hash + err = submitAttestation(ctx, from, chainID, node, home, height, "0x00", verbose) + if err != nil { + fmt.Printf("Error submitting attestation: %v\n", err) + //time.Sleep(time.Second / 10) + //continue + return err + } + + lastAttested = height + } + + // Wait before next poll + time.Sleep(time.Second / 10) + } + } +} + +func watchBlocksAndAttest(ctx context.Context, from, chainID, node, home string, epochLength uint64, verbose bool) error { + // Convert TCP node address to WebSocket address + parsed, err := url.Parse(node) + if err != nil { + return fmt.Errorf("parse node URL: %w", err) + } + wsURL := fmt.Sprintf("ws://%s/websocket", parsed.Host) + fmt.Printf("Connecting to WebSocket at %s\n", wsURL) + + // Connect to WebSocket + c, _, err := websocket.DefaultDialer.Dial(wsURL, nil) + if err != nil { + return fmt.Errorf("error connecting to websocket: %w", err) + } + defer c.Close() + + // Subscribe to new block events + subscribeMsg := map[string]interface{}{ + "jsonrpc": "2.0", + "method": "subscribe", + "id": 1, + "params": map[string]interface{}{ + "query": "tm.event='NewBlock'", + }, + } + + if err := c.WriteJSON(subscribeMsg); err != nil { + return fmt.Errorf("error subscribing to events: %w", err) + } + + // Process incoming messages + var lastAttested int64 = 0 + done := make(chan struct{}) + + go func() { + defer close(done) + for { + _, message, err := c.ReadMessage() + if err != nil { + fmt.Printf("Error reading message: %v\n", err) + return + } + + // Parse the message + var response struct { + Result struct { + Data struct { + Value struct { + Block struct { + Header struct { + Height string `json:"height"` + } `json:"header"` + } `json:"block"` + } `json:"value"` + } `json:"data"` + } `json:"result"` + } + + if err := json.Unmarshal(message, &response); err != nil { + fmt.Printf("Error parsing message: %v\n", err) + continue + } + + // Extract block height + heightStr := response.Result.Data.Value.Block.Header.Height + height, err := strconv.ParseInt(heightStr, 10, 64) + if err != nil { + fmt.Printf("Error parsing height: %v\n", err) + continue + } + + fmt.Printf("New block: %d\n", height) + + // Check if this is the end of an epoch and we haven't attested to it yet + if height > 1 && height%int64(epochLength) == 0 && height > lastAttested { + fmt.Printf("End of epoch at height %d, submitting attestation\n", height) + + // Submit attestation with "0x00" as the hash + err = submitAttestation(ctx, from, chainID, node, home, height, "0x00", verbose) + if err != nil { + fmt.Printf("Error submitting attestation: %v\n", err) + continue + } + + lastAttested = height + } + } + }() + + // Wait for context cancellation + select { + case <-ctx.Done(): + fmt.Println("Context cancelled, closing connection...") + // Close WebSocket connection + err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) + if err != nil { + fmt.Printf("Error closing websocket: %v\n", err) + } + // Wait for the goroutine to finish + <-done + return nil + case <-done: + return fmt.Errorf("websocket connection closed unexpectedly") + } +} + +// formatCommandArgs formats command arguments for verbose output +func formatCommandArgs(args []string) string { + var result string + for i, arg := range args { + if i > 0 { + result += " " + } + // Add quotes if the argument contains spaces + if containsSpace(arg) { + result += "\"" + arg + "\"" + } else { + result += arg + } + } + return result +} + +// containsSpace checks if a string contains any space character +func containsSpace(s string) bool { + for _, c := range s { + if c == ' ' || c == '\t' || c == '\n' || c == '\r' { + return true + } + } + return false +} + +// submitAttestation creates and submits an attestation for a block using gmd +func submitAttestation(ctx context.Context, from, chainID, node, home string, height int64, blockHash string, verbose bool) error { + // Prepare gmd command + args := []string{ + "tx", "network", "attest", + strconv.FormatInt(height, 10), + blockHash, + "--from", from, + "--chain-id", chainID, + "--node", node, + "--home", home, + "--keyring-backend=test", + "-y", // auto-confirm + } + gmdCmd := exec.Command("gmd", args...) + + // Set output to current process stdout and stderr + gmdCmd.Stdout = os.Stdout + gmdCmd.Stderr = os.Stderr + + // Execute command + if verbose { + fmt.Println("Executing command with all parameters:") + fmt.Printf("gmd %s\n", formatCommandArgs(args)) + } else { + fmt.Println("Executing:", gmdCmd.String()) + } + + if err := gmdCmd.Run(); err != nil { + return fmt.Errorf("execute gmd command: %w", err) + } + + fmt.Println("Attestation submitted successfully") + return nil +} diff --git a/hack/ibc-connection-hermes.sh b/hack/ibc-connection-hermes.sh new file mode 100755 index 00000000..5625e8aa --- /dev/null +++ b/hack/ibc-connection-hermes.sh @@ -0,0 +1,131 @@ +#!/bin/bash +set -e + +# Configuration variables +GAIA_CHAIN_ID="localnet-1" +WORDLED_CHAIN_ID="rollkitnet-1" + +GAIA_RPC="http://localhost:26654" +WORDLED_RPC="http://localhost:26657" + +GAIA_GRPC="http://localhost:9091" +WORDLED_GRPC="http://localhost:9090" + +GAIA_DENOM="stake" +WORDLED_DENOM="stake" + +RELAYER_WALLET="relayer" # Name of relayer account + +# Hardcoded mnemonic (must match initialization scripts) +RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" + + +# Logging functions +log_info() { + echo "[INFO] $1" +} + +log_success() { + echo "[SUCCESS] $1" +} + +log_error() { + echo "[ERROR] $1" >&2 +} + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +HERMES_BIN="${HERMES_BIN:-$CURRENT_DIR/downloads/hermes}" + +# Verify Hermes is installed +if [ ! -f "$HERMES_BIN" ]; then + log_error "Hermes not found at $HERMES_BIN" + exit 1 +fi +log_success "Hermes installed" + +CONFIG_DIR="${CURRENT_DIR}/testnet/hermes" +rm -rf "$CONFIG_DIR" +mkdir -p "$CONFIG_DIR" + +# Generate configuration file (config.toml) +CONFIG_FILE="$CONFIG_DIR/config.toml" +log_info "Generating Hermes configuration at $CONFIG_FILE..." + +cat < "$CONFIG_FILE" +[global] +log_level = "trace" + +[mode] + [mode.clients] + enabled = true + refresh = true + misbehaviour = true + [mode.connections] + enabled = true + [mode.channels] + enabled = true + [mode.packets] + enabled = true + +[[chains]] +id = "$GAIA_CHAIN_ID" +rpc_addr = "$GAIA_RPC" +grpc_addr = "$GAIA_GRPC" +event_source = { mode = "pull", interval = "1s", max_retries = 4 } +store_prefix = "ibc" +account_prefix = "cosmos" +key_name = "$RELAYER_WALLET" +gas_price = { price = 3.5, denom = "stake" } +gas_multiplier = 1.4 +rpc_timeout = "10s" +trusting_period = "503h" +clock_drift = "10s" +key_store_folder = "$CONFIG_DIR/$GAIA_CHAIN_ID-keys" + +[[chains]] +id = "$WORDLED_CHAIN_ID" +rpc_addr = "$WORDLED_RPC" +grpc_addr = "$WORDLED_GRPC" +store_prefix = "ibc" +event_source = { mode = "pull", interval = "1s", max_retries = 4 } +account_prefix = "gm" +key_name = "$RELAYER_WALLET" +gas_price = { price = 0.025, denom = "stake" } +gas_multiplier = 1.4 +rpc_timeout = "10s" +trusting_period = "503h" +clock_drift = "10s" +key_store_folder = "$CONFIG_DIR/$WORDLED_CHAIN_ID-keys" +EOF + +log_success "Configuration file generated" + +# Import keys to relayer (Hermes) using mnemonic +TMP_MNEMONIC=$(mktemp) +echo "$RELAYER_MNEMONIC" > "$TMP_MNEMONIC" + +log_info "Importing key for $GAIA_CHAIN_ID..." +"$HERMES_BIN" --config "$CONFIG_FILE" keys add --chain "$GAIA_CHAIN_ID" --mnemonic-file "$TMP_MNEMONIC" +log_success "Key imported for $GAIA_CHAIN_ID" + +log_info "Importing key for $WORDLED_CHAIN_ID..." +"$HERMES_BIN" --config "$CONFIG_FILE" keys add --chain "$WORDLED_CHAIN_ID" --mnemonic-file "$TMP_MNEMONIC" +log_success "Key imported for $WORDLED_CHAIN_ID" + +rm "$TMP_MNEMONIC" + +# Show configured addresses (optional) +log_info "Showing configured addresses:" +"$HERMES_BIN" --config "$CONFIG_FILE" keys list --chain "$GAIA_CHAIN_ID" +"$HERMES_BIN" --config "$CONFIG_FILE" keys list --chain "$WORDLED_CHAIN_ID" + +# Create IBC channel between chains +log_info "Creating IBC channel between $GAIA_CHAIN_ID and $WORDLED_CHAIN_ID..." + "$HERMES_BIN" --config "$CONFIG_FILE" create channel --a-chain "$GAIA_CHAIN_ID" --a-port transfer \ + --b-chain "$WORDLED_CHAIN_ID" --b-port transfer \ + --new-client-connection --yes +log_success "IBC channel created" + +# Start Hermes +log_info "Starting Hermes..." +"$HERMES_BIN" --config "$CONFIG_FILE" start \ No newline at end of file diff --git a/hack/ics20-token-transfer.sh b/hack/ics20-token-transfer.sh new file mode 100755 index 00000000..c638510e --- /dev/null +++ b/hack/ics20-token-transfer.sh @@ -0,0 +1,166 @@ +#!/bin/bash +set -e + +# Configuration variables (matching ibc-connection-hermes.sh) +GAIA_CHAIN_ID="localnet-1" +ROLLKIT_CHAIN_ID="rollkitnet-1" + +GAIA_RPC="http://localhost:26654" +ROLLKIT_RPC="http://localhost:26657" + +GAIA_DENOM="stake" +ROLLKIT_DENOM="stake" + +GAIA_KEY_NAME="bob" +ROLLKIT_KEY_NAME="carl" + +# IBC channel information +CHANNEL_ID="" +TRANSFER_PORT="transfer" + +# Logging functions +log_info() { + echo "[INFO] $1" +} + +log_success() { + echo "[SUCCESS] $1" +} + +log_error() { + echo "[ERROR] $1" >&2 +} + +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +GAIAD_BIN="${GAIAD_BIN:-$CURRENT_DIR/downloads/gaiad}" +GMD_BIN="gmd" +ROLLKIT_HOME="${1:-"${CURRENT_DIR}/testnet/gm"}" + +# Verify binaries are installed +if [ ! -f "$GAIAD_BIN" ]; then + log_error "Gaiad not found at $GAIAD_BIN" + exit 1 +fi +log_success "Gaiad installed" + +if ! command -v $GMD_BIN &> /dev/null; then + log_error "gmd binary not found in PATH" + exit 1 +fi +log_success "gmd installed" + +# Get validator addresses +log_info "Getting user addresses..." +USER_ADDRESS_GAIA=$($GAIAD_BIN keys show $GAIA_KEY_NAME -a --keyring-backend test --home "$CURRENT_DIR/testnet") +USER_ADDRESS_ROLLKIT=$($GMD_BIN keys show $ROLLKIT_KEY_NAME -a --keyring-backend test --home "$ROLLKIT_HOME") + +log_info "Gaia user address: $USER_ADDRESS_GAIA" +log_info "Rollkit user address: $USER_ADDRESS_ROLLKIT" + +# Check initial balances +log_info "Checking initial balances..." +log_info "Gaia $GAIA_KEY_NAME balance:" +$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" + +log_info "Rollkit $ROLLKIT_KEY_NAME balance:" +$GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" + +# Get channel ID +log_info "Getting IBC channel ID..." +CHANNEL_INFO=$($GAIAD_BIN q ibc channel channels --node $GAIA_RPC --home "$CURRENT_DIR/testnet" -o json) +CHANNEL_ID=$(echo $CHANNEL_INFO | jq -r '.channels[0].channel_id') + +if [ -z "$CHANNEL_ID" ] || [ "$CHANNEL_ID" == "null" ]; then + log_error "Failed to get channel ID. Make sure IBC connection is established." + exit 1 +fi + +log_info "Using IBC channel: $CHANNEL_ID" + +# Transfer Rollkit tokens to Gaia +ROLLKIT_TRANSFER_AMOUNT="101" + +log_info "Transferring ${ROLLKIT_TRANSFER_AMOUNT}${ROLLKIT_DENOM} from Rollkit to Gaia..." +TX_HASH=$($GMD_BIN tx ibc-transfer transfer $TRANSFER_PORT $CHANNEL_ID $USER_ADDRESS_GAIA ${ROLLKIT_TRANSFER_AMOUNT}${ROLLKIT_DENOM} \ + --from ${ROLLKIT_KEY_NAME} \ + --chain-id $ROLLKIT_CHAIN_ID \ + --node $ROLLKIT_RPC \ + --keyring-backend test \ + --home "$ROLLKIT_HOME" \ + --gas auto \ + --gas-adjustment 1.4 \ + --gas-prices 1stake \ + --yes -o json | jq -r '.txhash') + +log_info "Querying gmd tx... $TX_HASH" +for i in {1..10}; do + if ! tx_result=$($GMD_BIN q tx --type=hash "$TX_HASH" -o json --home "$ROLLKIT_HOME" 2>/dev/null); then + sleep 1 + continue + fi +done +if [ "$(echo "$tx_result" | jq -r '.code')" != "0" ]; then + log_error "Transaction failed : $tx_result" + exit 1 +fi + + +# Check balances after Rollkit to Gaia transfer +log_info "Checking balances after Rollkit to Gaia transfer..." +log_info "Gaia user balance (should show IBC tokens):" +$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" + +log_info "Rollkit user balance:" +$GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" + +# Transfer tokens from Gaia to Rollkit +TRANSFER_AMOUNT="102" +log_info "Transferring $TRANSFER_AMOUNT$GAIA_DENOM from Gaia to Rollkit..." +TX_HASH=$($GAIAD_BIN tx ibc-transfer transfer $TRANSFER_PORT $CHANNEL_ID $USER_ADDRESS_ROLLKIT ${TRANSFER_AMOUNT}${GAIA_DENOM} \ + --from ${GAIA_KEY_NAME} \ + --chain-id $GAIA_CHAIN_ID \ + --node $GAIA_RPC \ + --keyring-backend test \ + --home "$CURRENT_DIR/testnet" \ + --gas auto \ + --gas-adjustment 1.4 \ + --gas-prices 1stake \ + --yes -o json | jq -r '.txhash') + +log_info "Querying gaia tx... $TX_HASH" +for i in {1..20}; do + if ! tx_result=$($GAIAD_BIN q tx --type=hash "$TX_HASH" -o json --node $GAIA_RPC 2>/dev/null); then + echo "$tx_result" + sleep 1 + continue + fi +done +if [ "$(echo "$tx_result" | jq -r '.code')" != "0" ]; then + log_error "Transaction failed : $tx_result" + exit 1 +fi + +# Check balances after transfer to Rollkit +log_info "Checking balances after transfer to Rollkit..." +log_info "Gaia user balance:" +$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" + +log_info "Rollkit user balance (should show IBC tokens):" +ibc_tokens_visible=false + +for i in {1..${20}}; do + $GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" + if $GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" | grep -q "ibc"; then + log_success "IBC tokens are now visible in Rollkit balance" + ibc_tokens_visible=true + break + fi + sleep 1 +done + +if [ "$ibc_tokens_visible" = false ]; then + log_error "IBC tokens did not become visible within time frame" + exit 1 +fi + +log_success "ICS20 token transfer test completed!" diff --git a/hack/init-gaia.sh b/hack/init-gaia.sh index 9b2b8ec6..e6fcc5ae 100755 --- a/hack/init-gaia.sh +++ b/hack/init-gaia.sh @@ -11,9 +11,11 @@ log() { # Hardcoded mnemonic for validator account (igual que en Wordled) VALIDATOR_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" +BOB_MNEMONIC="rack argue disorder flame appear broom smile effort one rubber buffalo suspect tool devote zebra between inhale trigger brief possible parrot nation expose place" +RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -GAIA_HOME=${1:-"${CURRENT_DIR}/testnet"} +GAIA_HOME=${1:-"${CURRENT_DIR}/testnet/gaia"} GAIAD_BIN=${2:-"${CURRENT_DIR}/downloads/gaiad"} # Kill existing Gaia processes @@ -40,10 +42,20 @@ echo "$VALIDATOR_MNEMONIC" | "$GAIAD_BIN" keys add validator \ --keyring-backend test \ --home "$GAIA_HOME" \ --recover > /dev/null 2>&1 +echo "$BOB_MNEMONIC" | "$GAIAD_BIN" keys add bob \ + --keyring-backend test \ + --home "$GAIA_HOME" \ + --recover > /dev/null 2>&1 +echo "$RELAYER_MNEMONIC" | "$GAIAD_BIN" keys add relayer \ + --keyring-backend test \ + --home "$GAIA_HOME" \ + --recover > /dev/null 2>&1 # 3. Add account to genesis log "34" "📝" "Adding account to genesis..." "$GAIAD_BIN" genesis add-genesis-account validator 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" +"$GAIAD_BIN" genesis add-genesis-account bob 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" +"$GAIAD_BIN" genesis add-genesis-account relayer 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" # 4. Generate gentx log "33" "📜" "Creating validator transaction..." @@ -71,8 +83,8 @@ log "34" "🚀" "Starting Gaia node..." GAIA_PID=$! # Wait for initialization -log "33" "⏳" "Waiting for Gaia initialization (port 26667)..." -while ! nc -z localhost 26667; do +log "33" "⏳" "Waiting for Gaia initialization (port 26654)..." +while ! nc -z localhost 26654; do sleep 1 done log "32" "✅" "Gaia chain running successfully!" diff --git a/hack/run_gmd.sh b/hack/run_gmd.sh new file mode 100755 index 00000000..877b795e --- /dev/null +++ b/hack/run_gmd.sh @@ -0,0 +1,147 @@ +#!/bin/bash +set -x + +# Function for cleanup on script interruption +cleanup() { + log "31" "🛑" "Cleaning up processes..." + if [ -n "$DA_PID" ]; then + kill -9 "$DA_PID" 2>/dev/null || true + fi + if [ -n "$ROLLKIT_PID" ]; then + kill -9 "$ROLLKIT_PID" 2>/dev/null || true + fi + exit 0 +} + +trap cleanup INT TERM + +# Function for formatted logging +log() { + local color=$1 + local emoji=$2 + local message=$3 + shift 3 + printf "\e[${color}m${emoji} [$(date '+%T')] ${message}\e[0m\n" "$@" +} + + +# Define paths +CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROLLKIT_BIN="gmd" +ROLLKIT_HOME="${1:-"${CURRENT_DIR}/testnet/gm"}" +LOCAL_DA_PATH="${2:-"../../rollkit/build/local-da"}" +CHAIN_ID="${3:-"rollkitnet-1"}" + +# Clean previous configurations +log "32" "🔥" "Cleaning previous rollkit configurations..." +rm -rf "$ROLLKIT_HOME" + +"$ROLLKIT_BIN" init my-rollkit-node --chain-id "$CHAIN_ID" --home "$ROLLKIT_HOME" + +# Hardcoded mnemonic for validator account (igual que en Wordled) +VALIDATOR_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" +#ATTESTER_MNEMONIC="tennis sponsor brick almost coyote soup rib wisdom warm bean onion tray devote pretty crime grid rough boil wear december travel inch work note" +RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" +USER_MNEMONIC="sport head real antique sad expect ignore feature claim manual heavy mouse coil rebuild police flag robust picture milk symptom suffer chuckle worry virus" + + +echo "$VALIDATOR_MNEMONIC" | "$ROLLKIT_BIN" keys add validator \ + --keyring-backend test \ + --home "$ROLLKIT_HOME" \ + --recover > /dev/null 2>&1 + +#echo "$ATTESTER_MNEMONIC" | "$ROLLKIT_BIN" keys add attester \ +# --keyring-backend test \ +# --home "$ROLLKIT_HOME" \ +# --recover > /dev/null 2>&1 + +echo "$RELAYER_MNEMONIC" | "$ROLLKIT_BIN" keys add relayer \ + --keyring-backend test \ + --home "$ROLLKIT_HOME" \ + --recover > /dev/null 2>&1 + +echo "$USER_MNEMONIC" | "$ROLLKIT_BIN" keys add carl \ + --keyring-backend test \ + --home "$ROLLKIT_HOME" \ + --recover > /dev/null 2>&1 + +"$ROLLKIT_BIN" genesis add-genesis-account validator "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" +#"$ROLLKIT_BIN" genesis add-genesis-account attester "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" +"$ROLLKIT_BIN" genesis add-genesis-account relayer "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" +"$ROLLKIT_BIN" genesis add-genesis-account carl "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" + + +log "33" "📜" "Creating validator transaction..." +"$ROLLKIT_BIN" genesis gentx validator 1000000000stake \ + --chain-id "$CHAIN_ID" \ + --keyring-backend test \ + --home "$ROLLKIT_HOME" + +# 5. Collect gentxs +log "32" "📦" "Collecting genesis transactions..." +"$ROLLKIT_BIN" genesis collect-gentxs --home "$ROLLKIT_HOME" + +# Set validator in consensus block +log "32" "🔄" "Setting validator in consensus block..." +# Extract validator address and pubkey from validator key file, then modify genesis file to set the validator +jq -r '.address as $addr | .pub_key | { + address: $addr, + pub_key: { type: "tendermint/PubKeyEd25519", value: .value }, + power: "1000", + name: "Rollkit Sequencer" +}' "$ROLLKIT_HOME/config/priv_validator_key.json" | \ +jq --slurpfile genesis "$ROLLKIT_HOME/config/genesis.json" \ + '. as $validator | ($genesis[0] | .consensus.validators += [$validator])' > \ + "$ROLLKIT_HOME/config/tmp_genesis.json" && \ +mv "$ROLLKIT_HOME/config/tmp_genesis.json" "$ROLLKIT_HOME/config/genesis.json" + +# 6. Configure minimum gas prices +log "33" "⛽" "Setting minimum gas prices..." +sed -i.bak -E 's#minimum-gas-prices = ""#minimum-gas-prices = "0stake"#g' "$ROLLKIT_HOME/config/app.toml" + +# 7. Modify consensus timeouts +log "34" "⏱️" "Adjusting consensus timeouts..." +sed -i.bak -E 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$ROLLKIT_HOME/config/config.toml" +sed -i.bak -E 's/timeout_propose = "3s"/timeout_propose = "1s"/g' "$ROLLKIT_HOME/config/config.toml" + +# enable api +sed -i.bak 's#enable = false#enable = true#g' "$ROLLKIT_HOME/config/app.toml" + + + +# Build and start local DA +echo "Building and starting local DA..." +# --- Kill previous local-da process if running --- +echo "Checking for existing local-da process on port 7980..." +# Find PID using lsof on the DA port (adjust if your DA uses a different port) +DA_PORT=7980 +EXISTING_PID=$(lsof -ti tcp:${DA_PORT}) + +if [ -n "$EXISTING_PID" ]; then + echo "Found existing processes on port $DA_PORT with PIDs: $EXISTING_PID. Killing..." + # Kill the process(es) + kill -9 $EXISTING_PID + # Allow a moment for the OS to release the port + sleep 2 +else + echo "No existing process found on port $DA_PORT." +fi +# --- End Kill previous local-da process --- + + +if [ ! -f "$LOCAL_DA_PATH" ]; then + echo "Error: local-da binary not found at $LOCAL_DA_PATH" + exit 1 +else + echo "Starting local DA in background..." + $LOCAL_DA_PATH & + DA_PID=$! + echo "Local DA started with PID $DA_PID" + sleep 2 # Give DA a moment to start +fi + +log "35" "🚀" "Starting ROLLKIT node..." +"$ROLLKIT_BIN" start --home "$ROLLKIT_HOME" --rollkit.node.aggregator --minimum-gas-prices "0stake" --rollkit.node.lazy_block_interval=150ms --rollkit.node.block_time=100ms --rollkit.da.block_time=500ms --pruning=nothing --rollkit.network.soft-confirmation & +ROLLKIT_PID=$! +log "36" "✅" "ROLLKIT chain running successfully!" +wait $ROLLKIT_PID diff --git a/modules/network/client/cli/tx.go b/modules/network/client/cli/tx.go index 267de6bf..bd8ef3e9 100644 --- a/modules/network/client/cli/tx.go +++ b/modules/network/client/cli/tx.go @@ -2,6 +2,7 @@ package cli import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "strconv" "github.com/cosmos/cosmos-sdk/client" @@ -49,9 +50,9 @@ func CmdAttest() *cobra.Command { } vote := []byte(args[1]) - + valAddress := sdk.ValAddress(clientCtx.GetFromAddress()).String() msg := types.NewMsgAttest( - clientCtx.GetFromAddress().String(), + valAddress, height, vote, ) @@ -81,10 +82,8 @@ func CmdJoinAttesterSet() *cobra.Command { return err } - msg := types.NewMsgJoinAttesterSet( - clientCtx.GetFromAddress().String(), - ) - + valAddress := sdk.ValAddress(clientCtx.GetFromAddress()).String() + msg := types.NewMsgJoinAttesterSet(valAddress) if err := msg.ValidateBasic(); err != nil { return err } @@ -110,9 +109,8 @@ func CmdLeaveAttesterSet() *cobra.Command { return err } - msg := types.NewMsgLeaveAttesterSet( - clientCtx.GetFromAddress().String(), - ) + valAddress := sdk.ValAddress(clientCtx.GetFromAddress()).String() + msg := types.NewMsgLeaveAttesterSet(valAddress) if err := msg.ValidateBasic(); err != nil { return err diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index 66d70f18..5b8ec98e 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -135,13 +135,13 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { // todo (Alex): show we really fail? //return fmt.Errorf("no checkpoints achieved quorum in epoch: %d", epoch) k.Logger(ctx).Info("No checkpoints achieved quorum in epoch", "epoch", epoch) - return nil } } - if err := k.PruneOldBitmaps(ctx, epoch); err != nil { - return fmt.Errorf("pruning old data at epoch %d: %w", epoch, err) - } + // todo (Alex): find a way to prune only bitmaps that are not used anymore + //if err := k.PruneOldBitmaps(ctx, epoch); err != nil { + // return fmt.Errorf("pruning old data at epoch %d: %w", epoch, err) + //} if err := k.BuildValidatorIndexMap(ctx); err != nil { return fmt.Errorf("rebuilding validator index map at epoch %d: %w", epoch, err) diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index 5d94dde6..5be9d506 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -27,6 +27,8 @@ var _ types.MsgServer = msgServer{} func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.MsgAttestResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + var index uint16 + if !k.IsCheckpointHeight(ctx, msg.Height) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "height %d is not a checkpoint", msg.Height) } @@ -35,7 +37,8 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "validator %s not in attester set", msg.Validator) } - index, found := k.GetValidatorIndex(ctx, msg.Validator) + var found bool + index, found = k.GetValidatorIndex(ctx, msg.Validator) if !found { return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator index not found for %s", msg.Validator) } @@ -123,10 +126,10 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte if !validator.IsBonded() { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator must be bonded to join attester set") } - if k.IsInAttesterSet(ctx, msg.Validator) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator already in attester set") } + // TODO (Alex): the valset should be updated at the end of an epoch only if err := k.SetAttesterSetMember(ctx, msg.Validator); err != nil { return nil, errors.Wrap(err, "failed to set attester set member") @@ -138,7 +141,7 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte sdk.NewAttribute("validator", msg.Validator), ), ) - + k.Logger(ctx).Info("+++ joined attester set", "validator", msg.Validator) return &types.MsgJoinAttesterSetResponse{}, nil } diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go index 8cb76564..002873a0 100644 --- a/modules/network/keeper/msg_server_test.go +++ b/modules/network/keeper/msg_server_test.go @@ -157,18 +157,21 @@ func (m *MockStakingKeeper) SetValidator(ctx context.Context, validator stakingt return nil } -func (m MockStakingKeeper) GetAllValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { +func (m MockStakingKeeper) GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) { return slices.SortedFunc(maps.Values(m.activeSet), func(v1 stakingtypes.Validator, v2 stakingtypes.Validator) int { return strings.Compare(v1.OperatorAddress, v2.OperatorAddress) - }) + }), nil } -func (m MockStakingKeeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, found bool) { - validator, found = m.activeSet[addr.String()] - return +func (m MockStakingKeeper) GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error) { + validator, found := m.activeSet[addr.String()] + if !found { + return validator, sdkerrors.ErrNotFound + } + return validator, nil } -func (m MockStakingKeeper) GetLastValidators(ctx sdk.Context) (validators []stakingtypes.Validator) { +func (m MockStakingKeeper) GetLastValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) { for _, validator := range m.activeSet { if validator.IsBonded() { // Assuming IsBonded() identifies if a validator is in the last validators validators = append(validators, validator) @@ -177,6 +180,6 @@ func (m MockStakingKeeper) GetLastValidators(ctx sdk.Context) (validators []stak return } -func (m MockStakingKeeper) GetLastTotalPower(ctx sdk.Context) math.Int { - return math.NewInt(int64(len(m.activeSet))) +func (m MockStakingKeeper) GetLastTotalPower(ctx context.Context) (math.Int, error) { + return math.NewInt(int64(len(m.activeSet))), nil } diff --git a/modules/network/types/msgs.go b/modules/network/types/msgs.go index cb90200a..a8c0d94d 100644 --- a/modules/network/types/msgs.go +++ b/modules/network/types/msgs.go @@ -37,11 +37,11 @@ func (msg *MsgAttest) Type() string { // GetSigners returns the expected signers func (msg *MsgAttest) GetSigners() []sdk.AccAddress { - addr, err := sdk.AccAddressFromBech32(msg.Validator) + addr, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { panic(err) } - return []sdk.AccAddress{addr} + return []sdk.AccAddress{sdk.AccAddress(addr)} } // GetSignBytes returns the bytes for signing @@ -52,7 +52,7 @@ func (msg *MsgAttest) GetSignBytes() []byte { // ValidateBasic performs basic validation func (msg *MsgAttest) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Validator) + _, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) } @@ -87,11 +87,11 @@ func (msg *MsgJoinAttesterSet) Type() string { // GetSigners returns the expected signers func (msg *MsgJoinAttesterSet) GetSigners() []sdk.AccAddress { - addr, err := sdk.AccAddressFromBech32(msg.Validator) + addr, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { panic(err) } - return []sdk.AccAddress{addr} + return []sdk.AccAddress{sdk.AccAddress(addr)} } // GetSignBytes returns the bytes for signing @@ -102,7 +102,7 @@ func (msg *MsgJoinAttesterSet) GetSignBytes() []byte { // ValidateBasic performs basic validation func (msg *MsgJoinAttesterSet) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Validator) + _, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) } @@ -129,11 +129,11 @@ func (msg *MsgLeaveAttesterSet) Type() string { // GetSigners returns the expected signers func (msg *MsgLeaveAttesterSet) GetSigners() []sdk.AccAddress { - addr, err := sdk.AccAddressFromBech32(msg.Validator) + addr, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { panic(err) } - return []sdk.AccAddress{addr} + return []sdk.AccAddress{sdk.AccAddress(addr)} } // GetSignBytes returns the bytes for signing @@ -144,7 +144,7 @@ func (msg *MsgLeaveAttesterSet) GetSignBytes() []byte { // ValidateBasic performs basic validation func (msg *MsgLeaveAttesterSet) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Validator) + _, err := sdk.ValAddressFromBech32(msg.Validator) if err != nil { return errors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid validator address (%s)", err) } diff --git a/modules/network/types/params.go b/modules/network/types/params.go index 6d1bc183..15358e2b 100644 --- a/modules/network/types/params.go +++ b/modules/network/types/params.go @@ -18,7 +18,7 @@ var ( // Default parameter values var ( - DefaultEpochLength = uint64(100) + DefaultEpochLength = uint64(10) // todo (Alex): what is a good default? DefaultQuorumFraction = math.LegacyNewDecWithPrec(667, 3) // 2/3 DefaultMinParticipation = math.LegacyNewDecWithPrec(5, 1) // 1/2 DefaultPruneAfter = uint64(7) diff --git a/modules/network/types/tx.pb.go b/modules/network/types/tx.pb.go index 5323919d..d618154e 100644 --- a/modules/network/types/tx.pb.go +++ b/modules/network/types/tx.pb.go @@ -354,40 +354,41 @@ func init() { func init() { proto.RegisterFile("rollkitsdk/network/v1/tx.proto", fileDescriptor_cad4541892a6f0bf) } var fileDescriptor_cad4541892a6f0bf = []byte{ - // 521 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0x31, 0x6f, 0xd3, 0x40, - 0x14, 0xc7, 0x7d, 0xa4, 0x44, 0xea, 0xa3, 0x52, 0xc1, 0x2d, 0x6d, 0x6a, 0xa8, 0x13, 0x32, 0xa0, - 0x10, 0x29, 0xb6, 0x12, 0x24, 0x86, 0x32, 0x35, 0x23, 0xc2, 0x12, 0x72, 0xcb, 0xc2, 0x82, 0x9c, - 0xf8, 0xb8, 0x58, 0x89, 0xfd, 0xac, 0xbb, 0x8b, 0x69, 0x37, 0xc4, 0x02, 0x23, 0x9f, 0x00, 0xf5, - 0x1b, 0xd0, 0x81, 0x0f, 0xd1, 0xb1, 0x62, 0x62, 0x42, 0x28, 0x19, 0xca, 0xc7, 0x40, 0xb1, 0x1d, - 0x07, 0xdc, 0x5a, 0x8d, 0x90, 0xd8, 0xee, 0xee, 0xfd, 0xdf, 0xff, 0xff, 0x93, 0xee, 0xe9, 0x81, - 0xce, 0x71, 0x34, 0x1a, 0x7a, 0x52, 0xb8, 0x43, 0x33, 0xa0, 0xf2, 0x2d, 0xf2, 0xa1, 0x19, 0xb5, - 0x4d, 0x79, 0x64, 0x84, 0x1c, 0x25, 0xaa, 0x77, 0x17, 0x75, 0x23, 0xad, 0x1b, 0x51, 0x5b, 0xdb, - 0xee, 0xa3, 0xf0, 0x51, 0x98, 0xbe, 0x60, 0x33, 0xb9, 0x2f, 0x58, 0xa2, 0xd7, 0x76, 0x92, 0xc2, - 0xeb, 0xf8, 0x66, 0x26, 0x97, 0xb4, 0xb4, 0xc9, 0x90, 0x61, 0xf2, 0x3e, 0x3b, 0xa5, 0xaf, 0x0f, - 0x0a, 0x00, 0x8e, 0x43, 0x9a, 0x36, 0xd6, 0x3f, 0x10, 0x58, 0xb5, 0x04, 0xdb, 0x97, 0x92, 0x0a, - 0xa9, 0x3e, 0x81, 0xd5, 0xc8, 0x19, 0x79, 0xae, 0x23, 0x91, 0x57, 0x48, 0x8d, 0x34, 0x56, 0xbb, - 0x95, 0x6f, 0x5f, 0x5b, 0x9b, 0x69, 0xd6, 0xbe, 0xeb, 0x72, 0x2a, 0xc4, 0x81, 0xe4, 0x5e, 0xc0, - 0xec, 0x85, 0x54, 0xdd, 0x82, 0xf2, 0x80, 0x7a, 0x6c, 0x20, 0x2b, 0x37, 0x6a, 0xa4, 0x51, 0xb2, - 0xd3, 0x9b, 0xaa, 0xc2, 0x4a, 0x84, 0x92, 0x56, 0x4a, 0x35, 0xd2, 0x58, 0xb3, 0xe3, 0xf3, 0xde, - 0xd6, 0xc7, 0x93, 0xaa, 0xf2, 0xeb, 0xa4, 0xaa, 0xbc, 0xbf, 0x38, 0x6d, 0x2e, 0x3c, 0xea, 0x1b, - 0x70, 0x27, 0x03, 0xb1, 0xa9, 0x08, 0x31, 0x10, 0xb4, 0xee, 0x82, 0x6a, 0x09, 0xf6, 0x0c, 0xbd, - 0x20, 0x29, 0x50, 0x7e, 0x40, 0xff, 0x19, 0xb3, 0x30, 0xfa, 0x3e, 0x68, 0x97, 0x53, 0x32, 0x06, - 0x0a, 0x1b, 0x96, 0x60, 0xcf, 0xa9, 0x13, 0xd1, 0xff, 0x09, 0xb1, 0x0b, 0xf7, 0xae, 0x88, 0xc9, - 0x28, 0x3e, 0x13, 0x58, 0xb7, 0x04, 0x7b, 0x19, 0xba, 0x8e, 0xa4, 0x2f, 0x1c, 0xee, 0xf8, 0x62, - 0x86, 0xe0, 0x8c, 0xe5, 0x00, 0xb9, 0x27, 0x8f, 0xaf, 0x47, 0xc8, 0xa4, 0xea, 0x53, 0x28, 0x87, - 0xb1, 0x43, 0xfc, 0x5d, 0xb7, 0x3a, 0xbb, 0xc6, 0x95, 0x93, 0x68, 0x24, 0x31, 0xdd, 0x95, 0xb3, - 0x1f, 0x55, 0xc5, 0x4e, 0x5b, 0x72, 0xfc, 0x99, 0x69, 0x7d, 0x07, 0xb6, 0x73, 0x7c, 0x73, 0xf6, - 0xce, 0x97, 0x12, 0x94, 0x2c, 0xc1, 0xd4, 0x43, 0x28, 0xa7, 0x83, 0x56, 0x2b, 0x48, 0xcc, 0x26, - 0x40, 0x6b, 0x5c, 0xa7, 0x98, 0xbb, 0xab, 0x08, 0xeb, 0xf9, 0x01, 0x79, 0x54, 0xdc, 0x9c, 0x93, - 0x6a, 0xed, 0xa5, 0xa5, 0x59, 0x20, 0x87, 0xdb, 0x97, 0xa6, 0xa1, 0x59, 0x6c, 0x93, 0xd7, 0x6a, - 0x9d, 0xe5, 0xb5, 0x59, 0xe6, 0x1b, 0x58, 0xfb, 0xeb, 0xeb, 0x1f, 0x16, 0x7b, 0xfc, 0xa9, 0xd3, - 0x8c, 0xe5, 0x74, 0xf3, 0x1c, 0xed, 0xe6, 0xbb, 0x8b, 0xd3, 0x26, 0xe9, 0x1e, 0x9e, 0x4d, 0x74, - 0x72, 0x3e, 0xd1, 0xc9, 0xcf, 0x89, 0x4e, 0x3e, 0x4d, 0x75, 0xe5, 0x7c, 0xaa, 0x2b, 0xdf, 0xa7, - 0xba, 0xf2, 0x6a, 0x8f, 0x79, 0x72, 0x30, 0xee, 0x19, 0x7d, 0xf4, 0xcd, 0xd4, 0xda, 0x64, 0xd8, - 0xa2, 0x47, 0xb4, 0x3f, 0x96, 0x1e, 0x06, 0x2d, 0xa7, 0xd7, 0xf7, 0x4c, 0x1f, 0xdd, 0xf1, 0x88, - 0x8a, 0x6c, 0xeb, 0xc4, 0x2b, 0xa7, 0x57, 0x8e, 0x77, 0xce, 0xe3, 0xdf, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x40, 0xf9, 0x36, 0x1c, 0x19, 0x05, 0x00, 0x00, + // 534 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x94, 0x31, 0x6f, 0xd3, 0x40, + 0x14, 0xc7, 0x7d, 0xa4, 0x44, 0xca, 0xa3, 0x52, 0xe1, 0x5a, 0xda, 0xd4, 0x50, 0x27, 0xcd, 0x80, + 0x42, 0xa4, 0xd8, 0x4a, 0x90, 0x18, 0xca, 0x80, 0x9a, 0x11, 0x11, 0x09, 0xb9, 0x85, 0x81, 0x05, + 0x39, 0xf1, 0x71, 0xb1, 0x12, 0xfb, 0xac, 0xbb, 0x8b, 0x69, 0x37, 0xc4, 0xc4, 0xd8, 0x4f, 0x80, + 0xfa, 0x0d, 0xe8, 0xd0, 0x0f, 0xd1, 0xb1, 0xea, 0xc4, 0x84, 0x50, 0x32, 0x94, 0x8f, 0x81, 0x6a, + 0x5f, 0x1c, 0x70, 0x6b, 0x11, 0x09, 0x89, 0xed, 0xee, 0xde, 0xff, 0xfd, 0xff, 0x3f, 0xe9, 0x9e, + 0x1e, 0x18, 0x9c, 0x8d, 0x46, 0x43, 0x4f, 0x0a, 0x77, 0x68, 0x05, 0x44, 0x7e, 0x60, 0x7c, 0x68, + 0x45, 0x2d, 0x4b, 0x1e, 0x98, 0x21, 0x67, 0x92, 0xe1, 0xfb, 0xf3, 0xba, 0xa9, 0xea, 0x66, 0xd4, + 0xd2, 0x37, 0xfa, 0x4c, 0xf8, 0x4c, 0x58, 0xbe, 0xa0, 0x57, 0x72, 0x5f, 0xd0, 0x44, 0xaf, 0x6f, + 0x26, 0x85, 0x77, 0xf1, 0xcd, 0x4a, 0x2e, 0xaa, 0xb4, 0x46, 0x19, 0x65, 0xc9, 0xfb, 0xd5, 0x49, + 0xbd, 0x6e, 0xe7, 0x00, 0x1c, 0x86, 0x44, 0x35, 0xd6, 0x8e, 0x10, 0x94, 0xba, 0x82, 0xee, 0x4a, + 0x49, 0x84, 0xc4, 0xcf, 0xa1, 0x14, 0x39, 0x23, 0xcf, 0x75, 0x24, 0xe3, 0x65, 0x54, 0x45, 0xf5, + 0x52, 0x67, 0xfb, 0xe2, 0xb4, 0xb9, 0xa5, 0xb2, 0xde, 0xcc, 0x6a, 0xbb, 0xae, 0xcb, 0x89, 0x10, + 0x7b, 0x92, 0x7b, 0x01, 0xb5, 0xe7, 0x3d, 0x78, 0x1d, 0x8a, 0x03, 0xe2, 0xd1, 0x81, 0x2c, 0xdf, + 0xaa, 0xa2, 0x7a, 0xc1, 0x56, 0x37, 0x8c, 0x61, 0x29, 0x62, 0x92, 0x94, 0x0b, 0x55, 0x54, 0x5f, + 0xb6, 0xe3, 0xf3, 0xce, 0xfa, 0xe7, 0xe3, 0x8a, 0xf6, 0xf3, 0xb8, 0xa2, 0x7d, 0xba, 0x3c, 0x69, + 0xcc, 0x3d, 0x6a, 0xab, 0x70, 0x2f, 0x25, 0xb2, 0x89, 0x08, 0x59, 0x20, 0x48, 0xcd, 0x07, 0xdc, + 0x15, 0xf4, 0x05, 0xf3, 0x82, 0xa4, 0x40, 0xf8, 0x1e, 0xf9, 0x77, 0xde, 0x5c, 0x86, 0x87, 0xa0, + 0x5f, 0x8f, 0x4b, 0x61, 0x02, 0x58, 0xed, 0x0a, 0xfa, 0x92, 0x38, 0x11, 0xf9, 0x2f, 0x34, 0x5b, + 0xf0, 0xe0, 0x86, 0xbc, 0x14, 0xe7, 0x0b, 0x82, 0x95, 0xae, 0xa0, 0xaf, 0x43, 0xd7, 0x91, 0xe4, + 0x95, 0xc3, 0x1d, 0x5f, 0xe0, 0xa7, 0x50, 0x72, 0xc6, 0x72, 0xc0, 0xb8, 0x27, 0x0f, 0x15, 0x4b, + 0xf9, 0xe2, 0xb4, 0xb9, 0xa6, 0x58, 0x32, 0x08, 0xa9, 0x14, 0x3f, 0x83, 0x62, 0x18, 0x3b, 0xc4, + 0x1f, 0x78, 0xa7, 0xbd, 0x65, 0xde, 0x38, 0xa4, 0x66, 0x12, 0xd3, 0x59, 0x3a, 0xfb, 0x5e, 0xd1, + 0x6c, 0xd5, 0x92, 0xe1, 0x4f, 0x4d, 0x6b, 0x9b, 0xb0, 0x91, 0xe1, 0x9b, 0xb1, 0xb7, 0xbf, 0x16, + 0xa0, 0xd0, 0x15, 0x14, 0xef, 0x43, 0x51, 0xcd, 0x60, 0x35, 0x27, 0x31, 0x9d, 0x09, 0xbd, 0xfe, + 0x37, 0xc5, 0xcc, 0x1d, 0x33, 0x58, 0xc9, 0x8e, 0xcc, 0xe3, 0xfc, 0xe6, 0x8c, 0x54, 0x6f, 0x2d, + 0x2c, 0x4d, 0x03, 0x39, 0xdc, 0xbd, 0x36, 0x16, 0x8d, 0x7c, 0x9b, 0xac, 0x56, 0x6f, 0x2f, 0xae, + 0x4d, 0x33, 0xdf, 0xc3, 0xf2, 0x1f, 0x5f, 0xff, 0x28, 0xdf, 0xe3, 0x77, 0x9d, 0x6e, 0x2e, 0xa6, + 0x9b, 0xe5, 0xe8, 0xb7, 0x3f, 0x5e, 0x9e, 0x34, 0x50, 0x67, 0xff, 0x6c, 0x62, 0xa0, 0xf3, 0x89, + 0x81, 0x7e, 0x4c, 0x0c, 0x74, 0x34, 0x35, 0xb4, 0xf3, 0xa9, 0xa1, 0x7d, 0x9b, 0x1a, 0xda, 0xdb, + 0x1d, 0xea, 0xc9, 0xc1, 0xb8, 0x67, 0xf6, 0x99, 0x6f, 0x29, 0x6b, 0x8b, 0xb2, 0x26, 0x39, 0x20, + 0xfd, 0xb1, 0xf4, 0x58, 0xd0, 0x74, 0x7a, 0x7d, 0xcf, 0xf2, 0x99, 0x3b, 0x1e, 0x11, 0x91, 0x2e, + 0xa4, 0x78, 0x1b, 0xf5, 0x8a, 0xf1, 0x3a, 0x7a, 0xf2, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x2f, 0x15, + 0x7c, 0x0d, 0x34, 0x05, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/modules/proto/rollkitsdk/network/v1/tx.proto b/modules/proto/rollkitsdk/network/v1/tx.proto index b794f736..f555dc8c 100644 --- a/modules/proto/rollkitsdk/network/v1/tx.proto +++ b/modules/proto/rollkitsdk/network/v1/tx.proto @@ -33,7 +33,7 @@ message MsgAttest { option (gogoproto.goproto_getters) = false; // validator is the address of the validator submitting the attestation - string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string validator = 1 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; // height is the checkpoint height being attested int64 height = 2; @@ -52,7 +52,7 @@ message MsgJoinAttesterSet { option (gogoproto.goproto_getters) = false; // validator is the address of the validator joining - string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string validator = 1 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; } // MsgJoinAttesterSetResponse is the response type for the JoinAttesterSet RPC @@ -65,7 +65,7 @@ message MsgLeaveAttesterSet { option (gogoproto.goproto_getters) = false; // validator is the address of the validator leaving - string validator = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + string validator = 1 [(cosmos_proto.scalar) = "cosmos.ValidatorAddressString"]; } // MsgLeaveAttesterSetResponse is the response type for the LeaveAttesterSet RPC diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index a1f6ac0f..60cae950 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -2,8 +2,11 @@ package adapter import ( "context" + "crypto/sha256" + "encoding/hex" "errors" "fmt" + "strings" "time" "cosmossdk.io/log" @@ -84,7 +87,8 @@ type Adapter struct { Logger log.Logger metrics *Metrics - blockFilter BlockFilter + blockFilter BlockFilter + stackedEvents []StackedEvent } // NewABCIExecutor creates a new Adapter instance that implements the go-execution.Executor interface. @@ -255,7 +259,7 @@ func (a *Adapter) InitChain(ctx context.Context, genesisTime time.Time, initialH InitialHeight: int64(initialHeight), }) if err != nil { - return nil, 0, err + return nil, 0, fmt.Errorf("app initialize chain: %w", err) } s := &cmtstate.State{} @@ -268,7 +272,7 @@ func (a *Adapter) InitChain(ctx context.Context, genesisTime time.Time, initialH vals, err := cmttypes.PB2TM.ValidatorUpdates(res.Validators) if err != nil { - return nil, 0, err + return nil, 0, fmt.Errorf("validator updates: %w", err) } nValSet := cmttypes.NewValidatorSet(vals) @@ -362,6 +366,11 @@ func (a *Adapter) ExecuteTxs( return nil, 0, err } + for i, tx := range txs { + sum256 := sha256.Sum256(tx) + a.Logger.Info("+++ processed TX", "hash", strings.ToUpper(hex.EncodeToString(sum256[:])), "result", fbResp.TxResults[i].Code, "log", fbResp.TxResults[i].Log, "height", blockHeight) + } + s.AppHash = fbResp.AppHash s.LastBlockHeight = int64(blockHeight) @@ -443,40 +452,44 @@ func (a *Adapter) ExecuteTxs( if err != nil { return nil, 0, err } - if a.blockFilter.IsPublishable(ctx, int64(blockHeight)) { - cmtTxs := make(cmttypes.Txs, len(txs)) - for i := range txs { - cmtTxs[i] = txs[i] - } + cmtTxs := make(cmttypes.Txs, len(txs)) + for i := range txs { + cmtTxs[i] = txs[i] + } - // if blockheight is 0, we create a signed last commit. - if blockHeight == 0 { - lastCommit.Signatures = []cmttypes.CommitSig{ - { - BlockIDFlag: cmttypes.BlockIDFlagCommit, - ValidatorAddress: s.Validators.Proposer.Address, - Timestamp: time.Now().UTC(), - Signature: []byte{}, - }, - } + // if blockheight is 0, we create a signed last commit. + if blockHeight == 0 { + lastCommit.Signatures = []cmttypes.CommitSig{ + { + BlockIDFlag: cmttypes.BlockIDFlagCommit, + ValidatorAddress: s.Validators.Proposer.Address, + Timestamp: time.Now().UTC(), + Signature: []byte{}, + }, } + } - block := s.MakeBlock(int64(blockHeight), cmtTxs, lastCommit, nil, s.Validators.Proposer.Address) + block := s.MakeBlock(int64(blockHeight), cmtTxs, lastCommit, nil, s.Validators.Proposer.Address) - currentBlockID := cmttypes.BlockID{ - Hash: block.Hash(), - PartSetHeader: cmttypes.PartSetHeader{Total: 1, Hash: block.DataHash}, - } - - if err := fireEvents(a.EventBus, block, currentBlockID, fbResp, validatorUpdates); err != nil { - a.Logger.Error("failed to fire events", "err", err) - } + currentBlockID := cmttypes.BlockID{ + Hash: block.Hash(), + PartSetHeader: cmttypes.PartSetHeader{Total: 1, Hash: block.DataHash}, + } - // save the finalized block response - if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { - return nil, 0, fmt.Errorf("failed to save block response: %w", err) + // save the finalized block response + if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { + return nil, 0, fmt.Errorf("failed to save block response: %w", err) + } + a.stackBlockCommitEvents(currentBlockID, block, fbResp, validatorUpdates) + if a.blockFilter.IsPublishable(ctx, int64(header.Height())) { + if err := a.publishQueuedBlockEvents(ctx, int64(header.Height())); err != nil { + return nil, 0, err } } + // save the finalized block response + if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { + return nil, 0, fmt.Errorf("failed to save block response: %w", err) + } a.Logger.Info("block executed successfully", "height", blockHeight, "appHash", fmt.Sprintf("%X", fbResp.AppHash)) return fbResp.AppHash, uint64(s.ConsensusParams.Block.MaxBytes), nil } @@ -599,6 +612,28 @@ func cometCommitToABCICommitInfo(commit *cmttypes.Commit) abci.CommitInfo { } } +type StackedEvent struct { + blockID cmttypes.BlockID + block *cmttypes.Block + abciResponse *abci.ResponseFinalizeBlock + validatorUpdates []*cmttypes.Validator +} + +func (a *Adapter) stackBlockCommitEvents( + blockID cmttypes.BlockID, + block *cmttypes.Block, + abciResponse *abci.ResponseFinalizeBlock, + validatorUpdates []*cmttypes.Validator, +) { + // todo (Alex): we need this persisted to recover from restart + a.stackedEvents = append(a.stackedEvents, StackedEvent{ + blockID: blockID, + block: block, + abciResponse: abciResponse, + validatorUpdates: validatorUpdates, + }) +} + // GetTxs calls PrepareProposal with the next height from the store and returns the transactions from the ABCI app func (a *Adapter) GetTxs(ctx context.Context) ([][]byte, error) { getTxsStart := time.Now() @@ -647,5 +682,38 @@ func (a *Adapter) GetTxs(ctx context.Context) ([][]byte, error) { // SetFinal handles extra logic once the block has been finalized (posted to DA). // For a Cosmos SDK app, this is a no-op we do not need to do anything to mark the block as finalized. func (a *Adapter) SetFinal(ctx context.Context, blockHeight uint64) error { + return a.publishQueuedBlockEvents(ctx, int64(blockHeight)) +} + +func (a *Adapter) publishQueuedBlockEvents(ctx context.Context, persistedHeight int64) error { + maxPosReleased := -1 + for i, v := range a.stackedEvents { + h := v.block.Height + if h <= persistedHeight && a.blockFilter.IsPublishable(ctx, h) { + maxPosReleased = i + } + } + a.Logger.Info("processing stack for soft consensus", "count", len(a.stackedEvents), "soft_consensus", maxPosReleased != -1) + + if maxPosReleased == -1 { + return nil + } + softCommitHeight := a.stackedEvents[maxPosReleased].block.Height + for i := 0; i <= maxPosReleased; i++ { + // todo (Alex): exit loop when ctx cancelled + select { + case <-ctx.Done(): + maxPosReleased = i + break + default: + } + v := a.stackedEvents[i] + if err := fireEvents(a.EventBus, v.block, v.blockID, v.abciResponse, v.validatorUpdates); err != nil { + return fmt.Errorf("fire events: %w", err) + } + a.Logger.Info("releasing block with soft consensus", "height", v.block.Height, "soft_consensus", softCommitHeight) + } + a.stackedEvents = a.stackedEvents[maxPosReleased+1:] + a.Logger.Info("remaining stack after soft consensus", "count", len(a.stackedEvents), "soft_consensus", softCommitHeight) return nil } diff --git a/pkg/adapter/options.go b/pkg/adapter/options.go index f37fb7c2..f8c9bea4 100644 --- a/pkg/adapter/options.go +++ b/pkg/adapter/options.go @@ -2,6 +2,7 @@ package adapter import ( "context" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" servertypes "github.com/cosmos/cosmos-sdk/server/types" @@ -29,14 +30,16 @@ func WithBlockFilter(publisher BlockFilter) Option { func WithNetworkSoftConfirmationBlockFilter() Option { return func(a *Adapter) { a.blockFilter = &NetworkSoftConfirmationBlockFilter{ - app: a.App, + app: a.App, + logger: a.Logger, } } } // NetworkSoftConfirmationBlockFilter is a BlockFilter implementation that uses the network module's SoftConfirmationStatus. type NetworkSoftConfirmationBlockFilter struct { - app servertypes.ABCI + app servertypes.ABCI + logger log.Logger } // IsPublishable implements the BlockFilter interface. @@ -62,13 +65,19 @@ func (f *NetworkSoftConfirmationBlockFilter) IsPublishable(ctx context.Context, softConfirmRes, err := f.app.Query(ctx, softConfirmReq) if err != nil || softConfirmRes.Code != 0 { + var msg string + if softConfirmRes != nil { + msg = softConfirmRes.Log + } + f.logger.Error("query soft confirmation status", "height", height, "error", err, "log", msg) return false } softConfirmResp := &types.QuerySoftConfirmationStatusResponse{} if err := softConfirmResp.Unmarshal(softConfirmRes.Value); err != nil { + f.logger.Error("unmarshal soft confirmation status response", "height", height, "error", err) return false } - + f.logger.Debug("soft confirmation status", "height", height, "is_soft_confirmed", softConfirmResp.IsSoftConfirmed) return softConfirmResp.IsSoftConfirmed } From b0d8b2836f70699e0c0010fe7d28ddbccb1a4881 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 23 Jun 2025 13:37:42 +0200 Subject: [PATCH 11/21] Remove duplicate code --- pkg/adapter/adapter.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index 60cae950..80513bf2 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -457,7 +457,6 @@ func (a *Adapter) ExecuteTxs( cmtTxs[i] = txs[i] } - // if blockheight is 0, we create a signed last commit. if blockHeight == 0 { lastCommit.Signatures = []cmttypes.CommitSig{ { @@ -486,10 +485,6 @@ func (a *Adapter) ExecuteTxs( return nil, 0, err } } - // save the finalized block response - if err := a.Store.SaveBlockResponse(ctx, blockHeight, fbResp); err != nil { - return nil, 0, fmt.Errorf("failed to save block response: %w", err) - } a.Logger.Info("block executed successfully", "height", blockHeight, "appHash", fmt.Sprintf("%X", fbResp.AppHash)) return fbResp.AppHash, uint64(s.ConsensusParams.Block.MaxBytes), nil } @@ -708,6 +703,13 @@ func (a *Adapter) publishQueuedBlockEvents(ctx context.Context, persistedHeight default: } v := a.stackedEvents[i] + + blockHeight := uint64(v.block.Height) + rsp, err := a.Store.GetBlockResponse(ctx, blockHeight) + if err != nil { + return fmt.Errorf("get block response: %w", err) + } + if err := fireEvents(a.EventBus, v.block, v.blockID, v.abciResponse, v.validatorUpdates); err != nil { return fmt.Errorf("fire events: %w", err) } From a0da8fa0a62bf329965aa6e4a54cf453f37826db Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 23 Jun 2025 13:38:26 +0200 Subject: [PATCH 12/21] Remove wip code --- pkg/adapter/adapter.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index 80513bf2..d4560f67 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -704,12 +704,6 @@ func (a *Adapter) publishQueuedBlockEvents(ctx context.Context, persistedHeight } v := a.stackedEvents[i] - blockHeight := uint64(v.block.Height) - rsp, err := a.Store.GetBlockResponse(ctx, blockHeight) - if err != nil { - return fmt.Errorf("get block response: %w", err) - } - if err := fireEvents(a.EventBus, v.block, v.blockID, v.abciResponse, v.validatorUpdates); err != nil { return fmt.Errorf("fire events: %w", err) } From 1565f2c39cad8a0fd458f7e775616aa25ab71b80 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 23 Jun 2025 16:39:16 +0200 Subject: [PATCH 13/21] Fix linter issues --- hack/attester/main.go | 117 +--------------------- modules/network/client/cli/tx.go | 2 +- modules/network/depinject.go | 1 + modules/network/genesis.go | 1 + modules/network/keeper/abci.go | 21 +--- modules/network/keeper/bitmap.go | 2 +- modules/network/keeper/keeper.go | 2 +- modules/network/keeper/msg_server.go | 5 +- modules/network/keeper/msg_server_test.go | 19 ++-- modules/network/types/expected_keepers.go | 1 + modules/network/types/genesis.go | 10 +- pkg/adapter/adapter.go | 3 +- pkg/adapter/options.go | 3 +- server/start.go | 11 +- 14 files changed, 42 insertions(+), 156 deletions(-) diff --git a/hack/attester/main.go b/hack/attester/main.go index 861974da..b4f4076b 100644 --- a/hack/attester/main.go +++ b/hack/attester/main.go @@ -15,7 +15,6 @@ import ( "syscall" "time" - "github.com/gorilla/websocket" "github.com/spf13/cobra" ) @@ -46,8 +45,8 @@ func main() { rootCmd.Flags().String(flagHome, "", "Directory for config and data") rootCmd.Flags().Bool(flagVerbose, false, "Enable verbose output") - rootCmd.MarkFlagRequired(flagChainID) - rootCmd.MarkFlagRequired(flagHome) + _ = rootCmd.MarkFlagRequired(flagChainID) + _ = rootCmd.MarkFlagRequired(flagHome) // Execute if err := rootCmd.Execute(); err != nil { @@ -169,7 +168,7 @@ func getEpochLength(apiAddr string) (uint64, error) { if err != nil { return 0, fmt.Errorf("error getting params: %w", err) } - defer paramsResp.Body.Close() + defer paramsResp.Body.Close() //nolint:errcheck // test code var paramsResult struct { Params struct { @@ -233,11 +232,11 @@ func pullBlocksAndAttest(ctx context.Context, from, chainID, node, home string, if err := json.NewDecoder(resp.Body).Decode(&blockResponse); err != nil { fmt.Printf("Error parsing response: %v\n", err) - resp.Body.Close() + _ = resp.Body.Close() time.Sleep(time.Second / 10) continue } - resp.Body.Close() + _ = resp.Body.Close() // Extract block height height, err := strconv.ParseInt(blockResponse.Result.Block.Header.Height, 10, 64) @@ -271,112 +270,6 @@ func pullBlocksAndAttest(ctx context.Context, from, chainID, node, home string, } } -func watchBlocksAndAttest(ctx context.Context, from, chainID, node, home string, epochLength uint64, verbose bool) error { - // Convert TCP node address to WebSocket address - parsed, err := url.Parse(node) - if err != nil { - return fmt.Errorf("parse node URL: %w", err) - } - wsURL := fmt.Sprintf("ws://%s/websocket", parsed.Host) - fmt.Printf("Connecting to WebSocket at %s\n", wsURL) - - // Connect to WebSocket - c, _, err := websocket.DefaultDialer.Dial(wsURL, nil) - if err != nil { - return fmt.Errorf("error connecting to websocket: %w", err) - } - defer c.Close() - - // Subscribe to new block events - subscribeMsg := map[string]interface{}{ - "jsonrpc": "2.0", - "method": "subscribe", - "id": 1, - "params": map[string]interface{}{ - "query": "tm.event='NewBlock'", - }, - } - - if err := c.WriteJSON(subscribeMsg); err != nil { - return fmt.Errorf("error subscribing to events: %w", err) - } - - // Process incoming messages - var lastAttested int64 = 0 - done := make(chan struct{}) - - go func() { - defer close(done) - for { - _, message, err := c.ReadMessage() - if err != nil { - fmt.Printf("Error reading message: %v\n", err) - return - } - - // Parse the message - var response struct { - Result struct { - Data struct { - Value struct { - Block struct { - Header struct { - Height string `json:"height"` - } `json:"header"` - } `json:"block"` - } `json:"value"` - } `json:"data"` - } `json:"result"` - } - - if err := json.Unmarshal(message, &response); err != nil { - fmt.Printf("Error parsing message: %v\n", err) - continue - } - - // Extract block height - heightStr := response.Result.Data.Value.Block.Header.Height - height, err := strconv.ParseInt(heightStr, 10, 64) - if err != nil { - fmt.Printf("Error parsing height: %v\n", err) - continue - } - - fmt.Printf("New block: %d\n", height) - - // Check if this is the end of an epoch and we haven't attested to it yet - if height > 1 && height%int64(epochLength) == 0 && height > lastAttested { - fmt.Printf("End of epoch at height %d, submitting attestation\n", height) - - // Submit attestation with "0x00" as the hash - err = submitAttestation(ctx, from, chainID, node, home, height, "0x00", verbose) - if err != nil { - fmt.Printf("Error submitting attestation: %v\n", err) - continue - } - - lastAttested = height - } - } - }() - - // Wait for context cancellation - select { - case <-ctx.Done(): - fmt.Println("Context cancelled, closing connection...") - // Close WebSocket connection - err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, "")) - if err != nil { - fmt.Printf("Error closing websocket: %v\n", err) - } - // Wait for the goroutine to finish - <-done - return nil - case <-done: - return fmt.Errorf("websocket connection closed unexpectedly") - } -} - // formatCommandArgs formats command arguments for verbose output func formatCommandArgs(args []string) string { var result string diff --git a/modules/network/client/cli/tx.go b/modules/network/client/cli/tx.go index bd8ef3e9..9bafb53f 100644 --- a/modules/network/client/cli/tx.go +++ b/modules/network/client/cli/tx.go @@ -2,12 +2,12 @@ package cli import ( "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" "strconv" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/cobra" "github.com/rollkit/go-execution-abci/modules/network/types" diff --git a/modules/network/depinject.go b/modules/network/depinject.go index f641787f..01b57e6e 100644 --- a/modules/network/depinject.go +++ b/modules/network/depinject.go @@ -8,6 +8,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/rollkit/go-execution-abci/modules/network/keeper" modulev1 "github.com/rollkit/go-execution-abci/modules/network/module/v1" "github.com/rollkit/go-execution-abci/modules/network/types" diff --git a/modules/network/genesis.go b/modules/network/genesis.go index 6c2e8f52..55be35ea 100644 --- a/modules/network/genesis.go +++ b/modules/network/genesis.go @@ -2,6 +2,7 @@ package network import ( "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/rollkit/go-execution-abci/modules/network/keeper" diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index 5b8ec98e..1381b31f 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -3,6 +3,7 @@ package keeper import ( "crypto/sha256" "encoding/base64" + "errors" "fmt" // For error wrapping if needed @@ -18,8 +19,7 @@ func (k Keeper) BeginBlocker(ctx sdk.Context) error { // Only process if sign mode is IBC_ONLY and we have outbound IBC packets if params.SignMode == types.SignMode_SIGN_MODE_IBC_ONLY { - // TODO: Check for outbound IBC packets - // For now, this is a placeholder + return errors.New("IBC only sign mode not yet implemented") } return nil } @@ -174,20 +174,3 @@ func (k Keeper) emitCheckpointHashes(ctx sdk.Context, height int64, validatorHas ), ) } - -func (k Keeper) emitZeroHashes(ctx sdk.Context, height int64) { - zeroHash := make([]byte, 32) - ctx.EventManager().EmitEvent( - sdk.NewEvent( - "checkpoint", - sdk.NewAttribute("height", math.NewInt(height).String()), - sdk.NewAttribute("validator_hash", base64.StdEncoding.EncodeToString(zeroHash)), - sdk.NewAttribute("commit_hash", base64.StdEncoding.EncodeToString(zeroHash)), - sdk.NewAttribute("soft_confirmed", "false"), - ), - ) -} - -func (k Keeper) AfterValidatorSetUpdates(ctx sdk.Context) { - k.BuildValidatorIndexMap(ctx) -} diff --git a/modules/network/keeper/bitmap.go b/modules/network/keeper/bitmap.go index f60c3a8b..5e4a1c36 100644 --- a/modules/network/keeper/bitmap.go +++ b/modules/network/keeper/bitmap.go @@ -95,4 +95,4 @@ func (bh *BitmapHelper) CountInRange(bitmap []byte, start, end int) int { } } return count -} \ No newline at end of file +} diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index 4fa0de95..e967146a 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -9,6 +9,7 @@ import ( "cosmossdk.io/math" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/rollkit/go-execution-abci/modules/network/types" ) @@ -20,7 +21,6 @@ type Keeper struct { bankKeeper types.BankKeeper authority string bitmapHelper *BitmapHelper - schema collections.Schema // Collections for state management ValidatorIndex collections.Map[string, uint16] diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index 5be9d506..4eb35f0a 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" "cosmossdk.io/errors" "cosmossdk.io/math" @@ -180,7 +181,9 @@ func (k msgServer) UpdateParams(goCtx context.Context, msg *types.MsgUpdateParam return nil, err } - k.SetParams(ctx, msg.Params) + if err := k.SetParams(ctx, msg.Params); err != nil { + return nil, fmt.Errorf("set params: %w", err) + } ctx.EventManager().EmitEvent( sdk.NewEvent( diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go index 002873a0..7f8a992f 100644 --- a/modules/network/keeper/msg_server_test.go +++ b/modules/network/keeper/msg_server_test.go @@ -2,26 +2,27 @@ package keeper import ( "context" - "cosmossdk.io/log" - storetypes "cosmossdk.io/store/types" - cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" - "github.com/cosmos/cosmos-sdk/runtime" - "github.com/cosmos/cosmos-sdk/testutil/integration" - moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - "github.com/stretchr/testify/assert" "maps" "slices" "strings" "testing" "time" + "cosmossdk.io/log" "cosmossdk.io/math" + storetypes "cosmossdk.io/store/types" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/runtime" + "github.com/cosmos/cosmos-sdk/testutil/integration" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/rollkit/go-execution-abci/modules/network/types" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/rollkit/go-execution-abci/modules/network/types" ) func TestJoinAttesterSet(t *testing.T) { diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go index dd9e024d..8c11e6de 100644 --- a/modules/network/types/expected_keepers.go +++ b/modules/network/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( "context" + "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" diff --git a/modules/network/types/genesis.go b/modules/network/types/genesis.go index 1993af4a..fdba803e 100644 --- a/modules/network/types/genesis.go +++ b/modules/network/types/genesis.go @@ -7,9 +7,9 @@ import ( // DefaultGenesisState returns the default genesis state func DefaultGenesisState() *GenesisState { return &GenesisState{ - Params: DefaultParams(), - ValidatorIndices: []ValidatorIndex{}, - AttestationBitmaps: []AttestationBitmap{}, + Params: DefaultParams(), + ValidatorIndices: []ValidatorIndex{}, + AttestationBitmaps: []AttestationBitmap{}, } } @@ -22,7 +22,7 @@ func (gs GenesisState) Validate() error { // Check for duplicate validator indices indexMap := make(map[string]bool) usedIndices := make(map[uint32]bool) - + for _, vi := range gs.ValidatorIndices { if indexMap[vi.Address] { return fmt.Errorf("duplicate validator address: %s", vi.Address) @@ -45,4 +45,4 @@ func (gs GenesisState) Validate() error { } return nil -} \ No newline at end of file +} diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index d4560f67..9f6e23fb 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -694,12 +694,13 @@ func (a *Adapter) publishQueuedBlockEvents(ctx context.Context, persistedHeight return nil } softCommitHeight := a.stackedEvents[maxPosReleased].block.Height +outerLoop: for i := 0; i <= maxPosReleased; i++ { // todo (Alex): exit loop when ctx cancelled select { case <-ctx.Done(): maxPosReleased = i - break + break outerLoop default: } v := a.stackedEvents[i] diff --git a/pkg/adapter/options.go b/pkg/adapter/options.go index f8c9bea4..e9f9aa0f 100644 --- a/pkg/adapter/options.go +++ b/pkg/adapter/options.go @@ -2,10 +2,11 @@ package adapter import ( "context" - "cosmossdk.io/log" + "cosmossdk.io/log" abci "github.com/cometbft/cometbft/abci/types" servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/rollkit/go-execution-abci/modules/network/types" ) diff --git a/server/start.go b/server/start.go index f8b666f0..46e9dcfb 100644 --- a/server/start.go +++ b/server/start.go @@ -2,8 +2,13 @@ package server import ( "context" - "cosmossdk.io/log" "fmt" + "io" + "net" + "os" + "time" + + "cosmossdk.io/log" cmtcfg "github.com/cometbft/cometbft/config" "github.com/cometbft/cometbft/mempool" cmtp2p "github.com/cometbft/cometbft/p2p" @@ -28,10 +33,6 @@ import ( "golang.org/x/sync/errgroup" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "io" - "net" - "os" - "time" "github.com/rollkit/rollkit/da/jsonrpc" "github.com/rollkit/rollkit/node" From 0587cbe38de89cd5b404c4b13ae7541e0c5c835b Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Mon, 23 Jun 2025 16:40:50 +0200 Subject: [PATCH 14/21] Run go mod tidy only --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 41aa0eaa..e26f6537 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( golang.org/x/sync v0.15.0 google.golang.org/genproto/googleapis/api v0.0.0-20250505200425-f936aa4a68b2 google.golang.org/grpc v1.73.0 + google.golang.org/protobuf v1.36.6 ) require ( @@ -336,7 +337,6 @@ require ( gonum.org/v1/gonum v0.15.1 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect - google.golang.org/protobuf v1.36.6 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect From 607b5711ed102ce64c35beef8b4b16cbec9f8c84 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 24 Jun 2025 08:06:58 +0200 Subject: [PATCH 15/21] Remove hack/ folder --- hack/.gitignore | 3 - hack/README.md | 19 -- hack/attester/README.md | 4 - hack/attester/main.go | 334 ---------------------------------- hack/download.sh | 79 -------- hack/ibc-connection-hermes.sh | 131 ------------- hack/ics20-token-transfer.sh | 166 ----------------- hack/init-gaia.sh | 98 ---------- hack/run_gmd.sh | 147 --------------- 9 files changed, 981 deletions(-) delete mode 100644 hack/.gitignore delete mode 100644 hack/README.md delete mode 100644 hack/attester/README.md delete mode 100644 hack/attester/main.go delete mode 100755 hack/download.sh delete mode 100755 hack/ibc-connection-hermes.sh delete mode 100755 hack/ics20-token-transfer.sh delete mode 100755 hack/init-gaia.sh delete mode 100755 hack/run_gmd.sh diff --git a/hack/.gitignore b/hack/.gitignore deleted file mode 100644 index 934e3e0e..00000000 --- a/hack/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -downloads/ -testnet/ -config/ diff --git a/hack/README.md b/hack/README.md deleted file mode 100644 index 9dfc0de1..00000000 --- a/hack/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Hack - -Local test scripts - -## Requirements - -* `gaiad` + `hermes` app are available. Use `download.sh` script to fetch -* Rollkit example app `gmd` is built with network integration and available in the path -* `local-da` is built and located in `../../rollkit/build/local-da` - -## Run local setup - -```shell -./init-gaia.sh # setup and start gaia app -./run_node.sh # setup and start gmd example app + local da -go run ./attester --chain-id=rollkitnet-1 --home=$(pwd)/testnet/gm --from=validator -./ibc-connection-hermes.sh # relayer -./ics20-token-transfer.sh # token transfer -``` diff --git a/hack/attester/README.md b/hack/attester/README.md deleted file mode 100644 index 940c2be4..00000000 --- a/hack/attester/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Attest everything attester - -little helper that pulls new blocks from the rpc node and submits (fake) attestations after each epoch - diff --git a/hack/attester/main.go b/hack/attester/main.go deleted file mode 100644 index b4f4076b..00000000 --- a/hack/attester/main.go +++ /dev/null @@ -1,334 +0,0 @@ -package main - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "os" - "os/exec" - "os/signal" - "strconv" - "syscall" - "time" - - "github.com/spf13/cobra" -) - -const ( - flagFrom = "from" - flagChainID = "chain-id" - flagNode = "node" - flagAPIAddr = "api-addr" - flagHome = "home" - flagVerbose = "verbose" -) - -func main() { - rootCmd := &cobra.Command{ - Use: "attester_ws", - Short: "Attester client for Rollkit using websocket", - Long: `Attester client for Rollkit that joins the attester set and attests to blocks at the end of each epoch.`, - DisableFlagParsing: false, - SuggestionsMinimumDistance: 2, - RunE: runAttester, - } - - // Add flags - rootCmd.Flags().String(flagFrom, "validator", "Name or address of the account to sign with") - rootCmd.Flags().String(flagChainID, "", "Chain ID of the blockchain") - rootCmd.Flags().String(flagNode, "tcp://localhost:26657", "RPC node address") - rootCmd.Flags().String(flagAPIAddr, "http://localhost:1317", "API node address") - rootCmd.Flags().String(flagHome, "", "Directory for config and data") - rootCmd.Flags().Bool(flagVerbose, false, "Enable verbose output") - - _ = rootCmd.MarkFlagRequired(flagChainID) - _ = rootCmd.MarkFlagRequired(flagHome) - - // Execute - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -func runAttester(cmd *cobra.Command, args []string) error { - // Get flags - from, err := cmd.Flags().GetString(flagFrom) - if err != nil { - return err - } - - chainID, err := cmd.Flags().GetString(flagChainID) - if err != nil { - return err - } - - node, err := cmd.Flags().GetString(flagNode) - if err != nil { - return err - } - apiAddr, err := cmd.Flags().GetString(flagAPIAddr) - if err != nil { - return err - } - - home, err := cmd.Flags().GetString(flagHome) - if err != nil { - return err - } - - verbose, err := cmd.Flags().GetBool(flagVerbose) - if err != nil { - return err - } - - // Create context with cancellation - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // Handle OS signals for graceful shutdown - sigCh := make(chan os.Signal, 1) - signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) - go func() { - <-sigCh - fmt.Println("Received signal, shutting down...") - cancel() - }() - - // Step 1: Join attester set - fmt.Println("Joining attester set...") - if err := joinAttesterSet(from, chainID, node, home, verbose); err != nil { - return fmt.Errorf("join attester set: %w", err) - } - - // Step 2: Query network parameters to get epoch length - fmt.Println("Querying network parameters...") - epochLength, err := getEpochLength(apiAddr) - if err != nil { - return fmt.Errorf("get epoch length: %w", err) - } - fmt.Printf("Epoch length: %d blocks\n", epochLength) - - // Step 3 & 4: Watch new block events via websocket and attest at the end of each epoch - fmt.Println("Starting to watch for new blocks...") - if err := pullBlocksAndAttest(ctx, from, chainID, node, home, epochLength, verbose); err != nil { - return fmt.Errorf("error watching blocks: %w", err) - } - - return nil -} - -// joinAttesterSet executes the gmd tx network join-attester command -func joinAttesterSet(from, chainID, node, home string, verbose bool) error { - // Prepare gmd command - args := []string{ - "tx", "network", "join-attester", - "--from", from, - "--chain-id", chainID, - "--node", node, - "--home", home, - "--keyring-backend=test", - "-y", // auto-confirm - } - gmdCmd := exec.Command("gmd", args...) - - // Set output to current process stdout and stderr - gmdCmd.Stdout = os.Stdout - gmdCmd.Stderr = os.Stderr - - // Execute command - if verbose { - fmt.Println("Executing command with all parameters:") - fmt.Printf("gmd %s\n", formatCommandArgs(args)) - } else { - fmt.Println("Executing:", gmdCmd.String()) - } - - if err := gmdCmd.Run(); err != nil { - return fmt.Errorf("execute gmd command: %w", err) - } - - fmt.Println("Successfully joined attester set") - return nil -} - -// getEpochLength queries the network parameters to get the epoch length -func getEpochLength(apiAddr string) (uint64, error) { - // Create a simple HTTP client to query the node - httpClient := &http.Client{ - Timeout: 10 * time.Second, - } - - // Get epoch parameters - paramsResp, err := httpClient.Get(fmt.Sprintf("%s/rollkit/network/v1/params", apiAddr)) - if err != nil { - return 0, fmt.Errorf("error getting params: %w", err) - } - defer paramsResp.Body.Close() //nolint:errcheck // test code - - var paramsResult struct { - Params struct { - EpochLength string `json:"epoch_length"` - } `json:"params"` - } - var buf bytes.Buffer - - if err := json.NewDecoder(io.TeeReader(paramsResp.Body, &buf)).Decode(¶msResult); err != nil { - return 0, fmt.Errorf("error decoding params: %w: got %s", err, buf.String()) - } - - epochLength, err := strconv.ParseUint(paramsResult.Params.EpochLength, 10, 64) - if err != nil { - return 0, fmt.Errorf("epoch length: %w", err) - } - if epochLength == 0 { - return 0, fmt.Errorf("epoch length is 0") - } - - return epochLength, nil -} - -// pullBlocksAndAttest polls for new blocks via HTTP and attests at the end of each epoch -func pullBlocksAndAttest(ctx context.Context, from, chainID, node, home string, epochLength uint64, verbose bool) error { - // Parse node URL - parsed, err := url.Parse(node) - if err != nil { - return fmt.Errorf("parse node URL: %w", err) - } - - httpClient := &http.Client{ - Timeout: 10 * time.Second, - } - - var lastAttested int64 = 0 - - // Poll for new blocks - for { - select { - case <-ctx.Done(): - return nil - default: - // Query latest block - resp, err := httpClient.Get(fmt.Sprintf("http://%s/block", parsed.Host)) - if err != nil { - fmt.Printf("Error querying block: %v\n", err) - time.Sleep(time.Second / 10) - continue - } - - var blockResponse struct { - Result struct { - Block struct { - Header struct { - Height string `json:"height"` - } `json:"header"` - } `json:"block"` - } `json:"result"` - } - - if err := json.NewDecoder(resp.Body).Decode(&blockResponse); err != nil { - fmt.Printf("Error parsing response: %v\n", err) - _ = resp.Body.Close() - time.Sleep(time.Second / 10) - continue - } - _ = resp.Body.Close() - - // Extract block height - height, err := strconv.ParseInt(blockResponse.Result.Block.Header.Height, 10, 64) - if err != nil { - fmt.Printf("Error parsing height: %v\n", err) - time.Sleep(time.Second / 10) - continue - } - - fmt.Printf("Current block: %d\n", height) - - // Check if this is the end of an epoch and we haven't attested to it yet - if height > 1 && height%int64(epochLength) == 0 && height > lastAttested { - fmt.Printf("End of epoch at height %d, submitting attestation\n", height) - - // Submit attestation with "0x00" as the hash - err = submitAttestation(ctx, from, chainID, node, home, height, "0x00", verbose) - if err != nil { - fmt.Printf("Error submitting attestation: %v\n", err) - //time.Sleep(time.Second / 10) - //continue - return err - } - - lastAttested = height - } - - // Wait before next poll - time.Sleep(time.Second / 10) - } - } -} - -// formatCommandArgs formats command arguments for verbose output -func formatCommandArgs(args []string) string { - var result string - for i, arg := range args { - if i > 0 { - result += " " - } - // Add quotes if the argument contains spaces - if containsSpace(arg) { - result += "\"" + arg + "\"" - } else { - result += arg - } - } - return result -} - -// containsSpace checks if a string contains any space character -func containsSpace(s string) bool { - for _, c := range s { - if c == ' ' || c == '\t' || c == '\n' || c == '\r' { - return true - } - } - return false -} - -// submitAttestation creates and submits an attestation for a block using gmd -func submitAttestation(ctx context.Context, from, chainID, node, home string, height int64, blockHash string, verbose bool) error { - // Prepare gmd command - args := []string{ - "tx", "network", "attest", - strconv.FormatInt(height, 10), - blockHash, - "--from", from, - "--chain-id", chainID, - "--node", node, - "--home", home, - "--keyring-backend=test", - "-y", // auto-confirm - } - gmdCmd := exec.Command("gmd", args...) - - // Set output to current process stdout and stderr - gmdCmd.Stdout = os.Stdout - gmdCmd.Stderr = os.Stderr - - // Execute command - if verbose { - fmt.Println("Executing command with all parameters:") - fmt.Printf("gmd %s\n", formatCommandArgs(args)) - } else { - fmt.Println("Executing:", gmdCmd.String()) - } - - if err := gmdCmd.Run(); err != nil { - return fmt.Errorf("execute gmd command: %w", err) - } - - fmt.Println("Attestation submitted successfully") - return nil -} diff --git a/hack/download.sh b/hack/download.sh deleted file mode 100755 index 9011b3da..00000000 --- a/hack/download.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/bash - - -HERMES_VERSION=${1:-"v1.13.1"} -GAIAD_VERSION=${2:-"v24.0.0"} - -ARCH=$(uname -m) -OS=$(uname -s) - -case "$ARCH" in - "arm64") - ARCH_LABEL="aarch64" - ;; - "x86_64") - ARCH_LABEL="x86_64" - ;; - *) - echo "Unsupported architecture: $ARCH" - exit 1 - ;; -esac - -case "$OS" in - "Darwin") - OS_LABEL="apple-darwin" - ;; - "Linux") - OS_LABEL="unknown-linux-gnu" - ;; - *) - echo "Unsupported operating system: $OS" - exit 1 - ;; -esac - -HERMES_URL="https://github.com/informalsystems/hermes/releases/download/$HERMES_VERSION/hermes-$HERMES_VERSION-${ARCH_LABEL}-${OS_LABEL}.tar.gz" -GAIAD_URL="https://github.com/cosmos/gaia/releases/download/$GAIAD_VERSION/gaiad-$GAIAD_VERSION-darwin-$ARCH" - -if [ "$OS" == "Linux" ]; then - GAIAD_URL="https://github.com/cosmos/gaia/releases/download/$GAIAD_VERSION/gaiad-$GAIAD_VERSION-linux-amd64" -fi - -# Define output directories -DOWNLOAD_DIR="./downloads" -mkdir -p "$DOWNLOAD_DIR" - -# Function to download a file -download_file() { - local url=$1 - local output_path=$2 - - echo "Downloading: $url" - curl -L -o "$output_path" "$url" - if [ $? -ne 0 ]; then - echo "Failed to download $url" - exit 1 - fi -} - -# Download hermes -HERMES_ARCHIVE="$DOWNLOAD_DIR/hermes.tar.gz" -download_file "$HERMES_URL" "$HERMES_ARCHIVE" - -# Extract hermes if tar.gz -if [[ "$HERMES_ARCHIVE" == *.tar.gz ]]; then - echo "Extracting: $HERMES_ARCHIVE" - tar -xzvf "$HERMES_ARCHIVE" -C "$DOWNLOAD_DIR" -elif [[ "$HERMES_ARCHIVE" == *.zip ]]; then - echo "Extracting: $HERMES_ARCHIVE" - unzip "$HERMES_ARCHIVE" -d "$DOWNLOAD_DIR" -fi - -GAIAD_BINARY="$DOWNLOAD_DIR/gaiad" -download_file "$GAIAD_URL" "$GAIAD_BINARY" - -# Make gaiad binary executable -chmod +x "$GAIAD_BINARY" - -echo "Hermes and Gaiad downloaded successfully to $DOWNLOAD_DIR" \ No newline at end of file diff --git a/hack/ibc-connection-hermes.sh b/hack/ibc-connection-hermes.sh deleted file mode 100755 index 5625e8aa..00000000 --- a/hack/ibc-connection-hermes.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/bash -set -e - -# Configuration variables -GAIA_CHAIN_ID="localnet-1" -WORDLED_CHAIN_ID="rollkitnet-1" - -GAIA_RPC="http://localhost:26654" -WORDLED_RPC="http://localhost:26657" - -GAIA_GRPC="http://localhost:9091" -WORDLED_GRPC="http://localhost:9090" - -GAIA_DENOM="stake" -WORDLED_DENOM="stake" - -RELAYER_WALLET="relayer" # Name of relayer account - -# Hardcoded mnemonic (must match initialization scripts) -RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" - - -# Logging functions -log_info() { - echo "[INFO] $1" -} - -log_success() { - echo "[SUCCESS] $1" -} - -log_error() { - echo "[ERROR] $1" >&2 -} - -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -HERMES_BIN="${HERMES_BIN:-$CURRENT_DIR/downloads/hermes}" - -# Verify Hermes is installed -if [ ! -f "$HERMES_BIN" ]; then - log_error "Hermes not found at $HERMES_BIN" - exit 1 -fi -log_success "Hermes installed" - -CONFIG_DIR="${CURRENT_DIR}/testnet/hermes" -rm -rf "$CONFIG_DIR" -mkdir -p "$CONFIG_DIR" - -# Generate configuration file (config.toml) -CONFIG_FILE="$CONFIG_DIR/config.toml" -log_info "Generating Hermes configuration at $CONFIG_FILE..." - -cat < "$CONFIG_FILE" -[global] -log_level = "trace" - -[mode] - [mode.clients] - enabled = true - refresh = true - misbehaviour = true - [mode.connections] - enabled = true - [mode.channels] - enabled = true - [mode.packets] - enabled = true - -[[chains]] -id = "$GAIA_CHAIN_ID" -rpc_addr = "$GAIA_RPC" -grpc_addr = "$GAIA_GRPC" -event_source = { mode = "pull", interval = "1s", max_retries = 4 } -store_prefix = "ibc" -account_prefix = "cosmos" -key_name = "$RELAYER_WALLET" -gas_price = { price = 3.5, denom = "stake" } -gas_multiplier = 1.4 -rpc_timeout = "10s" -trusting_period = "503h" -clock_drift = "10s" -key_store_folder = "$CONFIG_DIR/$GAIA_CHAIN_ID-keys" - -[[chains]] -id = "$WORDLED_CHAIN_ID" -rpc_addr = "$WORDLED_RPC" -grpc_addr = "$WORDLED_GRPC" -store_prefix = "ibc" -event_source = { mode = "pull", interval = "1s", max_retries = 4 } -account_prefix = "gm" -key_name = "$RELAYER_WALLET" -gas_price = { price = 0.025, denom = "stake" } -gas_multiplier = 1.4 -rpc_timeout = "10s" -trusting_period = "503h" -clock_drift = "10s" -key_store_folder = "$CONFIG_DIR/$WORDLED_CHAIN_ID-keys" -EOF - -log_success "Configuration file generated" - -# Import keys to relayer (Hermes) using mnemonic -TMP_MNEMONIC=$(mktemp) -echo "$RELAYER_MNEMONIC" > "$TMP_MNEMONIC" - -log_info "Importing key for $GAIA_CHAIN_ID..." -"$HERMES_BIN" --config "$CONFIG_FILE" keys add --chain "$GAIA_CHAIN_ID" --mnemonic-file "$TMP_MNEMONIC" -log_success "Key imported for $GAIA_CHAIN_ID" - -log_info "Importing key for $WORDLED_CHAIN_ID..." -"$HERMES_BIN" --config "$CONFIG_FILE" keys add --chain "$WORDLED_CHAIN_ID" --mnemonic-file "$TMP_MNEMONIC" -log_success "Key imported for $WORDLED_CHAIN_ID" - -rm "$TMP_MNEMONIC" - -# Show configured addresses (optional) -log_info "Showing configured addresses:" -"$HERMES_BIN" --config "$CONFIG_FILE" keys list --chain "$GAIA_CHAIN_ID" -"$HERMES_BIN" --config "$CONFIG_FILE" keys list --chain "$WORDLED_CHAIN_ID" - -# Create IBC channel between chains -log_info "Creating IBC channel between $GAIA_CHAIN_ID and $WORDLED_CHAIN_ID..." - "$HERMES_BIN" --config "$CONFIG_FILE" create channel --a-chain "$GAIA_CHAIN_ID" --a-port transfer \ - --b-chain "$WORDLED_CHAIN_ID" --b-port transfer \ - --new-client-connection --yes -log_success "IBC channel created" - -# Start Hermes -log_info "Starting Hermes..." -"$HERMES_BIN" --config "$CONFIG_FILE" start \ No newline at end of file diff --git a/hack/ics20-token-transfer.sh b/hack/ics20-token-transfer.sh deleted file mode 100755 index c638510e..00000000 --- a/hack/ics20-token-transfer.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/bin/bash -set -e - -# Configuration variables (matching ibc-connection-hermes.sh) -GAIA_CHAIN_ID="localnet-1" -ROLLKIT_CHAIN_ID="rollkitnet-1" - -GAIA_RPC="http://localhost:26654" -ROLLKIT_RPC="http://localhost:26657" - -GAIA_DENOM="stake" -ROLLKIT_DENOM="stake" - -GAIA_KEY_NAME="bob" -ROLLKIT_KEY_NAME="carl" - -# IBC channel information -CHANNEL_ID="" -TRANSFER_PORT="transfer" - -# Logging functions -log_info() { - echo "[INFO] $1" -} - -log_success() { - echo "[SUCCESS] $1" -} - -log_error() { - echo "[ERROR] $1" >&2 -} - -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -GAIAD_BIN="${GAIAD_BIN:-$CURRENT_DIR/downloads/gaiad}" -GMD_BIN="gmd" -ROLLKIT_HOME="${1:-"${CURRENT_DIR}/testnet/gm"}" - -# Verify binaries are installed -if [ ! -f "$GAIAD_BIN" ]; then - log_error "Gaiad not found at $GAIAD_BIN" - exit 1 -fi -log_success "Gaiad installed" - -if ! command -v $GMD_BIN &> /dev/null; then - log_error "gmd binary not found in PATH" - exit 1 -fi -log_success "gmd installed" - -# Get validator addresses -log_info "Getting user addresses..." -USER_ADDRESS_GAIA=$($GAIAD_BIN keys show $GAIA_KEY_NAME -a --keyring-backend test --home "$CURRENT_DIR/testnet") -USER_ADDRESS_ROLLKIT=$($GMD_BIN keys show $ROLLKIT_KEY_NAME -a --keyring-backend test --home "$ROLLKIT_HOME") - -log_info "Gaia user address: $USER_ADDRESS_GAIA" -log_info "Rollkit user address: $USER_ADDRESS_ROLLKIT" - -# Check initial balances -log_info "Checking initial balances..." -log_info "Gaia $GAIA_KEY_NAME balance:" -$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" - -log_info "Rollkit $ROLLKIT_KEY_NAME balance:" -$GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" - -# Get channel ID -log_info "Getting IBC channel ID..." -CHANNEL_INFO=$($GAIAD_BIN q ibc channel channels --node $GAIA_RPC --home "$CURRENT_DIR/testnet" -o json) -CHANNEL_ID=$(echo $CHANNEL_INFO | jq -r '.channels[0].channel_id') - -if [ -z "$CHANNEL_ID" ] || [ "$CHANNEL_ID" == "null" ]; then - log_error "Failed to get channel ID. Make sure IBC connection is established." - exit 1 -fi - -log_info "Using IBC channel: $CHANNEL_ID" - -# Transfer Rollkit tokens to Gaia -ROLLKIT_TRANSFER_AMOUNT="101" - -log_info "Transferring ${ROLLKIT_TRANSFER_AMOUNT}${ROLLKIT_DENOM} from Rollkit to Gaia..." -TX_HASH=$($GMD_BIN tx ibc-transfer transfer $TRANSFER_PORT $CHANNEL_ID $USER_ADDRESS_GAIA ${ROLLKIT_TRANSFER_AMOUNT}${ROLLKIT_DENOM} \ - --from ${ROLLKIT_KEY_NAME} \ - --chain-id $ROLLKIT_CHAIN_ID \ - --node $ROLLKIT_RPC \ - --keyring-backend test \ - --home "$ROLLKIT_HOME" \ - --gas auto \ - --gas-adjustment 1.4 \ - --gas-prices 1stake \ - --yes -o json | jq -r '.txhash') - -log_info "Querying gmd tx... $TX_HASH" -for i in {1..10}; do - if ! tx_result=$($GMD_BIN q tx --type=hash "$TX_HASH" -o json --home "$ROLLKIT_HOME" 2>/dev/null); then - sleep 1 - continue - fi -done -if [ "$(echo "$tx_result" | jq -r '.code')" != "0" ]; then - log_error "Transaction failed : $tx_result" - exit 1 -fi - - -# Check balances after Rollkit to Gaia transfer -log_info "Checking balances after Rollkit to Gaia transfer..." -log_info "Gaia user balance (should show IBC tokens):" -$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" - -log_info "Rollkit user balance:" -$GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" - -# Transfer tokens from Gaia to Rollkit -TRANSFER_AMOUNT="102" -log_info "Transferring $TRANSFER_AMOUNT$GAIA_DENOM from Gaia to Rollkit..." -TX_HASH=$($GAIAD_BIN tx ibc-transfer transfer $TRANSFER_PORT $CHANNEL_ID $USER_ADDRESS_ROLLKIT ${TRANSFER_AMOUNT}${GAIA_DENOM} \ - --from ${GAIA_KEY_NAME} \ - --chain-id $GAIA_CHAIN_ID \ - --node $GAIA_RPC \ - --keyring-backend test \ - --home "$CURRENT_DIR/testnet" \ - --gas auto \ - --gas-adjustment 1.4 \ - --gas-prices 1stake \ - --yes -o json | jq -r '.txhash') - -log_info "Querying gaia tx... $TX_HASH" -for i in {1..20}; do - if ! tx_result=$($GAIAD_BIN q tx --type=hash "$TX_HASH" -o json --node $GAIA_RPC 2>/dev/null); then - echo "$tx_result" - sleep 1 - continue - fi -done -if [ "$(echo "$tx_result" | jq -r '.code')" != "0" ]; then - log_error "Transaction failed : $tx_result" - exit 1 -fi - -# Check balances after transfer to Rollkit -log_info "Checking balances after transfer to Rollkit..." -log_info "Gaia user balance:" -$GAIAD_BIN q bank balances $USER_ADDRESS_GAIA --node $GAIA_RPC --home "$CURRENT_DIR/testnet" - -log_info "Rollkit user balance (should show IBC tokens):" -ibc_tokens_visible=false - -for i in {1..${20}}; do - $GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" - if $GMD_BIN q bank balances $USER_ADDRESS_ROLLKIT --node $ROLLKIT_RPC --home "$ROLLKIT_HOME" | grep -q "ibc"; then - log_success "IBC tokens are now visible in Rollkit balance" - ibc_tokens_visible=true - break - fi - sleep 1 -done - -if [ "$ibc_tokens_visible" = false ]; then - log_error "IBC tokens did not become visible within time frame" - exit 1 -fi - -log_success "ICS20 token transfer test completed!" diff --git a/hack/init-gaia.sh b/hack/init-gaia.sh deleted file mode 100755 index e6fcc5ae..00000000 --- a/hack/init-gaia.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash - -# Function for formatted logging -log() { - local color=$1 - local emoji=$2 - local message=$3 - shift 3 - printf "\e[${color}m${emoji} [$(date '+%T')] ${message}\e[0m\n" "$@" -} - -# Hardcoded mnemonic for validator account (igual que en Wordled) -VALIDATOR_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" -BOB_MNEMONIC="rack argue disorder flame appear broom smile effort one rubber buffalo suspect tool devote zebra between inhale trigger brief possible parrot nation expose place" -RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" - -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -GAIA_HOME=${1:-"${CURRENT_DIR}/testnet/gaia"} -GAIAD_BIN=${2:-"${CURRENT_DIR}/downloads/gaiad"} - -# Kill existing Gaia processes -log "31" "💀" "Checking for existing Gaia processes..." -GAIA_PID=$(pgrep gaiad) -if [ -n "$GAIA_PID" ]; then - log "31" "🔪" "Killing existing Gaia process (PID: $GAIA_PID)..." - kill -9 "$GAIA_PID" -else - log "32" "👌" "No existing Gaia process found." -fi - -# Clean previous configurations -log "32" "🔥" "Cleaning previous Gaia configurations..." -rm -rf "$GAIA_HOME" - -# 1. Initialize Gaia chain -log "36" "🆕" "Initializing Gaia chain..." -"$GAIAD_BIN" init my-node --chain-id localnet-1 --home "$GAIA_HOME" - -# 2. Create/Recover validator account usando la mnemónica fija -log "35" "👤" "Generating validator account from mnemonic..." -echo "$VALIDATOR_MNEMONIC" | "$GAIAD_BIN" keys add validator \ - --keyring-backend test \ - --home "$GAIA_HOME" \ - --recover > /dev/null 2>&1 -echo "$BOB_MNEMONIC" | "$GAIAD_BIN" keys add bob \ - --keyring-backend test \ - --home "$GAIA_HOME" \ - --recover > /dev/null 2>&1 -echo "$RELAYER_MNEMONIC" | "$GAIAD_BIN" keys add relayer \ - --keyring-backend test \ - --home "$GAIA_HOME" \ - --recover > /dev/null 2>&1 - -# 3. Add account to genesis -log "34" "📝" "Adding account to genesis..." -"$GAIAD_BIN" genesis add-genesis-account validator 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" -"$GAIAD_BIN" genesis add-genesis-account bob 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" -"$GAIAD_BIN" genesis add-genesis-account relayer 10000000000000000stake --keyring-backend test --home "$GAIA_HOME" - -# 4. Generate gentx -log "33" "📜" "Creating validator transaction..." -"$GAIAD_BIN" genesis gentx validator 1000000000stake \ - --chain-id localnet-1 \ - --keyring-backend test \ - --home "$GAIA_HOME" - -# 5. Collect gentxs -log "32" "📦" "Collecting genesis transactions..." -"$GAIAD_BIN" genesis collect-gentxs --home "$GAIA_HOME" - -# 6. Configure minimum gas prices -log "36" "⛽" "Setting minimum gas prices..." -sed -i.bak -E 's#minimum-gas-prices = ""#minimum-gas-prices = "0stake"#g' "$GAIA_HOME/config/app.toml" - -# 7. Modify consensus timeouts -log "35" "⏱️" "Adjusting consensus timeouts..." -sed -i.bak -E 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$GAIA_HOME/config/config.toml" -sed -i.bak -E 's/timeout_propose = "3s"/timeout_propose = "1s"/g' "$GAIA_HOME/config/config.toml" - -# 8. Start Gaia chain -log "34" "🚀" "Starting Gaia node..." -"$GAIAD_BIN" start --home "$GAIA_HOME" --minimum-gas-prices "0stake" --rpc.laddr tcp://0.0.0.0:26654 --rpc.pprof_laddr localhost:6061 --p2p.laddr tcp://0.0.0.0:26653 --grpc.address 0.0.0.0:9091 | tee "$GAIA_HOME/gaia.log" & -GAIA_PID=$! - -# Wait for initialization -log "33" "⏳" "Waiting for Gaia initialization (port 26654)..." -while ! nc -z localhost 26654; do - sleep 1 -done -log "32" "✅" "Gaia chain running successfully!" - -# Show recent logs -log "36" "📄" "Last lines of Gaia log:" -tail -n 5 "$GAIA_HOME/gaia.log" - -# Keep script alive -log "35" "👀" "Monitoring Gaia chain activity..." -wait $GAIA_PID \ No newline at end of file diff --git a/hack/run_gmd.sh b/hack/run_gmd.sh deleted file mode 100755 index 877b795e..00000000 --- a/hack/run_gmd.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/bash -set -x - -# Function for cleanup on script interruption -cleanup() { - log "31" "🛑" "Cleaning up processes..." - if [ -n "$DA_PID" ]; then - kill -9 "$DA_PID" 2>/dev/null || true - fi - if [ -n "$ROLLKIT_PID" ]; then - kill -9 "$ROLLKIT_PID" 2>/dev/null || true - fi - exit 0 -} - -trap cleanup INT TERM - -# Function for formatted logging -log() { - local color=$1 - local emoji=$2 - local message=$3 - shift 3 - printf "\e[${color}m${emoji} [$(date '+%T')] ${message}\e[0m\n" "$@" -} - - -# Define paths -CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ROLLKIT_BIN="gmd" -ROLLKIT_HOME="${1:-"${CURRENT_DIR}/testnet/gm"}" -LOCAL_DA_PATH="${2:-"../../rollkit/build/local-da"}" -CHAIN_ID="${3:-"rollkitnet-1"}" - -# Clean previous configurations -log "32" "🔥" "Cleaning previous rollkit configurations..." -rm -rf "$ROLLKIT_HOME" - -"$ROLLKIT_BIN" init my-rollkit-node --chain-id "$CHAIN_ID" --home "$ROLLKIT_HOME" - -# Hardcoded mnemonic for validator account (igual que en Wordled) -VALIDATOR_MNEMONIC="abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art" -#ATTESTER_MNEMONIC="tennis sponsor brick almost coyote soup rib wisdom warm bean onion tray devote pretty crime grid rough boil wear december travel inch work note" -RELAYER_MNEMONIC="reject camp lock magic dragon degree loop ignore quantum verify invest primary object afraid crane unveil parrot jelly rubber risk mirror globe torch category" -USER_MNEMONIC="sport head real antique sad expect ignore feature claim manual heavy mouse coil rebuild police flag robust picture milk symptom suffer chuckle worry virus" - - -echo "$VALIDATOR_MNEMONIC" | "$ROLLKIT_BIN" keys add validator \ - --keyring-backend test \ - --home "$ROLLKIT_HOME" \ - --recover > /dev/null 2>&1 - -#echo "$ATTESTER_MNEMONIC" | "$ROLLKIT_BIN" keys add attester \ -# --keyring-backend test \ -# --home "$ROLLKIT_HOME" \ -# --recover > /dev/null 2>&1 - -echo "$RELAYER_MNEMONIC" | "$ROLLKIT_BIN" keys add relayer \ - --keyring-backend test \ - --home "$ROLLKIT_HOME" \ - --recover > /dev/null 2>&1 - -echo "$USER_MNEMONIC" | "$ROLLKIT_BIN" keys add carl \ - --keyring-backend test \ - --home "$ROLLKIT_HOME" \ - --recover > /dev/null 2>&1 - -"$ROLLKIT_BIN" genesis add-genesis-account validator "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" -#"$ROLLKIT_BIN" genesis add-genesis-account attester "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" -"$ROLLKIT_BIN" genesis add-genesis-account relayer "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" -"$ROLLKIT_BIN" genesis add-genesis-account carl "10000000000000000stake" --keyring-backend test --home "$ROLLKIT_HOME" - - -log "33" "📜" "Creating validator transaction..." -"$ROLLKIT_BIN" genesis gentx validator 1000000000stake \ - --chain-id "$CHAIN_ID" \ - --keyring-backend test \ - --home "$ROLLKIT_HOME" - -# 5. Collect gentxs -log "32" "📦" "Collecting genesis transactions..." -"$ROLLKIT_BIN" genesis collect-gentxs --home "$ROLLKIT_HOME" - -# Set validator in consensus block -log "32" "🔄" "Setting validator in consensus block..." -# Extract validator address and pubkey from validator key file, then modify genesis file to set the validator -jq -r '.address as $addr | .pub_key | { - address: $addr, - pub_key: { type: "tendermint/PubKeyEd25519", value: .value }, - power: "1000", - name: "Rollkit Sequencer" -}' "$ROLLKIT_HOME/config/priv_validator_key.json" | \ -jq --slurpfile genesis "$ROLLKIT_HOME/config/genesis.json" \ - '. as $validator | ($genesis[0] | .consensus.validators += [$validator])' > \ - "$ROLLKIT_HOME/config/tmp_genesis.json" && \ -mv "$ROLLKIT_HOME/config/tmp_genesis.json" "$ROLLKIT_HOME/config/genesis.json" - -# 6. Configure minimum gas prices -log "33" "⛽" "Setting minimum gas prices..." -sed -i.bak -E 's#minimum-gas-prices = ""#minimum-gas-prices = "0stake"#g' "$ROLLKIT_HOME/config/app.toml" - -# 7. Modify consensus timeouts -log "34" "⏱️" "Adjusting consensus timeouts..." -sed -i.bak -E 's/timeout_commit = "5s"/timeout_commit = "1s"/g' "$ROLLKIT_HOME/config/config.toml" -sed -i.bak -E 's/timeout_propose = "3s"/timeout_propose = "1s"/g' "$ROLLKIT_HOME/config/config.toml" - -# enable api -sed -i.bak 's#enable = false#enable = true#g' "$ROLLKIT_HOME/config/app.toml" - - - -# Build and start local DA -echo "Building and starting local DA..." -# --- Kill previous local-da process if running --- -echo "Checking for existing local-da process on port 7980..." -# Find PID using lsof on the DA port (adjust if your DA uses a different port) -DA_PORT=7980 -EXISTING_PID=$(lsof -ti tcp:${DA_PORT}) - -if [ -n "$EXISTING_PID" ]; then - echo "Found existing processes on port $DA_PORT with PIDs: $EXISTING_PID. Killing..." - # Kill the process(es) - kill -9 $EXISTING_PID - # Allow a moment for the OS to release the port - sleep 2 -else - echo "No existing process found on port $DA_PORT." -fi -# --- End Kill previous local-da process --- - - -if [ ! -f "$LOCAL_DA_PATH" ]; then - echo "Error: local-da binary not found at $LOCAL_DA_PATH" - exit 1 -else - echo "Starting local DA in background..." - $LOCAL_DA_PATH & - DA_PID=$! - echo "Local DA started with PID $DA_PID" - sleep 2 # Give DA a moment to start -fi - -log "35" "🚀" "Starting ROLLKIT node..." -"$ROLLKIT_BIN" start --home "$ROLLKIT_HOME" --rollkit.node.aggregator --minimum-gas-prices "0stake" --rollkit.node.lazy_block_interval=150ms --rollkit.node.block_time=100ms --rollkit.da.block_time=500ms --pruning=nothing --rollkit.network.soft-confirmation & -ROLLKIT_PID=$! -log "36" "✅" "ROLLKIT chain running successfully!" -wait $ROLLKIT_PID From 2ebf6b16667b2dd137040c5541acb503f7eda639 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 24 Jun 2025 13:36:17 +0200 Subject: [PATCH 16/21] Explicit error handling --- modules/network/genesis.go | 5 ++- modules/network/keeper/abci.go | 16 +++++--- modules/network/keeper/grpc_query.go | 32 ++++++++++++---- modules/network/keeper/keeper.go | 57 +++++++++++++--------------- modules/network/keeper/msg_server.go | 26 ++++++++----- 5 files changed, 84 insertions(+), 52 deletions(-) diff --git a/modules/network/genesis.go b/modules/network/genesis.go index 55be35ea..668aa1aa 100644 --- a/modules/network/genesis.go +++ b/modules/network/genesis.go @@ -55,7 +55,10 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { var validatorIndices []types.ValidatorIndex // Iterate through all validator indices if err := k.ValidatorIndex.Walk(ctx, nil, func(addr string, index uint16) (bool, error) { - power := k.GetValidatorPower(ctx, index) + power, err := k.GetValidatorPower(ctx, index) + if err != nil { + return false, fmt.Errorf("get validator power: %w", err) + } validatorIndices = append(validatorIndices, types.ValidatorIndex{ Address: addr, Index: uint32(index), diff --git a/modules/network/keeper/abci.go b/modules/network/keeper/abci.go index 1381b31f..8fbd645a 100644 --- a/modules/network/keeper/abci.go +++ b/modules/network/keeper/abci.go @@ -51,12 +51,15 @@ func (k Keeper) EndBlocker(ctx sdk.Context) error { // processCheckpoint handles checkpoint processing func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) error { - bitmapBytes := k.GetAttestationBitmap(ctx, height) + bitmapBytes, _ := k.GetAttestationBitmap(ctx, height) if bitmapBytes == nil { return nil } - votedPower := k.CalculateVotedPower(ctx, bitmapBytes) + votedPower, err := k.CalculateVotedPower(ctx, bitmapBytes) + if err != nil { + return err + } totalPower, err := k.GetTotalPower(ctx) if err != nil { return err @@ -66,7 +69,10 @@ func (k Keeper) processCheckpoint(ctx sdk.Context, height int64) error { commitHash := sha256.Sum256([]byte("placeholder")) - softConfirmed := k.CheckQuorum(ctx, votedPower, totalPower) + softConfirmed, err := k.CheckQuorum(ctx, votedPower, totalPower) + if err != nil { + return err + } attestationInfoToStore := types.AttestationBitmap{ Height: height, @@ -125,14 +131,14 @@ func (k Keeper) processEpochEnd(ctx sdk.Context, epoch uint64) error { } if k.IsCheckpointHeight(ctx, h) { checkpointsInEpoch++ - if k.IsSoftConfirmed(ctx, h) { + if q, err := k.IsSoftConfirmed(ctx, h); q && err == nil { softConfirmedCheckpoints++ } } } if checkpointsInEpoch > 0 && softConfirmedCheckpoints == 0 { - // todo (Alex): show we really fail? + // todo (Alex): should we really fail? //return fmt.Errorf("no checkpoints achieved quorum in epoch: %d", epoch) k.Logger(ctx).Info("No checkpoints achieved quorum in epoch", "epoch", epoch) } diff --git a/modules/network/keeper/grpc_query.go b/modules/network/keeper/grpc_query.go index a49b1fb1..aade9a21 100644 --- a/modules/network/keeper/grpc_query.go +++ b/modules/network/keeper/grpc_query.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" "google.golang.org/grpc/codes" @@ -41,13 +42,16 @@ func (q *queryServer) AttestationBitmap(c context.Context, req *types.QueryAttes ctx := sdk.UnwrapSDKContext(c) - bitmapBytes := q.keeper.GetAttestationBitmap(ctx, req.Height) + bitmapBytes, _ := q.keeper.GetAttestationBitmap(ctx, req.Height) if bitmapBytes == nil { return nil, status.Error(codes.NotFound, "attestation bitmap not found for height") } // Reconstruct attestation info using keeper methods - votedPower := q.keeper.CalculateVotedPower(ctx, bitmapBytes) + votedPower, err := q.keeper.CalculateVotedPower(ctx, bitmapBytes) + if err != nil { + return nil, err + } totalPower, err := q.keeper.GetTotalPower(ctx) if err != nil { return nil, err @@ -55,7 +59,10 @@ func (q *queryServer) AttestationBitmap(c context.Context, req *types.QueryAttes // Assuming IsSoftConfirmed is a method on the Keeper // If not, you might need to add it or compute it here using keeper.CheckQuorum - softConfirmed := q.keeper.IsSoftConfirmed(ctx, req.Height) + softConfirmed, err := q.keeper.IsSoftConfirmed(ctx, req.Height) + if err != nil { + return nil, err + } return &types.QueryAttestationBitmapResponse{ Bitmap: &types.AttestationBitmap{ @@ -130,7 +137,10 @@ func (q *queryServer) ValidatorIndex(c context.Context, req *types.QueryValidato return nil, status.Error(codes.NotFound, "validator index not found") } - power := q.keeper.GetValidatorPower(ctx, index) + power, err := q.keeper.GetValidatorPower(ctx, index) + if err != nil { + return nil, fmt.Errorf("get validator power: %w", err) + } return &types.QueryValidatorIndexResponse{ Index: &types.ValidatorIndex{ @@ -148,8 +158,14 @@ func (q *queryServer) SoftConfirmationStatus(c context.Context, req *types.Query } ctx := sdk.UnwrapSDKContext(c) - isSoftConfirmed := q.keeper.IsSoftConfirmed(ctx, req.Height) - bitmap := q.keeper.GetAttestationBitmap(ctx, req.Height) + isSoftConfirmed, err := q.keeper.IsSoftConfirmed(ctx, req.Height) + if err != nil { + return nil, err + } + bitmap, err := q.keeper.GetAttestationBitmap(ctx, req.Height) + if err != nil { + return nil, err + } totalPower, err := q.keeper.GetTotalPower(ctx) if err != nil { return nil, err @@ -157,7 +173,9 @@ func (q *queryServer) SoftConfirmationStatus(c context.Context, req *types.Query var votedPower uint64 if bitmap != nil { - votedPower = q.keeper.CalculateVotedPower(ctx, bitmap) + if votedPower, err = q.keeper.CalculateVotedPower(ctx, bitmap); err != nil { + return nil, err + } } return &types.QuerySoftConfirmationStatusResponse{ diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index e967146a..a52fcf9d 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -112,13 +112,9 @@ func (k Keeper) GetValidatorIndex(ctx sdk.Context, addr string) (uint16, bool) { } // GetValidatorPower retrieves the validator power by index -func (k Keeper) GetValidatorPower(ctx sdk.Context, index uint16) uint64 { +func (k Keeper) GetValidatorPower(ctx sdk.Context, index uint16) (uint64, error) { power, err := k.ValidatorPower.Get(ctx, index) - if err != nil { - // Consider logging the error or returning an error if 0 is a valid power value. - return 0 - } - return power + return power, err } // SetAttestationBitmap stores the attestation bitmap for a height @@ -127,13 +123,9 @@ func (k Keeper) SetAttestationBitmap(ctx sdk.Context, height int64, bitmap []byt } // GetAttestationBitmap retrieves the attestation bitmap for a height -func (k Keeper) GetAttestationBitmap(ctx sdk.Context, height int64) []byte { +func (k Keeper) GetAttestationBitmap(ctx sdk.Context, height int64) ([]byte, error) { bitmap, err := k.AttestationBitmap.Get(ctx, height) - if err != nil { - // Consider logging err or returning (nil, error) - return nil - } - return bitmap + return bitmap, err } // SetEpochBitmap stores the epoch participation bitmap @@ -152,13 +144,9 @@ func (k Keeper) GetEpochBitmap(ctx sdk.Context, epoch uint64) []byte { } // IsInAttesterSet checks if a validator is in the attester set -func (k Keeper) IsInAttesterSet(ctx sdk.Context, addr string) bool { +func (k Keeper) IsInAttesterSet(ctx sdk.Context, addr string) (bool, error) { has, err := k.AttesterSet.Has(ctx, addr) - if err != nil { - k.Logger(ctx).Error("failed to check attester set", "address", addr, "error", err) - return false - } - return has + return has, err } // SetAttesterSetMember adds a validator to the attester set @@ -223,15 +211,19 @@ func (k Keeper) IsCheckpointHeight(ctx sdk.Context, height int64) bool { } // CalculateVotedPower calculates the total voted power from a bitmap -func (k Keeper) CalculateVotedPower(ctx sdk.Context, bitmap []byte) uint64 { +func (k Keeper) CalculateVotedPower(ctx sdk.Context, bitmap []byte) (uint64, error) { var votedPower uint64 for i := 0; i < len(bitmap)*8; i++ { if k.bitmapHelper.IsSet(bitmap, i) { - power := k.GetValidatorPower(ctx, uint16(i)) + power, err := k.GetValidatorPower(ctx, uint16(i)) + if err != nil { + return 0, fmt.Errorf("get validator power: %w", err) + } + votedPower += power } } - return votedPower + return votedPower, nil } // GetTotalPower returns the total staking power @@ -244,29 +236,34 @@ func (k Keeper) GetTotalPower(ctx sdk.Context) (uint64, error) { } // CheckQuorum checks if the voted power meets quorum -func (k Keeper) CheckQuorum(ctx sdk.Context, votedPower, totalPower uint64) bool { +func (k Keeper) CheckQuorum(ctx sdk.Context, votedPower, totalPower uint64) (bool, error) { params := k.GetParams(ctx) quorumFrac, err := math.LegacyNewDecFromStr(params.QuorumFraction) if err != nil { - return false + return false, fmt.Errorf("invalid quorum fraction: %w", err) } requiredPower := math.LegacyNewDec(int64(totalPower)).Mul(quorumFrac).TruncateInt().Uint64() - return votedPower >= requiredPower + return votedPower >= requiredPower, nil } // IsSoftConfirmed checks if a block at a given height is soft-confirmed // based on the attestation bitmap and quorum rules. -func (k Keeper) IsSoftConfirmed(ctx sdk.Context, height int64) bool { - bitmap := k.GetAttestationBitmap(ctx, height) +func (k Keeper) IsSoftConfirmed(ctx sdk.Context, height int64) (bool, error) { + bitmap, err := k.GetAttestationBitmap(ctx, height) + if err != nil { + return false, err + } if bitmap == nil { - return false // No bitmap, so cannot be soft-confirmed + return false, nil // No bitmap, so cannot be soft-confirmed + } + votedPower, err := k.CalculateVotedPower(ctx, bitmap) + if err != nil { + return false, err } - - votedPower := k.CalculateVotedPower(ctx, bitmap) totalPower, err := k.GetTotalPower(ctx) // Assuming this gets the relevant total power for the height if err != nil { - return false + return false, err } return k.CheckQuorum(ctx, votedPower, totalPower) diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index 4eb35f0a..8547230e 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -28,25 +28,25 @@ var _ types.MsgServer = msgServer{} func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.MsgAttestResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - var index uint16 - if !k.IsCheckpointHeight(ctx, msg.Height) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "height %d is not a checkpoint", msg.Height) } - - if !k.IsInAttesterSet(ctx, msg.Validator) { + has, err := k.IsInAttesterSet(ctx, msg.Validator) + if err != nil { + return nil, errors.Wrapf(err, "in attester set") + } + if !has { return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "validator %s not in attester set", msg.Validator) } - var found bool - index, found = k.GetValidatorIndex(ctx, msg.Validator) + index, found := k.GetValidatorIndex(ctx, msg.Validator) if !found { return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator index not found for %s", msg.Validator) } // todo (Alex): we need to set a limit to not have validators attest old blocks. Also make sure that this relates with // the retention period for pruning - bitmap := k.GetAttestationBitmap(ctx, msg.Height) + bitmap, _ := k.GetAttestationBitmap(ctx, msg.Height) if bitmap == nil { validators, err := k.stakingKeeper.GetLastValidators(ctx) if err != nil { @@ -127,7 +127,11 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte if !validator.IsBonded() { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator must be bonded to join attester set") } - if k.IsInAttesterSet(ctx, msg.Validator) { + has, err := k.IsInAttesterSet(ctx, msg.Validator) + if err != nil { + return nil, errors.Wrapf(err, "in attester set") + } + if has { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator already in attester set") } @@ -150,7 +154,11 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte func (k msgServer) LeaveAttesterSet(goCtx context.Context, msg *types.MsgLeaveAttesterSet) (*types.MsgLeaveAttesterSetResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if !k.IsInAttesterSet(ctx, msg.Validator) { + has, err := k.IsInAttesterSet(ctx, msg.Validator) + if err != nil { + return nil, errors.Wrapf(err, "in attester set") + } + if !has { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator not in attester set") } From 541c00e2a6d52fd48a3c5a094db27bdc7f769ca5 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 24 Jun 2025 13:40:57 +0200 Subject: [PATCH 17/21] Ensure type safety --- modules/network/types/genesis.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/network/types/genesis.go b/modules/network/types/genesis.go index fdba803e..c722e021 100644 --- a/modules/network/types/genesis.go +++ b/modules/network/types/genesis.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "math" ) // DefaultGenesisState returns the default genesis state @@ -19,6 +20,9 @@ func (gs GenesisState) Validate() error { return fmt.Errorf("invalid params: %w", err) } + if len(gs.ValidatorIndices) > math.MaxUint16 { + return fmt.Errorf("too many validator indices") + } // Check for duplicate validator indices indexMap := make(map[string]bool) usedIndices := make(map[uint32]bool) From 7b7c564e880f06ecae251c0e66d08ba3a8e28992 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 24 Jun 2025 13:49:20 +0200 Subject: [PATCH 18/21] Remove ai generated audit file --- audit.md | 75 -------------------------------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 audit.md diff --git a/audit.md b/audit.md deleted file mode 100644 index e0b08362..00000000 --- a/audit.md +++ /dev/null @@ -1,75 +0,0 @@ -# Network Module Audit - -## Overview -This document presents an audit of the network module in the go-execution-abci repository. The network module appears to be responsible for managing validator attestations, checkpoints, and consensus-related functionality. - -## TODOs and Incomplete Features - -1. **Missing IBC Packet Checking** - - In `keeper/abci.go`, line 21-22: `// TODO: Check for outbound IBC packets` - - The BeginBlocker has a placeholder for checking outbound IBC packets when in IBC_ONLY sign mode, but this functionality is not implemented. - -2. **Incomplete Validator Ejection Logic** - - In `keeper/abci.go`, line 145-146: `// TODO: Implement validator ejection logic` - - The `ejectLowParticipants` function is a stub that only logs a message but doesn't actually implement the ejection logic. - -3. **Missing Vote Signature Verification** - - In `keeper/msg_server.go`, line 59: `// TODO: Verify the vote signature here once we implement vote parsing` - - The `Attest` message handler doesn't verify the signature of the vote, which is a critical security feature. - -## Security Issues - -1. **Lack of Signature Verification** - - Attestations are accepted without verifying the signature of the vote, which could allow forged attestations. - - This is a critical security vulnerability that needs to be addressed before production use. - -2. ~~**Potential Panic in Epoch Processing**~~ - - In `keeper/abci.go`, line 129: `panic("Network module: No checkpoints achieved quorum in epoch")` - - The module panics if no checkpoints achieve quorum in an epoch, which could be triggered by network issues or validator downtime, potentially causing chain halts. - -3. **Limited Genesis State Validation** - - The `InitGenesis` function in `genesis.go` doesn't perform comprehensive validation of the genesis state beyond what's in the `Params.Validate()` method. - - Invalid genesis state could potentially be provided, leading to unexpected behavior. - -4. **Bitmap Index Bounds Checking** - - While the `BitmapHelper` in `keeper/bitmap.go` does include bounds checking for index operations, there's no validation that the bitmap size matches the expected validator set size when loading from storage. - -5. **No Rate Limiting for Attestations** - - There doesn't appear to be any rate limiting for attestation submissions, which could potentially be abused in a DoS attack. - -## Missing Features - -1. **Comprehensive Testing** - - The codebase lacks comprehensive test coverage, particularly for critical functions like checkpoint processing and quorum calculation. - -2. **Metrics and Monitoring** - - There are no metrics exposed for monitoring the health and performance of the network module. - -3. **Recovery Mechanisms** - - The module lacks graceful recovery mechanisms for handling edge cases like network partitions or mass validator downtime. - -4. **Documentation** - - Inline documentation is sparse, making it difficult to understand the intended behavior and security properties of the module. - -## Recommendations - -1. **Implement Missing Features** - - Complete all TODO items, particularly the signature verification and validator ejection logic. - - Add comprehensive testing for all critical paths. - -2. **Enhance Security** - - Implement proper signature verification for attestations. - - Replace the panic with a more graceful handling of the no-quorum scenario. - - Add rate limiting for message submission. - -3. **Improve Robustness** - - Add more comprehensive validation of inputs and state transitions. - - Implement recovery mechanisms for handling network issues. - -4. **Add Observability** - - Implement metrics for monitoring the health of the network module. - - Add more detailed logging for debugging purposes. - -5. **Enhance Documentation** - - Add comprehensive inline documentation explaining the purpose and security properties of each function. - - Create external documentation describing the overall design and security model of the module. \ No newline at end of file From de5155f8476a7b72cb39ffa5dd405b7df786ab66 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Tue, 24 Jun 2025 17:46:21 +0200 Subject: [PATCH 19/21] Start better attestation --- modules/network/depinject.go | 2 + modules/network/keeper/keeper.go | 22 ++- modules/network/keeper/msg_server.go | 162 +++++++++++----- modules/network/keeper/msg_server_test.go | 217 +++++++++++++++++++++- modules/network/types/expected_keepers.go | 6 + 5 files changed, 351 insertions(+), 58 deletions(-) diff --git a/modules/network/depinject.go b/modules/network/depinject.go index 01b57e6e..b0c99cd4 100644 --- a/modules/network/depinject.go +++ b/modules/network/depinject.go @@ -35,6 +35,7 @@ type ModuleInputs struct { StakingKeeper types.StakingKeeper AccountKeeper types.AccountKeeper BankKeeper types.BankKeeper + BlockSource types.BlockSource } type ModuleOutputs struct { @@ -57,6 +58,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs { in.StakingKeeper, in.AccountKeeper, in.BankKeeper, + in.BlockSource, authority.String(), ) m := NewAppModule( diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index a52fcf9d..692eed09 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -1,12 +1,11 @@ package keeper import ( - "fmt" - "cosmossdk.io/collections" "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/math" + "fmt" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -21,11 +20,15 @@ type Keeper struct { bankKeeper types.BankKeeper authority string bitmapHelper *BitmapHelper + blockSource types.BlockSource // Collections for state management - ValidatorIndex collections.Map[string, uint16] - ValidatorPower collections.Map[uint16, uint64] - AttestationBitmap collections.Map[int64, []byte] + ValidatorIndex collections.Map[string, uint16] + ValidatorPower collections.Map[uint16, uint64] + + //AttestationBitmap tracks attestations for a block + AttestationBitmap collections.Map[int64, []byte] + // EpochBitmap track tracks participation over a range of epochs EpochBitmap collections.Map[uint64, []byte] AttesterSet collections.KeySet[string] Signatures collections.Map[collections.Pair[int64, string], []byte] @@ -40,6 +43,7 @@ func NewKeeper( sk types.StakingKeeper, ak types.AccountKeeper, bk types.BankKeeper, + blockSource types.BlockSource, authority string, ) Keeper { @@ -51,6 +55,7 @@ func NewKeeper( bankKeeper: bk, authority: authority, bitmapHelper: NewBitmapHelper(), + blockSource: blockSource, ValidatorIndex: collections.NewMap(sb, types.ValidatorIndexPrefix, "validator_index", collections.StringKey, collections.Uint16Value), ValidatorPower: collections.NewMap(sb, types.ValidatorPowerPrefix, "validator_power", collections.Uint16Key, collections.Uint64Value), @@ -195,9 +200,12 @@ func (k Keeper) BuildValidatorIndexMap(ctx sdk.Context) error { // GetCurrentEpoch returns the current epoch number func (k Keeper) GetCurrentEpoch(ctx sdk.Context) uint64 { + return k.GetEpochForHeight(ctx, ctx.BlockHeight()) +} + +func (k Keeper) GetEpochForHeight(ctx sdk.Context, height int64) uint64 { params := k.GetParams(ctx) - height := uint64(ctx.BlockHeight()) - return height / params.EpochLength + return uint64(height) / params.EpochLength } // IsCheckpointHeight checks if a height is a checkpoint diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index 8547230e..c31bb023 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -1,8 +1,13 @@ package keeper import ( + "bytes" "context" + "cosmossdk.io/collections" "fmt" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" + "github.com/cosmos/gogoproto/proto" "cosmossdk.io/errors" "cosmossdk.io/math" @@ -28,29 +33,53 @@ var _ types.MsgServer = msgServer{} func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.MsgAttestResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if !k.IsCheckpointHeight(ctx, msg.Height) { - return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "height %d is not a checkpoint", msg.Height) + if err := k.validateAttestation(ctx, msg); err != nil { + return nil, err } - has, err := k.IsInAttesterSet(ctx, msg.Validator) - if err != nil { - return nil, errors.Wrapf(err, "in attester set") - } - if !has { - return nil, errors.Wrapf(sdkerrors.ErrUnauthorized, "validator %s not in attester set", msg.Validator) + votedEpoch := k.GetEpochForHeight(ctx, msg.Height) + if k.GetCurrentEpoch(ctx) != votedEpoch+1 { // can vote only for last epoch + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator %s not voted for epoch %d", msg.Validator, votedEpoch) } - index, found := k.GetValidatorIndex(ctx, msg.Validator) + valIndexPos, found := k.GetValidatorIndex(ctx, msg.Validator) if !found { return nil, errors.Wrapf(sdkerrors.ErrNotFound, "validator index not found for %s", msg.Validator) } - // todo (Alex): we need to set a limit to not have validators attest old blocks. Also make sure that this relates with - // the retention period for pruning - bitmap, _ := k.GetAttestationBitmap(ctx, msg.Height) - if bitmap == nil { + if err := k.updateAttestationBitmap(ctx, msg, valIndexPos); err != nil { + return nil, errors.Wrap(err, "update attestation bitmap") + } + + vote, err := k.verifyVote(ctx, msg) + if err != nil { + return nil, err + } + + if err := k.SetSignature(ctx, msg.Height, msg.Validator, vote.Signature); err != nil { + return nil, errors.Wrap(err, "store signature") + } + + if err := k.updateEpochBitmap(ctx, votedEpoch, valIndexPos); err != nil { + return nil, err + } + + // Emit event + ctx.EventManager().EmitEvent( + sdk.NewEvent( + types.TypeMsgAttest, + sdk.NewAttribute("validator", msg.Validator), + sdk.NewAttribute("height", math.NewInt(msg.Height).String()), + ), + ) + return &types.MsgAttestResponse{}, nil +} + +func (k msgServer) updateEpochBitmap(ctx sdk.Context, votedEpoch uint64, index uint16) error { + epochBitmap := k.GetEpochBitmap(ctx, votedEpoch) + if epochBitmap == nil { validators, err := k.stakingKeeper.GetLastValidators(ctx) if err != nil { - return nil, err + return err } numValidators := 0 for _, v := range validators { @@ -58,32 +87,42 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M numValidators++ } } - bitmap = k.bitmapHelper.NewBitmap(numValidators) + epochBitmap = k.bitmapHelper.NewBitmap(numValidators) } - - if k.bitmapHelper.IsSet(bitmap, int(index)) { - return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator %s already attested for height %d", msg.Validator, msg.Height) + k.bitmapHelper.SetBit(epochBitmap, int(index)) + if err := k.SetEpochBitmap(ctx, votedEpoch, epochBitmap); err != nil { + return errors.Wrap(err, "set epoch bitmap") } + return nil +} - // TODO: Verify the vote signature here once we implement vote parsing +// validateAttestation validates the attestation request +func (k msgServer) validateAttestation(ctx sdk.Context, msg *types.MsgAttest) error { + if !k.IsCheckpointHeight(ctx, msg.Height) { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "height %d is not a checkpoint", msg.Height) + } - // Set the bit - k.bitmapHelper.SetBit(bitmap, int(index)) - if err := k.SetAttestationBitmap(ctx, msg.Height, bitmap); err != nil { - return nil, errors.Wrap(err, "failed to set attestation bitmap") + has, err := k.IsInAttesterSet(ctx, msg.Validator) + if err != nil { + return errors.Wrapf(err, "in attester set") + } + if !has { + return errors.Wrapf(sdkerrors.ErrUnauthorized, "validator %s not in attester set", msg.Validator) } + return nil +} - // Store signature using the new collection method - if err := k.SetSignature(ctx, msg.Height, msg.Validator, msg.Vote); err != nil { - return nil, errors.Wrap(err, "failed to store signature") +// updateAttestationBitmap handles bitmap operations for attestation +func (k msgServer) updateAttestationBitmap(ctx sdk.Context, msg *types.MsgAttest, index uint16) error { + bitmap, err := k.GetAttestationBitmap(ctx, msg.Height) + if err != nil && !errors.IsOf(err, collections.ErrNotFound) { + return err } - epoch := k.GetCurrentEpoch(ctx) - epochBitmap := k.GetEpochBitmap(ctx, epoch) - if epochBitmap == nil { + if bitmap == nil { validators, err := k.stakingKeeper.GetLastValidators(ctx) if err != nil { - return nil, err + return err } numValidators := 0 for _, v := range validators { @@ -91,23 +130,56 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M numValidators++ } } - epochBitmap = k.bitmapHelper.NewBitmap(numValidators) + bitmap = k.bitmapHelper.NewBitmap(numValidators) } - k.bitmapHelper.SetBit(epochBitmap, int(index)) - if err := k.SetEpochBitmap(ctx, epoch, epochBitmap); err != nil { - return nil, errors.Wrap(err, "failed to set epoch bitmap") + + if k.bitmapHelper.IsSet(bitmap, int(index)) { + return errors.Wrapf(sdkerrors.ErrInvalidRequest, "validator %s already attested for height %d", msg.Validator, msg.Height) } - // Emit event - ctx.EventManager().EmitEvent( - sdk.NewEvent( - types.TypeMsgAttest, - sdk.NewAttribute("validator", msg.Validator), - sdk.NewAttribute("height", math.NewInt(msg.Height).String()), - ), - ) + k.bitmapHelper.SetBit(bitmap, int(index)) - return &types.MsgAttestResponse{}, nil + if err := k.SetAttestationBitmap(ctx, msg.Height, bitmap); err != nil { + return errors.Wrap(err, "set attestation bitmap") + } + return nil +} + +// verifyVote verifies the vote signature and block hash +func (k msgServer) verifyVote(ctx sdk.Context, msg *types.MsgAttest) (*cmtproto.Vote, error) { + var vote cmtproto.Vote + if err := proto.Unmarshal(msg.Vote, &vote); err != nil { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "unmarshal vote: %s", err) + } + + header, _, err := k.blockSource.GetBlockData(ctx, uint64(msg.Height)) + if err != nil { + return nil, errors.Wrapf(err, "block data for height %d", msg.Height) + } + if header == nil { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "block header not found for height %d", msg.Height) + } + + if !bytes.Equal(vote.BlockID.Hash, header.Header.AppHash) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "vote block ID hash does not match app hash for height %d", msg.Height) + } + + validator, err := k.stakingKeeper.GetValidator(ctx, vote.ValidatorAddress) + if err != nil { + return nil, errors.Wrapf(err, "get validator") + } + + pubKey, err := validator.ConsPubKey() + if err != nil { + return nil, errors.Wrapf(err, "pubkey") + } + + voteSignBytes := cmttypes.VoteSignBytes(header.Header.ChainID(), &vote) + if !pubKey.VerifySignature(voteSignBytes, vote.Signature) { + return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid vote signature") + } + + return &vote, nil } // JoinAttesterSet handles MsgJoinAttesterSet @@ -137,7 +209,7 @@ func (k msgServer) JoinAttesterSet(goCtx context.Context, msg *types.MsgJoinAtte // TODO (Alex): the valset should be updated at the end of an epoch only if err := k.SetAttesterSetMember(ctx, msg.Validator); err != nil { - return nil, errors.Wrap(err, "failed to set attester set member") + return nil, errors.Wrap(err, "set attester set member") } ctx.EventManager().EmitEvent( @@ -164,7 +236,7 @@ func (k msgServer) LeaveAttesterSet(goCtx context.Context, msg *types.MsgLeaveAt // TODO (Alex): the valset should be updated at the end of an epoch only if err := k.RemoveAttesterSetMember(ctx, msg.Validator); err != nil { - return nil, errors.Wrap(err, "failed to remove attester set member") + return nil, errors.Wrap(err, "remove attester set member") } ctx.EventManager().EmitEvent( diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go index 7f8a992f..9cbe1ef2 100644 --- a/modules/network/keeper/msg_server_test.go +++ b/modules/network/keeper/msg_server_test.go @@ -2,16 +2,27 @@ package keeper import ( "context" + "crypto/sha256" + cmttypes "github.com/cometbft/cometbft/types" "maps" "slices" "strings" "testing" "time" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + + "github.com/cosmos/gogoproto/proto" + ds "github.com/ipfs/go-datastore" + kt "github.com/ipfs/go-datastore/keytransform" + rollnode "github.com/rollkit/rollkit/node" + rstore "github.com/rollkit/rollkit/pkg/store" + "cosmossdk.io/log" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil/integration" sdk "github.com/cosmos/cosmos-sdk/types" @@ -19,6 +30,7 @@ import ( moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + rollkittypes "github.com/rollkit/rollkit/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -26,7 +38,7 @@ import ( ) func TestJoinAttesterSet(t *testing.T) { - myValAddr := sdk.ValAddress("validator4") + myValAddr := sdk.ValAddress("validator") type testCase struct { setup func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper) @@ -114,7 +126,7 @@ func TestJoinAttesterSet(t *testing.T) { logger := log.NewTestLogger(t) cms := integration.CreateMultiStore(keys, logger) authority := authtypes.NewModuleAddress("gov") - keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), sk, nil, nil, authority.String()) + keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), sk, nil, nil, nil, authority.String()) server := msgServer{Keeper: keeper} ctx := sdk.NewContext(cms, cmtproto.Header{ChainID: "test-chain", Time: time.Now().UTC(), Height: 10}, false, logger). WithContext(t.Context()) @@ -141,23 +153,192 @@ func TestJoinAttesterSet(t *testing.T) { } } +func TestAttest(t *testing.T) { + var ( + myHash = sha256.Sum256([]byte("app_hash")) + myAppHash = myHash[:] + chainID = "testing" + voteSigner = ed25519.GenPrivKey() + validVote = &cmtproto.Vote{ + Type: cmtproto.PrecommitType, + Height: 10, + Round: 0, + BlockID: cmtproto.BlockID{Hash: myAppHash, PartSetHeader: cmtproto.PartSetHeader{Total: 1, Hash: myAppHash}}, + Timestamp: time.Now(), + ValidatorAddress: voteSigner.PubKey().Address(), + ValidatorIndex: 0, + } + // Create the vote signature using VoteSignBytes + ) + validVote.Signature = must(voteSigner.Sign(cmttypes.VoteSignBytes(chainID, validVote))) + validVoteBz := must(proto.Marshal(validVote)) + + testCases := map[string]struct { + setupMock func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) + msg *types.MsgAttest + expErr error + }{ + "valid attestation": { + setupMock: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) { + // Use the validator address from the vote + valAddrStr := sdk.ValAddress(voteSigner.PubKey().Address()).String() + validator, err := stakingtypes.NewValidator(valAddrStr, voteSigner.PubKey(), stakingtypes.Description{}) + require.NoError(t, err) + require.NoError(t, sk.SetValidator(ctx, validator)) + require.NoError(t, keeper.SetAttesterSetMember(ctx, valAddrStr)) + require.NoError(t, keeper.SetValidatorIndex(ctx, valAddrStr, 0, 100)) + sk.SetValidatorPubKey(valAddrStr, voteSigner.PubKey()) + + // Set up params for checkpoint height + params := types.DefaultParams() + params.EpochLength = 10 + require.NoError(t, keeper.SetParams(ctx, params)) + + header := rollkittypes.Header{ + BaseHeader: rollkittypes.BaseHeader{ + Height: 10, + Time: uint64(time.Now().UnixNano()), + ChainID: "testing", + }, + Version: rollkittypes.Version{Block: 1, App: 1}, + ProposerAddress: voteSigner.PubKey().Address(), + AppHash: myAppHash, + DataHash: []byte("data_hash"), + ConsensusHash: []byte("consensus_hash"), + ValidatorHash: []byte("validator_hash"), + } + signedHeader := &rollkittypes.SignedHeader{ + Header: header, + Signature: myAppHash, + //Signer: rollkittypes.Signer{PubKey: voteSigner.PubKey()}, + } + data := &rollkittypes.Data{ + Txs: rollkittypes.Txs{}, + } + var signature rollkittypes.Signature + require.NoError(t, bs.SaveBlockData(ctx, signedHeader, data, &signature)) + }, + msg: &types.MsgAttest{ + Validator: sdk.ValAddress(voteSigner.PubKey().Address()).String(), + Height: 10, + Vote: validVoteBz, + }, + }, + //"validator not in attester set": { + // setupMock: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) { + // // Set up validator but don't add to attester set + // valAddr := sdk.ValAddress("validator1") + // validator := stakingtypes.Validator{ + // OperatorAddress: valAddr.String(), + // Status: stakingtypes.Bonded, + // } + // require.NoError(t, sk.SetValidator(ctx, validator)) + // + // // Set up params for checkpoint height + // params := types.DefaultParams() + // params.EpochLength = 10 // Make height 10 a checkpoint + // require.NoError(t, keeper.SetParams(ctx, params)) + // }, + // msg: &types.MsgAttest{ + // Validator: sdk.ValAddress("validator1").String(), + // Height: 10, + // Vote: []byte("mock_vote"), + // }, + // expErr: sdkerrors.ErrUnauthorized, + //}, + //"not a checkpoint height": { + // setupMock: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) { + // // Set up validator and add to attester set + // valAddr := sdk.ValAddress("validator1") + // validator := stakingtypes.Validator{ + // OperatorAddress: valAddr.String(), + // Status: stakingtypes.Bonded, + // } + // require.NoError(t, sk.SetValidator(ctx, validator)) + // require.NoError(t, keeper.SetAttesterSetMember(ctx, valAddr.String())) + // + // // Set up params for checkpoint height + // params := types.DefaultParams() + // params.EpochLength = 10 // Make height 10 a checkpoint + // require.NoError(t, keeper.SetParams(ctx, params)) + // }, + // msg: &types.MsgAttest{ + // Validator: sdk.ValAddress("validator1").String(), + // Height: 11, // Not a checkpoint height + // Vote: []byte("mock_vote"), + // }, + // expErr: sdkerrors.ErrInvalidRequest, + //}, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + // Create mocks with test doubles + sk := NewMockStakingKeeper() + + rollkitPrefixStore := kt.Wrap(ds.NewMapDatastore(), &kt.PrefixTransform{ + Prefix: ds.NewKey(rollnode.RollkitPrefix), + }) + bs := rstore.New(rollkitPrefixStore) + + // Set up codec and store + cdc := moduletestutil.MakeTestEncodingConfig().Codec + keys := storetypes.NewKVStoreKeys(types.StoreKey) + + // Set up context and keeper + logger := log.NewTestLogger(t) + cms := integration.CreateMultiStore(keys, logger) + authority := authtypes.NewModuleAddress("gov") + keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), &sk, nil, nil, bs, authority.String()) + server := NewMsgServerImpl(keeper) + + ctx := sdk.NewContext(cms, cmtproto.Header{ChainID: "test-chain", Time: time.Now().UTC(), Height: 20}, false, logger). + WithContext(t.Context()) + + // Run setup + tc.setupMock(t, ctx, &keeper, &sk, bs) + + // when + rsp, err := server.Attest(ctx, tc.msg) + + // then + if tc.expErr != nil { + require.Error(t, err) + require.ErrorIs(t, err, tc.expErr) + require.Nil(t, rsp) + return + } + + require.NoError(t, err) + require.NotNil(t, rsp) + + // In a successful case, we would check that the signature was stored + // and the attestation bitmap was updated + // But since we're mocking the verifyVote method, we can't check these + // in a meaningful way + }) + } +} + var _ types.StakingKeeper = &MockStakingKeeper{} type MockStakingKeeper struct { activeSet map[string]stakingtypes.Validator + pubKeys map[string]cryptotypes.PubKey } func NewMockStakingKeeper() MockStakingKeeper { return MockStakingKeeper{ activeSet: make(map[string]stakingtypes.Validator), + pubKeys: make(map[string]cryptotypes.PubKey), } } func (m *MockStakingKeeper) SetValidator(ctx context.Context, validator stakingtypes.Validator) error { m.activeSet[validator.GetOperator()] = validator return nil - } + func (m MockStakingKeeper) GetAllValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) { return slices.SortedFunc(maps.Values(m.activeSet), func(v1 stakingtypes.Validator, v2 stakingtypes.Validator) int { return strings.Compare(v1.OperatorAddress, v2.OperatorAddress) @@ -165,11 +346,24 @@ func (m MockStakingKeeper) GetAllValidators(ctx context.Context) (validators []s } func (m MockStakingKeeper) GetValidator(ctx context.Context, addr sdk.ValAddress) (validator stakingtypes.Validator, err error) { + // First try to find the validator by address validator, found := m.activeSet[addr.String()] - if !found { - return validator, sdkerrors.ErrNotFound + if found { + return validator, nil + } + + // If not found by address, try to find by public key address + addrStr := addr.String() + for valAddrStr, pubKey := range m.pubKeys { + if pubKey.Address().String() == addrStr { + validator, found = m.activeSet[valAddrStr] + if found { + return validator, nil + } + } } - return validator, nil + + return validator, sdkerrors.ErrNotFound } func (m MockStakingKeeper) GetLastValidators(ctx context.Context) (validators []stakingtypes.Validator, err error) { @@ -184,3 +378,14 @@ func (m MockStakingKeeper) GetLastValidators(ctx context.Context) (validators [] func (m MockStakingKeeper) GetLastTotalPower(ctx context.Context) (math.Int, error) { return math.NewInt(int64(len(m.activeSet))), nil } + +func (m *MockStakingKeeper) SetValidatorPubKey(valAddrStr string, key cryptotypes.PubKey) { + m.pubKeys[valAddrStr] = key +} + +func must[T any](r T, err error) T { + if err != nil { + panic(err) + } + return r +} diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go index 8c11e6de..b9def7f3 100644 --- a/modules/network/types/expected_keepers.go +++ b/modules/network/types/expected_keepers.go @@ -2,6 +2,7 @@ package types import ( "context" + tyrollkittypes "github.com/rollkit/rollkit/types" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" @@ -25,3 +26,8 @@ type AccountKeeper interface { type BankKeeper interface { SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins } + +// BlockSource is the block store +type BlockSource interface { + GetBlockData(ctx context.Context, height uint64) (*tyrollkittypes.SignedHeader, *tyrollkittypes.Data, error) +} From 880efa449d67ea928dd3242954d2c15327d1288b Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 25 Jun 2025 15:07:45 +0200 Subject: [PATCH 20/21] Test attestation happy path --- modules/network/keeper/msg_server_test.go | 151 +++++++++++++--------- 1 file changed, 88 insertions(+), 63 deletions(-) diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go index 9cbe1ef2..de31053f 100644 --- a/modules/network/keeper/msg_server_test.go +++ b/modules/network/keeper/msg_server_test.go @@ -3,13 +3,15 @@ package keeper import ( "context" "crypto/sha256" - cmttypes "github.com/cometbft/cometbft/types" "maps" "slices" "strings" "testing" "time" + cmttypes "github.com/cometbft/cometbft/types" + "github.com/libp2p/go-libp2p/core/crypto" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/gogoproto/proto" @@ -18,6 +20,7 @@ import ( rollnode "github.com/rollkit/rollkit/node" rstore "github.com/rollkit/rollkit/pkg/store" + "cosmossdk.io/collections" "cosmossdk.io/log" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" @@ -155,34 +158,23 @@ func TestJoinAttesterSet(t *testing.T) { func TestAttest(t *testing.T) { var ( - myHash = sha256.Sum256([]byte("app_hash")) - myAppHash = myHash[:] - chainID = "testing" - voteSigner = ed25519.GenPrivKey() - validVote = &cmtproto.Vote{ - Type: cmtproto.PrecommitType, - Height: 10, - Round: 0, - BlockID: cmtproto.BlockID{Hash: myAppHash, PartSetHeader: cmtproto.PartSetHeader{Total: 1, Hash: myAppHash}}, - Timestamp: time.Now(), - ValidatorAddress: voteSigner.PubKey().Address(), - ValidatorIndex: 0, - } - // Create the vote signature using VoteSignBytes + myHash = sha256.Sum256([]byte("app_hash")) + myAppHash = myHash[:] + voteSigner = ed25519.GenPrivKey() + valAddrStr = sdk.ValAddress(voteSigner.PubKey().Address()).String() + validVote = VoteFixture(myAppHash, voteSigner) + validVoteBz = must(proto.Marshal(validVote)) ) - validVote.Signature = must(voteSigner.Sign(cmttypes.VoteSignBytes(chainID, validVote))) - validVoteBz := must(proto.Marshal(validVote)) - testCases := map[string]struct { - setupMock func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) - msg *types.MsgAttest - expErr error + specs := map[string]struct { + setup func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) + msg *types.MsgAttest + expErr error }{ "valid attestation": { - setupMock: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) { - // Use the validator address from the vote - valAddrStr := sdk.ValAddress(voteSigner.PubKey().Address()).String() + setup: func(t *testing.T, ctx sdk.Context, keeper *Keeper, sk *MockStakingKeeper, bs rstore.Store) { validator, err := stakingtypes.NewValidator(valAddrStr, voteSigner.PubKey(), stakingtypes.Description{}) + validator.Status = stakingtypes.Bonded require.NoError(t, err) require.NoError(t, sk.SetValidator(ctx, validator)) require.NoError(t, keeper.SetAttesterSetMember(ctx, valAddrStr)) @@ -194,32 +186,13 @@ func TestAttest(t *testing.T) { params.EpochLength = 10 require.NoError(t, keeper.SetParams(ctx, params)) - header := rollkittypes.Header{ - BaseHeader: rollkittypes.BaseHeader{ - Height: 10, - Time: uint64(time.Now().UnixNano()), - ChainID: "testing", - }, - Version: rollkittypes.Version{Block: 1, App: 1}, - ProposerAddress: voteSigner.PubKey().Address(), - AppHash: myAppHash, - DataHash: []byte("data_hash"), - ConsensusHash: []byte("consensus_hash"), - ValidatorHash: []byte("validator_hash"), - } - signedHeader := &rollkittypes.SignedHeader{ - Header: header, - Signature: myAppHash, - //Signer: rollkittypes.Signer{PubKey: voteSigner.PubKey()}, - } - data := &rollkittypes.Data{ - Txs: rollkittypes.Txs{}, - } + signedHeader := HeaderFixture(voteSigner, myAppHash) + data := &rollkittypes.Data{Txs: rollkittypes.Txs{}} var signature rollkittypes.Signature require.NoError(t, bs.SaveBlockData(ctx, signedHeader, data, &signature)) }, msg: &types.MsgAttest{ - Validator: sdk.ValAddress(voteSigner.PubKey().Address()).String(), + Validator: valAddrStr, Height: 10, Vote: validVoteBz, }, @@ -271,16 +244,12 @@ func TestAttest(t *testing.T) { //}, } - for name, tc := range testCases { + for name, spec := range specs { t.Run(name, func(t *testing.T) { - // Create mocks with test doubles - sk := NewMockStakingKeeper() - rollkitPrefixStore := kt.Wrap(ds.NewMapDatastore(), &kt.PrefixTransform{ Prefix: ds.NewKey(rollnode.RollkitPrefix), }) bs := rstore.New(rollkitPrefixStore) - // Set up codec and store cdc := moduletestutil.MakeTestEncodingConfig().Codec keys := storetypes.NewKVStoreKeys(types.StoreKey) @@ -289,6 +258,7 @@ func TestAttest(t *testing.T) { logger := log.NewTestLogger(t) cms := integration.CreateMultiStore(keys, logger) authority := authtypes.NewModuleAddress("gov") + sk := NewMockStakingKeeper() keeper := NewKeeper(cdc, runtime.NewKVStoreService(keys[types.StoreKey]), &sk, nil, nil, bs, authority.String()) server := NewMsgServerImpl(keeper) @@ -296,30 +266,85 @@ func TestAttest(t *testing.T) { WithContext(t.Context()) // Run setup - tc.setupMock(t, ctx, &keeper, &sk, bs) + spec.setup(t, ctx, &keeper, &sk, bs) // when - rsp, err := server.Attest(ctx, tc.msg) + gotRsp, gotErr := server.Attest(ctx, spec.msg) // then - if tc.expErr != nil { - require.Error(t, err) - require.ErrorIs(t, err, tc.expErr) - require.Nil(t, rsp) + if spec.expErr != nil { + require.Error(t, gotErr) + require.ErrorIs(t, gotErr, spec.expErr) + // and ensure the signature is not stored + _, err := keeper.GetSignature(ctx, spec.msg.Height, valAddrStr) + assert.ErrorIs(t, err, collections.ErrNotFound) return } - require.NoError(t, err) - require.NotNil(t, rsp) + require.NoError(t, gotErr) + require.NotNil(t, gotRsp) + + // and attestation marked + bitmap, gotErr := keeper.GetAttestationBitmap(ctx, spec.msg.Height) + require.NoError(t, gotErr) + require.NotEmpty(t, bitmap) + require.Equal(t, byte(1), bitmap[0]) - // In a successful case, we would check that the signature was stored - // and the attestation bitmap was updated - // But since we're mocking the verifyVote method, we can't check these - // in a meaningful way + // and the signature was stored properly + gotSig, err := keeper.GetSignature(ctx, spec.msg.Height, valAddrStr) + require.NoError(t, err) + var vote cmtproto.Vote + require.NoError(t, proto.Unmarshal(spec.msg.Vote, &vote)) + assert.Equal(t, vote.Signature, gotSig) }) } } +func HeaderFixture(signer *ed25519.PrivKey, myAppHash []byte, mutators ...func(*rollkittypes.SignedHeader)) *rollkittypes.SignedHeader { + header := rollkittypes.Header{ + BaseHeader: rollkittypes.BaseHeader{ + Height: 10, + Time: uint64(time.Now().UnixNano()), + ChainID: "testing", + }, + Version: rollkittypes.Version{Block: 1, App: 1}, + ProposerAddress: signer.PubKey().Address(), + AppHash: myAppHash, + DataHash: []byte("data_hash"), + ConsensusHash: []byte("consensus_hash"), + ValidatorHash: []byte("validator_hash"), + } + signedHeader := &rollkittypes.SignedHeader{ + Header: header, + Signature: myAppHash, + Signer: rollkittypes.Signer{PubKey: must(crypto.UnmarshalEd25519PublicKey(signer.PubKey().Bytes()))}, + } + for _, m := range mutators { + m(signedHeader) + } + return signedHeader +} + +func VoteFixture(myAppHash []byte, voteSigner *ed25519.PrivKey, mutators ...func(vote *cmtproto.Vote)) *cmtproto.Vote { + const chainID = "testing" + + vote := &cmtproto.Vote{ + Type: cmtproto.PrecommitType, + Height: 10, + Round: 0, + BlockID: cmtproto.BlockID{Hash: myAppHash, PartSetHeader: cmtproto.PartSetHeader{Total: 1, Hash: myAppHash}}, + Timestamp: time.Now(), + ValidatorAddress: voteSigner.PubKey().Address(), + ValidatorIndex: 0, + } + vote.Signature = must(voteSigner.Sign(cmttypes.VoteSignBytes(chainID, vote))) + + for _, m := range mutators { + m(vote) + } + return vote +} + var _ types.StakingKeeper = &MockStakingKeeper{} type MockStakingKeeper struct { From 4f29cf55aa8436df16e9efc8f83e7f543c49a8d5 Mon Sep 17 00:00:00 2001 From: Alex Peters Date: Wed, 25 Jun 2025 17:01:15 +0200 Subject: [PATCH 21/21] Provide network commits --- modules/network/keeper/keeper.go | 63 +++++++++++++++++++---- modules/network/keeper/msg_server.go | 14 ++--- modules/network/keeper/msg_server_test.go | 30 ++++++----- modules/network/types/expected_keepers.go | 3 +- modules/network/types/keys.go | 4 +- pkg/adapter/adapter.go | 1 - 6 files changed, 82 insertions(+), 33 deletions(-) diff --git a/modules/network/keeper/keeper.go b/modules/network/keeper/keeper.go index 692eed09..78b46eff 100644 --- a/modules/network/keeper/keeper.go +++ b/modules/network/keeper/keeper.go @@ -1,11 +1,16 @@ package keeper import ( + "fmt" + "time" + "cosmossdk.io/collections" "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/math" - "fmt" + cmbytes "github.com/cometbft/cometbft/libs/bytes" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -31,7 +36,7 @@ type Keeper struct { // EpochBitmap track tracks participation over a range of epochs EpochBitmap collections.Map[uint64, []byte] AttesterSet collections.KeySet[string] - Signatures collections.Map[collections.Pair[int64, string], []byte] + CommitSignatures collections.Map[collections.Pair[int64, string], cmtproto.CommitSig] StoredAttestationInfo collections.Map[int64, types.AttestationBitmap] Params collections.Item[types.Params] } @@ -62,7 +67,7 @@ func NewKeeper( AttestationBitmap: collections.NewMap(sb, types.AttestationBitmapPrefix, "attestation_bitmap", collections.Int64Key, collections.BytesValue), EpochBitmap: collections.NewMap(sb, types.EpochBitmapPrefix, "epoch_bitmap", collections.Uint64Key, collections.BytesValue), AttesterSet: collections.NewKeySet(sb, types.AttesterSetPrefix, "attester_set", collections.StringKey), - Signatures: collections.NewMap(sb, types.SignaturePrefix, "signatures", collections.PairKeyCodec(collections.Int64Key, collections.StringKey), collections.BytesValue), + CommitSignatures: collections.NewMap(sb, types.CommitPrefix, "commits", collections.PairKeyCodec(collections.Int64Key, collections.StringKey), codec.CollValue[cmtproto.CommitSig](cdc)), StoredAttestationInfo: collections.NewMap(sb, types.StoredAttestationInfoPrefix, "stored_attestation_info", collections.Int64Key, codec.CollValue[types.AttestationBitmap](cdc)), // Initialize new collection Params: collections.NewItem(sb, types.ParamsKey, "params", codec.CollValue[types.Params](cdc)), } @@ -308,23 +313,63 @@ func (k Keeper) PruneOldBitmaps(ctx sdk.Context, currentEpoch uint64) error { } // TODO: Consider pruning signatures associated with pruned heights. - // This would involve iterating k.Signatures and removing entries where height < pruneHeight. + // This would involve iterating k.CommitsByHeight and removing entries where height < pruneHeight. k.Logger(ctx).Info("Pruned old bitmaps and attestation info", "prunedBeforeEpoch", pruneBeforeEpoch, "prunedBeforeHeight", pruneHeight) return nil } // SetSignature stores the vote signature for a given height and validator -func (k Keeper) SetSignature(ctx sdk.Context, height int64, validatorAddr string, signature []byte) error { - return k.Signatures.Set(ctx, collections.Join(height, validatorAddr), signature) +func (k Keeper) SetSignature(ctx sdk.Context, height int64, validatorAddr string, consAddr []byte, timestamp time.Time, signature []byte) error { + cmtSig := cmtproto.CommitSig{ + BlockIdFlag: cmtproto.BlockIDFlagCommit, + ValidatorAddress: consAddr, + Timestamp: timestamp, + Signature: signature, + } + return k.CommitSignatures.Set(ctx, collections.Join(height, validatorAddr), cmtSig) } // GetSignature retrieves the vote signature for a given height and validator -func (k Keeper) GetSignature(ctx sdk.Context, height int64, validatorAddr string) ([]byte, error) { - return k.Signatures.Get(ctx, collections.Join(height, validatorAddr)) +func (k Keeper) GetSignature(ctx sdk.Context, height int64, validatorAddr string) (cmtproto.CommitSig, error) { + rsp, err := k.CommitSignatures.Get(ctx, collections.Join(height, validatorAddr)) + return rsp, err } // HasSignature checks if a signature exists for a given height and validator func (k Keeper) HasSignature(ctx sdk.Context, height int64, validatorAddr string) (bool, error) { - return k.Signatures.Has(ctx, collections.Join(height, validatorAddr)) + return k.CommitSignatures.Has(ctx, collections.Join(height, validatorAddr)) +} + +func (k Keeper) GetCommits(ctx sdk.Context, height int64) (*cmttypes.Commit, error) { + header, data, err := k.blockSource.GetBlockData(ctx, uint64(height)) + if err != nil { + return nil, fmt.Errorf("failed to get block at height %d: %w", height, err) + } + _ = data + + commit := &cmttypes.Commit{ + Height: height, + Round: 0, + BlockID: cmttypes.BlockID{ + Hash: cmbytes.HexBytes(header.LastHeaderHash), + PartSetHeader: cmttypes.PartSetHeader{Total: 0, Hash: nil}, + }, + Signatures: make([]cmttypes.CommitSig, 0), + } + // add the signatures (unordered) // todo (Alex): do we need them ordered? + rng := collections.NewPrefixedPairRange[int64, string](height) + err = k.CommitSignatures.Walk(ctx, rng, func(key collections.Pair[int64, string], value cmtproto.CommitSig) (bool, error) { + var sig cmttypes.CommitSig + if err := sig.FromProto(value); err != nil { + return true, err + } + commit.Signatures = append(commit.Signatures, sig) + return false, nil + }) + if err != nil { + return nil, err + } + + return commit, nil } diff --git a/modules/network/keeper/msg_server.go b/modules/network/keeper/msg_server.go index c31bb023..647369bb 100644 --- a/modules/network/keeper/msg_server.go +++ b/modules/network/keeper/msg_server.go @@ -3,17 +3,17 @@ package keeper import ( "bytes" "context" - "cosmossdk.io/collections" "fmt" - cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" - cmttypes "github.com/cometbft/cometbft/types" - "github.com/cosmos/gogoproto/proto" + "cosmossdk.io/collections" "cosmossdk.io/errors" "cosmossdk.io/math" + cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + "github.com/cosmos/gogoproto/proto" "github.com/rollkit/go-execution-abci/modules/network/types" ) @@ -55,7 +55,7 @@ func (k msgServer) Attest(goCtx context.Context, msg *types.MsgAttest) (*types.M return nil, err } - if err := k.SetSignature(ctx, msg.Height, msg.Validator, vote.Signature); err != nil { + if err := k.SetSignature(ctx, msg.Height, msg.Validator, vote.ValidatorAddress, vote.Timestamp, vote.Signature); err != nil { return nil, errors.Wrap(err, "store signature") } @@ -160,7 +160,7 @@ func (k msgServer) verifyVote(ctx sdk.Context, msg *types.MsgAttest) (*cmtproto. return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "block header not found for height %d", msg.Height) } - if !bytes.Equal(vote.BlockID.Hash, header.Header.AppHash) { + if !bytes.Equal(vote.BlockID.Hash, header.AppHash) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "vote block ID hash does not match app hash for height %d", msg.Height) } @@ -174,7 +174,7 @@ func (k msgServer) verifyVote(ctx sdk.Context, msg *types.MsgAttest) (*cmtproto. return nil, errors.Wrapf(err, "pubkey") } - voteSignBytes := cmttypes.VoteSignBytes(header.Header.ChainID(), &vote) + voteSignBytes := cmttypes.VoteSignBytes(header.ChainID(), &vote) if !pubKey.VerifySignature(voteSignBytes, vote.Signature) { return nil, errors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid vote signature") } diff --git a/modules/network/keeper/msg_server_test.go b/modules/network/keeper/msg_server_test.go index de31053f..42c195d9 100644 --- a/modules/network/keeper/msg_server_test.go +++ b/modules/network/keeper/msg_server_test.go @@ -9,23 +9,14 @@ import ( "testing" "time" - cmttypes "github.com/cometbft/cometbft/types" - "github.com/libp2p/go-libp2p/core/crypto" - - cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" - - "github.com/cosmos/gogoproto/proto" - ds "github.com/ipfs/go-datastore" - kt "github.com/ipfs/go-datastore/keytransform" - rollnode "github.com/rollkit/rollkit/node" - rstore "github.com/rollkit/rollkit/pkg/store" - "cosmossdk.io/collections" "cosmossdk.io/log" "cosmossdk.io/math" storetypes "cosmossdk.io/store/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + cmttypes "github.com/cometbft/cometbft/types" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/runtime" "github.com/cosmos/cosmos-sdk/testutil/integration" sdk "github.com/cosmos/cosmos-sdk/types" @@ -33,10 +24,17 @@ import ( moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" - rollkittypes "github.com/rollkit/rollkit/types" + "github.com/cosmos/gogoproto/proto" + ds "github.com/ipfs/go-datastore" + kt "github.com/ipfs/go-datastore/keytransform" + "github.com/libp2p/go-libp2p/core/crypto" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + rollnode "github.com/rollkit/rollkit/node" + rstore "github.com/rollkit/rollkit/pkg/store" + rollkittypes "github.com/rollkit/rollkit/types" + "github.com/rollkit/go-execution-abci/modules/network/types" ) @@ -295,7 +293,13 @@ func TestAttest(t *testing.T) { require.NoError(t, err) var vote cmtproto.Vote require.NoError(t, proto.Unmarshal(spec.msg.Vote, &vote)) - assert.Equal(t, vote.Signature, gotSig) + expSig := cmtproto.CommitSig{ + BlockIdFlag: cmtproto.BlockIDFlagCommit, + ValidatorAddress: vote.ValidatorAddress, + Timestamp: vote.Timestamp, + Signature: vote.Signature, + } + assert.Equal(t, expSig, gotSig) }) } } diff --git a/modules/network/types/expected_keepers.go b/modules/network/types/expected_keepers.go index b9def7f3..a356b9aa 100644 --- a/modules/network/types/expected_keepers.go +++ b/modules/network/types/expected_keepers.go @@ -2,11 +2,12 @@ package types import ( "context" - tyrollkittypes "github.com/rollkit/rollkit/types" "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + + tyrollkittypes "github.com/rollkit/rollkit/types" ) // StakingKeeper defines the expected staking keeper interface diff --git a/modules/network/types/keys.go b/modules/network/types/keys.go index b80eb45d..9c97e3ad 100644 --- a/modules/network/types/keys.go +++ b/modules/network/types/keys.go @@ -28,7 +28,7 @@ var ( AttestationBitmapPrefix = collections.NewPrefix("attestation_bitmap") EpochBitmapPrefix = collections.NewPrefix("epoch_bitmap") AttesterSetPrefix = collections.NewPrefix("attester_set") - SignaturePrefix = collections.NewPrefix("signature") + CommitPrefix = collections.NewPrefix("commits") StoredAttestationInfoPrefix = collections.NewPrefix("stored_attestation_info") ParamsKey = collections.NewPrefix("params") ) @@ -56,7 +56,7 @@ func GetAttestationKey(height int64) []byte { func GetSignatureKey(height int64, addr string) []byte { bz := make([]byte, 8) binary.BigEndian.PutUint64(bz, uint64(height)) - return append(append(SignaturePrefix, bz...), []byte(addr)...) + return append(append(CommitPrefix, bz...), []byte(addr)...) } // GetEpochBitmapKey returns the key for epoch participation bitmap diff --git a/pkg/adapter/adapter.go b/pkg/adapter/adapter.go index 9f6e23fb..6ed6ea88 100644 --- a/pkg/adapter/adapter.go +++ b/pkg/adapter/adapter.go @@ -110,7 +110,6 @@ func NewABCIExecutor( rollkitStore := rstore.New(rollkitPrefixStore) abciStore := NewExecABCIStore(store) - a := &Adapter{ App: app, Store: abciStore,