/// Attempt to submit the transaction to the base node via RPC.
/// # Returns:
/// `Ok(true)` => Transaction was successfully submitted to UnconfirmedPool
/// `Ok(false)` => There was a problem with the RPC call and this should be retried
/// `Err(_)` => The transaction was rejected by the base node and the protocol should end.
Attempt to submit the transaction to the base node via RPC.
Attempt to submit the transaction to the base node via RPC .
async fn submit_transaction(
        &mut self,
        tx: Transaction,
        client: &mut BaseNodeWalletRpcClient,
    ) -> Result<bool, TransactionServiceProtocolError> {
        let response = match client.submit_transaction(tx.into()).await {
            Ok(r) => match TxSubmissionResponse::try_from(r) {
                Ok(r) => r,
                Err(_) => {
                    trace!(target: LOG_TARGET, "Could not convert proto TxSubmission Response");
                    return Ok(false);
                },
            },
            Err(e) => {
                info!(
                    target: LOG_TARGET,
                    "Submit Transaction RPC Call to Base Node failed: {}", e
                );
                return Ok(false);
            },
        };
        if !response.is_synced {
            info!(
                target: LOG_TARGET,
                "Base Node reports not being synced, submission will be retried."
            );
            return Ok(false);
        }
        if !response.accepted && response.rejection_reason != TxSubmissionRejectionReason::AlreadyMined {
            error!(
                target: LOG_TARGET,
                "Transaction (TxId: {}) rejected by Base Node for reason: {}", self.tx_id, response.rejection_reason
            );
            self.cancel_transaction().await;
            let _ = self
                .resources
                .event_publisher
                .send(Arc::new(TransactionEvent::TransactionCancelled(self.tx_id)))
                .map_err(|e| {
                    trace!(
                        target: LOG_TARGET,
                        "Error sending event because there are no subscribers: {:?}",
                        e
                    );
                    e
                });
            let reason = match response.rejection_reason {
                TxSubmissionRejectionReason::None | TxSubmissionRejectionReason::ValidationFailed => {
                    TransactionServiceError::MempoolRejectionInvalidTransaction
                },
                TxSubmissionRejectionReason::DoubleSpend => TransactionServiceError::MempoolRejectionDoubleSpend,
                TxSubmissionRejectionReason::Orphan => TransactionServiceError::MempoolRejectionOrphan,
                TxSubmissionRejectionReason::TimeLocked => TransactionServiceError::MempoolRejectionTimeLocked,
                _ => TransactionServiceError::UnexpectedBaseNodeResponse,
            };
            return Err(TransactionServiceProtocolError::new(self.tx_id, reason));
        } else if response.rejection_reason == TxSubmissionRejectionReason::AlreadyMined {
            info!(
                target: LOG_TARGET,
                "Transaction (TxId: {}) is Already Mined according to Base Node.", self.tx_id
            );
            self.resources
                .db
                .mine_completed_transaction(self.tx_id)
                .await
                .map_err(|e| TransactionServiceProtocolError::new(self.tx_id, TransactionServiceError::from(e)))?;
        } else {
            info!(
                target: LOG_TARGET,
                "Transaction (TxId: {}) successfully submitted to UnconfirmedPool", self.tx_id
            );
            self.resources
                .db
                .broadcast_completed_transaction(self.tx_id)
                .await
                .map_err(|e| TransactionServiceProtocolError::new(self.tx_id, TransactionServiceError::from(e)))?;
            let _ = self
                .resources
                .event_publisher
                .send(Arc::new(TransactionEvent::TransactionBroadcast(self.tx_id)))
                .map_err(|e| {
                    trace!(
                        target: LOG_TARGET,
                        "Error sending event, usually because there are no subscribers: {:?}",
                        e
                    );
                    e
                });
        }
        Ok(true)
    }
async fn submit_transaction ( & mut self , tx : Transaction , client : & mut BaseNodeWalletRpcClient , ) -> Result < bool , TransactionServiceProtocolError > { let response = match client . submit_transaction ( tx . into ( ) ) . await { Ok ( r ) => match TxSubmissionResponse :: try_from ( r ) { Ok ( r ) => r , Err ( _ ) => { trace ! ( target LOG_TARGET " " ) ; return Ok ( false ) ; } , } , Err ( e ) => { info ! ( target LOG_TARGET " " e ) ; return Ok ( false ) ; } , } ; if ! response . is_synced { info ! ( target LOG_TARGET " " ) ; return Ok ( false ) ; } if ! response . accepted && response . rejection_reason != TxSubmissionRejectionReason :: AlreadyMined { error ! ( target LOG_TARGET " " self tx_id response rejection_reason ) ; self . cancel_transaction ( ) . await ; let _ = self . resources . event_publisher . send ( Arc :: new ( TransactionEvent :: TransactionCancelled ( self . tx_id ) ) ) . map_err ( | e | { trace ! ( target LOG_TARGET " " e ) ; e } ) ; let reason = match response . rejection_reason { TxSubmissionRejectionReason :: None | TxSubmissionRejectionReason :: ValidationFailed => { TransactionServiceError :: MempoolRejectionInvalidTransaction } , TxSubmissionRejectionReason :: DoubleSpend => TransactionServiceError :: MempoolRejectionDoubleSpend , TxSubmissionRejectionReason :: Orphan => TransactionServiceError :: MempoolRejectionOrphan , TxSubmissionRejectionReason :: TimeLocked => TransactionServiceError :: MempoolRejectionTimeLocked , _ => TransactionServiceError :: UnexpectedBaseNodeResponse , } ; return Err ( TransactionServiceProtocolError :: new ( self . tx_id , reason ) ) ; } else if response . rejection_reason == TxSubmissionRejectionReason :: AlreadyMined { info ! ( target LOG_TARGET " " self tx_id ) ; self . resources . db . mine_completed_transaction ( self . tx_id ) . await . map_err ( | e | TransactionServiceProtocolError :: new ( self . tx_id , TransactionServiceError :: from ( e ) ) ) ? ; } else { info ! ( target LOG_TARGET " " self tx_id ) ; self . resources . db . broadcast_completed_transaction ( self . tx_id ) . await . map_err ( | e | TransactionServiceProtocolError :: new ( self . tx_id , TransactionServiceError :: from ( e ) ) ) ? ; let _ = self . resources . event_publisher . send ( Arc :: new ( TransactionEvent :: TransactionBroadcast ( self . tx_id ) ) ) . map_err ( | e | { trace ! ( target LOG_TARGET " " e ) ; e } ) ; } Ok ( true ) }
Attempt to submit the transaction to the base node via RPC.
Attempt to submit the transaction to the base node via RPC .
&mut self
tx
Transaction
client
&mut BaseNodeWalletRpcClient
returns:
`Ok(true)` => Transaction was successfully submitted to UnconfirmedPool
`Ok(false)` => There was a problem with the RPC call and this should be retried
`Err(_)` => The transaction was rejected by the base node and the protocol should end.
` Ok ( true ) ` = > Transaction was successfully submitted to UnconfirmedPool ` Ok ( false ) ` = > There was a problem with the RPC call and this should be retried ` Err ( _ ) ` = > The transaction was rejected by the base node and the protocol should end .