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

feat(sdk): get node status #2139

Merged
merged 28 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c044004
feat: get node statuses in sdk
pauldelucia Sep 18, 2024
94235ee
fixes
pauldelucia Sep 18, 2024
45ebe6c
error handling
pauldelucia Sep 18, 2024
6d1af4c
return references instead of clones
pauldelucia Sep 19, 2024
7f098fc
fix
pauldelucia Sep 19, 2024
ea65946
Merge branch 'v1.3-dev' into feat/get-node-status-in-sdk
pauldelucia Sep 19, 2024
af067ed
Merge branch 'v1.3-dev' into feat/get-node-status-in-sdk
pauldelucia Sep 19, 2024
e4e26c4
Merge branch 'v1.4-dev' into feat/get-node-status-in-sdk
lklimek Sep 25, 2024
5537a05
Merge branch 'v1.4-dev' into feat/get-node-status-in-sdk
lklimek Sep 26, 2024
e409956
refactor
lklimek Sep 26, 2024
fa4bb87
chore(sdk): status tests
lklimek Sep 26, 2024
bad801c
chore: minor improvements
lklimek Sep 26, 2024
18d3df8
refactor(dapi-client): impl IntoIterator for address list
lklimek Sep 27, 2024
9a86b8f
fix: get status connecting to wrong node
lklimek Sep 27, 2024
beadf24
chore: fix dump of evonode
lklimek Sep 27, 2024
4263ed9
chore: fix mocking
lklimek Sep 27, 2024
99335cd
chore:remove unused bincode
lklimek Sep 27, 2024
e58541d
test(e2e): test vectors
lklimek Sep 27, 2024
ddbda44
chore: impl From<EvoNode> for GetStatusRequest
lklimek Sep 27, 2024
1ff4fce
feat(sdk): EvonodeStatus additional fields
lklimek Sep 27, 2024
9a22712
test(sdk): regen test vectors
lklimek Sep 27, 2024
1912407
chore: more meaningful msg
lklimek Sep 27, 2024
5491d3f
chore: fix features
lklimek Sep 27, 2024
c66c815
Merge remote-tracking branch 'origin/v1.4-dev' into feat/get-node-sta…
lklimek Sep 27, 2024
baa706f
chore: fix build
lklimek Sep 27, 2024
b2caae8
chore: apply review feedback
lklimek Sep 27, 2024
821af1f
refactor: move EvoNodeStatus to separate file
lklimek Sep 27, 2024
7f9c668
refactor: apply rabbit's feedback
lklimek Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/rs-dapi-client/src/address_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ pub enum AddressListError {

/// A structure to manage DAPI addresses to select from
/// for [DapiRequest](crate::DapiRequest) execution.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct AddressList {
addresses: HashSet<Address>,
base_ban_period: Duration,
Expand Down Expand Up @@ -198,6 +198,11 @@ impl AddressList {
pub fn is_empty(&self) -> bool {
self.addresses.is_empty()
}

/// Getter function that returns a reference to the Hashset of addresses
pub fn addresses(&self) -> &HashSet<Address> {
&self.addresses
}
lklimek marked this conversation as resolved.
Show resolved Hide resolved
}

impl From<&str> for AddressList {
Expand Down
5 changes: 5 additions & 0 deletions packages/rs-dapi-client/src/dapi_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ impl DapiClient {
dump_dir: None,
}
}

/// Return the [DapiClient] address list.
pub fn address_list(&self) -> &Arc<RwLock<AddressList>> {
&self.address_list
}
}

#[async_trait]
Expand Down
9 changes: 9 additions & 0 deletions packages/rs-dapi-client/src/transport/grpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,12 @@ impl_transport_request_grpc!(
},
subscribe_to_transactions_with_proofs
);

// rpc getStatus(GetStatusRequest) returns (GetStatusResponse);
impl_transport_request_grpc!(
platform_proto::GetStatusRequest,
platform_proto::GetStatusResponse,
PlatformGrpcClient,
RequestSettings::default(),
get_status
);
1 change: 1 addition & 0 deletions packages/rs-dpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub mod block;
pub mod core_subsidy;
pub mod fee;
pub mod nft;
pub mod node;
lklimek marked this conversation as resolved.
Show resolved Hide resolved
pub mod prefunded_specialized_balance;
pub mod serialization;
#[cfg(any(
Expand Down
1 change: 1 addition & 0 deletions packages/rs-dpp/src/node/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod status;
lklimek marked this conversation as resolved.
Show resolved Hide resolved
39 changes: 39 additions & 0 deletions packages/rs-dpp/src/node/status/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub mod v0;

