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

feat: More disbursal flags #171

Merged
merged 2 commits into from
Mar 2, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- Added `--disburse-amount` and `--disburse-to` to `quill neuron-manage`. (#171)
- Accepts bare principals and ICRC-1 account IDs in `quill account-balance` and `quill transfer`. (#168)
- Allowed omitting the account ID in `quill account-balance`. (#167)
- Added `--from-subaccount` to `quill transfer` and `quill neuron-stake`. (#166)
Expand Down
2 changes: 2 additions & 0 deletions docs/cli-reference/quill-neuron-manage.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ quill neuron-manage [option] <neuron id>
| `-a`, `--additional-dissolve-delay-seconds <SECONDS>` | Number of dissolve seconds to add. |
| `--add-hot-key <ADD_HOT_KEY>` | Principal to be used as a hot key. |
| `--auto-stake-maturity enabled|disabled` | Set whether new maturity should be automatically staked. |
| `--disburse-amount` | Disburse only the selected amount. |
| `--disburse-to` | Disburse to the selected NNS account instead of the controller. |
| `--follow-neurons <FOLLOW_NEURONS>...` | Defines the neuron ids of a follow rule. |
| `--follow-topic <FOLLOW_TOPIC>` | Defines the topic of a follow rule as defined [here][follow-rules]. |
| `--merge-from-neuron <MERGE_FROM_NEURON>` | Merge stake, maturity and age from the specified neuron into the managed neuron. |
Expand Down
26 changes: 19 additions & 7 deletions src/commands/neuron_manage.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::commands::transfer::parse_tokens;
use crate::lib::{
governance_canister_id,
signing::{sign_ingress_with_request_status_query, IngressWithRequestId},
AnyhowResult, AuthInfo, ROLE_NNS_GOVERNANCE,
AnyhowResult, AuthInfo, ParsedNnsAccount, ROLE_NNS_GOVERNANCE,
};
use anyhow::{anyhow, bail, Context};
use candid::{CandidType, Encode, Principal};
Expand All @@ -10,12 +11,13 @@ use ic_base_types::PrincipalId;
use ic_nns_common::pb::v1::{NeuronId, ProposalId};
use ic_nns_governance::pb::v1::{
manage_neuron::{
configure::Operation, AddHotKey, ChangeAutoStakeMaturity, Command, Configure, Disburse,
Follow, IncreaseDissolveDelay, JoinCommunityFund, LeaveCommunityFund, Merge, RegisterVote,
RemoveHotKey, Split, StakeMaturity, StartDissolving, StopDissolving,
configure::Operation, disburse::Amount, AddHotKey, ChangeAutoStakeMaturity, Command,
Configure, Disburse, Follow, IncreaseDissolveDelay, JoinCommunityFund, LeaveCommunityFund,
Merge, RegisterVote, RemoveHotKey, Split, StakeMaturity, StartDissolving, StopDissolving,
},
ManageNeuron,
};
use icp_ledger::Tokens;

// These constants are copied from src/governance.rs
pub const ONE_DAY_SECONDS: u32 = 24 * 60 * 60;
Expand Down Expand Up @@ -63,6 +65,14 @@ pub struct ManageOpts {
#[clap(long)]
disburse: bool,

/// Disburse only the selected amount, instead of the entire amount, to the controller's account.
#[clap(long, value_parser = parse_tokens)]
disburse_amount: Option<Tokens>,

/// Disburse to the selected NNS account instead of the controller.
#[clap(long)]
disburse_to: Option<ParsedNnsAccount>,

/// Spawn rewards to a new neuron under the controller's account.
#[clap(long)]
spawn: bool,
Expand Down Expand Up @@ -217,12 +227,14 @@ pub fn exec(auth: &AuthInfo, opts: ManageOpts) -> AnyhowResult<Vec<IngressWithRe
msgs.push(args);
};

if opts.disburse {
if opts.disburse || opts.disburse_amount.is_some() || opts.disburse_to.is_some() {
let args = Encode!(&ManageNeuron {
id: id.clone(),
command: Some(Command::Disburse(Disburse {
to_account: None,
amount: None
to_account: opts.disburse_to.map(|to| to.into_identifier().into()),
amount: opts.disburse_amount.map(|amount| Amount {
e8s: amount.get_e8s()
}),
})),
neuron_id_or_subaccount: None,
})?;
Expand Down
12 changes: 12 additions & 0 deletions src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ fn fmt_account(account: &Account, f: &mut Formatter<'_>) -> fmt::Result {
}
}

#[derive(Debug, Clone)]
pub enum ParsedNnsAccount {
Original(AccountIdentifier),
Icrc1(Account),
Expand Down Expand Up @@ -516,6 +517,17 @@ impl FromStr for ParsedNnsAccount {
}
}

impl ParsedNnsAccount {
pub fn into_identifier(self) -> AccountIdentifier {
match self {
Self::Original(ident) => ident,
Self::Icrc1(account) => {
AccountIdentifier::new(account.owner, account.subaccount.map(Subaccount))
}
}
}
}

#[cfg(test)]
mod tests {
use super::{ParsedAccount, ParsedSubaccount};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"$QUILL" neuron-manage 2313380519530470538 --disburse-to pnf55-r7gzn-s3oqn-ah2v7-r6b63-a2ma2-wyzhb-dzbwb-sghid-lzcxh-4ae --disburse-amount 57.31 --pem-file - | "$QUILL" send --dry-run
20 changes: 20 additions & 0 deletions tests/outputs/neuron-manage-disburse-somewhat-to-someone.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Sending message with

Call type: update
Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae
Canister id: rrkah-fqaaa-aaaaa-aaaaq-cai
Method name: manage_neuron
Arguments: (
record {
id = opt record { id = 2_313_380_519_530_470_538 : nat64 };
command = opt variant {
Disburse = record {
to_account = opt record {
hash = blob "\c6H\b8\14\e8\1dyF\e8\ba\ce\a9\92\80\e0|_Q\a0K\a7\a3\80\09\d8\ad\8e\89";
};
amount = opt record { e8s = 5_731_000_000 : nat64 };
}
};
neuron_id_or_subaccount = null;
},
)