mirror of
https://github.com/MAGICGrants/rust-monero-explorer.git
synced 2026-01-08 20:17:58 -05:00
Better responses
This commit is contained in:
118
src/main.rs
118
src/main.rs
@@ -1,69 +1,131 @@
|
||||
use std::sync::Mutex;
|
||||
use cuprate_blockchain::{config::ConfigBuilder, ops, tables::{OpenTables, Tables}} ;
|
||||
use cuprate_database::{ConcreteEnv, DatabaseRo, Env, EnvInner};
|
||||
use cuprate_types::json::tx::Transaction;
|
||||
use hex::FromHex;
|
||||
use actix_web::{get, web, App, HttpServer, Responder};
|
||||
use actix_web::{get, web::{self}, App, HttpServer, Responder};
|
||||
use serde::Serialize;
|
||||
|
||||
struct EnvState { env: Mutex<ConcreteEnv> }
|
||||
#[derive(Serialize)]
|
||||
struct TransactionOutput {
|
||||
pub amount: u64,
|
||||
pub public_key: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct TransactionResponse {
|
||||
pub hash: String,
|
||||
pub version: u8,
|
||||
pub is_coinbase: bool,
|
||||
pub confirmation_height: usize,
|
||||
pub timestamp: u64,
|
||||
pub weight: usize,
|
||||
pub inputs: Vec<String>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
pub extra: String,
|
||||
}
|
||||
|
||||
#[get("/api/tx/{tx_hash}")]
|
||||
async fn get_tx(
|
||||
env_state: web::Data<EnvState>,
|
||||
env: web::Data<ConcreteEnv>,
|
||||
tx_hash: web::Path<String>
|
||||
) -> std::io::Result<impl Responder> {
|
||||
let tx_hash_buff = <[u8; 32]>::from_hex(tx_hash.to_string())
|
||||
let tx_hash_buff = <[u8; 32]>::from_hex(tx_hash.clone().to_string())
|
||||
.unwrap();
|
||||
|
||||
let env = env_state.env.lock().unwrap();
|
||||
let env_inner = env.env_inner();
|
||||
let tx_ro = env_inner.tx_ro().unwrap();
|
||||
let tables = env_inner.open_tables(&tx_ro).unwrap();
|
||||
|
||||
let tx_id = tables.tx_ids().get(&tx_hash_buff).unwrap();
|
||||
let tx = ops::tx::get_tx_from_id(&tx_id, tables.tx_blobs()).unwrap();
|
||||
let tx_height = tables.tx_heights().get(&tx_id).unwrap();
|
||||
let tx_block = tables.block_infos().get(&tx_height).unwrap();
|
||||
let tx_prefix = tx.prefix();
|
||||
|
||||
let tx = ops::tx::get_tx(
|
||||
&tx_hash_buff,
|
||||
tables.tx_ids(),
|
||||
tables.tx_blobs()
|
||||
)
|
||||
.unwrap();
|
||||
let mut outputs: Vec<TransactionOutput> = Vec::with_capacity(tx_prefix.outputs.len());
|
||||
|
||||
let response: Transaction = tx.into();
|
||||
for o in &tx_prefix.outputs {
|
||||
outputs.push(TransactionOutput {
|
||||
amount: o.amount.unwrap(),
|
||||
public_key: hex::encode(o.key.to_bytes())
|
||||
})
|
||||
}
|
||||
|
||||
let response = TransactionResponse {
|
||||
hash: tx_hash.clone(),
|
||||
version: tx.version(),
|
||||
is_coinbase: tx_prefix.inputs.len() == 0,
|
||||
confirmation_height: tx_height,
|
||||
timestamp: tx_block.timestamp,
|
||||
weight: tx.weight(),
|
||||
inputs: Vec::with_capacity(0),
|
||||
outputs,
|
||||
extra: hex::encode(tx_prefix.extra.clone()),
|
||||
};
|
||||
|
||||
Ok(web::Json(response))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct BlockResponse {
|
||||
pub timestamp: u64,
|
||||
pub cumulative_generated_coins: u64,
|
||||
struct BlockTransactionResponse {
|
||||
pub hash: String,
|
||||
pub version: u8,
|
||||
pub is_coinbase: bool,
|
||||
pub weight: usize,
|
||||
pub inputs: Vec<String>,
|
||||
pub outputs: Vec<TransactionOutput>,
|
||||
pub extra: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct BlockResponse {
|
||||
pub hash: String,
|
||||
pub timestamp: u64,
|
||||
pub weight: usize,
|
||||
pub cumulative_generated_coins: u64,
|
||||
pub cumulative_difficulty_low: u64,
|
||||
pub cumulative_difficulty_high: u64,
|
||||
pub hash: String,
|
||||
pub cumulative_rct_outs: u64,
|
||||
pub long_term_weight: usize,
|
||||
pub tx_hashes: Vec<String>,
|
||||
pub transactions: Vec<BlockTransactionResponse>,
|
||||
}
|
||||
|
||||
#[get("/api/block/{height}")]
|
||||
async fn get_block(
|
||||
env_state: web::Data<EnvState>,
|
||||
env: web::Data<ConcreteEnv>,
|
||||
height: web::Path<String>
|
||||
) -> std::io::Result<impl Responder> {
|
||||
let env = env_state.env.lock().unwrap();
|
||||
let env_inner = env.env_inner();
|
||||
let tx_ro = env_inner.tx_ro().unwrap();
|
||||
let tables = env_inner.open_tables(&tx_ro).unwrap();
|
||||
|
||||
let height = height.parse::<usize>().ok().unwrap();
|
||||
let block_info = ops::block::get_block_info(&height, tables.block_infos()).unwrap();
|
||||
let block_tx_hashes = tables.block_txs_hashes().get(&height).unwrap();
|
||||
let block_tx_num = block_tx_hashes.len();
|
||||
let mut tx_hashes: Vec<String> = Vec::with_capacity(block_tx_num);
|
||||
let block_tx_hashes = tables.block_txs_hashes().get(&height).unwrap();
|
||||
let mut transactions: Vec<BlockTransactionResponse> = Vec::with_capacity(block_tx_hashes.len());
|
||||
|
||||
for tx_hash in block_tx_hashes.iter() {
|
||||
let tx = ops::tx::get_tx(&tx_hash, tables.tx_ids(), tables.tx_blobs()).unwrap();
|
||||
let tx_prefix = tx.prefix();
|
||||
let mut outputs: Vec<TransactionOutput> = Vec::with_capacity(tx_prefix.outputs.len());
|
||||
|
||||
for o in &tx_prefix.outputs {
|
||||
outputs.push(TransactionOutput {
|
||||
amount: o.amount.unwrap(),
|
||||
public_key: hex::encode(o.key.to_bytes())
|
||||
})
|
||||
}
|
||||
|
||||
transactions.push(BlockTransactionResponse {
|
||||
hash: hex::encode(tx.hash()),
|
||||
version: tx.version(),
|
||||
is_coinbase: true,
|
||||
weight: tx.weight(),
|
||||
inputs: Vec::with_capacity(0),
|
||||
outputs: outputs,
|
||||
extra: hex::encode(tx_prefix.extra.clone()),
|
||||
});
|
||||
|
||||
for tx_id_bytes in block_tx_hashes.iter() {
|
||||
tx_hashes.push(hex::encode(&tx_id_bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
let response = BlockResponse {
|
||||
@@ -75,7 +137,7 @@ async fn get_block(
|
||||
hash: hex::encode(&block_info.block_hash),
|
||||
cumulative_rct_outs: block_info.cumulative_rct_outs,
|
||||
long_term_weight: block_info.long_term_weight,
|
||||
tx_hashes,
|
||||
transactions,
|
||||
};
|
||||
|
||||
Ok(web::Json(response))
|
||||
@@ -91,7 +153,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.build();
|
||||
|
||||
let env = cuprate_blockchain::open(config).unwrap();
|
||||
let env_state = web::Data::new(EnvState { env: env.into() });
|
||||
let env_state = web::Data::new(env);
|
||||
|
||||
HttpServer::new(move || {
|
||||
App::new()
|
||||
|
||||
Reference in New Issue
Block a user