Compare commits

..

No commits in common. "43ec3492ef5509a8bca88d3d078a661d1a9d4d25" and "66bf42cbd35184683e094bf3fcd39fd38a33a8ba" have entirely different histories.

17 changed files with 198 additions and 247 deletions

10
Cargo.lock generated
View File

@ -3684,7 +3684,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-exodus" name = "ghost-exodus"
version = "0.0.8" version = "0.0.7"
dependencies = [ dependencies = [
"chacha20poly1305", "chacha20poly1305",
"frame-benchmarking", "frame-benchmarking",
@ -3733,7 +3733,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-governance" name = "ghost-governance"
version = "0.3.6" version = "0.3.5"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3757,7 +3757,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-helpers" name = "ghost-helpers"
version = "0.0.8" version = "0.0.6"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"ghost-traits", "ghost-traits",
@ -4085,7 +4085,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-traits" name = "ghost-traits"
version = "0.4.5" version = "0.4.4"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"frost-core", "frost-core",
@ -4109,7 +4109,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-weaver" name = "ghost-weaver"
version = "0.0.6" version = "0.0.4"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-exodus" name = "ghost-exodus"
version = "0.0.8" version = "0.0.7"
description = "Threshold signature generation with DKG included" description = "Threshold signature generation with DKG included"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -74,7 +74,7 @@ mod benchmarks {
c: Linear<4, { T::MaxAuthorities::get() }> c: Linear<4, { T::MaxAuthorities::get() }>
) -> Result<(), BenchmarkError> { ) -> Result<(), BenchmarkError> {
let max_signers = c as AuthIndex; let max_signers = c as AuthIndex;
let min_signers = get_byzantium_quorum_threshold(max_signers); let min_signers = get_byzantium_threshold(max_signers);
let (mut dkg_state, network_curve, authority, authority_index) = let (mut dkg_state, network_curve, authority, authority_index) =
prepare_pallet::<T>(max_signers as usize); prepare_pallet::<T>(max_signers as usize);
@ -637,7 +637,7 @@ mod benchmarks {
#[benchmark] #[benchmark]
fn register_signature_share() -> Result<(), BenchmarkError> { fn register_signature_share() -> Result<(), BenchmarkError> {
let max_signers = T::MaxAuthorities::get(); let max_signers = T::MaxAuthorities::get();
let threshold = get_byzantium_quorum_threshold(max_signers); let threshold = get_byzantium_threshold(max_signers);
let network_id: NetworkIdOf<T> = 69_420u64.unique_saturated_into(); let network_id: NetworkIdOf<T> = 69_420u64.unique_saturated_into();
let (mut dkg_state, network_curve, authority, authority_index) = let (mut dkg_state, network_curve, authority, authority_index) =

View File

@ -29,7 +29,7 @@ use sp_runtime::traits::BlockNumberProvider;
use sp_io::hashing::blake2_256; use sp_io::hashing::blake2_256;
use ghost_helpers::{ use ghost_helpers::{
get_byzantium_quorum_threshold, SubstrateBlake2Hasher, get_byzantium_threshold, SubstrateBlake2Hasher,
hash_chain::sequential_hash, hash_chain::sequential_hash,
networks::{NetworkData, NetworkCurve, NetworkType}, networks::{NetworkData, NetworkCurve, NetworkType},
bounded_bitmap::{validate_bitmap_sizes, BoundedBitmap}, bounded_bitmap::{validate_bitmap_sizes, BoundedBitmap},
@ -263,7 +263,7 @@ pub struct Round1MaxBytes<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> Get<u32> for Round1MaxBytes<T> { impl<T: Config> Get<u32> for Round1MaxBytes<T> {
fn get() -> u32 { fn get() -> u32 {
let max_authorities = T::MaxAuthorities::get(); let max_authorities = T::MaxAuthorities::get();
let min_authorities = get_byzantium_quorum_threshold(max_authorities); let min_authorities = get_byzantium_threshold(max_authorities);
round1_package_size( round1_package_size(
min_authorities as usize, min_authorities as usize,
@ -324,7 +324,7 @@ pub struct BindingFactorsProof<T>(sp_std::marker::PhantomData<T>);
impl<T: Config> Get<u32> for BindingFactorsProof<T> { impl<T: Config> Get<u32> for BindingFactorsProof<T> {
fn get() -> u32 { fn get() -> u32 {
let max_authorities = T::MaxAuthorities::get(); let max_authorities = T::MaxAuthorities::get();
get_byzantium_quorum_threshold(max_authorities) get_byzantium_threshold(max_authorities)
.next_power_of_two() .next_power_of_two()
.trailing_zeros() .trailing_zeros()
} }
@ -1422,7 +1422,7 @@ pub mod pallet {
}; };
let threshold = ActiveAuthorities::<T>::decode_len(&network_curve) let threshold = ActiveAuthorities::<T>::decode_len(&network_curve)
.map(|max_participants| get_byzantium_quorum_threshold(max_participants)) .map(|max_participants| get_byzantium_threshold(max_participants))
.ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?; .ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?;
let exodus_session = package.session; let exodus_session = package.session;
@ -1515,7 +1515,7 @@ pub mod pallet {
let max_authorities = ActiveAuthorities::<T>::decode_len(&network_curve) let max_authorities = ActiveAuthorities::<T>::decode_len(&network_curve)
.ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?; .ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?;
let threshold = get_byzantium_quorum_threshold(max_authorities); let threshold = get_byzantium_threshold(max_authorities);
let exodus_session = package.session; let exodus_session = package.session;
ensure!( ensure!(
@ -1633,7 +1633,7 @@ pub mod pallet {
}; };
let threshold = ActiveAuthorities::<T>::decode_len(&network_curve) let threshold = ActiveAuthorities::<T>::decode_len(&network_curve)
.map(|max_participants| get_byzantium_quorum_threshold(max_participants)) .map(|max_participants| get_byzantium_threshold(max_participants))
.ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?; .ok_or(Error::<T>::DkgAuthoritiesNotInitialized)?;
let exodus_session = package.session; let exodus_session = package.session;
@ -1898,7 +1898,7 @@ pub mod pallet {
None => return weight, None => return weight,
}; };
let min_threshold = get_byzantium_quorum_threshold(qualification_len); let min_threshold = get_byzantium_threshold(qualification_len);
weight.saturating_accrue(T::DbWeight::get().reads(1)); weight.saturating_accrue(T::DbWeight::get().reads(1));
let maybe_cursor = DkgMaybeCursor::<T>::get(&network_curve); let maybe_cursor = DkgMaybeCursor::<T>::get(&network_curve);
@ -2711,7 +2711,7 @@ impl<T: Config> Pallet<T> {
} }
let authorities = QualificationAuthorities::<T>::get(&network_curve); let authorities = QualificationAuthorities::<T>::get(&network_curve);
let expected_count = get_byzantium_quorum_threshold(authorities.len()); let expected_count = get_byzantium_threshold(authorities.len());
let expected_package_len = round1_package_size( let expected_package_len = round1_package_size(
expected_count, expected_count,
@ -3283,7 +3283,7 @@ impl<T: Config> Pallet<T> {
let max_authorities = ActiveAuthorities::<T>::decode_len(&network_curve) let max_authorities = ActiveAuthorities::<T>::decode_len(&network_curve)
.ok_or(ExodusError::NoActiveAuthorities)?; .ok_or(ExodusError::NoActiveAuthorities)?;
let threshold = get_byzantium_quorum_threshold(max_authorities); let threshold = get_byzantium_threshold(max_authorities);
let mut exodus_requests = ExodusRequests::<T>::iter_prefix(&network_curve) let mut exodus_requests = ExodusRequests::<T>::iter_prefix(&network_curve)
.collect::<Vec<(ExodusSession, ExodusRequest<_, _>)>>(); .collect::<Vec<(ExodusSession, ExodusRequest<_, _>)>>();
@ -3732,7 +3732,7 @@ impl<T: Config> Pallet<T> {
.map(|max_signers| max_signers as AuthIndex) .map(|max_signers| max_signers as AuthIndex)
.ok_or(ExodusError::InvalidMaxSigners(0))?; .ok_or(ExodusError::InvalidMaxSigners(0))?;
let min_signers = get_byzantium_quorum_threshold(max_signers); let min_signers = get_byzantium_threshold(max_signers);
if qualification_state.contains_index(authority_index) { if qualification_state.contains_index(authority_index) {
return Ok(ExodusOk::DkgRoundAlreadyPassed( return Ok(ExodusOk::DkgRoundAlreadyPassed(

View File

@ -841,7 +841,7 @@ fn run_dkg_session(
let threshold = ext.execute_with(|| { let threshold = ext.execute_with(|| {
let len = ActiveAuthorities::<Runtime>::decode_len(&curve) let len = ActiveAuthorities::<Runtime>::decode_len(&curve)
.unwrap_or(0); .unwrap_or(0);
get_byzantium_quorum_threshold(len) as u16 get_byzantium_threshold(len) as u16
}); });
let mut exodus_steps_outer = BTreeMap::new(); let mut exodus_steps_outer = BTreeMap::new();
@ -1259,7 +1259,7 @@ fn test_exodus_dkg_robustness() {
assert_eq!(state.get_dkg_index(), dkg_index); assert_eq!(state.get_dkg_index(), dkg_index);
assert_eq!(state.get_phase(), DkgPhase::Finalized); assert_eq!(state.get_phase(), DkgPhase::Finalized);
let bft_threshold = get_byzantium_quorum_threshold(authorities_len); let bft_threshold = get_byzantium_threshold(authorities_len);
assert!(qualification_count >= bft_threshold); assert!(qualification_count >= bft_threshold);
assert!(state.count_ones::<usize>() >= bft_threshold); assert!(state.count_ones::<usize>() >= bft_threshold);
assert_eq!(state.get_indexes().active_bits_count(), authorities_len as u32); assert_eq!(state.get_indexes().active_bits_count(), authorities_len as u32);
@ -1299,7 +1299,7 @@ fn test_prepare_round4_abort_on_byzantine_attack() {
} }
} }
let bft_threshold = get_byzantium_quorum_threshold(authorities_len); let bft_threshold = get_byzantium_threshold(authorities_len);
ext.execute_with(|| { ext.execute_with(|| {
let mut complaints_map = BitmapByAuthority::<Runtime>::default(); let mut complaints_map = BitmapByAuthority::<Runtime>::default();
for authority in 0..=bft_threshold { for authority in 0..=bft_threshold {
@ -1344,7 +1344,7 @@ fn test_prepare_round5_abort_on_byzantine_attack() {
} }
} }
let bft_threshold = get_byzantium_quorum_threshold(authorities_len); let bft_threshold = get_byzantium_threshold(authorities_len);
ext.execute_with(|| { ext.execute_with(|| {
let mut justifications_map = BitmapByAuthority::<Runtime>::default(); let mut justifications_map = BitmapByAuthority::<Runtime>::default();
for authority in 0..=bft_threshold { for authority in 0..=bft_threshold {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-governance" name = "ghost-governance"
version = "0.3.6" version = "0.3.5"
description = "Full-chain and cross-chain governance pallet with early adopter share claims" description = "Full-chain and cross-chain governance pallet with early adopter share claims"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -40,27 +40,24 @@ mod benchmarks {
}; };
let preimage_init = claim_package_init.get_preimage(&dummy_evm_address, network_id); let preimage_init = claim_package_init.get_preimage(&dummy_evm_address, network_id);
let some_hash = SubstrateKeccakHasher::hash(&preimage_init);
let mut leaf_combined = sp_std::vec![0u8; 1 + preimage_init.len()];
leaf_combined[1..].copy_from_slice(&preimage_init);
let some_hash = SubstrateKeccakHasher::hash(&leaf_combined);
let mut current_hash = some_hash; let mut current_hash = some_hash;
let mut proof_hashes = Vec::with_capacity(max_proof_depth as usize); let mut proof_hashes = Vec::with_capacity(max_proof_depth as usize);
let mut current_index = target_index as usize; let mut current_index = target_index as usize;
let hash_len = SubstrateKeccakHasher::hash_len(); let hash_len = SubstrateKeccakHasher::hash_len();
let mut combined = sp_std::vec![1u8; 1 + hash_len * 2]; let mut combined = sp_std::vec![0u8; hash_len * 2];
for _ in 0..max_proof_depth { for _ in 0..max_proof_depth {
proof_hashes.push(some_hash); proof_hashes.push(some_hash);
if current_index % 2 == 0 { if current_index % 2 == 0 {
combined[1..1 + hash_len].copy_from_slice(&current_hash.to_fixed_bytes()); combined[..hash_len].copy_from_slice(&current_hash.to_fixed_bytes());
combined[1 + hash_len..1 + hash_len * 2].copy_from_slice(&some_hash.to_fixed_bytes()); combined[hash_len..].copy_from_slice(&some_hash.to_fixed_bytes());
} else { } else {
combined[1..1 + hash_len].copy_from_slice(&some_hash.to_fixed_bytes()); combined[..hash_len].copy_from_slice(&some_hash.to_fixed_bytes());
combined[1 + hash_len..1 + hash_len * 2].copy_from_slice(&current_hash.to_fixed_bytes()); combined[hash_len..].copy_from_slice(&current_hash.to_fixed_bytes());
} }
current_hash = SubstrateKeccakHasher::hash(&combined); current_hash = SubstrateKeccakHasher::hash(&combined);

View File

@ -176,18 +176,18 @@ fn claim_happy_path() {
fn verify_proof_from_python_preclaims_for_sepolia() { fn verify_proof_from_python_preclaims_for_sepolia() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
// =========================================================================================================== // ===========================================================================================================
// === FINAL MERKLE ROOT FOR [SEPOLIA]: c41c281c8404f5ce0adfca067ef8ed260f28c2cb1d7944c84ce2431936b1919e === // === FINAL MERKLE ROOT FOR [SEPOLIA]: 0xd7f7f0061338c2c59a96caa8a2572491315755cdcce534954d4ce30150c3bb7c ===
// =========================================================================================================== // ===========================================================================================================
// [+] Total padded leaves: 128 // [+] Total padded leaves: 128
// [+] Merkle tree size: 255 // [+] Merkle tree size: 255
// [+] Network ID: 11155111 // [+] Network ID: 11155111
// [+] Proof size: 7 // [+] Proof size: 7
// [+] Total shares: 1398900000000000000000 // [+] Total shares: 694000000000000000000
let network_id = 11155111u64; let network_id = 11155111u64;
let merkle_root = EvmHash::from(hex!("c41c281c8404f5ce0adfca067ef8ed260f28c2cb1d7944c84ce2431936b1919e")); let merkle_root = EvmHash::from(hex!("d7f7f0061338c2c59a96caa8a2572491315755cdcce534954d4ce30150c3bb7c"));
let proof_size = 7; let proof_size = 7;
let total_shares = 1398900000000000000000; let total_shares = 694000000000000000000;
let network_state = NetworkShare::new(total_shares, merkle_root, proof_size); let network_state = NetworkShare::new(total_shares, merkle_root, proof_size);
let global_state = ShareState::new(total_shares); let global_state = ShareState::new(total_shares);
@ -198,16 +198,16 @@ fn verify_proof_from_python_preclaims_for_sepolia() {
let claim_package_1 = ClaimPackage { let claim_package_1 = ClaimPackage {
index: 0, index: 0,
token_id: 1, token_id: 1,
shares: 684900000000000000000, shares: 670000000000000000000,
merkle_proof: BoundedVec::try_from( merkle_proof: BoundedVec::try_from(
vec![ vec![
EvmHash::from(hex!("86d599b297ed8fb56476884b43502e15e7b207835f9a62bd07b4f3338ac63b44")), EvmHash::from(hex!("4dba08ba4fae6cbb0a6be6bdce81e91baf913d1857f470e97388157edd4d8d5c")),
EvmHash::from(hex!("85ec1f887b1a32e76cd1b70de6a5b1900045efd7dfe3b218d3b6cef672735da6")), EvmHash::from(hex!("7c1a4d2ebe6a500171b0c0f6c624898261da62d09c132106c4acec277660bd01")),
EvmHash::from(hex!("1e8a291eb2ba08696ca482c7869cab5ad360da4e4df55589adf40b08b020cc5b")), EvmHash::from(hex!("00c5bca05597b46f72d9ee739bd3c6ff80ebd1d20944879fe0c8d1dc9fda1643")),
EvmHash::from(hex!("a090ff633d4831ca76640ffce9d9399a0f8409bbbc98814d0d885c538c9ebc08")), EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("85ad79082ed24d2fc6748f131ed39280d402cb7a0844b42b9d768d4639b516a9")), EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("2c55408bc86c5a292611bc01ba46ac6c6b37b8409097b752bad884be24249ec4")), EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("9e046ea7683ac6dfa95caf833912d806b41296fcaa86718b4822f42ae68a6ff5")) EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4")),
] ]
).unwrap(), ).unwrap(),
}; };
@ -226,16 +226,16 @@ fn verify_proof_from_python_preclaims_for_sepolia() {
let claim_package_2 = ClaimPackage { let claim_package_2 = ClaimPackage {
index: 2, index: 2,
token_id: 3, token_id: 3,
shares: 14900000000000000000, shares: 8000000000000000000,
merkle_proof: BoundedVec::try_from( merkle_proof: BoundedVec::try_from(
vec![ vec![
EvmHash::from(hex!("547eb6ce3345e183448c61ee30e4eca0523537114e8d3971894196598651040e")), EvmHash::from(hex!("a8bbe4e0578964e3e6c40b93380967d69b7a1fd0358bffe789473892ec82872d")),
EvmHash::from(hex!("9e9936d6cd248898747a8d29d2ef1b02ca06c40583873fd7c3a7ddd1554f5472")), EvmHash::from(hex!("9b771d13977930979a26632d74e350885d5750b00646a5b03114b5815afb9f2f")),
EvmHash::from(hex!("1e8a291eb2ba08696ca482c7869cab5ad360da4e4df55589adf40b08b020cc5b")), EvmHash::from(hex!("00c5bca05597b46f72d9ee739bd3c6ff80ebd1d20944879fe0c8d1dc9fda1643")),
EvmHash::from(hex!("a090ff633d4831ca76640ffce9d9399a0f8409bbbc98814d0d885c538c9ebc08")), EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("85ad79082ed24d2fc6748f131ed39280d402cb7a0844b42b9d768d4639b516a9")), EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("2c55408bc86c5a292611bc01ba46ac6c6b37b8409097b752bad884be24249ec4")), EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("9e046ea7683ac6dfa95caf833912d806b41296fcaa86718b4822f42ae68a6ff5")) EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4")),
] ]
).unwrap(), ).unwrap(),
}; };
@ -254,16 +254,16 @@ fn verify_proof_from_python_preclaims_for_sepolia() {
let claim_package_3 = ClaimPackage { let claim_package_3 = ClaimPackage {
index: 6, index: 6,
token_id: 7, token_id: 7,
shares: 10900000000000000000, shares: 4000000000000000000,
merkle_proof: BoundedVec::try_from( merkle_proof: BoundedVec::try_from(
vec![ vec![
EvmHash::from(hex!("441f13d353fe0224fe4ab418fe56c66287e0ba1e5e562f56a4b7195ca3d9f741")), EvmHash::from(hex!("d28eec1544597d9e050c88a7a84535be82caf9b9e0b0c9b59b39283e7885a0d1")),
EvmHash::from(hex!("17f9ae41fbcbbfc35accf1e4e132a905b0a95e68e085757ae8304b6a0554e908")), EvmHash::from(hex!("6e939188f98c3ed00931e66fdfc220c036b98edc54a212f5b18e2d3776c7c22f")),
EvmHash::from(hex!("a6f6783441ed0d4c5f1da8d1f026c037e15706c4ecb4c400216d485105ec9596")), EvmHash::from(hex!("4141baa2d892b0111bbb102078bd3ad5331c74f176b228c588741c1c306cb67d")),
EvmHash::from(hex!("a090ff633d4831ca76640ffce9d9399a0f8409bbbc98814d0d885c538c9ebc08")), EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("85ad79082ed24d2fc6748f131ed39280d402cb7a0844b42b9d768d4639b516a9")), EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("2c55408bc86c5a292611bc01ba46ac6c6b37b8409097b752bad884be24249ec4")), EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("9e046ea7683ac6dfa95caf833912d806b41296fcaa86718b4822f42ae68a6ff5")) EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4"))
] ]
).unwrap(), ).unwrap(),
}; };
@ -282,16 +282,16 @@ fn verify_proof_from_python_preclaims_for_sepolia() {
let claim_package_4 = ClaimPackage { let claim_package_4 = ClaimPackage {
index: 35, index: 35,
token_id: 36, token_id: 36,
shares: 10900000000000000000, shares: 4000000000000000000,
merkle_proof: BoundedVec::try_from( merkle_proof: BoundedVec::try_from(
vec![ vec![
EvmHash::from(hex!("5ddb291d62d02afab17cee218f2f367d612736b0f1ae59d2d28aac811e2057f3")), EvmHash::from(hex!("6b405422bcab22b7c28a9b429096e31d664522154856efb0d7b16485080b2e2a")),
EvmHash::from(hex!("d990cb37076db084b1621bc8327e0f740e242da4c463ea3a0457a6483c07fdbf")), EvmHash::from(hex!("620bb1858eaf6c6bb543fcf5f4b0d0b5adfbb95506403038eb153f075a00f522")),
EvmHash::from(hex!("7bf41c14904c75e189893d05cf99c55516a194882463980cf08468c3bfd7dd8a")), EvmHash::from(hex!("e0b7058849ff216808963201ad2336f5587ff02eff08aceddb4764cc785413fd")),
EvmHash::from(hex!("1c4c8136fe9e6dc08dc1c69f2da707a271ae510cdb5af6051b5222f2812edee0")), EvmHash::from(hex!("e23325a502fe4248c8e049400a92a1c655689499c129b0ce6be3fad5d4a12dc1")),
EvmHash::from(hex!("3ec8d2443fd6f9decef06bf930e37cd37d78bf1c6004dc84b9ca1199712a82f8")), EvmHash::from(hex!("0cde8f646452003d6c8ff1fd265ea41cd3af2e733e63ec25a9dfc82ddf41e968")),
EvmHash::from(hex!("1951c00e48f734ba95daeb3e8f6a2d971cc6fb0afac471ae39a21013f5756794")), EvmHash::from(hex!("c012942dae89ee6d1e1e44e876ae29b9421aaf0597dd2345f07a1439a98e0cbd")),
EvmHash::from(hex!("9e046ea7683ac6dfa95caf833912d806b41296fcaa86718b4822f42ae68a6ff5")) EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4"))
] ]
).unwrap(), ).unwrap(),
}; };

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-helpers" name = "ghost-helpers"
version = "0.0.8" version = "0.0.6"
description = "Cryptographic utility suite for custom runtimes: optimized Bitmaps, UTXO parsing, Merkle Tree proofs, and Hash Chain components." description = "Cryptographic utility suite for custom runtimes: optimized Bitmaps, UTXO parsing, Merkle Tree proofs, and Hash Chain components."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -34,18 +34,20 @@ pub type NetworkIdU32 = u32;
pub type NetworkIdU64 = u64; pub type NetworkIdU64 = u64;
pub type NetworkIdU128 = u128; pub type NetworkIdU128 = u128;
pub fn get_byzantium_quorum_threshold<I>(value: I) -> I pub fn get_byzantium_threshold<I>(value: I) -> I
where where
I: num_traits::PrimInt, I: num_traits::PrimInt,
{ {
let zero = I::zero(); let zero = I::zero();
let one = I::one(); let one = I::one();
let three = one + one + one; let two = one + one;
let three = two + one;
if value == zero { return zero; } if value == zero {
return zero;
}
let f = (value - one) / three; (value - one) / three * two + one
value - f
} }
pub struct SubstrateBlake2Hasher; pub struct SubstrateBlake2Hasher;
@ -95,43 +97,3 @@ impl GhostHasher for UtxoSha2Hasher {
H256::zero() H256::zero()
} }
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bft_threshold_standard_paper_cases() {
// Lower boundaries (f increases here)
assert_eq!(get_byzantium_quorum_threshold(1u32), 1);
assert_eq!(get_byzantium_quorum_threshold(4u32), 3);
assert_eq!(get_byzantium_quorum_threshold(7u32), 5);
assert_eq!(get_byzantium_quorum_threshold(10u32), 7);
// Upper boundaries (max nodes for a given 'f')
assert_eq!(get_byzantium_quorum_threshold(3u32), 3);
assert_eq!(get_byzantium_quorum_threshold(6u32), 5);
assert_eq!(get_byzantium_quorum_threshold(9u32), 7);
}
#[test]
fn test_bft_threshold_zero_nodes() {
assert_eq!(get_byzantium_quorum_threshold(0u32), 0);
}
#[test]
fn test_bft_threshold_integer_boundaries() {
let max_val = usize::MAX;
let expected_f = (max_val - 1) / 3;
let expected_honest = max_val - expected_f;
assert_eq!(get_byzantium_quorum_threshold(max_val), expected_honest);
}
#[test]
fn test_bft_threshold_different_types() {
assert_eq!(get_byzantium_quorum_threshold(4u8), 3u8);
assert_eq!(get_byzantium_quorum_threshold(4u64), 3u64);
assert_eq!(get_byzantium_quorum_threshold(4usize), 3usize);
}
}

View File

@ -3,29 +3,6 @@ use sp_arithmetic::traits::AtLeast8BitUnsigned;
use sp_runtime::traits::UniqueSaturatedInto; use sp_runtime::traits::UniqueSaturatedInto;
use sp_std::vec::Vec; use sp_std::vec::Vec;
const LEAF_PREFIX: u8 = 0;
const NODE_PREFIX: u8 = 1;
fn leaf_prefixed<H>(preimage: &[u8]) -> H::Hash
where
H: GhostHasher,
{
let mut prefixed_data = sp_std::vec![LEAF_PREFIX; 1 + preimage.len()];
prefixed_data[1..].copy_from_slice(preimage);
H::hash(&prefixed_data)
}
fn node_prefixed<H>(preimage1: &[u8], preimage2: &[u8]) -> H::Hash
where
H: GhostHasher,
{
let total_len = preimage1.len() + preimage2.len();
let mut prefixed_data = sp_std::vec![NODE_PREFIX; 1 + total_len];
prefixed_data[1..1 + preimage1.len()].copy_from_slice(preimage1);
prefixed_data[1 + preimage1.len()..].copy_from_slice(preimage2);
H::hash(&prefixed_data)
}
pub fn generate_tree<H, I, S, F, E>( pub fn generate_tree<H, I, S, F, E>(
max_index: I, max_index: I,
raw_values: S, raw_values: S,
@ -40,28 +17,30 @@ where
let num_of_leaves: usize = (max_index + I::one()).unique_saturated_into(); let num_of_leaves: usize = (max_index + I::one()).unique_saturated_into();
let padded_leaves = num_of_leaves.next_power_of_two(); let padded_leaves = num_of_leaves.next_power_of_two();
let total_capacity = (2 * padded_leaves) - 1; let total_capacity = (2 * padded_leaves) - 1;
let mut merkle_tree = sp_std::vec![H::empty(); total_capacity];
let empty_hash = H::empty();
let empty_leaf_hash = leaf_prefixed::<H>(empty_hash.as_ref());
let mut merkle_tree = sp_std::vec![empty_leaf_hash; total_capacity];
for item in raw_values.into_iter() { for item in raw_values.into_iter() {
let (index, preimage) = generate_preimage(item)?; let (index, preimage) = generate_preimage(item)?;
if index >= padded_leaves { return Ok(sp_std::vec![]); } merkle_tree[index] = H::hash(&preimage);
merkle_tree[index] = leaf_prefixed::<H>(&preimage)
} }
let mut layer_start = 0; let mut layer_start = 0;
let mut current_layer_len = padded_leaves; let mut current_layer_len = padded_leaves;
let mut write_ptr = padded_leaves; let mut write_ptr = padded_leaves;
let hash_len = H::hash_len();
let mut combined = sp_std::vec![0u8; hash_len * 2];
while current_layer_len > 1 { while current_layer_len > 1 {
for i in (0..current_layer_len).step_by(2) { for i in (0..current_layer_len).step_by(2) {
let layer_index = layer_start + i; let layer_index = layer_start + i;
let left_bytes = merkle_tree[layer_index].as_ref(); let left_bytes = merkle_tree[layer_index].as_ref();
let right_bytes = merkle_tree[layer_index | 1].as_ref(); let right_bytes = merkle_tree[layer_index | 1].as_ref();
merkle_tree[write_ptr] = node_prefixed::<H>(left_bytes, right_bytes); combined[..hash_len].copy_from_slice(left_bytes);
combined[hash_len..].copy_from_slice(right_bytes);
merkle_tree[write_ptr] = H::hash(&combined);
write_ptr += 1; write_ptr += 1;
} }
layer_start += current_layer_len; layer_start += current_layer_len;
@ -71,17 +50,11 @@ where
Ok(merkle_tree) Ok(merkle_tree)
} }
pub fn generate_proof<H, I>( pub fn generate_proof<H, I>(merkle_tree: &[H::Hash], max_index: I, index: I) -> Vec<H::Hash>
merkle_tree: &[H::Hash],
max_index: I,
index: I,
) -> Vec<H::Hash>
where where
H: GhostHasher, H: GhostHasher,
I: AtLeast8BitUnsigned + UniqueSaturatedInto<usize>, I: AtLeast8BitUnsigned + UniqueSaturatedInto<usize>,
{ {
if index > max_index { return sp_std::vec![]; }
let num_of_leaves: usize = (max_index + I::one()).unique_saturated_into(); let num_of_leaves: usize = (max_index + I::one()).unique_saturated_into();
let mut current_index: usize = index.unique_saturated_into(); let mut current_index: usize = index.unique_saturated_into();
let mut current_layer_len = num_of_leaves.next_power_of_two(); let mut current_layer_len = num_of_leaves.next_power_of_two();
@ -114,21 +87,29 @@ where
H: GhostHasher, H: GhostHasher,
I: PartialOrd + UniqueSaturatedInto<usize>, I: PartialOrd + UniqueSaturatedInto<usize>,
{ {
let mut current_hash = H::hash(preimage);
let mut current_index: usize = index.unique_saturated_into(); let mut current_index: usize = index.unique_saturated_into();
if current_index >= (1 << merkle_proof.len()) { return false; }
let mut current_hash = leaf_prefixed::<H>(preimage); if current_index >= (1 << merkle_proof.len()) {
return false;
}
let hash_len = H::hash_len();
let mut combined = sp_std::vec![0u8; hash_len * 2];
for sibling in merkle_proof.iter() { for sibling in merkle_proof.iter() {
let sibling_bytes = sibling.as_ref(); let sibling_bytes = sibling.as_ref();
let hash_bytes = current_hash.as_ref(); let hash_bytes = current_hash.as_ref();
if current_index % 2 == 0 { if current_index % 2 == 0 {
current_hash = node_prefixed::<H>(hash_bytes, sibling_bytes); combined[..hash_len].copy_from_slice(hash_bytes);
combined[hash_len..].copy_from_slice(sibling_bytes);
} else { } else {
current_hash = node_prefixed::<H>(sibling_bytes, hash_bytes); combined[..hash_len].copy_from_slice(sibling_bytes);
combined[hash_len..].copy_from_slice(hash_bytes);
} }
current_hash = H::hash(&combined);
current_index >>= 1; current_index >>= 1;
} }
@ -176,27 +157,24 @@ mod tests {
assert_eq!(tree.len(), 7); assert_eq!(tree.len(), 7);
let h0 = TestBlake2Hasher::hash(&[ &[0u8], [1].as_slice() ].concat()); let h0 = TestBlake2Hasher::hash(&vec![1]);
let h1 = TestBlake2Hasher::hash(&[ &[0u8], [2].as_slice() ].concat()); let h1 = TestBlake2Hasher::hash(&vec![2]);
let h2 = TestBlake2Hasher::hash(&[ &[0u8], [3].as_slice() ].concat()); let h2 = TestBlake2Hasher::hash(&vec![3]);
let h3 = TestBlake2Hasher::hash(&[ &[0u8], [4].as_slice() ].concat()); let h3 = TestBlake2Hasher::hash(&vec![4]);
let mut c1 = [0u8; 65]; let mut c1 = [0u8; 64];
c1[0] = NODE_PREFIX; c1[..32].copy_from_slice(h0.as_ref());
c1[1..33].copy_from_slice(h0.as_ref()); c1[32..].copy_from_slice(h1.as_ref());
c1[33..].copy_from_slice(h1.as_ref());
let parent_left = TestBlake2Hasher::hash(&c1); let parent_left = TestBlake2Hasher::hash(&c1);
let mut c2 = [0u8; 65]; let mut c2 = [0u8; 64];
c2[0] = NODE_PREFIX; c2[..32].copy_from_slice(h2.as_ref());
c2[1..33].copy_from_slice(h2.as_ref()); c2[32..].copy_from_slice(h3.as_ref());
c2[33..].copy_from_slice(h3.as_ref());
let parent_right = TestBlake2Hasher::hash(&c2); let parent_right = TestBlake2Hasher::hash(&c2);
let mut c_root = [0u8; 65]; let mut c_root = [0u8; 64];
c_root[0] = NODE_PREFIX; c_root[..32].copy_from_slice(parent_left.as_ref());
c_root[1..33].copy_from_slice(parent_left.as_ref()); c_root[32..].copy_from_slice(parent_right.as_ref());
c_root[33..].copy_from_slice(parent_right.as_ref());
let expected_root = TestBlake2Hasher::hash(&c_root); let expected_root = TestBlake2Hasher::hash(&c_root);
assert_eq!(tree.last().unwrap(), &expected_root); assert_eq!(tree.last().unwrap(), &expected_root);
@ -218,23 +196,17 @@ mod tests {
) )
.unwrap(); .unwrap();
let mut empty_data = sp_std::vec![LEAF_PREFIX];
empty_data.extend_from_slice(&H256::zero().to_fixed_bytes());
let empty_hash = TestBlake2Hasher::hash(&empty_data);
assert_eq!(tree.len(), 7); assert_eq!(tree.len(), 7);
assert_eq!(tree[3], empty_hash); assert_eq!(tree[3], H256::zero());
let mut leaf2_data = sp_std::vec![LEAF_PREFIX]; let h2 = TestBlake2Hasher::hash(&vec![3]);
leaf2_data.extend_from_slice(&[3]); let h3_empty = H256::zero();
let h2 = TestBlake2Hasher::hash(&leaf2_data);
let mut combined_right = [0u8; 65];
combined_right[0] = NODE_PREFIX;
combined_right[1..33].copy_from_slice(h2.as_ref());
combined_right[33..].copy_from_slice(empty_hash.as_ref());
let mut combined_right = [0u8; 64];
combined_right[..32].copy_from_slice(h2.as_ref());
combined_right[32..].copy_from_slice(h3_empty.as_ref());
let expected_parent_right = TestBlake2Hasher::hash(&combined_right); let expected_parent_right = TestBlake2Hasher::hash(&combined_right);
assert_eq!(tree[5], expected_parent_right); assert_eq!(tree[5], expected_parent_right);
} }
@ -279,7 +251,7 @@ mod tests {
.unwrap(); .unwrap();
assert_eq!(tree.len(), 1); assert_eq!(tree.len(), 1);
assert_eq!(tree[0], TestBlake2Hasher::hash(&vec![LEAF_PREFIX, 42])); assert_eq!(tree[0], TestBlake2Hasher::hash(&vec![42]));
} }
#[test] #[test]
@ -400,14 +372,10 @@ mod tests {
raw_data, raw_data,
|(index, bytes)| Ok((index, bytes)), |(index, bytes)| Ok((index, bytes)),
) )
.unwrap(); .unwrap();
let proof = generate_proof::<TestBlake2Hasher, u32>(&tree, max_index, 2); let proof = generate_proof::<TestBlake2Hasher, u32>(&tree, max_index, 2);
assert_eq!(proof[0], H256::zero());
let mut empty_data = sp_std::vec![LEAF_PREFIX];
empty_data.extend_from_slice(&H256::zero().to_fixed_bytes());
let empty_hash = TestBlake2Hasher::hash(&empty_data);
assert_eq!(proof[0], empty_hash);
let root = *tree.last().unwrap(); let root = *tree.last().unwrap();
let is_valid = let is_valid =

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-traits" name = "ghost-traits"
version = "0.4.5" version = "0.4.4"
description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more." description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -4,7 +4,7 @@ use sp_core::H256;
pub trait MerkleTree<A, E>: IdentifierConverter<A, E> { pub trait MerkleTree<A, E>: IdentifierConverter<A, E> {
type VerifyingShares; type VerifyingShares;
type Hash: AsRef<[u8]>; type Hash;
fn merkle_build_tree(vs: &Self::VerifyingShares) -> Result<Vec<Self::Hash>, E>; fn merkle_build_tree(vs: &Self::VerifyingShares) -> Result<Vec<Self::Hash>, E>;
fn merkle_generate_proof_from_tree(vsm: &Self::VerifyingShares, t: &[Self::Hash], i: A) -> Result<(Vec<u8>, Vec<H256>), E>; fn merkle_generate_proof_from_tree(vsm: &Self::VerifyingShares, t: &[Self::Hash], i: A) -> Result<(Vec<u8>, Vec<H256>), E>;

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-weaver" name = "ghost-weaver"
version = "0.0.6" version = "0.0.4"
description = "Weaving a secure cryptographic tapestry across different external chains." description = "Weaving a secure cryptographic tapestry across different external chains."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -354,11 +354,11 @@ mod benchmarks {
let session = 69; let session = 69;
let (network_id, _, _) = prepare_pallet::<T>(1); let (network_id, _, _) = prepare_pallet::<T>(1);
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract // https://sepolia.etherscan.io/address/0x9cffbdbdf29c67c5dbab1b5e8ae897aeafcaf70c#readContract
// getRoot: session 0, atBlock 11660400 // getRoot: session 0, atBlock 11383380
let root_string = let root_string =
hex::decode("28d1e6b476b03a464f74d531d532572db29d6b57349e4f17f84e92843f6c4ee7") hex::decode("f72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d")
.expect("EVM Root hex should be valid"); .expect("EVM Root hex should be valid");
let expected_root = H256::from_slice(&root_string); let expected_root = H256::from_slice(&root_string);
LoomStates::<T>::insert(&network_id, &session, expected_root); LoomStates::<T>::insert(&network_id, &session, expected_root);
@ -373,14 +373,38 @@ mod benchmarks {
let transfer_amount: BalanceOf<T> = 420u64.unique_saturated_into(); let transfer_amount: BalanceOf<T> = 420u64.unique_saturated_into();
let proof = vec![ let proof = vec![
H256::from_slice(&hex::decode("c5354289f0397c916949373043eb1d5ea99447f67fe014324d96c58ef02a2d11").expect("Proof should be valid")), H256::from_slice(
H256::from_slice(&hex::decode("da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420").expect("Proof should be valid")), &hex::decode("6dfb19f049f557abff273ce9efb9195924d41e5699b1b7755be2c515b25ef7b6")
H256::from_slice(&hex::decode("1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f").expect("Proof should be valid")), .expect("Proof should be valid"),
H256::from_slice(&hex::decode("5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f").expect("Proof should be valid")), ),
H256::from_slice(&hex::decode("5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f").expect("Proof should be valid")), H256::from_slice(
H256::from_slice(&hex::decode("d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071").expect("Proof should be valid")), &hex::decode("9e0f9c5b8ffa146b74bb614482c0bc65a1ef961a8fa9a3a031a36c97f8c70733")
H256::from_slice(&hex::decode("68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f").expect("Proof should be valid")), .expect("Proof should be valid"),
H256::from_slice(&hex::decode("de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040").expect("Proof should be valid")), ),
H256::from_slice(
&hex::decode("890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d")
.expect("Proof should be valid"),
),
H256::from_slice(
&hex::decode("3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8")
.expect("Proof should be valid"),
),
H256::from_slice(
&hex::decode("ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da")
.expect("Proof should be valid"),
),
H256::from_slice(
&hex::decode("defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5")
.expect("Proof should be valid"),
),
H256::from_slice(
&hex::decode("617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7")
.expect("Proof should be valid"),
),
H256::from_slice(
&hex::decode("292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead")
.expect("Proof should be valid"),
),
]; ];
let slots = vec![H256::from_slice( let slots = vec![H256::from_slice(
&hex::decode("2e474dabf492786b3505d7b7cf0bf07c9dbce92c91982fa7344c77e24fd4310d") &hex::decode("2e474dabf492786b3505d7b7cf0bf07c9dbce92c91982fa7344c77e24fd4310d")

View File

@ -25,7 +25,7 @@ use sp_runtime::{
use ghost_helpers::{ use ghost_helpers::{
bounded_bitmap::{validate_bitmap_sizes, BoundedBitmap}, bounded_bitmap::{validate_bitmap_sizes, BoundedBitmap},
get_byzantium_quorum_threshold, get_byzantium_threshold,
networks::{NetworkData, NetworkType}, networks::{NetworkData, NetworkType},
}; };
use ghost_traits::{ use ghost_traits::{
@ -487,7 +487,7 @@ pub mod pallet {
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1)); weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 1));
let len = Authorities::<T>::decode_len().unwrap_or_default(); let len = Authorities::<T>::decode_len().unwrap_or_default();
let weaving_threshold = get_byzantium_quorum_threshold(len); let weaving_threshold = get_byzantium_threshold(len);
let maybe_tapestry_drafts = TapestryDrafts::<T>::get(&network_id); let maybe_tapestry_drafts = TapestryDrafts::<T>::get(&network_id);
@ -850,7 +850,7 @@ impl<T: Config> Pallet<T> {
.parse_block_requests(pending_requests, deadline, request_id); .parse_block_requests(pending_requests, deadline, request_id);
let total_blocks = block_numbers.len(); let total_blocks = block_numbers.len();
let weaving_threshold = get_byzantium_quorum_threshold(total_blocks); let weaving_threshold = get_byzantium_threshold(total_blocks);
let median_block = Self::validate_block_numbers_consensus( let median_block = Self::validate_block_numbers_consensus(
&mut block_numbers, &mut block_numbers,

View File

@ -65,9 +65,7 @@ fn should_successfully_compute_median_and_start_weaving_round() {
let pair3 = AuthorityPair::from_string("//Carol", None).expect("Should be valid seed"); let pair3 = AuthorityPair::from_string("//Carol", None).expect("Should be valid seed");
let network_id = 1; let network_id = 1;
let network_data = NetworkDataBuilder::default() let network_data = NetworkDataBuilder::default().build();
.with_block_deviation(5)
.build();
let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()]; let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()];
let networks = vec![(network_id, network_data, Default::default())]; let networks = vec![(network_id, network_data, Default::default())];
@ -124,8 +122,8 @@ fn should_apply_cooldown_delay_on_consensus_failure() {
.with_network_id(network_id); .with_network_id(network_id);
let att1 = context.with_authority_index(0).build_block_attestation(100); let att1 = context.with_authority_index(0).build_block_attestation(100);
let att2 = context.with_authority_index(1).build_block_attestation(102); let att2 = context.with_authority_index(1).build_block_attestation(500);
let att3 = context.with_authority_index(2).build_block_attestation(104); let att3 = context.with_authority_index(2).build_block_attestation(900);
let sig1 = pair1.sign(&att1.encode()); let sig1 = pair1.sign(&att1.encode());
let sig2 = pair2.sign(&att2.encode()); let sig2 = pair2.sign(&att2.encode());
@ -572,8 +570,8 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
// 420 sfDxNicCEPts6CVttVMPCs2eoymDpQahu1GUVyGPWu6dhwADJ - 0x0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e // 420 sfDxNicCEPts6CVttVMPCs2eoymDpQahu1GUVyGPWu6dhwADJ - 0x0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e
// 1337 sfH6zJ63fcxrFAZ1RmiHbxgy2t3sEufY26WdsBSS359AzJd4w - 0x962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b // 1337 sfH6zJ63fcxrFAZ1RmiHbxgy2t3sEufY26WdsBSS359AzJd4w - 0x962a2794f66c89e55d9b9692ce59f67345b99f6fddb51d90462c7eca8b5a7e1b
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract // https://sepolia.etherscan.io/address/0x9cffbdbdf29c67c5dbab1b5e8ae897aeafcaf70c#readContract
// getRoot: atBlock 11660400, globalIndexes from 0 to 2 // getRoot: atBlock 11383380, globalIndexes from 0 to 2
let inserts = vec![ let inserts = vec![
( (
0, 0,
@ -583,49 +581,49 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
vec![ vec![
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"675a2e7b05b8b3932cd0faf88f1bc29767b7462667f56d051b8d5325bda0ee73", "c7a710c9acbc193692f34ac1f1979013b04240a4c0d02b49b9178f17721350b1",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420", "9e0f9c5b8ffa146b74bb614482c0bc65a1ef961a8fa9a3a031a36c97f8c70733",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f", "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f", "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f", "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071", "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f", "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040", "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
@ -643,49 +641,49 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
vec![ vec![
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"c5354289f0397c916949373043eb1d5ea99447f67fe014324d96c58ef02a2d11", "6dfb19f049f557abff273ce9efb9195924d41e5699b1b7755be2c515b25ef7b6",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"da1fbdfefa1e9aedfedcfc48fb17cb0e731529f7a3695114e0a9caa1989dd420", "9e0f9c5b8ffa146b74bb614482c0bc65a1ef961a8fa9a3a031a36c97f8c70733",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f", "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f", "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f", "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071", "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f", "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040", "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
@ -703,49 +701,49 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
vec![ vec![
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"f39a869f62e75cf5f0bf914688a6b289caf2049435d8e68c5c5e6d05e44913f3", "290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"e0090094ce1d7af8a81ba78bef4b137c1ab32d20d5487224a9f8df95b516c1e4", "82ca531d09faff937c9b68f53d473c9f2c88bdbc8b1629af894479367881db5c",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"1c792b14bf66f82af36f00f5fba7014fa0c1e2ff3c7c273bfe523c1acf67dc3f", "890740a8eb06ce9be422cb8da5cdafc2b58c0a5e24036c578de2a433c828ff7d",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5fa080a686a5a0d05c3d4822fd54d632dc9cc04b1616046eba2ce499eb9af79f", "3b8ec09e026fdc305365dfc94e189a81b38c7597b3d941c279f042e8206e0bd8",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"5eb949690a0404abf4cebafc7cfffa382191b7dd9e7df778581e6fb78efab35f", "ecd50eee38e386bd62be9bedb990706951b65fe053bd9d8a521af753d139e2da",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"d364c9d5dadad4569b6dd47f7feabafa3571f842434425548335ac6e690dd071", "defff6d330bb5403f63b14f33b578274160de3a50df4efecf0e0db73bcdd3da5",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"68d8bc5b77979c1a6702334f529f5783f79e942fd2cd03f6e55ac2cf496e849f", "617bdd11f7c0a11f49db22f629387a12da7596f9d1704d7465177c63d88ec7d7",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
H256::from_slice( H256::from_slice(
&hex::decode( &hex::decode(
"de9c446fab46a8d27db1e3100f275a777d385b44e3cbc045cabac9da36cae040", "292c23a9aa1d8bea7e2435e555a4a60e379a5a35f3f452bae60121073fb6eead",
) )
.expect("Proof should be valid"), .expect("Proof should be valid"),
), ),
@ -758,11 +756,11 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
]; ];
new_test_ext(authorities, networks).execute_with(|| { new_test_ext(authorities, networks).execute_with(|| {
// https://sepolia.etherscan.io/address/0x81acdf2da6b50d806c96aecd9a498a5359e373c0#readContract // https://sepolia.etherscan.io/address/0x9cffbdbdf29c67c5dbab1b5e8ae897aeafcaf70c#readContract
// getRoot: session 0, atBlock 11660400 // getRoot: session 0, atBlock 11383380
let session = 0; let session = 0;
let root_string = let root_string =
hex::decode("28d1e6b476b03a464f74d531d532572db29d6b57349e4f17f84e92843f6c4ee7") hex::decode("f72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d")
.expect("Root hex should be valid"); .expect("Root hex should be valid");
let expected_root = H256::from_slice(&root_string); let expected_root = H256::from_slice(&root_string);
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root); LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);
@ -935,7 +933,7 @@ fn should_successfully_pull_utxo_thread_and_mint_currency() {
} }
#[test] #[test]
fn on_initialize_should_finalize_session_when_timeout_is_reached() { fn on_initialize_should_finalize_session_when_threshold_or_timeout_is_reached() {
let pair1 = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed"); let pair1 = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
let pair2 = AuthorityPair::from_string("//Bob", None).expect("Should be valid seed"); let pair2 = AuthorityPair::from_string("//Bob", None).expect("Should be valid seed");
let pair3 = AuthorityPair::from_string("//Charlie", None).expect("Should be valid seed"); let pair3 = AuthorityPair::from_string("//Charlie", None).expect("Should be valid seed");
@ -997,12 +995,14 @@ fn on_initialize_should_finalize_session_when_timeout_is_reached() {
let current_session = CurrentWeavingSession::<TestRuntime>::get(&network_id); let current_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
GhostWeaver::on_initialize(current_substrate_block); GhostWeaver::on_initialize(current_substrate_block);
let saved_loom = LoomStates::<TestRuntime>::get(&network_id, current_session); let saved_loot = LoomStates::<TestRuntime>::get(&network_id, current_session);
assert_ne!(saved_loom, target_hash); assert_eq!(saved_loot, target_hash);
assert_eq!(saved_loom, saved_loom);
let updated_session = CurrentWeavingSession::<TestRuntime>::get(&network_id); let updated_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
assert_eq!(updated_session, current_session); assert_eq!(updated_session, current_session + 1);
System::set_block_number(15);
GhostWeaver::on_initialize(15);
}); });
} }