-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #115 from ExocoreNetwork/dogfood-part2
feat(dogfood): add parameters
- Loading branch information
Showing
30 changed files
with
4,348 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.dogfood.v1; | ||
|
||
import "gogoproto/gogo.proto"; | ||
import "google/protobuf/any.proto"; | ||
import "google/protobuf/timestamp.proto"; | ||
|
||
import "cosmos_proto/cosmos.proto"; | ||
import "tendermint/crypto/keys.proto"; | ||
import "cosmos/staking/v1beta1/staking.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 { | ||
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 { | ||
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 { | ||
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 { | ||
repeated bytes list = 1; | ||
} | ||
|
||
// Validators is a list of validators stored according to the staking module. | ||
message 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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
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) | ||
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) | ||
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) | ||
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) | ||
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 { | ||
panic(err) | ||
} | ||
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: | ||
panic("unspecified operation type") | ||
} | ||
} | ||
// 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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package keeper | ||
|
||
import ( | ||
"github.com/ExocoreNetwork/exocore/x/dogfood/types" | ||
abci "github.com/cometbft/cometbft/abci/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// InitGenesis initializes the module's state from a provided genesis state. | ||
func (k Keeper) InitGenesis( | ||
ctx sdk.Context, | ||
genState types.GenesisState, | ||
) []abci.ValidatorUpdate { | ||
k.SetParams(ctx, genState.Params) | ||
// the `params` validator is not super useful to validate state level information | ||
// so, it must be done here. by extension, the `InitGenesis` of the epochs module | ||
// should be called before that of this module. | ||
_, found := k.epochsKeeper.GetEpochInfo(ctx, genState.Params.EpochIdentifier) | ||
if !found { | ||
// the panic is suitable here because it is being done at genesis, when the node | ||
// is not running. it means that the genesis file is malformed. | ||
panic("epoch info not found") | ||
} | ||
return k.ApplyValidatorChanges(ctx, genState.ValSet, types.InitialValidatorSetID, true) | ||
} | ||
|
||
// ExportGenesis returns the module's exported genesis | ||
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { | ||
genesis := types.DefaultGenesis() | ||
genesis.Params = k.GetDogfoodParams(ctx) | ||
|
||
return genesis | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package keeper | ||
|
||
import ( | ||
"github.com/ExocoreNetwork/exocore/x/dogfood/types" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
) | ||
|
||
// interface guard | ||
var _ types.DogfoodHooks = &MultiDogfoodHooks{} | ||
|
||
// MultiDogfoodHooks is a collection of DogfoodHooks. It calls the hook for each element in the | ||
// collection one-by-one. The hook is called in the order in which the collection is created. | ||
type MultiDogfoodHooks []types.DogfoodHooks | ||
|
||
// NewMultiDogfoodHooks is used to create a collective object of dogfood hooks from a list of | ||
// the hooks. It follows the "accept interface, return concrete types" philosophy. Other modules | ||
// may set the hooks by calling k := (*k).SetHooks(NewMultiDogfoodHooks(hookI)) | ||
func NewMultiDogfoodHooks(hooks ...types.DogfoodHooks) MultiDogfoodHooks { | ||
return hooks | ||
} | ||
|
||
// AfterValidatorBonded is the implementation of types.DogfoodHooks for MultiDogfoodHooks. | ||
func (hooks MultiDogfoodHooks) AfterValidatorBonded( | ||
ctx sdk.Context, | ||
consAddr sdk.ConsAddress, | ||
operator sdk.ValAddress, | ||
) error { | ||
for _, hook := range hooks { | ||
if err := hook.AfterValidatorBonded(ctx, consAddr, operator); err != nil { | ||
return err | ||
} | ||
} | ||
return nil | ||
} |
Oops, something went wrong.