cosmos-sdk/tests/systemtests/circuit_test.go
Julien Robert ca48cef255
build(deps): bump cometbft to v1.0.0-rc2 (#22577)
Co-authored-by: marbar3778 <marbar3778@yahoo.com>
2024-11-28 11:33:27 +00:00

247 lines
6.7 KiB
Go

//go:build system_test
package systemtests
import (
"encoding/json"
"fmt"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"github.com/tidwall/gjson"
systest "cosmossdk.io/systemtests"
)
var someMsgs = []string{"/cosmos.bank.v1beta1.MsgSend", "/cosmos.bank.v1beta1.MsgMultiSend"}
func TestCircuitCommands(t *testing.T) {
// scenario: test circuit commands
// given a running chain
systest.Sut.ResetChain(t)
require.GreaterOrEqual(t, systest.Sut.NodesCount(), 2)
cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose)
// get validator addresses
superAdmin := cli.GetKeyAddr("node0")
require.NotEmpty(t, superAdmin)
superAdmin2 := cli.GetKeyAddr("node1")
require.NotEmpty(t, superAdmin2)
// short voting period
// update expedited voting period to avoid validation error
votingPeriod := 5 * time.Second
systest.Sut.ModifyGenesisJSON(
t,
systest.SetGovVotingPeriod(t, votingPeriod),
systest.SetGovExpeditedVotingPeriod(t, votingPeriod-time.Second),
)
systest.Sut.StartChain(t)
allMsgsAcc := cli.AddKey("allMsgsAcc")
require.NotEmpty(t, allMsgsAcc)
someMsgsAcc := cli.AddKey("someMsgsAcc")
require.NotEmpty(t, someMsgsAcc)
// fund tokens to new created addresses
var amount int64 = 100000
denom := "stake"
rsp := cli.FundAddress(allMsgsAcc, fmt.Sprintf("%d%s", amount, denom))
systest.RequireTxSuccess(t, rsp)
require.Equal(t, amount, cli.QueryBalance(allMsgsAcc, denom))
rsp = cli.FundAddress(someMsgsAcc, fmt.Sprintf("%d%s", amount, denom))
systest.RequireTxSuccess(t, rsp)
require.Equal(t, amount, cli.QueryBalance(someMsgsAcc, denom))
// query gov module account address
rsp = cli.CustomQuery("q", "auth", "module-account", "gov")
govModAddr := gjson.Get(rsp, "account.value.address")
// create a proposal to add super admin
validProposal := fmt.Sprintf(`
{
"messages": [
{
"@type": "/cosmos.circuit.v1.MsgAuthorizeCircuitBreaker",
"granter": "%s",
"grantee": "%s",
"permissions": {"level": 3, "limit_type_urls": []}
}
],
"title": "Params update proposal",
"deposit": "10000000stake",
"summary": "A short summary of my proposal"
}`, govModAddr, superAdmin)
proposalFile := systest.StoreTempFile(t, []byte(validProposal))
rsp = cli.RunAndWait("tx", "gov", "submit-proposal", proposalFile.Name(), "--from="+superAdmin)
systest.RequireTxSuccess(t, rsp)
// vote to proposal from two validators
rsp = cli.RunAndWait("tx", "gov", "vote", "1", "yes", "--from="+superAdmin)
systest.RequireTxSuccess(t, rsp)
rsp = cli.RunAndWait("tx", "gov", "vote", "1", "yes", "--from="+superAdmin2)
systest.RequireTxSuccess(t, rsp)
// wait for proposal to pass
require.Eventually(t, func() bool {
rsp = cli.CustomQuery("q", "circuit", "accounts")
level := gjson.Get(rsp, fmt.Sprintf("accounts.#(address==%s).permissions.level", superAdmin)).String()
return "LEVEL_SUPER_ADMIN" == level
}, votingPeriod+systest.Sut.BlockTime(), 200*time.Millisecond)
authorizeTestCases := []struct {
name string
address string
level int
limtTypeURLs []string
expPermission string
}{
{
"set new super admin",
superAdmin2,
3,
[]string{},
"LEVEL_SUPER_ADMIN",
},
{
"set all msgs level to address",
allMsgsAcc,
2,
[]string{},
"LEVEL_ALL_MSGS",
},
{
"set some msgs level to address",
someMsgsAcc,
1,
someMsgs,
"LEVEL_SOME_MSGS",
},
}
for _, tc := range authorizeTestCases {
t.Run(tc.name, func(t *testing.T) {
permissionJSON := fmt.Sprintf(`{"level":%d,"limit_type_urls":[]}`, tc.level)
if len(tc.limtTypeURLs) != 0 {
permissionJSON = fmt.Sprintf(`{"level":%d,"limit_type_urls":["%s"]}`, tc.level, strings.Join(tc.limtTypeURLs[:], `","`))
}
rsp = cli.RunAndWait("tx", "circuit", "authorize", tc.address, permissionJSON, "--from="+superAdmin)
systest.RequireTxSuccess(t, rsp)
// query account permissions
rsp = cli.CustomQuery("q", "circuit", "account", tc.address)
require.Equal(t, tc.expPermission, gjson.Get(rsp, "permission.level").String())
if len(tc.limtTypeURLs) != 0 {
listStr := gjson.Get(rsp, "permission.limit_type_urls").String()
// convert string to array
var msgsList []string
require.NoError(t, json.Unmarshal([]byte(listStr), &msgsList))
require.EqualValues(t, tc.limtTypeURLs, msgsList)
}
})
}
// test disable tx command
testCircuitTxCommand(t, cli, "disable", superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc)
// test reset tx command
testCircuitTxCommand(t, cli, "reset", superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc)
}
func testCircuitTxCommand(t *testing.T, cli *systest.CLIWrapper, txType, superAdmin, superAdmin2, allMsgsAcc, someMsgsAcc string) {
t.Helper()
disableTestCases := []struct {
name string
fromAddr string
disableMsgs []string
executeTxs [][]string
}{
{
txType + " msgs with super admin",
superAdmin,
[]string{"/cosmos.gov.v1.MsgVote"},
[][]string{
{
"tx", "gov", "vote", "3", "yes", "--from=" + superAdmin,
},
},
},
{
txType + " msgs with all msgs level address",
allMsgsAcc,
[]string{"/cosmos.gov.v1.MsgDeposit"},
[][]string{
{
"tx", "gov", "deposit", "3", "1000stake", "--from=" + allMsgsAcc,
},
},
},
{
txType + " msgs with some msgs level address",
someMsgsAcc,
someMsgs,
[][]string{
{
"tx", "bank", "send", superAdmin, someMsgsAcc, "10000stake",
},
{
"tx", "bank", "multi-send", superAdmin, someMsgsAcc, superAdmin2, "10000stake", "--from=" + superAdmin,
},
},
},
}
for _, tc := range disableTestCases {
t.Run(tc.name, func(t *testing.T) {
cmd := []string{"tx", "circuit", txType, "--from=" + tc.fromAddr}
cmd = append(cmd, tc.disableMsgs...)
rsp := cli.RunAndWait(cmd...)
systest.RequireTxSuccess(t, rsp)
// execute given type transaction
rsp = cli.CustomQuery("q", "circuit", "disabled-list")
var list []string
if gjson.Get(rsp, "disabled_list").Exists() {
listJSON := gjson.Get(rsp, "disabled_list").Raw
// convert string to array
require.NoError(t, json.Unmarshal([]byte(listJSON), &list))
}
for _, msg := range tc.disableMsgs {
if txType == "disable" {
require.Contains(t, list, msg)
} else {
require.NotContains(t, list, msg)
}
}
// test given msg transaction to confirm
for _, tx := range tc.executeTxs {
tx = append(tx, "--fees=2stake")
rsp = cli.WithRunErrorsIgnored().RunCommandWithArgs(cli.WithTXFlags(tx...)...)
if txType == "disable" {
systest.RequireTxFailure(t, rsp)
require.Contains(t, rsp, "tx type not allowed")
continue
}
systest.RequireTxSuccess(t, rsp)
// wait for sometime to avoid sequence error
_, found := cli.AwaitTxCommitted(rsp)
require.True(t, found)
}
})
}
}