-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
009e2d3
commit 65819f0
Showing
11 changed files
with
509 additions
and
393 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package e2e | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"text/template" | ||
"time" | ||
|
||
"github.com/cometbft/cometbft/libs/cli" | ||
"github.com/cosmos/cosmos-sdk/codec/types" | ||
"github.com/cosmos/cosmos-sdk/types/tx" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
// updateParamsTxJSONTemplate is a text template for a tx JSON file which is | ||
// intended to be used with the `authz exec` CLI subcommand: `poktrolld tx authz exec <tx_json_file>`. | ||
var updateParamsTxJSONTemplate = template.Must( | ||
template.New("txJSON").Parse(`{ "body": {{.}} }`), | ||
) | ||
|
||
// sendAuthzExecTx sends an authz exec tx using the `authz exec` CLI subcommand: | ||
// `poktrolld tx authz exec <tx_json_file>`. | ||
// 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) { | ||
argsAndFlags := []string{ | ||
"tx", "authz", "exec", | ||
txJSONFilePath, | ||
"--from", s.granteeName, | ||
keyRingFlag, | ||
fmt.Sprintf("--%s=json", cli.OutputFlag), | ||
"--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 tx to be committed...", txDelaySeconds) | ||
time.Sleep(txDelaySeconds * time.Second) | ||
|
||
// Reset all module params to their default values after the test completes. | ||
s.once.Do(func() { | ||
s.Cleanup(func() { s.resetAllModuleParamsToDefaults() }) | ||
}) | ||
} | ||
|
||
// newTempTxJSONFile creates a new temp file with the JSON representation of a tx | ||
// which contains a MsgUpdateParams for each module and paramsMap in the given moduleParamsMap. | ||
// It is intended for use with the `authz exec` CLI subcommand: `poktrolld tx authz exec <tx_json_file>`. | ||
// It returns the file path. | ||
func (s *suite) newTempUpdateParamsTxJSONFile(moduleParamsMap moduleParamsMap) *os.File { | ||
var anyMsgs []*types.Any | ||
|
||
for moduleName, paramsMap := range moduleParamsMap { | ||
// Convert the params map to a MsgUpdateParams message. | ||
msg := s.paramsMapToMsgUpdateParams(moduleName, paramsMap) | ||
|
||
// Convert the MsgUpdateParams message to a pb.Any message. | ||
anyMsg, err := types.NewAnyWithValue(msg) | ||
require.NoError(s, err) | ||
|
||
anyMsgs = append(anyMsgs, anyMsg) | ||
} | ||
|
||
return s.newTempTxJSONFile(anyMsgs) | ||
} | ||
|
||
// newTempUpdateParamTxJSONFile creates a new temp file with the JSON representation of a tx, | ||
// intended for use with the `authz exec` CLI subcommand: `poktrolld tx authz exec <tx_json_file>`. | ||
// It returns the file path. | ||
func (s *suite) newTempUpdateParamTxJSONFile(moduleParams moduleParamsMap) *os.File { | ||
var anyMsgs []*types.Any | ||
|
||
for moduleName, paramsMap := range moduleParams { | ||
for _, param := range paramsMap { | ||
// Convert the params map to a MsgUpdateParams message. | ||
msg := s.newMsgUpdateParam(moduleName, param) | ||
|
||
// Convert the MsgUpdateParams message to a pb.Any message. | ||
anyMsg, err := types.NewAnyWithValue(msg) | ||
require.NoError(s, err) | ||
|
||
anyMsgs = append(anyMsgs, anyMsg) | ||
} | ||
} | ||
|
||
return s.newTempTxJSONFile(anyMsgs) | ||
} | ||
|
||
// newTempTxJSONFile creates & returns a new temp file with the JSON representation | ||
// 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 { | ||
// Construct a TxBody with the pb.Any message for serialization. | ||
txBody := &tx.TxBody{ | ||
Messages: anyMsgs, | ||
} | ||
|
||
// Serialize txBody to JSON for interpolation into the tx JSON template. | ||
txBodyJSON, err := s.cdc.MarshalJSON(txBody) | ||
require.NoError(s, err) | ||
|
||
// Create a temporary file to write the interpolated tx JSON. | ||
tempFile, err := os.CreateTemp("", "exec.json") | ||
require.NoError(s, err) | ||
|
||
defer func(f *os.File) { | ||
_ = f.Close() | ||
}(tempFile) | ||
|
||
// Remove tempFile when the test completes. | ||
s.Cleanup(func() { | ||
_ = os.Remove(tempFile.Name()) | ||
}) | ||
|
||
// Interpolate txBodyJSON into the tx JSON template. | ||
err = updateParamsTxJSONTemplate.Execute(tempFile, string(txBodyJSON)) | ||
require.NoError(s, err) | ||
|
||
return tempFile | ||
} |
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,41 @@ | ||
package e2e | ||
|
||
const ( | ||
computeUnitsToTokensMultipler = "compute_units_to_tokens_multiplier" | ||
minRelayDifficultyBits = "min_relay_difficulty_bits" | ||
) | ||
|
||
type ( | ||
// moduleNameKey is the key for a module name in the module params map. | ||
moduleNameKey = string | ||
// paramNameKey is the key for a param name in the params map. | ||
paramNameKey = string | ||
) | ||
|
||
// paramsMap is a map of param names to param values. | ||
type paramsMap map[paramNameKey]paramAny | ||
|
||
// moduleParamsMap is a map of module names to params maps. | ||
type moduleParamsMap map[moduleNameKey]paramsMap | ||
|
||
// paramAny is a struct that holds a param type and a param value. | ||
type paramAny struct { | ||
name string | ||
typeStr string | ||
value any | ||
} | ||
|
||
// authzCLIGrantResponse is the JSON response struct for the authz grants query | ||
// CLI subcommand: `poktrolld query authz grants <granter_addr> <grantee_addr>`. | ||
// NB: `authz.QueryGrantsResponse` is not used because it seems to be incompatible | ||
// with the JSON response format of the authz CLI query subcommand. | ||
type authzCLIGrantResponse struct { | ||
Grants []struct { | ||
Authorization struct { | ||
Type string `json:"type"` | ||
Value struct { | ||
Msg string `json:"msg"` | ||
} `json:"value"` | ||
} `json:"authorization"` | ||
} `json:"grants"` | ||
} |
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,177 @@ | ||
package e2e | ||
|
||
import ( | ||
"fmt" | ||
|
||
cosmostypes "github.com/cosmos/cosmos-sdk/types" | ||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||
"github.com/cosmos/gogoproto/proto" | ||
"github.com/regen-network/gocuke" | ||
|
||
prooftypes "github.com/pokt-network/poktroll/x/proof/types" | ||
tokenomicstypes "github.com/pokt-network/poktroll/x/tokenomics/types" | ||
) | ||
|
||
const ( | ||
paramNameColIdx = iota | ||
paramValueColIdx | ||
paramTypeColIdx | ||
) | ||
|
||
// parseParamsTable parses a gocuke.DataTable into a paramsMap. | ||
func (s *suite) parseParamsTable(table gocuke.DataTable) paramsMap { | ||
paramsMap := make(paramsMap) | ||
|
||
// NB: skip the header row. | ||
for rowIdx := 1; rowIdx < table.NumRows(); rowIdx++ { | ||
param := s.parseParam(table, rowIdx) | ||
paramsMap[param.name] = param | ||
} | ||
|
||
return 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 { | ||
var paramValue any | ||
paramName := table.Cell(rowIdx, paramNameColIdx).String() | ||
paramType := table.Cell(rowIdx, paramTypeColIdx).String() | ||
|
||
switch paramType { | ||
case "string": | ||
paramValue = table.Cell(rowIdx, paramValueColIdx).String() | ||
case "int64": | ||
paramValue = table.Cell(rowIdx, paramValueColIdx).Int64() | ||
case "bytes": | ||
paramValue = []byte(table.Cell(rowIdx, paramValueColIdx).String()) | ||
default: | ||
s.Fatalf("unexpected param type %q", paramType) | ||
} | ||
|
||
return paramAny{ | ||
name: paramName, | ||
typeStr: paramType, | ||
value: paramValue, | ||
} | ||
} | ||
|
||
// 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) (msg cosmostypes.Msg) { | ||
authority := authtypes.NewModuleAddress(s.granterName).String() | ||
|
||
switch moduleName { | ||
case tokenomicstypes.ModuleName: | ||
msgUpdateParams := &tokenomicstypes.MsgUpdateParams{ | ||
Authority: authority, | ||
Params: tokenomicstypes.Params{}, | ||
} | ||
|
||
for paramName, paramValue := range paramsMap { | ||
switch paramName { | ||
case "compute_units_to_tokens_multiplier": | ||
msgUpdateParams.Params.ComputeUnitsToTokensMultiplier = uint64(paramValue.value.(int64)) | ||
default: | ||
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName) | ||
} | ||
} | ||
msg = proto.Message(msgUpdateParams) | ||
|
||
case prooftypes.ModuleName: | ||
msgUpdateParams := &prooftypes.MsgUpdateParams{ | ||
Authority: authority, | ||
Params: prooftypes.Params{}, | ||
} | ||
|
||
for paramName, paramValue := range paramsMap { | ||
s.Logf("paramName: %s, value: %v", paramName, paramValue.value) | ||
switch paramName { | ||
case "min_relay_difficulty_bits": | ||
msgUpdateParams.Params.MinRelayDifficultyBits = uint64(paramValue.value.(int64)) | ||
default: | ||
s.Fatalf("unexpected %q type param name %q", paramValue.typeStr, paramName) | ||
} | ||
} | ||
msg = proto.Message(msgUpdateParams) | ||
|
||
default: | ||
err := fmt.Errorf("unexpected module name %q", moduleName) | ||
s.Fatal(err) | ||
panic(err) | ||
} | ||
|
||
return msg | ||
} | ||
|
||
// newMsgUpdateParam returns a MsgUpdateParam for the given module name, param name, | ||
// and param type/value. | ||
func (s *suite) newMsgUpdateParam( | ||
moduleName string, | ||
param paramAny, | ||
) (msg cosmostypes.Msg) { | ||
authority := authtypes.NewModuleAddress(s.granterName).String() | ||
|
||
// TODO_IMPROVE: can this be simplified? | ||
switch moduleName { | ||
case tokenomicstypes.ModuleName: | ||
switch param.typeStr { | ||
case "string": | ||
msg = proto.Message(&tokenomicstypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &tokenomicstypes.MsgUpdateParam_AsString{ | ||
AsString: param.value.(string), | ||
}, | ||
}) | ||
case "int64": | ||
msg = proto.Message(&tokenomicstypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &tokenomicstypes.MsgUpdateParam_AsInt64{ | ||
AsInt64: param.value.(int64), | ||
}, | ||
}) | ||
case "bytes": | ||
msg = proto.Message(&tokenomicstypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &tokenomicstypes.MsgUpdateParam_AsBytes{ | ||
AsBytes: param.value.([]byte), | ||
}, | ||
}) | ||
} | ||
case prooftypes.ModuleName: | ||
switch param.typeStr { | ||
case "string": | ||
msg = proto.Message(&prooftypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &prooftypes.MsgUpdateParam_AsString{ | ||
AsString: param.value.(string), | ||
}, | ||
}) | ||
case "int64": | ||
msg = proto.Message(&prooftypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &prooftypes.MsgUpdateParam_AsInt64{ | ||
AsInt64: param.value.(int64), | ||
}, | ||
}) | ||
case "bytes": | ||
msg = proto.Message(&prooftypes.MsgUpdateParam{ | ||
Authority: authority, | ||
Name: param.name, | ||
AsType: &prooftypes.MsgUpdateParam_AsBytes{ | ||
AsBytes: param.value.([]byte), | ||
}, | ||
}) | ||
} | ||
default: | ||
err := fmt.Errorf("unexpected module name %q", moduleName) | ||
s.Fatal(err) | ||
panic(err) | ||
} | ||
|
||
return msg | ||
} |
Oops, something went wrong.