Skip to content

Commit

Permalink
feat(genesis export): genesis exporting for avs,distribution modules (#…
Browse files Browse the repository at this point in the history
…209)

* impl genesis exporting for avs,distribution

* fix dogfood initgenesis duplicate registration of avs

* add UT for exportGenesis

* fix validatorAddr in initGenesis of distribution module

* fix test err
  • Loading branch information
trestinlsd authored Nov 6, 2024
1 parent a361c1d commit b4a331e
Show file tree
Hide file tree
Showing 23 changed files with 3,499 additions and 287 deletions.
2 changes: 1 addition & 1 deletion precompiles/avs/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ func (p Precompile) OperatorSubmitTask(
BlsSignature: resultParams.BlsSignature,
Phase: phaseEnum,
}
err := p.avsKeeper.SetTaskResultInfo(ctx, resultParams.CallerAddress.String(), result)
err := p.avsKeeper.SubmitTaskResult(ctx, resultParams.CallerAddress.String(), result)
if err != nil {
return nil, err
}
Expand Down
61 changes: 61 additions & 0 deletions proto/exocore/avs/v1/genesis.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
syntax = "proto3";
package exocore.avs.v1;

import "exocore/avs/v1/tx.proto";
import "gogoproto/gogo.proto";

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

// GenesisState defines the avs module's state. It needs to encompass
// all of the state that is required to start the chain from the genesis
// or in the event of a restart.
message GenesisState {
// avs_infos is the list of registered avs infos,
// that are supported at chain genesis (or restart).
repeated AVSInfo avs_infos = 1 [(gogoproto.nullable) = false];
// task_infos is the tasks issued by avs owner, indexed by
// task address and task id
// that are supported at chain genesis (or restart).
repeated TaskInfo task_infos = 2 [(gogoproto.nullable) = false];
// bls_pub_keys is the list of operator pubKey info, indexed by operator address
// The struct is the `BlsPubKeyInfo`
// which contains blsPubKey, operator address.
repeated BlsPubKeyInfo bls_pub_keys = 3 [(gogoproto.nullable) = false];

// task_result_infos is the task result informations, indexed
// by the operator address ,task address and the task id. The struct is the `TaskResultInfo`
repeated TaskResultInfo task_result_infos = 4 [(gogoproto.nullable) = false];
// challenge_infos is the task challenge informations, indexed
// by the operator address ,task address and the task id. The struct is the `ChallengeInfo`
repeated ChallengeInfo challenge_infos = 5 [(gogoproto.nullable) = false];
// task_nums is the task id, indexed
// by the task address. The struct is the `TaskID`
repeated TaskID task_nums = 6 [(gogoproto.nullable) = false];
// chain_id_infos is the dogfood chain id informations, indexed
// by the avs address. The struct is the `ChainIDInfo`
repeated ChainIDInfo chain_id_infos = 7 [(gogoproto.nullable) = false];

}

// TaskID is helper structure to store the task id information for the genesis state.
message TaskID {
// task_addr is the address of task as a hex string
string task_addr = 1;
// id of task.
uint64 task_id = 2;
}
// ChallengeInfo is helper structure to store the task challenge information for the genesis state.
message ChallengeInfo {
// key is used for storing the ChallengeInfos,
// which is a combination of the operator address ,task address and task id.
string key = 1;
// challenge_addr is the address of the challenger
string challenge_addr = 2;
}
// ChainIDInfo is helper structure to store the dogfood ChainID information for the genesis state.
message ChainIDInfo {
// avs_address is the address of avs as a hex string.
string avs_address = 1;
// chain_id is an optional parameter to specify the chain_id of the AVS, if any
string chain_id = 2;
}
59 changes: 59 additions & 0 deletions proto/exocore/feedistribution/v1/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";
package exocore.feedistribution.v1;

import "amino/amino.proto";
import "exocore/feedistribution/v1/distribution.proto";
import "exocore/feedistribution/v1/params.proto";
import "gogoproto/gogo.proto";

