Skip to content

Commit

Permalink
chore: review improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanchriswhite committed May 13, 2024
1 parent f31b645 commit c0dea35
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 16 deletions.
54 changes: 54 additions & 0 deletions e2e/tests/params_keys_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//go:build e2e

package e2e

import (
"fmt"
"strings"

"github.com/stretchr/testify/require"
)

// keyExistsInKeyring checks if a key with the given name exists in the keyring
// using the `poktrolld keys show <key_name>` CLI subcommand.
func (s *suite) keyExistsInKeyring(keyName string) bool {
s.Helper()

// poktrolld keys show <key_name> --keyring-backend test
argsAndFlags := []string{
"keys",
"show",
keyName,
keyRingFlag,
}
res, err := s.pocketd.RunCommand(argsAndFlags...)
if err == nil {
// `keys show <key_name>` will not error if a key with the given name exists.
return true
}

keyNotExistErrFmt := "%s is not a valid name or address"
if strings.Contains(res.Stderr, fmt.Sprintf(keyNotExistErrFmt, keyName)) {
return false
}

// If the key doesn't exist & the error message is unexpected, fail the test.
s.Fatal(err)
return false
}

// addKeyToKeyring adds a new key, with the given name, to the keyring
// using the `poktrolld keys add <key_name>` CLI subcommand.
func (s *suite) addKeyToKeyring(keyName string) {
s.Helper()

// poktrolld keys add <key_name> --keyring-backend test
argsAndFlags := []string{
"keys",
"add",
keyName,
keyRingFlag,
}
_, err := s.pocketd.RunCommand(argsAndFlags...)
require.NoError(s, err)
}
14 changes: 11 additions & 3 deletions e2e/tests/params_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ var updateParamsTxJSONTemplate = template.Must(
// It returns before the tx has been committed but after it has been broadcast.
// It ensures that all module params are reset to their default values after the
// test completes.
func (s *suite) sendAuthzExecTx(txJSONFilePath string) {
func (s *suite) sendAuthzExecTx(signingKeyName, txJSONFilePath string) {
s.Helper()

argsAndFlags := []string{
"tx", "authz", "exec",
txJSONFilePath,
"--from", s.granteeName,
"--from", signingKeyName,
keyRingFlag,
fmt.Sprintf("--%s=json", cli.OutputFlag),
"--yes",
Expand All @@ -39,7 +41,7 @@ func (s *suite) sendAuthzExecTx(txJSONFilePath string) {

// TODO_IMPROVE: wait for the tx to be committed using an events query client
// instead of sleeping for a specific amount of time.
s.Logf("waiting %d seconds for the tx to be committed...", txDelaySeconds)
s.Logf("waiting %d seconds for the authz exec tx to be committed...", txDelaySeconds)
time.Sleep(txDelaySeconds * time.Second)

// Reset all module params to their default values after the test completes.
Expand All @@ -53,6 +55,8 @@ func (s *suite) sendAuthzExecTx(txJSONFilePath string) {
// in the given moduleParamsMap. The returned file is intended for use with the `authz exec` CLI
// subcommand: `poktrolld tx authz exec <tx_json_file>`.
func (s *suite) newTempUpdateParamsTxJSONFile(moduleParams moduleParamsMap) *os.File {
s.Helper()

var anyMsgs []*types.Any

// Collect msgs to update all params (per msg) for each module.
Expand All @@ -76,6 +80,8 @@ func (s *suite) newTempUpdateParamsTxJSONFile(moduleParams moduleParamsMap) *os.
// given moduleParamsMap. The returned file is intended for use with the `authz exec` CLI subcommand:
// `poktrolld tx authz exec <tx_json_file>`.
func (s *suite) newTempUpdateParamTxJSONFile(moduleParams moduleParamsMap) *os.File {
s.Helper()

var anyMsgs []*types.Any

// Collect msgs to update given params, one param per msg, for each module.
Expand All @@ -100,6 +106,8 @@ func (s *suite) newTempUpdateParamTxJSONFile(moduleParams moduleParamsMap) *os.F
// of a tx which contains the given pb.Any messages. The temp file is removed when
// the test completes.
func (s *suite) newTempTxJSONFile(anyMsgs []*types.Any) *os.File {
s.Helper()

// Construct a TxBody with the pb.Any message for serialization.
txBody := &tx.TxBody{
Messages: anyMsgs,
Expand Down
8 changes: 8 additions & 0 deletions e2e/tests/parse_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const (

// parseParamsTable parses a gocuke.DataTable into a paramsMap.
func (s *suite) parseParamsTable(table gocuke.DataTable) paramsMap {
s.Helper()

paramsMap := make(paramsMap)

// NB: skip the header row.
Expand All @@ -35,6 +37,8 @@ func (s *suite) parseParamsTable(table gocuke.DataTable) paramsMap {

// parseParam parses a row of a gocuke.DataTable into a paramName and a paramAny.
func (s *suite) parseParam(table gocuke.DataTable, rowIdx int) paramAny {
s.Helper()

var paramValue any
paramName := table.Cell(rowIdx, paramNameColIdx).String()
paramType := table.Cell(rowIdx, paramTypeColIdx).String()
Expand All @@ -60,6 +64,8 @@ func (s *suite) parseParam(table gocuke.DataTable, rowIdx int) paramAny {
// paramsMapToMsgUpdateParams converts a paramsMap into a MsgUpdateParams, which
// it returns as a proto.Message/cosmostypes.Msg interface type.
func (s *suite) paramsMapToMsgUpdateParams(moduleName string, paramsMap paramsMap) (msgUpdateParams cosmostypes.Msg) {
s.Helper()

switch moduleName {
case tokenomicstypes.ModuleName:
msgUpdateParams = s.newTokenomicsMsgUpdateParams(paramsMap)
Expand Down Expand Up @@ -119,6 +125,8 @@ func (s *suite) newMsgUpdateParam(
moduleName string,
param paramAny,
) (msg cosmostypes.Msg) {
s.Helper()

authority := authtypes.NewModuleAddress(s.granterName).String()

// TODO_IMPROVE: can this be simplified?
Expand Down
8 changes: 7 additions & 1 deletion e2e/tests/reset_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ import (
// resetAllModuleParamsToDefaults resets all module params to their default values using
// a single authz exec message. It blocks until the resulting tx has been committed.
func (s *suite) resetAllModuleParamsToDefaults() {
s.Helper()

s.Log("resetting all module params to their default values")

msgUpdateParamsAnys := s.allModulesMsgUpdateParamsToDefaultsAny()
resetTxJSONFile := s.newTempTxJSONFile(msgUpdateParamsAnys)
s.sendAuthzExecTx(resetTxJSONFile.Name())
s.sendAuthzExecTx(s.granteeName, resetTxJSONFile.Name())
}

// allMoudlesMsgUpdateParamsToDefaultsAny returns a slice of Any messages, each corresponding
// to a MsgUpdateParams for a module, populated with the respective default values.
func (s *suite) allModulesMsgUpdateParamsToDefaultsAny() []*codectypes.Any {
s.Helper()

return []*codectypes.Any{
s.msgUpdateParamsToDefaultsAny(gatewaytypes.ModuleName),
s.msgUpdateParamsToDefaultsAny(apptypes.ModuleName),
Expand All @@ -39,6 +43,8 @@ func (s *suite) allModulesMsgUpdateParamsToDefaultsAny() []*codectypes.Any {
// msgUpdateParamsToDefaultsAny returns an Any corresponding to a MsgUpdateParams
// for the given module name, populated with the respective default values.
func (s *suite) msgUpdateParamsToDefaultsAny(moduleName string) *codectypes.Any {
s.Helper()

var (
anyMsg *codectypes.Any
err error
Expand Down
27 changes: 22 additions & 5 deletions e2e/tests/update_params.feature
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
Feature: Params Namespace
# TODO_DOCUMENT(@Olshansk): Document all of the on-chain governance parameters.

# TODO_TEST_IN_THIS_PR:
# Scenario: An unauthorized user cannot update an module params
Scenario: An unauthorized user cannot update an module params
Given the user has the pocketd binary installed
And all "tokenomics" module params are set to their default values
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.tokenomics.MsgUpdateParams" message
And a key and account exist for the "unauthorized" user
When the "unauthorized" account sends an authz exec message to update all "tokenomics" module params
| name | value | type |
| compute_units_to_tokens_multiplier | 666 | int64 |
Then all "tokenomics" module params should be set to their default values

# NB: If you are reading this and the tokenomics module has parameters
# that are not being updated in this test, please update the test.
Scenario: An authorized user updates all "tokenomics" module params
Given the user has the pocketd binary installed
And all "tokenomics" module params are set to their default values
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.tokenomics.MsgUpdateParams" message
When the user sends an authz exec message to update all "tokenomics" module params
When the "pnf" account sends an authz exec message to update all "tokenomics" module params
| name | value | type |
| compute_units_to_tokens_multiplier | 420 | int64 |
Then all "tokenomics" module params should be updated
Expand All @@ -21,7 +28,7 @@ Feature: Params Namespace
Given the user has the pocketd binary installed
And all "proof" module params are set to their default values
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.proof.MsgUpdateParams" message
When the user sends an authz exec message to update all "proof" module params
When the "pnf" account sends an authz exec message to update all "proof" module params
| name | value | type |
| min_relay_difficulty_bits | 8 | int64 |
Then all "proof" module params should be updated
Expand All @@ -32,7 +39,7 @@ Feature: Params Namespace
Given the user has the pocketd binary installed
And all "<module>" module params are set to their default values
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "<message_type>" message
When the user sends an authz exec message to update "<module>" the module param
When the "pnf" account sends an authz exec message to update "<module>" the module param
| name | value | type |
| <param_name> | <param_value> | <param_type> |
Then the "<module>" module param "<param_name>" should be updated
Expand All @@ -41,3 +48,13 @@ Feature: Params Namespace
| module | message_type | param_name | param_value | param_type |
| tokenomics | /poktroll.tokenomics.MsgUpdateParam | compute_units_to_tokens_multiplier | 68 | int64 |
| proof | /poktroll.proof.MsgUpdateParam | min_relay_difficulty_bits | 12 | int64 |

Scenario: An authorized user updates individual module params
Given the user has the pocketd binary installed
And all "proof" module params are set to their default values
And an authz grant from the "gov" "module" account to the "pnf" "user" account for the "/poktroll.proof.MsgUpdateParams" message
And a key and account exist for the "unauthorized" user
When the "unauthorized" account sends an authz exec message to update "proof" the module param
| name | value | type |
| "min_relay_difficulty_bits | 666 | int64 |
Then the "proof" module param "min_relay_difficulty_bits" should be set to its default value
85 changes: 78 additions & 7 deletions e2e/tests/update_params_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"reflect"
"strings"
"time"

cometcli "github.com/cometbft/cometbft/libs/cli"
cosmostypes "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -19,7 +20,10 @@ import (
)

// txDelaySeconds is the number of seconds to wait for a tx to be committed before making assertions.
const txDelaySeconds = 3
const (
txDelaySeconds = 3
minimalFundTokens = "1000000upokt"
)

// AllModuleParamsAreSetToTheirDefaultValues asserts that all module params are set to their default values.
func (s *suite) AllModuleParamsAreSetToTheirDefaultValues(moduleName string) {
Expand Down Expand Up @@ -113,9 +117,24 @@ func (s *suite) AnAuthzGrantFromTheAccountToTheAccountForTheMessage(
s.granteeName = granteeName
}

// TheUserSendsAnAuthzExecMessageToUpdateAllModuleParams sends an authz exec
// AKeyAndAccountExistForTheUser checks if a key with the given name exists in the keyring,
// and if not, adds a new key with the given name to the keyring. It then checks if an account
func (s *suite) AKeyAndAccountExistForTheUser(keyName string) {
if !s.keyExistsInKeyring(keyName) {
s.addKeyToKeyring(keyName)
}

s.ensureAccountForKeyName(keyName)
}

// AllModuleParamsShouldBeSetToTheirDefaultValues asserts that all module params are set to their default values.
func (s *suite) AllModuleParamsShouldBeSetToTheirDefaultValues(moduleName string) {
s.AllModuleParamsAreSetToTheirDefaultValues(moduleName)
}

// TheAccountSendsAnAuthzExecMessageToUpdateAllModuleParams sends an authz exec
// message to update all module params for the given module.
func (s *suite) TheUserSendsAnAuthzExecMessageToUpdateAllModuleParams(moduleName string, table gocuke.DataTable) {
func (s *suite) TheAccountSendsAnAuthzExecMessageToUpdateAllModuleParams(accountName, moduleName string, table gocuke.DataTable) {
// NB: set s#moduleParamsMap for later assertion.
s.expectedModuleParams = moduleParamsMap{
moduleName: s.parseParamsTable(table),
Expand All @@ -125,7 +144,7 @@ func (s *suite) TheUserSendsAnAuthzExecMessageToUpdateAllModuleParams(moduleName
txJSONFile := s.newTempUpdateParamsTxJSONFile(s.expectedModuleParams)

// Send the authz exec tx to update all module params.
s.sendAuthzExecTx(txJSONFile.Name())
s.sendAuthzExecTx(accountName, txJSONFile.Name())
}

// AllModuleParamsShouldBeUpdated asserts that all module params have been updated as expected.
Expand All @@ -136,8 +155,8 @@ func (s *suite) AllModuleParamsShouldBeUpdated(moduleName string) {
s.assertExpectedModuleParamsUpdated(moduleName)
}

// TheUserSendAnAuthzExecMessageToUpdateTheModuleParam sends an authz exec message to update a single module param.
func (s *suite) TheUserSendsAnAuthzExecMessageToUpdateTheModuleParam(moduleName string, table gocuke.DataTable) {
// TheAccountSendsAnAuthzExecMessageToUpdateTheModuleParam sends an authz exec message to update a single module param.
func (s *suite) TheAccountSendsAnAuthzExecMessageToUpdateTheModuleParam(accountName, moduleName string, table gocuke.DataTable) {
// NB: skip the header row & only expect a single row.
param := s.parseParam(table, 1)

Expand All @@ -152,7 +171,7 @@ func (s *suite) TheUserSendsAnAuthzExecMessageToUpdateTheModuleParam(moduleName
txJSONFile := s.newTempUpdateParamTxJSONFile(s.expectedModuleParams)

// Send the authz exec tx to update the module param.
s.sendAuthzExecTx(txJSONFile.Name())
s.sendAuthzExecTx(accountName, txJSONFile.Name())
}

// TheModuleParamShouldBeUpdated asserts that the module param has been updated as expected.
Expand All @@ -172,8 +191,56 @@ func (s *suite) TheModuleParamShouldBeUpdated(moduleName, paramName string) {
s.assertExpectedModuleParamsUpdated(moduleName)
}

// TheModuleParamShouldBeSetToItsDefaultValue asserts that the given param for the
// given module has been set to its default value.
func (s *suite) TheModuleParamShouldBeSetToItsDefaultValue(moduleName string, paramName string) {
// TODO_HACK: So long as no other modules are expected to have been changed by this scenario,
// it is more than sufficient (and less code) to re-use the existing step which asserts that
// all modules have their params set to their respective defaults.
_ = paramName
s.AllModuleParamsShouldBeSetToTheirDefaultValues(moduleName)
}

// ensureAccountForKeyName ensures that an account exists for the given key name in the keychain.
func (s *suite) ensureAccountForKeyName(keyName string) {
s.Helper()

// Get the address of the key.
addr := s.getKeyAddress(keyName)

// Fund the account with minimal tokens to ensure it is on-chain.
s.ensureOnChainAccount(addr)
}

// ensureOnChainAccount sends a minimal amount of upokt tokens to the given address
// to ensure it has an on-chain account.
func (s *suite) ensureOnChainAccount(addr string) {
s.Helper()

// poktrolld tx bank send <from> <to> <amount> --keyring-backend test --chain-id <chain_id> --yes
argsAndFlags := []string{
"tx",
"bank",
"send",
"pnf",
addr,
minimalFundTokens,
"--yes",
}

_, err := s.pocketd.RunCommandOnHost("", argsAndFlags...)
require.NoError(s, err)

// TODO_IMPROVE: wait for the tx to be committed using an events query client
// instead of sleeping for a specific amount of time.
s.Logf("waiting %d seconds for the funding tx to be committed...", txDelaySeconds)
time.Sleep(txDelaySeconds * time.Second)
}

// getKeyAddress uses the `keys show` CLI subcommand to get the address of a key.
func (s *suite) getKeyAddress(keyName string) string {
s.Helper()

argsAndFlags := []string{
"keys",
"show",
Expand All @@ -192,6 +259,8 @@ func (s *suite) getKeyAddress(keyName string) string {
}

func (s *suite) assertExpectedModuleParamsUpdated(moduleName string) {
s.Helper()

argsAndFlags := []string{
"query",
moduleName,
Expand Down Expand Up @@ -234,6 +303,8 @@ func assertUpdatedParams[P cosmostypes.Msg](
queryParamsResJSON []byte,
expectedParamsRes P,
) {
s.Helper()

queryParamsMsgValue := reflect.New(reflect.TypeOf(expectedParamsRes).Elem())
queryParamsMsg := queryParamsMsgValue.Interface().(P)
err := s.cdc.UnmarshalJSON(queryParamsResJSON, queryParamsMsg)
Expand Down

0 comments on commit c0dea35

Please sign in to comment.