Merge pull request #38 from CirclesUBI/server_only_part1

Server only part1
This commit is contained in:
chriseth 2023-05-25 16:13:05 +02:00 committed by GitHub
commit 37a44f8523
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 42 additions and 20 deletions

View file

@ -12,3 +12,4 @@ json = "^0.12.4"
num-bigint = "^0.4.3" num-bigint = "^0.4.3"
serde = { version = "1.0.149", features = ["serde_derive"] } serde = { version = "1.0.149", features = ["serde_derive"] }
serde_json = "1.0.89" serde_json = "1.0.89"
regex = "1.8.1"

View file

@ -4,6 +4,7 @@ use crate::types::edge::EdgeDB;
use crate::types::{Address, Edge, U256}; use crate::types::{Address, Edge, U256};
use json::JsonValue; use json::JsonValue;
use num_bigint::BigUint; use num_bigint::BigUint;
use regex::Regex;
use std::error::Error; use std::error::Error;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::io::Read; use std::io::Read;
@ -35,6 +36,38 @@ impl Display for InputValidationError {
} }
} }
fn validate_and_parse_ethereum_address(address: &str) -> Result<Address, Box<dyn Error>> {
let re = Regex::new(r"^0x[0-9a-fA-F]{40}$").unwrap();
if re.is_match(address) {
Ok(Address::from(address))
} else {
Err(Box::new(InputValidationError(format!(
"Invalid Ethereum address: {}",
address
))))
}
}
fn validate_and_parse_u256(value_str: &str) -> Result<U256, Box<dyn Error>> {
match BigUint::from_str(value_str) {
Ok(parsed_value) => {
if parsed_value > U256::MAX.into() {
Err(Box::new(InputValidationError(format!(
"Value {} is too large. Maximum value is {}.",
parsed_value,
U256::MAX
))))
} else {
Ok(U256::from_bigint_truncating(parsed_value))
}
}
Err(e) => Err(Box::new(InputValidationError(format!(
"Invalid value: {}. Couldn't parse value: {}",
value_str, e
)))),
}
}
pub fn start_server(listen_at: &str, queue_size: usize, threads: u64) { pub fn start_server(listen_at: &str, queue_size: usize, threads: u64) {
let edges: Arc<RwLock<Arc<EdgeDB>>> = Arc::new(RwLock::new(Arc::new(EdgeDB::default()))); let edges: Arc<RwLock<Arc<EdgeDB>>> = Arc::new(RwLock::new(Arc::new(EdgeDB::default())));
@ -156,38 +189,26 @@ fn compute_transfer(
socket.write_all(chunked_header().as_bytes())?; socket.write_all(chunked_header().as_bytes())?;
let parsed_value_param = match request.params["value"].as_str() { let parsed_value_param = match request.params["value"].as_str() {
Some(value_str) => match BigUint::from_str(value_str) { Some(value_str) => validate_and_parse_u256(value_str)?,
Ok(parsed_value) => parsed_value, None => U256::MAX,
Err(e) => {
return Err(Box::new(InputValidationError(format!(
"Invalid value: {}. Couldn't parse value: {}",
value_str, e
))));
}
},
None => U256::MAX.into(),
}; };
if parsed_value_param > U256::MAX.into() { let from_address = validate_and_parse_ethereum_address(&request.params["from"].to_string())?;
return Err(Box::new(InputValidationError(format!( let to_address = validate_and_parse_ethereum_address(&request.params["to"].to_string())?;
"Value {} is too large. Maximum value is {}.",
parsed_value_param,
U256::MAX
))));
}
let max_distances = if request.params["iterative"].as_bool().unwrap_or_default() { let max_distances = if request.params["iterative"].as_bool().unwrap_or_default() {
vec![Some(1), Some(2), None] vec![Some(1), Some(2), None]
} else { } else {
vec![None] vec![None]
}; };
let max_transfers = request.params["max_transfers"].as_u64(); let max_transfers = request.params["max_transfers"].as_u64();
for max_distance in max_distances { for max_distance in max_distances {
let (flow, transfers) = graph::compute_flow( let (flow, transfers) = graph::compute_flow(
&Address::from(request.params["from"].to_string().as_str()), &from_address,
&Address::from(request.params["to"].to_string().as_str()), &to_address,
edges, edges,
U256::from_bigint_truncating(parsed_value_param.clone()), parsed_value_param,
max_distance, max_distance,
max_transfers, max_transfers,
); );