Skip to content

Commit

Permalink
Merge branch 'brent/pos-redelegation' (#1612)
Browse files Browse the repository at this point in the history
* brent/pos-redelegation:
  SQUASHED redelegation
  • Loading branch information
brentstone committed Oct 16, 2023
2 parents 2e95338 + 68b5704 commit 64a42d6
Show file tree
Hide file tree
Showing 53 changed files with 15,103 additions and 2,089 deletions.
45 changes: 12 additions & 33 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ num-traits = "0.2.14"
once_cell = "1.8.0"
orion = "0.16.0"
paste = "1.0.9"
pretty_assertions = "0.7.2"
pretty_assertions = "1.4.0"
primitive-types = "0.12.1"
proptest = "1.2.0"
proptest-state-machine = "0.1.0"
Expand Down Expand Up @@ -147,7 +147,8 @@ tracing-log = "0.1.2"
tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]}
wasmparser = "0.107.0"
winapi = "0.3.9"
zeroize = {version = "1.5.5", features = ["zeroize_derive"]}
yansi = "0.5.1"
zeroize = { version = "1.5.5", features = ["zeroize_derive"] }

[profile.release]
lto = true
Expand Down
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ NAMADA_E2E_DEBUG ?= true
RUST_BACKTRACE ?= 1
NAMADA_MASP_TEST_SEED ?= 0
PROPTEST_CASES ?= 100
# Disable shrinking in `make test-pos-sm` for CI runs. If the test fail in CI,
# we only want to get the seed.
PROPTEST_MAX_SHRINK_ITERS ?= 0

cargo := $(env) cargo
rustup := $(env) rustup
Expand Down Expand Up @@ -211,11 +214,13 @@ test-debug:
test-benches:
$(cargo) +$(nightly) test --package namada_benchmarks --benches

# Run PoS state machine tests
# Run PoS state machine tests with shrinking disabled by default (can be
# overriden with `PROPTEST_MAX_SHRINK_ITERS`)
test-pos-sm:
cd proof_of_stake && \
RUST_BACKTRACE=1 \
RUST_BACKTRACE=1 \
PROPTEST_CASES=$(PROPTEST_CASES) \
PROPTEST_MAX_SHRINK_ITERS=$(PROPTEST_MAX_SHRINK_ITERS) \
RUSTFLAGS='-C debuginfo=2 -C debug-assertions=true -C overflow-checks=true' \
cargo test pos_state_machine_test --release

