mirror of
https://github.com/tig-pool-nk/tig-monorepo.git
synced 2026-02-21 15:17:22 +08:00
Add tests for tig-utils.
This commit is contained in:
parent
c0a94b560d
commit
420d62d41b
3
.github/workflows/test_workspace.yml
vendored
3
.github/workflows/test_workspace.yml
vendored
@ -26,7 +26,8 @@ jobs:
|
||||
with:
|
||||
targets: x86_64-unknown-linux-gnu
|
||||
- name: Cargo Test
|
||||
run: cargo test
|
||||
run: >
|
||||
cargo test -p tig-utils --features web3
|
||||
- name: Update Commit Status (Success)
|
||||
if: success()
|
||||
uses: myrotvorets/set-commit-status-action@master
|
||||
|
||||
@ -646,7 +646,9 @@ async fn update_frontiers<T: Context>(ctx: &mut T, block: &Block) {
|
||||
let multiplier = (*block_data.num_qualifiers() as f64
|
||||
/ config.qualifiers.total_qualifiers_threshold as f64)
|
||||
.clamp(0.0, config.difficulty_bounds.max_multiplier);
|
||||
let scaled_frontier = base_frontier.scale(&min_difficulty, &max_difficulty, multiplier);
|
||||
let scaled_frontier = base_frontier
|
||||
.scale(&min_difficulty, &max_difficulty, multiplier)
|
||||
.extend(&min_difficulty, &max_difficulty);
|
||||
|
||||
block_data.base_frontier = Some(base_frontier);
|
||||
block_data.scaled_frontier = Some(scaled_frontier);
|
||||
@ -729,7 +731,7 @@ async fn update_influence<T: Context>(ctx: &mut T, block: &Block) {
|
||||
|
||||
let imbalance = cv_sqr / (num_challenges - one);
|
||||
let imbalance_penalty =
|
||||
one - PreciseNumber::approx_inverse_exp(imbalance_multiplier * imbalance);
|
||||
one - PreciseNumber::approx_inv_exp(imbalance_multiplier * imbalance);
|
||||
|
||||
weights.push(mean * (one - imbalance_penalty));
|
||||
|
||||
|
||||
@ -227,12 +227,12 @@ fn verify_benchmark_difficulty(difficulty: &Vec<i32>, challenge: &Challenge) ->
|
||||
)
|
||||
};
|
||||
match difficulty.within(lower_frontier, upper_frontier) {
|
||||
PointCompareFrontiers::Above(_) => {
|
||||
PointCompareFrontiers::Above => {
|
||||
return Err(ProtocolError::DifficultyAboveHardestFrontier {
|
||||
difficulty: difficulty.clone(),
|
||||
});
|
||||
}
|
||||
PointCompareFrontiers::Below(_) => {
|
||||
PointCompareFrontiers::Below => {
|
||||
return Err(ProtocolError::DifficultyBelowEasiestFrontier {
|
||||
difficulty: difficulty.clone(),
|
||||
});
|
||||
|
||||
@ -30,6 +30,9 @@ web-sys = { version = "0.3.68", optional = true, features = [
|
||||
'Window',
|
||||
] }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "1.37.0", features = ["full"] }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::number::PreciseNumber;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||
pub struct Transaction {
|
||||
pub sender: String,
|
||||
pub receiver: String,
|
||||
|
||||
@ -6,10 +6,10 @@ pub type Point = Vec<i32>;
|
||||
pub type Frontier<P = Point> = HashSet<P>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum PointCompareFrontiers<P> {
|
||||
Below(P),
|
||||
pub enum PointCompareFrontiers {
|
||||
Below,
|
||||
Within,
|
||||
Above(P),
|
||||
Above,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
@ -28,7 +28,7 @@ pub trait PointOps {
|
||||
&self,
|
||||
lower_frontier: &Frontier<Self::Point>,
|
||||
upper_frontier: &Frontier<Self::Point>,
|
||||
) -> PointCompareFrontiers<Self::Point>;
|
||||
) -> PointCompareFrontiers;
|
||||
}
|
||||
pub trait FrontierOps {
|
||||
type Point;
|
||||
@ -85,21 +85,21 @@ impl PointOps for Point {
|
||||
&self,
|
||||
lower_frontier: &Frontier<Self::Point>,
|
||||
upper_frontier: &Frontier<Self::Point>,
|
||||
) -> PointCompareFrontiers<Self::Point> {
|
||||
) -> PointCompareFrontiers {
|
||||
// Check if the point is not dominated by any point in the lower frontier
|
||||
if let Some(point) = lower_frontier
|
||||
if lower_frontier
|
||||
.iter()
|
||||
.find(|lower_point| self.pareto_compare(lower_point) == ParetoCompare::BDominatesA)
|
||||
.any(|lower_point| self.pareto_compare(lower_point) == ParetoCompare::BDominatesA)
|
||||
{
|
||||
return PointCompareFrontiers::Below(point.clone());
|
||||
return PointCompareFrontiers::Below;
|
||||
}
|
||||
|
||||
// Check if the point does not dominate any point in the upper frontier
|
||||
if let Some(point) = upper_frontier
|
||||
if upper_frontier
|
||||
.iter()
|
||||
.find(|upper_point| self.pareto_compare(upper_point) == ParetoCompare::ADominatesB)
|
||||
.any(|upper_point| self.pareto_compare(upper_point) == ParetoCompare::ADominatesB)
|
||||
{
|
||||
return PointCompareFrontiers::Above(point.clone());
|
||||
return PointCompareFrontiers::Above;
|
||||
}
|
||||
|
||||
PointCompareFrontiers::Within
|
||||
@ -155,9 +155,22 @@ impl FrontierOps for Frontier {
|
||||
max_point: &Self::Point,
|
||||
multiplier: f64,
|
||||
) -> Frontier<Self::Point> {
|
||||
self.iter()
|
||||
let frontier: Frontier<Self::Point> = self
|
||||
.iter()
|
||||
.map(|point| point.scale(min_point, max_point, multiplier))
|
||||
.collect()
|
||||
.collect();
|
||||
if multiplier > 1.0 {
|
||||
frontier.pareto_frontier()
|
||||
} else {
|
||||
frontier
|
||||
.into_iter()
|
||||
.map(|d| d.iter().map(|x| -x).collect()) // mirror the points so easiest difficulties are first
|
||||
.collect::<Frontier>()
|
||||
.pareto_frontier()
|
||||
.iter()
|
||||
.map(|d| d.iter().map(|x| -x).collect())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
fn sample<R: Rng>(&self, rng: &mut R) -> Self::Point {
|
||||
// FIXME only works for 2 dimensional points
|
||||
|
||||
@ -43,7 +43,7 @@ impl PreciseNumber {
|
||||
Ok(Self(U256::from_dec_str(value)?))
|
||||
}
|
||||
|
||||
pub fn approx_inverse_exp(x: PreciseNumber) -> PreciseNumber {
|
||||
pub fn approx_inv_exp(x: PreciseNumber) -> PreciseNumber {
|
||||
// taylor series approximation of e^-x
|
||||
let one = PreciseNumber::from(1);
|
||||
let mut positive_terms = one.clone();
|
||||
|
||||
110
tig-utils/tests/eth.rs
Normal file
110
tig-utils/tests/eth.rs
Normal file
@ -0,0 +1,110 @@
|
||||
#[cfg(all(feature = "web3", test))]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn test_recover_address_from_msg_and_sig() {
|
||||
assert_eq!(
|
||||
tig_utils::recover_address_from_msg_and_sig(
|
||||
"test message",
|
||||
"0x3556abec5b4b955f02a3643a5a3a29672caee32bbae180506452c84ab51c83f608dce8828923eccd1f3b81d8aca540864b917f1221b3a4d7833a4e3ec183369d1c"
|
||||
)
|
||||
.unwrap(),
|
||||
"0x7e6f4be25823b70c97009670da2eea36ce9096dc"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_gnosis_safe_address() {
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_address(
|
||||
"https://mainnet.base.org",
|
||||
"0x0111ed72b3cd75e786083cf5d5db3a5ef0317891712315547fe49b3a16eebb16"
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
"0x6ab6dffdee6efc0e60b34ef4685b40784c497af8".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_address(
|
||||
"https://mainnet.base.org",
|
||||
"0xbe95f21a4172d16cbf243ed6082e6c1cc132ec5ac3011a8b5289283f9059b8ce",
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
"0xb787d8059689402dabc0a05832be526f79aa6b57".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_address(
|
||||
"https://sepolia.base.org",
|
||||
"0x90453a4f4ffffedeb70f144ce25d7ca74214f159ce394f0d929fda1d004d8ed0",
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
"0x0112fb82f8041071d7000fb9e4782668e8cbd05f".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_gnosis_safe_owners() {
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_owners(
|
||||
"https://mainnet.base.org",
|
||||
"0x6ab6dffdee6efc0e60b34ef4685b40784c497af8"
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["0x7adc19694782c61132bcc38accaf1156d13c80d1".to_string()]
|
||||
);
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_owners(
|
||||
"https://mainnet.base.org",
|
||||
"0xb787d8059689402dabc0a05832be526f79aa6b57",
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec![
|
||||
"0x9e10de6645d81823561aa4c91bef26c00b6c4d81".to_string(),
|
||||
"0xa327948a93000c6a37cac11b4239d7422a47c882".to_string(),
|
||||
"0x7a73bec3a56f935687dd30d0ff7c4bc632558c8b".to_string()
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
tig_utils::get_gnosis_safe_owners(
|
||||
"https://sepolia.base.org",
|
||||
"0x0112fb82f8041071d7000fb9e4782668e8cbd05f",
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
vec!["0x38d57e70513503c851f0a997fc1c8ab41cd2fca2".to_string()]
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_transaction() {
|
||||
assert_eq!(
|
||||
tig_utils::get_transaction(
|
||||
"https://mainnet.base.org",
|
||||
"0x2c84729e0c24ca982f598215a82888bf8620ebd1e42561b932ddf925b556ba51"
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
tig_utils::Transaction {
|
||||
sender: "0x097d62f58e2986f2e1d85f259454af15f02f601e".to_string(),
|
||||
receiver: "0xe37bf84f75a8c3225d80aea2a95a24fd5a736895".to_string(),
|
||||
amount: tig_utils::PreciseNumber::from_dec_str("362450000000000000").unwrap()
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
tig_utils::get_transaction(
|
||||
"https://sepolia.base.org",
|
||||
"0x72589afe1f24794328f6ab0b43933ba0d2f8d7321d7bb6febe1513961dd3271e",
|
||||
)
|
||||
.await
|
||||
.unwrap(),
|
||||
tig_utils::Transaction {
|
||||
sender: "0xf0e1c3b2bf8e5ec5420b82d6361d074bc4d8b7f4".to_string(),
|
||||
receiver: "0xb88a1d716fa26dea1b20b2263c10ca2d7613e22f".to_string(),
|
||||
amount: tig_utils::PreciseNumber::from_dec_str("499990756092107808").unwrap()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
108
tig-utils/tests/frontiers.rs
Normal file
108
tig-utils/tests/frontiers.rs
Normal file
@ -0,0 +1,108 @@
|
||||
use tig_utils::{Frontier, FrontierOps, ParetoCompare, PointCompareFrontiers, PointOps};
|
||||
|
||||
#[test]
|
||||
fn test_pareto_compare() {
|
||||
assert_eq!(vec![1, 0].pareto_compare(&vec![1, 0]), ParetoCompare::Equal);
|
||||
assert_eq!(vec![1, 0].pareto_compare(&vec![0, 1]), ParetoCompare::Equal);
|
||||
assert_eq!(
|
||||
vec![1, 1].pareto_compare(&vec![0, 1]),
|
||||
ParetoCompare::ADominatesB
|
||||
);
|
||||
assert_eq!(
|
||||
vec![1, 0].pareto_compare(&vec![1, 1]),
|
||||
ParetoCompare::BDominatesA
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_pareto_frontier() {
|
||||
let points: Frontier = vec![
|
||||
vec![3, 1],
|
||||
vec![1, 0],
|
||||
vec![0, 1],
|
||||
vec![1, 1],
|
||||
vec![0, 0],
|
||||
vec![2, 2],
|
||||
vec![2, 1],
|
||||
vec![1, 3],
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert_eq!(
|
||||
points.pareto_frontier(),
|
||||
vec![vec![2, 2], vec![3, 1], vec![1, 3]]
|
||||
.into_iter()
|
||||
.collect::<Frontier>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scale_point() {
|
||||
// ceil((x - min + 1) * multiplier)
|
||||
assert_eq!(
|
||||
vec![3, 1].scale(&vec![0, 0], &vec![10, 10], 1.2),
|
||||
vec![4, 2]
|
||||
);
|
||||
assert_eq!(
|
||||
vec![6, 2].scale(&vec![0, 0], &vec![10, 10], 0.7),
|
||||
vec![4, 2]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scale_frontier() {
|
||||
let frontier: Frontier = vec![vec![3, 1], vec![2, 2], vec![0, 4]]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert_eq!(
|
||||
frontier.scale(&vec![0, 0], &vec![10, 10], 1.2),
|
||||
vec![vec![4, 2], vec![3, 3], vec![1, 5]]
|
||||
.into_iter()
|
||||
.collect::<Frontier>()
|
||||
);
|
||||
assert_eq!(
|
||||
frontier.scale(&vec![0, 0], &vec![10, 10], 0.6),
|
||||
vec![vec![1, 1], vec![0, 2]]
|
||||
.into_iter()
|
||||
.collect::<Frontier>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_extend() {
|
||||
let frontier: Frontier = vec![vec![3, 1], vec![2, 2], vec![0, 4]]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert_eq!(
|
||||
frontier.extend(&vec![0, 0], &vec![10, 10]),
|
||||
vec![vec![4, 0], vec![3, 1], vec![2, 2], vec![0, 4]]
|
||||
.into_iter()
|
||||
.collect::<Frontier>()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_within() {
|
||||
let frontier1: Frontier = vec![vec![3, 1], vec![2, 2], vec![0, 4]]
|
||||
.into_iter()
|
||||
.collect();
|
||||
let frontier2: Frontier = vec![vec![6, 0], vec![5, 3], vec![0, 7]]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert_eq!(
|
||||
vec![4, 4].within(&frontier1, &frontier2),
|
||||
PointCompareFrontiers::Within
|
||||
);
|
||||
assert_eq!(
|
||||
vec![4, 0].within(&frontier1, &frontier2),
|
||||
PointCompareFrontiers::Within
|
||||
);
|
||||
assert_eq!(
|
||||
vec![5, 4].within(&frontier1, &frontier2),
|
||||
PointCompareFrontiers::Above
|
||||
);
|
||||
assert_eq!(
|
||||
vec![1, 2].within(&frontier1, &frontier2),
|
||||
PointCompareFrontiers::Below
|
||||
);
|
||||
}
|
||||
49
tig-utils/tests/number.rs
Normal file
49
tig-utils/tests/number.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use tig_utils::*;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_add_overflow() {
|
||||
let _ = PreciseNumber::from_dec_str(
|
||||
"115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
||||
)
|
||||
.unwrap()
|
||||
+ PreciseNumber::from(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_sub_underflow() {
|
||||
let _ = PreciseNumber::from(0) - PreciseNumber::from(1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_mul_overflow() {
|
||||
let _ = PreciseNumber::from_dec_str(
|
||||
"115792089237316195423570985008687907853269984665640564039457584007913129639935",
|
||||
)
|
||||
.unwrap()
|
||||
* PreciseNumber::from(2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn test_div_zero() {
|
||||
let _ = PreciseNumber::from(1) / PreciseNumber::from(0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_approx_inv_exp() {
|
||||
assert_eq!(
|
||||
PreciseNumber::approx_inv_exp(PreciseNumber::from(0)),
|
||||
PreciseNumber::from(1)
|
||||
);
|
||||
assert_eq!(
|
||||
PreciseNumber::approx_inv_exp(PreciseNumber::from(1) / PreciseNumber::from(2)),
|
||||
PreciseNumber::from_dec_str("606530659712633423").unwrap()
|
||||
);
|
||||
assert_eq!(
|
||||
PreciseNumber::approx_inv_exp(PreciseNumber::from(1)),
|
||||
PreciseNumber::from_dec_str("367879441171442320").unwrap()
|
||||
);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user