use crate::ProtocolError;
use bincode::{Decode, Encode};
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
use serde::{Deserialize, Serialize};
use v0::{EvonodeStatusV0, EvonodeStatusV0Getters};

/// Information about the status of an Evonode
#[derive(
Clone,
Debug,
PartialEq,
Serialize,
Deserialize,
Encode,
Decode,
PlatformSerialize,
PlatformDeserialize,
)]
pub enum EvonodeStatus {
V0(EvonodeStatusV0),
}
lklimek marked this conversation as resolved.
Show resolved Hide resolved

impl EvonodeStatusV0Getters for EvonodeStatus {
/// Returns the Evonode Identifier
fn pro_tx_hash(&self) -> String {
match self {
EvonodeStatus::V0(v0) => v0.pro_tx_hash.clone(),
}
}

/// Returns the Evonode's latest stored block height
fn latest_block_height(&self) -> u64 {
match self {
EvonodeStatus::V0(v0) => v0.latest_block_height,
}
}
}
20 changes: 20 additions & 0 deletions packages/rs-dpp/src/node/status/v0/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};

/// Information about the status of an Evonode
#[derive(Clone, Debug, PartialEq, Encode, Decode, Serialize, Deserialize)]
pub struct EvonodeStatusV0 {
/// The Identifier of the Evonode
pub pro_tx_hash: String,
/// The latest block height stored on the Evonode
pub latest_block_height: u64,
}

