mirror of
https://github.com/mimblewimble/grin.git
synced 2025-01-20 19:11:08 +03:00
parent
aad0e9402a
commit
ac6ed71abd
10 changed files with 236 additions and 175 deletions
|
@ -52,6 +52,15 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Helper function to easily issue a HTTP GET request
|
||||
/// on a given URL that returns nothing. Handles request
|
||||
/// building and response code checking.
|
||||
pub fn get_no_ret(url: &str, api_secret: Option<String>) -> Result<(), Error> {
|
||||
let req = build_request(url, "GET", api_secret, None)?;
|
||||
send_request(req)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Helper function to easily issue a HTTP POST request with the provided JSON
|
||||
/// object as body on a given URL that returns a JSON object. Handles request
|
||||
/// building, JSON serialization and deserialization, and response code
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::utils::{get_output, w};
|
||||
use crate::chain;
|
||||
use crate::core::core::hash::Hash;
|
||||
|
@ -68,10 +67,7 @@ impl HeaderHandler {
|
|||
|
||||
impl Handler for HeaderHandler {
|
||||
fn get(&self, req: Request<Body>) -> ResponseFuture {
|
||||
let el = match req.uri().path().trim_right_matches('/').rsplit('/').next() {
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
Some(el) => el,
|
||||
};
|
||||
let el = right_path_element!(req);
|
||||
result_to_response(self.get_header(el.to_string()))
|
||||
}
|
||||
}
|
||||
|
@ -130,11 +126,7 @@ fn check_block_param(input: &String) -> Result<(), Error> {
|
|||
|
||||
impl Handler for BlockHandler {
|
||||
fn get(&self, req: Request<Body>) -> ResponseFuture {
|
||||
let el = match req.uri().path().trim_right_matches('/').rsplit('/').next() {
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
Some(el) => el,
|
||||
};
|
||||
|
||||
let el = right_path_element!(req);
|
||||
let h = match self.parse_input(el.to_string()) {
|
||||
Err(e) => {
|
||||
return response(
|
||||
|
|
|
@ -22,9 +22,7 @@ use crate::util;
|
|||
use crate::util::secp::pedersen::Commitment;
|
||||
use crate::web::*;
|
||||
use hyper::{Body, Request, StatusCode};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Weak;
|
||||
use url::form_urlencoded;
|
||||
|
||||
/// Chain handler. Get the head details.
|
||||
/// GET /v1/chain
|
||||
|
@ -101,21 +99,9 @@ impl OutputHandler {
|
|||
fn outputs_by_ids(&self, req: &Request<Body>) -> Result<Vec<Output>, Error> {
|
||||
let mut commitments: Vec<String> = vec![];
|
||||
|
||||
let query = match req.uri().query() {
|
||||
Some(q) => q,
|
||||
None => return Err(ErrorKind::RequestError("no query string".to_owned()))?,
|
||||
};
|
||||
let params = form_urlencoded::parse(query.as_bytes())
|
||||
.into_owned()
|
||||
.collect::<Vec<(String, String)>>();
|
||||
|
||||
for (k, id) in params {
|
||||
if k == "id" {
|
||||
for id in id.split(',') {
|
||||
commitments.push(id.to_owned());
|
||||
}
|
||||
}
|
||||
}
|
||||
let query = must_get_query!(req);
|
||||
let params = QueryParams::from(query);
|
||||
params.process_multival_param("id", |id| commitments.push(id.to_owned()));
|
||||
|
||||
let mut outputs: Vec<Output> = vec![];
|
||||
for x in commitments {
|
||||
|
@ -159,49 +145,17 @@ impl OutputHandler {
|
|||
// returns outputs for a specified range of blocks
|
||||
fn outputs_block_batch(&self, req: &Request<Body>) -> Result<Vec<BlockOutputs>, Error> {
|
||||
let mut commitments: Vec<Commitment> = vec![];
|
||||
let mut start_height = 1;
|
||||
let mut end_height = 1;
|
||||
let mut include_rp = false;
|
||||
|
||||
let query = match req.uri().query() {
|
||||
Some(q) => q,
|
||||
None => return Err(ErrorKind::RequestError("no query string".to_owned()))?,
|
||||
};
|
||||
|
||||
let params = form_urlencoded::parse(query.as_bytes()).into_owned().fold(
|
||||
HashMap::new(),
|
||||
|mut hm, (k, v)| {
|
||||
hm.entry(k).or_insert(vec![]).push(v);
|
||||
hm
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(ids) = params.get("id") {
|
||||
for id in ids {
|
||||
for id in id.split(',') {
|
||||
if let Ok(x) = util::from_hex(String::from(id)) {
|
||||
commitments.push(Commitment::from_vec(x));
|
||||
}
|
||||
}
|
||||
let query = must_get_query!(req);
|
||||
let params = QueryParams::from(query);
|
||||
params.process_multival_param("id", |id| {
|
||||
if let Ok(x) = util::from_hex(String::from(id)) {
|
||||
commitments.push(Commitment::from_vec(x));
|
||||
}
|
||||
}
|
||||
if let Some(heights) = params.get("start_height") {
|
||||
for height in heights {
|
||||
start_height = height
|
||||
.parse()
|
||||
.map_err(|_| ErrorKind::RequestError("invalid start_height".to_owned()))?;
|
||||
}
|
||||
}
|
||||
if let Some(heights) = params.get("end_height") {
|
||||
for height in heights {
|
||||
end_height = height
|
||||
.parse()
|
||||
.map_err(|_| ErrorKind::RequestError("invalid end_height".to_owned()))?;
|
||||
}
|
||||
}
|
||||
if let Some(_) = params.get("include_rp") {
|
||||
include_rp = true;
|
||||
}
|
||||
});
|
||||
let start_height = parse_param!(params, "start_height", 1);
|
||||
let end_height = parse_param!(params, "end_height", 1);
|
||||
let include_rp = params.get("include_rp").is_some();
|
||||
|
||||
debug!(
|
||||
"outputs_block_batch: {}-{}, {:?}, {:?}",
|
||||
|
@ -223,11 +177,7 @@ impl OutputHandler {
|
|||
|
||||
impl Handler for OutputHandler {
|
||||
fn get(&self, req: Request<Body>) -> ResponseFuture {
|
||||
let command = match req.uri().path().trim_right_matches('/').rsplit('/').next() {
|
||||
Some(c) => c,
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
};
|
||||
match command {
|
||||
match right_path_element!(req) {
|
||||
"byids" => result_to_response(self.outputs_by_ids(&req)),
|
||||
"byheight" => result_to_response(self.outputs_block_batch(&req)),
|
||||
_ => response(StatusCode::BAD_REQUEST, ""),
|
||||
|
|
|
@ -37,11 +37,11 @@ pub struct PeersConnectedHandler {
|
|||
|
||||
impl Handler for PeersConnectedHandler {
|
||||
fn get(&self, _req: Request<Body>) -> ResponseFuture {
|
||||
let mut peers: Vec<PeerInfoDisplay> = vec![];
|
||||
for p in &w(&self.peers).connected_peers() {
|
||||
let peer_info = p.info.clone();
|
||||
peers.push(peer_info.into());
|
||||
}
|
||||
let peers: Vec<PeerInfoDisplay> = w(&self.peers)
|
||||
.connected_peers()
|
||||
.iter()
|
||||
.map(|p| p.info.clone().into())
|
||||
.collect();
|
||||
json_response(&peers)
|
||||
}
|
||||
}
|
||||
|
@ -56,10 +56,7 @@ pub struct PeerHandler {
|
|||
|
||||
impl Handler for PeerHandler {
|
||||
fn get(&self, req: Request<Body>) -> ResponseFuture {
|
||||
let command = match req.uri().path().trim_right_matches('/').rsplit('/').next() {
|
||||
Some(c) => c,
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
};
|
||||
let command = right_path_element!(req);
|
||||
if let Ok(addr) = command.parse() {
|
||||
match w(&self.peers).get_peer(addr) {
|
||||
Ok(peer) => json_response(&peer),
|
||||
|
|
|
@ -23,12 +23,11 @@ use crate::types::*;
|
|||
use crate::util;
|
||||
use crate::util::RwLock;
|
||||
use crate::web::*;
|
||||
use failure::ResultExt;
|
||||
use futures::future::ok;
|
||||
use futures::Future;
|
||||
use hyper::{Body, Request, StatusCode};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Weak;
|
||||
use url::form_urlencoded;
|
||||
|
||||
/// Get basic information about the transaction pool.
|
||||
/// GET /v1/pool
|
||||
|
@ -61,15 +60,7 @@ pub struct PoolPushHandler {
|
|||
|
||||
impl PoolPushHandler {
|
||||
fn update_pool(&self, req: Request<Body>) -> Box<dyn Future<Item = (), Error = Error> + Send> {
|
||||
let params = match req.uri().query() {
|
||||
Some(query_string) => form_urlencoded::parse(query_string.as_bytes())
|
||||
.into_owned()
|
||||
.fold(HashMap::new(), |mut hm, (k, v)| {
|
||||
hm.entry(k).or_insert(vec![]).push(v);
|
||||
hm
|
||||
}),
|
||||
None => HashMap::new(),
|
||||
};
|
||||
let params = QueryParams::from(req.uri().query());
|
||||
|
||||
let fluff = params.get("fluff").is_some();
|
||||
let pool_arc = w(&self.tx_pool).clone();
|
||||
|
@ -99,13 +90,14 @@ impl PoolPushHandler {
|
|||
|
||||
// Push to tx pool.
|
||||
let mut tx_pool = pool_arc.write();
|
||||
let header = tx_pool.blockchain.chain_head().unwrap();
|
||||
tx_pool
|
||||
let header = tx_pool
|
||||
.blockchain
|
||||
.chain_head()
|
||||
.context(ErrorKind::Internal("Failed to get chain head".to_owned()))?;
|
||||
let res = tx_pool
|
||||
.add_to_pool(source, tx, !fluff, &header)
|
||||
.map_err(|e| {
|
||||
error!("update_pool: failed with error: {:?}", e);
|
||||
ErrorKind::Internal(format!("Failed to update pool: {:?}", e)).into()
|
||||
})
|
||||
.context(ErrorKind::Internal("Failed to update pool".to_owned()))?;
|
||||
Ok(res)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,9 +22,7 @@ use crate::util::secp::pedersen::Commitment;
|
|||
use crate::web::*;
|
||||
use failure::ResultExt;
|
||||
use hyper::{Body, Request, StatusCode};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Weak;
|
||||
use url::form_urlencoded;
|
||||
|
||||
// Sum tree handler. Retrieve the roots:
|
||||
// GET /v1/txhashset/roots
|
||||
|
@ -114,59 +112,14 @@ impl TxHashSetHandler {
|
|||
|
||||
impl Handler for TxHashSetHandler {
|
||||
fn get(&self, req: Request<Body>) -> ResponseFuture {
|
||||
let mut start_index = 1;
|
||||
let mut max = 100;
|
||||
let mut id = "".to_owned();
|
||||
|
||||
// TODO: probably need to set a reasonable max limit here
|
||||
let mut last_n = 10;
|
||||
if let Some(query_string) = req.uri().query() {
|
||||
let params = form_urlencoded::parse(query_string.as_bytes())
|
||||
.into_owned()
|
||||
.fold(HashMap::new(), |mut hm, (k, v)| {
|
||||
hm.entry(k).or_insert(vec![]).push(v);
|
||||
hm
|
||||
});
|
||||
if let Some(nums) = params.get("n") {
|
||||
for num in nums {
|
||||
if let Ok(n) = str::parse(num) {
|
||||
last_n = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(start_indexes) = params.get("start_index") {
|
||||
for si in start_indexes {
|
||||
if let Ok(s) = str::parse(si) {
|
||||
start_index = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(maxes) = params.get("max") {
|
||||
for ma in maxes {
|
||||
if let Ok(m) = str::parse(ma) {
|
||||
max = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ids) = params.get("id") {
|
||||
if !ids.is_empty() {
|
||||
id = ids.last().unwrap().to_owned();
|
||||
}
|
||||
}
|
||||
}
|
||||
let command = match req
|
||||
.uri()
|
||||
.path()
|
||||
.trim_right()
|
||||
.trim_right_matches("/")
|
||||
.rsplit("/")
|
||||
.next()
|
||||
{
|
||||
Some(c) => c,
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
};
|
||||
let params = QueryParams::from(req.uri().query());
|
||||
let last_n = parse_param_no_err!(params, "n", 10);
|
||||
let start_index = parse_param_no_err!(params, "start_index", 1);
|
||||
let max = parse_param_no_err!(params, "max", 100);
|
||||
let id = parse_param_no_err!(params, "id", "".to_owned());
|
||||
|
||||
match command {
|
||||
match right_path_element!(req) {
|
||||
"roots" => json_response_pretty(&self.get_roots()),
|
||||
"lastoutputs" => json_response_pretty(&self.get_last_n_output(last_n)),
|
||||
"lastrangeproofs" => json_response_pretty(&self.get_last_n_rangeproof(last_n)),
|
||||
|
|
|
@ -48,12 +48,15 @@ pub fn get_output(
|
|||
OutputIdentifier::new(OutputFeatures::Coinbase, &commit),
|
||||
];
|
||||
|
||||
for x in outputs.iter() {
|
||||
if let Ok(_) = w(chain).is_unspent(&x) {
|
||||
let block_height = w(chain).get_header_for_output(&x).unwrap().height;
|
||||
let output_pos = w(chain).get_output_pos(&x.commit).unwrap_or(0);
|
||||
return Ok((Output::new(&commit, block_height, output_pos), x.clone()));
|
||||
}
|
||||
for x in outputs.iter().filter(|x| w(chain).is_unspent(x).is_ok()) {
|
||||
let block_height = w(chain)
|
||||
.get_header_for_output(&x)
|
||||
.context(ErrorKind::Internal(
|
||||
"Can't get header for output".to_owned(),
|
||||
))?
|
||||
.height;
|
||||
let output_pos = w(chain).get_output_pos(&x.commit).unwrap_or(0);
|
||||
return Ok((Output::new(&commit, block_height, output_pos), x.clone()));
|
||||
}
|
||||
Err(ErrorKind::NotFound)?
|
||||
}
|
||||
|
|
|
@ -30,13 +30,14 @@ extern crate serde_derive;
|
|||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
mod web;
|
||||
pub mod auth;
|
||||
pub mod client;
|
||||
mod handlers;
|
||||
mod rest;
|
||||
mod router;
|
||||
mod types;
|
||||
mod web;
|
||||
|
||||
pub use crate::auth::BasicAuthMiddleware;
|
||||
pub use crate::handlers::start_rest_apis;
|
||||
|
|
|
@ -5,7 +5,9 @@ use futures::{Future, Stream};
|
|||
use hyper::{Body, Request, Response, StatusCode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use url::form_urlencoded;
|
||||
|
||||
/// Parse request body
|
||||
pub fn parse_body<T>(req: Request<Body>) -> Box<dyn Future<Item = T, Error = Error> + Send>
|
||||
|
@ -81,3 +83,100 @@ pub fn just_response<T: Into<Body> + Debug>(status: StatusCode, text: T) -> Resp
|
|||
pub fn response<T: Into<Body> + Debug>(status: StatusCode, text: T) -> ResponseFuture {
|
||||
Box::new(ok(just_response(status, text)))
|
||||
}
|
||||
|
||||
pub struct QueryParams {
|
||||
params: HashMap<String, Vec<String>>,
|
||||
}
|
||||
|
||||
impl QueryParams {
|
||||
pub fn process_multival_param<F>(&self, name: &str, mut f: F)
|
||||
where
|
||||
F: FnMut(&str),
|
||||
{
|
||||
if let Some(ids) = self.params.get(name) {
|
||||
for id in ids {
|
||||
for id in id.split(',') {
|
||||
f(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self, name: &str) -> Option<&String> {
|
||||
match self.params.get(name) {
|
||||
None => None,
|
||||
Some(v) => v.first(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for QueryParams {
|
||||
fn from(query_string: &str) -> Self {
|
||||
let params = form_urlencoded::parse(query_string.as_bytes())
|
||||
.into_owned()
|
||||
.fold(HashMap::new(), |mut hm, (k, v)| {
|
||||
hm.entry(k).or_insert(vec![]).push(v);
|
||||
hm
|
||||
});
|
||||
QueryParams { params }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Option<&str>> for QueryParams {
|
||||
fn from(query_string: Option<&str>) -> Self {
|
||||
match query_string {
|
||||
Some(query_string) => Self::from(query_string),
|
||||
None => QueryParams {
|
||||
params: HashMap::new(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Request<Body>> for QueryParams {
|
||||
fn from(req: Request<Body>) -> Self {
|
||||
Self::from(req.uri().query())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! right_path_element(
|
||||
($req: expr) =>(
|
||||
match $req.uri().path().trim_right_matches('/').rsplit('/').next() {
|
||||
None => return response(StatusCode::BAD_REQUEST, "invalid url"),
|
||||
Some(el) => el,
|
||||
};
|
||||
));
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! must_get_query(
|
||||
($req: expr) =>(
|
||||
match $req.uri().query() {
|
||||
Some(q) => q,
|
||||
None => return Err(ErrorKind::RequestError("no query string".to_owned()))?,
|
||||
}
|
||||
));
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parse_param(
|
||||
($param: expr, $name: expr, $default: expr) =>(
|
||||
match $param.get($name) {
|
||||
None => $default,
|
||||
Some(val) => match val.parse() {
|
||||
Ok(val) => val,
|
||||
Err(_) => return Err(ErrorKind::RequestError(format!("invalid value of parameter {}", $name)))?,
|
||||
}
|
||||
}
|
||||
));
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parse_param_no_err(
|
||||
($param: expr, $name: expr, $default: expr) =>(
|
||||
match $param.get($name) {
|
||||
None => $default,
|
||||
Some(val) => match val.parse() {
|
||||
Ok(val) => val,
|
||||
Err(_) => $default,
|
||||
}
|
||||
}
|
||||
));
|
||||
|
|
|
@ -18,8 +18,7 @@ extern crate log;
|
|||
mod framework;
|
||||
|
||||
use self::core::global::{self, ChainTypes};
|
||||
use self::util::init_test_logger;
|
||||
use self::util::Mutex;
|
||||
use self::util::{init_test_logger, to_hex, Mutex};
|
||||
use crate::framework::{LocalServerContainer, LocalServerContainerConfig};
|
||||
use grin_api as api;
|
||||
use grin_core as core;
|
||||
|
@ -79,6 +78,7 @@ fn simple_server_wallet() {
|
|||
warn!("Testing chain handler");
|
||||
let tip = get_tip(&base_addr, api_server_port);
|
||||
assert!(tip.is_ok());
|
||||
assert!(validate_chain(&base_addr, api_server_port).is_ok());
|
||||
|
||||
warn!("Testing status handler");
|
||||
let status = get_status(&base_addr, api_server_port);
|
||||
|
@ -94,17 +94,30 @@ fn simple_server_wallet() {
|
|||
warn!("Testing block handler");
|
||||
let last_block_by_height = get_block_by_height(&base_addr, api_server_port, current_tip.height);
|
||||
assert!(last_block_by_height.is_ok());
|
||||
let block_hash = current_tip.last_block_pushed;
|
||||
let last_block_by_height_compact =
|
||||
get_block_by_height_compact(&base_addr, api_server_port, current_tip.height);
|
||||
assert!(last_block_by_height_compact.is_ok());
|
||||
|
||||
let block_hash = current_tip.last_block_pushed;
|
||||
let unspent_commit = get_unspent_output(&last_block_by_height.unwrap()).unwrap();
|
||||
|
||||
let last_block_by_hash = get_block_by_hash(&base_addr, api_server_port, &block_hash);
|
||||
assert!(last_block_by_hash.is_ok());
|
||||
let last_block_by_hash_compact =
|
||||
get_block_by_hash_compact(&base_addr, api_server_port, &block_hash);
|
||||
assert!(last_block_by_hash_compact.is_ok());
|
||||
|
||||
warn!("Testing header handler");
|
||||
let last_header_by_height =
|
||||
get_header_by_height(&base_addr, api_server_port, current_tip.height);
|
||||
assert!(last_header_by_height.is_ok());
|
||||
|
||||
let last_header_by_hash = get_header_by_hash(&base_addr, api_server_port, &block_hash);
|
||||
assert!(last_header_by_hash.is_ok());
|
||||
|
||||
let last_header_by_commit = get_header_by_commit(&base_addr, api_server_port, &unspent_commit);
|
||||
assert!(last_header_by_commit.is_ok());
|
||||
|
||||
warn!("Testing chain output handler");
|
||||
let start_height = 0;
|
||||
let end_height = current_tip.height;
|
||||
|
@ -286,6 +299,20 @@ fn get_block_by_hash(
|
|||
api::client::get::<api::BlockPrintable>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
fn get_header_by_commit(
|
||||
base_addr: &String,
|
||||
api_server_port: u16,
|
||||
commit: &api::PrintableCommitment,
|
||||
) -> Result<api::BlockHeaderPrintable, Error> {
|
||||
let url = format!(
|
||||
"http://{}:{}/v1/headers/{}",
|
||||
base_addr,
|
||||
api_server_port,
|
||||
to_hex(commit.to_vec())
|
||||
);
|
||||
api::client::get::<api::BlockHeaderPrintable>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
fn get_block_by_hash_compact(
|
||||
base_addr: &String,
|
||||
api_server_port: u16,
|
||||
|
@ -298,6 +325,31 @@ fn get_block_by_hash_compact(
|
|||
api::client::get::<api::CompactBlockPrintable>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
// Header handler functions
|
||||
fn get_header_by_height(
|
||||
base_addr: &String,
|
||||
api_server_port: u16,
|
||||
height: u64,
|
||||
) -> Result<api::BlockHeaderPrintable, Error> {
|
||||
let url = format!(
|
||||
"http://{}:{}/v1/headers/{}",
|
||||
base_addr, api_server_port, height
|
||||
);
|
||||
api::client::get::<api::BlockHeaderPrintable>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
fn get_header_by_hash(
|
||||
base_addr: &String,
|
||||
api_server_port: u16,
|
||||
header_hash: &String,
|
||||
) -> Result<api::BlockHeaderPrintable, Error> {
|
||||
let url = format!(
|
||||
"http://{}:{}/v1/headers/{}",
|
||||
base_addr, api_server_port, header_hash
|
||||
);
|
||||
api::client::get::<api::BlockHeaderPrintable>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
// Chain output handler functions
|
||||
fn get_outputs_by_ids1(
|
||||
base_addr: &String,
|
||||
|
@ -343,6 +395,11 @@ fn get_outputs_by_height(
|
|||
api::client::get::<Vec<api::BlockOutputs>>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
fn validate_chain(base_addr: &String, api_server_port: u16) -> Result<(), Error> {
|
||||
let url = format!("http://{}:{}/v1/chain/validate", base_addr, api_server_port);
|
||||
api::client::get_no_ret(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
// TxHashSet handler functions
|
||||
fn get_txhashset_roots(base_addr: &String, api_server_port: u16) -> Result<api::TxHashSet, Error> {
|
||||
let url = format!(
|
||||
|
@ -412,19 +469,6 @@ fn get_txhashset_lastkernels(
|
|||
api::client::get::<Vec<api::TxHashSetNode>>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
// Helper function to get a vec of commitment output ids from a vec of block
|
||||
// outputs
|
||||
fn get_ids_from_block_outputs(block_outputs: Vec<api::BlockOutputs>) -> Vec<String> {
|
||||
let mut ids: Vec<String> = Vec::new();
|
||||
for block_output in block_outputs {
|
||||
let outputs = &block_output.outputs;
|
||||
for output in outputs {
|
||||
ids.push(util::to_hex(output.clone().commit.0.to_vec()));
|
||||
}
|
||||
}
|
||||
ids.into_iter().take(100).collect()
|
||||
}
|
||||
|
||||
pub fn ban_peer(base_addr: &String, api_server_port: u16, peer_addr: &String) -> Result<(), Error> {
|
||||
let url = format!(
|
||||
"http://{}:{}/v1/peers/{}/ban",
|
||||
|
@ -477,6 +521,27 @@ pub fn get_all_peers(
|
|||
api::client::get::<Vec<p2p::PeerData>>(url.as_str(), None).map_err(|e| Error::API(e))
|
||||
}
|
||||
|
||||
// Helper function to get a vec of commitment output ids from a vec of block
|
||||
// outputs
|
||||
fn get_ids_from_block_outputs(block_outputs: Vec<api::BlockOutputs>) -> Vec<String> {
|
||||
let mut ids: Vec<String> = Vec::new();
|
||||
for block_output in block_outputs {
|
||||
let outputs = &block_output.outputs;
|
||||
for output in outputs {
|
||||
ids.push(util::to_hex(output.clone().commit.0.to_vec()));
|
||||
}
|
||||
}
|
||||
ids.into_iter().take(100).collect()
|
||||
}
|
||||
|
||||
fn get_unspent_output(block: &api::BlockPrintable) -> Option<api::PrintableCommitment> {
|
||||
match block.outputs.iter().find(|o| !o.spent) {
|
||||
None => None,
|
||||
Some(output) => Some(api::PrintableCommitment {
|
||||
commit: output.commit.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
/// Error type wrapping underlying module errors.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
|
Loading…
Reference in a new issue