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(platform): proof verification for many queries and a few more queries #2431

Merged
merged 3 commits into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 9 additions & 9 deletions Cargo.lock

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

31 changes: 31 additions & 0 deletions packages/dapi-grpc/protos/platform/v0/platform.proto
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ service Platform {
rpc getIdentityTokenInfos(GetIdentityTokenInfosRequest) returns (GetIdentityTokenInfosResponse);
rpc getIdentitiesTokenInfos(GetIdentitiesTokenInfosRequest) returns (GetIdentitiesTokenInfosResponse);
rpc getTokenStatuses(GetTokenStatusesRequest) returns (GetTokenStatusesResponse);
rpc getTokenTotalSupply(GetTokenTotalSupplyRequest) returns (GetTokenTotalSupplyResponse);
rpc getGroupInfo(GetGroupInfoRequest) returns (GetGroupInfoResponse);
rpc getGroupInfos(GetGroupInfosRequest) returns (GetGroupInfosResponse);
// rpc getActiveGroupActions(GetActiveGroupActionsRequest) returns (GetActiveGroupActionsResponse);
// rpc getClosedGroupActions(GetClosedGroupActionsRequest) returns (GetClosedGroupActionsResponse);
}
Expand Down Expand Up @@ -1398,6 +1400,35 @@ message GetTokenStatusesResponse {
}
}

message GetTokenTotalSupplyRequest {
message GetTokenTotalSupplyRequestV0 {
bytes token_id = 1;
bool prove = 2;
}
oneof version {
GetTokenTotalSupplyRequestV0 v0 = 1;
}
}

message GetTokenTotalSupplyResponse {
message GetTokenTotalSupplyResponseV0 {
message TokenTotalSupplyEntry {
bytes token_id = 1;
uint64 total_aggregated_amount_in_user_accounts = 2;
uint64 total_system_amount = 3;
}

oneof result {
TokenTotalSupplyEntry token_total_supply = 1;
Proof proof = 2;
}
ResponseMetadata metadata = 3;
}
oneof version {
GetTokenTotalSupplyResponseV0 v0 = 1;
}
}

message GetGroupInfoRequest {
message GetGroupInfoRequestV0 {
bytes contract_id = 1;
Expand Down
3 changes: 3 additions & 0 deletions packages/rs-dpp/src/balances/credits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub type Credits = u64;
/// Token Amount type
pub type TokenAmount = u64;

/// Signed Token Amount type
pub type SignedTokenAmount = i64;

/// Sum token amount
pub type SumTokenAmount = i128;

Expand Down
1 change: 1 addition & 0 deletions packages/rs-dpp/src/balances/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod total_credits_balance;

pub mod credits;
pub mod total_single_token_balance;
pub mod total_tokens_balance;
49 changes: 49 additions & 0 deletions packages/rs-dpp/src/balances/total_single_token_balance/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::balances::credits::SignedTokenAmount;
use crate::ProtocolError;
use std::fmt;

/// A structure where the token supply and the aggregated token account balances should always be equal
#[derive(Copy, Clone, Debug)]
pub struct TotalSingleTokenBalance {
/// the token supply
pub token_supply: SignedTokenAmount,
/// the sum of all user account balances
pub aggregated_token_account_balances: SignedTokenAmount,
}

impl fmt::Display for TotalSingleTokenBalance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "TotalSingleTokenBalance {{")?;
writeln!(f, " token_supply: {},", self.token_supply)?;
writeln!(
f,
" aggregated_token_account_balances: {}",
self.aggregated_token_account_balances
)?;
write!(f, "}}")
}
}
impl TotalSingleTokenBalance {
/// Is the outcome okay? basically do the values match up
/// Errors in case of overflow
pub fn ok(&self) -> Result<bool, ProtocolError> {
let TotalSingleTokenBalance {
token_supply,
aggregated_token_account_balances,
} = *self;

if token_supply < 0 {
return Err(ProtocolError::Generic(
"Token in platform are less than 0".to_string(),
));
}

if aggregated_token_account_balances < 0 {
return Err(ProtocolError::Generic(
"Token in aggregated identity balances are less than 0".to_string(),
));
}

Ok(token_supply == aggregated_token_account_balances)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl<C> Platform<C> {
// Verify sum trees
let token_balance = self
.drive
.calculate_total_tokens_balance(Some(transaction), &platform_version.drive)
.calculate_total_tokens_balance(Some(transaction), platform_version)
.map_err(Error::Drive)?;

if !token_balance.ok()? {
Expand Down
31 changes: 28 additions & 3 deletions packages/rs-drive-abci/src/query/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ use dapi_grpc::platform::v0::{
GetDocumentsRequest, GetDocumentsResponse, GetEpochsInfoRequest, GetEpochsInfoResponse,
GetEvonodesProposedEpochBlocksByIdsRequest, GetEvonodesProposedEpochBlocksByRangeRequest,
GetEvonodesProposedEpochBlocksResponse, GetGroupInfoRequest, GetGroupInfoResponse,
GetIdentitiesBalancesRequest, GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest,
GetGroupInfosRequest, GetGroupInfosResponse, GetIdentitiesBalancesRequest,
GetIdentitiesBalancesResponse, GetIdentitiesContractKeysRequest,
GetIdentitiesContractKeysResponse, GetIdentitiesTokenBalancesRequest,
GetIdentitiesTokenBalancesResponse, GetIdentitiesTokenInfosRequest,
GetIdentitiesTokenInfosResponse, GetIdentityBalanceAndRevisionRequest,
Expand All @@ -37,8 +38,8 @@ use dapi_grpc::platform::v0::{
GetProtocolVersionUpgradeStateRequest, GetProtocolVersionUpgradeStateResponse,
GetProtocolVersionUpgradeVoteStatusRequest, GetProtocolVersionUpgradeVoteStatusResponse,
GetStatusRequest, GetStatusResponse, GetTokenStatusesRequest, GetTokenStatusesResponse,
GetTotalCreditsInPlatformRequest, GetTotalCreditsInPlatformResponse,
GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse,
GetTokenTotalSupplyRequest, GetTokenTotalSupplyResponse, GetTotalCreditsInPlatformRequest,
GetTotalCreditsInPlatformResponse, GetVotePollsByEndDateRequest, GetVotePollsByEndDateResponse,
WaitForStateTransitionResultRequest, WaitForStateTransitionResultResponse,
};
use dapi_grpc::tonic::{Code, Request, Response, Status};
Expand Down Expand Up @@ -675,6 +676,18 @@ impl PlatformService for QueryService {
.await
}

async fn get_token_total_supply(
&self,
request: Request<GetTokenTotalSupplyRequest>,
) -> Result<Response<GetTokenTotalSupplyResponse>, Status> {
self.handle_blocking_query(
request,
Platform::<DefaultCoreRPC>::query_token_total_supply,
"get_token_total_supply",
)
.await
}

async fn get_group_info(
&self,
request: Request<GetGroupInfoRequest>,
Expand All @@ -687,6 +700,18 @@ impl PlatformService for QueryService {
.await
}

async fn get_group_infos(
&self,
request: Request<GetGroupInfosRequest>,
) -> Result<Response<GetGroupInfosResponse>, Status> {
self.handle_blocking_query(
request,
Platform::<DefaultCoreRPC>::query_group_infos,
"get_group_infos",
)
.await
}

// async fn get_active_group_actions(
// &self,
// request: Request<GetActiveGroupActionsRequest>,
Expand Down
1 change: 1 addition & 0 deletions packages/rs-drive-abci/src/query/token_queries/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ mod identities_token_infos;
mod identity_token_balances;
mod identity_token_infos;
mod token_status;
mod token_total_supply;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<C> Platform<C> {
let Some(version) = version else {
return Ok(QueryValidationResult::new_with_error(
QueryError::DecodingError(
"could not decode identity token infos query".to_string(),
"could not decode identity token statuses query".to_string(),
),
));
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::error::query::QueryError;
use crate::error::Error;
use crate::platform_types::platform::Platform;
use crate::platform_types::platform_state::PlatformState;
use crate::query::QueryValidationResult;
use dapi_grpc::platform::v0::get_token_total_supply_request::Version as RequestVersion;
use dapi_grpc::platform::v0::get_token_total_supply_response::Version as ResponseVersion;
use dapi_grpc::platform::v0::{GetTokenTotalSupplyRequest, GetTokenTotalSupplyResponse};
use dpp::version::PlatformVersion;
mod v0;

impl<C> Platform<C> {
/// Querying of token total supply
pub fn query_token_total_supply(
&self,
GetTokenTotalSupplyRequest { version }: GetTokenTotalSupplyRequest,
platform_state: &PlatformState,
platform_version: &PlatformVersion,
) -> Result<QueryValidationResult<GetTokenTotalSupplyResponse>, Error> {
let Some(version) = version else {
return Ok(QueryValidationResult::new_with_error(
QueryError::DecodingError(
"could not decode identity token total supply query".to_string(),
),
));
};

let feature_version_bounds = &platform_version
.drive_abci
.query
.token_queries
.token_total_supply;

let feature_version = match &version {
RequestVersion::V0(_) => 0,
};
if !feature_version_bounds.check_version(feature_version) {
return Ok(QueryValidationResult::new_with_error(
QueryError::UnsupportedQueryVersion(
"token_total_supply".to_string(),
feature_version_bounds.min_version,
feature_version_bounds.max_version,
platform_version.protocol_version,
feature_version,
),
));
}

match version {
RequestVersion::V0(request_v0) => {
let result =
self.query_token_total_supply_v0(request_v0, platform_state, platform_version)?;
Ok(result.map(|response_v0| GetTokenTotalSupplyResponse {
version: Some(ResponseVersion::V0(response_v0)),
}))
}
}
}
}
Loading