Skip to content

Commit 100b8c2

Browse files
committed
fix(sdk): mock sdk cannot find quorum keys
1 parent c9c4a21 commit 100b8c2

File tree

3 files changed

+68
-46
lines changed

3 files changed

+68
-46
lines changed

packages/rs-sdk/src/mock/sdk.rs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
//! See [MockDashPlatformSdk] for more details.
44
use crate::{
55
platform::{types::identity::IdentityRequest, DocumentQuery, Fetch, FetchMany, Query},
6-
Error,
6+
Error, Sdk,
77
};
8+
use arc_swap::ArcSwapOption;
89
use dapi_grpc::platform::v0::{Proof, ResponseMetadata};
910
use dapi_grpc::{
1011
mock::Mockable,
1112
platform::v0::{self as proto},
1213
};
1314
use dpp::dashcore::Network;
1415
use dpp::version::PlatformVersion;
15-
use drive_proof_verifier::{error::ContextProviderError, FromProof, MockContextProvider};
16+
use drive_proof_verifier::{error::ContextProviderError, ContextProvider, FromProof};
1617
use rs_dapi_client::mock::MockError;
1718
use rs_dapi_client::{
1819
mock::{Key, MockDapiClient},
@@ -34,47 +35,55 @@ use super::MockResponse;
3435
/// ## Panics
3536
///
3637
/// Can panic on errors.
37-
#[derive(Debug, Clone)]
38+
#[derive(Debug)]
3839
pub struct MockDashPlatformSdk {
3940
from_proof_expectations: BTreeMap<Key, Vec<u8>>,
4041
platform_version: &'static PlatformVersion,
4142
dapi: Arc<Mutex<MockDapiClient>>,
42-
prove: bool,
43-
quorum_provider: Option<Arc<MockContextProvider>>,
43+
sdk: ArcSwapOption<Sdk>,
4444
}
4545

4646
impl MockDashPlatformSdk {
47-
pub(crate) fn new(
48-
version: &'static PlatformVersion,
49-
dapi: Arc<Mutex<MockDapiClient>>,
50-
prove: bool,
51-
) -> Self {
47+
/// Returns true when requests should use proofs.
48+
///
49+
/// ## Panics
50+
///
51+
/// Panics when sdk is not set during initialization.
52+
pub fn prove(&self) -> bool {
53+
if let Some(sdk) = self.sdk.load().as_ref() {
54+
sdk.prove()
55+
} else {
56+
panic!("sdk must be set when creating mock ")
57+
}
58+
}
59+
60+
/// Create new mock SDK.
61+
///
62+
/// ## Note
63+
///
64+
/// You have to call [MockDashPlatformSdk::with_sdk()] to set sdk, otherwise Mock SDK will panic.
65+
pub(crate) fn new(version: &'static PlatformVersion, dapi: Arc<Mutex<MockDapiClient>>) -> Self {
5266
Self {
5367
from_proof_expectations: Default::default(),
5468
platform_version: version,
5569
dapi,
56-
prove,
57-
quorum_provider: None,
70+
sdk: ArcSwapOption::new(None),
5871
}
5972
}
6073

61-
pub(crate) fn version<'v>(&self) -> &'v PlatformVersion {
62-
self.platform_version
74+
pub(crate) fn set_sdk(&mut self, sdk: Sdk) {
75+
self.sdk.store(Some(Arc::new(sdk)));
6376
}
64-
/// Define a directory where files containing quorum information, like quorum public keys, are stored.
65-
///
66-
/// This directory will be used to load quorum information from files.
67-
/// You can use [SdkBuilder::with_dump_dir()](crate::SdkBuilder::with_dump_dir()) to generate these files.
68-
pub fn quorum_info_dir<P: AsRef<std::path::Path>>(&mut self, dir: P) -> &mut Self {
69-
let mut provider = MockContextProvider::new();
70-
provider.quorum_keys_dir(Some(dir.as_ref().to_path_buf()));
71-
self.quorum_provider = Some(Arc::new(provider));
7277

73-
self
78+
pub(crate) fn version<'v>(&self) -> &'v PlatformVersion {
79+
self.platform_version
7480
}
7581

7682
/// Load all expectations from files in a directory.
7783
///
84+
///
85+
/// By default, mock expectations are loaded when Sdk is built with [SdkBuilder::build()](crate::SdkBuilder::build()).
86+
/// This function can be used to load expectations after the Sdk is created, or use alternative location.
7887
/// Expectation files must be prefixed with [DapiClient::DUMP_FILE_PREFIX] and
7988
/// have `.json` extension.
8089
pub async fn load_expectations<P: AsRef<std::path::Path>>(
@@ -278,7 +287,7 @@ impl MockDashPlatformSdk {
278287
where
279288
<<O as Fetch>::Request as TransportRequest>::Response: Default,
280289
{
281-
let grpc_request = query.query(self.prove).expect("query must be correct");
290+
let grpc_request = query.query(self.prove()).expect("query must be correct");
282291
self.expect(grpc_request, object).await?;
283292

284293
Ok(self)
@@ -332,7 +341,7 @@ impl MockDashPlatformSdk {
332341
Response = <<O as FetchMany<K, R>>::Request as TransportRequest>::Response,
333342
> + Sync,
334343
{
335-
let grpc_request = query.query(self.prove).expect("query must be correct");
344+
let grpc_request = query.query(self.prove()).expect("query must be correct");
336345
self.expect(grpc_request, objects).await?;
337346

338347
Ok(self)
@@ -393,7 +402,7 @@ impl MockDashPlatformSdk {
393402
),
394403
None => {
395404
let version = self.version();
396-
let provider = self.quorum_provider.as_ref()
405+
let provider = self.context_provider()
397406
.ok_or(ContextProviderError::InvalidQuorum(
398407
"expectation not found and quorum info provider not initialized with sdk.mock().quorum_info_dir()".to_string()
399408
))?;
@@ -402,11 +411,19 @@ impl MockDashPlatformSdk {
402411
response,
403412
Network::Regtest,
404413
version,
405-
provider,
414+
&provider,
406415
)?
407416
}
408417
};
409418

410419
Ok(data)
411420
}
421+
/// Return context provider implementation defined for upstreeam Sdk object.
422+
fn context_provider(&self) -> Option<impl ContextProvider> {
423+
if let Some(sdk) = self.sdk.load_full() {
424+
sdk.clone().context_provider()
425+
} else {
426+
None
427+
}
428+
}
412429
}

packages/rs-sdk/src/sdk.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -840,22 +840,37 @@ impl SdkBuilder {
840840
None => {
841841
let dapi =Arc::new(tokio::sync::Mutex::new( MockDapiClient::new()));
842842
// We create mock context provider that will use the mock DAPI client to retrieve data contracts.
843-
let context_provider = self.context_provider.unwrap_or(Box::new(MockContextProvider::new()));
844-
845-
Sdk {
843+
let context_provider = self.context_provider.unwrap_or_else(||{
844+
let mut cp=MockContextProvider::new();
845+
if let Some(ref dump_dir) = self.dump_dir {
846+
cp.quorum_keys_dir(Some(dump_dir.clone()));
847+
}
848+
Box::new(cp)
849+
}
850+
);
851+
let mock_sdk = MockDashPlatformSdk::new(self.version, Arc::clone(&dapi));
852+
let mock_sdk = Arc::new(Mutex::new(mock_sdk));
853+
let sdk= Sdk {
846854
network: self.network,
847855
inner:SdkInstance::Mock {
848-
mock:Arc::new(Mutex::new( MockDashPlatformSdk::new(self.version, Arc::clone(&dapi), self.proofs))),
856+
mock:mock_sdk.clone(),
849857
dapi,
850858
version:self.version,
851859
},
852860
network_type: self.network_type,
853-
dump_dir: self.dump_dir,
861+
dump_dir: self.dump_dir.clone(),
854862
proofs:self.proofs,
855863
internal_cache: Default::default(),
856864
context_provider:Some(Arc::new(context_provider)),
857865
cancel_token: self.cancel_token,
858-
}
866+
};
867+
let mut guard = mock_sdk.try_lock().expect("mock sdk is in use by another thread and connot be reconfigured");
868+
guard.set_sdk(sdk.clone());
869+
if let Some(ref dump_dir) = self.dump_dir {
870+
pollster::block_on( guard.load_expectations(dump_dir))?;
871+
};
872+
873+
sdk
859874
},
860875
#[cfg(not(feature = "mocks"))]
861876
None => return Err(Error::Config("Mock mode is not available. Please enable `mocks` feature or provide address list.".to_string())),

packages/rs-sdk/tests/fetch/config.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! This module contains [Config] struct that can be used to configure dash-platform-sdk.
44
//! It's mainly used for testing.
55
6-
use dash_sdk::networks::NetworkType;
76
use dpp::platform_value::string_encoding::Encoding;
87
use dpp::{
98
dashcore::{hashes::Hash, ProTxHash},
@@ -211,18 +210,10 @@ impl Config {
211210
// offline testing takes precedence over network testing
212211
#[cfg(feature = "offline-testing")]
213212
let sdk = {
214-
let mut mock_sdk = dash_sdk::SdkBuilder::new_mock()
213+
dash_sdk::SdkBuilder::new_mock()
214+
.with_dump_dir(&dump_dir)
215215
.build()
216-
.expect("initialize api");
217-
218-
mock_sdk
219-
.mock()
220-
.quorum_info_dir(&dump_dir)
221-
.load_expectations(&dump_dir)
222-
.await
223-
.expect("load expectations");
224-
225-
mock_sdk
216+
.expect("initialize api")
226217
};
227218

228219
sdk
@@ -238,7 +229,6 @@ impl Config {
238229
Encoding::Base58,
239230
)
240231
.unwrap()
241-
.into()
242232
}
243233

244234
fn default_data_contract_id() -> Identifier {

0 commit comments

Comments
 (0)