Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds unit test for OB RPC #721

Merged
merged 4 commits into from
Apr 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 42 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions clients/orderbook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ env_logger = "0.10.0"
mockall = "0.11.1"
testing_logger = "0.1.1"
mockall_double = "0.3.0"
orderbook-rpc = {path="rpc"}
sc-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.37" }
69 changes: 41 additions & 28 deletions clients/orderbook/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ use jsonrpsee::{
use log::info;
use orderbook::DbRef;
use orderbook_primitives::{
types::{AccountAsset, ObMessage, ObRecoveryState},
recovery::ObRecoveryState,
types::{AccountAsset, ObMessage},
ObApi,
};
use parking_lot::RwLock;
Expand All @@ -23,7 +24,6 @@ use reference_trie::ExtensionLayout;
use rust_decimal::Decimal;
use sp_api::ProvideRuntimeApi;
use sp_arithmetic::traits::SaturatedConversion;
use sp_blockchain::HeaderBackend;
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use std::sync::Arc;
use trie_db::{TrieDBMut, TrieDBMutBuilder, TrieMut};
Expand Down Expand Up @@ -90,79 +90,73 @@ pub trait OrderbookApi {
}

/// Implements the OrderbookApi RPC trait for interacting with Orderbook.
pub struct OrderbookRpc<Client, Block> {
pub struct OrderbookRpc<Runtime, Block> {
tx: UnboundedSender<ObMessage>,
_executor: SubscriptionTaskExecutor,
last_successful_block_number_snapshot_created: Arc<RwLock<BlockNumber>>,
memory_db: DbRef,
working_state_root: Arc<RwLock<[u8; 32]>>,
client: Arc<Client>,
runtime: Arc<Runtime>,
_marker: std::marker::PhantomData<Block>,
}

impl<Client, Block> OrderbookRpc<Client, Block> {
impl<Runtime, Block> OrderbookRpc<Runtime, Block>
where
Block: BlockT,
Runtime: Send + Sync + ProvideRuntimeApi<Block>,
Runtime::Api: ObApi<Block>,
{
/// Creates a new Orderbook Rpc handler instance.
pub fn new(
_executor: SubscriptionTaskExecutor,
tx: UnboundedSender<ObMessage>,
last_successful_block_number_snapshot_created: Arc<RwLock<BlockNumber>>,
memory_db: DbRef,
working_state_root: Arc<RwLock<[u8; 32]>>,
client: Arc<Client>,
runtime: Arc<Runtime>,
) -> Self {
Self {
tx,
_executor,
last_successful_block_number_snapshot_created,
memory_db,
working_state_root,
client,
runtime,
_marker: Default::default(),
}
}
}

#[async_trait]
impl<Client, Block> OrderbookApiServer for OrderbookRpc<Client, Block>
where
Block: BlockT,
Client: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
Client::Api: ObApi<Block>,
{
async fn submit_action(&self, message: ObMessage) -> RpcResult<()> {
let mut tx = self.tx.clone();
tx.send(message).await?;
Ok(())
}

async fn get_orderbook_recovery_state(&self) -> RpcResult<Vec<u8>> {
/// Returns the serialized offchain state based on the last finalized snapshot summary
pub async fn get_orderbook_recovery_state_inner(&self) -> RpcResult<Vec<u8>> {
let last_finalized_block_guard = self.last_successful_block_number_snapshot_created.read();
let last_finalized_block = *last_finalized_block_guard;

let memory_db_guard = self.memory_db.read();
let mut memory_db = memory_db_guard.clone();
let worker_state_root_guard = self.working_state_root.read();
let mut worker_state_root = *worker_state_root_guard;

info!(target:"orderbook-rpc","Getting all registered accounts at last finalized snapshot");
// get all accounts
let all_register_accounts = self
.client
.runtime
.runtime_api()
.get_all_accounts_and_proxies(&BlockId::number(last_finalized_block.saturated_into()))
.map_err(|err| JsonRpseeError::Custom(err.to_string() + "failed to get accounts"))?;

info!(target:"orderbook-rpc","main accounts found: {:?}, Getting last finalized snapshot summary",all_register_accounts.len());
// get snapshot summary
let last_snapshot_summary = self
.client
.runtime
.runtime_api()
.get_latest_snapshot(&BlockId::number(last_finalized_block.saturated_into()))
.map_err(|err| {
JsonRpseeError::Custom(err.to_string() + "failed to get snapshot summary")
})?;

info!(target:"orderbook-rpc","Getting allowlisted asset ids");
// Get all allow listed AssetIds
let allowlisted_asset_ids = self
.client
.runtime
.runtime_api()
.get_allowlisted_assets(&BlockId::number(last_finalized_block.saturated_into()))
.map_err(|err| {
Expand Down Expand Up @@ -196,7 +190,7 @@ where
}
Ok(())
};

info!(target:"orderbook-rpc","Loading balances from trie to result...");
for (user_main_account, list_of_proxy_accounts) in all_register_accounts {
for asset in allowlisted_asset_ids.clone() {
let account_asset = AccountAsset::new(user_main_account.clone(), asset);
Expand All @@ -208,8 +202,27 @@ where
ob_recovery_state.snapshot_id = last_snapshot_summary.snapshot_id;
ob_recovery_state.state_change_id = last_snapshot_summary.state_change_id;
ob_recovery_state.worker_nonce = last_snapshot_summary.worker_nonce;

info!(target:"orderbook-rpc","Serializing Orderbook snapshot state");
let serialize_ob_recovery_state = serde_json::to_vec(&ob_recovery_state)?;
info!(target:"orderbook-rpc","Orderbook snapshot state exported");
Ok(serialize_ob_recovery_state)
}
}

#[async_trait]
impl<Runtime, Block> OrderbookApiServer for OrderbookRpc<Runtime, Block>
where
Block: BlockT,
Runtime: Send + Sync + 'static + ProvideRuntimeApi<Block>,
Runtime::Api: ObApi<Block>,
{
async fn submit_action(&self, message: ObMessage) -> RpcResult<()> {
let mut tx = self.tx.clone();
tx.send(message).await?;
Ok(())
}

async fn get_orderbook_recovery_state(&self) -> RpcResult<Vec<u8>> {
self.get_orderbook_recovery_state_inner().await
}
}
4 changes: 0 additions & 4 deletions clients/orderbook/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ pub enum Error {
// SnapshotSigningFailed,
#[error("Failed to submit snapshot to runtime")]
FailedToSubmitSnapshotToRuntime,
#[error("Main account already registered")]
MainAlreadyRegistered,
#[error("Proxy account already registered")]
ProxyAlreadyRegistered,
#[error("Offchain storage not available")]
OffchainStorageNotAvailable,
#[error("Signature verification Failed")]
Expand Down
20 changes: 18 additions & 2 deletions clients/orderbook/src/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod rpc;
pub mod sync;

use crate::protocol_standard_name;
Expand All @@ -11,7 +12,8 @@ use orderbook_primitives::{
};
use parking_lot::{Mutex, RwLock};
use polkadex_primitives::{
ocex::TradingPairConfig, withdrawal::Withdrawal, AccountId, BlockNumber,
ingress::IngressMessages, ocex::TradingPairConfig, withdrawal::Withdrawal, AccountId, AssetId,
BlockNumber,
};
use primitive_types::H256;
use reference_trie::RefHasher;
Expand Down Expand Up @@ -40,6 +42,8 @@ pub(crate) struct TestApi {
pub operator_key: Option<Public>,
pub trading_config: Vec<(TradingPair, TradingPairConfig)>,
pub withdrawals: Arc<RwLock<HashMap<u64, Vec<Withdrawal<AccountId>>>>>,
pub ingress_messages: Vec<IngressMessages<AccountId>>,
pub allowlisted_assets: Vec<AssetId>,
}

impl TestApi {
Expand Down Expand Up @@ -139,6 +143,14 @@ impl TestApi {
pub fn read_trading_pair_configs(&self) -> Vec<(TradingPair, TradingPairConfig)> {
self.trading_config.clone()
}

pub fn get_ingress_messages(&self) -> Vec<IngressMessages<AccountId>> {
self.ingress_messages.clone()
}

pub fn get_allowlisted_assets(&self) -> Vec<AssetId> {
self.allowlisted_assets.clone()
}
}

sp_api::mock_impl_runtime_apis! {
Expand All @@ -154,7 +166,7 @@ impl ObApi<Block> for RuntimeApi {
}

/// Return the ingress messages at the given block
fn ingress_messages() -> Vec<polkadex_primitives::ingress::IngressMessages<AccountId>> { Vec::new() }
fn ingress_messages() -> Vec<polkadex_primitives::ingress::IngressMessages<AccountId>> { self.inner.get_ingress_messages() }

/// Submits the snapshot to runtime
fn submit_snapshot(summary: SnapshotSummary<AccountId>) -> Result<(), ()> {
Expand Down Expand Up @@ -196,6 +208,10 @@ impl ObApi<Block> for RuntimeApi {
fn read_trading_pair_configs() -> Vec<(TradingPair, TradingPairConfig)>{
self.inner.read_trading_pair_configs()
}
/// Returns the allowlisted asset ids
fn get_allowlisted_assets() -> Vec<AssetId> {
self.inner.get_allowlisted_assets()
}
}
}

Expand Down