From 60849a5d8238d21b9b09955939f78b3784466ecf Mon Sep 17 00:00:00 2001 From: quasisamurai Date: Wed, 19 Oct 2022 14:28:52 +0400 Subject: [PATCH 1/2] rm patched gov --- app/app.go | 6 +- cmd/neutrond/genwasm.go | 30 --------- cmd/neutrond/root.go | 1 - contracts/neutron_dao.wasm | Bin 166424 -> 0 bytes network/init.sh | 14 +---- x/gov/README.md | 42 ------------- x/gov/abci.go | 117 ----------------------------------- x/gov/keeper/keeper.go | 48 -------------- x/gov/keeper/query_server.go | 79 ----------------------- x/gov/keeper/tally.go | 94 ---------------------------- x/gov/keeper/voting.go | 79 ----------------------- x/gov/module.go | 54 ---------------- x/gov/types/errors.go | 12 ---- x/gov/types/keys.go | 15 ----- x/gov/types/voting.go | 33 ---------- 15 files changed, 6 insertions(+), 618 deletions(-) delete mode 100644 cmd/neutrond/genwasm.go delete mode 100644 contracts/neutron_dao.wasm delete mode 100644 x/gov/README.md delete mode 100644 x/gov/abci.go delete mode 100644 x/gov/keeper/keeper.go delete mode 100644 x/gov/keeper/query_server.go delete mode 100644 x/gov/keeper/tally.go delete mode 100644 x/gov/keeper/voting.go delete mode 100644 x/gov/module.go delete mode 100644 x/gov/types/errors.go delete mode 100644 x/gov/types/keys.go delete mode 100644 x/gov/types/voting.go diff --git a/app/app.go b/app/app.go index a61a75a39..79ca06ca9 100644 --- a/app/app.go +++ b/app/app.go @@ -59,8 +59,10 @@ import ( feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" + "github.com/cosmos/cosmos-sdk/x/gov" cosmosgov "github.com/cosmos/cosmos-sdk/x/gov" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" + govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" "github.com/cosmos/cosmos-sdk/x/mint" mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper" @@ -98,8 +100,6 @@ import ( ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host" ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" ibctesting "github.com/cosmos/ibc-go/v3/testing" - "github.com/neutron-org/neutron/x/gov" - govkeeper "github.com/neutron-org/neutron/x/gov/keeper" "github.com/spf13/cast" abci "github.com/tendermint/tendermint/abci/types" tmjson "github.com/tendermint/tendermint/libs/json" @@ -510,7 +510,7 @@ func New( app.GovKeeper = govkeeper.NewKeeper( appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper, - app.WasmKeeper, + app.StakingKeeper, govRouter, ) diff --git a/cmd/neutrond/genwasm.go b/cmd/neutrond/genwasm.go deleted file mode 100644 index 50e48986b..000000000 --- a/cmd/neutrond/genwasm.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import ( - "github.com/cosmos/cosmos-sdk/client" - "github.com/spf13/cobra" - - wasmcli "github.com/CosmWasm/wasmd/x/wasm/client/cli" -) - -func addGenesisWasmMsgCmd(defaultNodeHome string) *cobra.Command { - txCmd := &cobra.Command{ - Use: "add-wasm-message", - Short: "Wasm genesis subcommands", - DisableFlagParsing: true, - SuggestionsMinimumDistance: 2, - RunE: client.ValidateCmd, - } - - genesisIO := wasmcli.NewDefaultGenesisIO() - - txCmd.AddCommand( - wasmcli.GenesisStoreCodeCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisInstantiateContractCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisExecuteContractCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisListContractsCmd(defaultNodeHome, genesisIO), - wasmcli.GenesisListCodesCmd(defaultNodeHome, genesisIO), - ) - - return txCmd -} diff --git a/cmd/neutrond/root.go b/cmd/neutrond/root.go index 6b3e0b9a0..77b7663a6 100644 --- a/cmd/neutrond/root.go +++ b/cmd/neutrond/root.go @@ -92,7 +92,6 @@ func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) { genutilcli.GenTxCmd(app.ModuleBasics, encodingConfig.TxConfig, banktypes.GenesisBalancesIterator{}, app.DefaultNodeHome), genutilcli.ValidateGenesisCmd(app.ModuleBasics), AddGenesisAccountCmd(app.DefaultNodeHome), - addGenesisWasmMsgCmd(app.DefaultNodeHome), tmcli.NewCompletionCmd(rootCmd, true), // testnetCmd(app.ModuleBasics, banktypes.GenesisBalancesIterator{}), debug.Cmd(), diff --git a/contracts/neutron_dao.wasm b/contracts/neutron_dao.wasm deleted file mode 100644 index 05f676e9c7cc778e7f026b9f1e992e2e7f113a43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166424 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 z 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 diff --git a/network/init.sh b/network/init.sh index 7e9c269cc..4c03328f9 100755 --- a/network/init.sh +++ b/network/init.sh @@ -23,7 +23,7 @@ RESTPORT_2=1317 ROSETTA_1=8080 ROSETTA_2=8081 -# Stop if it is already running +# Stop if it is already running if pgrep -x "$BINARY" >/dev/null; then echo "Terminating $BINARY..." killall $BINARY @@ -55,8 +55,8 @@ echo $VAL_MNEMONIC_2 | $BINARY keys add val2 --home $CHAIN_DIR/$CHAINID_2 --reco echo $DEMO_MNEMONIC_1 | $BINARY keys add demowallet1 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test echo $DEMO_MNEMONIC_2 | $BINARY keys add demowallet2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test echo $DEMO_MNEMONIC_3 | $BINARY keys add demowallet3 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test -echo $RLY_MNEMONIC_1 | $BINARY keys add rly1 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test -echo $RLY_MNEMONIC_2 | $BINARY keys add rly2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test +echo $RLY_MNEMONIC_1 | $BINARY keys add rly1 --home $CHAIN_DIR/$CHAINID_1 --recover --keyring-backend=test +echo $RLY_MNEMONIC_2 | $BINARY keys add rly2 --home $CHAIN_DIR/$CHAINID_2 --recover --keyring-backend=test $BINARY add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAINID_1 keys show val1 --keyring-backend test -a) 100000000000stake --home $CHAIN_DIR/$CHAINID_1 $BINARY add-genesis-account $($BINARY --home $CHAIN_DIR/$CHAINID_2 keys show val2 --keyring-backend test -a) 100000000000stake --home $CHAIN_DIR/$CHAINID_2 @@ -72,14 +72,6 @@ $BINARY gentx val2 7000000000stake --home $CHAIN_DIR/$CHAINID_2 --chain-id $CHAI $BINARY collect-gentxs --home $CHAIN_DIR/$CHAINID_1 $BINARY collect-gentxs --home $CHAIN_DIR/$CHAINID_2 -echo "Initializing dao contract in genesis..." -# Upload the dao contract -$BINARY add-wasm-message store ${DAO_CONTRACT} --output json --run-as neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u --home $CHAIN_DIR/$CHAINID_1 -# Instantiate the contract -INIT_CONTRACT="$(printf '{"owner":"%s"}' "${ADMIN_ADDRESS}")" -#echo "Instantiate" -$BINARY add-wasm-message instantiate-contract 1 "$INIT_CONTRACT" --run-as neutron1mjk79fjjgpplak5wq838w0yd982gzkyf8fxu8u --admin ${ADMIN_ADDRESS} --label "DAO" --home $CHAIN_DIR/$CHAINID_1 - echo "Changing defaults and ports in app.toml and config.toml files..." sed -i -e 's#"tcp://0.0.0.0:26656"#"tcp://0.0.0.0:'"$P2PPORT_1"'"#g' $CHAIN_DIR/$CHAINID_1/config/config.toml sed -i -e 's#"tcp://127.0.0.1:26657"#"tcp://0.0.0.0:'"$RPCPORT_1"'"#g' $CHAIN_DIR/$CHAINID_1/config/config.toml diff --git a/x/gov/README.md b/x/gov/README.md deleted file mode 100644 index d6eadf2f9..000000000 --- a/x/gov/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# x/gov -The Neutron's governance is a wrapper over original cosmos sdk `gov` module with a some key difference. For the modules are very similar, overview section describes only the differences. Learn more about the gov module (and therefore about the Neutron's one) by the link to the cosmos documentation site: https://docs.cosmos.network/master/modules/gov/ - -What makes this module different from the original one: -- Staking no more affects user's voting power -- Voting power is now calculates and stores in smart-contract -- Tally logic is modified - -Read about these features below to make a better understanding. - -## Staking no more affects user's voting power - -The original gov module computes voting power on proposals using each user's delegations. Since the Neutron's plan is to not use standard staking & validators, it's necessary to remove rudimentary usage of staking module. Instead of this, however, we are introduced an alternative -## Voting power is now calculated and stored in smart-contract - -We use cosm-wasm contract which implements several methods: -```rust -pub fn query_voting_power(deps: Deps, user_addr: Addr) -> StdResult {...} -``` - -```rust -pub fn query_voting_powers(deps: Deps) -> StdResult> {...} -``` -where ```VotingPowerResponse``` is - -```rust -pub struct VotingPowerResponse { - /// Address of the user - pub user: String, - /// The user's current voting power, i.e. the amount of NTRN tokens locked in voting contract - pub voting_power: Uint128, -} -``` -currently neutron-core uses only `query_voting_powers`, but `query_voting_power` seems to be useful in future - -## Tally logic is modified -Tally interface hasn't changed, but instead of calculating voting results by staked tokens, it uses an above contract's query -```golang -// GetTokensInDao queries the voting contract for an array of users who have tokens locked in the -// contract and their respective amount, as well as computing the total amount of locked tokens. -func GetTokensInDao(ctx sdk.Context, k wasmtypes.ViewKeeper, contractAddr sdk.AccAddress) (map[string]sdk.Int, sdk.Int, error) {...} -``` diff --git a/x/gov/abci.go b/x/gov/abci.go deleted file mode 100644 index 911a300c1..000000000 --- a/x/gov/abci.go +++ /dev/null @@ -1,117 +0,0 @@ -package gov - -import ( - "fmt" - "time" - - "github.com/cosmos/cosmos-sdk/telemetry" - sdk "github.com/cosmos/cosmos-sdk/types" - - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - - "github.com/neutron-org/neutron/x/gov/keeper" -) - -// EndBlocker called at the end of every block, processing proposals -// same as the vanilla gov EndBlocker, except for we replace the `Tally` -// function with our own implementation -func EndBlocker(ctx sdk.Context, keeper keeper.Keeper) { - defer telemetry.ModuleMeasureSince(govtypes.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker) - - logger := keeper.Logger(ctx) - - // delete inactive proposal from store and its deposits - keeper.IterateInactiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal govtypes.Proposal) bool { - keeper.DeleteProposal(ctx, proposal.ProposalId) - keeper.DeleteDeposits(ctx, proposal.ProposalId) - - // called when proposal become inactive - keeper.AfterProposalFailedMinDeposit(ctx, proposal.ProposalId) - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - govtypes.EventTypeInactiveProposal, - sdk.NewAttribute(govtypes.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalId)), - sdk.NewAttribute(govtypes.AttributeKeyProposalResult, govtypes.AttributeValueProposalDropped), - ), - ) - - logger.Info( - "proposal did not meet minimum deposit; deleted", - "proposal", proposal.ProposalId, - "title", proposal.GetTitle(), - "min_deposit", keeper.GetDepositParams(ctx).MinDeposit.String(), - "total_deposit", proposal.TotalDeposit.String(), - ) - - return false - }) - - // fetch active proposals whose voting periods have ended (are passed the block time) - keeper.IterateActiveProposalsQueue(ctx, ctx.BlockHeader().Time, func(proposal govtypes.Proposal) bool { - var tagValue, logMsg string - - passes, burnDeposits, tallyResults := keeper.Tally(ctx, proposal) // our custom implementation of tally logics - - if burnDeposits { - keeper.DeleteDeposits(ctx, proposal.ProposalId) - } else { - keeper.RefundDeposits(ctx, proposal.ProposalId) - } - - if passes { - handler := keeper.Router().GetRoute(proposal.ProposalRoute()) - cacheCtx, writeCache := ctx.CacheContext() - - // The proposal handler may execute state mutating logic depending on the proposal content. - // If the handler fails, no state mutation is written and the error message is logged. - err := handler(cacheCtx, proposal.GetContent()) - if err == nil { - proposal.Status = govtypes.StatusPassed - tagValue = govtypes.AttributeValueProposalPassed - logMsg = "passed" - - // The cached context is created with a new EventManager. However, since the proposal - // handler execution was successful, we want to track/keep any events emitted, so we - // re-emit to "merge" the events into the original Context's EventManager. - ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) - - // write state to the underlying multi-store - writeCache() - } else { - proposal.Status = govtypes.StatusFailed - tagValue = govtypes.AttributeValueProposalFailed - logMsg = fmt.Sprintf("passed, but failed on execution: %s", err) - } - } else { - proposal.Status = govtypes.StatusRejected - tagValue = govtypes.AttributeValueProposalRejected - logMsg = "rejected" - } - - proposal.FinalTallyResult = tallyResults - - keeper.SetProposal(ctx, proposal) - keeper.RemoveFromActiveProposalQueue(ctx, proposal.ProposalId, proposal.VotingEndTime) - - // when proposal become active - keeper.AfterProposalVotingPeriodEnded(ctx, proposal.ProposalId) - - logger.Info( - "proposal tallied", - "proposal", proposal.ProposalId, - "title", proposal.GetTitle(), - "result", logMsg, - ) - - ctx.EventManager().EmitEvent( - sdk.NewEvent( - govtypes.EventTypeActiveProposal, - sdk.NewAttribute(govtypes.AttributeKeyProposalID, fmt.Sprintf("%d", proposal.ProposalId)), - sdk.NewAttribute(govtypes.AttributeKeyProposalResult, tagValue), - ), - ) - - return false - }) -} diff --git a/x/gov/keeper/keeper.go b/x/gov/keeper/keeper.go deleted file mode 100644 index bac596e38..000000000 --- a/x/gov/keeper/keeper.go +++ /dev/null @@ -1,48 +0,0 @@ -package keeper - -import ( - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" -) - -// Keeper defines the custom governance module Keeper -// -// NOTE: Keeper wraps the vanilla gov keeper to inherit most of its functions. However, we include an -// additional dependency, the wasm keeper, which is needed for our custom vote tallying logic -type Keeper struct { - govkeeper.Keeper - - storeKey sdk.StoreKey - wasmKeeper wasmtypes.ViewKeeper -} - -// NewKeeper returns a custom gov keeper -// -// NOTE: compared to the vanilla gov keeper's constructor function here we: -// 1. require an additional wasm keeper, which is needed for our custom vote tallying logic -// 2. remove staking module -func NewKeeper( - cdc codec.BinaryCodec, key sdk.StoreKey, paramSpace govtypes.ParamSubspace, - authKeeper govtypes.AccountKeeper, bankKeeper govtypes.BankKeeper, - wasmKeeper wasmtypes.ViewKeeper, rtr govtypes.Router, -) Keeper { - return Keeper{ - Keeper: govkeeper.NewKeeper(cdc, key, paramSpace, authKeeper, bankKeeper, nil, rtr), - storeKey: key, - wasmKeeper: wasmKeeper, - } -} - -// deleteVote deletes a vote from a given proposalID and voter from the store -// -// NOTE: the vanilla gov module does not make the `deleteVote` function public, so in order to delete -// votes, we need to redefine the function here -func (k Keeper) deleteVote(ctx sdk.Context, proposalID uint64, voterAddr sdk.AccAddress) { - store := ctx.KVStore(k.storeKey) - store.Delete(govtypes.VoteKey(proposalID, voterAddr)) -} diff --git a/x/gov/keeper/query_server.go b/x/gov/keeper/query_server.go deleted file mode 100644 index 1e8877629..000000000 --- a/x/gov/keeper/query_server.go +++ /dev/null @@ -1,79 +0,0 @@ -package keeper - -import ( - "context" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - sdk "github.com/cosmos/cosmos-sdk/types" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -) - -type queryServer struct{ k Keeper } - -// NewQueryServerImpl creates an implementation of the QueryServer interface for the given keeper -func NewQueryServerImpl(k Keeper) govtypes.QueryServer { - return &queryServer{k} -} - -func (qs queryServer) TallyResult(goCtx context.Context, req *govtypes.QueryTallyResultRequest) (*govtypes.QueryTallyResultResponse, error) { - if req == nil { - return nil, status.Error(codes.InvalidArgument, "invalid request") - } - - if req.ProposalId == 0 { - return nil, status.Error(codes.InvalidArgument, "proposal id can not be 0") - } - - ctx := sdk.UnwrapSDKContext(goCtx) - - proposal, ok := qs.k.GetProposal(ctx, req.ProposalId) - if !ok { - return nil, status.Errorf(codes.NotFound, "proposal %d doesn't exist", req.ProposalId) - } - - var tallyResult govtypes.TallyResult - - switch { - case proposal.Status == govtypes.StatusDepositPeriod: - tallyResult = govtypes.EmptyTallyResult() - - case proposal.Status == govtypes.StatusPassed || proposal.Status == govtypes.StatusRejected: - tallyResult = proposal.FinalTallyResult - - default: - // proposal is in voting period - _, _, tallyResult = qs.k.Tally(ctx, proposal) // replace with our custom Tally function - } - - return &govtypes.QueryTallyResultResponse{Tally: tallyResult}, nil -} - -func (qs queryServer) Proposal(goCtx context.Context, req *govtypes.QueryProposalRequest) (*govtypes.QueryProposalResponse, error) { - return qs.k.Proposal(goCtx, req) -} - -func (qs queryServer) Proposals(goCtx context.Context, req *govtypes.QueryProposalsRequest) (*govtypes.QueryProposalsResponse, error) { - return qs.k.Proposals(goCtx, req) -} - -func (qs queryServer) Vote(goCtx context.Context, req *govtypes.QueryVoteRequest) (*govtypes.QueryVoteResponse, error) { - return qs.k.Vote(goCtx, req) -} - -func (qs queryServer) Votes(goCtx context.Context, req *govtypes.QueryVotesRequest) (*govtypes.QueryVotesResponse, error) { - return qs.k.Votes(goCtx, req) -} - -func (qs queryServer) Params(goCtx context.Context, req *govtypes.QueryParamsRequest) (*govtypes.QueryParamsResponse, error) { - return qs.k.Params(goCtx, req) -} - -func (qs queryServer) Deposit(goCtx context.Context, req *govtypes.QueryDepositRequest) (*govtypes.QueryDepositResponse, error) { - return qs.k.Deposit(goCtx, req) -} - -func (qs queryServer) Deposits(goCtx context.Context, req *govtypes.QueryDepositsRequest) (*govtypes.QueryDepositsResponse, error) { - return qs.k.Deposits(goCtx, req) -} diff --git a/x/gov/keeper/tally.go b/x/gov/keeper/tally.go deleted file mode 100644 index 7cfc907c4..000000000 --- a/x/gov/keeper/tally.go +++ /dev/null @@ -1,94 +0,0 @@ -package keeper - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" - - wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -) - -// DefaultContractAddr is the wasm contract address generated by code ID 1 and instance ID 1. -// -// In other words, the first ever contract to be deployed on this chain will necessarily have this address. -var DefaultContractAddr = wasmkeeper.BuildContractAddress(1, 1) - -// Tally iterates over the votes and updates the tally of a proposal based on the voting power of the voters -func (k Keeper) Tally(ctx sdk.Context, proposal govtypes.Proposal) (passes bool, burnDeposits bool, tallyResults govtypes.TallyResult) { - results := make(map[govtypes.VoteOption]sdk.Dec) - results[govtypes.OptionYes] = sdk.ZeroDec() - results[govtypes.OptionAbstain] = sdk.ZeroDec() - results[govtypes.OptionNo] = sdk.ZeroDec() - results[govtypes.OptionNoWithVeto] = sdk.ZeroDec() - - // fetch all tokens locked in the DAO contract - // - // NOTE: for now we simply use the default contract address. later it may be a better idea to use - // a configurable parameter - tokensLocked, totalTokensLocked := MustGetTokensInVoting(ctx, k.wasmKeeper, DefaultContractAddr) - - // total amount of tokens that have voted in this poll; used to determine whether the poll reaches - // quorum and the pass threshold - totalTokensVoted := sdk.ZeroDec() - - // iterate through votes - k.IterateVotes(ctx, proposal.ProposalId, func(vote govtypes.Vote) bool { - voterAddr := sdk.MustAccAddressFromBech32(vote.Voter) - - votingPower := sdk.ZeroDec() - - // if the voter has tokens locked in DAO contract, add that to the voting power - if votingPowerInDao, ok := tokensLocked[vote.Voter]; ok { - votingPower = votingPower.Add(votingPowerInDao.ToDec()) - } - - incrementTallyResult(votingPower, vote.Options, results, &totalTokensVoted) - k.deleteVote(ctx, vote.ProposalId, voterAddr) - - return false - }) - - tallyParams := k.GetTallyParams(ctx) - tallyResults = govtypes.NewTallyResultFromMap(results) - - // if there is no staked coins, the proposal fails - if totalTokensLocked.IsZero() { - return false, false, tallyResults - } - - // if there is not enough quorum of votes, the proposal fails, and deposit burned - // - // NOTE: should the deposit really be burned here? - if totalTokensVoted.Quo(totalTokensLocked.ToDec()).LT(tallyParams.Quorum) { - return false, true, tallyResults - } - - // if everyone abstains, proposal fails - if totalTokensVoted.Sub(results[govtypes.OptionAbstain]).IsZero() { - return false, false, tallyResults - } - - // if more than 1/3 of voters veto, proposal fails, and deposit burned - // - // NOTE: here 1/3 is defined as 1/3 *of all votes*, including abstaining votes. could it make more - // sense to instead define it as 1/3 *of all non-abstaining votes*? - if results[govtypes.OptionNoWithVeto].Quo(totalTokensVoted).GT(tallyParams.VetoThreshold) { - return false, true, tallyResults - } - - // if no less than 1/2 of non-abstaining voters vote No, proposal fails - if results[govtypes.OptionNo].Quo(totalTokensVoted.Sub(results[govtypes.OptionAbstain])).GTE(tallyParams.Threshold) { - return false, false, tallyResults - } - - // otherwise, meaning more than 1/2 of non-abstaining voters vote Yes, proposal passes - return true, false, tallyResults -} - -func incrementTallyResult(votingPower sdk.Dec, options []govtypes.WeightedVoteOption, results map[govtypes.VoteOption]sdk.Dec, totalTokensVoted *sdk.Dec) { - for _, option := range options { - subPower := votingPower.Mul(option.Weight) - results[option.Option] = results[option.Option].Add(subPower) - } - - *totalTokensVoted = totalTokensVoted.Add(votingPower) -} diff --git a/x/gov/keeper/voting.go b/x/gov/keeper/voting.go deleted file mode 100644 index 42a5444e7..000000000 --- a/x/gov/keeper/voting.go +++ /dev/null @@ -1,79 +0,0 @@ -package keeper - -import ( - "encoding/json" - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" - - "github.com/neutron-org/neutron/x/gov/types" -) - -// queryVotingPowers queries the dao contract of user voting powers based on the given query msg -func queryVotingPowers(ctx sdk.Context, k wasmtypes.ViewKeeper, contractAddr sdk.AccAddress) (types.VotingPowersResponse, error) { - var votingPowersResponse types.VotingPowersResponse - - req, err := json.Marshal(&types.QueryMsg{VotingPowers: &types.VotingPowersQuery{}}) - if err != nil { - return nil, sdkerrors.Wrapf(types.ErrFailedToQueryVoting, "failed to marshal query request: %s", err) - } - - res, err := k.QuerySmart(ctx, contractAddr, req) - if err != nil { - return nil, sdkerrors.Wrapf(types.ErrFailedToQueryVoting, "query returned error: %s", err) - } - - err = json.Unmarshal(res, &votingPowersResponse) - if err != nil { - return nil, sdkerrors.Wrapf(types.ErrFailedToQueryVoting, "failed to unmarshal query response: %s", err) - } - - return votingPowersResponse, nil -} - -// incrementVotingPowers increments the voting power counter based on the contract query response -// -// NOTE: This function modifies the `tokensLocked` and `totalTokensAmount` variables in place. -func incrementVotingPowers(votingPowersResponse types.VotingPowersResponse, tokensLocked map[string]sdk.Int, totalTockensLocked *sdk.Int) error { - for _, item := range votingPowersResponse { - if _, ok := tokensLocked[item.User]; ok { - return sdkerrors.Wrapf(types.ErrFailedToQueryVoting, "query response contains duplicate address: %s", item.User) - } - - tokensLocked[item.User] = sdk.Int(item.VotingPower) - *totalTockensLocked = totalTockensLocked.Add(sdk.Int(item.VotingPower)) - } - - return nil -} - -// GetTokensInDao queries the voting contract for an array of users who have tokens locked in the -// contract and their respective amount, as well as computing the total amount of locked tokens. -func GetTokensInDao(ctx sdk.Context, k wasmtypes.ViewKeeper, contractAddr sdk.AccAddress) (map[string]sdk.Int, sdk.Int, error) { - tokensLocked := make(map[string]sdk.Int) - totalTokenAmount := sdk.ZeroInt() - - votingPowersResponse, err := queryVotingPowers(ctx, k, contractAddr) - if err != nil { - return nil, sdk.ZeroInt(), err - } - - if err = incrementVotingPowers(votingPowersResponse, tokensLocked, &totalTokenAmount); err != nil { - return nil, sdk.ZeroInt(), err - } - - return tokensLocked, totalTokenAmount, nil -} - -// MustGetTokensInVoting is the same with `GetTokensInDao`, but panics on error -func MustGetTokensInVoting(ctx sdk.Context, k wasmtypes.ViewKeeper, contractAddr sdk.AccAddress) (map[string]sdk.Int, sdk.Int) { - tokensLocked, totalTokensLocked, err := GetTokensInDao(ctx, k, contractAddr) - if err != nil { - panic(fmt.Sprintf("failed to tally vote: %s", err)) - } - - return tokensLocked, totalTokensLocked -} diff --git a/x/gov/module.go b/x/gov/module.go deleted file mode 100644 index 7eb539cc6..000000000 --- a/x/gov/module.go +++ /dev/null @@ -1,54 +0,0 @@ -package gov - -import ( - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/module" - - "github.com/cosmos/cosmos-sdk/x/gov" - govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" - - "github.com/neutron-org/neutron/x/gov/keeper" -) - -// AppModule must implement the `module.AppModule` interface -var _ module.AppModule = AppModule{} - -// AppModule implements an application module for the custom gov module -// -// NOTE: our custom AppModule wraps the vanilla `gov.AppModule` to inherit most of its functions. -// However, we overwrite the `EndBlock` function to replace it with our custom vote tallying logic -type AppModule struct { - gov.AppModule - - keeper keeper.Keeper -} - -// NewAppModule creates a new AppModule object -func NewAppModule(cdc codec.Codec, keeper keeper.Keeper, ak govtypes.AccountKeeper, bk govtypes.BankKeeper) AppModule { - return AppModule{ - AppModule: gov.NewAppModule(cdc, keeper.Keeper, ak, bk), - keeper: keeper, - } -} - -// EndBlock returns the end blocker for the gov module. It returns no validator updates. -// -// NOTE: this overwrites the vanilla gov module EndBlocker with our custom vote tallying logic -func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { - EndBlocker(ctx, am.keeper) - return []abci.ValidatorUpdate{} -} - -// RegisterServices registers module services. -// -// NOTE: this overwrites the vanilla gov module RegisterServices function -func (am AppModule) RegisterServices(cfg module.Configurator) { - // msg server - use the vanilla implementation - govtypes.RegisterMsgServer(cfg.MsgServer(), govkeeper.NewMsgServerImpl(am.keeper.Keeper)) - // query server - use our custom implementation - govtypes.RegisterQueryServer(cfg.QueryServer(), keeper.NewQueryServerImpl(am.keeper)) -} diff --git a/x/gov/types/errors.go b/x/gov/types/errors.go deleted file mode 100644 index e547b427f..000000000 --- a/x/gov/types/errors.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -import ( - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - - govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" -) - -// ErrFailedToQueryVoting represents an error where the gov module fails to query the vesting contract -// -// NOTE: latest version (v0.46.0) of the vanilla gov module already registered 2-15, so we start from 16 -var ErrFailedToQueryVoting = sdkerrors.Register(govtypes.ModuleName, 16, "failed to query vesting contract") diff --git a/x/gov/types/keys.go b/x/gov/types/keys.go deleted file mode 100644 index a4577c29d..000000000 --- a/x/gov/types/keys.go +++ /dev/null @@ -1,15 +0,0 @@ -package types - -const ( - // ModuleName defines the module name - ModuleName = "gov" - - // StoreKey defines the primary module store key - StoreKey = ModuleName - - // RouterKey is the message route for slashing - RouterKey = ModuleName - - // MemStoreKey defines the in-memory store key - MemStoreKey = "mem_gov" -) diff --git a/x/gov/types/voting.go b/x/gov/types/voting.go deleted file mode 100644 index 619eeaee9..000000000 --- a/x/gov/types/voting.go +++ /dev/null @@ -1,33 +0,0 @@ -package types - -import sdk "github.com/cosmos/cosmos-sdk/types" - -// InstantiateMsg corresponding to the Rust type `neutron-voting::msg::InstantiateMsg` -type InstantiateMsg struct { - Owner string `json:"owner"` -} - -// QueryMsg corresponding to the Rust enum `neutron-voting::msg::QueryMsg` -// -// NOTE: For covenience, we don't include other enum variants, as they are not needed here -type QueryMsg struct { - VotingPower *VotingPowerQuery `json:"voting_power,omitempty"` - VotingPowers *VotingPowersQuery `json:"voting_powers,omitempty"` -} - -// VotingPowerQuery corresponding to the Rust enum variant `neutron-voting::msg::QueryMsg::VotingPower` -type VotingPowerQuery struct { - User string `json:"user,omitempty"` -} - -// VotingPowersQuery corresponding to the Rust enum variant `neutron-voting::msg::QueryMsg::VotingPowers` -type VotingPowersQuery struct{} - -// VotingPowerResponse corresponding to the `voting_powers` query's respons type's repeating element -type VotingPowerResponse struct { - User string `json:"user"` - VotingPower sdk.Uint `json:"voting_power"` -} - -// VotingPowersResponse corresponding to the response type of the `voting_powers` query -type VotingPowersResponse []VotingPowerResponse From e78cff6fb4fb337aec949692473299fe92fba2c7 Mon Sep 17 00:00:00 2001 From: quasisamurai Date: Wed, 19 Oct 2022 15:01:05 +0400 Subject: [PATCH 2/2] lint --- app/app.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/app.go b/app/app.go index 79ca06ca9..15888daad 100644 --- a/app/app.go +++ b/app/app.go @@ -60,7 +60,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/gov" - cosmosgov "github.com/cosmos/cosmos-sdk/x/gov" govclient "github.com/cosmos/cosmos-sdk/x/gov/client" govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -194,7 +193,7 @@ var ( transfer.AppModuleBasic{}, vesting.AppModuleBasic{}, wasm.AppModuleBasic{}, - cosmosgov.NewAppModuleBasic(getGovProposalHandlers()...), + gov.NewAppModuleBasic(getGovProposalHandlers()...), interchainqueries.AppModuleBasic{}, interchaintxs.AppModuleBasic{}, )