Add claim and compound wallet endpoints, proc_macro to generate execute and simulate

This commit is contained in:
durch
2022-06-06 11:21:35 +02:00
parent ec799cf17c
commit df1926071a
15 changed files with 416 additions and 153 deletions
Generated
+9
View File
@@ -1602,6 +1602,14 @@ dependencies = [
"uint",
]
[[package]]
name = "execute"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "explorer-api"
version = "1.0.1"
@@ -6257,6 +6265,7 @@ dependencies = [
"cosmrs",
"cosmwasm-std",
"cw3",
"execute",
"flate2",
"futures",
"itertools",
+1
View File
@@ -31,6 +31,7 @@ members = [
"common/credentials",
"common/crypto",
"common/crypto/dkg",
"common/execute",
"common/bandwidth-claim-contract",
"common/cosmwasm-smart-contracts/coconut-bandwidth-contract",
"common/cosmwasm-smart-contracts/contracts-common",
@@ -41,6 +41,7 @@ flate2 = { version = "1.0.20", optional = true }
sha2 = { version = "0.9.5", optional = true }
itertools = { version = "0.10", optional = true }
cosmwasm-std = { version = "1.0.0-beta8", optional = true }
execute = { path = "../../execute" }
[dev-dependencies]
ts-rs = "6.1.2"
@@ -14,6 +14,7 @@ use cosmrs::rpc::Error as TendermintRpcError;
use cosmrs::rpc::HttpClientUrl;
use cosmrs::tx::Msg;
use cosmwasm_std::Uint128;
use execute::execute;
pub use fee::gas_price::GasPrice;
use mixnet_contract_common::mixnode::DelegationEvent;
use mixnet_contract_common::{
@@ -26,6 +27,7 @@ use mixnet_contract_common::{
use network_defaults::DEFAULT_NETWORK;
use serde::Serialize;
use std::convert::TryInto;
use vesting_contract_common::ExecuteMsg as VestingExecuteMsg;
pub use crate::nymd::cosmwasm_client::client::CosmWasmClient;
pub use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient;
@@ -848,87 +850,93 @@ impl<C> NymdClient<C> {
.await
}
pub async fn compound_operator_reward(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>
#[execute("mixnet")]
fn _compound_operator_reward(&self, fee: Option<Fee>) -> (ExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::CompoundOperatorReward {};
self.client
.execute(
self.address(),
self.mixnet_contract_address(),
&req,
fee,
"MixnetContract::CompoundOperatorReward",
vec![],
)
.await
(ExecuteMsg::CompoundOperatorReward {}, fee)
}
pub async fn claim_operator_reward(&self, fee: Option<Fee>) -> Result<ExecuteResult, NymdError>
#[execute("mixnet")]
fn _claim_operator_reward(&self, fee: Option<Fee>) -> (ExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::ClaimOperatorReward {};
self.client
.execute(
self.address(),
self.mixnet_contract_address(),
&req,
fee,
"MixnetContract::ClaimOperatorReward",
vec![],
)
.await
(ExecuteMsg::ClaimOperatorReward {}, fee)
}
pub async fn compound_delegator_reward(
#[execute("mixnet")]
fn _compound_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>
) -> (ExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::CompoundDelegatorReward { mix_identity };
self.client
.execute(
self.address(),
self.mixnet_contract_address(),
&req,
fee,
"MixnetContract::CompoundDelegatorReward",
vec![],
)
.await
(ExecuteMsg::CompoundDelegatorReward { mix_identity }, fee)
}
pub async fn claim_delegator_reward(
#[execute("mixnet")]
fn _claim_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>
) -> (ExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = ExecuteMsg::ClaimDelegatorReward { mix_identity };
self.client
.execute(
self.address(),
self.mixnet_contract_address(),
&req,
fee,
"MixnetContract::ClaimDelegatorReward",
vec![],
)
.await
(ExecuteMsg::ClaimDelegatorReward { mix_identity }, fee)
}
#[execute("vesting")]
fn _vesting_compound_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> (VestingExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
(
VestingExecuteMsg::CompoundDelegatorReward { mix_identity },
fee,
)
}
#[execute("vesting")]
fn _vesting_claim_operator_reward(&self, fee: Option<Fee>) -> (VestingExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
(VestingExecuteMsg::ClaimOperatorReward {}, fee)
}
#[execute("vesting")]
fn _vesting_compound_operator_reward(
&self,
fee: Option<Fee>,
) -> (VestingExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
(VestingExecuteMsg::CompoundOperatorReward {}, fee)
}
#[execute("vesting")]
fn _vesting_claim_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> (VestingExecuteMsg, Option<Fee>)
where
C: SigningCosmWasmClient + Sync,
{
(
VestingExecuteMsg::ClaimDelegatorReward { mix_identity },
fee,
)
}
/// Announce a mixnode, paying a fee.
@@ -11,28 +11,6 @@ use vesting_contract_common::messages::{ExecuteMsg as VestingExecuteMsg, Vesting
#[async_trait]
pub trait VestingSigningClient {
async fn vesting_claim_operator_reward(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_claim_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_compound_operator_reward(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_compound_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError>;
async fn vesting_update_mixnode_config(
&self,
profix_margin_percent: u8,
@@ -397,78 +375,4 @@ impl<C: SigningCosmWasmClient + Sync + Send> VestingSigningClient for NymdClient
)
.await
}
async fn vesting_claim_operator_reward(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::ClaimOperatorReward {};
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::ClaimOperatorReward",
vec![],
)
.await
}
async fn vesting_compound_operator_reward(
&self,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::CompoundOperatorReward {};
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::CompoundOperatorReward",
vec![],
)
.await
}
async fn vesting_claim_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::ClaimDelegatorReward { mix_identity };
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::ClaimDelegatorReward",
vec![],
)
.await
}
async fn vesting_compound_delegator_reward(
&self,
mix_identity: IdentityKey,
fee: Option<Fee>,
) -> Result<ExecuteResult, NymdError> {
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
let req = VestingExecuteMsg::CompoundDelegatorReward { mix_identity };
self.client
.execute(
self.address(),
self.vesting_contract_address(),
&req,
fee,
"VestingContract::CompoundDelegatorReward",
vec![],
)
.await
}
}
+11
View File
@@ -0,0 +1,11 @@
[package]
name = "execute"
version = "0.1.0"
edition = "2021"
[lib]
proc-macro = true
[dependencies]
syn = { version = "1", features = ["full"] }
quote = "1"
+110
View File
@@ -0,0 +1,110 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{
parse_macro_input, Block, ExprMethodCall, FnArg, Ident, ItemFn, LitStr, ReturnType, Token,
VisPublic, Visibility,
};
#[proc_macro_attribute]
pub fn execute(attr: TokenStream, item: TokenStream) -> TokenStream {
let f = parse_macro_input!(item as ItemFn);
let target = parse_macro_input!(attr as LitStr).value();
let cl = if target == "mixnet" {
quote! {self.mixnet_contract_address()}
} else if target == "vesting" {
quote! {self.vesting_contract_address()}
} else {
panic!("Only `mixnet` and `vesting` targets are supported!")
};
let cl = proc_macro::TokenStream::from(cl);
let cl = parse_macro_input!(cl as ExprMethodCall);
let orig_f = f.clone();
let mut execute_f = f.clone();
let mut simulate_f = f.clone();
let name = f.sig.ident;
let name_str = name.to_string();
let call_args = f.sig.inputs.into_iter().filter_map(|arg| match arg {
FnArg::Receiver(_) => None,
FnArg::Typed(arg) => Some(arg.pat),
});
let execute_args = call_args.clone();
let simulate_args = call_args;
execute_f.sig.asyncness = Some(Token![async](execute_f.sig.ident.span()));
simulate_f.sig.asyncness = Some(Token![async](simulate_f.sig.ident.span()));
execute_f.vis = Visibility::Public(VisPublic {
pub_token: Token![pub](execute_f.sig.ident.span()),
});
simulate_f.vis = Visibility::Public(VisPublic {
pub_token: Token![pub](simulate_f.sig.ident.span()),
});
execute_f.sig.ident = Ident::new(
&format!("execute{}", execute_f.sig.ident),
execute_f.sig.ident.span(),
);
simulate_f.sig.ident = Ident::new(
&format!("simulate{}", simulate_f.sig.ident),
simulate_f.sig.ident.span(),
);
let execute_output = quote! {
-> Result<ExecuteResult, NymdError>
};
let o_ts = proc_macro::TokenStream::from(execute_output);
execute_f.sig.output = parse_macro_input!(o_ts as ReturnType);
let simulate_output = quote! {
-> Result<SimulateResponse, NymdError>
};
let o_ts = proc_macro::TokenStream::from(simulate_output);
simulate_f.sig.output = parse_macro_input!(o_ts as ReturnType);
let simulate_block = quote! {
{
let (msg, _fee) = self.#name(#(#simulate_args),*);
let msg = self.wrap_contract_execute_message(
#cl,
&msg,
vec![],
)?;
self.simulate(vec![msg]).await
}
};
let ts = proc_macro::TokenStream::from(simulate_block);
simulate_f.block = Box::new(parse_macro_input!(ts as Block));
let execute_block = quote! {
{
let (req, fee) = self.#name(#(#execute_args),*);
let fee = Fee::Auto(Some(self.simulated_gas_multiplier));
self.client
.execute(
self.address(),
#cl,
&req,
fee,
#name_str,
vec![],
)
.await
}
};
let ts = proc_macro::TokenStream::from(execute_block);
execute_f.block = Box::new(parse_macro_input!(ts as Block));
let out = quote! {
#orig_f
#execute_f
#simulate_f
};
out.into()
}
+9
View File
@@ -1537,6 +1537,14 @@ version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
[[package]]
name = "execute"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "eyre"
version = "0.6.7"
@@ -5542,6 +5550,7 @@ dependencies = [
"cosmrs",
"cosmwasm-std",
"cw3",
"execute",
"flate2",
"futures",
"itertools",
+16
View File
@@ -62,6 +62,10 @@ fn main() {
mixnet::delegate::get_reverse_mix_delegations_paged,
mixnet::delegate::undelegate_from_mixnode,
mixnet::epoch::get_current_epoch,
mixnet::rewards::claim_delegator_reward,
mixnet::rewards::claim_operator_reward,
mixnet::rewards::compound_operator_reward,
mixnet::rewards::compound_delegator_reward,
mixnet::send::send,
network_config::add_validator,
network_config::get_validator_api_urls,
@@ -84,6 +88,10 @@ fn main() {
validator_api::status::mixnode_reward_estimation,
validator_api::status::mixnode_stake_saturation,
validator_api::status::mixnode_status,
vesting::rewards::vesting_claim_delegator_reward,
vesting::rewards::vesting_claim_operator_reward,
vesting::rewards::vesting_compound_operator_reward,
vesting::rewards::vesting_compound_delegator_reward,
vesting::bond::vesting_bond_gateway,
vesting::bond::vesting_bond_mixnode,
vesting::bond::vesting_unbond_gateway,
@@ -122,6 +130,14 @@ fn main() {
simulate::vesting::simulate_vesting_unbond_mixnode,
simulate::vesting::simulate_vesting_update_mixnode,
simulate::vesting::simulate_withdraw_vested_coins,
simulate::vesting::simulate_vesting_claim_delegator_reward,
simulate::vesting::simulate_vesting_claim_operator_reward,
simulate::vesting::simulate_vesting_compound_operator_reward,
simulate::vesting::simulate_vesting_compound_delegator_reward,
simulate::mixnet::simulate_claim_delegator_reward,
simulate::mixnet::simulate_claim_operator_reward,
simulate::mixnet::simulate_compound_operator_reward,
simulate::mixnet::simulate_compound_delegator_reward,
])
.menu(Menu::new().add_default_app_submenu_if_macos())
.run(tauri::generate_context!())
@@ -3,4 +3,5 @@ pub mod admin;
pub mod bond;
pub mod delegate;
pub mod epoch;
pub mod rewards;
pub mod send;
@@ -0,0 +1,48 @@
use crate::error::BackendError;
use crate::nymd_client;
use crate::state::State;
use mixnet_contract_common::IdentityKey;
use std::sync::Arc;
use tokio::sync::RwLock;
#[tauri::command]
pub async fn claim_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_claim_operator_reward(None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn compound_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_compound_operator_reward(None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn claim_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_claim_delegator_reward(mix_identity, None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn compound_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_compound_delegator_reward(mix_identity, None)
.await?;
Ok(())
}
@@ -3,8 +3,10 @@
use crate::coin::Coin;
use crate::error::BackendError;
use crate::nymd_client;
use crate::simulate::{FeeDetails, SimulateResult};
use crate::State;
use mixnet_contract_common::IdentityKey;
use mixnet_contract_common::{ExecuteMsg, Gateway, MixNode};
use std::sync::Arc;
use tokio::sync::RwLock;
@@ -174,3 +176,49 @@ pub async fn simulate_undelegate_from_mixnode(
let result = client.nymd.simulate(vec![msg]).await?;
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_claim_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_claim_operator_reward(None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_compound_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_compound_operator_reward(None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_claim_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_claim_delegator_reward(mix_identity, None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_compound_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_compound_delegator_reward(mix_identity, None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
@@ -3,8 +3,10 @@
use crate::coin::Coin;
use crate::error::BackendError;
use crate::nymd_client;
use crate::simulate::{FeeDetails, SimulateResult};
use crate::State;
use mixnet_contract_common::IdentityKey;
use mixnet_contract_common::{Gateway, MixNode};
use std::sync::Arc;
use tokio::sync::RwLock;
@@ -152,3 +154,49 @@ pub async fn simulate_withdraw_vested_coins(
let result = client.nymd.simulate(vec![msg]).await?;
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_vesting_claim_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_vesting_claim_operator_reward(None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_vesting_compound_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_vesting_compound_operator_reward(None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_vesting_claim_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_vesting_claim_delegator_reward(mix_identity, None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
#[tauri::command]
pub async fn simulate_vesting_compound_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<FeeDetails, BackendError> {
let result = nymd_client!(state)
.simulate_vesting_compound_delegator_reward(mix_identity, None)
.await?;
let gas_price = nymd_client!(state).gas_price().clone();
Ok(SimulateResult::new(result.gas_info, gas_price).detailed_fee())
}
@@ -8,6 +8,7 @@ use vesting_contract_common::PledgeData as VestingPledgeData;
pub mod bond;
pub mod delegate;
pub mod queries;
pub mod rewards;
#[cfg_attr(test, derive(ts_rs::TS))]
#[cfg_attr(test, ts(export, export_to = "../src/types/rust/pledgedata.ts"))]
@@ -0,0 +1,48 @@
use crate::error::BackendError;
use crate::nymd_client;
use crate::state::State;
use mixnet_contract_common::IdentityKey;
use std::sync::Arc;
use tokio::sync::RwLock;
#[tauri::command]
pub async fn vesting_claim_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_vesting_claim_operator_reward(None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn vesting_compound_operator_reward(
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_vesting_compound_operator_reward(None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn vesting_claim_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_vesting_claim_delegator_reward(mix_identity, None)
.await?;
Ok(())
}
#[tauri::command]
pub async fn vesting_compound_delegator_reward(
mix_identity: IdentityKey,
state: tauri::State<'_, Arc<RwLock<State>>>,
) -> Result<(), BackendError> {
nymd_client!(state)
.execute_vesting_compound_delegator_reward(mix_identity, None)
.await?;
Ok(())
}