explorerd/rpc/transactions.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
/* This file is part of DarkFi (https://dark.fi)
*
* Copyright (C) 2020-2025 Dyne.org foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use tinyjson::JsonValue;
use darkfi::{rpc::jsonrpc::parse_json_array_string, Result};
use darkfi_sdk::tx::TransactionHash;
use crate::{error::ExplorerdError, Explorerd};
impl Explorerd {
// RPCAPI:
// Queries the database to retrieve the transactions corresponding to the provided block header hash.
// Returns the readable transactions upon success.
//
// **Params:**
// * `array[0]`: `String` Block header hash
//
// **Returns:**
// * Array of `TransactionRecord` encoded into a JSON.
//
// **Example API Usage:**
// --> {"jsonrpc": "2.0", "method": "transactions.get_transactions_by_header_hash", "params": ["5cc...2f9"], "id": 1}
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
pub async fn transactions_get_transactions_by_header_hash(
&self,
params: &JsonValue,
) -> Result<JsonValue> {
// Extract header hash
let header_hash = parse_json_array_string("header_hash", 0, params)?;
// Retrieve transactions by header hash
let transactions = self.service.get_transactions_by_header_hash(&header_hash)?;
// Convert transactions into a JSON array, return result
Ok(JsonValue::Array(transactions.iter().map(|tx| tx.to_json_array()).collect()))
}
// RPCAPI:
// Queries the database to retrieve the transaction corresponding to the provided hash.
// Returns the readable transaction upon success.
//
// **Params:**
// * `array[0]`: `String` Transaction hash
//
// **Returns:**
// * `TransactionRecord` encoded into a JSON.
//
// **Example API Usage:**
// --> {"jsonrpc": "2.0", "method": "transactions.get_transaction_by_hash", "params": ["7e7...b4d"], "id": 1}
// <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
pub async fn transactions_get_transaction_by_hash(
&self,
params: &JsonValue,
) -> Result<JsonValue> {
// Extract transaction hash
let tx_hash_str = parse_json_array_string("tx_hash", 0, params)?;
// Convert the provided hash into a `TransactionHash` instance
let tx_hash = tx_hash_str
.parse::<TransactionHash>()
.map_err(|_| ExplorerdError::InvalidTxHash(tx_hash_str.to_string()))?;
// Retrieve the transaction by its hash, returning the result as a JsonValue array
match self.service.get_transaction_by_hash(&tx_hash)? {
Some(transaction) => Ok(transaction.to_json_array()),
None => Ok(JsonValue::Array(vec![])),
}
}
}
#[cfg(test)]
/// Test module for validating the functionality of RPC methods related to explorer transactions.
/// Focuses on ensuring proper error handling for invalid parameters across several use cases,
/// including cases with missing values, unsupported types, and unparsable inputs.
mod tests {
use crate::test_utils::{
setup, validate_invalid_rpc_header_hash, validate_invalid_rpc_tx_hash,
};
#[test]
/// Tests the handling of invalid parameters for the `transactions.get_transactions_by_header_hash` JSON-RPC method.
/// Verifies that missing and an invalid `header_hash` value results in an appropriate error.
fn test_transactions_get_transactions_by_header_hash() {
smol::block_on(async {
// Define the RPC method name
let rpc_method = "transactions.get_transactions_by_header_hash";
// Set up the explorerd
let explorerd = setup();
// Validate when provided with an invalid header hash
validate_invalid_rpc_header_hash(&explorerd, rpc_method);
});
}
#[test]
/// Tests the handling of invalid parameters for the `transactions.get_transaction_by_hash` JSON-RPC method.
/// Verifies that missing and an invalid `tx_hash` value results in an appropriate error.
fn test_transactions_get_transaction_by_hash() {
smol::block_on(async {
// Define the RPC method name
let rpc_method = "transactions.get_transaction_by_hash";
// Set up the explorerd
let explorerd = setup();
// Validate when provided with an invalid tx hash
validate_invalid_rpc_tx_hash(&explorerd, rpc_method);
});
}
}