/// Prepare a Sender Transaction Protocol for the amount and fee_per_gram specified. If required a change output
/// will be produced.
Prepare a Sender Transaction Protocol for the amount and fee_per_gram specified. If required a change output
will be produced.
Prepare a Sender Transaction Protocol for the amount and fee_per_gram specified . If required a change output will be produced .
pub async fn prepare_transaction_to_send(
        &mut self,
        amount: MicroTari,
        fee_per_gram: MicroTari,
        lock_height: Option<u64>,
        message: String,
    ) -> Result<SenderTransactionProtocol, OutputManagerError>
    {
        let (outputs, _) = self.select_utxos(amount, fee_per_gram, 1, None).await?;
        let total = outputs
            .iter()
            .fold(MicroTari::from(0), |acc, x| acc + x.unblinded_output.value);
        let offset = PrivateKey::random(&mut OsRng);
        let nonce = PrivateKey::random(&mut OsRng);
        let mut builder = SenderTransactionProtocol::builder(1);
        builder
            .with_lock_height(lock_height.unwrap_or(0))
            .with_fee_per_gram(fee_per_gram)
            .with_offset(offset.clone())
            .with_private_nonce(nonce.clone())
            .with_amount(0, amount)
            .with_message(message)
            .with_prevent_fee_gt_amount(self.resources.config.prevent_fee_gt_amount);
        for uo in outputs.iter() {
            builder.with_input(
                uo.unblinded_output.as_transaction_input(
                    &self.resources.factories.commitment,
                    uo.unblinded_output.clone().features,
                ),
                uo.unblinded_output.clone(),
            );
        }
        let fee_without_change = Fee::calculate(fee_per_gram, 1, outputs.len(), 1);
        let mut change_key: Option<PrivateKey> = None;
        // If the input values > the amount to be sent + fees_without_change then we will need to include a change
        // output
        if total > amount + fee_without_change {
            let mut key = PrivateKey::default();
            {
                let mut km = self.key_manager.lock().await;
                key = km.next_key()?.k;
            }
            self.resources.db.increment_key_index().await?;
            change_key = Some(key.clone());
            builder.with_change_secret(key);
        }
        let stp = builder
            .build::<HashDigest>(&self.resources.factories)
            .map_err(|e| OutputManagerError::BuildError(e.message))?;
        // If a change output was created add it to the pending_outputs list.
        let mut change_output = Vec::<DbUnblindedOutput>::new();
        if let Some(key) = change_key {
            change_output.push(DbUnblindedOutput::from_unblinded_output(
                UnblindedOutput {
                    value: stp.get_amount_to_self()?,
                    spending_key: key,
                    features: OutputFeatures::default(),
                },
                &self.resources.factories,
            )?);
        }
        // The Transaction Protocol built successfully so we will pull the unspent outputs out of the unspent list and
        // store them until the transaction times out OR is confirmed
        self.resources
            .db
            .encumber_outputs(stp.get_tx_id()?, outputs, change_output)
            .await?;
        debug!(
            target: LOG_TARGET,
            "Prepared transaction (TxId: {}) to send",
            stp.get_tx_id()?
        );
        debug!(
            target: LOG_TARGET_STRESS,
            "Prepared transaction (TxId: {}) to send",
            stp.get_tx_id()?
        );
        Ok(stp)
    }
pub async fn prepare_transaction_to_send ( & mut self , amount : MicroTari , fee_per_gram : MicroTari , lock_height : Option < u64 > , message : String , ) -> Result < SenderTransactionProtocol , OutputManagerError > { let ( outputs , _ ) = self . select_utxos ( amount , fee_per_gram , 1 , None ) . await ? ; let total = outputs . iter ( ) . fold ( MicroTari :: from ( 0 ) , | acc , x | acc + x . unblinded_output . value ) ; let offset = PrivateKey :: random ( & mut OsRng ) ; let nonce = PrivateKey :: random ( & mut OsRng ) ; let mut builder = SenderTransactionProtocol :: builder ( 1 ) ; builder . with_lock_height ( lock_height . unwrap_or ( 0 ) ) . with_fee_per_gram ( fee_per_gram ) . with_offset ( offset . clone ( ) ) . with_private_nonce ( nonce . clone ( ) ) . with_amount ( 0 , amount ) . with_message ( message ) . with_prevent_fee_gt_amount ( self . resources . config . prevent_fee_gt_amount ) ; for uo in outputs . iter ( ) { builder . with_input ( uo . unblinded_output . as_transaction_input ( & self . resources . factories . commitment , uo . unblinded_output . clone ( ) . features , ) , uo . unblinded_output . clone ( ) , ) ; } let fee_without_change = Fee :: calculate ( fee_per_gram , 1 , outputs . len ( ) , 1 ) ; let mut change_key : Option < PrivateKey > = None ; // If the input values > the amount to be sent + fees_without_change then we will need to include a change // output if total > amount + fee_without_change { let mut key = PrivateKey :: default ( ) ; { let mut km = self . key_manager . lock ( ) . await ; key = km . next_key ( ) ? . k ; } self . resources . db . increment_key_index ( ) . await ? ; change_key = Some ( key . clone ( ) ) ; builder . with_change_secret ( key ) ; } let stp = builder . build :: < HashDigest > ( & self . resources . factories ) . map_err ( | e | OutputManagerError :: BuildError ( e . message ) ) ? ; // If a change output was created add it to the pending_outputs list. let mut change_output = Vec :: < DbUnblindedOutput > :: new ( ) ; if let Some ( key ) = change_key { change_output . push ( DbUnblindedOutput :: from_unblinded_output ( UnblindedOutput { value : stp . get_amount_to_self ( ) ? , spending_key : key , features : OutputFeatures :: default ( ) , } , & self . resources . factories , ) ? ) ; } // The Transaction Protocol built successfully so we will pull the unspent outputs out of the unspent list and // store them until the transaction times out OR is confirmed self . resources . db . encumber_outputs ( stp . get_tx_id ( ) ? , outputs , change_output ) . await ? ; debug ! ( target LOG_TARGET " " stp get_tx_id ( ) ) ; debug ! ( target LOG_TARGET_STRESS " " stp get_tx_id ( ) ) ; Ok ( stp ) }
Prepare a Sender Transaction Protocol for the amount and fee_per_gram specified.
Prepare a Sender Transaction Protocol for the amount and fee_per_gram specified .
&mut self
amount
MicroTari
fee_per_gram
MicroTari
lock_height
Option<u64>
message
String