Expand Down
88 changes: 87 additions & 1 deletion apps/src/lib/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ pub mod cmds {
.subcommand(Bond::def().display_order(2))
.subcommand(Unbond::def().display_order(2))
.subcommand(Withdraw::def().display_order(2))
.subcommand(Redelegate::def().display_order(2))
.subcommand(TxCommissionRateChange::def().display_order(2))
// Ethereum bridge transactions
.subcommand(AddToEthBridgePool::def().display_order(3))
Expand Down Expand Up @@ -285,6 +286,7 @@ pub mod cmds {
let bond = Self::parse_with_ctx(matches, Bond);
let unbond = Self::parse_with_ctx(matches, Unbond);
let withdraw = Self::parse_with_ctx(matches, Withdraw);
let redelegate = Self::parse_with_ctx(matches, Redelegate);
let query_epoch = Self::parse_with_ctx(matches, QueryEpoch);
let query_account = Self::parse_with_ctx(matches, QueryAccount);
let query_transfers = Self::parse_with_ctx(matches, QueryTransfers);
Expand Down Expand Up @@ -328,6 +330,7 @@ pub mod cmds {
.or(bond)
.or(unbond)
.or(withdraw)
.or(redelegate)
.or(add_to_eth_bridge_pool)
.or(tx_update_steward_commission)
.or(tx_resign_steward)
Expand Down Expand Up @@ -402,6 +405,7 @@ pub mod cmds {
Bond(Bond),
Unbond(Unbond),
Withdraw(Withdraw),
Redelegate(Redelegate),
AddToEthBridgePool(AddToEthBridgePool),
TxUpdateStewardCommission(TxUpdateStewardCommission),
TxResignSteward(TxResignSteward),
Expand Down Expand Up @@ -1425,6 +1429,27 @@ pub mod cmds {
}
}

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

impl SubCmd for Redelegate {
const CMD: &'static str = "redelegate";

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

fn def() -> App {
App::new(Self::CMD)
.about(
"Redelegate bonded tokens from one validator to another.",
)
.add_args::<args::Redelegate<args::CliTypes>>()
}
}

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

Expand Down Expand Up @@ -2552,6 +2577,7 @@ 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_REDELEGATE_WASM: &str = "tx_redelegate.wasm";
pub const TX_UPDATE_VP_WASM: &str = "tx_update_vp.wasm";
pub const TX_UPDATE_STEWARD_COMMISSION: &str =
"tx_update_steward_commission.wasm";
Expand Down Expand Up @@ -2582,7 +2608,7 @@ pub mod args {
arg_default(
"pool-gas-amount",
DefaultFn(|| token::DenominatedAmount {
amount: token::Amount::default(),
amount: token::Amount::zero(),
denom: NATIVE_MAX_DECIMAL_PLACES.into(),
}),
);
Expand Down Expand Up @@ -2615,6 +2641,8 @@ pub mod args {
pub const DATA_PATH: Arg<PathBuf> = arg("data-path");
pub const DECRYPT: ArgFlag = flag("decrypt");
pub const DISPOSABLE_SIGNING_KEY: ArgFlag = flag("disposable-gas-payer");
pub const DESTINATION_VALIDATOR: Arg<WalletAddress> =
arg("destination-validator");
pub const DONT_ARCHIVE: ArgFlag = flag("dont-archive");
pub const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm");
pub const DRY_RUN_TX: ArgFlag = flag("dry-run");
Expand Down Expand Up @@ -2719,6 +2747,7 @@ pub mod args {
pub const SOURCE: Arg<WalletAddress> = arg("source");
pub const SOURCE_OPT: ArgOpt<WalletAddress> = SOURCE.opt();
pub const STEWARD: Arg<WalletAddress> = arg("steward");
pub const SOURCE_VALIDATOR: Arg<WalletAddress> = arg("source-validator");
pub const STORAGE_KEY: Arg<storage::Key> = arg("storage-key");
pub const SUSPEND_ACTION: ArgFlag = flag("suspend");
pub const TIMEOUT_HEIGHT: ArgOpt<u64> = arg_opt("timeout-height");
Expand Down Expand Up @@ -4019,6 +4048,63 @@ pub mod args {
}
}

impl CliToSdk<Redelegate<SdkTypes>> for Redelegate<CliTypes> {
fn to_sdk(self, ctx: &mut Context) -> Redelegate<SdkTypes> {
Redelegate::<SdkTypes> {
tx: self.tx.to_sdk(ctx),
src_validator: ctx.get(&self.src_validator),
dest_validator: ctx.get(&self.dest_validator),
owner: ctx.get(&self.owner),
amount: self.amount,
tx_code_path: self.tx_code_path.to_path_buf(),
}
}
}

impl Args for Redelegate<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let tx = Tx::parse(matches);
let src_validator = SOURCE_VALIDATOR.parse(matches);
let dest_validator = DESTINATION_VALIDATOR.parse(matches);
let owner = OWNER.parse(matches);
let amount = AMOUNT.parse(matches);
let amount = amount
.canonical()
.increase_precision(NATIVE_MAX_DECIMAL_PLACES.into())
.unwrap_or_else(|e| {
println!("Could not parse bond amount: {:?}", e);
safe_exit(1);
})
.amount;
let tx_code_path = PathBuf::from(TX_REDELEGATE_WASM);
Self {
tx,
src_validator,
dest_validator,
owner,
amount,
tx_code_path,
}
}

fn def(app: App) -> App {
app.add_args::<Tx<CliTypes>>()
.arg(
SOURCE_VALIDATOR
.def()
.help("Source validator address for the redelegation."),
)
.arg(DESTINATION_VALIDATOR.def().help(
"Destination validator address for the redelegation.",
))
.arg(OWNER.def().help(
"Delegator (owner) address of the bonds that are being \
redelegated.",
))
.arg(AMOUNT.def().help("Amount of tokens to redelegate."))
}
}

impl CliToSdk<InitProposal<SdkTypes>> for InitProposal<CliTypes> {
fn to_sdk(self, ctx: &mut Context) -> InitProposal<SdkTypes> {
InitProposal::<SdkTypes> {
Expand Down
11 changes: 11 additions & 0 deletions apps/src/lib/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ impl CliApi {
let namada = ctx.to_sdk(&client, io);
tx::submit_withdraw(&namada, args).await?;
}
Sub::Redelegate(Redelegate(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_redelegate(&namada, args).await?;
}
Sub::TxCommissionRateChange(TxCommissionRateChange(
mut args,
)) => {
Expand Down
22 changes: 11 additions & 11 deletions apps/src/lib/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ use namada::core::ledger::pgf::parameters::PgfParameters;
use namada::core::ledger::pgf::storage::steward::StewardDetail;
use namada::ledger::events::Event;
use namada::ledger::parameters::{storage as param_storage, EpochDuration};
use namada::ledger::pos::{CommissionPair, PosParams, Slash};
use namada::ledger::pos::types::{CommissionPair, Slash};
use namada::ledger::pos::PosParams;
use namada::ledger::queries::RPC;
use namada::ledger::storage::ConversionState;
use namada::proof_of_stake::types::{ValidatorState, WeightedValidator};
Expand Down Expand Up @@ -1450,7 +1451,7 @@ pub async fn query_and_print_unbonds<'a>(
query_unbond_with_slashing(context.client(), source, validator).await;
let current_epoch = query_epoch(context.client()).await.unwrap();

let mut total_withdrawable = token::Amount::default();
let mut total_withdrawable = token::Amount::zero();
let mut not_yet_withdrawable = HashMap::<Epoch, token::Amount>::new();
for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() {
if withdraw_epoch <= current_epoch {
Expand All @@ -1461,7 +1462,7 @@ pub async fn query_and_print_unbonds<'a>(
*withdrawable_amount += amount;
}
}
if total_withdrawable != token::Amount::default() {
if !total_withdrawable.is_zero() {
display_line!(
context.io(),
"Total withdrawable now: {}.",
Expand Down Expand Up @@ -1537,7 +1538,7 @@ pub async fn query_bonds<'a>(
bond.amount.to_string_native()
)?;
}
if details.bonds_total != token::Amount::zero() {
if !details.bonds_total.is_zero() {
display_line!(
context.io(),
&mut w;
Expand Down Expand Up @@ -2331,13 +2332,12 @@ pub async fn get_bond_amount_at<C: namada::ledger::queries::Client + Sync>(
validator: &Address,
epoch: Epoch,
) -> Option<token::Amount> {
let (_total, total_active) =
unwrap_client_response::<C, (token::Amount, token::Amount)>(
RPC.vp()
.pos()
.bond_with_slashing(client, delegator, validator, &Some(epoch))
.await,
);
let total_active = unwrap_client_response::<C, token::Amount>(
RPC.vp()
.pos()
.bond_with_slashing(client, delegator, validator, &Some(epoch))
.await,
);
Some(total_active)
}

Expand Down
Loading

0 comments on commit 64a42d6

Please sign in to comment.