Updates for upstream PR (community pool spend proposal) (#10)

Related cosmos/cosmos-sdk#4329
This commit is contained in:
Christopher Goes
2019-05-21 15:32:48 +02:00
committed by Alessio Treglia
parent 5350d3b01b
commit 5c5bf7c49b
10 changed files with 192 additions and 5 deletions

View File

@@ -0,0 +1 @@
Update Gaia for community pool spend proposals per Cosmos Hub governance proposal #7 "Activate the Community Pool"

View File

@@ -159,7 +159,8 @@ func NewGaiaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest b
// register the proposal types // register the proposal types
govRouter := gov.NewRouter() govRouter := gov.NewRouter()
govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler). govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler).
AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)) AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.paramsKeeper)).
AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.distrKeeper))
app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper, govSubspace, app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.paramsKeeper, govSubspace,
app.bankKeeper, &stakingKeeper, gov.DefaultCodespace, govRouter) app.bankKeeper, &stakingKeeper, gov.DefaultCodespace, govRouter)

View File

@@ -302,6 +302,7 @@ func testAndRunTxs(app *GaiaApp) []simulation.WeightedOperation {
{50, distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper)}, {50, distrsim.SimulateMsgWithdrawValidatorCommission(app.accountKeeper, app.distrKeeper)},
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, govsim.SimulateTextProposalContent)}, {5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, govsim.SimulateTextProposalContent)},
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, paramsim.SimulateParamChangeProposalContent)}, {5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, paramsim.SimulateParamChangeProposalContent)},
{5, govsim.SimulateSubmittingVotingAndSlashingForProposal(app.govKeeper, distrsim.SimulateCommunityPoolSpendProposalContent(app.distrKeeper))},
{100, govsim.SimulateMsgDeposit(app.govKeeper)}, {100, govsim.SimulateMsgDeposit(app.govKeeper)},
{100, stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper)}, {100, stakingsim.SimulateMsgCreateValidator(app.accountKeeper, app.stakingKeeper)},
{5, stakingsim.SimulateMsgEditValidator(app.stakingKeeper)}, {5, stakingsim.SimulateMsgEditValidator(app.stakingKeeper)},

View File

