-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathconfig_builder.rs
64 lines (57 loc) · 2.69 KB
/
config_builder.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//! Custom GenesisConfigBuilder for Tuxedo, to allow extrinsics to be added to the genesis block.
use crate::{
ensure,
types::{OutputRef, Transaction},
ConstraintChecker, Verifier, EXTRINSIC_KEY, HEIGHT_KEY,
};
use parity_scale_codec::Encode;
use sp_runtime::traits::Hash as HashT;
use sp_std::vec::Vec;
pub struct TuxedoGenesisConfigBuilder<V, C>(sp_std::marker::PhantomData<(V, C)>);
impl<V, C> TuxedoGenesisConfigBuilder<V, C>
where
V: Verifier,
C: ConstraintChecker,
Transaction<V, C>: Encode,
{
/// This function expects a list of transactions to be included in the genesis block,
/// and stored along with their outputs. They must not contain any inputs or peeks.
/// The input transactions must be ordered: inherents first, then extrinsics.
/// The genesis transactions will not be validated by the corresponding ConstraintChecker or Verifier.
pub fn build(genesis_transactions: Vec<Transaction<V, C>>) -> sp_genesis_builder::Result {
// The transactions are stored under a special key.
sp_io::storage::set(EXTRINSIC_KEY, &genesis_transactions.encode());
//TODO This was added in during merge conflicts. Make sure inherents are working even in real parachains.
// Initialize the stored block number to 0
sp_io::storage::set(HEIGHT_KEY, &0u32.encode());
let mut finished_with_opening_inherents = false;
for tx in genesis_transactions.into_iter() {
// Enforce that inherents are in the right place
let current_tx_is_inherent = tx.checker.is_inherent();
if current_tx_is_inherent && finished_with_opening_inherents {
return Err(
"Tried to execute opening inherent after switching to non-inherents.".into(),
);
}
if !current_tx_is_inherent && !finished_with_opening_inherents {
// This is the first non-inherent, so we update our flag and continue.
finished_with_opening_inherents = true;
}
// Enforce that transactions do not have any inputs or peeks.
ensure!(
tx.inputs.is_empty() && tx.peeks.is_empty(),
"Genesis transactions must not have any inputs or peeks."
);
// Insert the outputs into the storage.
let tx_hash = sp_runtime::traits::BlakeTwo256::hash_of(&tx.encode());
for (index, utxo) in tx.outputs.iter().enumerate() {
let output_ref = OutputRef {
tx_hash,
index: index as u32,
};
sp_io::storage::set(&output_ref.encode(), &utxo.encode());
}
}
Ok(())
}
}