1#![cfg_attr(not(feature = "std"), no_std)]
30
31use frame_support::{pallet_prelude::*, traits::fungible::Inspect};
32use frame_system::pallet_prelude::*;
33use sp_statement_store::{Proof, Statement};
34
35pub use pallet::*;
36
37const LOG_TARGET: &str = "runtime::statement";
38
39#[frame_support::pallet]
40pub mod pallet {
41 use super::*;
42
43 pub type BalanceOf<T> =
44 <<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
45
46 pub type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
47
48 #[pallet::config]
49 pub trait Config: frame_system::Config
50 where
51 <Self as frame_system::Config>::AccountId: From<sp_statement_store::AccountId>,
52 {
53 #[allow(deprecated)]
55 type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
56 type Currency: Inspect<Self::AccountId>;
58 #[pallet::constant]
60 type StatementCost: Get<BalanceOf<Self>>;
61 #[pallet::constant]
63 type ByteCost: Get<BalanceOf<Self>>;
64 #[pallet::constant]
66 type MinAllowedStatements: Get<u32>;
67 #[pallet::constant]
69 type MaxAllowedStatements: Get<u32>;
70 #[pallet::constant]
72 type MinAllowedBytes: Get<u32>;
73 #[pallet::constant]
75 type MaxAllowedBytes: Get<u32>;
76 }
77
78 #[pallet::pallet]
79 pub struct Pallet<T>(core::marker::PhantomData<T>);
80
81 #[pallet::event]
82 #[pallet::generate_deposit(pub(super) fn deposit_event)]
83 pub enum Event<T: Config>
84 where
85 <T as frame_system::Config>::AccountId: From<sp_statement_store::AccountId>,
86 {
87 NewStatement { account: T::AccountId, statement: Statement },
89 }
90
91 #[pallet::hooks]
92 impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T>
93 where
94 <T as frame_system::Config>::AccountId: From<sp_statement_store::AccountId>,
95 sp_statement_store::AccountId: From<<T as frame_system::Config>::AccountId>,
96 <T as frame_system::Config>::RuntimeEvent: From<pallet::Event<T>>,
97 <T as frame_system::Config>::RuntimeEvent: TryInto<pallet::Event<T>>,
98 sp_statement_store::BlockHash: From<<T as frame_system::Config>::Hash>,
99 {
100 fn offchain_worker(now: BlockNumberFor<T>) {
101 log::trace!(target: LOG_TARGET, "Collecting statements at #{:?}", now);
102 Pallet::<T>::collect_statements();
103 }
104 }
105}
106
107impl<T: Config> Pallet<T>
108where
109 <T as frame_system::Config>::AccountId: From<sp_statement_store::AccountId>,
110 sp_statement_store::AccountId: From<<T as frame_system::Config>::AccountId>,
111 <T as frame_system::Config>::RuntimeEvent: From<pallet::Event<T>>,
112 <T as frame_system::Config>::RuntimeEvent: TryInto<pallet::Event<T>>,
113 sp_statement_store::BlockHash: From<<T as frame_system::Config>::Hash>,
114{
115 pub fn submit_statement(account: T::AccountId, statement: Statement) {
118 Self::deposit_event(Event::NewStatement { account, statement });
119 }
120
121 fn collect_statements() {
122 for (index, event) in frame_system::Pallet::<T>::read_events_no_consensus().enumerate() {
124 if let Ok(Event::<T>::NewStatement { account, mut statement }) = event.event.try_into()
125 {
126 if statement.proof().is_none() {
127 let proof = Proof::OnChain {
128 who: account.into(),
129 block_hash: frame_system::Pallet::<T>::parent_hash().into(),
130 event_index: index as u64,
131 };
132 statement.set_proof(proof);
133 }
134 sp_statement_store::runtime_api::statement_store::submit_statement(statement);
135 }
136 }
137 }
138}