Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(dogfood): add module #4

Merged
merged 48 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
4e4a45b
feat(dogfood): scaffold module
MaxMustermann2 Feb 6, 2024
503728c
fix(dogfood): remove mem store
MaxMustermann2 Feb 6, 2024
36a2961
fix(dogfood): remove not required keepers
MaxMustermann2 Feb 6, 2024
47861d7
refactor(dogfood): remove not required items
MaxMustermann2 Feb 6, 2024
15e8e8a
refactor(dogfood): remove errors
MaxMustermann2 Feb 6, 2024
92be565
refactor(dogfood): merge `query_params.go`
MaxMustermann2 Feb 6, 2024
6d44166
feat(dogfood): add parameters
MaxMustermann2 Feb 6, 2024
cb08e29
feat(dogfood): load genesis state for bootstrap
MaxMustermann2 Feb 6, 2024
b4f4df5
feat(dogfood): implement operator hooks
MaxMustermann2 Feb 7, 2024
fdf9b9a
docs(dogfood): explain the operator queue logic
MaxMustermann2 Feb 8, 2024
50d098d
feat(dogfood): implement delegation hooks
MaxMustermann2 Feb 8, 2024
ebc8530
fix(dogfood): upd delegation hook interface
MaxMustermann2 Feb 8, 2024
5d0a0cd
feat(dogfood): implement epochs hooks + end block
MaxMustermann2 Feb 8, 2024
a2aa2e1
fix(dogfood): call `EndBlock` from module
MaxMustermann2 Feb 8, 2024
cc56595
feat(dogfood): retrieve val set from id
MaxMustermann2 Feb 26, 2024
fada516
Merge branch 'dogfood-part3' into dogfood-part4
MaxMustermann2 Feb 26, 2024
3447309
fix(dogfood): remove old key then add new
MaxMustermann2 Feb 26, 2024
a0752e9
Merge branch 'dogfood-part4' into dogfood-part5
MaxMustermann2 Feb 26, 2024
fe987ce
fix(dogfood): RecordKeys > UndelegationRecordKeys
MaxMustermann2 Feb 26, 2024
a8d7b20
Merge branch 'dogfood-part5' into dogfood-part6
MaxMustermann2 Feb 26, 2024
061ec13
doc(dogfood): update comments in EndBlock
MaxMustermann2 Feb 26, 2024
ba3b5d8
fix(dogfood): clear validator set only if unused
MaxMustermann2 Feb 26, 2024
c77f746
Merge branch 'dogfood-part3' into dogfood-part4
MaxMustermann2 Feb 26, 2024
2775176
Merge branch 'dogfood-part4' into dogfood-part5
MaxMustermann2 Feb 26, 2024
c17bf22
Merge branch 'dogfood-part5' into dogfood-part6
MaxMustermann2 Feb 26, 2024
8e9dec2
feat(dogfood): implement sdk staking interface (#123)
MaxMustermann2 Feb 28, 2024
7e6485e
Merge pull request #122 from ExocoreNetwork/dogfood-part6
MaxMustermann2 Feb 28, 2024
0fdfd1b
Merge pull request #121 from ExocoreNetwork/dogfood-part5
MaxMustermann2 Feb 28, 2024
5379fc4
Merge pull request #119 from ExocoreNetwork/dogfood-part4
MaxMustermann2 Feb 28, 2024
5203fcd
Merge pull request #116 from ExocoreNetwork/dogfood-part3
MaxMustermann2 Feb 28, 2024
728c580
Merge pull request #115 from ExocoreNetwork/dogfood-part2
MaxMustermann2 Feb 28, 2024
3d78db7
Merge branch 'develop' into dogfood
MaxMustermann2 Feb 28, 2024
3a5d824
chore(lint): apply to dogfood
MaxMustermann2 Feb 28, 2024
ded8f3f
doc(dogfood): update minor comment
MaxMustermann2 Feb 28, 2024
84a8037
chore(build): attempt to fix consensuswarn
MaxMustermann2 Feb 28, 2024
0debcab
Revert "chore(build): attempt to fix consensuswarn
MaxMustermann2 Feb 28, 2024
05a98c8
Merge branch 'develop' into dogfood
MaxMustermann2 Mar 1, 2024
965ed26
Merge branch 'develop' into dogfood
MaxMustermann2 Mar 4, 2024
fe295ae
Merge branch 'develop' into dogfood
MaxMustermann2 Mar 4, 2024
715557b
Merge branch 'develop' into dogfood
MaxMustermann2 Mar 4, 2024
8258c46
chore(build): respond to gosec comments
MaxMustermann2 Mar 4, 2024
57f60a4
chore(build): remove unused proto import
MaxMustermann2 Mar 4, 2024
7bba29f
chore(dogfood): respond to golangci-lint
MaxMustermann2 Mar 4, 2024
55a228c
chore(dogfood): lint the proto files
MaxMustermann2 Mar 4, 2024
ca658d8
build(dogfood): regenerate proto code
MaxMustermann2 Mar 4, 2024
931a8e1
chore(dogfood): ignore redundant gosec errors
MaxMustermann2 Mar 4, 2024
59fce84
chore(dogfood): ignore redundant gosec warning
MaxMustermann2 Mar 4, 2024
f3df5ef
feat(dogfood): asset ids, oracle usage (#11)
MaxMustermann2 Mar 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions proto/buf.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@ deps:
owner: cosmos
repository: cosmos-proto
commit: 1935555c206d4afb9e94615dfd0fad31
digest: shake256:c74d91a3ac7ae07d579e90eee33abf9b29664047ac8816500cf22c081fec0d72d62c89ce0bebafc1f6fec7aa5315be72606717740ca95007248425102c365377
- remote: buf.build
owner: cosmos
repository: cosmos-sdk
commit: 508e19f5f37549e3a471a2a59b903c00
commit: 954f7b05f38440fc8250134b15adec47
digest: shake256:2ab4404fd04a7d1d52df0e2d0f2d477a3d83ffd88d876957bf3fedfd702c8e52833d65b3ce1d89a3c5adf2aab512616b0e4f51d8463f07eda9a8a3317ee3ac54
- remote: buf.build
owner: cosmos
repository: gogo-proto
commit: 34d970b699f84aa382f3c29773a60836
commit: 88ef6483f90f478fb938c37dde52ece3
digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba
- remote: buf.build
owner: googleapis
repository: googleapis
commit: 783e4b5374fa488ab068d08af9658438
commit: e874a0be2bf140a5a4c7d4122c635823
digest: shake256:4fe3036b4d706f6ee2b13c730bd04777f021dfd02ed27e6e40480acfe664a7548238312ee0727fd77648a38d227e296d43f4a38a34cdd46068156211016d9657
2 changes: 1 addition & 1 deletion proto/buf.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: v1
name: buf.build/evmos/evmos
deps:
- buf.build/cosmos/cosmos-sdk
- buf.build/cosmos/cosmos-sdk:v0.47.0
- buf.build/cosmos/cosmos-proto
- buf.build/cosmos/gogo-proto
- buf.build/googleapis/googleapis
Expand Down
113 changes: 113 additions & 0 deletions proto/exocore/dogfood/v1/dogfood.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
syntax = "proto3";

package exocore.dogfood.v1;

import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";
import "google/protobuf/timestamp.proto";

import "cosmos/staking/v1beta1/staking.proto";
import "cosmos_proto/cosmos.proto";
import "tendermint/crypto/keys.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/dogfood/types";

// ExocoreValidator is a validator that is part of the Exocore network. It is
// used to validate and sign blocks and transactions.
message ExocoreValidator {
// The address, as derived from the consensus key. It has no relation
// with the operator's account address.
bytes address = 1;
// Last known power
int64 power = 2;
// pubkey is the consensus public key of the validator, as a Protobuf Any.
google.protobuf.Any pubkey = 3 [
(cosmos_proto.accepts_interface) = "cosmos.crypto.PubKey",
(gogoproto.moretags) = "yaml:\"consensus_pubkey\""
];
}

// OperationType is used to indicate the type of operation that is being
// cached by the module to create the updated validator set.
enum OperationType {
option (gogoproto.goproto_enum_prefix) = false;
// KeyOpUnspecified is used to indicate that the operation type is not specified.
// This should never be used.
OPERATION_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "KeyOpUnspecified" ];
// KeyAddition is used to indicate that the operation is a key addition.
OPERATION_TYPE_ADDITION_OR_UPDATE = 1 [ (gogoproto.enumvalue_customname) = "KeyAdditionOrUpdate" ];
// KeyRemoval is used to indicate that the operation is a key removal. Typically
// this is done due to key replacement mechanism and not directly.
OPERATION_TYPE_REMOVAL = 2 [ (gogoproto.enumvalue_customname) = "KeyRemoval" ];
}

// QueueResultType is used to indicate the result of the queue operation.
enum QueueResultType {
option (gogoproto.goproto_enum_prefix) = false;
// QueueResultUnspecified is used to indicate that the queue result type is not specified.
QUEUE_RESULT_TYPE_UNSPECIFIED = 0 [ (gogoproto.enumvalue_customname) = "QueueResultUnspecified" ];
// QueueResultSuccess is used to indicate that the queue operation was successful.
QUEUE_RESULT_TYPE_SUCCESS = 1 [ (gogoproto.enumvalue_customname) = "QueueResultSuccess" ];
// QueueResultExists is used to indicate that the queue operation failed because the
// operation already exists in the queue.
QUEUE_RESULT_TYPE_EXISTS = 2 [ (gogoproto.enumvalue_customname) = "QueueResultExists" ];
// QueueResultRemoved is used to indicate that the queue operation resulted in an existing
// operation being removed from the queue.
QUEUE_RESULT_TYPE_REMOVED = 3 [ (gogoproto.enumvalue_customname) = "QueueResultRemoved" ];
}

// Operation is used to indicate the operation that is being cached by the module
// to create the updated validator set.
message Operation {
// OperationType is the type of the operation (addition / removal).
OperationType operation_type = 1;
// OperatorAddress is the sdk.AccAddress of the operator.
bytes operator_address = 2;
// PubKey is the public key for which the operation is being applied.
tendermint.crypto.PublicKey pub_key = 3 [(gogoproto.nullable) = false];
}

// Operations is a collection of Operation.
message Operations {
// list is the list of operations.
repeated Operation list = 1 [(gogoproto.nullable) = false];
}

// AccountAddresses represents a list of account addresses. It is used to store the list of
// operator addresses whose operations are maturing at an epoch.
message AccountAddresses {
// list is the list of account addresses.
repeated bytes list = 1;
}

// ConsensusAddresses represents a list of account addresses. It is used to store the list of
// addresses (which correspond to operator public keys) to delete at the end of an epoch.
message ConsensusAddresses {
// list is the list of consensus addresses.
repeated bytes list = 1;
}

// UndelegationRecordKeys is a collection of undelegation record keys. This is used to store a
// list of undelegation records to mature in the delegation module at the end of the epoch.
message UndelegationRecordKeys {
// list is the list of undelegation record keys.
repeated bytes list = 1;
}

// Validators is a list of validators stored according to the staking module.
message Validators {
// list is the list of validators.
repeated cosmos.staking.v1beta1.Validator list = 1 [(gogoproto.nullable) = false];
}

// HeaderSubset is a subset of the block header that is relevant to the IBC codebase. It is
// stored for each height and then converted to the `tm.Header` object after queried. It is
// pruned when the information is no longer needed according to the `HistoricalEntries` param.
message HeaderSubset {
// timestamp of the block
google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
// validators for the next block
bytes next_validators_hash = 2;
// state after txs from the previous block
bytes app_hash = 3;
}
21 changes: 21 additions & 0 deletions proto/exocore/dogfood/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
syntax = "proto3";

package exocore.dogfood.v1;

import "gogoproto/gogo.proto";

import "tendermint/abci/types.proto";

import "exocore/dogfood/v1/params.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/dogfood/types";

// GenesisState defines the dogfood module's genesis state.
message GenesisState {
// Parameters of the module.
Params params = 1 [(gogoproto.nullable) = false];

// Validator set, stored by ExocoreValidatorKey.
repeated .tendermint.abci.ValidatorUpdate val_set = 2
[ (gogoproto.nullable) = false ];
}
23 changes: 23 additions & 0 deletions proto/exocore/dogfood/v1/params.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

package exocore.dogfood.v1;

import "gogoproto/gogo.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/dogfood/types";

// Params defines the parameters for the module.
message Params {
option (gogoproto.goproto_stringer) = false;
// EpochsUntilUnbonded is the number of epochs after which an unbonding
// is released. Note that it starts from the beginning of the next epoch
// in which the unbonding request was received. At that point, the vote
// power is reduced by the amount of the unbonding operation.
uint32 epochs_until_unbonded = 1;
// EpochIdentifier is the identifier of the epoch (week, hour, day).
string epoch_identifier = 2;
// MaxValidators is the maximum number of validators.
uint32 max_validators = 3;
// HistoricalEntries is the number of historical entries to persist.
uint32 historical_entries = 4;
}
26 changes: 26 additions & 0 deletions proto/exocore/dogfood/v1/query.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
syntax = "proto3";

package exocore.dogfood.v1;

import "exocore/dogfood/v1/params.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";

option go_package = "github.com/ExocoreNetwork/exocore/x/dogfood/types";

// Query defines the gRPC querier service.
service Query {
// Parameters queries the parameters of the module.
rpc Params(QueryParamsRequest) returns (QueryParamsResponse) {
option (google.api.http).get = "/exocore/dogfood/params";
}
}

// QueryParamsRequest is request type for the Query/Params RPC method.
message QueryParamsRequest {}

// QueryParamsResponse is response type for the Query/Params RPC method.
message QueryParamsResponse {
// params holds all the parameters of this module.
Params params = 1 [(gogoproto.nullable) = false];
}
8 changes: 8 additions & 0 deletions proto/exocore/dogfood/v1/tx.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
syntax = "proto3";

package exocore.dogfood.v1;

option go_package = "github.com/ExocoreNetwork/exocore/x/dogfood/types";

// Msg defines the Msg service.
service Msg {}
62 changes: 62 additions & 0 deletions x/dogfood/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cli

import (
"fmt"
// "strings"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"

// "github.com/cosmos/cosmos-sdk/client/flags"
// sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/ExocoreNetwork/exocore/x/dogfood/types"
)

// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd(string) *cobra.Command {
// Group dogfood queries under a subcommand
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())

