extend loom state to track last extracted median block
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
This commit is contained in:
parent
ba575d0ab8
commit
6ae8fd9ed4
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ghost-weaver"
|
||||
version = "0.0.20"
|
||||
version = "0.0.21"
|
||||
description = "Weaving a secure cryptographic tapestry across different external chains."
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
@ -325,9 +325,12 @@ mod benchmarks {
|
||||
let first_sha = sp_io::hashing::sha2_256(&last_header[..80]);
|
||||
let mut native_le = sp_io::hashing::sha2_256(&first_sha);
|
||||
native_le.reverse();
|
||||
let dynamic_trusted_root = H256::from(native_le);
|
||||
|
||||
LoomStates::<T>::insert(&network_id, &session, dynamic_trusted_root);
|
||||
let at_block = 420;
|
||||
let dynamic_trusted_root = H256::from(native_le);
|
||||
let loom_state = LoomState { at_block, root_hash: dynamic_trusted_root };
|
||||
|
||||
LoomStates::<T>::insert(&network_id, &session, loom_state);
|
||||
|
||||
let utxo_thread_proof = UtxoThreadProof::new(
|
||||
gettxproof_bytes,
|
||||
@ -365,8 +368,11 @@ mod benchmarks {
|
||||
let root_string =
|
||||
hex::decode("07f4a5ba4750d9ddfc080429287cbcbde7464aa2f8ae13feaade0dcb45ca6129")
|
||||
.expect("EVM Root hex should be valid");
|
||||
|
||||
let at_block = 420;
|
||||
let expected_root = H256::from_slice(&root_string);
|
||||
LoomStates::<T>::insert(&network_id, &session, expected_root);
|
||||
let loom_state = LoomState { at_block, root_hash: expected_root };
|
||||
LoomStates::<T>::insert(&network_id, &session, loom_state);
|
||||
|
||||
let receiver_32: [u8; 32] =
|
||||
hex::decode("0ae3ba32f8555fe3031461e2cb6feeadb67029ef7490b982824fc90751a4cb3e")
|
||||
|
||||
@ -211,7 +211,7 @@ pub mod pallet {
|
||||
_,
|
||||
Twox64Concat, NetworkIdOf<T>,
|
||||
Twox64Concat, WeavingSession,
|
||||
H256,
|
||||
LoomState,
|
||||
ValueQuery,
|
||||
>;
|
||||
|
||||
@ -297,7 +297,12 @@ pub mod pallet {
|
||||
);
|
||||
return;
|
||||
}
|
||||
LoomStates::<T>::insert(&data.0, data.1, data.2);
|
||||
let initial_loom_state = LoomState {
|
||||
at_block: 0u16.into(),
|
||||
root_hash: data.2,
|
||||
};
|
||||
|
||||
LoomStates::<T>::insert(&data.0, data.1, initial_loom_state);
|
||||
});
|
||||
|
||||
if !self.authorities.is_empty() {
|
||||
@ -444,7 +449,7 @@ pub mod pallet {
|
||||
let network_data = T::NetworkDataHandler::get(&network_id)
|
||||
.ok_or(Error::<T>::NonExistentNetworkId)?;
|
||||
|
||||
let root_hash = LoomStates::<T>::get(&network_id, &session);
|
||||
let state = LoomStates::<T>::get(&network_id, &session);
|
||||
let pulled_thread_key = thread_proof.get_unique_key(session, network_id);
|
||||
|
||||
ensure!(
|
||||
@ -453,7 +458,7 @@ pub mod pallet {
|
||||
);
|
||||
|
||||
let (receiver_account, amount) = thread_proof
|
||||
.verify_thread_proof(root_hash, network_id, &network_data.gatekeeper)
|
||||
.verify_thread_proof(state.root_hash, network_id, &network_data.gatekeeper)
|
||||
.ok_or(Error::<T>::InvalidMerkleProof)?;
|
||||
|
||||
let receiver_bytes: &[u8; 32] = receiver_account.as_ref();
|
||||
@ -510,11 +515,13 @@ pub mod pallet {
|
||||
let current_session = CurrentWeavingSession::<T>::get(&network_id);
|
||||
let loom_state_changed =
|
||||
LoomStates::<T>::mutate(&network_id, ¤t_session, |loom_state| {
|
||||
if *loom_state != weaving_state.hash && threshold_reached {
|
||||
*loom_state = weaving_state.hash;
|
||||
return true;
|
||||
}
|
||||
false
|
||||
if !threshold_reached { return false; }
|
||||
|
||||
let hash_changed = loom_state.root_hash != weaving_state.hash;
|
||||
loom_state.at_block = tapestry_draft.median;
|
||||
if hash_changed { loom_state.root_hash = weaving_state.hash; }
|
||||
|
||||
hash_changed
|
||||
});
|
||||
|
||||
if loom_state_changed && weaving_state.next_session != current_session {
|
||||
@ -655,7 +662,7 @@ impl<T: Config> Pallet<T> {
|
||||
let network_data = T::NetworkDataHandler::get(&network_id)
|
||||
.ok_or(InvalidTransaction::BadProof)?;
|
||||
|
||||
let root_hash = LoomStates::<T>::get(&network_id, &session);
|
||||
let root_hash = LoomStates::<T>::get(&network_id, &session).root_hash;
|
||||
if root_hash == Default::default() {
|
||||
return Err(InvalidTransaction::BadProof);
|
||||
}
|
||||
|
||||
@ -377,6 +377,9 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
let evm_network_id = 1u32;
|
||||
let utxo_network_id = 69u32;
|
||||
|
||||
let median_utxo_block = 960129;
|
||||
let median_evm_block = 25639556;
|
||||
|
||||
let pair = AuthorityPair::from_string("//Alice", None).expect("Should be valid seed");
|
||||
|
||||
let new_evm_network_data = NetworkDataBuilder::default()
|
||||
@ -415,8 +418,8 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
GhostWeaver::on_initialize(2);
|
||||
|
||||
let tapestry_draft = TapestryDraftBuilder::<crate::ExternalBlockNumber, u32>::default();
|
||||
let evm_tapestry_draft = tapestry_draft.with_median_external(25639556).build();
|
||||
let utxo_tapestry_draft = tapestry_draft.with_median_external(960129).build();
|
||||
let evm_tapestry_draft = tapestry_draft.with_median_external(median_evm_block).build();
|
||||
let utxo_tapestry_draft = tapestry_draft.with_median_external(median_utxo_block).build();
|
||||
|
||||
CurrentWeavingSession::<TestRuntime>::insert(&evm_network_id, evm_session);
|
||||
CurrentWeavingSession::<TestRuntime>::insert(&utxo_network_id, utxo_session);
|
||||
@ -523,8 +526,10 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
GhostWeaver::on_initialize(3u64);
|
||||
let curr_state = LoomStates::<TestRuntime>::get(&utxo_network_id, &utxo_session);
|
||||
|
||||
assert_eq!(prev_state, H256::default());
|
||||
assert_eq!(curr_state, block_hash);
|
||||
assert_eq!(prev_state.root_hash, H256::default());
|
||||
assert_eq!(curr_state.root_hash, block_hash);
|
||||
assert_eq!(prev_state.at_block, 0);
|
||||
assert_eq!(curr_state.at_block, median_utxo_block);
|
||||
});
|
||||
|
||||
ext.execute_with(|| {
|
||||
@ -546,7 +551,7 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
assert_eq!(curr_weaving_state.next_session, evm_session + 1);
|
||||
|
||||
let bytes = hex::decode("f72b9ef0b66c8cc3952ffd11dc0b85f3b02e6edfa9236da400138f2fcba4668d")
|
||||
.expect("UTXO block hash should be valid");
|
||||
.expect("EVM block hash should be valid");
|
||||
let block_hash = H256::from_slice(&bytes);
|
||||
|
||||
assert_eq!(curr_weaving_state.hash, block_hash);
|
||||
@ -556,8 +561,10 @@ fn offchain_worker_should_fetch_hash_and_submit_unsigned_tx() {
|
||||
GhostWeaver::on_initialize(4u64);
|
||||
let curr_state = LoomStates::<TestRuntime>::get(&evm_network_id, &evm_session);
|
||||
|
||||
assert_eq!(prev_state, H256::default());
|
||||
assert_eq!(curr_state, block_hash);
|
||||
assert_eq!(prev_state.root_hash, H256::default());
|
||||
assert_eq!(curr_state.root_hash, block_hash);
|
||||
assert_eq!(prev_state.at_block, 0);
|
||||
assert_eq!(curr_state.at_block, median_evm_block);
|
||||
});
|
||||
}
|
||||
|
||||
@ -648,8 +655,10 @@ fn should_successfully_pull_evm_thread_and_mint_currency() {
|
||||
let root_string =
|
||||
hex::decode("07f4a5ba4750d9ddfc080429287cbcbde7464aa2f8ae13feaade0dcb45ca6129")
|
||||
.expect("Root hex should be valid");
|
||||
|
||||
let expected_root = H256::from_slice(&root_string);
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);
|
||||
let expected_loom_state = LoomState { at_block: 420, root_hash: expected_root };
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_loom_state);
|
||||
|
||||
let mut total_issuance = 0;
|
||||
|
||||
@ -762,7 +771,8 @@ fn should_successfully_pull_utxo_thread_and_mint_currency() {
|
||||
.expect("Bitcoin Root hex should be valid");
|
||||
|
||||
let expected_root = H256::from_slice(&block_hash);
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);
|
||||
let expected_loom_state = LoomState { at_block: 420, root_hash: expected_root };
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_loom_state);
|
||||
|
||||
let expected_receiver_bytes = hex::decode("1657090d02985f0cdb41436fe2d5a83a3acb1995d963a698e7e619e927bdcc5e").unwrap();
|
||||
let mut receiver_raw = [0u8; 32];
|
||||
@ -860,7 +870,8 @@ fn should_successfully_pull_utxo_thread_and_reject_nominal_varint_encoding() {
|
||||
.expect("Bitcoin Root hex should be valid");
|
||||
|
||||
let expected_root = H256::from_slice(&block_hash);
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_root);
|
||||
let expected_loom_state = LoomState { at_block: 420, root_hash: expected_root };
|
||||
LoomStates::<TestRuntime>::insert(&network_id, &session, expected_loom_state);
|
||||
|
||||
let expected_receiver_bytes = hex::decode("1657090d02985f0cdb41436fe2d5a83a3acb1995d963a698e7e619e927bdcc5e").unwrap();
|
||||
let mut receiver_raw = [0u8; 32];
|
||||
@ -983,8 +994,96 @@ fn on_initialize_should_finalize_session_when_timeout_is_reached() {
|
||||
GhostWeaver::on_initialize(current_substrate_block);
|
||||
|
||||
let saved_loom = LoomStates::<TestRuntime>::get(&network_id, current_session);
|
||||
assert_ne!(saved_loom, target_hash);
|
||||
assert_eq!(saved_loom, saved_loom);
|
||||
assert_ne!(saved_loom.root_hash, target_hash);
|
||||
assert_eq!(saved_loom.at_block, 0);
|
||||
|
||||
let updated_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
|
||||
assert_eq!(updated_session, current_session);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn on_initialize_should_update_at_block_when_threshold_reached_with_same_hash() {
|
||||
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 pair3 = AuthorityPair::from_string("//Charlie", None).expect("Should be valid seed");
|
||||
|
||||
let network_id = 1;
|
||||
|
||||
let new_network_data = NetworkDataBuilder::default()
|
||||
.with_network_type(NetworkType::Evm)
|
||||
.build();
|
||||
|
||||
let authorities = vec![pair1.clone(), pair2.clone(), pair3.clone()];
|
||||
let networks = vec![(network_id, new_network_data, 0u64)];
|
||||
|
||||
new_test_ext(authorities, networks).execute_with(|| {
|
||||
let current_substrate_block = 10;
|
||||
let current_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
|
||||
|
||||
let target_hash = H256::repeat_byte(0xAA);
|
||||
LoomStates::<TestRuntime>::insert(&network_id, ¤t_session, crate::LoomState {
|
||||
root_hash: target_hash,
|
||||
at_block: 0,
|
||||
});
|
||||
|
||||
System::set_block_number(current_substrate_block);
|
||||
GhostWeaver::on_initialize(current_substrate_block);
|
||||
|
||||
let tapestry_draft = TapestryDraftBuilder::default()
|
||||
.with_current_block(current_substrate_block)
|
||||
.with_block_delay(5u32)
|
||||
.with_median_external(100)
|
||||
.build();
|
||||
|
||||
TapestryDrafts::<TestRuntime>::insert(&network_id, tapestry_draft);
|
||||
|
||||
let attestation = AttestationContext::default()
|
||||
.with_current_block(current_substrate_block)
|
||||
.with_network_id(network_id)
|
||||
.with_weaving_session(current_session);
|
||||
|
||||
let hash_att1 = attestation
|
||||
.with_authority_index(0)
|
||||
.build_hash_attestation(target_hash, current_session);
|
||||
|
||||
let hash_att2 = attestation
|
||||
.with_authority_index(1)
|
||||
.build_hash_attestation(target_hash, current_session);
|
||||
|
||||
let hash_att3 = attestation
|
||||
.with_authority_index(2)
|
||||
.build_hash_attestation(target_hash, current_session);
|
||||
|
||||
assert!(GhostWeaver::weave_weft(
|
||||
RuntimeOrigin::none(),
|
||||
hash_att1,
|
||||
pair1.sign(&hash_att1.encode())
|
||||
)
|
||||
.is_ok());
|
||||
assert!(GhostWeaver::weave_weft(
|
||||
RuntimeOrigin::none(),
|
||||
hash_att2,
|
||||
pair2.sign(&hash_att2.encode())
|
||||
)
|
||||
.is_ok());
|
||||
assert!(GhostWeaver::weave_weft(
|
||||
RuntimeOrigin::none(),
|
||||
hash_att3,
|
||||
pair3.sign(&hash_att3.encode())
|
||||
)
|
||||
.is_ok());
|
||||
|
||||
let state_before = WeavingStates::<TestRuntime>::get(&network_id);
|
||||
assert_eq!(state_before.count, 3);
|
||||
assert_eq!(state_before.hash, target_hash);
|
||||
|
||||
GhostWeaver::on_initialize(current_substrate_block);
|
||||
|
||||
let saved_loom = LoomStates::<TestRuntime>::get(&network_id, current_session);
|
||||
|
||||
assert_eq!(saved_loom.root_hash, target_hash);
|
||||
assert_eq!(saved_loom.at_block, 100);
|
||||
|
||||
let updated_session = CurrentWeavingSession::<TestRuntime>::get(&network_id);
|
||||
assert_eq!(updated_session, current_session);
|
||||
|
||||
@ -52,6 +52,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Default,
|
||||
RuntimeDebug,
|
||||
Clone,
|
||||
Copy,
|
||||
Eq,
|
||||
PartialEq,
|
||||
Ord,
|
||||
PartialOrd,
|
||||
Encode,
|
||||
Decode,
|
||||
TypeInfo,
|
||||
MaxEncodedLen,
|
||||
)]
|
||||
pub struct LoomState {
|
||||
pub at_block: ExternalBlockNumber,
|
||||
pub root_hash: H256,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Default,
|
||||
RuntimeDebug,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user