forked from imua-xyz/imuachain
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(appchains): Introduce module + register AVS (imua-xyz#173)
* feat(appchain): scaffold coordinator * feat(appchain): scaffold subscriber * feat(epochs): create number + id structure * feat(appchain): add coordinator params * fix(epochs): invalidate negative duration * fix(avs): stateful validation of staking assets * refactor(dogfood): carve `sortByPower` out * fix(dogfood): avoid duplicate validation x/avs handles the assetID validation * fix(dogfood): replace with max unbonding duration * doc(app): add comment about slashing frac storage * feat(appchain): allow sub chain creation - Anyone can create a subchain via a simple transaction. The genesis file is available at the end of the current epoch. - If no operators opt in by that time, it is dropped. - If the state is available, it is queried via CLI and added to the genesis file of the subchain. - The genesis file, with data from other modules, starts the chain once enough vote power is live * chore(lint) * fix(test): make avs test pass The AVS module now validates the assetIDs passed to it * fix(appchain): remove superfluous test * fix(epochs): update expected test message negative duration is also not supported * chore(lint) * chore(lint): proto lint * chore: run proto gen * fix(appchain): remove floating point arithmetic * fix(appchain): remove wrong comment * doc(appchain): add comment about params expect * fix(appchain): remove superfluous fmt * feat(appchain): report invalid json * fix(utils): remove SliceStable and use Slice * doc(appchain): add more logging * chore(lint) * fix(ci): pin the golang lint version * chore(lint): remove unused timestamp proto * fix(doc): update field comments after review - The subscriber unbonding duration has no bounds - The advantage of reusing an already established channel was explicitly listed out * refactor(appchain): option pattern for Subscriber * fix(appchain-coord): remove unnecessary panic * fix(appchain): optimize capacity of val set * fix(appchain): option-pattern not on pointers Since the rest of the codebase uses direct objects and not pointers, making it pointers here would be too cumbersome. * refactor(dogfood,operator): carve out wrapped key The wrapped consensus key object has utility in the subscriber module as well, and, may have some utility in the coordinator module. Hence, it is better located in a `types` subpackage. * fix: respond to AI comments * fix(coordinator): correct epochs calc * fix: build and tests - The `github.com/ExocoreNetwork/exocore/types` package is a bit finicky to deal with, and hence, the wrapped key has been moved to its own subpackage within that. - Some files that were copied word-to-word in our codebase were never being used but instead referred from the parent codebase. This resulted in test errors about duplicate `proto` registration. Hence, these files have been removed. * fix(appchain): respond to review comments
- Loading branch information
1 parent
28ddae2
commit e290743
Showing
117 changed files
with
9,570 additions
and
2,001 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
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,107 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.common.v1; | ||
|
||
import "amino/amino.proto"; | ||
import "gogoproto/gogo.proto"; | ||
import "google/protobuf/duration.proto"; | ||
import "ibc/lightclients/tendermint/v1/tendermint.proto"; | ||
import "tendermint/abci/types.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/common/types"; | ||
|
||
// This file contains all of the types shared within the coordinator module | ||
// and each of the subscriber modules. These types (or parts thereof) are stored | ||
// within the module states but not sent over the wire. | ||
|
||
// Params defines the parameters for the subscriber module. TODO(mm): These must be deny listed | ||
// for edits via governance on the subscriber chain to prevent the subcriber participants | ||
// from unilaterally alterting parameters (like reward %) for their own benefit. | ||
message SubscriberParams { | ||
// Reward related params | ||
|
||
// coordinator_fee_pool_addr_str is the address of the fee pool on the coordinator. | ||
string coordinator_fee_pool_addr_str = 1; | ||
// distribution_transmission_channel is the channel name used to transmit | ||
// the rewards from the subscriber to the coordinator. It is used in the event | ||
// that a channel between coordinator and subscriber exists prior to the | ||
// provision of security from Exocore to the appchain. Until a changeover | ||
// process is implemented, it is currently unused. (TODO). The advantage | ||
// of reusing a channel that was already in place is that the coin denomination | ||
// which contains a hash of the channel name will remain unchanged. | ||
string distribution_transmission_channel = 2; | ||
// blocks_per_distribution_transmission is the number of blocks after which the minted | ||
// reward is sent to the coordinator. | ||
int64 blocks_per_distribution_transmission = 3; | ||
// subscriber_redistribution_fraction is the %age of the rewards that the subscriber | ||
// should send out. For example, "0.75" means 75% of the rewards are sent out. | ||
string subscriber_redistribution_fraction = 4; | ||
// reward_denom is the denomination of the reward. For now, this is not | ||
// distributed but rather simply tracked. | ||
string reward_denom = 5; | ||
|
||
// IBC related params | ||
|
||
// ibc_timeout_period is the timeout period used for IBC packets (excluding transfers) | ||
// Such a timeout is enforced by IBC itself and not by either of the chains. | ||
google.protobuf.Duration ibc_timeout_period = 6 | ||
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, | ||
(gogoproto.customname) = "IBCTimeoutPeriod" ]; | ||
// transfer_timeout_period is the timeout period used for IBC transfers. | ||
google.protobuf.Duration transfer_timeout_period = 7 | ||
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; | ||
|
||
// Params relevant to chain operation | ||
// unbonding_duration is the subscriber chain's unbonding duration. | ||
// for now, we don't support the subscriber chain using x/epochs as a unit of time; however, | ||
// when we do, this duration should be the best approximation of that mechanism, with | ||
// 1 epoch added to account for the current epoch. (TODO) | ||
google.protobuf.Duration unbonding_period = 8 | ||
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true ]; | ||
// HistoricalEntries is the number of historical entries to persist in the | ||
// historical stats module. It is the same as that defined in the staking module, | ||
// however, we use the signed version so that negative values can be caught. | ||
int64 historical_entries = 9; | ||
|
||
// These are params related to the slashing module. Requests are received | ||
// from the subscriber and slashed according to these params. Since signing | ||
// can only be tracked by the subscriber chain, we do not have any parameters | ||
// here that can be used to configure the signing window and the number of | ||
// blocks that should be signed in it. Conversely, the subscriber chain | ||
// does not do anything with these parameters (even though they are shared) | ||
// since slashing is done by the coordinator chain. | ||
// Operators should refer to the genesis file of the subscriber chain to | ||
// check their comfort with these values before onboarding the chain. | ||
|
||
// slash_fraction_downtime is the fraction of the stake that is slashed when a | ||
// validator is found to be offline. | ||
string slash_fraction_downtime = 15; | ||
// downtime_jail_duration is the duration of the jail period for a validator | ||
// after they have been found to be offline for too long. | ||
google.protobuf.Duration downtime_jail_duration = 16 | ||
[(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true]; | ||
// slash_fraction_double_sign is the fraction of the stake that is slashed | ||
// when a validator is found to have double signed. | ||
string slash_fraction_double_sign = 17; | ||
} | ||
|
||
// SubscriberGenesisState is the genesis state of a subscriber at the time of | ||
// it being provisioned by Exocore, as stored in the coordinator module. | ||
message SubscriberGenesisState { | ||
// params is the parameters of the subscriber module, as generated. | ||
SubscriberParams params = 1 [(gogoproto.nullable) = false]; | ||
// coordinator is the coordinator information for the subscriber. | ||
CoordinatorInfo coordinator = 2 [ (gogoproto.nullable) = false ]; | ||
} | ||
|
||
// CoordinatorInfo is the information about the coordinator chain that is | ||
// stored within the subscriber chain's subscriber module. | ||
message CoordinatorInfo { | ||
// client_state is the client state of the coordinator chain. | ||
ibc.lightclients.tendermint.v1.ClientState client_state = 1; | ||
// consensus_state is the consensus state of the coordinator chain. | ||
ibc.lightclients.tendermint.v1.ConsensusState consensus_state = 2; | ||
// initial_val_set is the initial validator set of the coordinator chain. | ||
repeated .tendermint.abci.ValidatorUpdate initial_val_set = 3 | ||
[ (gogoproto.nullable) = 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,23 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.coordinator.v1; | ||
|
||
import "exocore/appchain/coordinator/v1/tx.proto"; | ||
import "gogoproto/gogo.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; | ||
|
||
// PendingSubscriberChainRequests is a helper structure to store a list of | ||
// subscriber chain requests that are pending activation. | ||
message PendingSubscriberChainRequests { | ||
// list is the list of subscriber chain requests that are pending activation. | ||
repeated .exocore.appchain.coordinator.v1.RegisterSubscriberChainRequest list = 1 | ||
[(gogoproto.nullable) = false]; | ||
} | ||
|
||
// ChainIDs is a helper structure to store a list of chain IDs. | ||
message ChainIDs { | ||
// list is the list of chain IDs. | ||
repeated string list = 1; | ||
} | ||
|
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,14 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.coordinator.v1; | ||
|
||
import "exocore/appchain/coordinator/v1/params.proto"; | ||
import "gogoproto/gogo.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; | ||
|
||
// GenesisState is the genesis state for the appchain coordinator module. | ||
message GenesisState { | ||
// Params is the parameters for the appchain coordinator module. | ||
Params params = 1 [(gogoproto.nullable) = 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,34 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.coordinator.v1; | ||
|
||
import "exocore/epochs/v1/epochs.proto"; | ||
import "gogoproto/gogo.proto"; | ||
import "google/protobuf/duration.proto"; | ||
import "ibc/lightclients/tendermint/v1/tendermint.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; | ||
|
||
// Params is the parameters for the appchain coordinator module. | ||
message Params { | ||
// template_client is the IBC template client. | ||
ibc.lightclients.tendermint.v1.ClientState template_client = 1; | ||
// trusting_period_fraction is the multiplier applied on the subscriber's | ||
// unbonding duration to determine the IBC trusting period. | ||
string trusting_period_fraction = 2; | ||
// ibc_timeout_period is the timeout period for IBC packets. While our | ||
// system is largely created with epochs as a unit of time (and not | ||
// standard durations), this is an exception since it is used directly | ||
// by the IBC codebase. | ||
google.protobuf.Duration ibc_timeout_period = 3 | ||
[ (gogoproto.nullable) = false, (gogoproto.stdduration) = true, | ||
(gogoproto.customname) = "IBCTimeoutPeriod" ]; | ||
// init_timeout_period is the period within which the subscriber chain | ||
// must make a connection with the coordinator, after being spawned. | ||
exocore.epochs.v1.Epoch init_timeout_period = 4 | ||
[ (gogoproto.nullable) = false ]; | ||
// vsc_timeout_period is the period within which the subscriber chain | ||
// must respond to a VSC request, after it is sent. | ||
exocore.epochs.v1.Epoch vsc_timeout_period = 5 | ||
[ (gogoproto.nullable) = false, (gogoproto.customname) = "VSCTimeoutPeriod" ]; | ||
} |
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,49 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.coordinator.v1; | ||
|
||
import "exocore/appchain/common/v1/common.proto"; | ||
import "exocore/appchain/coordinator/v1/params.proto"; | ||
import "gogoproto/gogo.proto"; | ||
import "google/api/annotations.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; | ||
|
||
// Query defines the gRPC querier service. | ||
service Query { | ||
// QueryParams returns the appchain coordinator module parameters. | ||
rpc QueryParams(QueryParamsRequest) returns (QueryParamsResponse) { | ||
option (google.api.http) = { | ||
get: "/appchain/coordinator/params" | ||
}; | ||
} | ||
// QuerySubscriberGenesis returns the genesis state for a subscriber chain. | ||
rpc QuerySubscriberGenesis(QuerySubscriberGenesisRequest) returns (QuerySubscriberGenesisResponse) { | ||
option (google.api.http) = { | ||
get: "/exocore/appchain/coordinator/v1/subscriber_genesis/{chain}" | ||
}; | ||
} | ||
} | ||
|
||
// QueryParamsRequest is the request type for the Query.QueryParams RPC method. | ||
message QueryParamsRequest {} | ||
|
||
// QueryParamsResponse is the response type for the Query.QueryParams RPC method. | ||
message QueryParamsResponse { | ||
// params is the parameters for the appchain coordinator module. | ||
Params params = 1 [(gogoproto.nullable) = false]; | ||
} | ||
|
||
// QuerySubscriberGenesisRequest is the request type for the Query.QuerySubscriberGenesis RPC method. | ||
message QuerySubscriberGenesisRequest { | ||
// chain is the chain ID of the subscriber chain. we intentionally don't use ChainID so that | ||
// the query can work (it does not support custom names). | ||
string chain = 1; | ||
} | ||
|
||
// QuerySubscriberGenesisResponse is the response type for the Query.QuerySubscriberGenesis RPC method. | ||
message QuerySubscriberGenesisResponse { | ||
// subscriber_genesis is the genesis state for the subscriber chain. | ||
exocore.appchain.common.v1.SubscriberGenesisState subscriber_genesis = 1 | ||
[ (gogoproto.nullable) = 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,57 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.coordinator.v1; | ||
|
||
import "cosmos/msg/v1/msg.proto"; | ||
import "cosmos_proto/cosmos.proto"; | ||
import "exocore/appchain/common/v1/common.proto"; | ||
import "gogoproto/gogo.proto"; | ||
import "google/api/annotations.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/coordinator/types"; | ||
|
||
// Msg defines the Msg service. | ||
service Msg { | ||
option (cosmos.msg.v1.service) = true; | ||
// RegisterSubscriberChain registers a subscriber chain with the coordinator. | ||
// By default, it is activated at the next epoch. | ||
rpc RegisterSubscriberChain( | ||
RegisterSubscriberChainRequest | ||
) returns (RegisterSubscriberChainResponse) { | ||
option (google.api.http).post = "/exocore/appchain/coordinator/v1/tx/RegisterSubscriberChain"; | ||
} | ||
} | ||
|
||
// RegisterSubscriberChainRequest is the request type for the | ||
// RegisterSubscriberChain message. | ||
message RegisterSubscriberChainRequest { | ||
option (cosmos.msg.v1.signer) = "FromAddress"; | ||
// from_address is the address of the transaction signer. any transactions | ||
// originating from this address may be used to edit the chain. at some point | ||
// in the future this will be offloaded to the governance module on the | ||
// subscriber chain. (TODO) | ||
string from_address = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; | ||
// chain_id is the unique identifier for the chain, serving as the primary key. | ||
string chain_id = 2 [(gogoproto.customname) = "ChainID"]; | ||
// epoch_identifier specifies the unit of epoch (week, hour, day). It must be | ||
// registered in the x/epochs module. | ||
// This epoch is the identifier used by the coordinator to send validator set | ||
// updates to the subscriber at the end of each epoch. The subscriber chain's | ||
// genesis is made available at the end of the current epoch | ||
// (marked by this identifier). | ||
string epoch_identifier = 3; | ||
// asset_ids lists the IDs of assets accepted by the subscriber chain. | ||
repeated string asset_ids = 4 [(gogoproto.customname) = "AssetIDs"]; | ||
// min_self_delegation_usd is the minimum self-delegation in USD required to | ||
// be a validator on the chain. | ||
uint64 min_self_delegation_usd = 5; | ||
// max_validators is the maximum number of validators allowed on the chain. | ||
uint32 max_validators = 6; | ||
// subscriber_params are the parameters used by the subscriber module | ||
// on the subscriber chain. | ||
exocore.appchain.common.v1.SubscriberParams subscriber_params = 7 [(gogoproto.nullable) = false]; | ||
} | ||
|
||
// RegisterSubscriberChainResponse defines the response structure for executing a | ||
// RegisterSubscriberChain message. | ||
message RegisterSubscriberChainResponse {} |
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,14 @@ | ||
syntax = "proto3"; | ||
|
||
package exocore.appchain.subscriber.v1; | ||
|
||
import "exocore/appchain/common/v1/common.proto"; | ||
import "gogoproto/gogo.proto"; | ||
|
||
option go_package = "github.com/ExocoreNetwork/exocore/x/appchain/subscriber/types"; | ||
|
||
// GenesisState is the genesis state for the appchain subscriber module. | ||
message GenesisState { | ||
// Params is the parameters for the appchain subscriber module. | ||
exocore.appchain.common.v1.SubscriberParams params = 1 [(gogoproto.nullable) = false]; | ||
} |
Oops, something went wrong.