Skip to content

Commit 5e66e75

Browse files
committed
add runtime compatibility code in decoding ER and BlockTreeNode and remove unnecessary clone
1 parent 8469518 commit 5e66e75

File tree

6 files changed

+141
-29
lines changed

6 files changed

+141
-29
lines changed

crates/pallet-domains/src/block_tree.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#[cfg(not(feature = "std"))]
44
extern crate alloc;
55

6+
use crate::migrations::execution_receipt::{get_block_tree_node, take_block_tree_node};
67
use crate::{
78
BalanceOf, BlockTree, BlockTreeNodeFor, BlockTreeNodes, Config, ConsensusBlockHash,
89
DomainBlockNumberFor, DomainGenesisBlockExecutionReceipt, DomainHashingFor,
@@ -54,7 +55,6 @@ pub enum Error {
5455
}
5556

5657
#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
57-
// TODO: migrate
5858
pub struct BlockTreeNode<Number, Hash, DomainNumber, DomainHash, Balance> {
5959
/// The full ER for this block.
6060
pub execution_receipt: ExecutionReceipt<Number, Hash, DomainNumber, DomainHash, Balance>,
@@ -458,12 +458,10 @@ pub(crate) fn process_execution_receipt<T: Config>(
458458
}
459459
AcceptedReceiptType::CurrentHead => {
460460
// Add confirmation to the current head receipt
461-
BlockTreeNodes::<T>::mutate(er_hash, |maybe_node| {
462-
let node = maybe_node.as_mut().expect(
463-
"The domain block of `CurrentHead` receipt is checked to be exist in `execution_receipt_type`; qed"
464-
);
465-
node.operator_ids.push(submitter);
466-
});
461+
let mut node = get_block_tree_node::<T>(er_hash)
462+
.expect("The domain block of `CurrentHead` receipt is checked to be exist in `execution_receipt_type`; qed");
463+
node.operator_ids.push(submitter);
464+
BlockTreeNodes::<T>::insert(er_hash, node);
467465
}
468466
}
469467

@@ -608,7 +606,7 @@ pub(crate) fn prune_receipt<T: Config>(
608606
None => return Ok(None),
609607
};
610608
let block_tree_node =
611-
BlockTreeNodes::<T>::take(receipt_hash).ok_or(Error::MissingDomainBlock)?;
609+
take_block_tree_node::<T>(receipt_hash).ok_or(Error::MissingDomainBlock)?;
612610

613611
// If the pruned ER is the operator's `latest_submitted_er` for this domain, it means either:
614612
//

crates/pallet-domains/src/lib.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern crate alloc;
2424
use crate::block_tree::{Error as BlockTreeError, verify_execution_receipt};
2525
use crate::bundle_storage_fund::{charge_bundle_storage_fee, storage_fund_account};
2626
use crate::domain_registry::{DomainConfig, Error as DomainRegistryError};
27+
use crate::migrations::execution_receipt::get_block_tree_node;
2728
use crate::runtime_registry::into_complete_raw_genesis;
2829
use crate::staking::OperatorStatus;
2930
#[cfg(feature = "runtime-benchmarks")]
@@ -227,6 +228,7 @@ mod pallet {
227228
DomainConfigParams, DomainObject, Error as DomainRegistryError, do_instantiate_domain,
228229
do_update_domain_allow_list,
229230
};
231+
use crate::migrations::execution_receipt::get_block_tree_node;
230232
use crate::runtime_registry::{
231233
DomainRuntimeUpgradeEntry, Error as RuntimeRegistryError, ScheduledRuntimeUpgrade,
232234
do_register_runtime, do_schedule_runtime_upgrade, do_upgrade_runtimes,
@@ -704,15 +706,11 @@ mod pallet {
704706

705707
/// Storage to hold all the domain's latest confirmed block.
706708
#[pallet::storage]
707-
#[pallet::getter(fn latest_confirmed_domain_execution_receipt)]
708-
// TODO: migration
709709
pub type LatestConfirmedDomainExecutionReceipt<T: Config> =
710710
StorageMap<_, Identity, DomainId, ExecutionReceiptOf<T>, OptionQuery>;
711711

712712
/// Storage to hold all the domain's genesis execution receipt.
713713
#[pallet::storage]
714-
#[pallet::getter(fn domain_genesis_block_execution_receipt)]
715-
// TODO: migration
716714
pub type DomainGenesisBlockExecutionReceipt<T: Config> =
717715
StorageMap<_, Identity, DomainId, ExecutionReceiptOf<T>, OptionQuery>;
718716

@@ -1345,7 +1343,7 @@ mod pallet {
13451343
let domain_id = fraud_proof.domain_id();
13461344
let bad_receipt_hash = fraud_proof.targeted_bad_receipt_hash();
13471345
let head_receipt_number = HeadReceiptNumber::<T>::get(domain_id);
1348-
let bad_receipt_number = *BlockTreeNodes::<T>::get(bad_receipt_hash)
1346+
let bad_receipt_number = *get_block_tree_node::<T>(bad_receipt_hash)
13491347
.ok_or::<Error<T>>(FraudProofError::BadReceiptNotFound.into())?
13501348
.execution_receipt
13511349
.domain_block_number();
@@ -1720,7 +1718,7 @@ mod pallet {
17201718
);
17211719

17221720
let head_receipt_number = HeadReceiptNumber::<T>::get(domain_id);
1723-
let bad_receipt_number = *BlockTreeNodes::<T>::get(bad_receipt_hash)
1721+
let bad_receipt_number = *get_block_tree_node::<T>(bad_receipt_hash)
17241722
.ok_or::<Error<T>>(FraudProofError::BadReceiptNotFound.into())?
17251723
.execution_receipt
17261724
.domain_block_number();
@@ -2200,7 +2198,7 @@ impl<T: Config> Pallet<T> {
22002198
}
22012199

22022200
pub fn genesis_state_root(domain_id: DomainId) -> Option<H256> {
2203-
DomainGenesisBlockExecutionReceipt::<T>::get(domain_id)
2201+
crate::migrations::execution_receipt::domain_genesis_block_execution_receipt::<T>(domain_id)
22042202
.map(|er| (*er.final_state_root()).into())
22052203
}
22062204

@@ -2486,7 +2484,7 @@ impl<T: Config> Pallet<T> {
24862484
) -> Result<(DomainId, TransactionPriority), FraudProofError> {
24872485
let domain_id = fraud_proof.domain_id();
24882486
let bad_receipt_hash = fraud_proof.targeted_bad_receipt_hash();
2489-
let bad_receipt = BlockTreeNodes::<T>::get(bad_receipt_hash)
2487+
let bad_receipt = get_block_tree_node::<T>(bad_receipt_hash)
24902488
.ok_or(FraudProofError::BadReceiptNotFound)?
24912489
.execution_receipt;
24922490
let bad_receipt_domain_block_number = *bad_receipt.domain_block_number();
@@ -2562,7 +2560,7 @@ impl<T: Config> Pallet<T> {
25622560
digest_storage_proof,
25632561
}) => {
25642562
let parent_receipt =
2565-
BlockTreeNodes::<T>::get(bad_receipt.parent_domain_block_receipt_hash())
2563+
get_block_tree_node::<T>(*bad_receipt.parent_domain_block_receipt_hash())
25662564
.ok_or(FraudProofError::ParentReceiptNotFound)?
25672565
.execution_receipt;
25682566
verify_invalid_domain_block_hash_fraud_proof::<
@@ -2615,7 +2613,7 @@ impl<T: Config> Pallet<T> {
26152613
fraud_proof.maybe_domain_runtime_code_proof.clone(),
26162614
)?;
26172615
let bad_receipt_parent =
2618-
BlockTreeNodes::<T>::get(bad_receipt.parent_domain_block_receipt_hash())
2616+
get_block_tree_node::<T>(*bad_receipt.parent_domain_block_receipt_hash())
26192617
.ok_or(FraudProofError::ParentReceiptNotFound)?
26202618
.execution_receipt;
26212619

@@ -2638,7 +2636,7 @@ impl<T: Config> Pallet<T> {
26382636
)?;
26392637

26402638
let bad_receipt_parent =
2641-
BlockTreeNodes::<T>::get(bad_receipt.parent_domain_block_receipt_hash())
2639+
get_block_tree_node::<T>(*bad_receipt.parent_domain_block_receipt_hash())
26422640
.ok_or(FraudProofError::ParentReceiptNotFound)?
26432641
.execution_receipt;
26442642

@@ -2775,16 +2773,20 @@ impl<T: Config> Pallet<T> {
27752773
/// Returns the latest confirmed domain block number for a given domain
27762774
/// Zero block is always a default confirmed block.
27772775
pub fn latest_confirmed_domain_block_number(domain_id: DomainId) -> DomainBlockNumberFor<T> {
2778-
LatestConfirmedDomainExecutionReceipt::<T>::get(domain_id)
2779-
.map(|er| *er.domain_block_number())
2780-
.unwrap_or_default()
2776+
crate::migrations::execution_receipt::latest_confirmed_domain_execution_receipt::<T>(
2777+
domain_id,
2778+
)
2779+
.map(|er| *er.domain_block_number())
2780+
.unwrap_or_default()
27812781
}
27822782

27832783
pub fn latest_confirmed_domain_block(
27842784
domain_id: DomainId,
27852785
) -> Option<(DomainBlockNumberFor<T>, T::DomainHash)> {
2786-
LatestConfirmedDomainExecutionReceipt::<T>::get(domain_id)
2787-
.map(|er| (*er.domain_block_number(), *er.domain_block_hash()))
2786+
crate::migrations::execution_receipt::latest_confirmed_domain_execution_receipt::<T>(
2787+
domain_id,
2788+
)
2789+
.map(|er| (*er.domain_block_number(), *er.domain_block_hash()))
27882790
}
27892791

27902792
/// Returns the domain bundle limit of the given domain
@@ -2895,7 +2897,7 @@ impl<T: Config> Pallet<T> {
28952897
}
28962898

28972899
pub fn execution_receipt(receipt_hash: ReceiptHashFor<T>) -> Option<ExecutionReceiptOf<T>> {
2898-
BlockTreeNodes::<T>::get(receipt_hash).map(|db| db.execution_receipt)
2900+
get_block_tree_node::<T>(receipt_hash).map(|db| db.execution_receipt)
28992901
}
29002902

29012903
pub fn receipt_hash(
@@ -3047,7 +3049,7 @@ impl<T: Config> Pallet<T> {
30473049
// that used to derive `receipt` we need to use runtime code at `parent_receipt.consensus_block_number`
30483050
let at = {
30493051
let parent_receipt =
3050-
BlockTreeNodes::<T>::get(receipt.parent_domain_block_receipt_hash())
3052+
get_block_tree_node::<T>(*receipt.parent_domain_block_receipt_hash())
30513053
.ok_or(FraudProofError::ParentReceiptNotFound)?
30523054
.execution_receipt;
30533055
*parent_receipt.consensus_block_number()
@@ -3172,6 +3174,14 @@ impl<T: Config> Pallet<T> {
31723174
) -> Option<sp_domains::PermissionedActionAllowedBy<EthereumAccountId>> {
31733175
EvmDomainContractCreationAllowedByCalls::<T>::get(domain_id).maybe_call
31743176
}
3177+
3178+
pub fn latest_confirmed_domain_execution_receipt(
3179+
domain_id: DomainId,
3180+
) -> Option<ExecutionReceiptOf<T>> {
3181+
crate::migrations::execution_receipt::latest_confirmed_domain_execution_receipt::<T>(
3182+
domain_id,
3183+
)
3184+
}
31753185
}
31763186

31773187
impl<T: Config> sp_domains::DomainOwner<T::AccountId> for Pallet<T> {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub(crate) mod execution_receipt;
12
mod v1_to_v5;
23

34
pub use v1_to_v5::VersionCheckedMigrateDomainsV1ToV5;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#[cfg(not(feature = "std"))]
2+
extern crate alloc;
3+
4+
use crate::pallet::BlockTreeNodes;
5+
use crate::{
6+
BalanceOf, BlockTreeNodeFor, Config, DomainBlockNumberFor, DomainGenesisBlockExecutionReceipt,
7+
ExecutionReceiptOf, LatestConfirmedDomainExecutionReceipt, ReceiptHashFor,
8+
};
9+
#[cfg(not(feature = "std"))]
10+
use alloc::vec::Vec;
11+
use frame_support::pallet_prelude::{Encode, TypeInfo};
12+
use frame_support::storage::generator::StorageMap;
13+
use frame_system::pallet_prelude::BlockNumberFor;
14+
use parity_scale_codec::Decode;
15+
use sp_domains::execution_receipt::execution_receipt_v0::ExecutionReceiptV0;
16+
use sp_domains::{DomainId, OperatorId};
17+
18+
pub(crate) type ExecutionReceiptV0Of<T> = ExecutionReceiptV0<
19+
BlockNumberFor<T>,
20+
<T as frame_system::Config>::Hash,
21+
DomainBlockNumberFor<T>,
22+
<T as Config>::DomainHash,
23+
BalanceOf<T>,
24+
>;
25+
26+
pub fn latest_confirmed_domain_execution_receipt<T: Config>(
27+
domain_id: DomainId,
28+
) -> Option<ExecutionReceiptOf<T>> {
29+
let key = LatestConfirmedDomainExecutionReceipt::<T>::storage_map_final_key(domain_id);
30+
decode_execution_receipt::<T>(key)
31+
}
32+
33+
fn decode_execution_receipt<T: Config>(key: Vec<u8>) -> Option<ExecutionReceiptOf<T>> {
34+
let raw_value = sp_io::storage::get(key.as_slice())?;
35+
match ExecutionReceiptOf::<T>::decode(&mut &raw_value[..]) {
36+
Ok(er) => Some(er),
37+
Err(_) => ExecutionReceiptV0Of::<T>::decode(&mut &raw_value[..])
38+
.ok()
39+
.map(ExecutionReceiptOf::<T>::V0),
40+
}
41+
}
42+
43+
pub fn domain_genesis_block_execution_receipt<T: Config>(
44+
domain_id: DomainId,
45+
) -> Option<ExecutionReceiptOf<T>> {
46+
let key = DomainGenesisBlockExecutionReceipt::<T>::storage_map_final_key(domain_id);
47+
decode_execution_receipt::<T>(key)
48+
}
49+
50+
#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
51+
struct BlockTreeNodeV0<Number, Hash, DomainNumber, DomainHash, Balance> {
52+
/// The full ER for this block.
53+
execution_receipt: ExecutionReceiptV0<Number, Hash, DomainNumber, DomainHash, Balance>,
54+
/// A set of all operators who have committed to this ER within a bundle. Used to determine who to
55+
/// slash if a fraudulent branch of the `block_tree` is pruned.
56+
///
57+
/// NOTE: there may be duplicated operator id as an operator can submit multiple bundles with the
58+
/// same head receipt to a consensus block.
59+
operator_ids: Vec<OperatorId>,
60+
}
61+
62+
type BlockTreeNodeV0For<T> = BlockTreeNodeV0<
63+
BlockNumberFor<T>,
64+
<T as frame_system::Config>::Hash,
65+
DomainBlockNumberFor<T>,
66+
<T as Config>::DomainHash,
67+
BalanceOf<T>,
68+
>;
69+
70+
fn decode_block_tree_node<T: Config>(raw_value: Vec<u8>) -> Option<BlockTreeNodeFor<T>> {
71+
match BlockTreeNodeFor::<T>::decode(&mut &raw_value[..]) {
72+
Ok(er) => Some(er),
73+
Err(_) => BlockTreeNodeV0For::<T>::decode(&mut &raw_value[..])
74+
.ok()
75+
.map(|node| {
76+
let BlockTreeNodeV0 {
77+
execution_receipt,
78+
operator_ids,
79+
} = node;
80+
BlockTreeNodeFor::<T> {
81+
execution_receipt: ExecutionReceiptOf::<T>::V0(execution_receipt),
82+
operator_ids,
83+
}
84+
}),
85+
}
86+
}
87+
88+
pub(crate) fn get_block_tree_node<T: Config>(
89+
receipt_hash: ReceiptHashFor<T>,
90+
) -> Option<BlockTreeNodeFor<T>> {
91+
let key = BlockTreeNodes::<T>::storage_map_final_key(receipt_hash);
92+
let raw_value = sp_io::storage::get(key.as_slice())?;
93+
decode_block_tree_node::<T>(raw_value.to_vec())
94+
}
95+
96+
pub(crate) fn take_block_tree_node<T: Config>(
97+
receipt_hash: ReceiptHashFor<T>,
98+
) -> Option<BlockTreeNodeFor<T>> {
99+
let key = BlockTreeNodes::<T>::storage_map_final_key(receipt_hash);
100+
let raw_value = sp_io::storage::get(key.as_slice())?;
101+
sp_io::storage::clear(key.as_slice());
102+
decode_block_tree_node::<T>(raw_value.to_vec())
103+
}

crates/sc-domains/src/domain_block_er/receipt_receiver.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ async fn send_request<NR: NetworkRequest, Block: BlockT, DomainHeader: Header>(
265265
return Err(DomainBlockERResponseError::InvalidProtocol);
266266
}
267267

268-
let response = match DomainBlockERResponse::decode(&mut data.clone().as_slice()) {
268+
let response = match DomainBlockERResponse::decode(&mut data.as_slice()) {
269269
Ok(response) => Ok(response),
270270
Err(_) => DomainBlockERResponseV0::decode(&mut data.as_slice()).map(Into::into),
271271
}

domains/pallets/messenger/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,7 +1356,7 @@ mod pallet {
13561356
BlockNumberFor<T>,
13571357
T::Hash,
13581358
BalanceOf<T>,
1359-
>::decode(&mut &bare_value.clone()[..])
1359+
>::decode(&mut &bare_value[..])
13601360
{
13611361
Ok(receipt) => Some(receipt),
13621362
Err(_) => ExecutionReceiptV0::<
@@ -1365,7 +1365,7 @@ mod pallet {
13651365
BlockNumberFor<T>,
13661366
T::Hash,
13671367
BalanceOf<T>,
1368-
>::decode(&mut &bare_value.clone()[..])
1368+
>::decode(&mut &bare_value[..])
13691369
.map(ExecutionReceipt::V0)
13701370
.ok(),
13711371
}

0 commit comments

Comments
 (0)