/// Trait defining getters for `EvonodeStatusV0`.
pub trait EvonodeStatusV0Getters {
/// Returns the Evonode proTxHash
fn pro_tx_hash(&self) -> String;

/// Returns the Evonode's latest stored block height
fn latest_block_height(&self) -> u64;
}
75 changes: 72 additions & 3 deletions packages/rs-drive-proof-verifier/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ use crate::from_request::TryFromRequest;
use crate::provider::DataContractProvider;
use crate::verify::verify_tenderdash_proof;
use crate::{types, types::*, ContextProvider, Error};
use dapi_grpc::platform::v0::get_evonodes_proposed_epoch_blocks_by_range_request::get_evonodes_proposed_epoch_blocks_by_range_request_v0::Start;
use dapi_grpc::platform::v0::get_identities_contract_keys_request::GetIdentitiesContractKeysRequestV0;
use dapi_grpc::platform::v0::get_path_elements_request::GetPathElementsRequestV0;
use dapi_grpc::platform::v0::get_protocol_version_upgrade_vote_status_request::{
self, GetProtocolVersionUpgradeVoteStatusRequestV0,
};
use dapi_grpc::platform::v0::security_level_map::KeyKindRequestType as GrpcKeyKind;
use dapi_grpc::platform::v0::{get_contested_resource_identity_votes_request, get_data_contract_history_request, get_data_contract_request, get_data_contracts_request, get_epochs_info_request, get_evonodes_proposed_epoch_blocks_by_ids_request, get_evonodes_proposed_epoch_blocks_by_range_request, get_identities_balances_request, get_identities_contract_keys_request, get_identity_balance_and_revision_request, get_identity_balance_request, get_identity_by_public_key_hash_request, get_identity_contract_nonce_request, get_identity_keys_request, get_identity_nonce_request, get_identity_request, get_path_elements_request, get_prefunded_specialized_balance_request, GetContestedResourceVotersForIdentityRequest, GetContestedResourceVotersForIdentityResponse, GetPathElementsRequest, GetPathElementsResponse, GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse, Proof, ResponseMetadata};
use dapi_grpc::platform::v0::{
get_contested_resource_identity_votes_request, get_data_contract_history_request, get_data_contract_request, get_data_contracts_request, get_epochs_info_request, get_evonodes_proposed_epoch_blocks_by_ids_request, get_evonodes_proposed_epoch_blocks_by_range_request, get_identities_balances_request, get_identities_contract_keys_request, get_identity_balance_and_revision_request, get_identity_balance_request, get_identity_by_public_key_hash_request, get_identity_contract_nonce_request, get_identity_keys_request, get_identity_nonce_request, get_identity_request, get_path_elements_request, get_prefunded_specialized_balance_request, GetContestedResourceVotersForIdentityRequest, GetContestedResourceVotersForIdentityResponse, GetPathElementsRequest, GetPathElementsResponse, GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse, Proof, ResponseMetadata
};
use dapi_grpc::platform::{
v0::{self as platform, key_request_type, KeyRequestType as GrpcKeyType},
VersionedGrpcResponse,
Expand All @@ -22,28 +25,30 @@ use dpp::dashcore::{Network, ProTxHash};
use dpp::document::{Document, DocumentV0Getters};
use dpp::identity::identities_contract_keys::IdentitiesContractKeys;
use dpp::identity::Purpose;
use dpp::node::status::v0::EvonodeStatusV0;
use dpp::node::status::EvonodeStatus;
use dpp::platform_value::{self};
use dpp::prelude::{DataContract, Identifier, Identity};
use dpp::serialization::PlatformDeserializable;
use dpp::state_transition::proof_result::StateTransitionProofResult;
use dpp::state_transition::StateTransition;
use dpp::version::PlatformVersion;
use dpp::voting::votes::Vote;
use dpp::ProtocolError;
use drive::drive::identity::key::fetch::{
IdentityKeysRequest, KeyKindRequestType, KeyRequestType, PurposeU8, SecurityLevelU8,
};
use drive::drive::Drive;
use drive::error::proof::ProofError;
use drive::query::contested_resource_votes_given_by_identity_query::ContestedResourceVotesGivenByIdentityQuery;
use drive::query::proposer_block_count_query::ProposerQueryType;
use drive::query::vote_poll_contestant_votes_query::ContestedDocumentVotePollVotesDriveQuery;
use drive::query::vote_poll_vote_state_query::ContestedDocumentVotePollDriveQuery;
use drive::query::vote_polls_by_document_type_query::VotePollsByDocumentTypeQuery;
use drive::query::{DriveDocumentQuery, VotePollsByEndDateDriveQuery};
use std::array::TryFromSliceError;
use std::collections::BTreeMap;
use std::num::TryFromIntError;
use dapi_grpc::platform::v0::get_evonodes_proposed_epoch_blocks_by_range_request::get_evonodes_proposed_epoch_blocks_by_range_request_v0::Start;
use drive::query::proposer_block_count_query::ProposerQueryType;

/// Parse and verify the received proof and retrieve the requested object, if any.
///
Expand Down Expand Up @@ -1735,6 +1740,70 @@ impl FromProof<platform::GetTotalCreditsInPlatformRequest> for TotalCreditsInPla
}
}

impl FromProof<platform::GetStatusRequest> for EvonodeStatus {
type Request = platform::GetStatusRequest;
type Response = platform::GetStatusResponse;

fn maybe_from_proof_with_metadata<'a, I: Into<Self::Request>, O: Into<Self::Response>>(
_request: I,
response: O,
_network: Network,
_platform_version: &PlatformVersion,
_provider: &'a dyn ContextProvider,
) -> Result<(Option<Self>, ResponseMetadata, Proof), Error>
where
Self: Sized + 'a,
{
let response: Self::Response = response.into();
let version = match response.version {
Some(version) => version,
None => {
return Err(ProtocolError::Generic("No version in the response".to_string()).into())
}
};
let (pro_tx_hash, latest_block_height) = match version {
platform::get_status_response::Version::V0(v0) => {
let pro_tx_hash = match v0.node {
Some(node) => node.pro_tx_hash,
None => None,
};
let chain = match v0.chain {
Some(chain) => chain.latest_block_height,
None => {
tracing::debug!("Missing chain message from response");
0
}
lklimek marked this conversation as resolved.
Show resolved Hide resolved
};
(pro_tx_hash, chain)
}
};

match pro_tx_hash {
Some(hash) => match Identifier::from_bytes(&hash) {
Ok(identifier) => {
let evonode_status = EvonodeStatus::V0(EvonodeStatusV0 {
pro_tx_hash: identifier
.to_string(platform_value::string_encoding::Encoding::Base58),
latest_block_height,
lklimek marked this conversation as resolved.
Show resolved Hide resolved
});

Ok((
Some(evonode_status),
ResponseMetadata::default(),
Proof::default(),
))
}
Err(e) => Err(ProtocolError::Generic(format!(
"Failed to convert pro_tx_hash to Identifier: {}",
e
))
.into()),
},
lklimek marked this conversation as resolved.
Show resolved Hide resolved
None => Ok((None, ResponseMetadata::default(), Proof::default())),
}
}
lklimek marked this conversation as resolved.
Show resolved Hide resolved
}