@@ -687,6 +687,90 @@ func TestGaiaCLISubmitParamChangeProposal(t *testing.T) {
f.Cleanup() f.Cleanup()
} }
func TestGaiaCLISubmitCommunityPoolSpendProposal(t *testing.T) {
t.Parallel()
f := InitFixtures(t)
// create some inflation
cdc := app.MakeCodec()
genesisState := f.GenesisState()
inflationMin := sdk.MustNewDecFromStr("10000.0")
var mintData mint.GenesisState
cdc.UnmarshalJSON(genesisState[mint.ModuleName], &mintData)
mintData.Minter.Inflation = inflationMin
mintData.Params.InflationMin = inflationMin
mintData.Params.InflationMax = sdk.MustNewDecFromStr("15000.0")
mintDataBz, err := cdc.MarshalJSON(mintData)
require.NoError(t, err)
genesisState[mint.ModuleName] = mintDataBz
genFile := filepath.Join(f.GaiadHome, "config", "genesis.json")
genDoc, err := tmtypes.GenesisDocFromFile(genFile)
require.NoError(t, err)
genDoc.AppState, err = cdc.MarshalJSON(genesisState)
require.NoError(t, genDoc.SaveAs(genFile))
proc := f.GDStart()
defer proc.Stop(false)
fooAddr := f.KeyAddress(keyFoo)
fooAcc := f.QueryAccount(fooAddr)
startTokens := sdk.TokensFromTendermintPower(50)
require.Equal(t, startTokens, fooAcc.GetCoins().AmountOf(sdk.DefaultBondDenom))
tests.WaitForNextNBlocksTM(3, f.Port)
// write proposal to file
proposalTokens := sdk.TokensFromTendermintPower(5)
proposal := fmt.Sprintf(`{
"title": "Community Pool Spend",
"description": "Spend from community pool",
"recipient": "%s",
"amount": [
{
"denom": "%s",
"amount": "1"
}
],
"deposit": [
{
"denom": "%s",
"amount": "%s"
}
]
}
`, fooAddr, sdk.DefaultBondDenom, sdk.DefaultBondDenom, proposalTokens.String())
proposalFile := WriteToNewTempFile(t, proposal)
// create the param change proposal
f.TxGovSubmitCommunityPoolSpendProposal(keyFoo, proposalFile.Name(), sdk.NewCoin(denom, proposalTokens), "-y")
tests.WaitForNextNBlocksTM(1, f.Port)
// ensure transaction tags can be queried
txsPage := f.QueryTxs(1, 50, "action:submit_proposal", fmt.Sprintf("sender:%s", fooAddr))
require.Len(t, txsPage.Txs, 1)
// ensure deposit was deducted
fooAcc = f.QueryAccount(fooAddr)
require.Equal(t, startTokens.Sub(proposalTokens).String(), fooAcc.GetCoins().AmountOf(sdk.DefaultBondDenom).String())
// ensure proposal is directly queryable
proposal1 := f.QueryGovProposal(1)
require.Equal(t, uint64(1), proposal1.ProposalID)
require.Equal(t, gov.StatusDepositPeriod, proposal1.Status)
// ensure correct query proposals result
proposalsQuery := f.QueryGovProposals()
require.Equal(t, uint64(1), proposalsQuery[0].ProposalID)
// ensure the correct deposit amount on the proposal
deposit := f.QueryGovDeposit(1, fooAddr)
require.Equal(t, proposalTokens, deposit.Amount.AmountOf(denom))
// Cleanup testing directories
f.Cleanup()
}
func TestGaiaCLIQueryTxPagination(t *testing.T) { func TestGaiaCLIQueryTxPagination(t *testing.T) {
t.Parallel() t.Parallel()
f := InitFixtures(t) f := InitFixtures(t)

View File

@@ -403,6 +403,20 @@ func (f *Fixtures) TxGovSubmitParamChangeProposal(
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass) return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
} }
// TxGovSubmitCommunityPoolSpendProposal executes a CLI community pool spend proposal
// submission.
func (f *Fixtures) TxGovSubmitCommunityPoolSpendProposal(
from, proposalPath string, deposit sdk.Coin, flags ...string,
) (bool, string, string) {
cmd := fmt.Sprintf(
"%s tx gov submit-proposal community-pool-spend %s --from=%s %v",
f.GaiacliBinary, proposalPath, from, f.Flags(),
)
return executeWriteRetStdStreams(f.T, addFlags(cmd, flags), client.DefaultKeyPass)
}
//___________________________________________________________________________________ //___________________________________________________________________________________
// gaiacli query account // gaiacli query account

View File

@@ -23,6 +23,7 @@ import (
crisisclient "github.com/cosmos/cosmos-sdk/x/crisis/client" crisisclient "github.com/cosmos/cosmos-sdk/x/crisis/client"
distcmd "github.com/cosmos/cosmos-sdk/x/distribution" distcmd "github.com/cosmos/cosmos-sdk/x/distribution"
distClient "github.com/cosmos/cosmos-sdk/x/distribution/client" distClient "github.com/cosmos/cosmos-sdk/x/distribution/client"
distrcli "github.com/cosmos/cosmos-sdk/x/distribution/client/cli"
dist "github.com/cosmos/cosmos-sdk/x/distribution/client/rest" dist "github.com/cosmos/cosmos-sdk/x/distribution/client/rest"
gv "github.com/cosmos/cosmos-sdk/x/gov" gv "github.com/cosmos/cosmos-sdk/x/gov"
govClient "github.com/cosmos/cosmos-sdk/x/gov/client" govClient "github.com/cosmos/cosmos-sdk/x/gov/client"
@@ -70,7 +71,7 @@ func main() {
// Module clients hold cli commnads (tx,query) and lcd routes // Module clients hold cli commnads (tx,query) and lcd routes
// TODO: Make the lcd command take a list of ModuleClient // TODO: Make the lcd command take a list of ModuleClient
mc := []sdk.ModuleClient{ mc := []sdk.ModuleClient{
govClient.NewModuleClient(gv.StoreKey, cdc, paramcli.GetCmdSubmitProposal(cdc)), govClient.NewModuleClient(gv.StoreKey, cdc, paramcli.GetCmdSubmitProposal(cdc), distrcli.GetCmdSubmitProposal(cdc)),
distClient.NewModuleClient(distcmd.StoreKey, cdc), distClient.NewModuleClient(distcmd.StoreKey, cdc),
stakingclient.NewModuleClient(st.StoreKey, cdc), stakingclient.NewModuleClient(st.StoreKey, cdc),
mintclient.NewModuleClient(mint.StoreKey, cdc), mintclient.NewModuleClient(mint.StoreKey, cdc),
@@ -175,7 +176,7 @@ func registerRoutes(rs *lcd.RestServer) {
dist.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distcmd.StoreKey) dist.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distcmd.StoreKey)
staking.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) staking.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) slashing.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
gov.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, paramsrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc)) gov.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, paramsrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc), dist.ProposalRESTHandler(rs.CliCtx, rs.Cdc))
mintrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) mintrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
} }

