sp_statement_store/store_api.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18pub use crate::runtime_api::StatementSource;
19use crate::{Hash, Statement, Topic};
20
21/// Statement store error.
22#[derive(Debug, Clone, Eq, PartialEq, thiserror::Error)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub enum Error {
25 /// Database error.
26 #[error("Database error: {0:?}")]
27 Db(String),
28 /// Error decoding statement structure.
29 #[error("Error decoding statement: {0:?}")]
30 Decode(String),
31 /// Error making runtime call.
32 #[error("Error calling into the runtime")]
33 Runtime,
34}
35
36/// Reason why a statement was rejected from the store.
37#[derive(Debug, Clone, Eq, PartialEq)]
38#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
39#[cfg_attr(feature = "serde", serde(tag = "reason", rename_all = "camelCase"))]
40pub enum RejectionReason {
41 /// Statement data exceeds the maximum allowed size for the account.
42 DataTooLarge {
43 /// The size of the submitted statement data.
44 submitted_size: usize,
45 /// Still available data size for the account.
46 available_size: usize,
47 },
48 /// Attempting to replace a channel message with lower or equal priority.
49 ChannelPriorityTooLow {
50 /// The priority of the submitted statement.
51 submitted_priority: u32,
52 /// The minimum priority of the existing channel message.
53 min_priority: u32,
54 },
55 /// Account reached its statement limit and submitted priority is too low to evict existing.
56 AccountFull {
57 /// The priority of the submitted statement.
58 submitted_priority: u32,
59 /// The minimum priority of the existing statement.
60 min_priority: u32,
61 },
62 /// The global statement store is full and cannot accept new statements.
63 StoreFull,
64}
65
66/// Reason why a statement failed validation.
67#[derive(Debug, Clone, Eq, PartialEq)]
68#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
69#[cfg_attr(feature = "serde", serde(tag = "reason", rename_all = "camelCase"))]
70pub enum InvalidReason {
71 /// Statement has no proof.
72 NoProof,
73 /// Proof validation failed.
74 BadProof,
75 /// Statement exceeds max allowed statement size.
76 EncodingTooLarge {
77 /// The size of the submitted statement encoding.
78 submitted_size: usize,
79 /// The maximum allowed size.
80 max_size: usize,
81 },
82}
83
84/// Statement submission outcome
85#[derive(Debug, Clone, Eq, PartialEq)]
86#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
87#[cfg_attr(feature = "serde", serde(tag = "status", rename_all = "camelCase"))]
88pub enum SubmitResult {
89 /// Statement was accepted as new.
90 New,
91 /// Statement was already known.
92 Known,
93 /// Statement was already known but has expired.
94 KnownExpired,
95 /// Statement was rejected because the store is full or priority is too low.
96 Rejected(RejectionReason),
97 /// Statement failed validation.
98 Invalid(InvalidReason),
99 /// Internal store error.
100 InternalError(Error),
101}
102
103/// Result type for `Error`
104pub type Result<T> = std::result::Result<T, Error>;
105
106/// Statement store API.
107pub trait StatementStore: Send + Sync {
108 /// Return all statements.
109 fn statements(&self) -> Result<Vec<(Hash, Statement)>>;
110
111 /// Return recent statements and clear the internal index.
112 ///
113 /// This consumes and clears the recently received statements,
114 /// allowing new statements to be collected from this point forward.
115 fn take_recent_statements(&self) -> Result<Vec<(Hash, Statement)>>;
116
117 /// Get statement by hash.
118 fn statement(&self, hash: &Hash) -> Result<Option<Statement>>;
119
120 /// Check if statement exists in the store
121 ///
122 /// Fast index check without accessing the DB.
123 fn has_statement(&self, hash: &Hash) -> bool;
124
125 /// Return the data of all known statements which include all topics and have no `DecryptionKey`
126 /// field.
127 fn broadcasts(&self, match_all_topics: &[Topic]) -> Result<Vec<Vec<u8>>>;
128
129 /// Return the data of all known statements whose decryption key is identified as `dest` (this
130 /// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
131 /// private key for symmetric ciphers).
132 fn posted(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>>;
133
134 /// Return the decrypted data of all known statements whose decryption key is identified as
135 /// `dest`. The key must be available to the client.
136 fn posted_clear(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>>;
137
138 /// Return all known statements which include all topics and have no `DecryptionKey`
139 /// field.
140 fn broadcasts_stmt(&self, match_all_topics: &[Topic]) -> Result<Vec<Vec<u8>>>;
141
142 /// Return all known statements whose decryption key is identified as `dest` (this
143 /// will generally be the public key or a hash thereof for symmetric ciphers, or a hash of the
144 /// private key for symmetric ciphers).
145 fn posted_stmt(&self, match_all_topics: &[Topic], dest: [u8; 32]) -> Result<Vec<Vec<u8>>>;
146
147 /// Return the statement and the decrypted data of all known statements whose decryption key is
148 /// identified as `dest`. The key must be available to the client.
149 ///
150 /// The result is for each statement: the SCALE-encoded statement concatenated to the
151 /// decrypted data.
152 fn posted_clear_stmt(&self, match_all_topics: &[Topic], dest: [u8; 32])
153 -> Result<Vec<Vec<u8>>>;
154
155 /// Submit a statement.
156 fn submit(&self, statement: Statement, source: StatementSource) -> SubmitResult;
157
158 /// Remove a statement from the store.
159 fn remove(&self, hash: &Hash) -> Result<()>;
160
161 /// Remove all statements authored by `who`.
162 fn remove_by(&self, who: [u8; 32]) -> Result<()>;
163}