return cmd
}

func CmdQueryParams() *cobra.Command {
cmd := &cobra.Command{
Use: "params",
Short: "shows the parameters of the module",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
if err != nil {
return err
}

return clientCtx.PrintProto(res)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
27 changes: 27 additions & 0 deletions x/dogfood/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package cli

import (
"fmt"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
// "github.com/cosmos/cosmos-sdk/client/flags"
"github.com/ExocoreNetwork/exocore/x/dogfood/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,
}

return cmd
}
69 changes: 69 additions & 0 deletions x/dogfood/keeper/abci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package keeper

import (
"github.com/ExocoreNetwork/exocore/x/dogfood/types"
abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

func (k Keeper) EndBlock(ctx sdk.Context) []abci.ValidatorUpdate {
// start with clearing the hold on the undelegations.
undelegations := k.GetPendingUndelegations(ctx)
Fixed Show fixed Hide fixed
for _, undelegation := range undelegations.GetList() {
k.delegationKeeper.DecrementUndelegationHoldCount(ctx, undelegation)
}
k.ClearPendingUndelegations(ctx)
// then, let the operator module know that the opt out has finished.
optOuts := k.GetPendingOptOuts(ctx)
Fixed Show fixed Hide fixed
for _, addr := range optOuts.GetList() {
k.operatorKeeper.CompleteOperatorOptOutFromChainId(ctx, addr, ctx.ChainID())
}
k.ClearPendingOptOuts(ctx)
// for slashing, the operator module is required to store a mapping of chain id + cons addr
// to operator address. this information can now be pruned, since the opt out is considered
// complete.
consensusAddrs := k.GetPendingConsensusAddrs(ctx)
Fixed Show fixed Hide fixed
for _, consensusAddr := range consensusAddrs.GetList() {
k.operatorKeeper.DeleteOperatorAddressForChainIdAndConsAddr(
ctx, ctx.ChainID(), consensusAddr,
)
}
k.ClearPendingConsensusAddrs(ctx)
// finally, perform the actual operations of vote power changes.
operations := k.GetPendingOperations(ctx)
Fixed Show fixed Hide fixed
id, _ := k.getValidatorSetID(ctx, ctx.BlockHeight())
if len(operations.GetList()) == 0 {
// there is no validator set change, so we just increment the block height
// and retain the same val set id mapping.
k.setValidatorSetID(ctx, ctx.BlockHeight()+1, id)
return []abci.ValidatorUpdate{}
}
res := make([]abci.ValidatorUpdate, 0, len(operations.GetList()))
for _, operation := range operations.GetList() {
switch operation.OperationType {
case types.KeyAdditionOrUpdate:
power, err := k.restakingKeeper.GetOperatorAssetValue(
ctx, operation.OperatorAddress,
)
if err != nil {
// this should never happen, but if it does, we just skip the operation.
continue
}
res = append(res, abci.ValidatorUpdate{
PubKey: operation.PubKey,
Power: power,
})
case types.KeyRemoval:
res = append(res, abci.ValidatorUpdate{
PubKey: operation.PubKey,
Power: 0,
})
case types.KeyOpUnspecified:
// this should never happen, but if it does, we just skip the operation.
continue
}
}
// call via wrapper function so that validator info is stored.
// the id is incremented by 1 for the next block.
return k.ApplyValidatorChanges(ctx, res, id+1, false)
Fixed Show fixed Hide fixed
}
Loading
Loading