use std::sync::Arc;
use log::{debug, error};
use tari_core::{
base_node::rpc::{BaseNodeWalletQueryService, query_service},
chain_storage::BlockchainBackend,
mempool::{TxStorageResponse, service::MempoolHandle},
};
use tari_transaction_components::{
rpc::models::{TxSubmissionRejectionReason, TxSubmissionResponse},
transaction_components::Transaction,
};
const LOG_TARGET: &str = "c::base_node::rpc::http::handler::json_rpc::submit_transaction";
pub async fn handle<T: BlockchainBackend + 'static>(
query_service: Arc<query_service::Service<T>>,
mempool_service: &mut MempoolHandle,
transaction: Transaction,
) -> Result<TxSubmissionResponse, anyhow::Error> {
let is_synced = query_service
.get_tip_info()
.await
.map_err(|e| {
error!(target: LOG_TARGET, "Failed to get tip info: {e}");
anyhow::anyhow!("Failed to get tip info: {e}")
})?
.is_synced;
let res = match mempool_service.submit_transaction(transaction).await {
Ok(response) => {
debug!(target: LOG_TARGET, "Transaction submitted successfully: {response:?}");
match response {
TxStorageResponse::UnconfirmedPool => TxSubmissionResponse {
accepted: true,
rejection_reason: TxSubmissionRejectionReason::None,
is_synced,
details: None,
},
TxStorageResponse::NotStoredOrphan => TxSubmissionResponse {
accepted: false,
rejection_reason: TxSubmissionRejectionReason::Orphan,
is_synced,
details: None,
},
TxStorageResponse::NotStoredFeeTooLow => TxSubmissionResponse {
accepted: false,
rejection_reason: TxSubmissionRejectionReason::FeeTooLow,
is_synced,
details: None,
},
TxStorageResponse::NotStoredTimeLocked => TxSubmissionResponse {
accepted: false,
rejection_reason: TxSubmissionRejectionReason::TimeLocked,
is_synced,
details: None,
},
TxStorageResponse::NotStoredConsensus(details) | TxStorageResponse::NotStored(details) => {
TxSubmissionResponse {
accepted: false,
rejection_reason: TxSubmissionRejectionReason::ValidationFailed,
is_synced,
details,
}
},
TxStorageResponse::NotStoredAlreadySpent |
TxStorageResponse::ReorgPool |
TxStorageResponse::NotStoredAlreadyMined => TxSubmissionResponse {
accepted: false,
rejection_reason: TxSubmissionRejectionReason::AlreadyMined,
is_synced,
details: None,
},
}
},
Err(e) => {
return Err(anyhow::anyhow!("Failed to submit transaction: {e}"));
},
};
Ok(res)
}