Compare commits

..

No commits in common. "main" and "main-test" have entirely different histories.

19 changed files with 584 additions and 2148 deletions

16
Cargo.lock generated
View File

@ -1186,7 +1186,7 @@ dependencies = [
[[package]] [[package]]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.37" version = "3.5.35"
dependencies = [ dependencies = [
"casper-runtime-constants", "casper-runtime-constants",
"frame-benchmarking", "frame-benchmarking",
@ -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.5"
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.5"
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 #{:?}.",
@ -363,7 +347,6 @@ pub mod pallet {
TimeWentBackwards, TimeWentBackwards,
DisabledAuthority, DisabledAuthority,
ExecutedBlockIsHigher, ExecutedBlockIsHigher,
CommitInWrongSession,
} }
#[pallet::storage] #[pallet::storage]
@ -471,11 +454,13 @@ pub mod pallet {
#[pallet::hooks] #[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn offchain_worker(now: BlockNumberFor<T>) { fn offchain_worker(now: BlockNumberFor<T>) {
match Self::start_slow_clapping(now) { if let Err(e) = Self::start_slow_clapping(now) {
Ok(_) => { log::info!(
log::info!(target: LOG_TARGET, "👻 Slow Clap #{:?} finished gracefully", now) target: LOG_TARGET,
} "👻 Skipping slow clap at {:?}: {:?}",
Err(e) => log::info!(target: LOG_TARGET, "👻 Slow Clap #{:?} failed: {:?}", now, e), now,
e,
)
} }
} }
} }
@ -728,31 +713,19 @@ impl<T: Config> Pallet<T> {
fn try_commit_block(new_commitment: &BlockCommitment<NetworkIdOf<T>>) -> DispatchResult { fn try_commit_block(new_commitment: &BlockCommitment<NetworkIdOf<T>>) -> DispatchResult {
let authority_index = new_commitment.authority_index; let authority_index = new_commitment.authority_index;
let network_id = new_commitment.network_id; let network_id = new_commitment.network_id;
let session_index = T::ValidatorSet::session_index();
ensure!( ensure!(
T::NetworkDataHandler::get(&network_id).is_some(), T::NetworkDataHandler::get(&network_id).is_some(),
Error::<T>::UnregistedNetwork Error::<T>::UnregistedNetwork
); );
ensure!( let current_commits = BlockCommitments::<T>::try_mutate(
new_commitment.session_index == session_index,
Error::<T>::CommitInWrongSession,
);
let block_commitments = BlockCommitments::<T>::try_mutate(
&network_id, &network_id,
|current_commitments| -> Result<BTreeMap<AuthIndex, CommitmentDetails>, DispatchError> { |current_commitments| -> Result<u64, DispatchError> {
let mut new_commitment_details = new_commitment.commitment; let mut new_commitment_details = new_commitment.commitment;
let (current_commits, current_last_updated) = current_commitments let (current_commits, current_last_updated) = current_commitments
.get(&authority_index) .get(&authority_index)
.map(|details| { .map(|details| (details.commits + 1, details.last_updated))
(
details.commits.saturating_add(1),
details.last_updated.saturating_add(COMMITMENT_DELAY_MILLIS),
)
})
.unwrap_or((1, 0)); .unwrap_or((1, 0));
ensure!( ensure!(
@ -763,21 +736,19 @@ impl<T: Config> Pallet<T> {
new_commitment_details.commits = current_commits; new_commitment_details.commits = current_commits;
current_commitments.insert(authority_index, new_commitment_details); current_commitments.insert(authority_index, new_commitment_details);
Ok(current_commitments.clone()) Ok(current_commits)
}, },
)?; )?;
let current_commits = block_commitments
.get(&authority_index)
.map(|details| details.commits)
.unwrap_or(1);
Self::deposit_event(Event::<T>::BlockCommited { Self::deposit_event(Event::<T>::BlockCommited {
network_id, network_id,
authority_id: authority_index, authority_id: authority_index,
}); });
let session_index = T::ValidatorSet::session_index();
let validators = Validators::<T>::get(&session_index); let validators = Validators::<T>::get(&session_index);
let block_commitments = BlockCommitments::<T>::get(&network_id);
let disabled_bitmap = DisabledAuthorityIndexes::<T>::get(&session_index) let disabled_bitmap = DisabledAuthorityIndexes::<T>::get(&session_index)
.unwrap_or(BitMap::new(validators.len() as u32)); .unwrap_or(BitMap::new(validators.len() as u32));
@ -789,7 +760,7 @@ impl<T: Config> Pallet<T> {
}) })
.unwrap_or_default(); .unwrap_or_default();
if current_commits % 3 == 0 && validators.len() > 0 { if current_commits > 2 && validators.len() > 0 {
let offence_bitmap = Self::capture_deviation_in_commitments_and_remove( let offence_bitmap = Self::capture_deviation_in_commitments_and_remove(
&disabled_bitmap, &disabled_bitmap,
&block_commitments, &block_commitments,
@ -812,45 +783,46 @@ impl<T: Config> Pallet<T> {
fn start_slow_clapping(block_number: BlockNumberFor<T>) -> OffchainResult<T, ()> { fn start_slow_clapping(block_number: BlockNumberFor<T>) -> OffchainResult<T, ()> {
let session_index = T::ValidatorSet::session_index(); let session_index = T::ValidatorSet::session_index();
let networks = T::NetworkDataHandler::iter().collect::<Vec<_>>(); let networks_len = T::NetworkDataHandler::iter().count();
let network_index = block_number let network_in_use = T::NetworkDataHandler::iter()
.into() .nth(
.as_usize() block_number
.checked_rem(networks.len()) .into()
.unwrap_or_default(); .as_usize()
.checked_rem(networks_len)
let network_in_use = networks .unwrap_or_default(),
.iter() )
.nth(network_index)
.ok_or(OffchainErr::NoStoredNetworks)?; .ok_or(OffchainErr::NoStoredNetworks)?;
log::info!( let network_id_encoded = network_in_use.0.encode();
target: LOG_TARGET,
"👻 Slow Clap #{:?} started for network #{:?}", let rate_limit_delay_key = Self::create_storage_key(b"rate-limit-", &network_id_encoded);
block_number, let rate_limit_delay = Self::read_persistent_offchain_storage(
network_in_use.0, &rate_limit_delay_key,
network_in_use.1.rate_limit_delay,
); );
let network_id_encoded = network_in_use.0.encode();
let network_lock_key = Self::create_storage_key(b"network-lock-", &network_id_encoded); let network_lock_key = Self::create_storage_key(b"network-lock-", &network_id_encoded);
let lock_until = rt_offchain::Duration::from_millis(MIN_LOCK_GUARD_PERIOD); let block_until =
let mut network_lock = StorageLock::<Time>::with_deadline(&network_lock_key, lock_until); rt_offchain::Duration::from_millis(rate_limit_delay.max(MIN_LOCK_GUARD_PERIOD));
let mut network_lock = StorageLock::<Time>::with_deadline(&network_lock_key, block_until);
let _lock_guard = network_lock let _lock_guard = network_lock
.try_lock() .try_lock()
.map_err(|_| OffchainErr::OffchainTimeoutPeriod(network_in_use.0))?; .map_err(|_| OffchainErr::OffchainTimeoutPeriod(network_in_use.0))?;
Self::do_evm_claps_or_save_block( log::info!(
session_index, target: LOG_TARGET,
block_number, "👻 Offchain worker started for network #{:?} at block #{:?}",
network_in_use.0, network_in_use.0,
&network_in_use.1, block_number,
) );
Self::do_evm_claps_or_save_block(session_index, network_in_use.0, &network_in_use.1)
} }
fn do_evm_claps_or_save_block( fn do_evm_claps_or_save_block(
session_index: SessionIndex, session_index: SessionIndex,
block_number: BlockNumberFor<T>,
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
network_data: &NetworkData, network_data: &NetworkData,
) -> OffchainResult<T, ()> { ) -> OffchainResult<T, ()> {
@ -869,59 +841,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();
let request_body = if from_block < to_block.saturating_sub(1) {
Self::prepare_request_body_for_latest_transfers(
from_block,
to_block.saturating_sub(1),
network_data,
)
} else {
Self::prepare_request_body_for_latest_block(network_data)
};
let response_bytes = Self::fetch_from_remote(&rpc_endpoint, &request_body)?;
match network_data.network_type { match network_data.network_type {
NetworkType::Evm => { NetworkType::Evm => {
let request_body = if from_block < to_block.saturating_sub(1) { let parsed_evm_response = Self::parse_evm_response(&response_bytes)?;
Self::prepare_evm_request_body_for_latest_transfers(
from_block,
to_block.saturating_sub(1),
network_data,
)
} else {
Self::prepare_evm_request_body_for_latest_block(network_data)
};
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)?;
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 +899,14 @@ impl<T: Config> Pallet<T> {
log::info!( log::info!(
target: LOG_TARGET, target: LOG_TARGET,
"👻 Offchain worker #{:?} stored block #{:?} for network {:?}", "👻 Stored from_block is #{:?} for network {:?}",
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 +926,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 +960,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) { .add_header("Accept", "application/json")
Ok(rpc_endpoint_str) => rpc_endpoint_str, .add_header("Content-Type", "application/json")
Err(_) => { .deadline(deadline)
log::info!( .send()
target: LOG_TARGET, .map_err(|err| OffchainErr::HttpRequestError(err))?;
"👻 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]) let response = pending
.add_header("Accept", "application/json") .try_wait(deadline)
.add_header("Content-Type", "application/json") .map_err(|_| OffchainErr::RequestUncompleted)?
.deadline(deadline) .map_err(|_| OffchainErr::RequestUncompleted)?;
.send()
{ if response.code != 200 {
Ok(pending) => pending_requests.push(pending), return Err(OffchainErr::HttpResponseNotOk(response.code));
Err(_) => {
log::info!(
target: LOG_TARGET,
"👻 Request skipped: failed to send request to \"{}\"",
rpc_endpoint_str,
)
}
}
} }
if pending_requests.len() == 0 { Ok(response.body().collect::<Vec<u8>>())
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( fn prepare_request_body_for_latest_block(network_data: &NetworkData) -> Vec<u8> {
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 {
responses_non_200 += 1;
return None;
}
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_evm_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 +997,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,
@ -1273,7 +1076,7 @@ impl<T: Config> Pallet<T> {
debug_assert!(cursor.maybe_cursor.is_none()); debug_assert!(cursor.maybe_cursor.is_none());
} }
fn calculate_median_value(values: &mut Vec<(AuthIndex, u64)>) -> u64 { fn calculate_weighted_median(values: &mut Vec<(AuthIndex, u64)>) -> u64 {
values.sort_by_key(|data| data.1); values.sort_by_key(|data| data.1);
let length = values.len(); let length = values.len();
@ -1321,8 +1124,8 @@ impl<T: Config> Pallet<T> {
time_updates.push((authority_index, data.last_updated)); time_updates.push((authority_index, data.last_updated));
} }
let stored_block_median = Self::calculate_median_value(&mut stored_blocks); let stored_block_median = Self::calculate_weighted_median(&mut stored_blocks);
let time_update_median = Self::calculate_median_value(&mut time_updates); let time_update_median = Self::calculate_weighted_median(&mut time_updates);
Self::apply_median_deviation( Self::apply_median_deviation(
&mut delayed, &mut delayed,
@ -1409,9 +1212,8 @@ impl<T: Config> Pallet<T> {
}) })
.collect::<Vec<IdentificationTuple<T>>>(); .collect::<Vec<IdentificationTuple<T>>>();
let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap);
let not_enough_validators_left = validator_set_count let not_enough_validators_left = validator_set_count
.saturating_sub(disabled_or_offence_bitmap.count_ones()) .saturating_sub(disabled_bitmap.bitor(offence_bitmap).count_ones())
.lt(&T::MinAuthoritiesNumber::get()); .lt(&T::MinAuthoritiesNumber::get());
if not_enough_validators_left && offenders.len() > 0 { if not_enough_validators_left && offenders.len() > 0 {
@ -1446,17 +1248,7 @@ impl<T: Config> Pallet<T> {
offence_type, offence_type,
}; };
let reporters = validators if let Err(e) = T::ReportUnresponsiveness::report_offence(vec![], offence) {
.into_iter()
.enumerate()
.filter_map(|(index, _)| {
(!disabled_or_offence_bitmap.exists(&(index as AuthIndex)))
.then(|| T::ExposureListener::get_account_by_index(index))
.flatten()
})
.collect();
if let Err(e) = T::ReportUnresponsiveness::report_offence(reporters, offence) {
sp_runtime::print(e); sp_runtime::print(e);
} }
} }
@ -1582,10 +1374,10 @@ impl<Offender: Clone> Offence<Offender> for SlowClapOffence<Offender> {
missed_percent.saturating_mul(Perbill::from_rational(1, offenders_count)) missed_percent.saturating_mul(Perbill::from_rational(1, offenders_count))
} }
OffenceType::CommitmentOffence => offenders_count OffenceType::CommitmentOffence => offenders_count
.checked_sub(Perbill::from_percent(9).mul_ceil(self.validator_set_count)) .checked_sub(self.validator_set_count / 10 + 1)
.map(|threshold| { .map(|threshold| {
Perbill::from_rational(threshold.saturating_mul(4), self.validator_set_count) Perbill::from_rational(3 * threshold, self.validator_set_count)
.square() .saturating_mul(Perbill::from_percent(7))
}) })
.unwrap_or_default(), .unwrap_or_default(),
} }

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};
@ -32,7 +31,7 @@ fn should_calculate_throttling_slash_function_correctly() {
let dummy_offence = SlowClapOffence { let dummy_offence = SlowClapOffence {
session_index: 0, session_index: 0,
validator_set_count: 100, validator_set_count: 50,
offenders: vec![()], offenders: vec![()],
offence_type: OffenceType::CommitmentOffence, offence_type: OffenceType::CommitmentOffence,
}; };
@ -40,22 +39,13 @@ fn should_calculate_throttling_slash_function_correctly() {
assert_eq!(dummy_offence.slash_fraction(1), Perbill::zero()); assert_eq!(dummy_offence.slash_fraction(1), Perbill::zero());
assert_eq!(dummy_offence.slash_fraction(5), Perbill::zero()); assert_eq!(dummy_offence.slash_fraction(5), Perbill::zero());
assert_eq!( assert_eq!(
dummy_offence.slash_fraction(15), dummy_offence.slash_fraction(7),
Perbill::from_parts(57_600_000) Perbill::from_parts(4_200_000)
); );
assert_eq!( assert_eq!(
dummy_offence.slash_fraction(20), dummy_offence.slash_fraction(17),
Perbill::from_parts(193_600_000) Perbill::from_parts(46_200_000)
); );
assert_eq!(
dummy_offence.slash_fraction(25),
Perbill::from_parts(409_600_000)
);
assert_eq!(
dummy_offence.slash_fraction(30),
Perbill::from_parts(705_600_000)
);
assert_eq!(dummy_offence.slash_fraction(50), Perbill::one());
} }
#[test] #[test]
@ -138,6 +128,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 +146,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 +164,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 +181,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 +201,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 +224,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 +254,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 +276,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);
@ -1182,8 +1008,8 @@ fn should_disable_on_commitment_inactivity() {
}; };
// two block commitments // two block commitments
for extra_time in 1..=3 { for extra_time in 0..=2 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time; block_commitment.last_updated += extra_time;
for i in 0..3 { for i in 0..3 {
assert_ok!(do_block_commitment( assert_ok!(do_block_commitment(
session_index, session_index,
@ -1240,9 +1066,9 @@ fn should_disable_on_commitment_block_deviation() {
}; };
// two block commitments // two block commitments
for extra_time in 1..=3 { for extra_time in 0..=2 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time; block_commitment.last_updated += extra_time;
bad_block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time; bad_block_commitment.last_updated += extra_time;
for i in 0..3 { for i in 0..3 {
assert_ok!(do_block_commitment( assert_ok!(do_block_commitment(
session_index, session_index,
@ -1267,73 +1093,6 @@ fn should_disable_on_commitment_block_deviation() {
}); });
} }
#[test]
fn should_throw_error_on_fast_commitments() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
assert_ok!(do_block_commitment(
session_index,
network_id,
0,
&block_commitment
));
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS / 2;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS / 2;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
block_commitment.last_updated += 1;
assert_ok!(do_block_commitment(
session_index,
network_id,
0,
&block_commitment
));
block_commitment.last_updated = timestamp;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 9_500_000);
assert_eq!(
commitment_details.last_updated,
timestamp + COMMITMENT_DELAY_MILLIS + 1
);
assert_eq!(commitment_details.commits, 2);
}
});
}
#[test] #[test]
fn should_not_offend_disabled_authorities() { fn should_not_offend_disabled_authorities() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None); let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
@ -1360,8 +1119,8 @@ fn should_not_offend_disabled_authorities() {
Session::disable_index(3); Session::disable_index(3);
// two block commitments // two block commitments
for extra_time in 1..=3 { for extra_time in 0..=2 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time; block_commitment.last_updated += extra_time;
for i in 0..3 { for i in 0..3 {
assert_ok!(do_block_commitment( assert_ok!(do_block_commitment(
session_index, session_index,
@ -1405,8 +1164,8 @@ fn should_not_slash_by_applause_if_disabled_by_commitment() {
Session::disable_index(3); Session::disable_index(3);
// two block commitments // two block commitments
for extra_time in 1..=3 { for extra_time in 0..=2 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time; block_commitment.last_updated += extra_time;
for i in 0..3 { for i in 0..3 {
assert_ok!(do_block_commitment( assert_ok!(do_block_commitment(
session_index, session_index,
@ -1444,18 +1203,20 @@ fn should_not_nullify_on_incorrect_block_commitment() {
for i in 0..4 { for i in 0..4 {
assert_ok!(do_block_commitment( assert_ok!(do_block_commitment(
session_index, session_index,
network_id, network_id,
i, i,
&block_commitment &block_commitment
)); ));
} }
block_commitment.last_updated = 0; block_commitment.last_updated = 0;
assert_err!( assert_err!(do_block_commitment(
do_block_commitment(session_index, network_id, 3, &block_commitment), session_index,
Error::<Runtime>::TimeWentBackwards network_id,
); 3,
&block_commitment),
Error::<Runtime>::TimeWentBackwards);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() { for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 9_500_000); assert_eq!(commitment_details.last_stored_block, 9_500_000);
@ -1465,202 +1226,6 @@ fn should_not_nullify_on_incorrect_block_commitment() {
}); });
} }
#[test]
fn should_split_commit_slash_between_active_validators() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
for extra_time in 1..=3 {
if extra_time < 3 {
let offences = Offences::get();
assert_eq!(offences.len(), 0);
}
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
));
}
}
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::SomeAuthoritiesDelayed {
delayed: vec![(3, 3)],
},
));
let offences = Offences::get();
assert_eq!(offences.len(), 3);
for offence in offences {
assert_eq!(offence.0, vec![0, 1, 2]);
assert_eq!(offence.1.session_index, session_index);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offenders, vec![(3, 3)]);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offence_type, OffenceType::CommitmentOffence);
}
});
}
#[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 +1442,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 +1450,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 +1507,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

@ -1,6 +1,6 @@
[package] [package]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.37" version = "3.5.35"
build = "build.rs" build = "build.rs"
description = "Runtime of the Casper Network" description = "Runtime of the Casper Network"
edition.workspace = true edition.workspace = true

View File

@ -117,8 +117,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("casper"), spec_name: create_runtime_str!("casper"),
impl_name: create_runtime_str!("casper-svengali"), impl_name: create_runtime_str!("casper-svengali"),
authoring_version: 0, authoring_version: 0,
spec_version: 4, spec_version: 3,
impl_version: 3, impl_version: 1,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
transaction_version: 1, transaction_version: 1,
state_version: 1, state_version: 1,

View File

@ -1,21 +1,2 @@
#!/bin/bash
EXIT_CODE=0
SCRIPT_DIR=$(dirname "$0") SCRIPT_DIR=$(dirname "$0")
PATCHES_DIR="$SCRIPT_DIR/patches" bash "$SCRIPT_DIR/patches/patch-1.sh"
if [[ ! -d "$PATCHES_DIR" ]]; then
echo "[-] Error: directory with patches not found: $PATCHES_DIR"
exit 1
fi
for patch_file in "$PATCHES_DIR"/*.sh; do
if [ -f "$patch_file" ] && [ -x "$patch_file" ]; then
"$patch_file" "$1"
if [ $? -eq 2 ]; then
EXIT_CODE=2
fi
fi
done
exit $EXIT_CODE

View File

@ -1,26 +1,32 @@
#!/bin/bash DEFAULT_SERVICE_NAME="ghost-node.service"
SERVICE_NAME="${2:-ghost-node.service}" check_unit_file_validity() {
SERVICE_NAME=$1
if [[ "$SERVICE_NAME" != *.service ]]; then
SERVICE_NAME="${SERVICE_NAME}.service"
fi
if [[ "$SERVICE_NAME" != *.service ]]; then SERVICE_FULL_PATH="/etc/systemd/system/$SERVICE_NAME"
SERVICE_NAME="${SERVICE_NAME}.service" if [[ -e "$SERVICE_FULL_PATH" ]]; then
fi NETWORK_ONLINE_EXISTS=$(grep -Fx "After=network-online.target" "$SERVICE_FULL_PATH")
NETWORK_EXISTS=$(grep -Fx "After=network.target" "$SERVICE_FULL_PATH")
SERVICE_FULL_PATH="/etc/systemd/system/$SERVICE_NAME" if [[ -z "$NETWORK_ONLINE_EXISTS" && -n "$NETWORK_EXISTS" ]]
SKIPPED_NO_SERVICE="[-] patch-1 skipped: no serivce found at $SERVICE_FULL_PATH" then
[[ ! -e "$SERVICE_FULL_PATH" ]] && { echo $SKIPPED_NO_SERVICE; exit 1; } echo "[-] WARNING: missing network-online.target dependency in $SERVICE_FULL_PATH, trying to replace"
sudo sed -i "s/After=network.target/After=network-online.target\nRequires=network-online.target/g" "$SERVICE_FULL_PATH"
else
echo "[+] INFO: network-online.target is set correctly for $SERVICE_FULL_PATH"
fi
else
echo "[-] No serivce found at $SERVICE_FULL_PATH"
fi
NETWORK_ONLINE_EXISTS=$(grep -Fx "After=network-online.target" "$SERVICE_FULL_PATH") }
NETWORK_EXISTS=$(grep -Fx "After=network.target" "$SERVICE_FULL_PATH")
SKIPPED_SERVICE_OK="[+] patch-1 already applied: network-online.target is set correctly for $SERVICE_FULL_PATH" check_unit_file_validity $DEFAULT_SERVICE_NAME
[[ ! (-z "$NETWORK_ONLINE_EXISTS" && -n "$NETWORK_EXISTS") ]] && { echo $SKIPPED_SERVICE_OK; exit 0; } read -p "[?] Enter names for the node service, separated by commas (default: ghost-node): " -a SERVICE_NAMES
for NAME in "${SERVICE_NAMES[@]}"; do
PATCH_MESSAGE="missing network-online.target dependency in $SERVICE_FULL_PATH" check_unit_file_validity $NAME
[[ -z "$1" ]] && { echo "[!] patch-1 could be applied: $PATCH_MESSAGE"; exit 2; } done
sudo systemctl daemon-reload
echo "[+] patch-1 will be applied: $PATCH_MESSAGE"
sudo sed -i "s/After=network.target/After=network-online.target\nRequires=network-online.target/g" "$SERVICE_FULL_PATH"
echo "sudo systemctl daemon-reload"
echo "sudo systemctl restart $SERVICE_NAME"
exit 0

View File

@ -1,26 +0,0 @@
#!/bin/bash
LATEST_TESTED_VERSION=83
MANIFEST_PATH=$(cargo metadata --format-version 1 | python3 -c "
import sys,json
data = json.load(sys.stdin)
for pkg in data['packages']:
if pkg['name'] == 'sp-io':
print(pkg['manifest_path'])
break
")
DEPENDENCY_PATH="${MANIFEST_PATH%Cargo.toml}src/lib.rs"
SKIPPED_PATCH_OK="[+] patch-2 not needed: rustc compiler version is compatible"
cargo_version=$(cargo --version | cut -d'.' -f2)
[[ "$cargo_version" -le "$LATEST_TESTED_VERSION" ]] && { echo $SKIPPED_PATCH_OK; exit 0; }
SKIPPED_PATCH_OK="[+] patch-2 already applied: #[no_mangle] already removed from source code of sp-io"
! grep -q '#\[no_mangle\]' "$DEPENDENCY_PATH" && { echo $SKIPPED_PATCH_OK; exit 0; }
PATCH_MESSAGE="remove unnecessary #[no_mangle] from the source code for sp-io"
[[ -z "$1" ]] && { echo "[!] patch-2 could be applied: $PATCH_MESSAGE"; exit 2; }
echo "[+] patch-2 will be applied: $PATCH_MESSAGE"
sed -i '/#\[no_mangle\]/d' "$DEPENDENCY_PATH"
exit 0

View File

@ -1,19 +0,0 @@
#!/bin/bash
LATEST_GCC_WORKING_VERSION=14
PATH_TO_BUILD_CONFIG=~/.local/share/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/librocksdb-sys-0.11.0+8.1.1/build.rs
GCC_MAJOR=$(gcc -dumpversion | cut -d. -f1)
SKIPPED_PATCH_OK="[+] patch-3 not needed: gcc version is good to compile without patch"
[[ "$GCC_MAJOR" -le "$LATEST_GCC_WORKING_VERSION" ]] && { echo $SKIPPED_PATCH_OK; exit 0; }
SKIPPED_PATCH_OK="[+] patch-3 already applied: no need to change build config of librocksdb"
grep -q "config.flag(\"-include\").flag(\"cstdint\");" "$PATH_TO_BUILD_CONFIG" && { echo $SKIPPED_PATCH_OK; exit 0; }
PATCH_MESSAGE="include cstdint for build config of librocksdb"
[[ -z "$1" ]] && { echo "[!] patch-3 could be applied: $PATCH_MESSAGE"; exit 2; }
sed -i "/$(printf '%s' "config.compile(\"librocksdb.a\");" | sed 's/[].[*^$\/]/\\&/g')/i \
if !target.contains(\"windows\") {\n config.flag(\"-include\").flag(\"cstdint\");\n }" "$PATH_TO_BUILD_CONFIG"
echo "[+] patch-3 will be applied: $PATCH_MESSAGE"
exit 0

View File

@ -1,136 +0,0 @@
#!/bin/bash
SEPOLIA_RPC=(
"https://sepolia.drpc.org"
"https://sepolia.gateway.tenderly.co"
"https://api.zan.top/eth-sepolia"
"https://rpc.sepolia.ethpandaops.io"
"https://ethereum-sepolia-rpc.publicnode.com"
"https://1rpc.io/sepolia"
"https://0xrpc.io/sep"
"https://eth-sepolia.api.onfinality.io/public"
)
MORDOR_RPC=(
"https://0xrpc.io/mordor"
"https://geth-mordor.etc-network.info"
"https://rpc.mordor.etccooperative.org"
)
show_help() {
cat << EOF
Usage: $(basename "$0") [OPTIONS]
Options:
--chain <name> Specify network: 'sepolia' or 'mordor'. If omitted, checks both.
--output <dir> Base directory to save results. Creates a subfolder with Unix Timestamp.
--rpcs <urls> Comma-separated list of custom RPC endpoints.
Disables default Sepolia/Mordor lists.
--help Show this help message.
Example:
$0 --chain sepolia --output ./logs
EOF
exit 0
}
spinner() {
local pid=$1
local net_name=$2
local delay=0.1
local spinstr='|/-\'
tput civis
while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do
local temp=${spinstr#?}
printf "\r [%c] Checking %s... " "$spinstr" "$net_name"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
done
printf " \r"
tput cnorm
}
check_network() {
local name=$1
shift
local rpcs=("$@")
local target_dir="${OUT_DIR:-/tmp}"
local tmp_file="${target_dir}/$(date +%s)_${name,,}"
local max_len=0
for e in "${rpcs[@]}"; do (( ${#e} > max_len )) && max_len=${#e}; done
[[ $max_len -lt 20 ]] && max_len=20
local total_width=$(( max_len + 32 ))
local line=$(printf "%.0s-" $(seq 1 $total_width))
local header_fmt="| %-${max_len}s | %-12s | %-10s |\n"
(
for endpoint in "${rpcs[@]}"; do
res_b=$(curl -s -X POST -H "Content-Type: application/json" --max-time 10 \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' "$endpoint")
hex=$(echo "$res_b" | grep -o '"result":"[^"]*' | cut -d'"' -f4)
[[ -n "$hex" && "$hex" != "null" ]] && blk=$(printf "%d" "$hex") || blk="ERROR"
res_l=$(curl -s -X POST -H "Content-Type: application/json" --max-time 10 \
--data '{"jsonrpc":"2.0","method":"eth_getLogs","params":[{"fromBlock":"0x1","toBlock":"0x2"}],"id":1}' "$endpoint")
echo "$res_l" | grep -q '"result"' && ev="YES" || ev="NO"
echo "$endpoint|$blk|$ev"
done
) > "$tmp_file" &
local worker_pid=$!
if [[ -z "$OUT_DIR" ]]; then
spinner $worker_pid "$name"
local table_output="$line\n"
table_output+=$(printf "$header_fmt" "Endpoint" "Block" "Events")"\n"
table_output+="$line\n"
while IFS="|" read -r url blk ev; do
table_output+=$(printf "$header_fmt" "$url" "$blk" "$ev")"\n"
done < "$tmp_file"
table_output+="$line"
echo -e "$table_output"
rm "$tmp_file"
else
wait $worker_pid
fi
}
CHOSEN_CHAIN=""
BASE_OUT_DIR=""
CUSTOM_RPCS=""
while [[ $# -gt 0 ]]; do
case "$1" in
--help) show_help ;;
--chain) CHOSEN_CHAIN="$2"; shift 2 ;;
--output) BASE_OUT_DIR="$2"; shift 2 ;;
--rpcs) CUSTOM_RPCS="$2"; shift 2 ;;
*) echo "Unknown option: $1. Use --help for usage."; exit 1 ;;
esac
done
if [[ -n "$BASE_OUT_DIR" ]]; then
OUT_DIR="${BASE_OUT_DIR}"
mkdir -p "$OUT_DIR"
fi
if [[ -n "$CUSTOM_RPCS" ]]; then
IFS=',' read -r -a USER_RPC_ARRAY <<< "$CUSTOM_RPCS"
check_network "Custom" "${USER_RPC_ARRAY[@]}"
else
if [ "$CHOSEN_CHAIN" == "sepolia" ]; then
check_network "Sepolia" "${SEPOLIA_RPC[@]}"
elif [ "$CHOSEN_CHAIN" == "mordor" ]; then
check_network "Mordor" "${MORDOR_RPC[@]}"
else
check_network "Sepolia" "${SEPOLIA_RPC[@]}"
check_network "Mordor" "${MORDOR_RPC[@]}"
fi
fi

View File

@ -80,35 +80,27 @@ extract_seed() {
echo $seed echo $seed
} }
upgrade_compiler_if_needed() { downgrade_compiler_if_needed() {
UPDATE_STATUS=$(rustup check 2>&1) echo "[+] fetching the latest ghost-node source code"
"$SCRIPT_FOLDER"/patch.sh || PATCH_STATUS=$? git switch main
git pull origin main
if echo "$UPDATE_STATUS" | grep -q "Update available" || [ $PATCH_STATUS -eq 2 ]; then # 1.86.0 works fine, tested with:
echo "[+] clean all cache on the current system" # 1.87.0 throws errors during compilation
cargo install cargo-cache # 1.88.0 throws errors during compilation
cargo clean LATEST_TESTED_VERSION=86
cargo cache --remove-dir all cargo_version=$(cargo --version | cut -d'.' -f2)
if [ "$cargo_version" -gt "$LATEST_TESTED_VERSION" ]; then
echo "[+] upgrading rustc compiler version to latest" echo "[+] downgrading rustc compiler version to 1.86.0"
rustup update rustup default 1.86.0
toolchain_name=$(rustup show | grep default | head -n 1 | cut -d' ' -f1) toolchain_name=$(rustup show | grep default | head -n 1 | cut -d' ' -f1)
rustup target add wasm32-unknown-unknown --toolchain $toolchain_name
if ! rustup target list --installed | grep -q "wasm32-unknown-unknown"; then rustup component add rust-src --toolchain $toolchain_name
echo "[+] installing wasm32-unknown-unknown target" cd $PROJECT_FOLDER
rustup target add wasm32-unknown-unknown echo "[+] clean build cache..."
fi cargo clean
else
if ! rustup component list --installed | grep -q "rust-src"; then echo "[+] rustc compiler version is compatible"
echo "[+] installing rust-src component"
rustup component add rust-src
fi
echo "[+] fetching all dependencies"
cargo fetch
echo "[+] trying to apply all patches"
"$SCRIPT_FOLDER"/patch.sh apply
fi fi
} }
@ -217,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
@ -231,7 +219,7 @@ if [[ $HARD_RESET = true ]]; then
exit 1 exit 1
fi fi
upgrade_compiler_if_needed downgrade_compiler_if_needed
echo "[+] trying to stop current ghost-node" echo "[+] trying to stop current ghost-node"
sudo systemctl stop ghost-node sudo systemctl stop ghost-node
@ -239,7 +227,6 @@ if [[ $HARD_RESET = true ]]; then
sudo rm -rf "$BASE_PATH/chains/casper_staging_testnet" sudo rm -rf "$BASE_PATH/chains/casper_staging_testnet"
cd $PROJECT_FOLDER cd $PROJECT_FOLDER
git switch main
git pull origin main git pull origin main
echo "[+] starting build in 3 seconds..." echo "[+] starting build in 3 seconds..."
sleep 3 sleep 3
@ -340,12 +327,12 @@ if [[ $SET_ENVIRONMENT = true ]]; then
if prompt "[?] setup the rust environment (e.g. WASM support)?"; then if prompt "[?] setup the rust environment (e.g. WASM support)?"; then
rustup default stable rustup default stable
upgrade_compiler_if_needed downgrade_compiler_if_needed
fi fi
fi fi
if [[ ! -z $RELEASE ]]; then if [[ ! -z $RELEASE ]]; then
upgrade_compiler_if_needed downgrade_compiler_if_needed
if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then
cd $PROJECT_FOLDER cd $PROJECT_FOLDER
echo "[+] starting build in 3 seconds..." echo "[+] starting build in 3 seconds..."

File diff suppressed because one or more lines are too long

View File

@ -190,55 +190,33 @@ 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(), default_endpoints: vec![
default_endpoints: vec![ "https://sepolia.drpc.org".into(),
"https://sepolia.drpc.org".into(), "https://sepolia.gateway.tenderly.co".into(),
"https://sepolia.gateway.tenderly.co".into(), "https://api.zan.top/eth-sepolia".into(),
"https://api.zan.top/eth-sepolia".into(), "https://rpc.sepolia.ethpandaops.io".into(),
"https://rpc.sepolia.ethpandaops.io".into(), "https://ethereum-sepolia-rpc.publicnode.com".into(),
"https://ethereum-sepolia-rpc.publicnode.com".into(), "https://1rpc.io/sepolia".into(),
"https://1rpc.io/sepolia".into(), "https://0xrpc.io/sep".into(),
"https://0xrpc.io/sep".into(), "https://eth-sepolia.api.onfinality.io/public".into(),
"https://eth-sepolia.api.onfinality.io/public".into(), ],
], finality_delay: 69u64,
finality_delay: 69u64, rate_limit_delay: 5_000u64,
rate_limit_delay: 5_000u64, block_distance: 20u64,
block_distance: 20u64, avg_block_speed: 12_000,
avg_block_speed: 12_000, network_type: ghost_networks::NetworkType::Evm,
network_type: ghost_networks::NetworkType::Evm, gatekeeper: "0xc85129A097773B7F8970a7364c928C05f265E6A1".into(),
gatekeeper: "0xc85129A097773B7F8970a7364c928C05f265E6A1".into(), 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(), .encode(),
2048861035254140036511u128, 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;