sp_statement_store/
runtime_api.rs1use crate::{Hash, Statement, Topic};
21use alloc::vec::Vec;
22use codec::{Decode, Encode};
23use scale_info::TypeInfo;
24use sp_runtime::RuntimeDebug;
25use sp_runtime_interface::{pass_by::PassByEnum, runtime_interface};
26
27#[cfg(feature = "std")]
28use sp_externalities::ExternalitiesExt;
29
30#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
32pub struct ValidStatement {
33 pub max_count: u32,
35 pub max_size: u32,
37}
38
39#[derive(Clone, PartialEq, Eq, Encode, Decode, Copy, RuntimeDebug, TypeInfo)]
41pub enum InvalidStatement {
42 BadProof,
44 NoProof,
46 InternalError,
48}
49
50#[derive(Copy, Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, TypeInfo)]
54pub enum StatementSource {
55 Chain,
57 Network,
59 Local,
61}
62
63impl StatementSource {
64 pub fn can_be_resubmitted(&self) -> bool {
67 match self {
68 StatementSource::Chain | StatementSource::Local => true,
69 StatementSource::Network => false,
70 }
71 }
72}
73
74sp_api::decl_runtime_apis! {
75 pub trait ValidateStatement {
77 fn validate_statement(
79 source: StatementSource,
80 statement: Statement,
81 ) -> Result<ValidStatement, InvalidStatement>;
82 }
83}
84
85#[cfg(feature = "std")]
86sp_externalities::decl_extension! {
87 pub struct StatementStoreExt(std::sync::Arc<dyn crate::StatementStore>);
89}
90
91#[cfg(feature = "std")]
93impl StatementStoreExt {
94 pub fn new(store: std::sync::Arc<dyn crate::StatementStore>) -> Self {
96 Self(store)
97 }
98}
99
100#[derive(Debug, Eq, PartialEq, Clone, Copy, Encode, Decode, PassByEnum)]
102pub enum SubmitResult {
103 OkNew,
105 OkKnown,
107 Bad,
109 NotAvailable,
111 Full,
113}
114
115#[cfg(feature = "std")]
117pub type HostFunctions = (statement_store::HostFunctions,);
118
119#[runtime_interface]
121pub trait StatementStore {
122 fn submit_statement(&mut self, statement: Statement) -> SubmitResult {
125 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
126 match store.submit(statement, StatementSource::Chain) {
127 crate::SubmitResult::New(_) => SubmitResult::OkNew,
128 crate::SubmitResult::Known => SubmitResult::OkKnown,
129 crate::SubmitResult::Ignored => SubmitResult::Full,
130 crate::SubmitResult::KnownExpired => SubmitResult::Bad,
133 crate::SubmitResult::Bad(_) => SubmitResult::Bad,
134 crate::SubmitResult::InternalError(_) => SubmitResult::Bad,
135 }
136 } else {
137 SubmitResult::NotAvailable
138 }
139 }
140
141 fn statements(&mut self) -> Vec<(Hash, Statement)> {
143 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
144 store.statements().unwrap_or_default()
145 } else {
146 Vec::default()
147 }
148 }
149
150 fn broadcasts(&mut self, match_all_topics: &[Topic]) -> Vec<Vec<u8>> {
153 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
154 store.broadcasts(match_all_topics).unwrap_or_default()
155 } else {
156 Vec::default()
157 }
158 }
159
160 fn posted(&mut self, match_all_topics: &[Topic], dest: [u8; 32]) -> Vec<Vec<u8>> {
164 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
165 store.posted(match_all_topics, dest).unwrap_or_default()
166 } else {
167 Vec::default()
168 }
169 }
170
171 fn posted_clear(&mut self, match_all_topics: &[Topic], dest: [u8; 32]) -> Vec<Vec<u8>> {
174 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
175 store.posted_clear(match_all_topics, dest).unwrap_or_default()
176 } else {
177 Vec::default()
178 }
179 }
180
181 fn remove(&mut self, hash: &Hash) {
183 if let Some(StatementStoreExt(store)) = self.extension::<StatementStoreExt>() {
184 store.remove(hash).unwrap_or_default()
185 }
186 }
187}