Loading edge database.

This commit is contained in:
chriseth 2022-08-30 18:53:34 +02:00
parent 6200fec2f2
commit 12bb20d58d
5 changed files with 120 additions and 6 deletions

8
src/address.rs Normal file
View 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
View 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
View 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)
}

View file

@ -1,5 +1,9 @@
mod address;
mod edge;
mod io;
mod u256;
fn main() {
println!("Hello, world!");
let edges = io::read_edges_binary(&String::from("./edges.dat")).expect("Error loading edges.");
print!("Read {} edges", edges.len());
}

View file

@ -5,7 +5,11 @@ use std::ops::{Add, AddAssign};
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, PartialOrd)]
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 {
fn from(item: u128) -> Self {
@ -25,14 +29,22 @@ impl From<&str> for U256 {
assert!(
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_hex = &item[high_start..low_start];
// disallow + and - prefixes
assert!(
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])
} else {
todo!("Decimal import");
@ -71,7 +83,7 @@ impl Display for U256 {
}
mod test {
use super::*;
use super::U256;
#[test]
fn to_string() {
assert_eq!(format!("{}", U256::from(0)), "0x0");
@ -116,5 +128,4 @@ mod test {
U256::from(u128::MAX) + U256::from(1)
);
}
}