Skip to content

Commit

Permalink
Merge branch 'dev' of https://github.com/CirclesUBI/pathfinder2 into …
Browse files Browse the repository at this point in the history
…feature/add-user-balance-to-org-flow-edges
  • Loading branch information
JacqueGM committed Aug 7, 2023
2 parents 5950ab8 + 44f1564 commit b37076d
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 29 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/container-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ name: Container Image

on:
push:
tags:
- v[0-9]+.[0-9]+.[0-9]+*
branches:
- main
- next
- dev
- feature/server_only
workflow_dispatch:

jobs:
call-build-and-push:
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
name: BuildAndTest

on:
push:
pull_request:
branches: [ "main" ]
branches: [ "dev" ]

env:
CARGO_TERM_COLOR: always
Expand All @@ -23,17 +22,20 @@ jobs:
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.toml') }}
- name: Setup PATH
run: echo ~/.foundry/bin/ >> $GITHUB_PATH
- name: Install Dependencies
run: curl -L https://foundry.paradigm.xyz | bash && foundryup

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Format
run: cargo fmt --check --verbose
- name: Lint
run: cargo clippy --all --all-features -- -D warnings

- name: Build
run: cargo build --verbose

- name: Download safes
run: wget -q -c https://rpc.circlesubi.id/pathfinder-db/capacity_graph.db

- name: Run tests
run: cargo test --verbose
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ json = "^0.12.4"
num-bigint = "^0.4.3"
serde = { version = "1.0.149", features = ["serde_derive"] }
serde_json = "1.0.89"
regex = "1.8.1"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The `server` (default), the `cli` and the `convert` tool.
All need a file that contains the trust graph edges to work.
A reasonably up to date edge database file can be obtained from

- https://chriseth.github.io/pathfinder2/edges.dat
- https://circlesubi.github.io/pathfinder2/edges.dat

### Using the Server

Expand Down
62 changes: 42 additions & 20 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use crate::io::{import_from_safes_binary, read_edges_binary, read_edges_csv};
use crate::types::edge::EdgeDB;
use crate::types::{Address, Edge, U256};
use json::JsonValue;
use num_bigint::BigUint;
use regex::Regex;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::io::Read;
Expand All @@ -13,7 +15,6 @@ use std::str::FromStr;
use std::sync::mpsc::TrySendError;
use std::sync::{mpsc, Arc, Mutex, RwLock};
use std::thread;
use num_bigint::BigUint;

struct JsonRpcRequest {
id: JsonValue,
Expand All @@ -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) {
let edges: Arc<RwLock<Arc<EdgeDB>>> = Arc::new(RwLock::new(Arc::new(EdgeDB::default())));

Expand Down Expand Up @@ -156,37 +189,26 @@ fn compute_transfer(
socket.write_all(chunked_header().as_bytes())?;

let parsed_value_param = match request.params["value"].as_str() {
Some(value_str) => match BigUint::from_str(value_str) {
Ok(parsed_value) => parsed_value,
Err(e) => {
return Err(Box::new(InputValidationError(format!(
"Invalid value: {}. Couldn't parse value: {}",
value_str, e
))));
}
},
None => U256::MAX.into(),
Some(value_str) => validate_and_parse_u256(value_str)?,
None => U256::MAX,
};

if parsed_value_param > U256::MAX.into() {
return Err(Box::new(InputValidationError(format!(
"Value {} is too large. Maximum value is {}.",
parsed_value_param, U256::MAX
))));
}
let from_address = validate_and_parse_ethereum_address(&request.params["from"].to_string())?;
let to_address = validate_and_parse_ethereum_address(&request.params["to"].to_string())?;

let max_distances = if request.params["iterative"].as_bool().unwrap_or_default() {
vec![Some(1), Some(2), None]
} else {
vec![None]
};

let max_transfers = request.params["max_transfers"].as_u64();
for max_distance in max_distances {
let (flow, transfers) = graph::compute_flow(
&Address::from(request.params["from"].to_string().as_str()),
&Address::from(request.params["to"].to_string().as_str()),
&from_address,
&to_address,
edges,
U256::from_bigint_truncating(parsed_value_param.clone()),
parsed_value_param,
max_distance,
max_transfers,
);
Expand Down

0 comments on commit b37076d

Please sign in to comment.