Expand All @@ -14,4 +15,62 @@ message GenesisState {
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
// fee_pool is the global fee pool for distribution.
// It holds decimal coins. Once whole those coins can be burned or distributed to the community pool.
FeePool fee_pool = 2 [(gogoproto.nullable) = false];
// validator_accumulated_commissions represents accumulated commission
// for a validator kept as a running counter, can be withdrawn at any time.
repeated ValidatorAccumulatedCommissions validator_accumulated_commissions = 3 [(gogoproto.nullable) = false];
// validator_current_rewards_list represents current rewards and current
// period for a validator kept as a running counter and incremented
// each block as long as the validator's tokens remain constant.
repeated ValidatorCurrentRewardsList validator_current_rewards_list = 4 [(gogoproto.nullable) = false];

// validator_outstanding_rewards_list represents outstanding (un-withdrawn) rewards
// for a validator inexpensive to track, allows simple sanity checks.
repeated ValidatorOutstandingRewardsList validator_outstanding_rewards_list = 5 [(gogoproto.nullable) = false];
// staker_outstanding_rewards_list represents outstanding (un-withdrawn) rewards
// for a staker inexpensive to track, allows simple sanity checks.
repeated StakerOutstandingRewardsList staker_outstanding_rewards_list = 6 [(gogoproto.nullable) = false];

}

