Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validator deactivation and reactivation #2082

Merged
merged 10 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add transactions to deactivate and reactivate a validator
([\#2082](https://github.com/anoma/namada/pull/2082))
1 change: 1 addition & 0 deletions .github/workflows/scripts/e2e.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"e2e::ledger_tests::test_node_connectivity_and_consensus": 28,
"e2e::ledger_tests::test_epoch_sleep": 12,
"e2e::ledger_tests::wrapper_disposable_signer": 28,
"e2e::ledger_tests::deactivate_and_reactivate_validator": 67,
"e2e::wallet_tests::wallet_address_cmds": 1,
"e2e::wallet_tests::wallet_encrypted_key_cmds": 1,
"e2e::wallet_tests::wallet_encrypted_key_cmds_env_var": 1,
Expand Down
2 changes: 2 additions & 0 deletions apps/src/lib/bench_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ pub const TX_CHANGE_VALIDATOR_COMMISSION_WASM: &str =
"tx_change_validator_commission.wasm";
pub const TX_IBC_WASM: &str = "tx_ibc.wasm";
pub const TX_UNJAIL_VALIDATOR_WASM: &str = "tx_unjail_validator.wasm";
pub const TX_DEACTIVATE_VALIDATOR_WASM: &str = "tx_deactivate_validator.wasm";
pub const TX_REACTIVATE_VALIDATOR_WASM: &str = "tx_reactivate_validator.wasm";
pub const TX_WITHDRAW_WASM: &str = "tx_withdraw.wasm";
pub const TX_INIT_ACCOUNT_WASM: &str = "tx_init_account.wasm";
pub const TX_INIT_VALIDATOR_WASM: &str = "tx_init_validator.wasm";
Expand Down
135 changes: 132 additions & 3 deletions apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ pub mod cmds {
// PoS transactions
.subcommand(TxInitValidator::def().display_order(2))
.subcommand(TxUnjailValidator::def().display_order(2))
.subcommand(TxDeactivateValidator::def().display_order(2))
.subcommand(TxReactivateValidator::def().display_order(2))
.subcommand(Bond::def().display_order(2))
.subcommand(Unbond::def().display_order(2))
.subcommand(Withdraw::def().display_order(2))
Expand Down Expand Up @@ -273,6 +275,10 @@ pub mod cmds {
Self::parse_with_ctx(matches, TxInitValidator);
let tx_unjail_validator =
Self::parse_with_ctx(matches, TxUnjailValidator);
let tx_deactivate_validator =
Self::parse_with_ctx(matches, TxDeactivateValidator);
let tx_reactivate_validator =
Self::parse_with_ctx(matches, TxReactivateValidator);
let tx_reveal_pk = Self::parse_with_ctx(matches, TxRevealPk);
let tx_init_proposal =
Self::parse_with_ctx(matches, TxInitProposal);
Expand Down Expand Up @@ -330,6 +336,8 @@ pub mod cmds {
.or(tx_init_validator)
.or(tx_commission_rate_change)
.or(tx_unjail_validator)
.or(tx_deactivate_validator)
.or(tx_reactivate_validator)
.or(bond)
.or(unbond)
.or(withdraw)
Expand Down Expand Up @@ -403,6 +411,8 @@ pub mod cmds {
TxInitValidator(TxInitValidator),
TxCommissionRateChange(TxCommissionRateChange),
TxUnjailValidator(TxUnjailValidator),
TxDeactivateValidator(TxDeactivateValidator),
TxReactivateValidator(TxReactivateValidator),
TxInitProposal(TxInitProposal),
TxVoteProposal(TxVoteProposal),
TxRevealPk(TxRevealPk),
Expand Down Expand Up @@ -1380,6 +1390,55 @@ pub mod cmds {
}
}

#[derive(Clone, Debug)]
pub struct TxDeactivateValidator(
pub args::TxDeactivateValidator<args::CliTypes>,
);

impl SubCmd for TxDeactivateValidator {
const CMD: &'static str = "deactivate-validator";

fn parse(matches: &ArgMatches) -> Option<Self> {
matches.subcommand_matches(Self::CMD).map(|matches| {
TxDeactivateValidator(args::TxDeactivateValidator::parse(
matches,
))
})
}

fn def() -> App {
App::new(Self::CMD)
.about("Send a signed transaction to deactivate a validator.")
.add_args::<args::TxDeactivateValidator<args::CliTypes>>()
}
}

#[derive(Clone, Debug)]
pub struct TxReactivateValidator(
pub args::TxReactivateValidator<args::CliTypes>,
);

impl SubCmd for TxReactivateValidator {
const CMD: &'static str = "reactivate-validator";

fn parse(matches: &ArgMatches) -> Option<Self> {
matches.subcommand_matches(Self::CMD).map(|matches| {
TxReactivateValidator(args::TxReactivateValidator::parse(
matches,
))
})
}

fn def() -> App {
App::new(Self::CMD)
.about(
"Send a signed transaction to reactivate an inactive \
validator.",
)
.add_args::<args::TxReactivateValidator<args::CliTypes>>()
}
}

#[derive(Clone, Debug)]
pub struct Bond(pub args::Bond<args::CliTypes>);

Expand Down Expand Up @@ -2648,6 +2707,8 @@ pub mod args {
pub const TX_BRIDGE_POOL_WASM: &str = "tx_bridge_pool.wasm";
pub const TX_CHANGE_COMMISSION_WASM: &str =
"tx_change_validator_commission.wasm";
pub const TX_DEACTIVATE_VALIDATOR_WASM: &str =
"tx_deactivate_validator.wasm";
pub const TX_IBC_WASM: &str = "tx_ibc.wasm";
pub const TX_INIT_ACCOUNT_WASM: &str = "tx_init_account.wasm";
pub const TX_INIT_PROPOSAL: &str = "tx_init_proposal.wasm";
Expand All @@ -2657,6 +2718,8 @@ pub mod args {
pub const TX_TRANSFER_WASM: &str = "tx_transfer.wasm";
pub const TX_UNBOND_WASM: &str = "tx_unbond.wasm";
pub const TX_UNJAIL_VALIDATOR_WASM: &str = "tx_unjail_validator.wasm";
pub const TX_REACTIVATE_VALIDATOR_WASM: &str =
"tx_reactivate_validator.wasm";
pub const TX_REDELEGATE_WASM: &str = "tx_redelegate.wasm";
pub const TX_UPDATE_VP_WASM: &str = "tx_update_vp.wasm";
pub const TX_UPDATE_STEWARD_COMMISSION: &str =
Expand Down Expand Up @@ -4914,9 +4977,75 @@ pub mod args {

fn def(app: App) -> App {
app.add_args::<Tx<CliTypes>>().arg(
VALIDATOR.def().help(
"The address of the jailed validator to re-activate.",
),
VALIDATOR
.def()
.help("The address of the jailed validator to unjail."),
)
}
}

impl CliToSdk<TxDeactivateValidator<SdkTypes>>
for TxDeactivateValidator<CliTypes>
{
fn to_sdk(self, ctx: &mut Context) -> TxDeactivateValidator<SdkTypes> {
TxDeactivateValidator::<SdkTypes> {
tx: self.tx.to_sdk(ctx),
validator: ctx.borrow_chain_or_exit().get(&self.validator),
tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}

impl Args for TxDeactivateValidator<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let tx = Tx::parse(matches);
let validator = VALIDATOR.parse(matches);
let tx_code_path = PathBuf::from(TX_DEACTIVATE_VALIDATOR_WASM);
Self {
tx,
validator,
tx_code_path,
}
}

fn def(app: App) -> App {
app.add_args::<Tx<CliTypes>>().arg(
VALIDATOR
.def()
.help("The address of the jailed validator to deactivate."),
)
}
}

impl CliToSdk<TxReactivateValidator<SdkTypes>>
for TxReactivateValidator<CliTypes>
{
fn to_sdk(self, ctx: &mut Context) -> TxReactivateValidator<SdkTypes> {
TxReactivateValidator::<SdkTypes> {
tx: self.tx.to_sdk(ctx),
validator: ctx.borrow_chain_or_exit().get(&self.validator),
tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}

impl Args for TxReactivateValidator<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let tx = Tx::parse(matches);
let validator = VALIDATOR.parse(matches);
let tx_code_path = PathBuf::from(TX_REACTIVATE_VALIDATOR_WASM);
Self {
tx,
validator,
tx_code_path,
}
}

fn def(app: App) -> App {
app.add_args::<Tx<CliTypes>>().arg(
VALIDATOR
.def()
.help("The address of the jailed validator to deactivate."),
)
}
}
Expand Down
26 changes: 26 additions & 0 deletions apps/src/lib/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,32 @@ impl CliApi {
let namada = ctx.to_sdk(&client, io);
tx::submit_unjail_validator(&namada, args).await?;
}
Sub::TxDeactivateValidator(TxDeactivateValidator(
mut args,
)) => {
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(
&mut args.tx.ledger_address,
)
});
client.wait_until_node_is_synced(io).await?;
let args = args.to_sdk(&mut ctx);
let namada = ctx.to_sdk(&client, io);
tx::submit_deactivate_validator(&namada, args).await?;
}
Sub::TxReactivateValidator(TxReactivateValidator(
mut args,
)) => {
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(
&mut args.tx.ledger_address,
)
});
client.wait_until_node_is_synced(io).await?;
let args = args.to_sdk(&mut ctx);
let namada = ctx.to_sdk(&client, io);
tx::submit_reactivate_validator(&namada, args).await?;
}
Sub::TxUpdateStewardCommission(
TxUpdateStewardCommission(mut args),
) => {
Expand Down
44 changes: 44 additions & 0 deletions apps/src/lib/client/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1016,6 +1016,50 @@ where
Ok(())
}

pub async fn submit_deactivate_validator<'a, N: Namada<'a>>(
namada: &N,
args: args::TxDeactivateValidator,
) -> Result<(), error::Error>
where
<N::Client as namada::ledger::queries::Client>::Error: std::fmt::Display,
{
let (mut tx, signing_data, _fee_unshield_epoch) =
args.build(namada).await?;
signing::generate_test_vector(namada, &tx).await?;

if args.tx.dump_tx {
tx::dump_tx(namada.io(), &args.tx, tx);
} else {
namada.sign(&mut tx, &args.tx, signing_data).await?;

namada.submit(tx, &args.tx).await?;
}

Ok(())
}

pub async fn submit_reactivate_validator<'a, N: Namada<'a>>(
namada: &N,
args: args::TxReactivateValidator,
) -> Result<(), error::Error>
where
<N::Client as namada::ledger::queries::Client>::Error: std::fmt::Display,
{
let (mut tx, signing_data, _fee_unshield_epoch) =
args.build(namada).await?;
signing::generate_test_vector(namada, &tx).await?;

if args.tx.dump_tx {
tx::dump_tx(namada.io(), &args.tx, tx);
} else {
namada.sign(&mut tx, &args.tx, signing_data).await?;

namada.submit(tx, &args.tx).await?;
}

Ok(())
}

pub async fn submit_update_steward_commission<'a, N: Namada<'a>>(
namada: &N,
args: args::UpdateStewardCommission,
Expand Down
66 changes: 63 additions & 3 deletions benches/txs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ use namada::types::transaction::EllipticCurve;
use namada_apps::bench_utils::{
generate_ibc_transfer_tx, generate_tx, BenchShell, BenchShieldedCtx,
ALBERT_PAYMENT_ADDRESS, ALBERT_SPENDING_KEY, BERTHA_PAYMENT_ADDRESS,
TX_BOND_WASM, TX_CHANGE_VALIDATOR_COMMISSION_WASM, TX_INIT_ACCOUNT_WASM,
TX_INIT_PROPOSAL_WASM, TX_INIT_VALIDATOR_WASM, TX_REDELEGATE_WASM,
TX_BOND_WASM, TX_CHANGE_VALIDATOR_COMMISSION_WASM,
TX_DEACTIVATE_VALIDATOR_WASM, TX_INIT_ACCOUNT_WASM, TX_INIT_PROPOSAL_WASM,
TX_INIT_VALIDATOR_WASM, TX_REACTIVATE_VALIDATOR_WASM, TX_REDELEGATE_WASM,
TX_REVEAL_PK_WASM, TX_UNBOND_WASM, TX_UNJAIL_VALIDATOR_WASM,
TX_UPDATE_ACCOUNT_WASM, TX_VOTE_PROPOSAL_WASM, TX_WITHDRAW_WASM,
VP_VALIDATOR_WASM,
Expand Down Expand Up @@ -718,6 +719,63 @@ fn unjail_validator(c: &mut Criterion) {
});
}

fn deactivate_validator(c: &mut Criterion) {
let signed_tx = generate_tx(
TX_DEACTIVATE_VALIDATOR_WASM,
defaults::validator_address(),
None,
None,
Some(&defaults::validator_keypair()),
);

c.bench_function("deactivate_validator", |b| {
b.iter_batched_ref(
BenchShell::default,
|shell| shell.execute_tx(&signed_tx),
criterion::BatchSize::LargeInput,
)
});
}

fn reactivate_validator(c: &mut Criterion) {
let signed_tx = generate_tx(
TX_REACTIVATE_VALIDATOR_WASM,
defaults::validator_address(),
None,
None,
Some(&defaults::validator_keypair()),
);

c.bench_function("reactivate_validator", |b| {
b.iter_batched_ref(
|| {
let mut shell = BenchShell::default();

// Deactivate the validator
let pos_params = read_pos_params(&shell.wl_storage).unwrap();
let current_epoch = shell.wl_storage.storage.block.epoch;
proof_of_stake::deactivate_validator(
&mut shell.wl_storage,
&defaults::validator_address(),
current_epoch,
)
.unwrap();

shell.wl_storage.commit_tx();
shell.commit();
// Advance by slash epoch offset epochs
for _ in 0..=pos_params.pipeline_len {
shell.advance_epoch();
}

shell
},
|shell| shell.execute_tx(&signed_tx),
criterion::BatchSize::LargeInput,
)
});
}

criterion_group!(
whitelisted_txs,
transfer,
Expand All @@ -733,6 +791,8 @@ criterion_group!(
init_validator,
change_validator_commission,
ibc,
unjail_validator
unjail_validator,
deactivate_validator,
reactivate_validator
);
criterion_main!(whitelisted_txs);
Loading
Loading