2
go.mod
View File

@@ -4,7 +4,7 @@ go 1.12
require ( require (
github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17 // indirect github.com/btcsuite/btcd v0.0.0-20190427004231-96897255fd17 // indirect
github.com/cosmos/cosmos-sdk v0.28.2-0.20190520151953-4b872d2eb4bb github.com/cosmos/cosmos-sdk v0.28.2-0.20190521100210-dd89c329516e
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
github.com/gogo/protobuf v1.2.1 // indirect github.com/gogo/protobuf v1.2.1 // indirect
github.com/google/gofuzz v1.0.0 // indirect github.com/google/gofuzz v1.0.0 // indirect

2
go.sum
View File

@@ -39,6 +39,8 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cosmos/cosmos-sdk v0.28.2-0.20190520151953-4b872d2eb4bb h1:njT3ur+sTKBaNvQOaWVvFr1mqczrqB3gaLd2BTCgXlQ= github.com/cosmos/cosmos-sdk v0.28.2-0.20190520151953-4b872d2eb4bb h1:njT3ur+sTKBaNvQOaWVvFr1mqczrqB3gaLd2BTCgXlQ=
github.com/cosmos/cosmos-sdk v0.28.2-0.20190520151953-4b872d2eb4bb/go.mod h1:asKfALbDgAL4BGwQdoYwEyfRIPHL20mA2Esan1ELVB4= github.com/cosmos/cosmos-sdk v0.28.2-0.20190520151953-4b872d2eb4bb/go.mod h1:asKfALbDgAL4BGwQdoYwEyfRIPHL20mA2Esan1ELVB4=
github.com/cosmos/cosmos-sdk v0.28.2-0.20190521100210-dd89c329516e h1:sey/szRUq+qpsaWP3TxNzT8MmFMQT/6QFhqD6xeLF9o=
github.com/cosmos/cosmos-sdk v0.28.2-0.20190521100210-dd89c329516e/go.mod h1:asKfALbDgAL4BGwQdoYwEyfRIPHL20mA2Esan1ELVB4=
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8 h1:Iwin12wRQtyZhH6FV3ykFcdGNlYEzoeR0jN8Vn+JWsI=
github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v0.0.0-20180618194314-52158e4697b8/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y=
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU=

View File

@@ -301,6 +301,14 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress
accs = append(accs, acc) accs = append(accs, acc)
} }
// distr data
distrDataBz := genesisState[distr.ModuleName]
var distrData distr.GenesisState
cdc.MustUnmarshalJSON(distrDataBz, &distrData)
distrData.FeePool.CommunityPool = sdk.DecCoins{sdk.DecCoin{"test", sdk.NewDecFromInt(sdk.NewInt(10))}}
distrDataBz = cdc.MustMarshalJSON(distrData)
genesisState[distr.ModuleName] = distrDataBz
// now add the account tokens to the non-bonded pool // now add the account tokens to the non-bonded pool
for _, acc := range accs { for _, acc := range accs {
accTokens := acc.Coins.AmountOf(sdk.DefaultBondDenom) accTokens := acc.Coins.AmountOf(sdk.DefaultBondDenom)
@@ -438,7 +446,7 @@ func registerRoutes(rs *lcd.RestServer) {
distrrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distr.StoreKey) distrrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, distr.StoreKey)
stakingrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) stakingrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
slashingrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase) slashingrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, rs.KeyBase)
govrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, paramsrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc)) govrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc, paramsrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc), distrrest.ProposalRESTHandler(rs.CliCtx, rs.Cdc))
mintrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc) mintrest.RegisterRoutes(rs.CliCtx, rs.Mux, rs.Cdc)
} }
@@ -1221,6 +1229,44 @@ func doSubmitParamChangeProposal(
return txResp return txResp
} }
func doSubmitCommunityPoolSpendProposal(
t *testing.T, port, seed, name, pwd string, proposerAddr sdk.AccAddress,
amount sdk.Int, fees sdk.Coins,
) sdk.TxResponse {
acc := getAccount(t, port, proposerAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
from := acc.GetAddress().String()
baseReq := rest.NewBaseReq(from, "", chainID, "", "", accnum, sequence, fees, nil, false)
pr := distrrest.CommunityPoolSpendProposalReq{
BaseReq: baseReq,
Title: "Test",
Description: "test",
Proposer: proposerAddr,
Recipient: proposerAddr,
Deposit: sdk.Coins{sdk.NewCoin(sdk.DefaultBondDenom, amount)},
Amount: sdk.Coins{sdk.NewCoin("test", sdk.NewInt(5))},
}
req, err := cdc.MarshalJSON(pr)
require.NoError(t, err)
resp, body := Request(t, port, "POST", "/gov/proposals/community_pool_spend", req)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
resp, body = signAndBroadcastGenTx(t, port, name, pwd, body, acc, client.DefaultGasAdjustment, false)
require.Equal(t, http.StatusOK, resp.StatusCode, body)
var txResp sdk.TxResponse
err = cdc.UnmarshalJSON([]byte(body), &txResp)
require.NoError(t, err)
return txResp
}
// GET /gov/proposals Query proposals // GET /gov/proposals Query proposals
func getProposalsAll(t *testing.T, port string) []gov.Proposal { func getProposalsAll(t *testing.T, port string) []gov.Proposal {
res, body := Request(t, port, "GET", "/gov/proposals", nil) res, body := Request(t, port, "GET", "/gov/proposals", nil)

View File

@@ -625,6 +625,43 @@ func TestSubmitProposal(t *testing.T) {
require.Equal(t, proposalID, proposer.ProposalID) require.Equal(t, proposalID, proposer.ProposalID)
} }
func TestSubmitCommunityPoolSpendProposal(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err)
addr, seed := CreateAddr(t, name1, pw, kb)
cleanup, _, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr}, true)
defer cleanup()
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create proposal tx
proposalTokens := sdk.TokensFromTendermintPower(5)
resultTx := doSubmitCommunityPoolSpendProposal(t, port, seed, name1, pw, addr, proposalTokens, fees)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.Code)
var proposalID uint64
bz, err := hex.DecodeString(resultTx.Data)
require.NoError(t, err)
cdc.MustUnmarshalBinaryLengthPrefixed(bz, &proposalID)
// verify balance
acc = getAccount(t, port, addr)
expectedBalance := initialBalance[0].Sub(fees[0])
require.Equal(t, expectedBalance.Amount.Sub(proposalTokens), acc.GetCoins().AmountOf(sdk.DefaultBondDenom))
// query proposal
proposal := getProposal(t, port, proposalID)
require.Equal(t, "Test", proposal.GetTitle())
proposer := getProposer(t, port, proposalID)
require.Equal(t, addr.String(), proposer.Proposer)
require.Equal(t, proposalID, proposer.ProposalID)
}
func TestSubmitParamChangeProposal(t *testing.T) { func TestSubmitParamChangeProposal(t *testing.T) {
kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, "")) kb, err := keys.NewKeyBaseFromDir(InitClientHome(t, ""))
require.NoError(t, err) require.NoError(t, err)