adding first wave of code
parent
49ee0d84e0
commit
7addf838ae
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "monero-blockchain-explorer"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["lalanza808 <lance@reciprocitylabs.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
description = ""
|
||||||
|
|
||||||
|
# https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rocket = "0.4.4"
|
||||||
|
rocket_contrib = "0.4.4"
|
||||||
|
serde = "1.0"
|
||||||
|
serde_json = "1.0"
|
||||||
|
serde_derive = "1.0"
|
||||||
|
reqwest = { version = "0.10.4", features = ["blocking", "json"] }
|
@ -0,0 +1,12 @@
|
|||||||
|
# Monero Block Explorer
|
||||||
|
|
||||||
|
Building a very simple HTTP service to help learn Rust and get more familiar with the ecosystem.
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://github.com/lalanza808/monero-blockchain-explorer
|
||||||
|
cd monero-blockchain-explorer
|
||||||
|
rustup override set nightly
|
||||||
|
cargo run
|
||||||
|
```
|
@ -0,0 +1,97 @@
|
|||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct RPCPayload {
|
||||||
|
pub jsonrpc: String,
|
||||||
|
pub id: String,
|
||||||
|
pub method: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for RPCPayload {
|
||||||
|
fn default() -> RPCPayload {
|
||||||
|
RPCPayload {
|
||||||
|
jsonrpc: "2.0".to_string(),
|
||||||
|
id: "0".to_string(),
|
||||||
|
method: "get_info".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct GetInfo {
|
||||||
|
pub jsonrpc: String,
|
||||||
|
pub id: String,
|
||||||
|
pub result: GetInfoResult
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct GetInfoResult {
|
||||||
|
pub alt_blocks_count: u32,
|
||||||
|
pub block_size_limit: u32,
|
||||||
|
pub block_size_median: u32,
|
||||||
|
pub block_weight_limit: u32,
|
||||||
|
pub block_weight_median: u64,
|
||||||
|
pub bootstrap_daemon_address: String,
|
||||||
|
pub credits: u32,
|
||||||
|
pub cumulative_difficulty: u64,
|
||||||
|
pub cumulative_difficulty_top64: u32,
|
||||||
|
pub database_size: u64,
|
||||||
|
pub difficulty: u64,
|
||||||
|
pub difficulty_top64: u32,
|
||||||
|
pub free_space: u64,
|
||||||
|
pub grey_peerlist_size: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub height_without_bootstrap: u32,
|
||||||
|
pub incoming_connections_count: u32,
|
||||||
|
pub mainnet: bool,
|
||||||
|
pub nettype: String,
|
||||||
|
pub offline: bool,
|
||||||
|
pub outgoing_connections_count: u32,
|
||||||
|
pub rpc_connections_count: u32,
|
||||||
|
pub stagenet: bool,
|
||||||
|
pub start_time: u32,
|
||||||
|
pub status: String,
|
||||||
|
pub target: u32,
|
||||||
|
pub target_height: u32,
|
||||||
|
pub testnet: bool,
|
||||||
|
pub top_block_hash: String,
|
||||||
|
pub top_hash: String,
|
||||||
|
pub tx_count: u32,
|
||||||
|
pub tx_pool_size: u32,
|
||||||
|
pub untrusted: bool,
|
||||||
|
pub update_available: bool,
|
||||||
|
pub version: String,
|
||||||
|
pub was_bootstrap_ever_used: bool,
|
||||||
|
pub white_peerlist_size: u32,
|
||||||
|
pub wide_cumulative_difficulty: String,
|
||||||
|
pub wide_difficulty: String
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct BlockByHeaderHash {
|
||||||
|
pub id: String,
|
||||||
|
pub jsonrpc: String,
|
||||||
|
pub result: BlockByHeaderHashResult
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct BlockByHeaderHashResult {
|
||||||
|
pub status: String,
|
||||||
|
pub untrusted: bool,
|
||||||
|
pub block_header: BlockHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct BlockHeader {
|
||||||
|
pub block_size: u32,
|
||||||
|
pub depth: u32,
|
||||||
|
pub difficulty: u64,
|
||||||
|
pub hash: String,
|
||||||
|
pub height: u32,
|
||||||
|
pub major_version: u8,
|
||||||
|
pub minor_version: u8,
|
||||||
|
pub nonce: u32,
|
||||||
|
pub num_txes: u32,
|
||||||
|
pub orphan_status: bool,
|
||||||
|
pub prev_hash: String,
|
||||||
|
pub reward: u64,
|
||||||
|
pub timestamp: u64
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
#![feature(proc_macro_hygiene, decl_macro)]
|
||||||
|
#[macro_use] extern crate rocket;
|
||||||
|
#[macro_use] extern crate rocket_contrib;
|
||||||
|
#[macro_use] extern crate serde_derive;
|
||||||
|
extern crate reqwest;
|
||||||
|
mod data_types;
|
||||||
|
use rocket_contrib::json::{Json, JsonValue};
|
||||||
|
use std::env;
|
||||||
|
use data_types::*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn issue_rpc(method: &str) -> reqwest::blocking::RequestBuilder {
|
||||||
|
let uri = env::var("DAEMON_URI").unwrap();
|
||||||
|
let http_client = reqwest::blocking::Client::new();
|
||||||
|
let post_data = RPCPayload {
|
||||||
|
method: method.to_string(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
return http_client.post(&uri).json(&post_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[catch(404)]
|
||||||
|
fn not_found() -> JsonValue {
|
||||||
|
json!({
|
||||||
|
"status": "error",
|
||||||
|
"reason": "Resource was not found."
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/transaction/<hash>")]
|
||||||
|
fn get_transaction(hash: String) -> Json<BlockHeader> {
|
||||||
|
let res: BlockByHeaderHash = issue_rpc(&"get_block_header_by_hash")
|
||||||
|
.send()
|
||||||
|
.unwrap().json().unwrap();
|
||||||
|
Json(res.result.block_header)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/info")]
|
||||||
|
fn get_daemon_info() -> Json<GetInfoResult> {
|
||||||
|
let res: GetInfo = issue_rpc(&"get_info")
|
||||||
|
.send()
|
||||||
|
.unwrap().json().unwrap();
|
||||||
|
Json(res.result)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let env_url = env::var("DAEMON_URI");
|
||||||
|
match env_url {
|
||||||
|
Ok(_) => {
|
||||||
|
rocket::ignite()
|
||||||
|
.mount("/", routes![
|
||||||
|
get_daemon_info, get_transaction
|
||||||
|
])
|
||||||
|
.register(catchers![not_found])
|
||||||
|
.launch();
|
||||||
|
},
|
||||||
|
Err(_) => panic!("Environment variable `DAEMON_URI` not provided.")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue