Skip to content

Commit 847436d

Browse files
feat(platform): add token contract info and query (#2641)
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent 45e4575 commit 847436d

File tree

47 files changed

+1203
-45
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1203
-45
lines changed

packages/dapi-grpc/build.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
7373
// Derive features for versioned messages
7474
//
7575
// "GetConsensusParamsRequest" is excluded as this message does not support proofs
76-
const VERSIONED_REQUESTS: [&str; 42] = [
76+
const VERSIONED_REQUESTS: [&str; 43] = [
7777
"GetDataContractHistoryRequest",
7878
"GetDataContractRequest",
7979
"GetDataContractsRequest",
@@ -110,6 +110,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
110110
"GetIdentityTokenInfosRequest",
111111
"GetIdentitiesTokenInfosRequest",
112112
"GetTokenDirectPurchasePricesRequest",
113+
"GetTokenContractInfoRequest",
113114
"GetTokenStatusesRequest",
114115
"GetTokenTotalSupplyRequest",
115116
"GetGroupInfoRequest",
@@ -126,7 +127,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
126127
// - "GetIdentityByNonUniquePublicKeyHashResponse"
127128
//
128129
// "GetEvonodesProposedEpochBlocksResponse" is used for 2 Requests
129-
const VERSIONED_RESPONSES: [&str; 40] = [
130+
const VERSIONED_RESPONSES: [&str; 41] = [
130131
"GetDataContractHistoryResponse",
131132
"GetDataContractResponse",
132133
"GetDataContractsResponse",
@@ -161,6 +162,7 @@ fn configure_platform(mut platform: MappingConfig) -> MappingConfig {
161162
"GetIdentityTokenInfosResponse",
162163
"GetIdentitiesTokenInfosResponse",
163164
"GetTokenDirectPurchasePricesResponse",
165+
"GetTokenContractInfoResponse",
164166
"GetTokenStatusesResponse",
165167
"GetTokenTotalSupplyResponse",
166168
"GetGroupInfoResponse",

packages/dapi-grpc/protos/platform/v0/platform.proto

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ service Platform {
8686
returns (GetTokenStatusesResponse);
8787
rpc getTokenDirectPurchasePrices(GetTokenDirectPurchasePricesRequest)
8888
returns (GetTokenDirectPurchasePricesResponse);
89+
rpc getTokenContractInfo(GetTokenContractInfoRequest)
90+
returns (GetTokenContractInfoResponse);
8991
rpc getTokenPreProgrammedDistributions(
9092
GetTokenPreProgrammedDistributionsRequest)
9193
returns (GetTokenPreProgrammedDistributionsResponse);
@@ -1370,6 +1372,27 @@ message GetTokenStatusesResponse {
13701372
oneof version { GetTokenStatusesResponseV0 v0 = 1; }
13711373
}
13721374

1375+
// Retrieve direct purchase prices defined for one or more tokens.
1376+
//
1377+
// Some tokens can have a direct purchase price defined using
1378+
// `TokenSetPriceForDirectPurchaseTransition` (see `dpp` crate for details).
1379+
// This request retrieves the direct purchase prices for those tokens and
1380+
// returns [GetTokenDirectPurchasePricesResponse].
1381+
message GetTokenDirectPurchasePricesRequest {
1382+
message GetTokenDirectPurchasePricesRequestV0 {
1383+
// List of token IDs to get prices for.
1384+
//
1385+
// The list must not be empty.
1386+
// Token IDs must have 32 bytes and be unique.
1387+
// Results for non-unique token IDs are undefined.
1388+
repeated bytes token_ids = 1;
1389+
// Whether to return proofs for the response, or just direct response.
1390+
bool prove = 2;
1391+
}
1392+
oneof version { GetTokenDirectPurchasePricesRequestV0 v0 = 1; }
1393+
}
1394+
1395+
13731396
// Response to GetTokenDirectPurchasePricesRequest, containing information about
13741397
// direct purchase prices defined for requested token IDs.
13751398
message GetTokenDirectPurchasePricesResponse {
@@ -1419,24 +1442,49 @@ message GetTokenDirectPurchasePricesResponse {
14191442
oneof version { GetTokenDirectPurchasePricesResponseV0 v0 = 1; }
14201443
}
14211444

1422-
// Retrieve direct purchase prices defined for one or more tokens.
1423-
//
1424-
// Some tokens can have a direct purchase price defined using
1425-
// `TokenSetPriceForDirectPurchaseTransition` (see `dpp` crate for details).
1426-
// This request retrieves the direct purchase prices for those tokens and
1427-
// returns [GetTokenDirectPurchasePricesResponse].
1428-
message GetTokenDirectPurchasePricesRequest {
1429-
message GetTokenDirectPurchasePricesRequestV0 {
1430-
// List of token IDs to get prices for.
1431-
//
1432-
// The list must not be empty.
1433-
// Token IDs must have 32 bytes and be unique.
1434-
// Results for non-unique token IDs are undefined.
1435-
repeated bytes token_ids = 1;
1436-
// Whether to return proofs for the response, or just direct response.
1445+
// Request to retrieve token contract info for a specific token ID.
1446+
message GetTokenContractInfoRequest {
1447+
message GetTokenContractInfoRequestV0 {
1448+
// The token ID to retrieve contract info for.
1449+
// Must be exactly 32 bytes.
1450+
bytes token_id = 1;
1451+
1452+
// Whether to return a cryptographic proof.
14371453
bool prove = 2;
14381454
}
1439-
oneof version { GetTokenDirectPurchasePricesRequestV0 v0 = 1; }
1455+
1456+
oneof version {
1457+
GetTokenContractInfoRequestV0 v0 = 1;
1458+
}
1459+
}
1460+
1461+
// Response to GetTokenContractInfoRequest.
1462+
message GetTokenContractInfoResponse {
1463+
message GetTokenContractInfoResponseV0 {
1464+
// Direct token contract info.
1465+
message TokenContractInfoData {
1466+
// The ID of the contract associated with the token.
1467+
bytes contract_id = 1;
1468+
1469+
// The position of the token within the contract.
1470+
uint32 token_contract_position = 2;
1471+
}
1472+
1473+
oneof result {
1474+
// Direct token contract data
1475+
TokenContractInfoData data = 1;
1476+
1477+
// Cryptographic proof of token contract info
1478+
Proof proof = 2;
1479+
}
1480+
1481+
// Metadata about the blockchain state at the time of the query
1482+
ResponseMetadata metadata = 3;
1483+
}
1484+
1485+
oneof version {
1486+
GetTokenContractInfoResponseV0 v0 = 1;
1487+
}
14401488
}
14411489

14421490
message GetTokenPreProgrammedDistributionsRequest {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::data_contract::TokenContractPosition;
2+
use crate::tokens::contract_info::v0::TokenContractInfoV0Accessors;
3+
use crate::tokens::contract_info::TokenContractInfo;
4+
use platform_value::Identifier;
5+
6+
impl TokenContractInfoV0Accessors for TokenContractInfo {
7+
fn contract_id(&self) -> Identifier {
8+
match self {
9+
TokenContractInfo::V0(v0) => v0.contract_id(),
10+
}
11+
}
12+
13+
fn set_contract_id(&mut self, contract_id: Identifier) {
14+
match self {
15+
TokenContractInfo::V0(v0) => v0.set_contract_id(contract_id),
16+
}
17+
}
18+
19+
fn token_contract_position(&self) -> TokenContractPosition {
20+
match self {
21+
TokenContractInfo::V0(v0) => v0.token_contract_position(),
22+
}
23+
}
24+
25+
fn set_token_contract_position(&mut self, position: TokenContractPosition) {
26+
match self {
27+
TokenContractInfo::V0(v0) => v0.set_token_contract_position(position),
28+
}
29+
}
30+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use crate::data_contract::TokenContractPosition;
2+
use crate::tokens::contract_info::v0::TokenContractInfoV0;
3+
use crate::ProtocolError;
4+
use bincode::Encode;
5+
use derive_more::From;
6+
use platform_serialization::de::Decode;
7+
use platform_serialization_derive::{PlatformDeserialize, PlatformSerialize};
8+
use platform_value::Identifier;
9+
use platform_version::version::PlatformVersion;
10+
use platform_versioning::PlatformVersioned;
11+
12+
mod methods;
13+
pub mod v0;
14+
15+
#[derive(
16+
Debug,
17+
Clone,
18+
Encode,
19+
Decode,
20+
PlatformDeserialize,
21+
PlatformSerialize,
22+
PlatformVersioned,
23+
From,
24+
PartialEq,
25+
)]
26+
#[platform_serialize(unversioned)] //versioned directly, no need to use platform_version
27+
pub enum TokenContractInfo {
28+
V0(TokenContractInfoV0),
29+
}
30+
31+
impl TokenContractInfo {
32+
pub fn new(
33+
contract_id: Identifier,
34+
token_contract_position: TokenContractPosition,
35+
platform_version: &PlatformVersion,
36+
) -> Result<Self, ProtocolError> {
37+
match platform_version
38+
.dpp
39+
.token_versions
40+
.token_contract_info_default_structure_version
41+
{
42+
0 => Ok(TokenContractInfo::V0(TokenContractInfoV0 {
43+
contract_id,
44+
token_contract_position,
45+
})),
46+
version => Err(ProtocolError::UnknownVersionMismatch {
47+
method: "TokenContractInfo::new".to_string(),
48+
known_versions: vec![0],
49+
received: version,
50+
}),
51+
}
52+
}
53+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use crate::data_contract::TokenContractPosition;
2+
use bincode::{Decode, Encode};
3+
use derive_more::From;
4+
use platform_value::Identifier;
5+
6+
#[derive(Debug, Clone, Encode, Decode, From, PartialEq)]
7+
/// Token contract info
8+
pub struct TokenContractInfoV0 {
9+
/// The contract id of the token
10+
pub contract_id: Identifier,
11+
/// The token contract position
12+
pub token_contract_position: TokenContractPosition,
13+
}
14+
15+
/// Accessor trait for `TokenContractInfoV0`
16+
pub trait TokenContractInfoV0Accessors {
17+
/// Returns a reference to the contract ID.
18+
fn contract_id(&self) -> Identifier;
19+
20+
/// Sets the contract ID.
21+
fn set_contract_id(&mut self, contract_id: Identifier);
22+
23+
/// Returns the token contract position.
24+
fn token_contract_position(&self) -> TokenContractPosition;
25+
26+
/// Sets the token contract position.
27+
fn set_token_contract_position(&mut self, position: TokenContractPosition);
28+
}
29+
30+
impl TokenContractInfoV0Accessors for TokenContractInfoV0 {
31+
fn contract_id(&self) -> Identifier {
32+
self.contract_id
33+
}
34+
35+
fn set_contract_id(&mut self, contract_id: Identifier) {
36+
self.contract_id = contract_id;
37+
}
38+
39+
fn token_contract_position(&self) -> TokenContractPosition {
40+
self.token_contract_position
41+
}
42+
43+
fn set_token_contract_position(&mut self, position: TokenContractPosition) {
44+
self.token_contract_position = position;
45+
}
46+
}

packages/rs-dpp/src/tokens/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::prelude::{
55
use crate::util::hash::hash_double;
66

77
pub mod allowed_currency;
8+
pub mod contract_info;
89
pub mod emergency_action;
910
pub mod errors;
1011
pub mod gas_fees_paid_by;

packages/rs-drive-abci/src/execution/platform_events/protocol_upgrade/perform_events_on_first_block_of_protocol_change/v0/mod.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use drive::drive::prefunded_specialized_balances::prefunded_specialized_balances
2525
use drive::drive::system::misc_path;
2626
use drive::drive::tokens::paths::{
2727
token_distributions_root_path, token_timed_distributions_path, tokens_root_path,
28-
TOKEN_BALANCES_KEY, TOKEN_BLOCK_TIMED_DISTRIBUTIONS_KEY, TOKEN_DIRECT_SELL_PRICE_KEY,
29-
TOKEN_DISTRIBUTIONS_KEY, TOKEN_EPOCH_TIMED_DISTRIBUTIONS_KEY, TOKEN_IDENTITY_INFO_KEY,
30-
TOKEN_MS_TIMED_DISTRIBUTIONS_KEY, TOKEN_PERPETUAL_DISTRIBUTIONS_KEY,
28+
TOKEN_BALANCES_KEY, TOKEN_BLOCK_TIMED_DISTRIBUTIONS_KEY, TOKEN_CONTRACT_INFO_KEY,
29+
TOKEN_DIRECT_SELL_PRICE_KEY, TOKEN_DISTRIBUTIONS_KEY, TOKEN_EPOCH_TIMED_DISTRIBUTIONS_KEY,
30+
TOKEN_IDENTITY_INFO_KEY, TOKEN_MS_TIMED_DISTRIBUTIONS_KEY, TOKEN_PERPETUAL_DISTRIBUTIONS_KEY,
3131
TOKEN_PRE_PROGRAMMED_DISTRIBUTIONS_KEY, TOKEN_STATUS_INFO_KEY, TOKEN_TIMED_DISTRIBUTIONS_KEY,
3232
};
3333
use drive::drive::votes::paths::vote_end_date_queries_tree_path_vec;
@@ -415,6 +415,15 @@ impl<C> Platform<C> {
415415
&platform_version.drive,
416416
)?;
417417

418+
self.drive.grove_insert_if_not_exists(
419+
(&path).into(),
420+
&[TOKEN_CONTRACT_INFO_KEY],
421+
Element::empty_tree(),
422+
Some(transaction),
423+
None,
424+
&platform_version.drive,
425+
)?;
426+
418427
// The token distribution trees
419428

420429
let token_distributions_path = token_distributions_root_path();

packages/rs-drive-abci/src/execution/validation/state_transition/state_transitions/batch/tests/token/direct_selling/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ mod token_selling_tests {
151151
.drive
152152
.fetch_identity_balance(buyer.id().to_buffer(), None, platform_version)
153153
.expect("expected to fetch credit balance");
154-
assert_eq!(buyer_credit_balance, Some(699_868_051_500)); // 10.0 - 3.0 spent - fees =~ 7 dash left
154+
assert_eq!(buyer_credit_balance, Some(699_868_130_120)); // 10.0 - 3.0 spent - fees =~ 7 dash left
155155
}
156156

157157
#[test]

packages/rs-drive-abci/src/query/service.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,11 @@ use dapi_grpc::platform::v0::{
4040
GetPrefundedSpecializedBalanceResponse, GetProtocolVersionUpgradeStateRequest,
4141
GetProtocolVersionUpgradeStateResponse, GetProtocolVersionUpgradeVoteStatusRequest,
4242
GetProtocolVersionUpgradeVoteStatusResponse, GetStatusRequest, GetStatusResponse,
43-
GetTokenDirectPurchasePricesRequest, GetTokenDirectPurchasePricesResponse,
44-
GetTokenPerpetualDistributionLastClaimRequest, GetTokenPerpetualDistributionLastClaimResponse,
45-
GetTokenPreProgrammedDistributionsRequest, GetTokenPreProgrammedDistributionsResponse,
46-
GetTokenStatusesRequest, GetTokenStatusesResponse, GetTokenTotalSupplyRequest,
47-
GetTokenTotalSupplyResponse, GetTotalCreditsInPlatformRequest,
43+
GetTokenContractInfoRequest, GetTokenContractInfoResponse, GetTokenDirectPurchasePricesRequest,
44+
GetTokenDirectPurchasePricesResponse, GetTokenPerpetualDistributionLastClaimRequest,
45+
GetTokenPerpetualDistributionLastClaimResponse, GetTokenPreProgrammedDistributionsRequest,
46+
GetTokenPreProgrammedDistributionsResponse, GetTokenStatusesRequest, GetTokenStatusesResponse,
47+
GetTokenTotalSupplyRequest, GetTokenTotalSupplyResponse, GetTotalCreditsInPlatformRequest,
4848
GetTotalCreditsInPlatformResponse, GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse,
4949
WaitForStateTransitionResultRequest, WaitForStateTransitionResultResponse,
5050
};
@@ -766,6 +766,18 @@ impl PlatformService for QueryService {
766766
.await
767767
}
768768

769+
async fn get_token_contract_info(
770+
&self,
771+
request: Request<GetTokenContractInfoRequest>,
772+
) -> Result<Response<GetTokenContractInfoResponse>, Status> {
773+
self.handle_blocking_query(
774+
request,
775+
Platform::<DefaultCoreRPC>::query_token_contract_info,
776+
"get_token_contract_info",
777+
)
778+
.await
779+
}
780+
769781
async fn get_token_perpetual_distribution_last_claim(
770782
&self,
771783
request: Request<GetTokenPerpetualDistributionLastClaimRequest>,

packages/rs-drive-abci/src/query/token_queries/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod identities_token_balances;
22
mod identities_token_infos;
33
mod identity_token_balances;
44
mod identity_token_infos;
5+
mod token_contract_info;
56
mod token_direct_purchase_prices;
67
mod token_perpetual_distribution_last_claim;
78
mod token_pre_programmed_distributions;

0 commit comments

Comments
 (0)