Skip to content

Commit

Permalink
Add OffchainDBExt for OB RPC (#888)
Browse files Browse the repository at this point in the history
## Describe your changes
Orderbook RPCs require the registration of OffchainDBExt to access off
chain storage from pallet functions on the rpc crate.
  • Loading branch information
Gauthamastro authored Dec 6, 2023
2 parents af3d9ea + 379849e commit 390523c
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/clients/orderbook/keystore-*
/clients/thea/keystore-*

/fullnode
# Generated by Cargo
# will have compiled files and executables
**/target/
Expand Down
28 changes: 17 additions & 11 deletions pallets/ocex/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ use jsonrpsee::{
use orderbook_primitives::recovery::{DeviationMap, ObCheckpoint, ObRecoveryState};
pub use pallet_ocex_runtime_api::PolkadexOcexRuntimeApi;
use parity_scale_codec::{Codec, Decode};
use parking_lot::RwLock;
use polkadex_primitives::AssetId;
use sc_rpc_api::DenyUnsafe;
use sp_api::ProvideRuntimeApi;
use sp_api::{ApiExt, ProvideRuntimeApi};
use sp_blockchain::HeaderBackend;
use sp_core::offchain::OffchainStorage;
use sp_core::offchain::{storage::OffchainDb, OffchainDbExt, OffchainStorage};
use sp_runtime::traits::Block as BlockT;
use std::sync::Arc;

Expand Down Expand Up @@ -74,7 +73,7 @@ pub struct PolkadexOcexRpc<Client, Block, T: OffchainStorage + 'static> {
client: Arc<Client>,

/// Offchain storage
storage: Arc<RwLock<T>>,
offchain_db: OffchainDb<T>,
deny_unsafe: DenyUnsafe,

/// A marker for the `Block` type parameter, used to ensure the struct
Expand All @@ -86,7 +85,7 @@ impl<Client, Block, T: OffchainStorage> PolkadexOcexRpc<Client, Block, T> {
pub fn new(client: Arc<Client>, storage: T, deny_unsafe: DenyUnsafe) -> Self {
Self {
client,
storage: Arc::new(RwLock::new(storage)),
offchain_db: OffchainDb::new(storage),
deny_unsafe,
_marker: Default::default(),
}
Expand All @@ -109,11 +108,12 @@ where
&self,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<ObRecoveryState> {
let api = self.client.runtime_api();
let mut api = self.client.runtime_api();
let at = match at {
Some(at) => at,
None => self.client.info().best_hash,
};
api.register_extension(OffchainDbExt::new(self.offchain_db.clone()));
// WARN: this is a hack on beating the boundry of runtime ->
// polkadex-node with decoding tuple of underlying data into
// solid std type
Expand All @@ -133,11 +133,13 @@ where
of: AssetId,
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<String> {
let api = self.client.runtime_api();
let mut api = self.client.runtime_api();
let at = match at {
Some(at) => at,
None => self.client.info().best_hash,
};

api.register_extension(OffchainDbExt::new(self.offchain_db.clone()));
let runtime_api_result =
api.get_balance(at, account_id, of).map_err(runtime_error_into_rpc_err)?;
let json =
Expand All @@ -150,12 +152,14 @@ where
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<String> {
self.deny_unsafe.check_if_safe()?;
let api = self.client.runtime_api();
let mut api = self.client.runtime_api();
let at = match at {
Some(at) => at,
None => self.client.info().best_hash,
};
let offchain_storage = offchain::OffchainStorageAdapter::new(self.storage.clone());

api.register_extension(OffchainDbExt::new(self.offchain_db.clone()));
let mut offchain_storage = offchain::OffchainStorageAdapter::new(self.offchain_db.clone());
if !offchain_storage.acquire_offchain_lock(3).await {
return Err(runtime_error_into_rpc_err("Failed to acquire offchain lock"))
}
Expand All @@ -180,12 +184,14 @@ where
at: Option<<Block as BlockT>::Hash>,
) -> RpcResult<ObCheckpoint> {
//self.deny_unsafe.check_if_safe()?; //As it is used by the aggregator, we need to allow it
let api = self.client.runtime_api();
let mut api = self.client.runtime_api();
let at = match at {
Some(at) => at,
None => self.client.info().best_hash,
};
let offchain_storage = offchain::OffchainStorageAdapter::new(self.storage.clone());

api.register_extension(OffchainDbExt::new(self.offchain_db.clone()));
let mut offchain_storage = offchain::OffchainStorageAdapter::new(self.offchain_db.clone());
if !offchain_storage.acquire_offchain_lock(RETRIES).await {
return Err(runtime_error_into_rpc_err("Failed to acquire offchain lock"))
}
Expand Down
19 changes: 8 additions & 11 deletions pallets/ocex/rpc/src/offchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@
//! This adapter is used by `function_handler` to access offchain storage.
use parity_scale_codec::Encode;
use parking_lot::RwLock;
use sp_core::offchain::OffchainStorage;
use std::sync::Arc;
use sp_core::offchain::{storage::OffchainDb, DbExternalities, OffchainStorage, StorageKind};

pub const WORKER_STATUS: [u8; 28] = *b"offchain-ocex::worker_status";

/// Adapter to Access OCEX Offchain Storage
pub struct OffchainStorageAdapter<T: OffchainStorage> {
storage: Arc<RwLock<T>>,
storage: OffchainDb<T>,
}

impl<T: OffchainStorage> OffchainStorageAdapter<T> {
Expand All @@ -38,7 +36,7 @@ impl<T: OffchainStorage> OffchainStorageAdapter<T> {
/// * `storage`: Offchain storage
/// # Returns
/// * `OffchainStorageAdapter`: A new `OffchainStorageAdapter` instance.
pub fn new(storage: Arc<RwLock<T>>) -> Self {
pub fn new(storage: OffchainDb<T>) -> Self {
Self { storage }
}

Expand All @@ -47,13 +45,12 @@ impl<T: OffchainStorage> OffchainStorageAdapter<T> {
/// * `tries`: Number of tries to acquire lock
/// # Returns
/// * `bool`: True if lock is acquired else false
pub async fn acquire_offchain_lock(&self, tries: u8) -> bool {
let prefix = sp_offchain::STORAGE_PREFIX;
pub async fn acquire_offchain_lock(&mut self, tries: u8) -> bool {
let old_value = Encode::encode(&false);
let new_value = Encode::encode(&true);
for _ in 0..tries {
if self.storage.write().compare_and_set(
prefix,
if self.storage.local_storage_compare_and_set(
StorageKind::PERSISTENT,
&WORKER_STATUS,
Some(&old_value),
&new_value,
Expand All @@ -69,8 +66,8 @@ impl<T: OffchainStorage> OffchainStorageAdapter<T> {

impl<T: OffchainStorage> Drop for OffchainStorageAdapter<T> {
fn drop(&mut self) {
let prefix = sp_offchain::STORAGE_PREFIX;
let encoded_value = Encode::encode(&false);
self.storage.write().set(prefix, &WORKER_STATUS, &encoded_value);
self.storage
.local_storage_set(StorageKind::PERSISTENT, &WORKER_STATUS, &encoded_value);
}
}
2 changes: 1 addition & 1 deletion runtimes/mainnet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
// and set impl_version to 0. If only runtime
// implementation changes and behavior does not, then leave spec_version as
// is and increment impl_version.
spec_version: 314,
spec_version: 315,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 3,
Expand Down
7 changes: 7 additions & 0 deletions scripts/fetch_checkpoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
curl -H "Content-Type: application/json" -d '{
"jsonrpc":"2.0",
"id":1,
"method":"ob_fetchCheckpoint",
"params":[]
}' http://localhost:9944
7 changes: 7 additions & 0 deletions scripts/fetch_obRecoverState.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
curl -H "Content-Type: application/json" -d '{
"jsonrpc":"2.0",
"id":1,
"method":"ob_getRecoverState",
"params":[]
}' http://localhost:9944

0 comments on commit 390523c

Please sign in to comment.