Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
1 change: 0 additions & 1 deletion .pnp.cjs

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

1 change: 1 addition & 0 deletions packages/dapi-grpc/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
src/core/*/
src/platform/*/
src/drive/*/
4 changes: 3 additions & 1 deletion packages/dapi-grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ license = "MIT"

[features]
default = ["core", "platform", "client"]
# Internal Drive endpoints. Used by DAPI
drive = ["platform"]
core = []
platform = []
# Re-export Dash Platform protobuf types as `dapi_grpc::platform::proto`
Expand All @@ -25,7 +27,7 @@ tenderdash-proto = []
client = ["platform"]

# Build tonic server code. Includes all client features and adds server-specific dependencies.
server = ["platform", "tenderdash-proto/server", "client"]
server = ["platform", "tenderdash-proto/server", "client", "drive"]

serde = ["dep:serde", "dep:serde_bytes", "tenderdash-proto/serde"]
mocks = ["serde", "dep:serde_json"]
Expand Down
37 changes: 33 additions & 4 deletions packages/dapi-grpc/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ fn generate_code(typ: ImplType) {
.generate()
.expect("generate platform proto");

let drive = MappingConfig::new(
PathBuf::from("protos/drive/v0/drive.proto"),
PathBuf::from("src/drive"),
&typ,
);

configure_drive(drive)
.generate()
.expect("generate platform proto");

println!("cargo:rerun-if-changed=./protos");
println!("cargo:rerun-if-env-changed=CARGO_FEATURE_SERDE");
println!("cargo:rerun-if-env-changed=CARGO_CFG_TARGET_ARCH");
Expand All @@ -63,7 +73,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
// Derive features for versioned messages
//
// "GetConsensusParamsRequest" is excluded as this message does not support proofs
const VERSIONED_REQUESTS: [&str; 40] = [
const VERSIONED_REQUESTS: [&str; 39] = [
"GetDataContractHistoryRequest",
"GetDataContractRequest",
"GetDataContractsRequest",
Expand All @@ -78,7 +88,6 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
"GetIdentityByPublicKeyHashRequest",
"GetIdentityKeysRequest",
"GetIdentityRequest",
"GetProofsRequest",
"WaitForStateTransitionResultRequest",
"GetProtocolVersionUpgradeStateRequest",
"GetProtocolVersionUpgradeVoteStatusRequest",
Expand Down Expand Up @@ -111,7 +120,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
// - "GetStatusResponse"
//
// "GetEvonodesProposedEpochBlocksResponse" is used for 2 Requests
const VERSIONED_RESPONSES: [&str; 39] = [
const VERSIONED_RESPONSES: [&str; 38] = [
"GetDataContractHistoryResponse",
"GetDataContractResponse",
"GetDataContractsResponse",
Expand All @@ -126,7 +135,6 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
"GetIdentityByPublicKeyHashResponse",
"GetIdentityKeysResponse",
"GetIdentityResponse",
"GetProofsResponse",
"WaitForStateTransitionResultResponse",
"GetEpochsInfoResponse",
"GetProtocolVersionUpgradeStateResponse",
Expand Down Expand Up @@ -210,6 +218,19 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
platform
}

fn configure_drive(drive: MappingConfig) -> MappingConfig {
drive
.message_attribute(".", r#"#[derive( ::dapi_grpc_macros::Mockable)]"#)
.type_attribute(
".",
r#"#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]"#,
)
.type_attribute(
".",
r#"#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]"#,
)
}

/// Check for duplicate messages in the list.
fn check_unique(messages: &[&'static str]) -> Result<(), String> {
let mut hashset: HashSet<&'static str> = HashSet::new();
Expand Down Expand Up @@ -322,6 +343,14 @@ impl MappingConfig {
self
}

#[allow(unused)]
fn includes(mut self, includes: &[PathBuf]) -> Self {
for include in includes {
self.proto_includes.push(abs_path(include));
}
self
}

#[allow(unused)]
fn field_attribute(mut self, path: &str, attribute: &str) -> Self {
self.builder = self.builder.field_attribute(path, attribute);
Expand Down
111 changes: 111 additions & 0 deletions packages/dapi-grpc/clients/drive/v0/nodejs/DrivePromiseClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const grpc = require('@grpc/grpc-js');
const { promisify } = require('util');

const {
convertObjectToMetadata,
utils: {
isObject,
},
client: {
interceptors: {
jsonToProtobufInterceptorFactory,
},
converters: {
jsonToProtobufFactory,
protobufToJsonFactory,
},
},
} = require('@dashevo/grpc-common');

const { URL } = require('url');
const {
org: {
dash: {
platform: {
drive: {
v0: {
GetProofsRequest: PBJSGetProofsRequest,
GetProofsResponse: PBJSGetProofsResponse,
},
},
},
},
},
} = require('./drive_pbjs');

const {
GetProofsResponse: ProtocGetProofsResponse,
} = require('./drive_protoc');

const getDriveDefinition = require('../../../../lib/getDriveDefinition');

const DriveNodeJSClient = getDriveDefinition(0);

class DrivePromiseClient {
/**
* @param {string} hostname
* @param {?Object} credentials
* @param {?Object} options
*/
constructor(hostname, credentials, options = {}) {
if (credentials !== undefined) {
throw new Error('"credentials" option is not supported yet');
}

const url = new URL(hostname);
const { protocol, host: strippedHostname } = url;

// See this issue https://github.com/nodejs/node/issues/3176
// eslint-disable-next-line no-param-reassign
credentials = protocol.replace(':', '') === 'https' ? grpc.credentials.createSsl() : grpc.credentials.createInsecure();

this.client = new DriveNodeJSClient(strippedHostname, credentials, options);

this.client.getProofs = promisify(
this.client.getProofs.bind(this.client),
);

this.protocolVersion = undefined;
}

/**
*
* @param {!GetProofsRequest} request
* @param {?Object<string, string>} metadata
* @param {CallOptions} [options={}]
* @returns {Promise<!GetProofsResponse>}
*/
getProofs(request, metadata = {}, options = {}) {
if (!isObject(metadata)) {
throw new Error('metadata must be an object');
}

return this.client.getProofs(
request,
convertObjectToMetadata(metadata),
{
interceptors: [
jsonToProtobufInterceptorFactory(
jsonToProtobufFactory(
ProtocGetProofsResponse,
PBJSGetProofsResponse,
),
protobufToJsonFactory(
PBJSGetProofsRequest,
),
),
],
...options,
},
);
}

/**
* @param {string} protocolVersion
*/
setProtocolVersion(protocolVersion) {
this.setProtocolVersion = protocolVersion;
}
}

module.exports = DrivePromiseClient;
Loading
Loading