Governance
MultiTest provides two minimal implementations of the governance module that do not
replicate the real blockchain behavior: GovAcceptingModule and
GovFailingModule. The default chain configuration is using
GovFailingModule.
The following sections provide examples of how to initialize a specific governance module and how to execute governance messages in tests.
Default governance module
Currently, in MultiTest, the default governance module is
GovFailingModule, and no additional configuration is required to use
it.
GovMsg::Vote
use cosmwasm_std::{GovMsg, VoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, IntoAddr};
// Build the application with default (always failing) governance module.
let mut app = AppBuilder::default().build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for vote.
let vote_msg = GovMsg::Vote {
proposal_id: 1,
option: VoteOption::Yes,
};
// Execute vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap_err();
// Always an error is returned.
assert!(response.to_string().starts_with("Unexpected exec msg Vote"));
GovMsg::VoteWeighted
use cosmwasm_std::{Decimal, GovMsg, Uint128, VoteOption, WeightedVoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, IntoAddr};
// Build the application with default (always failing) governance module.
let mut app = AppBuilder::default().build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for weighted vote.
let vote_msg = GovMsg::VoteWeighted {
proposal_id: 1,
options: vec![WeightedVoteOption {
option: VoteOption::Yes,
weight: Decimal::new(Uint128::new(12)),
}],
};
// Execute weighted vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap_err();
// Always an error is returned.
assert!(response.to_string().starts_with("Unexpected exec msg VoteWeighted"));
Failing governance module
Executing governance messages using GovFailingModule always returns an
error.
GovMsg::Vote
use cosmwasm_std::{GovMsg, VoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, GovFailingModule, IntoAddr};
// Build the application with always failing governance module.
let mut app = AppBuilder::default()
.with_gov(GovFailingModule::new())
.build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for vote.
let vote_msg = GovMsg::Vote {
proposal_id: 1,
option: VoteOption::Yes,
};
// Execute vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap_err();
// Always an error is returned.
assert!(response.to_string().starts_with("Unexpected exec msg Vote"));
GovMsg::VoteWeighted
use cosmwasm_std::{Decimal, GovMsg, Uint128, VoteOption, WeightedVoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, GovFailingModule, IntoAddr};
// Build the application with always failing governance module.
let mut app = AppBuilder::default()
.with_gov(GovFailingModule::new())
.build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for weighted vote.
let vote_msg = GovMsg::VoteWeighted {
proposal_id: 1,
options: vec![WeightedVoteOption {
option: VoteOption::Yes,
weight: Decimal::new(Uint128::new(12)),
}],
};
// Execute weighted vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap_err();
// Always an error is returned.
assert!(response.to_string().starts_with("Unexpected exec msg VoteWeighted"));
Accepting governance module
Executing governance messages using GovAcceptingModule always
succeeds, but the returned data is empty.
GovMsg::Vote
use cosmwasm_std::{GovMsg, VoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, GovAcceptingModule, IntoAddr};
// Build the application with always failing governance module.
let mut app = AppBuilder::default()
.with_gov(GovAcceptingModule::new())
.build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for vote.
let vote_msg = GovMsg::Vote {
proposal_id: 1,
option: VoteOption::Yes,
};
// Execute vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap();
// Always empty data is returned.
assert_eq!(None, response.data);
GovMsg::VoteWeighted
use cosmwasm_std::{Decimal, GovMsg, Uint128, VoteOption, WeightedVoteOption};
use cw_multi_test::{no_init, AppBuilder, Executor, GovAcceptingModule, IntoAddr};
// Build the application with always failing governance module.
let mut app = AppBuilder::default()
.with_gov(GovAcceptingModule::new())
.build(no_init);
// Prepare sender address.
let sender_addr = "sender".into_addr();
// Prepare message for weighted vote.
let vote_msg = GovMsg::VoteWeighted {
proposal_id: 1,
options: vec![WeightedVoteOption {
option: VoteOption::Yes,
weight: Decimal::new(Uint128::new(12)),
}],
};
// Execute weighted vote governance message.
let response = app.execute(sender_addr, vote_msg.into()).unwrap();
// Always empty data is returned.
assert_eq!(None, response.data);