impl FromProof<platform::GetEvonodesProposedEpochBlocksByIdsRequest> for ProposerBlockCounts {
type Request = platform::GetEvonodesProposedEpochBlocksByIdsRequest;
type Response = platform::GetEvonodesProposedEpochBlocksResponse;
Expand Down
8 changes: 4 additions & 4 deletions packages/rs-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ Run the offline test using the following command:
cargo test -p dash-platform-sdk
```

## Implementing Fetch and FetchAny on new objects
## Implementing Fetch and FetchMany on new objects

How to implement `Fetch` and `FetchAny` trait on new object types (`Object`).
How to implement `Fetch` and `FetchMany` trait on new object types (`Object`).

It's basically copy-paste and tweaking of existing implementation for another object type.

Expand All @@ -114,7 +114,7 @@ Definitions:
Checklist:

1. [ ] Ensure protobuf messages are defined in `packages/dapi-grpc/protos/platform/v0/platform.proto` and generated
correctly in `packages/dapi-grpc/src/platform/proto/org.dash.platform.dapi.v0.rs`.
correctly in `packages/dapi-grpc/src/platform/client/org.dash.platform.dapi.v0.rs`.
2. [ ] In `packages/dapi-grpc/build.rs`, add `Request` to `VERSIONED_REQUESTS` and response `Response` to `VERSIONED_RESPONSES`.
This should add derive of `VersionedGrpcMessage` (and some more) in `org.dash.platform.dapi.v0.rs`.
3. [ ] Link request and response type to dapi-client by adding appropriate invocation of `impl_transport_request_grpc!` macro
Expand All @@ -123,7 +123,7 @@ in `packages/rs-dapi-client/src/transport/grpc.rs`.
used internally.

If you intend to implement `FetchMany`, you should define type returned by `fetch_many()` using `RetrievedObjects`
that will store collection of returned objects, indexd by some key.
that will store collection of returned objects, indexed by some key.
5. [ ] Implement `FromProof` trait for the `Object` (or type defined in `types.rs`) in `packages/rs-drive-proof-verifier/src/proof.rs`.
6. [ ] Implement `Query` trait for the `Request` in `packages/rs-sdk/src/platform/query.rs`.
7. [ ] Implement `Fetch` trait for the `Object` (or type defined in `types.rs`), with inner type Request = `Request`,
Expand Down
2 changes: 2 additions & 0 deletions packages/rs-sdk/src/mock/requests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use dpp::{
document::{serialization_traits::DocumentCborMethodsV0, Document},
identifier::Identifier,
identity::IdentityPublicKey,
node::status::EvonodeStatus,
platform_serialization::{platform_encode_to_vec, platform_versioned_decode_from_slice},
prelude::{DataContract, Identity},
serialization::{
Expand Down Expand Up @@ -243,3 +244,4 @@ impl_mock_response!(VotePollsGroupedByTimestamp);
impl_mock_response!(PrefundedSpecializedBalance);
impl_mock_response!(TotalCreditsInPlatform);
impl_mock_response!(ElementFetchRequestItem);
impl_mock_response!(EvonodeStatus);
8 changes: 6 additions & 2 deletions packages/rs-sdk/src/platform/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{error::Error, platform::query::Query, Sdk};
use dapi_grpc::platform::v0::{self as platform_proto, Proof, ResponseMetadata};
use dpp::voting::votes::Vote;
use dpp::{
block::extended_epoch_info::ExtendedEpochInfo, document::Document, platform_value::Identifier,
prelude::Identity,
block::extended_epoch_info::ExtendedEpochInfo, document::Document, node::status::EvonodeStatus,
platform_value::Identifier, prelude::Identity,
};
use drive_proof_verifier::FromProof;
use rs_dapi_client::{transport::TransportRequest, DapiRequest, RequestSettings};
Expand Down Expand Up @@ -282,3 +282,7 @@ impl Fetch for drive_proof_verifier::types::PrefundedSpecializedBalance {
impl Fetch for Vote {
type Request = platform_proto::GetContestedResourceIdentityVotesRequest;
}

impl Fetch for EvonodeStatus {
type Request = platform_proto::GetStatusRequest;
}
17 changes: 15 additions & 2 deletions packages/rs-sdk/src/platform/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use dapi_grpc::platform::v0::get_contested_resource_voters_for_identity_request:
use dapi_grpc::platform::v0::get_contested_resources_request::GetContestedResourcesRequestV0;
use dapi_grpc::platform::v0::get_evonodes_proposed_epoch_blocks_by_range_request::GetEvonodesProposedEpochBlocksByRangeRequestV0;
use dapi_grpc::platform::v0::get_path_elements_request::GetPathElementsRequestV0;
use dapi_grpc::platform::v0::get_status_request::GetStatusRequestV0;
use dapi_grpc::platform::v0::get_total_credits_in_platform_request::GetTotalCreditsInPlatformRequestV0;
use dapi_grpc::platform::v0::{
self as proto, get_identity_keys_request, get_identity_keys_request::GetIdentityKeysRequestV0,
Expand All @@ -20,8 +21,8 @@ use dapi_grpc::platform::v0::{
GetTotalCreditsInPlatformRequest, KeyRequestType,
};
use dapi_grpc::platform::v0::{
GetContestedResourceIdentityVotesRequest, GetPrefundedSpecializedBalanceRequest,
GetVotePollsByEndDateRequest,
get_status_request, GetContestedResourceIdentityVotesRequest,
GetPrefundedSpecializedBalanceRequest, GetStatusRequest, GetVotePollsByEndDateRequest,
};
use dashcore_rpc::dashcore::{hashes::Hash, ProTxHash};
use dpp::version::PlatformVersionError;
Expand Down Expand Up @@ -645,3 +646,15 @@ impl Query<GetEvonodesProposedEpochBlocksByRangeRequest> for LimitQuery<Option<E
})
}
}

impl Query<GetStatusRequest> for () {
fn query(self, _prove: bool) -> Result<GetStatusRequest, Error> {
// ignore proof

let request: GetStatusRequest = GetStatusRequest {
version: Some(get_status_request::Version::V0(GetStatusRequestV0 {})),
};

Ok(request)
}
}
19 changes: 16 additions & 3 deletions packages/rs-sdk/src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,22 @@ impl Sdk {
pub fn shutdown(&self) {
self.cancel_token.cancel();
}

/// Return the [DapiClient] address list
pub fn address_list(&self) -> Result<AddressList, String> {
match &self.inner {
SdkInstance::Dapi { dapi, version: _ } => {
let address_list_arc = dapi.address_list();
let address_list_lock = address_list_arc
.read()
.map_err(|e| format!("Failed to read address list: {e}"))?;
Ok(address_list_lock.clone())
}
SdkInstance::Mock { .. } => {
todo!();
}
}
}
lklimek marked this conversation as resolved.
Show resolved Hide resolved
}

#[async_trait::async_trait]
Expand Down Expand Up @@ -765,9 +781,6 @@ impl SdkBuilder {
if sdk.context_provider.is_none() {
#[cfg(feature = "mocks")]
if !self.core_ip.is_empty() {
tracing::warn!("ContextProvider not set; mocking with Dash Core. \
Please provide your own ContextProvider with SdkBuilder::with_context_provider().");

let mut context_provider = GrpcContextProvider::new(None,
&self.core_ip, self.core_port, &self.core_user, &self.core_password,
self.data_contract_cache_size, self.quorum_public_keys_cache_size)?;
Expand Down
Loading