Loading edge database.
This commit is contained in:
parent
6200fec2f2
commit
12bb20d58d
5 changed files with 120 additions and 6 deletions
8
src/address.rs
Normal file
8
src/address.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
|
||||||
|
pub struct Address([u8; 20]);
|
||||||
|
|
||||||
|
impl From<[u8; 20]> for Address {
|
||||||
|
fn from(item: [u8; 20]) -> Self {
|
||||||
|
Address(item)
|
||||||
|
}
|
||||||
|
}
|
15
src/edge.rs
Normal file
15
src/edge.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
use crate::address::Address;
|
||||||
|
use crate::u256::U256;
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
|
||||||
|
pub struct Edge {
|
||||||
|
pub from: Address,
|
||||||
|
pub to: Address,
|
||||||
|
pub token: Address,
|
||||||
|
pub capacity: U256,
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO comparison, hash, etc. can ignore the capacity field.
|
||||||
|
|
||||||
|
// TODO can we derive it?
|
||||||
|
impl Eq for Edge {}
|
76
src/io.rs
Normal file
76
src/io.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
use crate::address::Address;
|
||||||
|
use crate::edge::Edge;
|
||||||
|
use crate::u256::U256;
|
||||||
|
|
||||||
|
pub fn read_edges_binary(path: &String) -> Result<HashSet<Edge>, io::Error> {
|
||||||
|
let mut f = File::open(path)?;
|
||||||
|
let address_index = read_address_index(&mut f)?;
|
||||||
|
read_edges(&mut f, &address_index)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_address_index(file: &mut File) -> Result<HashMap<u32, Address>, io::Error> {
|
||||||
|
let address_count = read_u32(file)?;
|
||||||
|
let mut addresses = HashMap::new();
|
||||||
|
for i in 0..address_count {
|
||||||
|
let mut buf = [0; 20];
|
||||||
|
file.read_exact(&mut buf)?;
|
||||||
|
addresses.insert(i, Address::from(buf));
|
||||||
|
}
|
||||||
|
Ok(addresses)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u32(file: &mut File) -> Result<u32, io::Error> {
|
||||||
|
let mut buf = [0; 4];
|
||||||
|
file.read_exact(&mut buf)?;
|
||||||
|
Ok(u32::from_be_bytes(buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u8(file: &mut File) -> Result<u8, io::Error> {
|
||||||
|
let mut buf = [0; 1];
|
||||||
|
file.read_exact(&mut buf)?;
|
||||||
|
Ok(u8::from_be_bytes(buf))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_address(
|
||||||
|
file: &mut File,
|
||||||
|
address_index: &HashMap<u32, Address>,
|
||||||
|
) -> Result<Address, io::Error> {
|
||||||
|
let index = read_u32(file)?;
|
||||||
|
Ok(address_index[&index])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_u256(file: &mut File) -> Result<U256, io::Error> {
|
||||||
|
let length = read_u8(file)? as usize;
|
||||||
|
let mut bytes = [0u8; 32];
|
||||||
|
file.read_exact(&mut bytes[32 - length..32])?;
|
||||||
|
let high = u128::from_be_bytes(*<&[u8; 16]>::try_from(&bytes[0..16]).unwrap());
|
||||||
|
let low = u128::from_be_bytes(*<&[u8; 16]>::try_from(&bytes[0..16]).unwrap());
|
||||||
|
Ok(U256::new(high, low))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_edges(
|
||||||
|
file: &mut File,
|
||||||
|
address_index: &HashMap<u32, Address>,
|
||||||
|
) -> Result<HashSet<Edge>, io::Error> {
|
||||||
|
let edge_count = read_u32(file)?;
|
||||||
|
let mut edges = HashSet::new();
|
||||||
|
for _i in 0..edge_count {
|
||||||
|
let from = read_address(file, address_index)?;
|
||||||
|
let to = read_address(file, address_index)?;
|
||||||
|
let token = read_address(file, address_index)?;
|
||||||
|
let capacity = read_u256(file)?;
|
||||||
|
edges.insert(Edge {
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
token,
|
||||||
|
capacity,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(edges)
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
|
mod address;
|
||||||
|
mod edge;
|
||||||
|
mod io;
|
||||||
mod u256;
|
mod u256;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
let edges = io::read_edges_binary(&String::from("./edges.dat")).expect("Error loading edges.");
|
||||||
|
print!("Read {} edges", edges.len());
|
||||||
}
|
}
|
||||||
|
|
21
src/u256.rs
21
src/u256.rs
|
@ -5,7 +5,11 @@ use std::ops::{Add, AddAssign};
|
||||||
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
|
||||||
pub struct U256([u128; 2]);
|
pub struct U256([u128; 2]);
|
||||||
|
|
||||||
impl U256 {}
|
impl U256 {
|
||||||
|
pub fn new(high: u128, low: u128) -> U256 {
|
||||||
|
U256([high, low])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<u128> for U256 {
|
impl From<u128> for U256 {
|
||||||
fn from(item: u128) -> Self {
|
fn from(item: u128) -> Self {
|
||||||
|
@ -25,14 +29,22 @@ impl From<&str> for U256 {
|
||||||
assert!(
|
assert!(
|
||||||
low_hex.as_bytes().get(0) != Some(&54) && low_hex.as_bytes().get(0) != Some(&43)
|
low_hex.as_bytes().get(0) != Some(&54) && low_hex.as_bytes().get(0) != Some(&43)
|
||||||
);
|
);
|
||||||
let low = if low_hex.is_empty() { 0 } else {u128::from_str_radix(low_hex, 16).unwrap()};
|
let low = if low_hex.is_empty() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
u128::from_str_radix(low_hex, 16).unwrap()
|
||||||
|
};
|
||||||
let high_start = if len >= 2 + 32 + 32 { len - 64 } else { 2 };
|
let high_start = if len >= 2 + 32 + 32 { len - 64 } else { 2 };
|
||||||
let high_hex = &item[high_start..low_start];
|
let high_hex = &item[high_start..low_start];
|
||||||
// disallow + and - prefixes
|
// disallow + and - prefixes
|
||||||
assert!(
|
assert!(
|
||||||
high_hex.as_bytes().get(0) != Some(&54) && high_hex.as_bytes().get(0) != Some(&43)
|
high_hex.as_bytes().get(0) != Some(&54) && high_hex.as_bytes().get(0) != Some(&43)
|
||||||
);
|
);
|
||||||
let high = if high_hex.is_empty() { 0 } else { u128::from_str_radix(high_hex, 16).unwrap() };
|
let high = if high_hex.is_empty() {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
u128::from_str_radix(high_hex, 16).unwrap()
|
||||||
|
};
|
||||||
U256([high, low])
|
U256([high, low])
|
||||||
} else {
|
} else {
|
||||||
todo!("Decimal import");
|
todo!("Decimal import");
|
||||||
|
@ -71,7 +83,7 @@ impl Display for U256 {
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::U256;
|
||||||
#[test]
|
#[test]
|
||||||
fn to_string() {
|
fn to_string() {
|
||||||
assert_eq!(format!("{}", U256::from(0)), "0x0");
|
assert_eq!(format!("{}", U256::from(0)), "0x0");
|
||||||
|
@ -116,5 +128,4 @@ mod test {
|
||||||
U256::from(u128::MAX) + U256::from(1)
|
U256::from(u128::MAX) + U256::from(1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue