Skip to content

Commit a923d5c

Browse files
authored
fix: 🐛 correctly emit mutations in events (#613)
* fix: 🐛 correctly emit mutations in events This makes it so we emit the mutations with their value in the `MutationsApplied` and `MutationsAppliedForProvider` events, so providers that listen to them can process them accordingly and, for example, revert them during a reorg. * fix: 🐛 correctly match trie remove mutations in task
1 parent 06813a9 commit a923d5c

File tree

14 files changed

+170
-134
lines changed

14 files changed

+170
-134
lines changed

client/src/tasks/bsp_delete_file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use shc_blockchain_service::events::{
77
use shc_common::{
88
consts::CURRENT_FOREST_KEY,
99
traits::StorageEnableRuntime,
10-
types::{FileKey, TrieMutation, TrieRemoveMutation},
10+
types::{FileKey, TrieMutation},
1111
};
1212
use shc_file_manager::traits::FileStorage;
1313
use shc_forest_manager::traits::{ForestStorage, ForestStorageHandler};
@@ -202,7 +202,7 @@ where
202202
let file_key = FileKey::from(mutation.0);
203203

204204
// Only process remove mutations in this task.
205-
if mutation.1 != TrieMutation::Remove(TrieRemoveMutation::new()) {
205+
if !matches!(mutation.1, TrieMutation::Remove(_)) {
206206
debug!(target: LOG_TARGET, "Skipping non-remove mutation for file key {:?}", file_key);
207207
continue;
208208
}

client/src/tasks/msp_delete_file.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use shc_blockchain_service::events::{
66
};
77
use shc_common::{
88
traits::StorageEnableRuntime,
9-
types::{FileKey, TrieMutation, TrieRemoveMutation},
9+
types::{FileKey, TrieMutation},
1010
};
1111
use shc_file_manager::traits::FileStorage;
1212
use shc_forest_manager::traits::{ForestStorage, ForestStorageHandler};
@@ -106,8 +106,8 @@ where
106106
// Get the file key from the mutation.
107107
let file_key = FileKey::from(mutation.0);
108108

109-
// Only process remove mutations in this task..
110-
if mutation.1 != TrieMutation::Remove(TrieRemoveMutation::new()) {
109+
// Only process remove mutations in this task.
110+
if !matches!(mutation.1, TrieMutation::Remove(_)) {
111111
debug!(target: LOG_TARGET, "Skipping non-remove mutation for file key {:?}", file_key);
112112
continue;
113113
}

pallets/file-system/src/mock.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use sp_runtime::{
2727
traits::{BlakeTwo256, Convert, ConvertBack, IdentifyAccount, IdentityLookup, Verify, Zero},
2828
BuildStorage, DispatchError, MultiSignature, Perbill, SaturatedConversion,
2929
};
30-
use sp_std::collections::btree_set::BTreeSet;
30+
use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
3131
use sp_trie::{CompactProof, LayoutV1, MemoryDB, TrieConfiguration, TrieLayout};
3232
use sp_weights::FixedFee;
3333
use std::{
@@ -557,7 +557,7 @@ where
557557
(
558558
MemoryDB<T::Hash>,
559559
Self::Key,
560-
Vec<(Self::Key, Option<Vec<u8>>)>,
560+
BTreeMap<Self::Key, TrieMutation>,
561561
),
562562
DispatchError,
563563
> {
@@ -567,7 +567,7 @@ where
567567
0 => *root,
568568
_ => mutations.last().unwrap().0,
569569
},
570-
Vec::new(),
570+
BTreeMap::new(),
571571
))
572572
}
573573
}

pallets/payment-streams/src/mock.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use sp_runtime::{
2525
use sp_runtime::{traits::Convert, BoundedBTreeSet};
2626
use sp_trie::{CompactProof, LayoutV1, MemoryDB, TrieConfiguration, TrieLayout};
2727
use sp_weights::Weight;
28-
use std::collections::BTreeSet;
28+
use std::collections::{BTreeMap, BTreeSet};
2929

3030
type Block = frame_system::mocking::MockBlock<Test>;
3131
type Balance = u128;
@@ -381,12 +381,12 @@ where
381381
(
382382
MemoryDB<T::Hash>,
383383
Self::Key,
384-
Vec<(Self::Key, Option<Vec<u8>>)>,
384+
BTreeMap<Self::Key, TrieMutation>,
385385
),
386386
DispatchError,
387387
> {
388388
// Just return the root as is with no mutations
389-
Ok((MemoryDB::<T::Hash>::default(), *root, Vec::new()))
389+
Ok((MemoryDB::<T::Hash>::default(), *root, BTreeMap::new()))
390390
}
391391
}
392392

pallets/proofs-dealer/src/mock.rs

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ use frame_system::{pallet_prelude::BlockNumberFor, EnsureRoot, EnsureSigned};
1414
use shp_file_metadata::{FileMetadata, Fingerprint};
1515
use shp_traits::{
1616
CommitRevealRandomnessInterface, CommitmentVerifier, MaybeDebug, ProofSubmittersInterface,
17-
TrieMutation, TrieProofDeltaApplier,
17+
TrieMutation, TrieProofDeltaApplier, TrieRemoveMutation,
1818
};
1919
use shp_treasury_funding::NoCutTreasuryCutCalculator;
2020
use sp_core::{hashing::blake2_256, ConstU128, ConstU32, ConstU64, Hasher, H256};
2121
use sp_runtime::{
2222
traits::{BlakeTwo256, Convert, ConvertBack, IdentityLookup},
2323
BuildStorage, DispatchError, Perbill, SaturatedConversion,
2424
};
25-
use sp_std::collections::btree_set::BTreeSet;
25+
use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
2626
use sp_trie::{CompactProof, LayoutV1, MemoryDB, TrieConfiguration, TrieLayout};
2727

2828
type Block = frame_system::mocking::MockBlock<Test>;
@@ -422,53 +422,57 @@ where
422422
(
423423
MemoryDB<T::Hash>,
424424
Self::Key,
425-
Vec<(Self::Key, Option<Vec<u8>>)>,
425+
BTreeMap<Self::Key, TrieMutation>,
426426
),
427427
DispatchError,
428428
> {
429429
let last_key = mutations.last().unwrap().0;
430430

431431
let db = MemoryDB::<T::Hash>::default();
432432

433-
let mutated_keys_and_values = mutations
434-
.iter()
435-
.map(|(key, mutation)| {
436-
let value = match mutation {
437-
TrieMutation::Add(add_mutation) => Some(add_mutation.value.clone()),
438-
TrieMutation::Remove(_) => {
439-
let file_metadata: FileMetadata<
440-
{ shp_constants::H_LENGTH },
441-
{ shp_constants::FILE_CHUNK_SIZE },
442-
{ shp_constants::FILE_SIZE_TO_CHALLENGES },
443-
> = match FileMetadata::new(
444-
1_u64.encode(),
445-
blake2_256(b"bucket").as_ref().to_vec(),
446-
b"path/to/file".to_vec(),
447-
1,
448-
Fingerprint::default().into(),
449-
) {
450-
Ok(file_metadata) => file_metadata,
451-
Err(_) => {
452-
return Err(DispatchError::Other("Failed to create file metadata"))
453-
}
454-
};
455-
456-
if key.as_ref() != [0; H_LENGTH] {
457-
Some(file_metadata.encode())
458-
} else {
459-
Some(vec![1, 2, 3, 4, 5, 6]) // We make it so the metadata is invalid for the empty key
433+
let mut applied_mutations = BTreeMap::new();
434+
435+
for (key, mutation) in mutations {
436+
match mutation {
437+
TrieMutation::Add(add_mutation) => {
438+
applied_mutations.insert(*key, add_mutation.clone().into());
439+
}
440+
TrieMutation::Remove(_) => {
441+
let file_metadata: FileMetadata<
442+
{ shp_constants::H_LENGTH },
443+
{ shp_constants::FILE_CHUNK_SIZE },
444+
{ shp_constants::FILE_SIZE_TO_CHALLENGES },
445+
> = match FileMetadata::new(
446+
1_u64.encode(),
447+
blake2_256(b"bucket").as_ref().to_vec(),
448+
b"path/to/file".to_vec(),
449+
1,
450+
Fingerprint::default().into(),
451+
) {
452+
Ok(file_metadata) => file_metadata,
453+
Err(_) => {
454+
return Err(DispatchError::Other("Failed to create file metadata"))
460455
}
456+
};
457+
458+
if key.as_ref() != [0; H_LENGTH] {
459+
applied_mutations.insert(
460+
*key,
461+
TrieRemoveMutation::with_value(file_metadata.encode()).into(),
462+
);
463+
} else {
464+
applied_mutations.insert(
465+
*key,
466+
TrieRemoveMutation::with_value(vec![1, 2, 3, 4, 5, 6]).into(),
467+
); // We make it so the metadata is invalid for the empty key
461468
}
462-
};
463-
Ok((*key, value))
464-
})
465-
.collect::<Result<Vec<_>, _>>()?;
466-
467-
let mutated_keys_and_values = mutated_keys_and_values;
469+
}
470+
}
471+
}
468472

469473
// Return default db, the last key in mutations as the new root, and a
470474
// vector holding the supposedly mutated keys and values, so it is deterministic for testing.
471-
Ok((db, last_key, mutated_keys_and_values))
475+
Ok((db, last_key, applied_mutations))
472476
}
473477
}
474478

pallets/proofs-dealer/src/tests.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use frame_system::{
1717
limits::BlockWeights, pallet_prelude::BlockNumberFor, BlockWeight, ConsumedWeight,
1818
};
1919
use pallet_storage_providers::HoldReason;
20+
use shp_file_metadata::{FileMetadata, Fingerprint};
2021
use shp_traits::{ProofsDealerInterface, ReadChallengeableProvidersInterface, TrieRemoveMutation};
2122
use sp_core::{blake2_256, Get, Hasher, H256};
2223
use sp_runtime::{
@@ -1628,6 +1629,21 @@ fn submit_proof_with_checkpoint_challenges_mutations_success() {
16281629
// Dispatch submit proof extrinsic.
16291630
assert_ok!(ProofsDealer::submit_proof(user.clone(), proof, None));
16301631

1632+
// Construct the file metadata that the mock returns for remove mutations.
1633+
// This must match the file metadata constructed in the mock's apply_delta.
1634+
let file_metadata: FileMetadata<
1635+
{ shp_constants::H_LENGTH },
1636+
{ shp_constants::FILE_CHUNK_SIZE },
1637+
{ shp_constants::FILE_SIZE_TO_CHALLENGES },
1638+
> = FileMetadata::new(
1639+
1_u64.encode(),
1640+
blake2_256(b"bucket").as_ref().to_vec(),
1641+
b"path/to/file".to_vec(),
1642+
1,
1643+
Fingerprint::default().into(),
1644+
)
1645+
.expect("Failed to create file metadata");
1646+
16311647
// Check that the event for mutations applied is emitted.
16321648
System::assert_has_event(
16331649
Event::MutationsAppliedForProvider {
@@ -1636,7 +1652,10 @@ fn submit_proof_with_checkpoint_challenges_mutations_success() {
16361652
.iter()
16371653
.filter_map(|custom_challenge| {
16381654
if custom_challenge.should_remove_key {
1639-
Some((custom_challenge.key, TrieRemoveMutation::default().into()))
1655+
Some((
1656+
custom_challenge.key,
1657+
TrieRemoveMutation::with_value(file_metadata.encode()).into(),
1658+
))
16401659
} else {
16411660
None
16421661
}

pallets/proofs-dealer/src/utils.rs

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ where
323323

324324
if !mutations.is_empty() {
325325
// Apply the mutations to the Forest.
326-
let (_, new_root, mutated_keys_and_values) = <T::ForestVerifier as TrieProofDeltaApplier<
326+
let (_, new_root, applied_mutations) = <T::ForestVerifier as TrieProofDeltaApplier<
327327
T::MerkleTrieHashing,
328328
>>::apply_delta(
329329
&root, mutations.as_slice(), forest_proof
@@ -332,21 +332,24 @@ where
332332

333333
// Check that the number of mutated keys is the same as the mutations expected.
334334
ensure!(
335-
mutated_keys_and_values.len() == mutations.len(),
335+
applied_mutations.len() == mutations.len(),
336336
Error::<T>::UnexpectedNumberOfRemoveMutations
337337
);
338338

339-
for (key, maybe_value) in mutated_keys_and_values.iter() {
339+
for (key, mutation) in applied_mutations.iter() {
340340
// Remove the mutated key from the list of `forest_keys_proven` to avoid having to verify the key proof.
341341
forest_keys_proven.remove(key);
342342

343343
// Use the interface exposed by the Providers pallet to update the submitting Provider
344344
// after the key removal if the key had a value.
345-
if let Some(trie_value) = maybe_value {
346-
ProvidersPalletFor::<T>::update_provider_after_key_removal(
347-
submitter, trie_value,
348-
)
349-
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
345+
if let TrieMutation::Remove(trie_remove_mutation) = mutation {
346+
if let Some(trie_value) = &trie_remove_mutation.maybe_value {
347+
ProvidersPalletFor::<T>::update_provider_after_key_removal(
348+
submitter,
349+
&trie_value,
350+
)
351+
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
352+
}
350353
}
351354
}
352355

@@ -363,7 +366,7 @@ where
363366
// Emit event of mutation applied.
364367
Self::deposit_event(Event::MutationsAppliedForProvider {
365368
provider_id: *submitter,
366-
mutations: mutations.to_vec(),
369+
mutations: applied_mutations.into_iter().collect(),
367370
old_root: root,
368371
new_root,
369372
});
@@ -1097,16 +1100,15 @@ impl<T: pallet::Config> ProofsDealerInterface for Pallet<T> {
10971100
let root = ProvidersPalletFor::<T>::get_root(*provider_id)
10981101
.ok_or(Error::<T>::ProviderRootNotFound)?;
10991102

1100-
let (_, new_root, _) =
1101-
<T::ForestVerifier as TrieProofDeltaApplier<T::MerkleTrieHashing>>::apply_delta(
1102-
&root, mutations, proof,
1103-
)
1104-
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
1103+
let (_, new_root, applied_mutations) = <T::ForestVerifier as TrieProofDeltaApplier<
1104+
T::MerkleTrieHashing,
1105+
>>::apply_delta(&root, mutations, proof)
1106+
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
11051107

11061108
// Emit event of mutation applied.
11071109
Self::deposit_event(Event::MutationsAppliedForProvider {
11081110
provider_id: *provider_id,
1109-
mutations: mutations.to_vec(),
1111+
mutations: applied_mutations.into_iter().collect(),
11101112
old_root: root,
11111113
new_root,
11121114
});
@@ -1120,15 +1122,14 @@ impl<T: pallet::Config> ProofsDealerInterface for Pallet<T> {
11201122
proof: &Self::ForestProof,
11211123
event_info: Option<Vec<u8>>,
11221124
) -> Result<Self::MerkleHash, DispatchError> {
1123-
let (_, new_root, _) =
1124-
<T::ForestVerifier as TrieProofDeltaApplier<T::MerkleTrieHashing>>::apply_delta(
1125-
&root, mutations, proof,
1126-
)
1127-
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
1125+
let (_, new_root, applied_mutations) = <T::ForestVerifier as TrieProofDeltaApplier<
1126+
T::MerkleTrieHashing,
1127+
>>::apply_delta(&root, mutations, proof)
1128+
.map_err(|_| Error::<T>::FailedToApplyDelta)?;
11281129

11291130
// Emit event of mutation applied.
11301131
Self::deposit_event(Event::MutationsApplied {
1131-
mutations: mutations.to_vec(),
1132+
mutations: applied_mutations.into_iter().collect(),
11321133
old_root: *root,
11331134
new_root,
11341135
event_info,

0 commit comments

Comments
 (0)