use codec::{Decode, Encode};
use jsonrpsee::{
core::{async_trait, RpcResult},
Extensions,
};
pub use sc_rpc_api::statement::{error::Error, StatementApiServer};
use sp_core::Bytes;
use sp_statement_store::{StatementSource, SubmitResult};
use std::sync::Arc;
pub struct StatementStore {
store: Arc<dyn sp_statement_store::StatementStore>,
}
impl StatementStore {
pub fn new(store: Arc<dyn sp_statement_store::StatementStore>) -> Self {
StatementStore { store }
}
}
#[async_trait]
impl StatementApiServer for StatementStore {
fn dump(&self, ext: &Extensions) -> RpcResult<Vec<Bytes>> {
sc_rpc_api::check_if_safe(ext)?;
let statements =
self.store.statements().map_err(|e| Error::StatementStore(e.to_string()))?;
Ok(statements.into_iter().map(|(_, s)| s.encode().into()).collect())
}
fn broadcasts(&self, match_all_topics: Vec<[u8; 32]>) -> RpcResult<Vec<Bytes>> {
Ok(self
.store
.broadcasts(&match_all_topics)
.map_err(|e| Error::StatementStore(e.to_string()))?
.into_iter()
.map(Into::into)
.collect())
}
fn posted(&self, match_all_topics: Vec<[u8; 32]>, dest: [u8; 32]) -> RpcResult<Vec<Bytes>> {
Ok(self
.store
.posted(&match_all_topics, dest)
.map_err(|e| Error::StatementStore(e.to_string()))?
.into_iter()
.map(Into::into)
.collect())
}
fn posted_clear(
&self,
match_all_topics: Vec<[u8; 32]>,
dest: [u8; 32],
) -> RpcResult<Vec<Bytes>> {
Ok(self
.store
.posted_clear(&match_all_topics, dest)
.map_err(|e| Error::StatementStore(e.to_string()))?
.into_iter()
.map(Into::into)
.collect())
}
fn submit(&self, encoded: Bytes) -> RpcResult<()> {
let statement = Decode::decode(&mut &*encoded)
.map_err(|e| Error::StatementStore(format!("Error decoding statement: {:?}", e)))?;
match self.store.submit(statement, StatementSource::Local) {
SubmitResult::New(_) | SubmitResult::Known => Ok(()),
SubmitResult::KnownExpired =>
Err(Error::StatementStore("Submitted an expired statement.".into()).into()),
SubmitResult::Bad(e) => Err(Error::StatementStore(e.into()).into()),
SubmitResult::Ignored => Err(Error::StatementStore("Store is full.".into()).into()),
SubmitResult::InternalError(e) => Err(Error::StatementStore(e.to_string()).into()),
}
}
fn remove(&self, hash: [u8; 32]) -> RpcResult<()> {
Ok(self.store.remove(&hash).map_err(|e| Error::StatementStore(e.to_string()))?)
}
}