Compare commits

...

12 Commits

Author SHA1 Message Date
0a762388d7
make script work with main branch
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-03 22:30:34 +03:00
cdc14c5ed1
finally fix script for boostrappers
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-03 18:53:13 +03:00
fc3a6f0cd0
temporarily remove git manipulations during hard reset
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-03 18:14:20 +03:00
c90ef5f7e3
set git branch for bootstrapers
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-03 15:20:21 +03:00
a8651dfe84
prepare node to latest version of chain
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-03 15:17:46 +03:00
ddfbaae2f5
additional information during hard reset
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-02 19:18:33 +03:00
172edd46de
additional safety for multi request logic
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-02 18:10:52 +03:00
32483cdd40
make logs more self-descriptive
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-02 15:26:38 +03:00
eb9fc16b43
tests added for new offchain worker functionality
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-01 15:08:03 +03:00
b282ebad62
rustfmt the whole project
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-01-31 18:14:26 +03:00
73503fd13a
remove local testing scripts
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-01-31 18:12:05 +03:00
90c82f73cb
multiple requests from all endpoints
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-01-31 18:10:40 +03:00
12 changed files with 1665 additions and 457 deletions

14
Cargo.lock generated
View File

@ -3530,7 +3530,7 @@ dependencies = [
[[package]]
name = "ghost-cli"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"cfg-if",
"clap 4.5.4",
@ -3586,7 +3586,7 @@ dependencies = [
[[package]]
name = "ghost-machine-primitives"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"lazy_static",
"sc-sysinfo",
@ -3595,7 +3595,7 @@ dependencies = [
[[package]]
name = "ghost-metrics"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"assert_cmd",
"bs58 0.5.1",
@ -3670,7 +3670,7 @@ dependencies = [
[[package]]
name = "ghost-node"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"assert_cmd",
"color-eyre",
@ -3701,7 +3701,7 @@ dependencies = [
[[package]]
name = "ghost-rpc"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"ghost-core-primitives",
"jsonrpsee",
@ -3753,7 +3753,7 @@ dependencies = [
[[package]]
name = "ghost-service"
version = "0.8.4"
version = "0.8.5"
dependencies = [
"assert_matches",
"async-trait",
@ -3837,7 +3837,7 @@ dependencies = [
[[package]]
name = "ghost-slow-clap"
version = "0.4.10"
version = "0.4.14"
dependencies = [
"frame-benchmarking",
"frame-support",

View File

@ -17,7 +17,7 @@ homepage.workspace = true
[workspace.package]
license = "GPL-3.0-only"
authors = ["571nky", "57r37ch", "f4750"]
version = "0.8.4"
version = "0.8.5"
edition = "2021"
homepage = "https://ghostchain.io"
repository = "https://git.ghostchain.io/ghostchain/ghost-node"

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-slow-clap"
version = "0.4.10"
version = "0.4.14"
description = "Applause protocol for the EVM bridge"
license.workspace = true
authors.workspace = true

View File

@ -1,8 +1,6 @@
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
use core::usize;
use codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use serde::{Deserialize, Deserializer};
@ -26,11 +24,11 @@ use sp_core::H256;
use sp_runtime::{
offchain::{
self as rt_offchain,
http::PendingRequest,
storage::StorageValueRef,
storage_lock::{StorageLock, Time},
HttpError,
},
traits::{BlockNumberProvider, Convert, Saturating, TrailingZeroInput},
traits::{BlockNumberProvider, Convert, Saturating},
Perbill, RuntimeAppPublic, RuntimeDebug,
};
use sp_staking::{
@ -162,11 +160,16 @@ pub struct PreparedApplause<AccountId, NetworkId, Balance> {
enum OffchainErr<NetworkId> {
HttpJsonParsingError,
HttpBytesParsingError,
HttpRequestError(HttpError),
RequestUncompleted,
HttpResponseNotOk(u16),
ErrorInEvmResponse,
NoStoredNetworks,
NoRequestsSent,
EmptyResponses,
NotValidator,
DifferentEvmResponseTypes,
MissingBlockNumber(u32, u32),
ContradictoryTransactionLogs(u32, u32),
ContradictoryBlockMedian(u64, u64, u64),
UnparsableRequestBody(Vec<u8>),
NoEndpointAvailable(NetworkId),
StorageRetrievalError(NetworkId),
UtxoNotImplemented(NetworkId),
@ -183,31 +186,44 @@ impl<NetworkId: core::fmt::Debug> core::fmt::Debug for OffchainErr<NetworkId> {
OffchainErr::HttpBytesParsingError => {
write!(fmt, "Failed to parse evm response as bytes.")
}
OffchainErr::HttpRequestError(http_error) => match http_error {
HttpError::DeadlineReached => write!(
fmt,
"Requested action couldn't been completed within a deadline."
),
HttpError::IoError => {
write!(fmt, "There was an IO error while processing the request.")
}
HttpError::Invalid => {
write!(fmt, "The ID of the request is invalid in this context.")
}
},
OffchainErr::StorageRetrievalError(ref network_id) => write!(
fmt,
"Storage value found for network #{:?} but it's undecodable.",
network_id
),
OffchainErr::RequestUncompleted => write!(fmt, "Failed to complete request."),
OffchainErr::HttpResponseNotOk(code) => {
write!(fmt, "Http response returned code {:?}.", code)
}
OffchainErr::ErrorInEvmResponse => write!(fmt, "Error in evm reponse."),
OffchainErr::NoStoredNetworks => {
write!(fmt, "No networks stored for the offchain slow claps.")
}
OffchainErr::NoRequestsSent => write!(
fmt,
"Could not send a request to any available RPC ednpoint."
),
OffchainErr::EmptyResponses => {
write!(fmt, "No responses to be used by the offchain worker.")
}
OffchainErr::NotValidator => write!(fmt, "Not a validator to broadcast slow claps"),
OffchainErr::DifferentEvmResponseTypes => write!(
fmt,
"Different endpoints returned conflicting response types."
),
OffchainErr::MissingBlockNumber(ref index, ref length) => write!(
fmt,
"Could not get block response at index {index} where total length is {length}.",
),
OffchainErr::ContradictoryBlockMedian(ref mid, ref prev, ref distance) => write!(
fmt,
"Contradictory block median: values are {prev} {mid} while max distance is {distance}.",
),
OffchainErr::ContradictoryTransactionLogs(ref count, ref number) => write!(
fmt,
"Contradictory tx logs: {number} event sequences from {count} endpoints.",
),
OffchainErr::UnparsableRequestBody(ref bytes) => write!(
fmt,
"Could not get valid utf8 request body from bytes: {:?}.",
bytes
),
OffchainErr::NoEndpointAvailable(ref network_id) => write!(
fmt,
"No RPC endpoint available for network #{:?}.",
@ -853,55 +869,59 @@ impl<T: Config> Pallet<T> {
network_data.default_endpoints.clone(),
);
let random_seed = sp_io::offchain::random_seed();
let random_number = <u32>::decode(&mut TrailingZeroInput::new(random_seed.as_ref()))
.expect("input is padded with zeroes; qed");
let random_index = (random_number as usize)
.checked_rem(stored_endpoints.len())
.unwrap_or_default();
let endpoints = if !stored_endpoints.is_empty() {
let rpc_endpoints = if !stored_endpoints.is_empty() {
&stored_endpoints
} else {
&network_data.default_endpoints
};
let rpc_endpoint = endpoints
.get(random_index)
.ok_or(OffchainErr::NoEndpointAvailable(network_id))?;
if rpc_endpoints.len() == 0 {
return Err(OffchainErr::NoEndpointAvailable(network_id));
}
let (from_block, to_block): (u64, u64) = StorageValueRef::persistent(&block_number_key)
.get()
.map_err(|_| OffchainErr::StorageRetrievalError(network_id))?
.unwrap_or_default();
match network_data.network_type {
NetworkType::Evm => {
let request_body = if from_block < to_block.saturating_sub(1) {
Self::prepare_request_body_for_latest_transfers(
Self::prepare_evm_request_body_for_latest_transfers(
from_block,
to_block.saturating_sub(1),
network_data,
)
} else {
Self::prepare_request_body_for_latest_block(network_data)
Self::prepare_evm_request_body_for_latest_block(network_data)
};
let response_bytes = Self::fetch_from_remote(&rpc_endpoint, &request_body)?;
let pending_requests =
Self::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let parsed_evm_responses = Self::fetch_multiple_evm_from_remote(pending_requests)
.iter()
.filter_map(|response_bytes| {
let parsed_evm_response = Self::parse_evm_response(response_bytes).ok()?;
Some(parsed_evm_response)
})
.collect::<Vec<EvmResponseType>>();
Self::check_evm_responses_correctness(&parsed_evm_responses)?;
let parsed_evm_response =
Self::get_balanced_evm_response(&parsed_evm_responses, max_block_distance)?;
match network_data.network_type {
NetworkType::Evm => {
let parsed_evm_response = Self::parse_evm_response(&response_bytes)?;
let new_block_range = match parsed_evm_response {
EvmResponseType::BlockNumber(new_evm_block) if from_block.le(&to_block) => {
// stay in the range of block distance
let estimated_block =
new_evm_block.saturating_sub(network_data.finality_delay);
let adjusted_block =
Self::adjust_to_block(estimated_block, from_block, max_block_distance);
if from_block == 0 {
(estimated_block, estimated_block)
} else {
(from_block, adjusted_block)
match from_block {
0 => (estimated_block, estimated_block),
start_block => {
let block_deviation =
start_block.saturating_add(max_block_distance);
(start_block, estimated_block.min(block_deviation))
}
}
}
_ => (to_block, to_block),
@ -911,15 +931,14 @@ impl<T: Config> Pallet<T> {
log::info!(
target: LOG_TARGET,
"👻 Slow Clap #{:?} stored block #{:?} for network {:?}",
"👻 Offchain worker #{:?} stored block #{:?} for network {:?}",
block_number,
new_block_range.0,
network_id,
);
if !sp_io::offchain::is_validator() {
log::info!(target: LOG_TARGET, "👻 Not a validator; no transactions available");
return Ok(());
return Err(OffchainErr::NotValidator);
}
for (authority_index, authority_key) in Self::local_authorities(&session_index) {
@ -939,22 +958,6 @@ impl<T: Config> Pallet<T> {
}
}
fn adjust_to_block(estimated_block: u64, from_block: u64, max_block_distance: u64) -> u64 {
let fallback_value = from_block
.saturating_add(max_block_distance)
.min(estimated_block);
estimated_block
.checked_sub(from_block)
.map(|current_distance| {
current_distance
.le(&max_block_distance)
.then_some(estimated_block)
})
.flatten()
.unwrap_or(fallback_value)
}
fn local_authorities(
session_index: &SessionIndex,
) -> impl Iterator<Item = (u32, T::AuthorityId)> {
@ -973,35 +976,216 @@ impl<T: Config> Pallet<T> {
})
}
fn fetch_from_remote(rpc_endpoint: &[u8], request_body: &[u8]) -> OffchainResult<T, Vec<u8>> {
let rpc_endpoint_str =
core::str::from_utf8(rpc_endpoint).expect("rpc endpoint valid str; qed");
let request_body_str =
core::str::from_utf8(request_body).expect("request body valid str: qed");
fn prepare_pending_evm_requests(
rpc_endpoints: &Vec<Vec<u8>>,
request_body: &[u8],
) -> OffchainResult<T, Vec<PendingRequest>> {
let mut pending_requests = Vec::new();
let request_body_str = core::str::from_utf8(request_body)
.map_err(|_| OffchainErr::UnparsableRequestBody(request_body.to_vec()))?;
let deadline = sp_io::offchain::timestamp()
.add(rt_offchain::Duration::from_millis(FETCH_TIMEOUT_PERIOD));
let pending = rt_offchain::http::Request::post(&rpc_endpoint_str, vec![request_body_str])
for rpc_endpoint in rpc_endpoints.iter() {
let rpc_endpoint_str = match core::str::from_utf8(rpc_endpoint) {
Ok(rpc_endpoint_str) => rpc_endpoint_str,
Err(_) => {
log::info!(
target: LOG_TARGET,
"👻 Could not get valid utf8 rpc endpoint from bytes; skipped \"{:?}\"",
rpc_endpoint,
);
continue;
}
};
match rt_offchain::http::Request::post(&rpc_endpoint_str, vec![request_body_str])
.add_header("Accept", "application/json")
.add_header("Content-Type", "application/json")
.deadline(deadline)
.send()
.map_err(|err| OffchainErr::HttpRequestError(err))?;
{
Ok(pending) => pending_requests.push(pending),
Err(_) => {
log::info!(
target: LOG_TARGET,
"👻 Request skipped: failed to send request to \"{}\"",
rpc_endpoint_str,
)
}
}
}
let response = pending
.try_wait(deadline)
.map_err(|_| OffchainErr::RequestUncompleted)?
.map_err(|_| OffchainErr::RequestUncompleted)?;
if pending_requests.len() == 0 {
return Err(OffchainErr::NoRequestsSent);
}
log::info!(
target: LOG_TARGET,
"👻 Requests sent {} out of {} possible RPC endpoints",
pending_requests.len(),
rpc_endpoints.len(),
);
Ok(pending_requests)
}
fn get_balanced_evm_response(
parsed_evm_responses: &Vec<EvmResponseType>,
max_block_distance: u64,
) -> OffchainResult<T, EvmResponseType> {
let first_evm_response = parsed_evm_responses
.first()
.ok_or(OffchainErr::EmptyResponses)?;
let result = match first_evm_response {
EvmResponseType::BlockNumber(_) => {
let mut block_numbers = parsed_evm_responses
.iter()
.enumerate()
.filter_map(|(index, response)| match response {
EvmResponseType::BlockNumber(block) => Some((index as u32, *block)),
EvmResponseType::TransactionLogs(_) => None,
})
.collect::<Vec<_>>();
let block_numbers_len = block_numbers.len() as u32;
let median_value = Self::calculate_median_value(&mut block_numbers);
// there is no intention to make it resistent to *ANY* type of issues around RPC
// ednpoint. here we are trying to protect against `parsed_evm_responses.len() ==
// 2` while one of it is malicious in order not to fall in the block backoff later
let mid_idx =
block_numbers.partition_point(|&block_meta| block_meta.1 < median_value);
let mid_block = block_numbers.get(mid_idx).map(|(_, block)| *block).ok_or(
OffchainErr::MissingBlockNumber(mid_idx as u32, block_numbers_len),
)?;
let prev_block = if block_numbers_len % 2 == 0 {
let prev_idx = mid_idx.saturating_sub(1);
let prev_block = block_numbers.get(prev_idx).map(|(_, block)| *block).ok_or(
OffchainErr::MissingBlockNumber(prev_idx as u32, block_numbers_len),
)?;
prev_block
} else {
mid_block
};
if mid_block.abs_diff(prev_block) > max_block_distance {
return Err(OffchainErr::ContradictoryBlockMedian(
mid_block,
prev_block,
max_block_distance,
));
}
EvmResponseType::BlockNumber(median_value)
}
EvmResponseType::TransactionLogs(_) => {
let mut count_btree_map = BTreeMap::new();
parsed_evm_responses.iter().for_each(|response| {
if let EvmResponseType::TransactionLogs(logs) = response {
let mut inner_logs = logs.clone();
inner_logs.sort_by_key(|l| l.block_number);
*count_btree_map.entry(inner_logs).or_insert(0) += 1;
}
});
let (best_logs_ref, max_count) = count_btree_map
.iter()
.max_by_key(|&(_, count)| count)
.map(|(logs, count)| (logs, count))
.ok_or(OffchainErr::EmptyResponses)?;
let best_logs_count = count_btree_map
.values()
.filter(|&&count| count == *max_count)
.count();
if best_logs_count > 1 {
return Err(OffchainErr::ContradictoryTransactionLogs(
*max_count,
best_logs_count as u32,
));
}
EvmResponseType::TransactionLogs(best_logs_ref.clone())
}
};
Ok(result)
}
fn check_evm_responses_correctness(
parsed_evm_responses: &Vec<EvmResponseType>,
) -> OffchainResult<T, ()> {
let first_evm_response = parsed_evm_responses
.first()
.ok_or(OffchainErr::EmptyResponses)?;
let first_evm_response_type = core::mem::discriminant(first_evm_response);
if !parsed_evm_responses.iter().all(|parsed_evm_response| {
core::mem::discriminant(parsed_evm_response) == first_evm_response_type
}) {
return Err(OffchainErr::DifferentEvmResponseTypes);
}
Ok(())
}
fn fetch_multiple_evm_from_remote(pending_requests: Vec<PendingRequest>) -> Vec<Vec<u8>> {
let mut requests_failed = 0;
let mut responses_failed = 0;
let mut responses_non_200 = 0;
let pending_requests_len = pending_requests.len();
let deadline = sp_io::offchain::timestamp()
.add(rt_offchain::Duration::from_millis(FETCH_TIMEOUT_PERIOD));
let parsed_evm_responses = PendingRequest::try_wait_all(pending_requests, Some(deadline))
.into_iter()
.filter_map(|pending_request| {
// handle request-level errors (transport/connection failures)
let request_result = match pending_request {
Ok(request) => request,
Err(_) => {
requests_failed += 1;
return None;
}
};
// handle response-level errors (HTTP/protocol errors)
let response = match request_result {
Ok(response) => response,
Err(_) => {
responses_failed += 1;
return None;
}
};
if response.code != 200 {
return Err(OffchainErr::HttpResponseNotOk(response.code));
responses_non_200 += 1;
return None;
}
Ok(response.body().collect::<Vec<u8>>())
Some(response.body().collect::<Vec<u8>>())
})
.collect::<Vec<Vec<u8>>>();
log::info!(
target: LOG_TARGET,
"👻 Fetched {} of {}: {} failed request, {} failed responses, {} non 200 code",
parsed_evm_responses.len(),
pending_requests_len,
requests_failed,
responses_failed,
responses_non_200,
);
parsed_evm_responses
}
fn prepare_request_body_for_latest_block(network_data: &NetworkData) -> Vec<u8> {
fn prepare_evm_request_body_for_latest_block(network_data: &NetworkData) -> Vec<u8> {
match network_data.network_type {
NetworkType::Evm => {
b"{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}".to_vec()
@ -1010,7 +1194,7 @@ impl<T: Config> Pallet<T> {
}
}
fn prepare_request_body_for_latest_transfers(
fn prepare_evm_request_body_for_latest_transfers(
from_block: u64,
to_block: u64,
network_data: &NetworkData,

View File

@ -3,6 +3,7 @@
use std::time::{SystemTime, UNIX_EPOCH};
use super::*;
use crate::evm_types::Log;
use crate::mock::*;
use frame_support::{assert_err, assert_ok, dispatch};
@ -137,16 +138,6 @@ fn bitmap_operations_correct() {
assert_eq!(ones, 11);
}
#[test]
fn should_correctly_adjust_to_block() {
assert_eq!(SlowClap::adjust_to_block(420, 69, 1337), 420);
assert_eq!(SlowClap::adjust_to_block(420, 1337, 69), 420);
assert_eq!(SlowClap::adjust_to_block(1337, 420, 69), 489);
assert_eq!(SlowClap::adjust_to_block(1337, 69, 420), 489);
assert_eq!(SlowClap::adjust_to_block(69, 1337, 420), 69);
assert_eq!(SlowClap::adjust_to_block(69, 420, 1337), 69);
}
#[test]
fn request_body_is_correct_for_get_block_number() {
let (offchain, _) = TestOffchainExt::new();
@ -155,7 +146,7 @@ fn request_body_is_correct_for_get_block_number() {
t.execute_with(|| {
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
assert_eq!(
core::str::from_utf8(&request_body).unwrap(),
r#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#
@ -173,7 +164,7 @@ fn request_body_is_correct_for_get_logs() {
let from_block: u64 = 420;
let to_block: u64 = 1337;
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers(
from_block, to_block, &network_data);
assert_eq!(core::str::from_utf8(&request_body).unwrap(),
r#"{"id":0,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1a4","toBlock":"0x539","address":"0x4d224452801ACEd8B2F0aebE155379bb5D594381","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}"#,
@ -190,10 +181,15 @@ fn should_make_http_call_for_block_number() {
evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoint = get_rpc_endpoint();
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let raw_responses = SlowClap::fetch_multiple_evm_from_remote(pending_requests);
let raw_response = raw_responses.first().unwrap();
assert_eq!(raw_response.len(), 45usize); // precalculated
Ok(())
});
@ -210,15 +206,20 @@ fn should_make_http_call_for_logs() {
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let from_block: u64 = 20335770;
let to_block: u64 = 20335858;
let rpc_endpoint = get_rpc_endpoint();
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers(
from_block,
to_block,
&network_data,
);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let raw_responses = SlowClap::fetch_multiple_evm_from_remote(pending_requests);
let raw_response = raw_responses.first().unwrap();
assert_eq!(raw_response.len(), 1805); // precalculated
Ok(())
});
@ -233,11 +234,15 @@ fn should_make_http_call_and_parse_block_number() {
evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoint = get_rpc_endpoint();
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let raw_responses = SlowClap::fetch_multiple_evm_from_remote(pending_requests);
let raw_response = raw_responses.first().unwrap();
let evm_block_number = SlowClap::parse_evm_response(&raw_response).map(
|parsed_response| match parsed_response {
EvmResponseType::BlockNumber(block_number) => block_number,
@ -263,19 +268,23 @@ fn should_make_http_call_and_parse_logs() {
evm_logs_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoint = get_rpc_endpoint();
let rpc_endpoints = get_rpc_endpoints();
let from_block: u64 = 20335770;
let to_block: u64 = 20335858;
let network_data = prepare_evm_network(None, None);
let request_body = SlowClap::prepare_request_body_for_latest_transfers(
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers(
from_block,
to_block,
&network_data,
);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let raw_responses = SlowClap::fetch_multiple_evm_from_remote(pending_requests);
let raw_response = raw_responses.first().unwrap();
match SlowClap::parse_evm_response(&raw_response)? {
EvmResponseType::BlockNumber(_) => assert_eq!(1, 0), // force break
EvmResponseType::TransactionLogs(evm_logs) => assert_eq!(evm_logs.len(), 2),
@ -285,6 +294,162 @@ fn should_make_http_call_and_parse_logs() {
});
}
#[test]
fn should_prepare_correct_evm_request_for_latest_block() {
let (offchain, state) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
assert_eq!(pending_requests.len(), rpc_endpoints.len());
for (i, pending_metadata) in pending_requests.iter().enumerate() {
assert_eq!(pending_metadata.id.0, i as u16);
}
Ok(())
});
}
#[test]
fn should_prepare_correct_evm_request_for_latest_transfers() {
let (offchain, state) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
evm_logs_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let from_block: u64 = 20335770;
let to_block: u64 = 20335858;
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers(
from_block,
to_block,
&network_data,
);
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
assert_eq!(pending_requests.len(), rpc_endpoints.len());
for (i, pending_metadata) in pending_requests.iter().enumerate() {
assert_eq!(pending_metadata.id.0, i as u16);
}
Ok(())
});
}
#[test]
fn should_throw_error_on_empty_prepared_requests() {
let (offchain, _) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = vec![];
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
assert_err!(
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body),
OffchainErr::NoRequestsSent,
);
Ok(())
});
}
#[test]
fn should_ignore_unparsable_rpc_ednpoint() {
let (offchain, _) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = vec![get_rpc_endpoint(), vec![0xFF]];
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_empty_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
assert_eq!(pending_empty_requests.len(), 1);
Ok(())
});
}
#[test]
fn should_fetch_blocks_correctly() {
let (offchain, state) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_requests =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let fetched_blocks_raw = SlowClap::fetch_multiple_evm_from_remote(pending_requests);
assert_eq!(fetched_blocks_raw.len(), 2);
Ok(())
});
}
#[test]
fn should_parse_blocks_correctly() {
let (offchain, state) = TestOffchainExt::new();
let mut t = sp_io::TestExternalities::default();
t.register_extension(OffchainWorkerExt::new(offchain));
evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints();
let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data);
let pending_requests_metadata =
SlowClap::prepare_pending_evm_requests(&rpc_endpoints, &request_body)?;
let parsed_evm_responses =
SlowClap::fetch_multiple_evm_from_remote(pending_requests_metadata)
.iter()
.filter_map(|response_bytes| {
let parsed_evm_response = SlowClap::parse_evm_response(response_bytes).ok()?;
Some(parsed_evm_response)
})
.collect::<Vec<EvmResponseType>>();
assert_eq!(parsed_evm_responses.len(), 2);
assert_eq!(
parsed_evm_responses[0],
EvmResponseType::BlockNumber(20335745)
);
assert_eq!(
parsed_evm_responses[1],
EvmResponseType::BlockNumber(20335745)
);
Ok(())
});
}
#[test]
fn should_emit_black_swan_if_not_enough_authorities_left() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
@ -1355,6 +1520,147 @@ fn should_split_commit_slash_between_active_validators() {
});
}
#[test]
fn should_check_responses_correctly() {
new_test_ext().execute_with(|| {
let empty_responses = vec![];
assert_err!(
SlowClap::check_evm_responses_correctness(&empty_responses),
OffchainErr::EmptyResponses,
);
let different_responses_types = vec![
EvmResponseType::BlockNumber(60),
EvmResponseType::BlockNumber(420),
EvmResponseType::TransactionLogs(Default::default()),
EvmResponseType::BlockNumber(1337),
];
assert_err!(
SlowClap::check_evm_responses_correctness(&different_responses_types),
OffchainErr::DifferentEvmResponseTypes,
);
let correct_block_responses = vec![
EvmResponseType::BlockNumber(69),
EvmResponseType::BlockNumber(420),
EvmResponseType::BlockNumber(1337),
EvmResponseType::BlockNumber(20335745),
];
assert_ok!(SlowClap::check_evm_responses_correctness(
&correct_block_responses
));
let correct_log_responses = vec![
EvmResponseType::TransactionLogs(Default::default()),
EvmResponseType::TransactionLogs(Default::default()),
EvmResponseType::TransactionLogs(Default::default()),
EvmResponseType::TransactionLogs(Default::default()),
];
assert_ok!(SlowClap::check_evm_responses_correctness(
&correct_log_responses
));
});
}
#[test]
fn should_get_balanced_responses_correctly() {
new_test_ext().execute_with(|| {
let max_distance = 420;
let empty_responses = vec![];
assert_err!(
SlowClap::get_balanced_evm_response(&empty_responses, max_distance),
OffchainErr::EmptyResponses,
);
let correct_block_responses = vec![
EvmResponseType::BlockNumber(69),
EvmResponseType::BlockNumber(420),
EvmResponseType::BlockNumber(422),
EvmResponseType::BlockNumber(1337),
];
let median_block =
SlowClap::get_balanced_evm_response(&correct_block_responses, max_distance)
.expect("median block should be extractable; qed");
assert_eq!(median_block, EvmResponseType::BlockNumber(421));
let contradictory_block_responses = vec![
EvmResponseType::BlockNumber(69),
EvmResponseType::BlockNumber(1337),
];
assert_err!(
SlowClap::get_balanced_evm_response(&contradictory_block_responses, max_distance),
OffchainErr::ContradictoryBlockMedian(1337, 69, max_distance),
);
let first_correct_log = Log {
transaction_hash: Some(H256::random()),
block_number: Some(69),
topics: vec![],
removed: false,
};
let second_correct_log = Log {
transaction_hash: Some(H256::random()),
block_number: Some(420),
topics: vec![],
removed: false,
};
let first_wrong_block_log = Log {
block_number: Some(1338),
..first_correct_log.clone()
};
let first_wrong_transaction_log = Log {
transaction_hash: Some(H256::zero()),
..first_correct_log.clone()
};
let second_wrong_block_log = Log {
block_number: Some(1338),
..second_correct_log.clone()
};
let second_wrong_transaction_log = Log {
transaction_hash: Some(H256::zero()),
..second_correct_log.clone()
};
let correct_log_responses = vec![
EvmResponseType::TransactionLogs(vec![
first_correct_log.clone(),
second_correct_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![
first_correct_log.clone(),
second_correct_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![
first_correct_log.clone(),
second_wrong_block_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![
first_correct_log.clone(),
second_wrong_transaction_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![
first_wrong_block_log.clone(),
second_correct_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![
first_wrong_transaction_log.clone(),
second_correct_log.clone(),
]),
EvmResponseType::TransactionLogs(vec![first_wrong_block_log, second_wrong_block_log]),
EvmResponseType::TransactionLogs(vec![
first_wrong_transaction_log,
second_wrong_transaction_log,
]),
];
let best_logs = SlowClap::get_balanced_evm_response(&correct_log_responses, 420)
.expect("best logs should be extractable; qed");
assert_eq!(
best_logs,
EvmResponseType::TransactionLogs(vec![first_correct_log, second_correct_log])
);
});
}
fn assert_clapped_amount(
session_index: &SessionIndex,
unique_hash: &H256,
@ -1571,6 +1877,7 @@ fn get_mocked_metadata() -> (H256, u64, u64, u64) {
fn evm_block_response(state: &mut testing::OffchainState) {
let expected_body = br#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#.to_vec();
state.expect_request(testing::PendingRequest {
method: "POST".into(),
uri: "https://rpc.endpoint.network.com".into(),
@ -1579,6 +1886,19 @@ fn evm_block_response(state: &mut testing::OffchainState) {
("Content-Type".to_string(), "application/json".to_string()),
],
response: Some(b"{\"id\":0,\"jsonrpc\":\"2.0\",\"result\":\"0x1364c81\"}".to_vec()),
body: expected_body.clone(),
sent: true,
..Default::default()
});
state.expect_request(testing::PendingRequest {
method: "POST".into(),
uri: "https://other.endpoint.network.com".into(),
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
],
response: Some(b"{\"id\":0,\"jsonrpc\":\"2.0\",\"result\":\"0x1364c81\"}".to_vec()),
body: expected_body,
sent: true,
..Default::default()
@ -1636,6 +1956,23 @@ fn evm_logs_response(state: &mut testing::OffchainState) {
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
],
body: expected_body.clone(),
response: Some(expected_response.clone()),
sent: true,
..Default::default()
});
state.expect_request(testing::PendingRequest {
method: "POST".into(),
uri: "https://other.endpoint.network.com".into(),
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
],
response_headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
],
body: expected_body,
response: Some(expected_response),
sent: true,

View File

@ -209,9 +209,13 @@ if [[ $HARD_RESET = true ]]; then
echo "WARNING!!! THIS ACTION WILL COMPLETELY PURGE THE LEDGER AND REBUILD THE NODE USING THE LATEST"
echo "REPOSITORY VERSION. NOTE THAT THE VALIDATION PROCESS WILL BE LOST BECAUSE SESSION OF KEYS."
echo "THERE ARE TWO SCENARIOS IN WHICH YOU MIGHT NEED TO PROCEED:"
echo -e "\t- A new version of the network hsa been released, and a restart is neccessary"
echo -e "\t- A new version of the network has been released, and a restart is neccessary"
echo -e "\t- There is a critical issue, and you require a hard reset of the node in a single command"
echo -e "\n"
echo "IMPORTANT!!! Your validator's session keys will be also removed. Consequently, your validator node"
echo "will be slashed indefinitely and will become inactive. After hard reset, you'll need to manage the"
echo "keys manually to reactivate the validator."
echo -e "\n"
if prompt "[?] do you understand all risks?"; then
echo "[+] you were warned, I hope you know what you're doing"
else

File diff suppressed because one or more lines are too long

View File

@ -190,7 +190,8 @@ fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> {
#[cfg(feature = "casper-native")]
fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
vec![(
vec![
(
11155111,
ghost_networks::NetworkData {
chain_name: "sepolia-ethereum-testnet".into(),
@ -213,10 +214,31 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
incoming_fee: 69_000_000u32,
outgoing_fee: 0u32,
}
.encode(),
1464619352760244956993u128,
)]
}.encode(),
2048861035254140036511u128,
),
(
63,
ghost_networks::NetworkData {
chain_name: "mordor-classic-testnet".into(),
default_endpoints: vec![
"https://rpc.mordor.etccooperative.org".into(),
"https://geth-mordor.etc-network.info".into(),
"https://0xrpc.io/mordor".into(),
],
finality_delay: 3_000u64,
rate_limit_delay: 5_000u64,
block_distance: 20u64,
avg_block_speed: 13_000,
network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0xA59cB4ff90bE2206121aE61eEB68d0AeC7BA095f".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
incoming_fee: 69_000_000u32,
outgoing_fee: 0u32,
}.encode(),
5100000000000000000u128,
),
]
}
/// Helper function to create casper `GenesisConfig` for testing
@ -438,7 +460,7 @@ fn casper_staging_config_genesis() -> serde_json::Value {
.collect::<Vec<_>>(),
},
"staking": {
"validatorCount": 500,
"validatorCount": 69,
"minimumValidatorCount": 3,
"stakers": initial_authorities
.iter()
@ -453,8 +475,10 @@ fn casper_staging_config_genesis() -> serde_json::Value {
.collect::<Vec<_>>(),
"forceEra": Forcing::NotForcing,
"slashRewardFraction": Perbill::from_percent(10),
"minNominatorBond": 6_900 * STRH,
"minNominatorBond": 690 * STRH,
"minValidatorBond": 6_900 * STRH,
"maxNominatorCount": Some(1337),
"maxValidatorCount": Some(420),
},
"babe": {
"epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG),

View File

@ -2,186 +2,805 @@ use hex_literal::hex;
pub fn legacy_endowments() -> Vec<(primitives::AccountId, u128)> {
vec![
(hex!["fe3cb0119ffaf59434233d0b0d85cd2d16fde46f713dcab39047eb222f3ae666"].into(), 898508876174623538u128),
(hex!["88a74a42ca9a17acc210ae56ff8ace565e246025a2743da967dfde9d6c76277c"].into(), 11499490981584684807u128),
(hex!["94addf7d81d155c9f4d8d0eab3ceb019939db5f3b0081ae3e888a6ed3c845307"].into(), 1000000000000000u128),
(hex!["6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666"].into(), 20045398007416485176u128),
(hex!["7409c6caca65472f77938a143a7ee73a85dd9c1acf60fcc13aade8dc1be38a0a"].into(), 30478997642754917282u128),
(hex!["fa402c6b1c1db2ce9e3e1ba4e559581faa821d20254d8d16e4e18057a3b90672"].into(), 9796698744519740142u128),
(hex!["ac1932d76a47c5819724999aa3626aa85e71bf60c8fccdeac92cf53beab7a85f"].into(), 346508876174623538u128),
(hex!["a6bbe75122ce02a5c0d9ebeda902fb0ae21138a7487e18adef1c3e7d106b3715"].into(), 898508876174623538u128),
(hex!["1225d9453ad3fe1197dfc2410760cea284529e226fef262fb01574ae2a6c5900"].into(), 16442998462241875728u128),
(hex!["ac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c"].into(), 1998508837042115740u128),
(hex!["6cabf6e32fb8909acae30605bb3e5997d201103d298734851d58022423977655"].into(), 12822257832237511466u128),
(hex!["fe0f596b6bf22b5fbad52ebce3429bb6bdeb00996fc8e51aae2e437450f6b578"].into(), 12157355198880897693u128),
(hex!["84e01e431c701383fb0fc204338aca8cff0a2e88bb9397ba7b5ec8b236850e17"].into(), 9488095602980648270u128),
(hex!["507110e1a96c4b781207ad9c790c558f752ca99614f281b6b24a2e467e04e25e"].into(), 9713310740009473644u128),
(hex!["005dc72f4d842896adf3505695eef833aad9cdee22448751f0500c30cfdda247"].into(), 14021423144351682305u128),
(hex!["a64f42e128afa40b848faf5df5e260e58390c6ca2bbcd5e866b5460a4c2dc60c"].into(), 10792504141381628956u128),
(hex!["4a32ed6e36b6dec1ce328c650f5276a6e5ac4e594b7ba71a1cb87a2770f53b33"].into(), 14140001662633653275u128),
(hex!["58967ccdc9d4ddab5c32b6605947becba27cca5799a93c9d4d03a0fb3ebc7316"].into(), 453608876174623538u128),
(hex!["323158b7e1cb9b3104fce73ed72095764fe785a1d14b9a8f73e54973f04b9d74"].into(), 13375245216003871505u128),
(hex!["3e130ccc1fac5e9d5c2c280341ce8b8dbcafc17ceb75d3722f83404ed2215856"].into(), 16753318413269579418u128),
(hex!["acbda1ba4cfd81cd430b53a834c0d92085e8efc6948a03c10c2f6a66ba19443a"].into(), 36751232674856508996u128),
(hex!["4cecf92b37e6954f086002cf7b6a61ac7d9ba40c83ef963005e3cacfb5c1e13f"].into(), 14040022959030355565u128),
(hex!["f09c9f7ecdd1be0d07a2d0759efdff5152f23ec742f86e15a9ac03c0995f2365"].into(), 898508876174623538u128),
(hex!["8256b4a52f0277042cacc427cf00b8d668d0e7fe7824f53acf927da985f32410"].into(), 898508876174623538u128),
(hex!["3a926d7cf3546e58e48f9faf392b02e6d1d43011676378914988eeaea2cbff3a"].into(), 4035504698494152u128),
(hex!["e4dcfdec0dda94b9cb45bf6ff12439392f01fb9d738f806fb115b1d21c99135d"].into(), 3977726628523870614u128),
(hex!["cc88301ef74e085f731220d101dcd14d2b04bc1e59a6c45009c156a9990eab46"].into(), 38103139771143223684u128),
(hex!["46f41aed549dcfa8c094c19787dfbe974fef680eacd209ef88640c82bcb77811"].into(), 13819008291976111251u128),
(hex!["9a3e9942c0cb9fe1f1acc97c3bf458e9b7955f44604183e569d5120de3400e10"].into(), 8835780408986419448u128),
(hex!["9aceaa2fa9e3226bbe106cd0150f9807b089281b16942bff471caa1359aa8a22"].into(), 1360508232557032475u128),
(hex!["661fd59a3748d65d66d9612f0c8f5871029e8e74deb3c0e1fbdbcf3c04e84a5e"].into(), 246508876174623538u128),
(hex!["20fed126411d5d1a1ab3915bffac49297b0eae9dcf4288589c0cad49d925637b"].into(), 1308508876174623538u128),
(hex!["eeaaf5db1b1eb55cc8c1b26c5092868ada9af63c2961bba4d4b5d63e99371c00"].into(), 13381482878571786796u128),
(hex!["ac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50"].into(), 75053899371678858u128),
(hex!["144a1fa97fdba679efd2a36696a0d40f585b649143bb7da5cbd7458ea4a0f674"].into(), 19762757562620855283u128),
(hex!["a231498b31f698619d80746aa2049ec187c4a103a3c5a8940e14d1b03abe1239"].into(), 676568060690000000u128),
(hex!["d05b788865ffffdfbb7dfecd937188628a275926ab47742f84b5cda86e5d825d"].into(), 97017752349247076u128),
(hex!["7673ef8a48eaf9364831735201743d20587e27ff5ff2df42808e4625be6f656b"].into(), 899439876174623538u128),
(hex!["6a92d2e77c6b56428db2129d33c3ba1e71c8a52315a65f03f30dbaf31224153d"].into(), 708444482928862970u128),
(hex!["d8193ef891724c66a6cc58273eadcfb133f9bbc7d777e6456721a70e90ded71f"].into(), 195510000000000000u128),
(hex!["c256b6d62a54c94220ceb1b55f4afae84e59c913b8163d57791463d7ac67555c"].into(), 13111614265582327685u128),
(hex!["723aabc24abe3a04fb79c4a51e5b023e99f5c1afcfeac7d434276496a65ede3e"].into(), 898508876174623538u128),
(hex!["4078ddb1ba1388f768fe6aa40ba9124a72692ecbcc83dc088fa86c735e4dc128"].into(), 1045536628523870614u128),
(hex!["d8a1924995f48a61c0bb79f3fdaeff18573cf1d2164454938c773f6066d81413"].into(), 3296223653083995083u128),
(hex!["b85a4db79fa17d9853f2c4031aa60c8ee09a38bbce5e484ddb4c6b32bfefd401"].into(), 14390589865809310762u128),
(hex!["224f1f3a7534ab5a9a218812d5b6d3587d8b3de89e73310ca8ea74d35c63ee46"].into(), 898508876174623538u128),
(hex!["d84a9b4a2039ac793cb4108990e10e8341039a9c5caee9ed271cd84cc91d2e10"].into(), 82999821765415413069u128),
(hex!["a280b6e97389ed44d9ae9fcb36df39072ab60c7e71088087c4890b8e07f1d97b"].into(), 13104582315236011828u128),
(hex!["0436858543a367154f1a6e9c1f67c4a865a7c92e6adb31d21e7c4312a64d6219"].into(), 2201608876174623538u128),
(hex!["de24e0e98fd99ca8079f9f154293f967731303cf3b862d19d34b98c1db689f41"].into(), 2196169714471969993u128),
(hex!["6255ca0f443e06c0031045d9b6883964f3176526f7243941b48cf89a09adc057"].into(), 14616699999999998u128),
(hex!["f01ce72cc4db3db4eff729f4dab35db89117f40e9f53c7d5cb68d09f2bf28802"].into(), 10583410569668495529u128),
(hex!["3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315"].into(), 28409923837144670351u128),
(hex!["785b89d27366fcba6ff4dc6a6fa3dfc586d2f5edc15f9416e3a93229f0e7c45d"].into(), 2203940931652105261u128),
(hex!["985562d52d2ce181cdfe12598b40c15ea91adbf74a681ce82029d323f63af45d"].into(), 10071185931226347521u128),
(hex!["fa7728904cfced5998fd559251a9dfb008d2bd838917b9eb6c5332a9ed22b302"].into(), 13266286751478030059u128),
(hex!["80aac52e8482215ae5d022f71c50734b9f5e6d5048bb4d7a198fb77925f97a34"].into(), 11402028653479979903u128),
(hex!["0afa4924d17ab1f9d4aa4197f566ab29f5360a3e03949799f74638cf33d9b852"].into(), 12792398754994057800u128),
(hex!["42c3d5a95c5ba5b9daaa0f68631fa1d0cc744c0dc50476c392167d86d6368b0a"].into(), 12276140304411166019u128),
(hex!["1c65ddadd315f740e7cc162ed79f1d2d743af5c92403615cb078f0da9d78f95d"].into(), 898508876174623538u128),
(hex!["ea1c01ff56725c6fdd62efaa119b704a2f467fd21d20a3c2117668bfeba02e76"].into(), 15364926655816994525u128),
(hex!["ea24c5b5640658f8ad793b40d819dc22c4d55415c666c2e402f6c8412c9c3126"].into(), 13459266313430743241u128),
(hex!["0e05218ac7c6f6c809460d476bc23f660415089854ffe9ad2ddce02704de0049"].into(), 898508876174623538u128),
(hex!["ac0ed11176b0f1cd7539ea734c2a157aadb8b385e43f7731fa3c115174260332"].into(), 921318876174623538u128),
(hex!["f684d118dc9ddfc2f3f6365feae3c258c8ba2c8e5872373c9fa3803ef3d0cf5b"].into(), 21228508876174623538u128),
(hex!["d281d7b41a3e369eef42d15060819df4d9c7d3e43eb5c223244a9bb8c5a2ed44"].into(), 12907092936613202269u128),
(hex!["2224294c8b826c3d35b6105a91923dfcf6c50706a2d57527b971dbc1f4a8c90b"].into(), 529726628523870614u128),
(hex!["20655f7d14fb63c001601c177e513c4e2197253e38638cb034e0ecda9f93db79"].into(), 1005108876174623538u128),
(hex!["7000daf495c30583e255cbf926dcc278427a300c96ef807ddf3f05a38bb3bd6f"].into(), 12295813875568537231u128),
(hex!["fa18d3053a66f26a024bbf0b04571477688542fab309fc4fab6419e7744e023d"].into(), 727997752349247076u128),
(hex!["12ff06ed5c993253837f627ff4ddcee4658ebcea47bb7f13d299bc3b2d520440"].into(), 9660045161058603076u128),
(hex!["d263c987009ee0bc900162e9af9e2f2ed073f2d2af895e4bb8f4fb72840aa457"].into(), 12688435840744280612u128),
(hex!["dca9bba238f216683ea0c43bdce1709578d83e4b41875c76266e84024c34a72b"].into(), 898508876174623538u128),
(hex!["a25b474bb6a2b241ff7f574309240e0ca84aa29f5d04912842e5748af631a740"].into(), 13370440034824674362u128),
(hex!["007143a869c6e707fe03eae20704a81a97eb7beabedef62f8e3cbe5706b6e247"].into(), 14768512833373884464u128),
(hex!["5e1456904c40192cd3a18183df7dffea90d97739830a902cabb702ecdae4f649"].into(), 376017752349247076u128),
(hex!["6d6f646c70792f74727372790000000000000000000000000000000000000000"].into(), 490184997478957959982u128),
(hex!["9607407bc837b24624c7886129755843bd3a149f8bfec76bc8f828876cac3461"].into(), 10929472937167428328u128),
(hex!["20f8135fb600717f8e288e6b9a6dacbeb54677664dcde4998558975e606caf20"].into(), 786017752349247076u128),
(hex!["beadbe750127679102bb60e0493ad501394283b7a9a0001887f320ec8d83af5f"].into(), 13059337743467906765u128),
(hex!["84328018915f262b63a52d947506c9e75878f3bae7454aa197c7624393256609"].into(), 93100000000000000u128),
(hex!["b624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73"].into(), 20389023363985231125u128),
(hex!["1eef351e2c381586366f89bbdf5c690372fa05c7c5a47e6351315f0aa9507029"].into(), 13515506357309430378u128),
(hex!["4a2aa2bccfe5ae7a771fc2ce7732ad2da397ee51f0a45f18c167bb555fa70506"].into(), 2793000000000000000u128),
(hex!["909f0584f25fd044fc4336f966e14e925d77466e8629f4c6888d55cf594b6d76"].into(), 346508876174623538u128),
(hex!["08aae874b34057e02c3f6c28fffe8eaa0f665e9d7cc0d38f878c9ae862d47277"].into(), 499553257047741228u128),
(hex!["749089588c2a57b4cc4adc4541c441332d2fa11acf13f785e470d03cef61d75d"].into(), 13128362389531005022u128),
(hex!["de3d246b0109357114d1ee78ec4598fcff1cf19da4254ced289ac4e534b6084b"].into(), 506451628523870614u128),
(hex!["2a5bc425d9c6b8e29d5ccfe3282560fc8ab079262763aaf4d9269c7c6043f208"].into(), 12344029246075616723u128),
(hex!["347db8f39a1a1efa2ec9daeaaa04e3512238e9a6970fba65878f83366e927f27"].into(), 13250762917778422850u128),
(hex!["4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a"].into(), 31034809886518069653u128),
(hex!["3cae73748956c91dc21f54e2653e0fb76b9c8ffe38c2c3e2ad6483e88c968a02"].into(), 12376423999653776239u128),
(hex!["5688a4d3171b935a3b038729ccb0cca068a4243cd3a6b7e102e7e14ac49d6427"].into(), 13207638229965515023u128),
(hex!["8c7a053eb4ce5a680150650e88533ade4ce08fee5340888ae655df3c37910d04"].into(), 388508876174623538u128),
(hex!["3a2e10fef720299388eb789aaab0e0bb1b7c10464aa7c442c6a584cf11c01845"].into(), 345017752349247076u128),
(hex!["8e20ae229b297cdb71aaa122c0182c636d9f97f9d38e7dffb24045b00374a060"].into(), 316542729061225383u128),
(hex!["4850e7dd6e309b3758b16a43e96cc16455245ab31dbf2920397e58106ee7a112"].into(), 898508876174623538u128),
(hex!["c28559a4c9a9ffc428441295a309e944e3e9b87a832cf3cebd3def8c57b4ec1a"].into(), 13244103182710791045u128),
(hex!["6a7a10e74c6fbcd0d9ea2ec1cfff2ce89cc5501315117757642f50c36dfa5c01"].into(), 24416873171189988097u128),
(hex!["5a792ca101c15da5b237477a3c1e30f4873a21c8046bfc44117d4f3dedceb374"].into(), 24125718413269577510u128),
(hex!["3068d31973cc3b18745cf5d6e75e2ec0a940d2aec79af2b313a530f6c558d77e"].into(), 1990135504698494152u128),
(hex!["76ef9c99dfb1ee5604b7d7314f61908957db55fa294a0794c6bf793691c49954"].into(), 13101580949598094188u128),
(hex!["c8ffc2b4e770b08b9a4ae10168c48dd821581a2df3cf5f3a371dcc1326bbe94c"].into(), 9310000000000000000u128),
(hex!["f235af8680ec5cbfbac0fc818da07c727e449454b04e2d96671e2d64ececb30a"].into(), 4167571995070680428u128),
(hex!["c8f4d838e6e262a7c905eb268f36a3e5b7240130aa895384822cdd968586cb01"].into(), 14912878206297721983u128),
(hex!["160d647d9a380687f63cbe4ea23279692b997a3dad19227b1bb85f08965d7859"].into(), 15280448272566261071u128),
(hex!["e872e23fc05919751708f5bf887a68ef9c175cf7f1728dca6220e2a2370e163f"].into(), 12599268699455778903u128),
(hex!["685c600574546bad67b0ae6768f07b7fee1f1aec6473c941606f9829cfa93b6c"].into(), 2211687751137074462u128),
(hex!["ba821401516b2429cd25e506c1af11b23808d039d1319d6b2eb7a9222d922179"].into(), 18372096744466282652u128),
(hex!["2e1158566a7c2a57c68e542b64ac5987cb69aaaf846735addafc6f90cb5d8e3b"].into(), 13985217814424299670u128),
(hex!["da35bf90643e1f5431031728c9f9c3eebea63c6bcfce1c8b468591cf6ed35210"].into(), 11680033590958446157u128),
(hex!["a8c76be6e69cb05748f5accbced41809a1bdf30400402e63753fc85adfbea418"].into(), 8060691100000000000u128),
(hex!["f442a26de0c465651bbe51ff90d0b31f63af206d84cf2bcab5a1ee7ab537ec4b"].into(), 2793000000000000u128),
(hex!["909ab2271d3fc8df9e8556232a29eea7cf1cfdf8c89603a602779daa6484f011"].into(), 15989848178884321645u128),
(hex!["f0515fcc6570d35645675f99aa04295fd1e12d88ab9abcac61f58092a5c3e316"].into(), 1622526628523870614u128),
(hex!["a02d33ee7c4d38649d4bd88f330e75740ab4e4aa55e0f18110d8e6c72f71615a"].into(), 430027752349247076u128),
(hex!["ee5005bc008184ed8d8d71774a167e4773fdbad6c8bf8e4d46a211b6b52e806f"].into(), 405127480873117690u128),
(hex!["562f42de365612dd23609a21117e3b807242f50af7a51877fc907656e723b41c"].into(), 23545504698493896u128),
(hex!["3cd73e0f752cf301d3c2bca3d72d2502003d7143bacac8944e972bbe921a1b11"].into(), 539608876174623538u128),
(hex!["223ab980529a7f877a79fb4bd2280c60e8ed0978b21007de70e1682f5d0fe846"].into(), 6394212201126639927u128),
(hex!["74302b4989cfd149c4a99b0bc9a4ff82cf63d3f4291fa2597963fe4db56e401a"].into(), 898508876174623538u128),
(hex!["9696d44dce264f5c1e2e5cdbc3c0609a627ac712dbd7ce6a24a415b7ea652773"].into(), 13064032622783391575u128),
(hex!["b852757ba5ce6a3fddcdd13f7a548d16532dbf1b16693d951c348860c421ab16"].into(), 13090753661669103954u128),
(hex!["223983e8b68f45666ec4faa573b2aa9b664b20bc25517c179cb354eda6704b04"].into(), 15187474897366947923u128),
(hex!["94cc169c4cd81710fe19a6ce10ef35b1fe1d53aa04dc24e0a55d3a6dda728909"].into(), 9490152116008452257u128),
(hex!["daff035dfadff80ada04930d67be6dc9837d65d39a124a64973b1f52e6203876"].into(), 16388220707138965567u128),
(hex!["a04214ec6484663f990a1dd3f4a02f8f174723a54a369478c076573aa43d1e30"].into(), 11024583916484684117u128),
(hex!["425533de216bf2e3a9d1f3358dbf23a8d56d3d2fdbfe5deb2d989716fd26734f"].into(), 14124681775633429910u128),
(hex!["fc1310a824a7c8744b6f6308198e4a9bf9baea4a673bafedd49f35824eeb3947"].into(), 9795048450282732123u128),
(hex!["385a826ba8113391c26d03c8bf3d911ce8f20a523ba19da996926e401226e921"].into(), 1048508876174623538u128),
(hex!["e82bad686d3318e72e36bfe9776e197ae04b60fc140b7a221fbf1b730e9b0162"].into(), 898508876174623538u128),
(hex!["8a0bb3642b563b842649ca9870ddb8efb67d0bc3b128df0d59e7bd5f1c19db22"].into(), 297635726269865672u128),
(hex!["8e18636616b2f67f20469a71d7f6508fd2e2f045742e6ba5d80b2a0782b2ae50"].into(), 3072300000000000000u128),
(hex!["08c04b4b3540dff6e2e489a888f336f1f09c7a648b19194836584ecafe74f632"].into(), 962544380873117722u128),
(hex!["30acd0fd37df7b6b9dca64287fe3bf0ad3563ad2868567170b79d48a2be1905d"].into(), 10233781528150093525u128),
(hex!["46c78fcacffd80abc9cca4917ef8369a37e21a1691ca11e7a3b53f80be745313"].into(), 7147764927833644204u128),
(hex!["e8c8d51024385be1fa0e5003a6725626d96f7b02fdc0a289bdef2095a2170039"].into(), 461545504698494152u128),
(hex!["a0746c5aee539430c94f18adc4a723d3216e348a5e770bd65c70c8e2655e4f73"].into(), 12197794185639438614u128),
(hex!["da59bcd9273cea92f120a9a9a5a5148a551decb191588dc949331d6badf29a19"].into(), 9490654217464110064u128),
(hex!["3482a145ab988dfd56683d2ca621a900656188eef040c92e8dbc45288fa51409"].into(), 12923631455237538822u128),
(hex!["96b26d15a812e30bc0dae710eb6ab9ce0c82a450e8eeb94c19c9ee0483ed907c"].into(), 3389562133222364766u128),
(hex!["8610f2ee704cb43240f62a9d7aafa91e31168976c4f91ce7f87db37f42db2953"].into(), 1702544380873117690u128),
(hex!["96cd8b97a9256ee5ddac3d5d4e128544041d041957815f415d33e51212e5794d"].into(), 1396585066737448782u128),
(hex!["b0d88e3974dd9b8e2b5919bb3eaca3241bc3ceca163df036ea539528121cde36"].into(), 12804373197912707987u128),
(hex!["8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13"].into(), 3909659906201812974u128),
(hex!["40ad428cb7a2530fc0c38ab879e7f5d54f25cd757cfcb21f46cb023d413eb916"].into(), 236636628523870614u128),
(hex!["4cec57aebb419ab80b7d8b699024eaaa9016bb2b90821f18303abebe87b4983e"].into(), 15265761957965221177u128),
(hex!["2c2d1ac621c332cc1b8e5c1bfc5b1c00c61e9767e8fcf96b1852bb39940fa209"].into(), 97016443351365356u128),
(hex!["6ea653659d6a5e6f3fa95b2ffa4acad62233f91d2dc323632a3fa5c9fc7b533a"].into(), 12393794455887420639u128),
(hex!["f614e6494fbb66397fe4c799971be187183d85996ac08c2ba37d666635fd0f7d"].into(), 14633565813546398869u128),
(hex!["24fae36f401bf052057d4a011dc8b9ec40fcd9ef12a2823c9c8a2acbd40b906d"].into(), 2386381009396988304u128),
(hex!["46b7889030d5f4653002b4b3cc50b031548c237e1b26639e26b66af113258c65"].into(), 12142098465731542975u128),
(hex!["eefeff9e4cfa6e9d55128803895ff50e917f5601fda7f38f7aa71c48ee8a182c"].into(), 11439023815236597370u128),
(hex!["4ec775d54f1e4d03524571e664108c5c7d8e256ac0b7a9566fe91a13fb489c1d"].into(), 9489578019617777151u128),
(hex!["2c1a2fcaaddeb083764fdd5364e961506807f295b7de086bfebcf85323ec3e6f"].into(), 13079350324389304724u128),
(hex!["345ff8df58e39dbae032bfed1a3f5d41078376d57adb6cabd8b319fb817b892e"].into(), 14761261709701909726u128),
(hex!["da6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702"].into(), 3496638131388321921u128),
(hex!["1a32c203646616b88f262569c5e52c8c45468c0b5ade90996af844a9971ddf31"].into(), 15811907815599745021u128),
(hex!["e261f574706b696fa627ca60abcd27d71e509d48955c7bd39cfe26a4dbd1a305"].into(), 10913969526740320780u128),
(hex!["3484fb56e2660d6d91ef93f432777778dcff9df2f9cccf0672504dd71a705358"].into(), 898508876174623538u128),
(hex!["fef9b143712fefdf6825c9d85a151c0ff526f978becf980da6f5b10f8dac6c47"].into(), 32731550000000000000u128),
(hex!["70ee2d1a6ae80d1fee15f47c646cbcbc9fa8dcf7365bfb5f7135daf9e4933312"].into(), 11375887786446002232u128),
(hex!["94715daf5090147de11f48aee9661c46f98b1215e3a4e54867344635c7e8cf68"].into(), 1000000000000000u128),
(hex!["d2da442bc774b21bf0a2485bc6099e468765255363136b6517adda3d6ceb8e39"].into(), 11360623175679553528u128),
(hex!["4e5dbd1516d69f4132e5ea96b7cf92799075c14a32f7995fb9d6f6ebed537d64"].into(), 898508876174623538u128),
(hex!["dc3c2d888a41e766647e56ec7e9b71cc8db6553407be8646e35d4c0f803b9946"].into(), 118117752349247076u128),
(hex!["b2c232a2c68b1b9094568fde28bca4b3845031b1afc386b4f6881c7c0162b00d"].into(), 931000000000000u128),
(hex!["422f1935ec60c7e30ea45aa8b9f94adf9fc416887bdfb797860eae4d6ff2552c"].into(), 13280690314171744710u128),
(hex!["728d8f346c9be14f387d1ce92598cee4becdb41d944ed0d77b9ee3d652e7ec62"].into(), 6258403189666179783u128),
(hex!["3e4c0237d057d92401fc9188893254f503d28af6b35535749f46420827de754d"].into(), 11870458022253848637u128),
(hex!["4c19778e758d3f4763972e2b5119aee898a0c86b3f7dc2f4536f495b44f7a151"].into(), 93100000000000000u128),
(hex!["484b5356ad84cc7ce4cbaf5e53c79c5d77195ad560810fa6d3fafc2145a04f69"].into(), 7634199999999999046u128),
(hex!["80eca749f37cb93f00f5309552c26b2c70960452e11faa63d081090542aeac42"].into(), 15018816123219290155u128),
(hex!["585bde23981ce0400b174cf234c495114421bb01554344c63dc724357a6dac24"].into(), 35007104380873117690u128),
(hex!["c02c41834889bf3fec8d38e25d976dcfde3e2e44ca1275c341b0ff7617a2f14c"].into(), 2976235504698494152u128),
(hex!["328135c5defeeb32f3b3f90196108f56837bb1cb999033bf380464c20ede0d4e"].into(), 1670483976174623538u128),
(hex!["1c96c3a56374256afa95ffa1c15cb9730d33d91fa4a8fa10b4053b166e714e68"].into(), 9310000000000000u128),
(hex!["844ee060a2a94beb0c3a744d00093d1929a68f3b5acc2265e99375855bd60c00"].into(), 6979217752349247076u128),
(hex!["6083d585d458daed6a19c3258e311132ab786eb5144bb7b7dace2218522d274b"].into(), 931000000000000u128),
(hex!["68c3d18fb07714cab1b1f8b5368e9c1e1f2b5f0e739c0602eeffc1669936ed02"].into(), 14676476815062037968u128),
(hex!["5cb839c6a5e065e83b5dbf20d7082086a376586fe37fa7658cba71eda689c118"].into(), 11658791447719213988u128),
(
hex!["fe3cb0119ffaf59434233d0b0d85cd2d16fde46f713dcab39047eb222f3ae666"].into(),
898508876174623538u128,
),
(
hex!["88a74a42ca9a17acc210ae56ff8ace565e246025a2743da967dfde9d6c76277c"].into(),
20734039366660590012u128,
),
(
hex!["94addf7d81d155c9f4d8d0eab3ceb019939db5f3b0081ae3e888a6ed3c845307"].into(),
1000000000000000u128,
),
(
hex!["6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666"].into(),
21042733373739997438u128,
),
(
hex!["7409c6caca65472f77938a143a7ee73a85dd9c1acf60fcc13aade8dc1be38a0a"].into(),
8609732485052672834u128,
),
(
hex!["fa402c6b1c1db2ce9e3e1ba4e559581faa821d20254d8d16e4e18057a3b90672"].into(),
9796698744519740142u128,
),
(
hex!["ac1932d76a47c5819724999aa3626aa85e71bf60c8fccdeac92cf53beab7a85f"].into(),
346508876174623538u128,
),
(
hex!["a6bbe75122ce02a5c0d9ebeda902fb0ae21138a7487e18adef1c3e7d106b3715"].into(),
898508876174623538u128,
),
(
hex!["1225d9453ad3fe1197dfc2410760cea284529e226fef262fb01574ae2a6c5900"].into(),
25679625557282857591u128,
),
(
hex!["ac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c"].into(),
4495926542421046636u128,
),
(
hex!["6cabf6e32fb8909acae30605bb3e5997d201103d298734851d58022423977655"].into(),
301045085375060900u128,
),
(
hex!["fe0f596b6bf22b5fbad52ebce3429bb6bdeb00996fc8e51aae2e437450f6b578"].into(),
2686488249070628254u128,
),
(
hex!["84e01e431c701383fb0fc204338aca8cff0a2e88bb9397ba7b5ec8b236850e17"].into(),
9488095602980648270u128,
),
(
hex!["507110e1a96c4b781207ad9c790c558f752ca99614f281b6b24a2e467e04e25e"].into(),
446342905026072u128,
),
(
hex!["005dc72f4d842896adf3505695eef833aad9cdee22448751f0500c30cfdda247"].into(),
19922026892862601u128,
),
(
hex!["a64f42e128afa40b848faf5df5e260e58390c6ca2bbcd5e866b5460a4c2dc60c"].into(),
10792504141381628956u128,
),
(
hex!["4a32ed6e36b6dec1ce328c650f5276a6e5ac4e594b7ba71a1cb87a2770f53b33"].into(),
726673904645949199u128,
),
(
hex!["58967ccdc9d4ddab5c32b6605947becba27cca5799a93c9d4d03a0fb3ebc7316"].into(),
453608876174623538u128,
),
(
hex!["323158b7e1cb9b3104fce73ed72095764fe785a1d14b9a8f73e54973f04b9d74"].into(),
531467153727934259u128,
),
(
hex!["3e130ccc1fac5e9d5c2c280341ce8b8dbcafc17ceb75d3722f83404ed2215856"].into(),
16753318413269579418u128,
),
(
hex!["a003dfd6d28a3fabf2b46df20383635c72c5a41d8ee79a5fb75e9d1298b3761f"].into(),
1172036132833830838u128,
),
(
hex!["acbda1ba4cfd81cd430b53a834c0d92085e8efc6948a03c10c2f6a66ba19443a"].into(),
36751232674856508996u128,
),
(
hex!["4cecf92b37e6954f086002cf7b6a61ac7d9ba40c83ef963005e3cacfb5c1e13f"].into(),
14038937501875054342u128,
),
(
hex!["f09c9f7ecdd1be0d07a2d0759efdff5152f23ec742f86e15a9ac03c0995f2365"].into(),
898508876174623538u128,
),
(
hex!["8256b4a52f0277042cacc427cf00b8d668d0e7fe7824f53acf927da985f32410"].into(),
898508876174623538u128,
),
(
hex!["bea3d9a526bfdbd98870bb615dc91d5d9295a6e021e5e9b9193801697a05586e"].into(),
225166041881037450131u128,
),
(
hex!["3a926d7cf3546e58e48f9faf392b02e6d1d43011676378914988eeaea2cbff3a"].into(),
4035504698494152u128,
),
(
hex!["e4dcfdec0dda94b9cb45bf6ff12439392f01fb9d738f806fb115b1d21c99135d"].into(),
3977726628523870614u128,
),
(
hex!["cc88301ef74e085f731220d101dcd14d2b04bc1e59a6c45009c156a9990eab46"].into(),
153582139771143223684u128,
),
(
hex!["46f41aed549dcfa8c094c19787dfbe974fef680eacd209ef88640c82bcb77811"].into(),
13819008291976111251u128,
),
(
hex!["58ed8cee04bcfb70719644a6b9478b8eebfe7ffc8964590e12e1bf36ea245375"].into(),
11624450784910043012u128,
),
(
hex!["9a3e9942c0cb9fe1f1acc97c3bf458e9b7955f44604183e569d5120de3400e10"].into(),
14452183576445203470u128,
),
(
hex!["9aceaa2fa9e3226bbe106cd0150f9807b089281b16942bff471caa1359aa8a22"].into(),
1360508232557032475u128,
),
(
hex!["661fd59a3748d65d66d9612f0c8f5871029e8e74deb3c0e1fbdbcf3c04e84a5e"].into(),
246508876174623538u128,
),
(
hex!["d02a399ba8d6efe950c0c6557606b8b13147b353c11f4495a2cba2a396e7be2f"].into(),
29163375134216277028u128,
),
(
hex!["20fed126411d5d1a1ab3915bffac49297b0eae9dcf4288589c0cad49d925637b"].into(),
5963508876174623538u128,
),
(
hex!["eeaaf5db1b1eb55cc8c1b26c5092868ada9af63c2961bba4d4b5d63e99371c00"].into(),
11725156115646367945u128,
),
(
hex!["ac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50"].into(),
7523053899371678858u128,
),
(
hex!["144a1fa97fdba679efd2a36696a0d40f585b649143bb7da5cbd7458ea4a0f674"].into(),
28761584046403187249u128,
),
(
hex!["a231498b31f698619d80746aa2049ec187c4a103a3c5a8940e14d1b03abe1239"].into(),
1093016078816558319u128,
),
(
hex!["d05b788865ffffdfbb7dfecd937188628a275926ab47742f84b5cda86e5d825d"].into(),
4095526634890427372u128,
),
(
hex!["7673ef8a48eaf9364831735201743d20587e27ff5ff2df42808e4625be6f656b"].into(),
899439876174623538u128,
),
(
hex!["6a92d2e77c6b56428db2129d33c3ba1e71c8a52315a65f03f30dbaf31224153d"].into(),
708444482928862970u128,
),
(
hex!["d8193ef891724c66a6cc58273eadcfb133f9bbc7d777e6456721a70e90ded71f"].into(),
195510000000000000u128,
),
(
hex!["c256b6d62a54c94220ceb1b55f4afae84e59c913b8163d57791463d7ac67555c"].into(),
13111614265582327685u128,
),
(
hex!["723aabc24abe3a04fb79c4a51e5b023e99f5c1afcfeac7d434276496a65ede3e"].into(),
898508876174623538u128,
),
(
hex!["4078ddb1ba1388f768fe6aa40ba9124a72692ecbcc83dc088fa86c735e4dc128"].into(),
1045536628523870614u128,
),
(
hex!["d8a1924995f48a61c0bb79f3fdaeff18573cf1d2164454938c773f6066d81413"].into(),
3296223653083995083u128,
),
(
hex!["b85a4db79fa17d9853f2c4031aa60c8ee09a38bbce5e484ddb4c6b32bfefd401"].into(),
14390589865809310762u128,
),
(
hex!["224f1f3a7534ab5a9a218812d5b6d3587d8b3de89e73310ca8ea74d35c63ee46"].into(),
898508876174623538u128,
),
(
hex!["d84a9b4a2039ac793cb4108990e10e8341039a9c5caee9ed271cd84cc91d2e10"].into(),
136401570550894040265u128,
),
(
hex!["a280b6e97389ed44d9ae9fcb36df39072ab60c7e71088087c4890b8e07f1d97b"].into(),
13104582315236011828u128,
),
(
hex!["0436858543a367154f1a6e9c1f67c4a865a7c92e6adb31d21e7c4312a64d6219"].into(),
2201608876174623538u128,
),
(
hex!["de24e0e98fd99ca8079f9f154293f967731303cf3b862d19d34b98c1db689f41"].into(),
2196169714471969993u128,
),
(
hex!["6255ca0f443e06c0031045d9b6883964f3176526f7243941b48cf89a09adc057"].into(),
14616699999999998u128,
),
(
hex!["f01ce72cc4db3db4eff729f4dab35db89117f40e9f53c7d5cb68d09f2bf28802"].into(),
10583410569668495529u128,
),
(
hex!["3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315"].into(),
56407584060005963171u128,
),
(
hex!["785b89d27366fcba6ff4dc6a6fa3dfc586d2f5edc15f9416e3a93229f0e7c45d"].into(),
2203940931652105261u128,
),
(
hex!["985562d52d2ce181cdfe12598b40c15ea91adbf74a681ce82029d323f63af45d"].into(),
12374996121419906402u128,
),
(
hex!["fa7728904cfced5998fd559251a9dfb008d2bd838917b9eb6c5332a9ed22b302"].into(),
13266286751478030059u128,
),
(
hex!["80aac52e8482215ae5d022f71c50734b9f5e6d5048bb4d7a198fb77925f97a34"].into(),
21321617482381290055u128,
),
(
hex!["0afa4924d17ab1f9d4aa4197f566ab29f5360a3e03949799f74638cf33d9b852"].into(),
10790907513786741192u128,
),
(
hex!["42c3d5a95c5ba5b9daaa0f68631fa1d0cc744c0dc50476c392167d86d6368b0a"].into(),
12276140304411166019u128,
),
(
hex!["1c65ddadd315f740e7cc162ed79f1d2d743af5c92403615cb078f0da9d78f95d"].into(),
898508876174623538u128,
),
(
hex!["ea1c01ff56725c6fdd62efaa119b704a2f467fd21d20a3c2117668bfeba02e76"].into(),
24674926655816994525u128,
),
(
hex!["ea24c5b5640658f8ad793b40d819dc22c4d55415c666c2e402f6c8412c9c3126"].into(),
13459266313430743241u128,
),
(
hex!["0e05218ac7c6f6c809460d476bc23f660415089854ffe9ad2ddce02704de0049"].into(),
898508876174623538u128,
),
(
hex!["ac0ed11176b0f1cd7539ea734c2a157aadb8b385e43f7731fa3c115174260332"].into(),
921318876174623538u128,
),
(
hex!["f684d118dc9ddfc2f3f6365feae3c258c8ba2c8e5872373c9fa3803ef3d0cf5b"].into(),
21228508876174623538u128,
),
(
hex!["d281d7b41a3e369eef42d15060819df4d9c7d3e43eb5c223244a9bb8c5a2ed44"].into(),
12907092936613202269u128,
),
(
hex!["2224294c8b826c3d35b6105a91923dfcf6c50706a2d57527b971dbc1f4a8c90b"].into(),
529726628523870614u128,
),
(
hex!["3a77a32adecbed35c23e07ed397d22a135542e0d8f265b874f9985792e7bc600"].into(),
86560477751508148u128,
),
(
hex!["20655f7d14fb63c001601c177e513c4e2197253e38638cb034e0ecda9f93db79"].into(),
1005108876174623538u128,
),
(
hex!["7000daf495c30583e255cbf926dcc278427a300c96ef807ddf3f05a38bb3bd6f"].into(),
114705813875568537231u128,
),
(
hex!["fa18d3053a66f26a024bbf0b04571477688542fab309fc4fab6419e7744e023d"].into(),
727997752349247076u128,
),
(
hex!["12ff06ed5c993253837f627ff4ddcee4658ebcea47bb7f13d299bc3b2d520440"].into(),
9660045161058603076u128,
),
(
hex!["d263c987009ee0bc900162e9af9e2f2ed073f2d2af895e4bb8f4fb72840aa457"].into(),
12688435840744280612u128,
),
(
hex!["dca9bba238f216683ea0c43bdce1709578d83e4b41875c76266e84024c34a72b"].into(),
898508876174623538u128,
),
(
hex!["a25b474bb6a2b241ff7f574309240e0ca84aa29f5d04912842e5748af631a740"].into(),
13370440034824674362u128,
),
(
hex!["007143a869c6e707fe03eae20704a81a97eb7beabedef62f8e3cbe5706b6e247"].into(),
14768512833373884464u128,
),
(
hex!["5e1456904c40192cd3a18183df7dffea90d97739830a902cabb702ecdae4f649"].into(),
376017752349247076u128,
),
(
hex!["6d6f646c70792f74727372790000000000000000000000000000000000000000"].into(),
853506701376908793934u128,
),
(
hex!["9607407bc837b24624c7886129755843bd3a149f8bfec76bc8f828876cac3461"].into(),
10929472937167428328u128,
),
(
hex!["20f8135fb600717f8e288e6b9a6dacbeb54677664dcde4998558975e606caf20"].into(),
786017752349247076u128,
),
(
hex!["beadbe750127679102bb60e0493ad501394283b7a9a0001887f320ec8d83af5f"].into(),
13059337743467906765u128,
),
(
hex!["84328018915f262b63a52d947506c9e75878f3bae7454aa197c7624393256609"].into(),
93100000000000000u128,
),
(
hex!["b624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73"].into(),
30936250630249413310u128,
),
(
hex!["1eef351e2c381586366f89bbdf5c690372fa05c7c5a47e6351315f0aa9507029"].into(),
19477108324061651032u128,
),
(
hex!["4a2aa2bccfe5ae7a771fc2ce7732ad2da397ee51f0a45f18c167bb555fa70506"].into(),
1936519460520939399u128,
),
(
hex!["909f0584f25fd044fc4336f966e14e925d77466e8629f4c6888d55cf594b6d76"].into(),
346508876174623538u128,
),
(
hex!["08aae874b34057e02c3f6c28fffe8eaa0f665e9d7cc0d38f878c9ae862d47277"].into(),
499553257047741228u128,
),
(
hex!["749089588c2a57b4cc4adc4541c441332d2fa11acf13f785e470d03cef61d75d"].into(),
15232317322641616299u128,
),
(
hex!["de3d246b0109357114d1ee78ec4598fcff1cf19da4254ced289ac4e534b6084b"].into(),
506451628523870614u128,
),
(
hex!["2a5bc425d9c6b8e29d5ccfe3282560fc8ab079262763aaf4d9269c7c6043f208"].into(),
19879072140569666945u128,
),
(
hex!["347db8f39a1a1efa2ec9daeaaa04e3512238e9a6970fba65878f83366e927f27"].into(),
13250762917778422850u128,
),
(
hex!["4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a"].into(),
41638135068286046818u128,
),
(
hex!["3cae73748956c91dc21f54e2653e0fb76b9c8ffe38c2c3e2ad6483e88c968a02"].into(),
4059791817567310973u128,
),
(
hex!["5688a4d3171b935a3b038729ccb0cca068a4243cd3a6b7e102e7e14ac49d6427"].into(),
14893617583873139066u128,
),
(
hex!["8c7a053eb4ce5a680150650e88533ade4ce08fee5340888ae655df3c37910d04"].into(),
3076517758715803834u128,
),
(
hex!["3a2e10fef720299388eb789aaab0e0bb1b7c10464aa7c442c6a584cf11c01845"].into(),
345017752349247076u128,
),
(
hex!["8e20ae229b297cdb71aaa122c0182c636d9f97f9d38e7dffb24045b00374a060"].into(),
343021429061225383u128,
),
(
hex!["4850e7dd6e309b3758b16a43e96cc16455245ab31dbf2920397e58106ee7a112"].into(),
898508876174623538u128,
),
(
hex!["c28559a4c9a9ffc428441295a309e944e3e9b87a832cf3cebd3def8c57b4ec1a"].into(),
13244103182710791045u128,
),
(
hex!["6a7a10e74c6fbcd0d9ea2ec1cfff2ce89cc5501315117757642f50c36dfa5c01"].into(),
24416873171189988097u128,
),
(
hex!["5a792ca101c15da5b237477a3c1e30f4873a21c8046bfc44117d4f3dedceb374"].into(),
24023038343078900634u128,
),
(
hex!["3068d31973cc3b18745cf5d6e75e2ec0a940d2aec79af2b313a530f6c558d77e"].into(),
2095662152322035040u128,
),
(
hex!["76ef9c99dfb1ee5604b7d7314f61908957db55fa294a0794c6bf793691c49954"].into(),
17910287937252530940u128,
),
(
hex!["c8ffc2b4e770b08b9a4ae10168c48dd821581a2df3cf5f3a371dcc1326bbe94c"].into(),
25677594611394060807u128,
),
(
hex!["f235af8680ec5cbfbac0fc818da07c727e449454b04e2d96671e2d64ececb30a"].into(),
4260671995070680428u128,
),
(
hex!["c8f4d838e6e262a7c905eb268f36a3e5b7240130aa895384822cdd968586cb01"].into(),
14912878206297721983u128,
),
(
hex!["160d647d9a380687f63cbe4ea23279692b997a3dad19227b1bb85f08965d7859"].into(),
15825904340197502330u128,
),
(
hex!["e872e23fc05919751708f5bf887a68ef9c175cf7f1728dca6220e2a2370e163f"].into(),
25193857844634143446u128,
),
(
hex!["685c600574546bad67b0ae6768f07b7fee1f1aec6473c941606f9829cfa93b6c"].into(),
2211687751137074462u128,
),
(
hex!["ba821401516b2429cd25e506c1af11b23808d039d1319d6b2eb7a9222d922179"].into(),
28918786313447682171u128,
),
(
hex!["2e1158566a7c2a57c68e542b64ac5987cb69aaaf846735addafc6f90cb5d8e3b"].into(),
13985217814424299670u128,
),
(
hex!["da35bf90643e1f5431031728c9f9c3eebea63c6bcfce1c8b468591cf6ed35210"].into(),
11680033590958446157u128,
),
(
hex!["d0b6e4237e5d05345ce398eed219ae1be33b4180afb35c54d1d02a5da4feeb68"].into(),
30482480277587823790u128,
),
(
hex!["a8c76be6e69cb05748f5accbced41809a1bdf30400402e63753fc85adfbea418"].into(),
8060691100000000000u128,
),
(
hex!["f442a26de0c465651bbe51ff90d0b31f63af206d84cf2bcab5a1ee7ab537ec4b"].into(),
2793000000000000u128,
),
(
hex!["909ab2271d3fc8df9e8556232a29eea7cf1cfdf8c89603a602779daa6484f011"].into(),
24759199566796371707u128,
),
(
hex!["f0515fcc6570d35645675f99aa04295fd1e12d88ab9abcac61f58092a5c3e316"].into(),
1622526628523870614u128,
),
(
hex!["8af45cf6dd06aeb958c3b41fe2b37a2d523179efffe7ce287fbe0b80471e363b"].into(),
6949838187631199u128,
),
(
hex!["a02d33ee7c4d38649d4bd88f330e75740ab4e4aa55e0f18110d8e6c72f71615a"].into(),
430027752349247076u128,
),
(
hex!["ee5005bc008184ed8d8d71774a167e4773fdbad6c8bf8e4d46a211b6b52e806f"].into(),
405127480873117690u128,
),
(
hex!["562f42de365612dd23609a21117e3b807242f50af7a51877fc907656e723b41c"].into(),
23545504698493896u128,
),
(
hex!["bc5660de2352353da342e9c853ff20f820929aff755a0802841d32f36cf06672"].into(),
14997410948120188860u128,
),
(
hex!["3cd73e0f752cf301d3c2bca3d72d2502003d7143bacac8944e972bbe921a1b11"].into(),
1193117758715803834u128,
),
(
hex!["223ab980529a7f877a79fb4bd2280c60e8ed0978b21007de70e1682f5d0fe846"].into(),
6566608321352507005u128,
),
(
hex!["74302b4989cfd149c4a99b0bc9a4ff82cf63d3f4291fa2597963fe4db56e401a"].into(),
898508876174623538u128,
),
(
hex!["9696d44dce264f5c1e2e5cdbc3c0609a627ac712dbd7ce6a24a415b7ea652773"].into(),
20698814168008932416u128,
),
(
hex!["b852757ba5ce6a3fddcdd13f7a548d16532dbf1b16693d951c348860c421ab16"].into(),
11351527332712054762u128,
),
(
hex!["223983e8b68f45666ec4faa573b2aa9b664b20bc25517c179cb354eda6704b04"].into(),
14905713185341512010u128,
),
(
hex!["94cc169c4cd81710fe19a6ce10ef35b1fe1d53aa04dc24e0a55d3a6dda728909"].into(),
9490152116008452257u128,
),
(
hex!["9811dbf8f334e5bd354374b5224be3db6d2d0019d4abd84e57701093ae2fcd38"].into(),
508205226151823215u128,
),
(
hex!["daff035dfadff80ada04930d67be6dc9837d65d39a124a64973b1f52e6203876"].into(),
14139373499800648011u128,
),
(
hex!["a04214ec6484663f990a1dd3f4a02f8f174723a54a369478c076573aa43d1e30"].into(),
16582086343620630086u128,
),
(
hex!["3884cb632764ef37c200430b9247935df3370eb1f68e26d2335e7a08cfee6331"].into(),
15809344826831310198u128,
),
(
hex!["425533de216bf2e3a9d1f3358dbf23a8d56d3d2fdbfe5deb2d989716fd26734f"].into(),
14123180658174610206u128,
),
(
hex!["fc1310a824a7c8744b6f6308198e4a9bf9baea4a673bafedd49f35824eeb3947"].into(),
9795048450282732123u128,
),
(
hex!["385a826ba8113391c26d03c8bf3d911ce8f20a523ba19da996926e401226e921"].into(),
1048508876174623538u128,
),
(
hex!["e82bad686d3318e72e36bfe9776e197ae04b60fc140b7a221fbf1b730e9b0162"].into(),
898508876174623538u128,
),
(
hex!["8a0bb3642b563b842649ca9870ddb8efb67d0bc3b128df0d59e7bd5f1c19db22"].into(),
297635726269865672u128,
),
(
hex!["8e18636616b2f67f20469a71d7f6508fd2e2f045742e6ba5d80b2a0782b2ae50"].into(),
3072300000000000000u128,
),
(
hex!["08c04b4b3540dff6e2e489a888f336f1f09c7a648b19194836584ecafe74f632"].into(),
962544380873117722u128,
),
(
hex!["30acd0fd37df7b6b9dca64287fe3bf0ad3563ad2868567170b79d48a2be1905d"].into(),
10233781528150093525u128,
),
(
hex!["10b2b93e271f30d21a3c0c8937e5190750667fea2ae7fb56a0f179a86c383713"].into(),
21613466323512262u128,
),
(
hex!["46c78fcacffd80abc9cca4917ef8369a37e21a1691ca11e7a3b53f80be745313"].into(),
7147764927833644204u128,
),
(
hex!["d25b9ebe75a5d72c366c26588416509881a273ac9411e5fe6052c25ab7ed5311"].into(),
25066498882541180296u128,
),
(
hex!["e8c8d51024385be1fa0e5003a6725626d96f7b02fdc0a289bdef2095a2170039"].into(),
461545504698494152u128,
),
(
hex!["a0746c5aee539430c94f18adc4a723d3216e348a5e770bd65c70c8e2655e4f73"].into(),
19193345540608109431u128,
),
(
hex!["da59bcd9273cea92f120a9a9a5a5148a551decb191588dc949331d6badf29a19"].into(),
9490654217464110064u128,
),
(
hex!["3482a145ab988dfd56683d2ca621a900656188eef040c92e8dbc45288fa51409"].into(),
12923631455237538822u128,
),
(
hex!["96b26d15a812e30bc0dae710eb6ab9ce0c82a450e8eeb94c19c9ee0483ed907c"].into(),
3389562133222364766u128,
),
(
hex!["8a5807668ec5a9f0cad02fa02a7b8b5ac7a754f94f00da5048de53e883c54d14"].into(),
20555316237553836240u128,
),
(
hex!["8610f2ee704cb43240f62a9d7aafa91e31168976c4f91ce7f87db37f42db2953"].into(),
2702544380873117690u128,
),
(
hex!["96cd8b97a9256ee5ddac3d5d4e128544041d041957815f415d33e51212e5794d"].into(),
2790800114219541994u128,
),
(
hex!["b0d88e3974dd9b8e2b5919bb3eaca3241bc3ceca163df036ea539528121cde36"].into(),
12804373197912707987u128,
),
(
hex!["8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13"].into(),
17029519112752711171u128,
),
(
hex!["40ad428cb7a2530fc0c38ab879e7f5d54f25cd757cfcb21f46cb023d413eb916"].into(),
236636628523870614u128,
),
(
hex!["4cec57aebb419ab80b7d8b699024eaaa9016bb2b90821f18303abebe87b4983e"].into(),
5989065741777255205u128,
),
(
hex!["2c2d1ac621c332cc1b8e5c1bfc5b1c00c61e9767e8fcf96b1852bb39940fa209"].into(),
97016443351365356u128,
),
(
hex!["6ea653659d6a5e6f3fa95b2ffa4acad62233f91d2dc323632a3fa5c9fc7b533a"].into(),
7082036763487176084u128,
),
(
hex!["f614e6494fbb66397fe4c799971be187183d85996ac08c2ba37d666635fd0f7d"].into(),
14369468997618688200u128,
),
(
hex!["24fae36f401bf052057d4a011dc8b9ec40fcd9ef12a2823c9c8a2acbd40b906d"].into(),
2315886107309065433u128,
),
(
hex!["46b7889030d5f4653002b4b3cc50b031548c237e1b26639e26b66af113258c65"].into(),
12142098465731542975u128,
),
(
hex!["eefeff9e4cfa6e9d55128803895ff50e917f5601fda7f38f7aa71c48ee8a182c"].into(),
11439023815236597370u128,
),
(
hex!["4ec775d54f1e4d03524571e664108c5c7d8e256ac0b7a9566fe91a13fb489c1d"].into(),
9489578019617777151u128,
),
(
hex!["cebeae91074bd44a612a42098fc923e69d9b2986a9346b9e22e194867cfe1878"].into(),
15601890531640086483u128,
),
(
hex!["2c1a2fcaaddeb083764fdd5364e961506807f295b7de086bfebcf85323ec3e6f"].into(),
13079350324389304724u128,
),
(
hex!["345ff8df58e39dbae032bfed1a3f5d41078376d57adb6cabd8b319fb817b892e"].into(),
23468808288638423759u128,
),
(
hex!["da6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702"].into(),
6493072525488370028u128,
),
(
hex!["1a32c203646616b88f262569c5e52c8c45468c0b5ade90996af844a9971ddf31"].into(),
19038726261292405641u128,
),
(
hex!["e261f574706b696fa627ca60abcd27d71e509d48955c7bd39cfe26a4dbd1a305"].into(),
21295213717464967001u128,
),
(
hex!["3484fb56e2660d6d91ef93f432777778dcff9df2f9cccf0672504dd71a705358"].into(),
898508876174623538u128,
),
(
hex!["fef9b143712fefdf6825c9d85a151c0ff526f978becf980da6f5b10f8dac6c47"].into(),
32731550000000000000u128,
),
(
hex!["70ee2d1a6ae80d1fee15f47c646cbcbc9fa8dcf7365bfb5f7135daf9e4933312"].into(),
11375887786446002232u128,
),
(
hex!["94715daf5090147de11f48aee9661c46f98b1215e3a4e54867344635c7e8cf68"].into(),
1000000000000000u128,
),
(
hex!["3618b39b2ea7f3b6540772f898d4e10659e63be2cae3f83809464ca0bb5db22a"].into(),
464151188721441320u128,
),
(
hex!["d2da442bc774b21bf0a2485bc6099e468765255363136b6517adda3d6ceb8e39"].into(),
11360623175679553528u128,
),
(
hex!["4e5dbd1516d69f4132e5ea96b7cf92799075c14a32f7995fb9d6f6ebed537d64"].into(),
898508876174623538u128,
),
(
hex!["c60a0232c2be6412a0d4e48d6754179b554d35a245adf6f6fccde7ae6cc0243e"].into(),
58698491577496531u128,
),
(
hex!["dc3c2d888a41e766647e56ec7e9b71cc8db6553407be8646e35d4c0f803b9946"].into(),
118117752349247076u128,
),
(
hex!["b2c232a2c68b1b9094568fde28bca4b3845031b1afc386b4f6881c7c0162b00d"].into(),
931000000000000u128,
),
(
hex!["422f1935ec60c7e30ea45aa8b9f94adf9fc416887bdfb797860eae4d6ff2552c"].into(),
13279615062396777665u128,
),
(
hex!["90d14cddba5be458254e80a127cb06f6b2e0344928d949241da6c3e230a9c374"].into(),
4686200000000000000u128,
),
(
hex!["728d8f346c9be14f387d1ce92598cee4becdb41d944ed0d77b9ee3d652e7ec62"].into(),
6258403189666179783u128,
),
(
hex!["3e4c0237d057d92401fc9188893254f503d28af6b35535749f46420827de754d"].into(),
19242175230462504503u128,
),
(
hex!["4c19778e758d3f4763972e2b5119aee898a0c86b3f7dc2f4536f495b44f7a151"].into(),
93100000000000000u128,
),
(
hex!["484b5356ad84cc7ce4cbaf5e53c79c5d77195ad560810fa6d3fafc2145a04f69"].into(),
7634199999999999046u128,
),
(
hex!["80eca749f37cb93f00f5309552c26b2c70960452e11faa63d081090542aeac42"].into(),
15018909223219290155u128,
),
(
hex!["585bde23981ce0400b174cf234c495114421bb01554344c63dc724357a6dac24"].into(),
35007104380873117690u128,
),
(
hex!["c02c41834889bf3fec8d38e25d976dcfde3e2e44ca1275c341b0ff7617a2f14c"].into(),
2976235504698494152u128,
),
(
hex!["328135c5defeeb32f3b3f90196108f56837bb1cb999033bf380464c20ede0d4e"].into(),
1670483976174623538u128,
),
(
hex!["fc01510458f9a54c10b0fb9be4f6a5f110388ecffbffb79e3b6bfd999a17ed4c"].into(),
1824791460713404165u128,
),
(
hex!["1c96c3a56374256afa95ffa1c15cb9730d33d91fa4a8fa10b4053b166e714e68"].into(),
9310000000000000u128,
),
(
hex!["6c151c9f790fa18a0dd60debb296bb252700c482298eaf8b681f599b6f7b5150"].into(),
100000000000000u128,
),
(
hex!["844ee060a2a94beb0c3a744d00093d1929a68f3b5acc2265e99375855bd60c00"].into(),
6979217752349247076u128,
),
(
hex!["6083d585d458daed6a19c3258e311132ab786eb5144bb7b7dace2218522d274b"].into(),
931000000000000u128,
),
(
hex!["68c3d18fb07714cab1b1f8b5368e9c1e1f2b5f0e739c0602eeffc1669936ed02"].into(),
23861181086695331736u128,
),
(
hex!["5cb839c6a5e065e83b5dbf20d7082086a376586fe37fa7658cba71eda689c118"].into(),
14120423305018263853u128,
),
]
}

View File

@ -9,10 +9,16 @@ fn cli_version_works() {
.output()
.unwrap();
assert!(output.status.success(), "command returned with non-success exit code");
assert!(
output.status.success(),
"command returned with non-success exit code"
);
let version = String::from_utf8_lossy(&output.stdout).trim().to_owned();
assert_eq!(version, format!("{} {}", crate_name, env!("CARGO_PKG_VERSION")));
assert_eq!(
version,
format!("{} {}", crate_name, env!("CARGO_PKG_VERSION"))
);
}
#[test]
@ -25,7 +31,10 @@ fn cli_info_works() {
.output()
.unwrap();
assert!(output.status.success(), "command returned with non-success exit code");
assert!(
output.status.success(),
"command returned with non-success exit code"
);
let info = String::from_utf8_lossy(&output.stdout).trim().to_owned();
let v: Result<Value> = serde_json::from_str(&info);
let v = v.unwrap();

View File

@ -14,9 +14,7 @@ use tracing_subscriber::EnvFilter;
pub use runtime::{
election_provider_multi_phase::events::SolutionStored,
runtime_types::pallet_election_provider_multi_phase::{
ElectionCompute, ReadySolution,
},
runtime_types::pallet_election_provider_multi_phase::{ElectionCompute, ReadySolution},
};
pub const MAX_DURATION_FOR_SUBMIT_SOLUTION: Duration = Duration::form_secs(6 * 60);
@ -38,7 +36,8 @@ pub fn find_ws_url_from_output(read: impl Read + Send) -> (String, String) {
.lines()
.take(1024 * 1024)
.find_map(|line| {
let line = line.expect("Failed to obtain next line from stdout for WS address discovery; qed");
let line =
line.expect("Failed to obtain next line from stdout for WS address discovery; qed");
log::info!("{}", line);
data.push_str(&line);
@ -161,7 +160,14 @@ pub async fn test_submit_solution(target: Target) {
process::Command::new(cargo_bin(env!("CARGO_PKG_NAME")))
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped())
.args(["--uri", &ws_url, "monitor", "--seed-or-path", "//Alice", "seq-phragmen"])
.args([
"--uri",
&ws_url,
"monitor",
"--seed-or-path",
"//Alice",
"seq-phragmen",
])
.spawn()
.unwrap(),
);

View File

@ -2,9 +2,9 @@ pub mod common;
use assert_cmd::cargo::carg_bin;
use command::{
init_logger, run_staking_miner_playground, spawn_cli_output_threads,
test_submit_solution, wait_for_mined_solution, ElectionCompute, Target,
KillChildOnDrop, MAX_DURATION_FOR_SUBMIT_SOLUTION,
init_logger, run_staking_miner_playground, spawn_cli_output_threads, test_submit_solution,
wait_for_mined_solution, ElectionCompute, KillChildOnDrop, Target,
MAX_DURATION_FOR_SUBMIT_SOLUTION,
};
use ghost_staking_miner::opt::Chain;
use regex::Regex;
@ -27,13 +27,19 @@ async fn default_trimming_works() {
.stdout(process::Stdio::piped())
.stderr(process::Stdio::piped())
.env("RUST_LOGS", "runtime=debug,ghost-staking-miner=debug")
.args(["--uri", &ws_url, "monitor", "--seed-or-path", "//Alice", "seq-phragmen"])
.args([
"--uri",
&ws_url,
"monitor",
"--seed-or-path",
"//Alice",
"seq-phragmen",
])
.spawn()
.unwrap(),
);
let ready_solution_task =
tokio::spawn(async move { wait_for_mined_solution(&ws_url).await });
let ready_solution_task = tokio::spawn(async move { wait_for_mined_solution(&ws_url).await });
assert!(has_trimming_output(&mut miner).await);
let ready_solution = ready_solution_task
@ -51,7 +57,7 @@ async fn default_trimming_works() {
// Thus, the only way to ensure that trimming actually works.
async fn has_trimming_output(miner: &mut KillChildOnDrop) -> bool {
let trimming_re = Regex::new(
r#"from (\d+) assignments, truncating to (\d+) for (?P<target>weight|length), removing (?P<removed>\d+)#,
r#"from (\d+) assignments, truncating to (\d+) for (?P<target>weight|length), removing (?P<removed>\d+)"#,
).unwrap();
let mut got_truncate_len = false;
@ -75,11 +81,7 @@ async fn has_trimming_output(miner: &mut KillChildOnDrop) -> bool {
log::info!("{line}");
if let Some(caps) = trimming_re.captures(&line) {
let trimmed_items: usize = caps.name("removed")
.unwrap()
.as_str()
.parse()
.unwrap();
let trimmed_items: usize = caps.name("removed").unwrap().as_str().parse().unwrap();
if caps.name("target").unwrap().as_str() == "weight" && trimmed_items > 0 {
got_truncate_weight = true;