// ValidatorAccumulatedCommissions is helper structure to store
// the validator accumulated commissions for the genesis state.
message ValidatorAccumulatedCommissions {
// val_addr is the address of validator
string val_addr = 1;

// ValidatorAccumulatedCommission represents accumulated commission
// for a validator kept as a running counter, can be withdrawn at any time.
ValidatorAccumulatedCommission commission = 2;
}
// ValidatorCurrentRewardsList is helper structure to store the validator current rewards for the genesis state.
message ValidatorCurrentRewardsList {
// val_addr is the address of validator
string val_addr = 1;

// ValidatorCurrentRewards represents current rewards and current
// period for a validator kept as a running counter and incremented
// each block as long as the validator's tokens remain constant.
ValidatorCurrentRewards current_rewards = 2;
}
// ValidatorOutstandingRewardsList is a helper structure to store
// the validator outstanding rewards for the genesis state.
message ValidatorOutstandingRewardsList {
// val_addr is the address of validator
string val_addr = 1;

// ValidatorOutstandingRewards represents outstanding (un-withdrawn) rewards
// for a validator inexpensive to track, allows simple sanity checks.
ValidatorOutstandingRewards outstanding_rewards = 2;
}
// StakerOutstandingRewardsList is helper structure to store the staker outstanding rewards for the genesis state.
message StakerOutstandingRewardsList {
// staker_addr is the address of staker
string staker_addr = 1;

// StakerOutstandingRewards represents outstanding (un-withdrawn) rewards
// for a staker inexpensive to track, allows simple sanity checks.
StakerOutstandingRewards staker_outstanding_rewards = 2;
}
2 changes: 1 addition & 1 deletion x/avs/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func QuerySubmitTaskResult() *cobra.Command {
Use: "SubmitTaskResult <task-address-in-hex> <task-id> <operator-addreess>",
Short: "Query the SubmitTaskResult by taskAddr taskID operatorAddr",
Long: "Query the currently submitted Task Result",
Example: "exocored query avs ChallengeInfo 0x96949787E6a209AFb4dE035754F79DC9982D3F2a 2 exo1mq6pj6f5tafmgkk6lehew5radfq3w20gpegzs5",
Example: "exocored query avs SubmitTaskResult 0x96949787E6a209AFb4dE035754F79DC9982D3F2a 2 exo1mq6pj6f5tafmgkk6lehew5radfq3w20gpegzs5",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
if !common.IsHexAddress(args[0]) {
Expand Down
22 changes: 22 additions & 0 deletions x/avs/keeper/avs.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ func (k Keeper) RegisterAVSWithChainID(
}
avsAddrStr := types.GenerateAVSAddr(params.ChainID)
avsAddr = common.HexToAddress(avsAddrStr)
// check that the AVS is registered
if isAvs, _ := k.IsAVS(ctx, avsAddrStr); isAvs {
return avsAddr, nil
}
defer func() {
if err == nil {
// store the reverse lookup from AVSAddress to ChainID
Expand Down Expand Up @@ -194,3 +198,21 @@ func (k Keeper) GetChainIDByAVSAddr(ctx sdk.Context, avsAddr string) (string, bo
}
return string(bz), true
}

func (k *Keeper) GetAllChainIDInfos(ctx sdk.Context) ([]types.ChainIDInfo, error) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixAVSAddressToChainID)
iterator := sdk.KVStorePrefixIterator(store, nil)
defer iterator.Close()

ret := make([]types.ChainIDInfo, 0)
for ; iterator.Valid(); iterator.Next() {
avsAddr := strings.ToLower(common.BytesToAddress(iterator.Key()).Hex())
chainID := string(iterator.Value())

ret = append(ret, types.ChainIDInfo{
AvsAddress: avsAddr,
ChainId: chainID,
})
}
return ret, nil
}
99 changes: 89 additions & 10 deletions x/avs/keeper/genesis.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,104 @@
package keeper

import (
"strings"

errorsmod "cosmossdk.io/errors"
"github.com/ExocoreNetwork/exocore/x/avs/types"
abci "github.com/cometbft/cometbft/abci/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/common"
)

// InitGenesis initializes the module's state from a provided genesis state.
// Since this action typically occurs on chain starts, this function is allowed to panic.
func (k Keeper) InitGenesis(
ctx sdk.Context,
_ types.GenesisState,
) []abci.ValidatorUpdate {
func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) {
// Store a lookup from codeHash to code. Since these are static parameters,
// such a lookup is stored at genesis and never updated.
k.evmKeeper.SetCode(ctx, types.ChainIDCodeHash.Bytes(), types.ChainIDCode)
return []abci.ValidatorUpdate{}
// Set all the avs infos
for _, avs := range state.AvsInfos {
avs.AvsAddress = strings.ToLower(avs.AvsAddress)
avs.TaskAddr = strings.ToLower(avs.TaskAddr)
avs.RewardAddr = strings.ToLower(avs.RewardAddr)
avs.SlashAddr = strings.ToLower(avs.SlashAddr)
err := k.SetAVSInfo(ctx, &avs) //nolint:gosec
if err != nil {
panic(errorsmod.Wrap(err, "failed to set all avs info"))
}
}
// Set all the task infos
for _, elem := range state.TaskInfos {
elem.TaskContractAddress = strings.ToLower(elem.TaskContractAddress)
err := k.SetTaskInfo(ctx, &elem) //nolint:gosec
if err != nil {
panic(errorsmod.Wrap(err, "failed to set all task info"))
}
}
// Set all the bls infos
for _, elem := range state.BlsPubKeys {
err := k.SetOperatorPubKey(ctx, &elem) //nolint:gosec
if err != nil {
panic(errorsmod.Wrap(err, "failed to set all bls info"))
}
}
// Set all the taskNum infos
for _, elem := range state.TaskNums {
elem.TaskAddr = strings.ToLower(elem.TaskAddr)
k.SetTaskID(ctx, common.HexToAddress(elem.TaskAddr), elem.TaskId)
}
// Set all the task result infos
for _, elem := range state.TaskResultInfos {
elem.TaskContractAddress = strings.ToLower(elem.TaskContractAddress)
k.SetTaskResultInfo(ctx, &elem) //nolint:gosec
}
// Set all the task challenge infos
err := k.SetAllTaskChallengedInfo(ctx, state.ChallengeInfos)
if err != nil {
panic(errorsmod.Wrap(err, "failed to set all challenge info"))
}
// Set all the chainID infos
for _, elem := range state.ChainIdInfos {
elem.AvsAddress = strings.ToLower(elem.AvsAddress)
k.SetAVSAddrToChainID(ctx, common.HexToAddress(elem.AvsAddress), elem.ChainId)
}
}

// ExportGenesis returns the module's exported genesis
func (Keeper) ExportGenesis(sdk.Context) *types.GenesisState {
// TODO
return types.DefaultGenesis()
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
res := types.GenesisState{}
var err error
res.AvsInfos, err = k.GetAllAVSInfos(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all avs infos"))
}
res.TaskInfos, err = k.GetAllTaskInfos(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all task infos").Error())
}

res.BlsPubKeys, err = k.GetAllBlsPubKeys(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all bls key info").Error())
}

res.TaskNums, err = k.GetAllTaskNums(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all TaskNums").Error())
}

res.TaskResultInfos, err = k.GetAllTaskResultInfos(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all TaskResultInfos").Error())
}

res.ChallengeInfos, err = k.GetAllChallengeInfos(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all ChallengeInfos").Error())
}

res.ChainIdInfos, err = k.GetAllChainIDInfos(ctx)
if err != nil {
panic(errorsmod.Wrap(err, "failed to get all ChainIdInfos").Error())
}

return &res
}
Loading

0 comments on commit b4a331e

Please sign in to comment.