diff --git a/contracts/stake/tests/partial_stake.rs b/contracts/stake/tests/partial_stake.rs index 537d4b03d..6dcff4f22 100644 --- a/contracts/stake/tests/partial_stake.rs +++ b/contracts/stake/tests/partial_stake.rs @@ -52,6 +52,7 @@ fn stake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, stake_1, GAS_LIMIT, GAS_PRICE, @@ -79,6 +80,7 @@ fn stake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, stake_2, GAS_LIMIT, GAS_PRICE, @@ -112,6 +114,7 @@ fn stake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, stake_3, GAS_LIMIT, GAS_PRICE, @@ -146,6 +149,7 @@ fn stake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, stake_4, GAS_LIMIT, GAS_PRICE, @@ -179,6 +183,7 @@ fn unstake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, STAKE_VALUE, GAS_LIMIT, GAS_PRICE, @@ -200,6 +205,7 @@ fn unstake() -> Result<(), PiecrustError> { rng, &moonlight_sk, &stake_sk, + &stake_sk, unstake_1, GAS_LIMIT, GAS_PRICE, @@ -229,6 +235,7 @@ fn unstake() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, unstake_1, GAS_LIMIT, GAS_PRICE, @@ -254,6 +261,7 @@ fn unstake() -> Result<(), PiecrustError> { rng, &moonlight_sk, &stake_sk, + &stake_sk, unstake_2, GAS_LIMIT, GAS_PRICE, @@ -291,6 +299,7 @@ fn unstake() -> Result<(), PiecrustError> { rng, &moonlight_sk, &stake_sk, + &stake_sk, unstake_3, GAS_LIMIT, GAS_PRICE, @@ -333,6 +342,7 @@ fn withdraw_reward() -> Result<(), PiecrustError> { let tx = moonlight_stake( &moonlight_sk, &stake_sk, + &stake_sk, STAKE_VALUE, GAS_LIMIT, GAS_PRICE, @@ -357,6 +367,7 @@ fn withdraw_reward() -> Result<(), PiecrustError> { rng, &moonlight_sk, &stake_sk, + &stake_sk, reward_withdawal_1, GAS_LIMIT, GAS_PRICE, @@ -391,6 +402,7 @@ fn withdraw_reward() -> Result<(), PiecrustError> { rng, &moonlight_sk, &stake_sk, + &stake_sk, reward_withdawal_2, GAS_LIMIT, GAS_PRICE, diff --git a/contracts/stake/tests/stake.rs b/contracts/stake/tests/stake.rs index 7719bd700..265405499 100644 --- a/contracts/stake/tests/stake.rs +++ b/contracts/stake/tests/stake.rs @@ -64,7 +64,7 @@ fn stake_withdraw_unstake() { // Stake // Fashion a Stake struct - let stake = Stake::new(&stake_sk, INITIAL_STAKE, CHAIN_ID); + let stake = Stake::new(&stake_sk, &stake_sk, INITIAL_STAKE, CHAIN_ID); let stake_bytes = rkyv::to_bytes::<_, 1024>(&stake) .expect("Should serialize Stake correctly") .to_vec(); @@ -153,7 +153,7 @@ fn stake_withdraw_unstake() { input_notes[1].gen_nullifier(&phoenix_sender_sk), ]), ); - let withdraw = StakeWithdraw::new(&stake_sk, withdraw); + let withdraw = StakeWithdraw::new(&stake_sk, &stake_sk, withdraw); let withdraw_bytes = rkyv::to_bytes::<_, 2048>(&withdraw) .expect("Serializing Withdraw should succeed") @@ -248,7 +248,7 @@ fn stake_withdraw_unstake() { ]), ); - let unstake = StakeWithdraw::new(&stake_sk, withdraw); + let unstake = StakeWithdraw::new(&stake_sk, &stake_sk, withdraw); let unstake_bytes = rkyv::to_bytes::<_, 2048>(&unstake) .expect("Serializing Unstake should succeed") diff --git a/execution-core/src/stake.rs b/execution-core/src/stake.rs index a99960602..de74d9227 100644 --- a/execution-core/src/stake.rs +++ b/execution-core/src/stake.rs @@ -51,12 +51,18 @@ impl Stake { const MESSAGE_SIZE: usize = 1 + BlsPublicKey::SIZE + BlsPublicKey::SIZE + u64::SIZE; - /// Create a new stake. + /// Create a new stake specifying the owner. #[must_use] - pub fn new(sk: &BlsSecretKey, value: u64, chain_id: u8) -> Self { - let key = BlsPublicKey::from(sk); + pub fn new( + account_sk: &BlsSecretKey, + owner_sk: &BlsSecretKey, + value: u64, + chain_id: u8, + ) -> Self { + let account = BlsPublicKey::from(account_sk); + let owner = BlsPublicKey::from(owner_sk); - let keys = StakeKeys::single_key(key); + let keys = StakeKeys::new(account, owner); let mut stake = Stake { chain_id, @@ -68,14 +74,14 @@ impl Stake { let msg = stake.signature_message(); stake.signature = DoubleSignature { - account: sk.sign(&msg), - owner: sk.sign(&msg), + account: account_sk.sign(&msg), + owner: owner_sk.sign(&msg), }; stake } - /// Create a new stake. + /// Create a new stake from a contract. #[must_use] pub fn new_from_contract( sk: &BlsSecretKey, @@ -249,10 +255,15 @@ pub struct Withdraw { } impl Withdraw { - /// Create a new withdraw call. + /// Create a new withdraw call specifying the owner. #[must_use] - pub fn new(sk: &BlsSecretKey, withdraw: TransferWithdraw) -> Self { - let account = BlsPublicKey::from(sk); + pub fn new( + account_sk: &BlsSecretKey, + owner_sk: &BlsSecretKey, + withdraw: TransferWithdraw, + ) -> Self { + let account = BlsPublicKey::from(account_sk); + let mut stake_withdraw = Withdraw { account, withdraw, @@ -262,13 +273,22 @@ impl Withdraw { let msg = stake_withdraw.signature_message(); stake_withdraw.signature = DoubleSignature { - account: sk.sign(&msg), - owner: sk.sign(&msg), + account: account_sk.sign(&msg), + owner: owner_sk.sign(&msg), }; stake_withdraw } + /// Create a new withdraw call using the same account as the owner. + #[must_use] + pub fn with_single_key( + sk: &BlsSecretKey, + withdraw: TransferWithdraw, + ) -> Self { + Self::new(sk, sk, withdraw) + } + /// The public key to withdraw from. #[must_use] pub fn account(&self) -> &BlsPublicKey { diff --git a/rusk-wallet/src/bin/command.rs b/rusk-wallet/src/bin/command.rs index 3e0233326..75fbce712 100644 --- a/rusk-wallet/src/bin/command.rs +++ b/rusk-wallet/src/bin/command.rs @@ -159,6 +159,10 @@ pub(crate) enum Command { #[arg(long)] address: Option
, + /// Owner of the stake [default: same Public address of the stake] + #[arg(long)] + owner: Option
, + /// Amount of DUSK to stake #[arg(short, long)] amt: Dusk, @@ -393,21 +397,28 @@ impl Command { } Command::Stake { address, + owner, amt, gas_limit, gas_price, } => { let address = address.unwrap_or(wallet.default_address()); let addr_idx = wallet.find_index(&address)?; + let owner_idx = + owner.map(|owner| wallet.find_index(&owner)).transpose()?; let gas = Gas::new(gas_limit).with_price(gas_price); let tx = match address { Address::Shielded(_) => { wallet.sync().await?; - wallet.phoenix_stake(addr_idx, amt, gas).await + wallet + .phoenix_stake(addr_idx, owner_idx, amt, gas) + .await } Address::Public(_) => { - wallet.moonlight_stake(addr_idx, amt, gas).await + wallet + .moonlight_stake(addr_idx, owner_idx, amt, gas) + .await } }?; diff --git a/rusk-wallet/src/bin/interactive.rs b/rusk-wallet/src/bin/interactive.rs index 129594d64..d3330d5c1 100644 --- a/rusk-wallet/src/bin/interactive.rs +++ b/rusk-wallet/src/bin/interactive.rs @@ -373,6 +373,7 @@ fn confirm(cmd: &Command, wallet: &Wallet) -> anyhow::Result { } Command::Stake { address, + owner, amt, gas_limit, gas_price, @@ -380,8 +381,10 @@ fn confirm(cmd: &Command, wallet: &Wallet) -> anyhow::Result { let sender = address.as_ref().ok_or(Error::BadAddress)?; let max_fee = gas_limit * gas_price; let stake_to = wallet.public_address(wallet.find_index(sender)?)?; + let owner = owner.as_ref().unwrap_or(&stake_to); println!(" > Pay with {}", sender.preview()); println!(" > Stake to {}", stake_to.preview()); + println!(" > Stake owner {}", owner.preview()); println!(" > Amount to stake = {} DUSK", amt); println!(" > Max fee = {} DUSK", Dusk::from(max_fee)); if let Address::Public(_) = sender { diff --git a/rusk-wallet/src/bin/interactive/command_menu.rs b/rusk-wallet/src/bin/interactive/command_menu.rs index f995787c7..3003027e4 100644 --- a/rusk-wallet/src/bin/interactive/command_menu.rs +++ b/rusk-wallet/src/bin/interactive/command_menu.rs @@ -14,7 +14,7 @@ use rusk_wallet::gas::{ DEFAULT_PRICE, GAS_PER_DEPLOY_BYTE, MIN_PRICE_DEPLOYMENT, }; use rusk_wallet::{ - Address, Wallet, MAX_CONTRACT_INIT_ARG_SIZE, MAX_FUNCTION_NAME_SIZE, + Address, Error, Wallet, MAX_CONTRACT_INIT_ARG_SIZE, MAX_FUNCTION_NAME_SIZE, }; use super::ProfileOp; @@ -162,8 +162,29 @@ pub(crate) async fn online( let mempool_gas_prices = wallet.get_mempool_gas_prices().await?; + let stake_idx = wallet + .find_index(&addr) + .expect("index to exists in interactive mode"); + let stake_pk = wallet + .public_key(stake_idx) + .expect("public key to exists in interactive mode"); + + let owner = match wallet.find_stake_owner_account(stake_pk).await { + Ok(account) => account, + Err(Error::NotStaked) => { + let choices = wallet + .profiles() + .iter() + .map(|p| Address::Public(p.public_addr)) + .collect(); + prompt::request_address(stake_idx, choices)? + } + e => e?, + }; + ProfileOp::Run(Box::new(Command::Stake { address: Some(addr), + owner: Some(owner), amt: prompt::request_stake_token_amt(balance)?, gas_limit: prompt::request_gas_limit(gas::DEFAULT_LIMIT_CALL)?, gas_price: prompt::request_gas_price( diff --git a/rusk-wallet/src/bin/io/prompt.rs b/rusk-wallet/src/bin/io/prompt.rs index ecae173c9..7498d2c19 100644 --- a/rusk-wallet/src/bin/io/prompt.rs +++ b/rusk-wallet/src/bin/io/prompt.rs @@ -354,6 +354,19 @@ pub(crate) fn request_transaction_model() -> anyhow::Result { ) } +/// Request transaction model to use +pub(crate) fn request_address( + current_idx: u8, + choices: Vec
, +) -> anyhow::Result
{ + Ok(Select::new( + "Please select the moonlight address to use as stake owner", + choices, + ) + .with_starting_cursor(current_idx as usize) + .prompt()?) +} + /// Request contract WASM file location pub(crate) fn request_contract_code() -> anyhow::Result { let validator = |path_str: &str| { diff --git a/rusk-wallet/src/clients.rs b/rusk-wallet/src/clients.rs index 2836efa92..368074d86 100644 --- a/rusk-wallet/src/clients.rs +++ b/rusk-wallet/src/clients.rs @@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex}; use dusk_bytes::Serializable; use execution_core::signatures::bls::PublicKey as BlsPublicKey; +use execution_core::stake::{StakeFundOwner, StakeKeys}; use execution_core::transfer::moonlight::AccountData; use execution_core::transfer::phoenix::{Note, NoteLeaf, Prove}; use execution_core::transfer::Transaction; @@ -322,6 +323,33 @@ impl State { Ok(stake_data) } + /// Get the stake owner of a given stake account. + pub(crate) async fn fetch_stake_owner( + &self, + pk: &BlsPublicKey, + ) -> Result, Error> { + let status = self.status; + status("Fetching stake owner..."); + + // the target type of the deserialization has to match the return type + // of the contract-query + let stake_keys: Option = rkyv::from_bytes( + &self + .client + .contract_query::<_, _, 1024>( + STAKE_CONTRACT, + "get_stake_keys", + pk, + ) + .await?, + ) + .map_err(|_| Error::Rkyv)?; + + let stake_owner = stake_keys.map(|keys| keys.owner); + + Ok(stake_owner) + } + pub(crate) fn store(&self) -> &LocalStore { &self.store } diff --git a/rusk-wallet/src/wallet/transaction.rs b/rusk-wallet/src/wallet/transaction.rs index ae64f6951..cea494d5a 100644 --- a/rusk-wallet/src/wallet/transaction.rs +++ b/rusk-wallet/src/wallet/transaction.rs @@ -7,6 +7,7 @@ use std::fmt::Debug; use execution_core::signatures::bls::PublicKey as BlsPublicKey; +use execution_core::stake::StakeFundOwner; use execution_core::transfer::data::TransactionData; use execution_core::transfer::phoenix::PublicKey as PhoenixPublicKey; use execution_core::transfer::Transaction; @@ -20,7 +21,7 @@ use wallet_core::transaction::{ use zeroize::Zeroize; use super::file::SecureWalletFile; -use super::Wallet; +use super::{Address, Wallet}; use crate::clients::Prover; use crate::currency::Dusk; use crate::gas::Gas; @@ -236,6 +237,7 @@ impl Wallet { pub async fn phoenix_stake( &self, profile_idx: u8, + owner_idx: Option, amt: Dusk, gas: Gas, ) -> Result { @@ -263,6 +265,22 @@ impl Wallet { } } + let stake_owner_idx = match self.find_stake_owner_idx(stake_pk).await { + Ok(state_idx) => { + if let Some(owner_idx) = owner_idx { + if state_idx != owner_idx { + return Err(Error::Unauthorized); + } + } + state_idx + } + Err(Error::NotStaked) => owner_idx.unwrap_or(profile_idx), + Err(e) => { + return Err(e); + } + }; + let mut stake_owner_sk = self.derive_bls_sk(stake_owner_idx); + let tx_cost = amt + gas.limit * gas.price; let inputs = state .tx_input_notes(profile_idx, tx_cost) @@ -275,12 +293,22 @@ impl Wallet { let chain_id = state.fetch_chain_id().await?; let stake = phoenix_stake( - &mut rng, &sender_sk, &stake_sk, inputs, root, gas.limit, - gas.price, chain_id, amt, &Prover, + &mut rng, + &sender_sk, + &stake_sk, + &stake_owner_sk, + inputs, + root, + gas.limit, + gas.price, + chain_id, + amt, + &Prover, )?; sender_sk.zeroize(); stake_sk.zeroize(); + stake_owner_sk.zeroize(); let stake = state.prove(stake).await?; state.propagate(stake).await @@ -290,6 +318,7 @@ impl Wallet { pub async fn moonlight_stake( &self, profile_idx: u8, + owner_idx: Option, amt: Dusk, gas: Gas, ) -> Result { @@ -317,9 +346,26 @@ impl Wallet { } } + let stake_owner_idx = match self.find_stake_owner_idx(stake_pk).await { + Ok(state_idx) => { + if let Some(owner_idx) = owner_idx { + if state_idx != owner_idx { + return Err(Error::Unauthorized); + } + } + state_idx + } + Err(Error::NotStaked) => owner_idx.unwrap_or(profile_idx), + Err(e) => { + return Err(e); + } + }; + let mut stake_owner_sk = self.derive_bls_sk(stake_owner_idx); + let stake = moonlight_stake( &stake_sk, &stake_sk, + &stake_owner_sk, amt, gas.limit, gas.price, @@ -328,6 +374,7 @@ impl Wallet { )?; stake_sk.zeroize(); + stake_owner_sk.zeroize(); state.propagate(stake).await } @@ -344,9 +391,13 @@ impl Wallet { let mut sender_sk = self.derive_phoenix_sk(profile_idx); let mut stake_sk = self.derive_bls_sk(profile_idx); + let stake_pk = BlsPublicKey::from(&stake_sk); + + let stake_owner_idx = self.find_stake_owner_idx(&stake_pk).await?; + let mut stake_owner_sk = self.derive_bls_sk(stake_owner_idx); let unstake_value = state - .fetch_stake(&BlsPublicKey::from(&stake_sk)) + .fetch_stake(&stake_pk) .await? .and_then(|s| s.amount) .map(|s| s.total_funds()) @@ -366,6 +417,7 @@ impl Wallet { &mut rng, &sender_sk, &stake_sk, + &stake_owner_sk, inputs, root, unstake_value, @@ -377,6 +429,7 @@ impl Wallet { sender_sk.zeroize(); stake_sk.zeroize(); + stake_owner_sk.zeroize(); let unstake = state.prove(unstake).await?; state.propagate(unstake).await @@ -392,13 +445,13 @@ impl Wallet { let state = self.state()?; let mut stake_sk = self.derive_bls_sk(profile_idx); - let pk = self.public_key(profile_idx)?; + let stake_pk = self.public_key(profile_idx)?; let chain_id = state.fetch_chain_id().await?; - let account_nonce = state.fetch_account(pk).await?.nonce + 1; + let account_nonce = state.fetch_account(stake_pk).await?.nonce + 1; let unstake_value = state - .fetch_stake(pk) + .fetch_stake(stake_pk) .await? .and_then(|s| s.amount) .map(|s| s.total_funds()) @@ -408,10 +461,14 @@ impl Wallet { return Err(Error::NotStaked); } + let stake_owner_idx = self.find_stake_owner_idx(stake_pk).await?; + let mut stake_owner_sk = self.derive_bls_sk(stake_owner_idx); + let unstake = moonlight_unstake( &mut rng, &stake_sk, &stake_sk, + &stake_owner_sk, unstake_value, gas.limit, gas.price, @@ -420,6 +477,7 @@ impl Wallet { )?; stake_sk.zeroize(); + stake_owner_sk.zeroize(); state.propagate(unstake).await } @@ -442,16 +500,22 @@ impl Wallet { let root = state.fetch_root().await?; let chain_id = state.fetch_chain_id().await?; + let stake_pk = BlsPublicKey::from(&stake_sk); + let reward_amount = state - .fetch_stake(&BlsPublicKey::from(&stake_sk)) + .fetch_stake(&stake_pk) .await? .map(|s| s.reward) .unwrap_or(0); + let stake_owner_idx = self.find_stake_owner_idx(&stake_pk).await?; + let mut stake_owner_sk = self.derive_bls_sk(stake_owner_idx); + let withdraw = phoenix_stake_reward( &mut rng, &sender_sk, &stake_sk, + &stake_owner_sk, inputs, root, reward_amount, @@ -463,6 +527,7 @@ impl Wallet { sender_sk.zeroize(); stake_sk.zeroize(); + stake_owner_sk.zeroize(); let withdraw = state.prove(withdraw).await?; state.propagate(withdraw).await @@ -485,13 +550,22 @@ impl Wallet { let reward = Dusk::from(reward); let mut sender_sk = self.derive_bls_sk(sender_idx); + let mut stake_owner_sk = self.derive_bls_sk(sender_idx); let withdraw = moonlight_stake_reward( - &mut rng, &sender_sk, &sender_sk, *reward, gas.limit, gas.price, - nonce, chain_id, + &mut rng, + &sender_sk, + &sender_sk, + &stake_owner_sk, + *reward, + gas.limit, + gas.price, + nonce, + chain_id, )?; sender_sk.zeroize(); + stake_owner_sk.zeroize(); state.propagate(withdraw).await } @@ -644,4 +718,31 @@ impl Wallet { state.propagate(deploy).await } + + /// Finds the index of the stake owner account. + pub async fn find_stake_owner_idx( + &self, + stake_pk: &BlsPublicKey, + ) -> Result { + self.find_index(&self.find_stake_owner_account(stake_pk).await?) + } + + /// Finds the address of the stake owner account. + pub async fn find_stake_owner_account( + &self, + stake_pk: &BlsPublicKey, + ) -> Result { + let stake_owner = self + .state()? + .fetch_stake_owner(stake_pk) + .await? + .ok_or(Error::NotStaked)?; + + match stake_owner { + StakeFundOwner::Account(public_key) => { + Ok(Address::Public(public_key)) + } + StakeFundOwner::Contract(_) => Err(Error::Unauthorized), + } + } } diff --git a/rusk/tests/services/contract_stake.rs b/rusk/tests/services/contract_stake.rs index 43038d9e0..52307a496 100644 --- a/rusk/tests/services/contract_stake.rs +++ b/rusk/tests/services/contract_stake.rs @@ -169,6 +169,7 @@ pub async fn stake_from_contract() -> Result<()> { ); let unstake = stake::Withdraw::new( + &sk, &sk, transfer::withdraw::Withdraw::new( &mut rng, @@ -206,7 +207,8 @@ pub async fn stake_from_contract() -> Result<()> { let current_reward = wallet.get_stake(0).expect("Stake to exists").reward; let withdraw = stake::Withdraw::new( - &wallet.account_secret_key(0).unwrap(), + &sk, + &sk, transfer::withdraw::Withdraw::new( &mut rng, &sk, diff --git a/test-wallet/src/imp.rs b/test-wallet/src/imp.rs index 8f614f6de..1b3a29405 100644 --- a/test-wallet/src/imp.rs +++ b/test-wallet/src/imp.rs @@ -510,6 +510,7 @@ where rng, &phoenix_sender_sk, &stake_sk, + &stake_sk, inputs, root, gas_limit, @@ -566,6 +567,7 @@ where rng, &phoenix_sender_sk, &stake_sk, + &stake_sk, inputs, root, staked_amount, @@ -616,6 +618,7 @@ where rng, &phoenix_sender_sk, &stake_sk, + &stake_sk, inputs, root, stake_reward, @@ -818,6 +821,7 @@ where let tx = moonlight_stake( &sender_sk, &staker_sk, + &staker_sk, stake_value, gas_limit, gas_price, @@ -869,6 +873,7 @@ where rng, &sender_sk, &staker_sk, + &staker_sk, unstake_value, gas_limit, gas_price, @@ -914,6 +919,7 @@ where rng, &sender_sk, &staker_sk, + &staker_sk, staker_data.reward, gas_limit, gas_price, diff --git a/wallet-core/src/ffi.rs b/wallet-core/src/ffi.rs index 6c09752a8..76df75588 100644 --- a/wallet-core/src/ffi.rs +++ b/wallet-core/src/ffi.rs @@ -646,7 +646,7 @@ pub unsafe fn moonlight_stake( let sender_sk = derive_bls_sk(&seed, sender_index); let stake_sk = sender_sk.clone(); - let stake = Stake::new(&stake_sk, *stake_value, chain_id); + let stake = Stake::new(&stake_sk, &stake_sk, *stake_value, chain_id); let contract_call = ContractCall::new(STAKE_CONTRACT, "stake", &stake) .or(Err(ErrorCode::ContractCallError))?; @@ -710,6 +710,7 @@ pub unsafe fn moonlight_unstake( &mut rng, &sender_sk, &stake_sk, + &stake_sk, gas_payment_token, *unstake_value, ) @@ -774,6 +775,7 @@ pub unsafe fn moonlight_stake_reward( &mut rng, &sender_sk, &stake_sk, + &stake_sk, gas_payment_token, *reward_amount, ) diff --git a/wallet-core/src/transaction.rs b/wallet-core/src/transaction.rs index 9bcab708d..c6bf02a47 100644 --- a/wallet-core/src/transaction.rs +++ b/wallet-core/src/transaction.rs @@ -144,6 +144,7 @@ pub fn phoenix_stake( rng: &mut R, phoenix_sender_sk: &PhoenixSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, inputs: Vec<(Note, NoteOpening)>, root: BlsScalar, gas_limit: u64, @@ -160,7 +161,7 @@ pub fn phoenix_stake( let is_transfer = false; let deposit = stake_value; - let stake = Stake::new(stake_sk, stake_value, chain_id); + let stake = Stake::new(stake_sk, stake_owner_sk, stake_value, chain_id); let contract_call = ContractCall::new(STAKE_CONTRACT, "stake", &stake)?; @@ -195,6 +196,7 @@ pub fn phoenix_stake( pub fn moonlight_stake( moonlight_sender_sk: &BlsSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, stake_value: u64, gas_limit: u64, gas_price: u64, @@ -204,7 +206,7 @@ pub fn moonlight_stake( let transfer_value = 0; let deposit = stake_value; - let stake = Stake::new(stake_sk, stake_value, chain_id); + let stake = Stake::new(stake_sk, stake_owner_sk, stake_value, chain_id); let contract_call = ContractCall::new(STAKE_CONTRACT, "stake", &stake)?; @@ -236,6 +238,7 @@ pub fn phoenix_stake_reward( rng: &mut R, phoenix_sender_sk: &PhoenixSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, inputs: Vec<(Note, NoteOpening, BlsScalar)>, root: BlsScalar, reward_amount: u64, @@ -268,6 +271,7 @@ pub fn phoenix_stake_reward( rng, phoenix_sender_sk, stake_sk, + stake_owner_sk, gas_payment_token, reward_amount, )?; @@ -304,6 +308,7 @@ pub fn moonlight_stake_reward( rng: &mut R, moonlight_sender_sk: &BlsSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, reward_amount: u64, gas_limit: u64, gas_price: u64, @@ -319,6 +324,7 @@ pub fn moonlight_stake_reward( rng, moonlight_sender_sk, stake_sk, + stake_owner_sk, gas_payment_token, reward_amount, )?; @@ -350,6 +356,7 @@ pub fn phoenix_unstake( rng: &mut R, phoenix_sender_sk: &PhoenixSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, inputs: Vec<(Note, NoteOpening, BlsScalar)>, root: BlsScalar, unstake_value: u64, @@ -382,6 +389,7 @@ pub fn phoenix_unstake( rng, phoenix_sender_sk, stake_sk, + stake_owner_sk, gas_payment_token, unstake_value, )?; @@ -418,6 +426,7 @@ pub fn moonlight_unstake( rng: &mut R, moonlight_sender_sk: &BlsSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, unstake_value: u64, gas_limit: u64, gas_price: u64, @@ -433,6 +442,7 @@ pub fn moonlight_unstake( rng, moonlight_sender_sk, stake_sk, + stake_owner_sk, gas_payment_token, unstake_value, )?; @@ -698,6 +708,7 @@ fn stake_reward_to_phoenix( rng: &mut R, phoenix_sender_sk: &PhoenixSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, gas_payment_token: WithdrawReplayToken, reward_amount: u64, ) -> Result { @@ -709,7 +720,8 @@ fn stake_reward_to_phoenix( reward_amount, ); - let reward_withdraw = StakeWithdraw::new(stake_sk, withdraw); + let reward_withdraw = + StakeWithdraw::new(stake_sk, stake_owner_sk, withdraw); ContractCall::new(STAKE_CONTRACT, "withdraw", &reward_withdraw) } @@ -718,6 +730,7 @@ pub(crate) fn stake_reward_to_moonlight( rng: &mut R, moonlight_receiver_sk: &BlsSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, gas_payment_token: WithdrawReplayToken, reward_amount: u64, ) -> Result { @@ -729,7 +742,8 @@ pub(crate) fn stake_reward_to_moonlight( reward_amount, ); - let reward_withdraw = StakeWithdraw::new(stake_sk, withdraw); + let reward_withdraw = + StakeWithdraw::new(stake_sk, stake_owner_sk, withdraw); ContractCall::new(STAKE_CONTRACT, "withdraw", &reward_withdraw) } @@ -738,6 +752,7 @@ fn unstake_to_phoenix( rng: &mut R, phoenix_sender_sk: &PhoenixSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, gas_payment_token: WithdrawReplayToken, unstake_value: u64, ) -> Result { @@ -749,7 +764,7 @@ fn unstake_to_phoenix( unstake_value, ); - let unstake = StakeWithdraw::new(stake_sk, withdraw); + let unstake = StakeWithdraw::new(stake_sk, stake_owner_sk, withdraw); ContractCall::new(STAKE_CONTRACT, "unstake", &unstake) } @@ -758,6 +773,7 @@ pub(crate) fn unstake_to_moonlight( rng: &mut R, moonlight_receiver_sk: &BlsSecretKey, stake_sk: &BlsSecretKey, + stake_owner_sk: &BlsSecretKey, gas_payment_token: WithdrawReplayToken, unstake_value: u64, ) -> Result { @@ -769,7 +785,7 @@ pub(crate) fn unstake_to_moonlight( unstake_value, ); - let unstake = StakeWithdraw::new(stake_sk, withdraw); + let unstake = StakeWithdraw::new(stake_sk, stake_owner_sk, withdraw); ContractCall::new(STAKE_CONTRACT, "unstake", &unstake) }