Compare commits

..

No commits in common. "0a762388d76babcde73106abf7f76a3610db0f84" and "3c7e51c0f8db8117fd8b02dee8acae80b4eb6cbf" have entirely different histories.

12 changed files with 457 additions and 1665 deletions

14
Cargo.lock generated
View File

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

View File

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

View File

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

View File

@ -1,6 +1,8 @@
// Ensure we're `no_std` when compiling for Wasm. // Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use core::usize;
use codec::{Decode, Encode, MaxEncodedLen}; use codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo; use scale_info::TypeInfo;
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
@ -24,11 +26,11 @@ use sp_core::H256;
use sp_runtime::{ use sp_runtime::{
offchain::{ offchain::{
self as rt_offchain, self as rt_offchain,
http::PendingRequest,
storage::StorageValueRef, storage::StorageValueRef,
storage_lock::{StorageLock, Time}, storage_lock::{StorageLock, Time},
HttpError,
}, },
traits::{BlockNumberProvider, Convert, Saturating}, traits::{BlockNumberProvider, Convert, Saturating, TrailingZeroInput},
Perbill, RuntimeAppPublic, RuntimeDebug, Perbill, RuntimeAppPublic, RuntimeDebug,
}; };
use sp_staking::{ use sp_staking::{
@ -160,16 +162,11 @@ pub struct PreparedApplause<AccountId, NetworkId, Balance> {
enum OffchainErr<NetworkId> { enum OffchainErr<NetworkId> {
HttpJsonParsingError, HttpJsonParsingError,
HttpBytesParsingError, HttpBytesParsingError,
HttpRequestError(HttpError),
RequestUncompleted,
HttpResponseNotOk(u16),
ErrorInEvmResponse, ErrorInEvmResponse,
NoStoredNetworks, NoStoredNetworks,
NoRequestsSent,
EmptyResponses,
NotValidator,
DifferentEvmResponseTypes,
MissingBlockNumber(u32, u32),
ContradictoryTransactionLogs(u32, u32),
ContradictoryBlockMedian(u64, u64, u64),
UnparsableRequestBody(Vec<u8>),
NoEndpointAvailable(NetworkId), NoEndpointAvailable(NetworkId),
StorageRetrievalError(NetworkId), StorageRetrievalError(NetworkId),
UtxoNotImplemented(NetworkId), UtxoNotImplemented(NetworkId),
@ -186,44 +183,31 @@ impl<NetworkId: core::fmt::Debug> core::fmt::Debug for OffchainErr<NetworkId> {
OffchainErr::HttpBytesParsingError => { OffchainErr::HttpBytesParsingError => {
write!(fmt, "Failed to parse evm response as bytes.") 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!( OffchainErr::StorageRetrievalError(ref network_id) => write!(
fmt, fmt,
"Storage value found for network #{:?} but it's undecodable.", "Storage value found for network #{:?} but it's undecodable.",
network_id 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::ErrorInEvmResponse => write!(fmt, "Error in evm reponse."),
OffchainErr::NoStoredNetworks => { OffchainErr::NoStoredNetworks => {
write!(fmt, "No networks stored for the offchain slow claps.") 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!( OffchainErr::NoEndpointAvailable(ref network_id) => write!(
fmt, fmt,
"No RPC endpoint available for network #{:?}.", "No RPC endpoint available for network #{:?}.",
@ -869,59 +853,55 @@ impl<T: Config> Pallet<T> {
network_data.default_endpoints.clone(), network_data.default_endpoints.clone(),
); );
let rpc_endpoints = if !stored_endpoints.is_empty() { 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() {
&stored_endpoints &stored_endpoints
} else { } else {
&network_data.default_endpoints &network_data.default_endpoints
}; };
if rpc_endpoints.len() == 0 { let rpc_endpoint = endpoints
return Err(OffchainErr::NoEndpointAvailable(network_id)); .get(random_index)
} .ok_or(OffchainErr::NoEndpointAvailable(network_id))?;
let (from_block, to_block): (u64, u64) = StorageValueRef::persistent(&block_number_key) let (from_block, to_block): (u64, u64) = StorageValueRef::persistent(&block_number_key)
.get() .get()
.map_err(|_| OffchainErr::StorageRetrievalError(network_id))? .map_err(|_| OffchainErr::StorageRetrievalError(network_id))?
.unwrap_or_default(); .unwrap_or_default();
match network_data.network_type {
NetworkType::Evm => {
let request_body = if from_block < to_block.saturating_sub(1) { let request_body = if from_block < to_block.saturating_sub(1) {
Self::prepare_evm_request_body_for_latest_transfers( Self::prepare_request_body_for_latest_transfers(
from_block, from_block,
to_block.saturating_sub(1), to_block.saturating_sub(1),
network_data, network_data,
) )
} else { } else {
Self::prepare_evm_request_body_for_latest_block(network_data) Self::prepare_request_body_for_latest_block(network_data)
}; };
let pending_requests = let response_bytes = Self::fetch_from_remote(&rpc_endpoint, &request_body)?;
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 { let new_block_range = match parsed_evm_response {
EvmResponseType::BlockNumber(new_evm_block) if from_block.le(&to_block) => { EvmResponseType::BlockNumber(new_evm_block) if from_block.le(&to_block) => {
// stay in the range of block distance
let estimated_block = let estimated_block =
new_evm_block.saturating_sub(network_data.finality_delay); new_evm_block.saturating_sub(network_data.finality_delay);
match from_block { let adjusted_block =
0 => (estimated_block, estimated_block), Self::adjust_to_block(estimated_block, from_block, max_block_distance);
start_block => {
let block_deviation = if from_block == 0 {
start_block.saturating_add(max_block_distance); (estimated_block, estimated_block)
(start_block, estimated_block.min(block_deviation)) } else {
} (from_block, adjusted_block)
} }
} }
_ => (to_block, to_block), _ => (to_block, to_block),
@ -931,14 +911,15 @@ impl<T: Config> Pallet<T> {
log::info!( log::info!(
target: LOG_TARGET, target: LOG_TARGET,
"👻 Offchain worker #{:?} stored block #{:?} for network {:?}", "👻 Slow Clap #{:?} stored block #{:?} for network {:?}",
block_number, block_number,
new_block_range.0, new_block_range.0,
network_id, network_id,
); );
if !sp_io::offchain::is_validator() { if !sp_io::offchain::is_validator() {
return Err(OffchainErr::NotValidator); log::info!(target: LOG_TARGET, "👻 Not a validator; no transactions available");
return Ok(());
} }
for (authority_index, authority_key) in Self::local_authorities(&session_index) { for (authority_index, authority_key) in Self::local_authorities(&session_index) {
@ -958,6 +939,22 @@ 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( fn local_authorities(
session_index: &SessionIndex, session_index: &SessionIndex,
) -> impl Iterator<Item = (u32, T::AuthorityId)> { ) -> impl Iterator<Item = (u32, T::AuthorityId)> {
@ -976,216 +973,35 @@ impl<T: Config> Pallet<T> {
}) })
} }
fn prepare_pending_evm_requests( fn fetch_from_remote(rpc_endpoint: &[u8], request_body: &[u8]) -> OffchainResult<T, Vec<u8>> {
rpc_endpoints: &Vec<Vec<u8>>, let rpc_endpoint_str =
request_body: &[u8], core::str::from_utf8(rpc_endpoint).expect("rpc endpoint valid str; qed");
) -> OffchainResult<T, Vec<PendingRequest>> { let request_body_str =
let mut pending_requests = Vec::new(); core::str::from_utf8(request_body).expect("request body valid str: qed");
let request_body_str = core::str::from_utf8(request_body)
.map_err(|_| OffchainErr::UnparsableRequestBody(request_body.to_vec()))?;
let deadline = sp_io::offchain::timestamp() let deadline = sp_io::offchain::timestamp()
.add(rt_offchain::Duration::from_millis(FETCH_TIMEOUT_PERIOD)); .add(rt_offchain::Duration::from_millis(FETCH_TIMEOUT_PERIOD));
for rpc_endpoint in rpc_endpoints.iter() { let pending = rt_offchain::http::Request::post(&rpc_endpoint_str, vec![request_body_str])
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("Accept", "application/json")
.add_header("Content-Type", "application/json") .add_header("Content-Type", "application/json")
.deadline(deadline) .deadline(deadline)
.send() .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,
)
}
}
}
if pending_requests.len() == 0 { let response = pending
return Err(OffchainErr::NoRequestsSent); .try_wait(deadline)
} .map_err(|_| OffchainErr::RequestUncompleted)?
.map_err(|_| OffchainErr::RequestUncompleted)?;
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 { if response.code != 200 {
responses_non_200 += 1; return Err(OffchainErr::HttpResponseNotOk(response.code));
return None;
} }
Some(response.body().collect::<Vec<u8>>()) Ok(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_evm_request_body_for_latest_block(network_data: &NetworkData) -> Vec<u8> { fn prepare_request_body_for_latest_block(network_data: &NetworkData) -> Vec<u8> {
match network_data.network_type { match network_data.network_type {
NetworkType::Evm => { NetworkType::Evm => {
b"{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}".to_vec() b"{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"eth_blockNumber\"}".to_vec()
@ -1194,7 +1010,7 @@ impl<T: Config> Pallet<T> {
} }
} }
fn prepare_evm_request_body_for_latest_transfers( fn prepare_request_body_for_latest_transfers(
from_block: u64, from_block: u64,
to_block: u64, to_block: u64,
network_data: &NetworkData, network_data: &NetworkData,

View File

@ -3,7 +3,6 @@
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use super::*; use super::*;
use crate::evm_types::Log;
use crate::mock::*; use crate::mock::*;
use frame_support::{assert_err, assert_ok, dispatch}; use frame_support::{assert_err, assert_ok, dispatch};
@ -138,6 +137,16 @@ fn bitmap_operations_correct() {
assert_eq!(ones, 11); 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] #[test]
fn request_body_is_correct_for_get_block_number() { fn request_body_is_correct_for_get_block_number() {
let (offchain, _) = TestOffchainExt::new(); let (offchain, _) = TestOffchainExt::new();
@ -146,7 +155,7 @@ fn request_body_is_correct_for_get_block_number() {
t.execute_with(|| { t.execute_with(|| {
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data); let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
assert_eq!( assert_eq!(
core::str::from_utf8(&request_body).unwrap(), core::str::from_utf8(&request_body).unwrap(),
r#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"# r#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#
@ -164,7 +173,7 @@ fn request_body_is_correct_for_get_logs() {
let from_block: u64 = 420; let from_block: u64 = 420;
let to_block: u64 = 1337; let to_block: u64 = 1337;
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers( let request_body = SlowClap::prepare_request_body_for_latest_transfers(
from_block, to_block, &network_data); from_block, to_block, &network_data);
assert_eq!(core::str::from_utf8(&request_body).unwrap(), 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"]}]}"#, r#"{"id":0,"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1a4","toBlock":"0x539","address":"0x4d224452801ACEd8B2F0aebE155379bb5D594381","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}"#,
@ -181,15 +190,10 @@ fn should_make_http_call_for_block_number() {
evm_block_response(&mut state.write()); evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints(); let rpc_endpoint = get_rpc_endpoint();
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data); let request_body = SlowClap::prepare_request_body_for_latest_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(), 45usize); // precalculated assert_eq!(raw_response.len(), 45usize); // precalculated
Ok(()) Ok(())
}); });
@ -206,20 +210,15 @@ fn should_make_http_call_for_logs() {
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let from_block: u64 = 20335770; let from_block: u64 = 20335770;
let to_block: u64 = 20335858; let to_block: u64 = 20335858;
let rpc_endpoints = get_rpc_endpoints(); let rpc_endpoint = get_rpc_endpoint();
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers( let request_body = SlowClap::prepare_request_body_for_latest_transfers(
from_block, from_block,
to_block, to_block,
&network_data, &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 assert_eq!(raw_response.len(), 1805); // precalculated
Ok(()) Ok(())
}); });
@ -234,15 +233,11 @@ fn should_make_http_call_and_parse_block_number() {
evm_block_response(&mut state.write()); evm_block_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints(); let rpc_endpoint = get_rpc_endpoint();
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_block(&network_data); let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
let pending_requests = let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
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( let evm_block_number = SlowClap::parse_evm_response(&raw_response).map(
|parsed_response| match parsed_response { |parsed_response| match parsed_response {
EvmResponseType::BlockNumber(block_number) => block_number, EvmResponseType::BlockNumber(block_number) => block_number,
@ -268,23 +263,19 @@ fn should_make_http_call_and_parse_logs() {
evm_logs_response(&mut state.write()); evm_logs_response(&mut state.write());
let _: Result<(), OffchainErr<u32>> = t.execute_with(|| { let _: Result<(), OffchainErr<u32>> = t.execute_with(|| {
let rpc_endpoints = get_rpc_endpoints(); let rpc_endpoint = get_rpc_endpoint();
let from_block: u64 = 20335770; let from_block: u64 = 20335770;
let to_block: u64 = 20335858; let to_block: u64 = 20335858;
let network_data = prepare_evm_network(None, None); let network_data = prepare_evm_network(None, None);
let request_body = SlowClap::prepare_evm_request_body_for_latest_transfers( let request_body = SlowClap::prepare_request_body_for_latest_transfers(
from_block, from_block,
to_block, to_block,
&network_data, &network_data,
); );
let pending_requests = let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
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)? { match SlowClap::parse_evm_response(&raw_response)? {
EvmResponseType::BlockNumber(_) => assert_eq!(1, 0), // force break EvmResponseType::BlockNumber(_) => assert_eq!(1, 0), // force break
EvmResponseType::TransactionLogs(evm_logs) => assert_eq!(evm_logs.len(), 2), EvmResponseType::TransactionLogs(evm_logs) => assert_eq!(evm_logs.len(), 2),
@ -294,162 +285,6 @@ 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] #[test]
fn should_emit_black_swan_if_not_enough_authorities_left() { fn should_emit_black_swan_if_not_enough_authorities_left() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None); let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
@ -1520,147 +1355,6 @@ 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( fn assert_clapped_amount(
session_index: &SessionIndex, session_index: &SessionIndex,
unique_hash: &H256, unique_hash: &H256,
@ -1877,7 +1571,6 @@ fn get_mocked_metadata() -> (H256, u64, u64, u64) {
fn evm_block_response(state: &mut testing::OffchainState) { fn evm_block_response(state: &mut testing::OffchainState) {
let expected_body = br#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#.to_vec(); let expected_body = br#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#.to_vec();
state.expect_request(testing::PendingRequest { state.expect_request(testing::PendingRequest {
method: "POST".into(), method: "POST".into(),
uri: "https://rpc.endpoint.network.com".into(), uri: "https://rpc.endpoint.network.com".into(),
@ -1886,19 +1579,6 @@ fn evm_block_response(state: &mut testing::OffchainState) {
("Content-Type".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()), 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, body: expected_body,
sent: true, sent: true,
..Default::default() ..Default::default()
@ -1956,23 +1636,6 @@ fn evm_logs_response(state: &mut testing::OffchainState) {
("Accept".to_string(), "application/json".to_string()), ("Accept".to_string(), "application/json".to_string()),
("Content-Type".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, body: expected_body,
response: Some(expected_response), response: Some(expected_response),
sent: true, sent: true,

View File

@ -209,13 +209,9 @@ if [[ $HARD_RESET = true ]]; then
echo "WARNING!!! THIS ACTION WILL COMPLETELY PURGE THE LEDGER AND REBUILD THE NODE USING THE LATEST" 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 "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 "THERE ARE TWO SCENARIOS IN WHICH YOU MIGHT NEED TO PROCEED:"
echo -e "\t- A new version of the network has been released, and a restart is neccessary" echo -e "\t- A new version of the network hsa 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 "\t- There is a critical issue, and you require a hard reset of the node in a single command"
echo -e "\n" 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 if prompt "[?] do you understand all risks?"; then
echo "[+] you were warned, I hope you know what you're doing" echo "[+] you were warned, I hope you know what you're doing"
else else

File diff suppressed because one or more lines are too long

View File

@ -190,8 +190,7 @@ fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> {
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> { fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
vec![ vec![(
(
11155111, 11155111,
ghost_networks::NetworkData { ghost_networks::NetworkData {
chain_name: "sepolia-ethereum-testnet".into(), chain_name: "sepolia-ethereum-testnet".into(),
@ -214,31 +213,10 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(), topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
incoming_fee: 69_000_000u32, incoming_fee: 69_000_000u32,
outgoing_fee: 0u32, outgoing_fee: 0u32,
}.encode(), }
2048861035254140036511u128, .encode(),
), 1464619352760244956993u128,
( )]
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 /// Helper function to create casper `GenesisConfig` for testing
@ -460,7 +438,7 @@ fn casper_staging_config_genesis() -> serde_json::Value {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}, },
"staking": { "staking": {
"validatorCount": 69, "validatorCount": 500,
"minimumValidatorCount": 3, "minimumValidatorCount": 3,
"stakers": initial_authorities "stakers": initial_authorities
.iter() .iter()
@ -475,10 +453,8 @@ fn casper_staging_config_genesis() -> serde_json::Value {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
"forceEra": Forcing::NotForcing, "forceEra": Forcing::NotForcing,
"slashRewardFraction": Perbill::from_percent(10), "slashRewardFraction": Perbill::from_percent(10),
"minNominatorBond": 690 * STRH, "minNominatorBond": 6_900 * STRH,
"minValidatorBond": 6_900 * STRH, "minValidatorBond": 6_900 * STRH,
"maxNominatorCount": Some(1337),
"maxValidatorCount": Some(420),
}, },
"babe": { "babe": {
"epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG), "epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG),

View File

@ -2,805 +2,186 @@ use hex_literal::hex;
pub fn legacy_endowments() -> Vec<(primitives::AccountId, u128)> { pub fn legacy_endowments() -> Vec<(primitives::AccountId, u128)> {
vec![ vec![
( (hex!["fe3cb0119ffaf59434233d0b0d85cd2d16fde46f713dcab39047eb222f3ae666"].into(), 898508876174623538u128),
hex!["fe3cb0119ffaf59434233d0b0d85cd2d16fde46f713dcab39047eb222f3ae666"].into(), (hex!["88a74a42ca9a17acc210ae56ff8ace565e246025a2743da967dfde9d6c76277c"].into(), 11499490981584684807u128),
898508876174623538u128, (hex!["94addf7d81d155c9f4d8d0eab3ceb019939db5f3b0081ae3e888a6ed3c845307"].into(), 1000000000000000u128),
), (hex!["6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666"].into(), 20045398007416485176u128),
( (hex!["7409c6caca65472f77938a143a7ee73a85dd9c1acf60fcc13aade8dc1be38a0a"].into(), 30478997642754917282u128),
hex!["88a74a42ca9a17acc210ae56ff8ace565e246025a2743da967dfde9d6c76277c"].into(), (hex!["fa402c6b1c1db2ce9e3e1ba4e559581faa821d20254d8d16e4e18057a3b90672"].into(), 9796698744519740142u128),
20734039366660590012u128, (hex!["ac1932d76a47c5819724999aa3626aa85e71bf60c8fccdeac92cf53beab7a85f"].into(), 346508876174623538u128),
), (hex!["a6bbe75122ce02a5c0d9ebeda902fb0ae21138a7487e18adef1c3e7d106b3715"].into(), 898508876174623538u128),
( (hex!["1225d9453ad3fe1197dfc2410760cea284529e226fef262fb01574ae2a6c5900"].into(), 16442998462241875728u128),
hex!["94addf7d81d155c9f4d8d0eab3ceb019939db5f3b0081ae3e888a6ed3c845307"].into(), (hex!["ac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c"].into(), 1998508837042115740u128),
1000000000000000u128, (hex!["6cabf6e32fb8909acae30605bb3e5997d201103d298734851d58022423977655"].into(), 12822257832237511466u128),
), (hex!["fe0f596b6bf22b5fbad52ebce3429bb6bdeb00996fc8e51aae2e437450f6b578"].into(), 12157355198880897693u128),
( (hex!["84e01e431c701383fb0fc204338aca8cff0a2e88bb9397ba7b5ec8b236850e17"].into(), 9488095602980648270u128),
hex!["6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666"].into(), (hex!["507110e1a96c4b781207ad9c790c558f752ca99614f281b6b24a2e467e04e25e"].into(), 9713310740009473644u128),
21042733373739997438u128, (hex!["005dc72f4d842896adf3505695eef833aad9cdee22448751f0500c30cfdda247"].into(), 14021423144351682305u128),
), (hex!["a64f42e128afa40b848faf5df5e260e58390c6ca2bbcd5e866b5460a4c2dc60c"].into(), 10792504141381628956u128),
( (hex!["4a32ed6e36b6dec1ce328c650f5276a6e5ac4e594b7ba71a1cb87a2770f53b33"].into(), 14140001662633653275u128),
hex!["7409c6caca65472f77938a143a7ee73a85dd9c1acf60fcc13aade8dc1be38a0a"].into(), (hex!["58967ccdc9d4ddab5c32b6605947becba27cca5799a93c9d4d03a0fb3ebc7316"].into(), 453608876174623538u128),
8609732485052672834u128, (hex!["323158b7e1cb9b3104fce73ed72095764fe785a1d14b9a8f73e54973f04b9d74"].into(), 13375245216003871505u128),
), (hex!["3e130ccc1fac5e9d5c2c280341ce8b8dbcafc17ceb75d3722f83404ed2215856"].into(), 16753318413269579418u128),
( (hex!["acbda1ba4cfd81cd430b53a834c0d92085e8efc6948a03c10c2f6a66ba19443a"].into(), 36751232674856508996u128),
hex!["fa402c6b1c1db2ce9e3e1ba4e559581faa821d20254d8d16e4e18057a3b90672"].into(), (hex!["4cecf92b37e6954f086002cf7b6a61ac7d9ba40c83ef963005e3cacfb5c1e13f"].into(), 14040022959030355565u128),
9796698744519740142u128, (hex!["f09c9f7ecdd1be0d07a2d0759efdff5152f23ec742f86e15a9ac03c0995f2365"].into(), 898508876174623538u128),
), (hex!["8256b4a52f0277042cacc427cf00b8d668d0e7fe7824f53acf927da985f32410"].into(), 898508876174623538u128),
( (hex!["3a926d7cf3546e58e48f9faf392b02e6d1d43011676378914988eeaea2cbff3a"].into(), 4035504698494152u128),
hex!["ac1932d76a47c5819724999aa3626aa85e71bf60c8fccdeac92cf53beab7a85f"].into(), (hex!["e4dcfdec0dda94b9cb45bf6ff12439392f01fb9d738f806fb115b1d21c99135d"].into(), 3977726628523870614u128),
346508876174623538u128, (hex!["cc88301ef74e085f731220d101dcd14d2b04bc1e59a6c45009c156a9990eab46"].into(), 38103139771143223684u128),
), (hex!["46f41aed549dcfa8c094c19787dfbe974fef680eacd209ef88640c82bcb77811"].into(), 13819008291976111251u128),
( (hex!["9a3e9942c0cb9fe1f1acc97c3bf458e9b7955f44604183e569d5120de3400e10"].into(), 8835780408986419448u128),
hex!["a6bbe75122ce02a5c0d9ebeda902fb0ae21138a7487e18adef1c3e7d106b3715"].into(), (hex!["9aceaa2fa9e3226bbe106cd0150f9807b089281b16942bff471caa1359aa8a22"].into(), 1360508232557032475u128),
898508876174623538u128, (hex!["661fd59a3748d65d66d9612f0c8f5871029e8e74deb3c0e1fbdbcf3c04e84a5e"].into(), 246508876174623538u128),
), (hex!["20fed126411d5d1a1ab3915bffac49297b0eae9dcf4288589c0cad49d925637b"].into(), 1308508876174623538u128),
( (hex!["eeaaf5db1b1eb55cc8c1b26c5092868ada9af63c2961bba4d4b5d63e99371c00"].into(), 13381482878571786796u128),
hex!["1225d9453ad3fe1197dfc2410760cea284529e226fef262fb01574ae2a6c5900"].into(), (hex!["ac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50"].into(), 75053899371678858u128),
25679625557282857591u128, (hex!["144a1fa97fdba679efd2a36696a0d40f585b649143bb7da5cbd7458ea4a0f674"].into(), 19762757562620855283u128),
), (hex!["a231498b31f698619d80746aa2049ec187c4a103a3c5a8940e14d1b03abe1239"].into(), 676568060690000000u128),
( (hex!["d05b788865ffffdfbb7dfecd937188628a275926ab47742f84b5cda86e5d825d"].into(), 97017752349247076u128),
hex!["ac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c"].into(), (hex!["7673ef8a48eaf9364831735201743d20587e27ff5ff2df42808e4625be6f656b"].into(), 899439876174623538u128),
4495926542421046636u128, (hex!["6a92d2e77c6b56428db2129d33c3ba1e71c8a52315a65f03f30dbaf31224153d"].into(), 708444482928862970u128),
), (hex!["d8193ef891724c66a6cc58273eadcfb133f9bbc7d777e6456721a70e90ded71f"].into(), 195510000000000000u128),
( (hex!["c256b6d62a54c94220ceb1b55f4afae84e59c913b8163d57791463d7ac67555c"].into(), 13111614265582327685u128),
hex!["6cabf6e32fb8909acae30605bb3e5997d201103d298734851d58022423977655"].into(), (hex!["723aabc24abe3a04fb79c4a51e5b023e99f5c1afcfeac7d434276496a65ede3e"].into(), 898508876174623538u128),
301045085375060900u128, (hex!["4078ddb1ba1388f768fe6aa40ba9124a72692ecbcc83dc088fa86c735e4dc128"].into(), 1045536628523870614u128),
), (hex!["d8a1924995f48a61c0bb79f3fdaeff18573cf1d2164454938c773f6066d81413"].into(), 3296223653083995083u128),
( (hex!["b85a4db79fa17d9853f2c4031aa60c8ee09a38bbce5e484ddb4c6b32bfefd401"].into(), 14390589865809310762u128),
hex!["fe0f596b6bf22b5fbad52ebce3429bb6bdeb00996fc8e51aae2e437450f6b578"].into(), (hex!["224f1f3a7534ab5a9a218812d5b6d3587d8b3de89e73310ca8ea74d35c63ee46"].into(), 898508876174623538u128),
2686488249070628254u128, (hex!["d84a9b4a2039ac793cb4108990e10e8341039a9c5caee9ed271cd84cc91d2e10"].into(), 82999821765415413069u128),
), (hex!["a280b6e97389ed44d9ae9fcb36df39072ab60c7e71088087c4890b8e07f1d97b"].into(), 13104582315236011828u128),
( (hex!["0436858543a367154f1a6e9c1f67c4a865a7c92e6adb31d21e7c4312a64d6219"].into(), 2201608876174623538u128),
hex!["84e01e431c701383fb0fc204338aca8cff0a2e88bb9397ba7b5ec8b236850e17"].into(), (hex!["de24e0e98fd99ca8079f9f154293f967731303cf3b862d19d34b98c1db689f41"].into(), 2196169714471969993u128),
9488095602980648270u128, (hex!["6255ca0f443e06c0031045d9b6883964f3176526f7243941b48cf89a09adc057"].into(), 14616699999999998u128),
), (hex!["f01ce72cc4db3db4eff729f4dab35db89117f40e9f53c7d5cb68d09f2bf28802"].into(), 10583410569668495529u128),
( (hex!["3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315"].into(), 28409923837144670351u128),
hex!["507110e1a96c4b781207ad9c790c558f752ca99614f281b6b24a2e467e04e25e"].into(), (hex!["785b89d27366fcba6ff4dc6a6fa3dfc586d2f5edc15f9416e3a93229f0e7c45d"].into(), 2203940931652105261u128),
446342905026072u128, (hex!["985562d52d2ce181cdfe12598b40c15ea91adbf74a681ce82029d323f63af45d"].into(), 10071185931226347521u128),
), (hex!["fa7728904cfced5998fd559251a9dfb008d2bd838917b9eb6c5332a9ed22b302"].into(), 13266286751478030059u128),
( (hex!["80aac52e8482215ae5d022f71c50734b9f5e6d5048bb4d7a198fb77925f97a34"].into(), 11402028653479979903u128),
hex!["005dc72f4d842896adf3505695eef833aad9cdee22448751f0500c30cfdda247"].into(), (hex!["0afa4924d17ab1f9d4aa4197f566ab29f5360a3e03949799f74638cf33d9b852"].into(), 12792398754994057800u128),
19922026892862601u128, (hex!["42c3d5a95c5ba5b9daaa0f68631fa1d0cc744c0dc50476c392167d86d6368b0a"].into(), 12276140304411166019u128),
), (hex!["1c65ddadd315f740e7cc162ed79f1d2d743af5c92403615cb078f0da9d78f95d"].into(), 898508876174623538u128),
( (hex!["ea1c01ff56725c6fdd62efaa119b704a2f467fd21d20a3c2117668bfeba02e76"].into(), 15364926655816994525u128),
hex!["a64f42e128afa40b848faf5df5e260e58390c6ca2bbcd5e866b5460a4c2dc60c"].into(), (hex!["ea24c5b5640658f8ad793b40d819dc22c4d55415c666c2e402f6c8412c9c3126"].into(), 13459266313430743241u128),
10792504141381628956u128, (hex!["0e05218ac7c6f6c809460d476bc23f660415089854ffe9ad2ddce02704de0049"].into(), 898508876174623538u128),
), (hex!["ac0ed11176b0f1cd7539ea734c2a157aadb8b385e43f7731fa3c115174260332"].into(), 921318876174623538u128),
( (hex!["f684d118dc9ddfc2f3f6365feae3c258c8ba2c8e5872373c9fa3803ef3d0cf5b"].into(), 21228508876174623538u128),
hex!["4a32ed6e36b6dec1ce328c650f5276a6e5ac4e594b7ba71a1cb87a2770f53b33"].into(), (hex!["d281d7b41a3e369eef42d15060819df4d9c7d3e43eb5c223244a9bb8c5a2ed44"].into(), 12907092936613202269u128),
726673904645949199u128, (hex!["2224294c8b826c3d35b6105a91923dfcf6c50706a2d57527b971dbc1f4a8c90b"].into(), 529726628523870614u128),
), (hex!["20655f7d14fb63c001601c177e513c4e2197253e38638cb034e0ecda9f93db79"].into(), 1005108876174623538u128),
( (hex!["7000daf495c30583e255cbf926dcc278427a300c96ef807ddf3f05a38bb3bd6f"].into(), 12295813875568537231u128),
hex!["58967ccdc9d4ddab5c32b6605947becba27cca5799a93c9d4d03a0fb3ebc7316"].into(), (hex!["fa18d3053a66f26a024bbf0b04571477688542fab309fc4fab6419e7744e023d"].into(), 727997752349247076u128),
453608876174623538u128, (hex!["12ff06ed5c993253837f627ff4ddcee4658ebcea47bb7f13d299bc3b2d520440"].into(), 9660045161058603076u128),
), (hex!["d263c987009ee0bc900162e9af9e2f2ed073f2d2af895e4bb8f4fb72840aa457"].into(), 12688435840744280612u128),
( (hex!["dca9bba238f216683ea0c43bdce1709578d83e4b41875c76266e84024c34a72b"].into(), 898508876174623538u128),
hex!["323158b7e1cb9b3104fce73ed72095764fe785a1d14b9a8f73e54973f04b9d74"].into(), (hex!["a25b474bb6a2b241ff7f574309240e0ca84aa29f5d04912842e5748af631a740"].into(), 13370440034824674362u128),
531467153727934259u128, (hex!["007143a869c6e707fe03eae20704a81a97eb7beabedef62f8e3cbe5706b6e247"].into(), 14768512833373884464u128),
), (hex!["5e1456904c40192cd3a18183df7dffea90d97739830a902cabb702ecdae4f649"].into(), 376017752349247076u128),
( (hex!["6d6f646c70792f74727372790000000000000000000000000000000000000000"].into(), 490184997478957959982u128),
hex!["3e130ccc1fac5e9d5c2c280341ce8b8dbcafc17ceb75d3722f83404ed2215856"].into(), (hex!["9607407bc837b24624c7886129755843bd3a149f8bfec76bc8f828876cac3461"].into(), 10929472937167428328u128),
16753318413269579418u128, (hex!["20f8135fb600717f8e288e6b9a6dacbeb54677664dcde4998558975e606caf20"].into(), 786017752349247076u128),
), (hex!["beadbe750127679102bb60e0493ad501394283b7a9a0001887f320ec8d83af5f"].into(), 13059337743467906765u128),
( (hex!["84328018915f262b63a52d947506c9e75878f3bae7454aa197c7624393256609"].into(), 93100000000000000u128),
hex!["a003dfd6d28a3fabf2b46df20383635c72c5a41d8ee79a5fb75e9d1298b3761f"].into(), (hex!["b624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73"].into(), 20389023363985231125u128),
1172036132833830838u128, (hex!["1eef351e2c381586366f89bbdf5c690372fa05c7c5a47e6351315f0aa9507029"].into(), 13515506357309430378u128),
), (hex!["4a2aa2bccfe5ae7a771fc2ce7732ad2da397ee51f0a45f18c167bb555fa70506"].into(), 2793000000000000000u128),
( (hex!["909f0584f25fd044fc4336f966e14e925d77466e8629f4c6888d55cf594b6d76"].into(), 346508876174623538u128),
hex!["acbda1ba4cfd81cd430b53a834c0d92085e8efc6948a03c10c2f6a66ba19443a"].into(), (hex!["08aae874b34057e02c3f6c28fffe8eaa0f665e9d7cc0d38f878c9ae862d47277"].into(), 499553257047741228u128),
36751232674856508996u128, (hex!["749089588c2a57b4cc4adc4541c441332d2fa11acf13f785e470d03cef61d75d"].into(), 13128362389531005022u128),
), (hex!["de3d246b0109357114d1ee78ec4598fcff1cf19da4254ced289ac4e534b6084b"].into(), 506451628523870614u128),
( (hex!["2a5bc425d9c6b8e29d5ccfe3282560fc8ab079262763aaf4d9269c7c6043f208"].into(), 12344029246075616723u128),
hex!["4cecf92b37e6954f086002cf7b6a61ac7d9ba40c83ef963005e3cacfb5c1e13f"].into(), (hex!["347db8f39a1a1efa2ec9daeaaa04e3512238e9a6970fba65878f83366e927f27"].into(), 13250762917778422850u128),
14038937501875054342u128, (hex!["4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a"].into(), 31034809886518069653u128),
), (hex!["3cae73748956c91dc21f54e2653e0fb76b9c8ffe38c2c3e2ad6483e88c968a02"].into(), 12376423999653776239u128),
( (hex!["5688a4d3171b935a3b038729ccb0cca068a4243cd3a6b7e102e7e14ac49d6427"].into(), 13207638229965515023u128),
hex!["f09c9f7ecdd1be0d07a2d0759efdff5152f23ec742f86e15a9ac03c0995f2365"].into(), (hex!["8c7a053eb4ce5a680150650e88533ade4ce08fee5340888ae655df3c37910d04"].into(), 388508876174623538u128),
898508876174623538u128, (hex!["3a2e10fef720299388eb789aaab0e0bb1b7c10464aa7c442c6a584cf11c01845"].into(), 345017752349247076u128),
), (hex!["8e20ae229b297cdb71aaa122c0182c636d9f97f9d38e7dffb24045b00374a060"].into(), 316542729061225383u128),
( (hex!["4850e7dd6e309b3758b16a43e96cc16455245ab31dbf2920397e58106ee7a112"].into(), 898508876174623538u128),
hex!["8256b4a52f0277042cacc427cf00b8d668d0e7fe7824f53acf927da985f32410"].into(), (hex!["c28559a4c9a9ffc428441295a309e944e3e9b87a832cf3cebd3def8c57b4ec1a"].into(), 13244103182710791045u128),
898508876174623538u128, (hex!["6a7a10e74c6fbcd0d9ea2ec1cfff2ce89cc5501315117757642f50c36dfa5c01"].into(), 24416873171189988097u128),
), (hex!["5a792ca101c15da5b237477a3c1e30f4873a21c8046bfc44117d4f3dedceb374"].into(), 24125718413269577510u128),
( (hex!["3068d31973cc3b18745cf5d6e75e2ec0a940d2aec79af2b313a530f6c558d77e"].into(), 1990135504698494152u128),
hex!["bea3d9a526bfdbd98870bb615dc91d5d9295a6e021e5e9b9193801697a05586e"].into(), (hex!["76ef9c99dfb1ee5604b7d7314f61908957db55fa294a0794c6bf793691c49954"].into(), 13101580949598094188u128),
225166041881037450131u128, (hex!["c8ffc2b4e770b08b9a4ae10168c48dd821581a2df3cf5f3a371dcc1326bbe94c"].into(), 9310000000000000000u128),
), (hex!["f235af8680ec5cbfbac0fc818da07c727e449454b04e2d96671e2d64ececb30a"].into(), 4167571995070680428u128),
( (hex!["c8f4d838e6e262a7c905eb268f36a3e5b7240130aa895384822cdd968586cb01"].into(), 14912878206297721983u128),
hex!["3a926d7cf3546e58e48f9faf392b02e6d1d43011676378914988eeaea2cbff3a"].into(), (hex!["160d647d9a380687f63cbe4ea23279692b997a3dad19227b1bb85f08965d7859"].into(), 15280448272566261071u128),
4035504698494152u128, (hex!["e872e23fc05919751708f5bf887a68ef9c175cf7f1728dca6220e2a2370e163f"].into(), 12599268699455778903u128),
), (hex!["685c600574546bad67b0ae6768f07b7fee1f1aec6473c941606f9829cfa93b6c"].into(), 2211687751137074462u128),
( (hex!["ba821401516b2429cd25e506c1af11b23808d039d1319d6b2eb7a9222d922179"].into(), 18372096744466282652u128),
hex!["e4dcfdec0dda94b9cb45bf6ff12439392f01fb9d738f806fb115b1d21c99135d"].into(), (hex!["2e1158566a7c2a57c68e542b64ac5987cb69aaaf846735addafc6f90cb5d8e3b"].into(), 13985217814424299670u128),
3977726628523870614u128, (hex!["da35bf90643e1f5431031728c9f9c3eebea63c6bcfce1c8b468591cf6ed35210"].into(), 11680033590958446157u128),
), (hex!["a8c76be6e69cb05748f5accbced41809a1bdf30400402e63753fc85adfbea418"].into(), 8060691100000000000u128),
( (hex!["f442a26de0c465651bbe51ff90d0b31f63af206d84cf2bcab5a1ee7ab537ec4b"].into(), 2793000000000000u128),
hex!["cc88301ef74e085f731220d101dcd14d2b04bc1e59a6c45009c156a9990eab46"].into(), (hex!["909ab2271d3fc8df9e8556232a29eea7cf1cfdf8c89603a602779daa6484f011"].into(), 15989848178884321645u128),
153582139771143223684u128, (hex!["f0515fcc6570d35645675f99aa04295fd1e12d88ab9abcac61f58092a5c3e316"].into(), 1622526628523870614u128),
), (hex!["a02d33ee7c4d38649d4bd88f330e75740ab4e4aa55e0f18110d8e6c72f71615a"].into(), 430027752349247076u128),
( (hex!["ee5005bc008184ed8d8d71774a167e4773fdbad6c8bf8e4d46a211b6b52e806f"].into(), 405127480873117690u128),
hex!["46f41aed549dcfa8c094c19787dfbe974fef680eacd209ef88640c82bcb77811"].into(), (hex!["562f42de365612dd23609a21117e3b807242f50af7a51877fc907656e723b41c"].into(), 23545504698493896u128),
13819008291976111251u128, (hex!["3cd73e0f752cf301d3c2bca3d72d2502003d7143bacac8944e972bbe921a1b11"].into(), 539608876174623538u128),
), (hex!["223ab980529a7f877a79fb4bd2280c60e8ed0978b21007de70e1682f5d0fe846"].into(), 6394212201126639927u128),
( (hex!["74302b4989cfd149c4a99b0bc9a4ff82cf63d3f4291fa2597963fe4db56e401a"].into(), 898508876174623538u128),
hex!["58ed8cee04bcfb70719644a6b9478b8eebfe7ffc8964590e12e1bf36ea245375"].into(), (hex!["9696d44dce264f5c1e2e5cdbc3c0609a627ac712dbd7ce6a24a415b7ea652773"].into(), 13064032622783391575u128),
11624450784910043012u128, (hex!["b852757ba5ce6a3fddcdd13f7a548d16532dbf1b16693d951c348860c421ab16"].into(), 13090753661669103954u128),
), (hex!["223983e8b68f45666ec4faa573b2aa9b664b20bc25517c179cb354eda6704b04"].into(), 15187474897366947923u128),
( (hex!["94cc169c4cd81710fe19a6ce10ef35b1fe1d53aa04dc24e0a55d3a6dda728909"].into(), 9490152116008452257u128),
hex!["9a3e9942c0cb9fe1f1acc97c3bf458e9b7955f44604183e569d5120de3400e10"].into(), (hex!["daff035dfadff80ada04930d67be6dc9837d65d39a124a64973b1f52e6203876"].into(), 16388220707138965567u128),
14452183576445203470u128, (hex!["a04214ec6484663f990a1dd3f4a02f8f174723a54a369478c076573aa43d1e30"].into(), 11024583916484684117u128),
), (hex!["425533de216bf2e3a9d1f3358dbf23a8d56d3d2fdbfe5deb2d989716fd26734f"].into(), 14124681775633429910u128),
( (hex!["fc1310a824a7c8744b6f6308198e4a9bf9baea4a673bafedd49f35824eeb3947"].into(), 9795048450282732123u128),
hex!["9aceaa2fa9e3226bbe106cd0150f9807b089281b16942bff471caa1359aa8a22"].into(), (hex!["385a826ba8113391c26d03c8bf3d911ce8f20a523ba19da996926e401226e921"].into(), 1048508876174623538u128),
1360508232557032475u128, (hex!["e82bad686d3318e72e36bfe9776e197ae04b60fc140b7a221fbf1b730e9b0162"].into(), 898508876174623538u128),
), (hex!["8a0bb3642b563b842649ca9870ddb8efb67d0bc3b128df0d59e7bd5f1c19db22"].into(), 297635726269865672u128),
( (hex!["8e18636616b2f67f20469a71d7f6508fd2e2f045742e6ba5d80b2a0782b2ae50"].into(), 3072300000000000000u128),
hex!["661fd59a3748d65d66d9612f0c8f5871029e8e74deb3c0e1fbdbcf3c04e84a5e"].into(), (hex!["08c04b4b3540dff6e2e489a888f336f1f09c7a648b19194836584ecafe74f632"].into(), 962544380873117722u128),
246508876174623538u128, (hex!["30acd0fd37df7b6b9dca64287fe3bf0ad3563ad2868567170b79d48a2be1905d"].into(), 10233781528150093525u128),
), (hex!["46c78fcacffd80abc9cca4917ef8369a37e21a1691ca11e7a3b53f80be745313"].into(), 7147764927833644204u128),
( (hex!["e8c8d51024385be1fa0e5003a6725626d96f7b02fdc0a289bdef2095a2170039"].into(), 461545504698494152u128),
hex!["d02a399ba8d6efe950c0c6557606b8b13147b353c11f4495a2cba2a396e7be2f"].into(), (hex!["a0746c5aee539430c94f18adc4a723d3216e348a5e770bd65c70c8e2655e4f73"].into(), 12197794185639438614u128),
29163375134216277028u128, (hex!["da59bcd9273cea92f120a9a9a5a5148a551decb191588dc949331d6badf29a19"].into(), 9490654217464110064u128),
), (hex!["3482a145ab988dfd56683d2ca621a900656188eef040c92e8dbc45288fa51409"].into(), 12923631455237538822u128),
( (hex!["96b26d15a812e30bc0dae710eb6ab9ce0c82a450e8eeb94c19c9ee0483ed907c"].into(), 3389562133222364766u128),
hex!["20fed126411d5d1a1ab3915bffac49297b0eae9dcf4288589c0cad49d925637b"].into(), (hex!["8610f2ee704cb43240f62a9d7aafa91e31168976c4f91ce7f87db37f42db2953"].into(), 1702544380873117690u128),
5963508876174623538u128, (hex!["96cd8b97a9256ee5ddac3d5d4e128544041d041957815f415d33e51212e5794d"].into(), 1396585066737448782u128),
), (hex!["b0d88e3974dd9b8e2b5919bb3eaca3241bc3ceca163df036ea539528121cde36"].into(), 12804373197912707987u128),
( (hex!["8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13"].into(), 3909659906201812974u128),
hex!["eeaaf5db1b1eb55cc8c1b26c5092868ada9af63c2961bba4d4b5d63e99371c00"].into(), (hex!["40ad428cb7a2530fc0c38ab879e7f5d54f25cd757cfcb21f46cb023d413eb916"].into(), 236636628523870614u128),
11725156115646367945u128, (hex!["4cec57aebb419ab80b7d8b699024eaaa9016bb2b90821f18303abebe87b4983e"].into(), 15265761957965221177u128),
), (hex!["2c2d1ac621c332cc1b8e5c1bfc5b1c00c61e9767e8fcf96b1852bb39940fa209"].into(), 97016443351365356u128),
( (hex!["6ea653659d6a5e6f3fa95b2ffa4acad62233f91d2dc323632a3fa5c9fc7b533a"].into(), 12393794455887420639u128),
hex!["ac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50"].into(), (hex!["f614e6494fbb66397fe4c799971be187183d85996ac08c2ba37d666635fd0f7d"].into(), 14633565813546398869u128),
7523053899371678858u128, (hex!["24fae36f401bf052057d4a011dc8b9ec40fcd9ef12a2823c9c8a2acbd40b906d"].into(), 2386381009396988304u128),
), (hex!["46b7889030d5f4653002b4b3cc50b031548c237e1b26639e26b66af113258c65"].into(), 12142098465731542975u128),
( (hex!["eefeff9e4cfa6e9d55128803895ff50e917f5601fda7f38f7aa71c48ee8a182c"].into(), 11439023815236597370u128),
hex!["144a1fa97fdba679efd2a36696a0d40f585b649143bb7da5cbd7458ea4a0f674"].into(), (hex!["4ec775d54f1e4d03524571e664108c5c7d8e256ac0b7a9566fe91a13fb489c1d"].into(), 9489578019617777151u128),
28761584046403187249u128, (hex!["2c1a2fcaaddeb083764fdd5364e961506807f295b7de086bfebcf85323ec3e6f"].into(), 13079350324389304724u128),
), (hex!["345ff8df58e39dbae032bfed1a3f5d41078376d57adb6cabd8b319fb817b892e"].into(), 14761261709701909726u128),
( (hex!["da6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702"].into(), 3496638131388321921u128),
hex!["a231498b31f698619d80746aa2049ec187c4a103a3c5a8940e14d1b03abe1239"].into(), (hex!["1a32c203646616b88f262569c5e52c8c45468c0b5ade90996af844a9971ddf31"].into(), 15811907815599745021u128),
1093016078816558319u128, (hex!["e261f574706b696fa627ca60abcd27d71e509d48955c7bd39cfe26a4dbd1a305"].into(), 10913969526740320780u128),
), (hex!["3484fb56e2660d6d91ef93f432777778dcff9df2f9cccf0672504dd71a705358"].into(), 898508876174623538u128),
( (hex!["fef9b143712fefdf6825c9d85a151c0ff526f978becf980da6f5b10f8dac6c47"].into(), 32731550000000000000u128),
hex!["d05b788865ffffdfbb7dfecd937188628a275926ab47742f84b5cda86e5d825d"].into(), (hex!["70ee2d1a6ae80d1fee15f47c646cbcbc9fa8dcf7365bfb5f7135daf9e4933312"].into(), 11375887786446002232u128),
4095526634890427372u128, (hex!["94715daf5090147de11f48aee9661c46f98b1215e3a4e54867344635c7e8cf68"].into(), 1000000000000000u128),
), (hex!["d2da442bc774b21bf0a2485bc6099e468765255363136b6517adda3d6ceb8e39"].into(), 11360623175679553528u128),
( (hex!["4e5dbd1516d69f4132e5ea96b7cf92799075c14a32f7995fb9d6f6ebed537d64"].into(), 898508876174623538u128),
hex!["7673ef8a48eaf9364831735201743d20587e27ff5ff2df42808e4625be6f656b"].into(), (hex!["dc3c2d888a41e766647e56ec7e9b71cc8db6553407be8646e35d4c0f803b9946"].into(), 118117752349247076u128),
899439876174623538u128, (hex!["b2c232a2c68b1b9094568fde28bca4b3845031b1afc386b4f6881c7c0162b00d"].into(), 931000000000000u128),
), (hex!["422f1935ec60c7e30ea45aa8b9f94adf9fc416887bdfb797860eae4d6ff2552c"].into(), 13280690314171744710u128),
( (hex!["728d8f346c9be14f387d1ce92598cee4becdb41d944ed0d77b9ee3d652e7ec62"].into(), 6258403189666179783u128),
hex!["6a92d2e77c6b56428db2129d33c3ba1e71c8a52315a65f03f30dbaf31224153d"].into(), (hex!["3e4c0237d057d92401fc9188893254f503d28af6b35535749f46420827de754d"].into(), 11870458022253848637u128),
708444482928862970u128, (hex!["4c19778e758d3f4763972e2b5119aee898a0c86b3f7dc2f4536f495b44f7a151"].into(), 93100000000000000u128),
), (hex!["484b5356ad84cc7ce4cbaf5e53c79c5d77195ad560810fa6d3fafc2145a04f69"].into(), 7634199999999999046u128),
( (hex!["80eca749f37cb93f00f5309552c26b2c70960452e11faa63d081090542aeac42"].into(), 15018816123219290155u128),
hex!["d8193ef891724c66a6cc58273eadcfb133f9bbc7d777e6456721a70e90ded71f"].into(), (hex!["585bde23981ce0400b174cf234c495114421bb01554344c63dc724357a6dac24"].into(), 35007104380873117690u128),
195510000000000000u128, (hex!["c02c41834889bf3fec8d38e25d976dcfde3e2e44ca1275c341b0ff7617a2f14c"].into(), 2976235504698494152u128),
), (hex!["328135c5defeeb32f3b3f90196108f56837bb1cb999033bf380464c20ede0d4e"].into(), 1670483976174623538u128),
( (hex!["1c96c3a56374256afa95ffa1c15cb9730d33d91fa4a8fa10b4053b166e714e68"].into(), 9310000000000000u128),
hex!["c256b6d62a54c94220ceb1b55f4afae84e59c913b8163d57791463d7ac67555c"].into(), (hex!["844ee060a2a94beb0c3a744d00093d1929a68f3b5acc2265e99375855bd60c00"].into(), 6979217752349247076u128),
13111614265582327685u128, (hex!["6083d585d458daed6a19c3258e311132ab786eb5144bb7b7dace2218522d274b"].into(), 931000000000000u128),
), (hex!["68c3d18fb07714cab1b1f8b5368e9c1e1f2b5f0e739c0602eeffc1669936ed02"].into(), 14676476815062037968u128),
( (hex!["5cb839c6a5e065e83b5dbf20d7082086a376586fe37fa7658cba71eda689c118"].into(), 11658791447719213988u128),
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,16 +9,10 @@ fn cli_version_works() {
.output() .output()
.unwrap(); .unwrap();
assert!( assert!(output.status.success(), "command returned with non-success exit code");
output.status.success(),
"command returned with non-success exit code"
);
let version = String::from_utf8_lossy(&output.stdout).trim().to_owned(); let version = String::from_utf8_lossy(&output.stdout).trim().to_owned();
assert_eq!( assert_eq!(version, format!("{} {}", crate_name, env!("CARGO_PKG_VERSION")));
version,
format!("{} {}", crate_name, env!("CARGO_PKG_VERSION"))
);
} }
#[test] #[test]
@ -31,10 +25,7 @@ fn cli_info_works() {
.output() .output()
.unwrap(); .unwrap();
assert!( assert!(output.status.success(), "command returned with non-success exit code");
output.status.success(),
"command returned with non-success exit code"
);
let info = String::from_utf8_lossy(&output.stdout).trim().to_owned(); let info = String::from_utf8_lossy(&output.stdout).trim().to_owned();
let v: Result<Value> = serde_json::from_str(&info); let v: Result<Value> = serde_json::from_str(&info);
let v = v.unwrap(); let v = v.unwrap();

View File

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

View File

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