Skip to content

Commit 5eacc13

Browse files
authored
chore(drive): logs and metrics for withdrawal daily limit (#2192)
1 parent 023ff85 commit 5eacc13

File tree

7 files changed

+68
-14
lines changed
  • packages
    • rs-drive-abci/src
    • rs-drive/src/drive/identity/withdrawals
      • calculate_current_withdrawal_limit
      • transaction/queue/dequeue_untied_withdrawal_transactions

7 files changed

+68
-14
lines changed

packages/rs-drive-abci/src/execution/engine/run_block_proposal/v0/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,8 @@ where
293293
// required for signature verification (core height and quorum hash)
294294
// Then we save unsigned transaction bytes to block execution context
295295
// to be signed (on extend_vote), verified (on verify_vote) and broadcasted (on finalize_block)
296+
// Also, the dequeued untiled transaction added to the broadcasted transaction queue to for further
297+
// resigning in case of failures.
296298
let unsigned_withdrawal_transaction_bytes = self
297299
.dequeue_and_build_unsigned_withdrawal_transactions(
298300
validator_set_quorum_hash,
@@ -329,12 +331,13 @@ where
329331
// Corresponding withdrawal documents are changed from queued to pooled
330332
self.pool_withdrawals_into_transactions_queue(
331333
&block_info,
332-
&last_committed_platform_state,
334+
last_committed_platform_state,
333335
Some(transaction),
334336
platform_version,
335337
)?;
336338

337339
// Cleans up the expired locks for withdrawal amounts
340+
// to update daily withdrawal limit
338341
// This is for example when we make a withdrawal for 30 Dash
339342
// But we can only withdraw 1000 Dash a day
340343
// after the withdrawal we should only be able to withdraw 970 Dash
@@ -350,7 +353,7 @@ where
350353
let mut block_execution_context: BlockExecutionContext =
351354
block_execution_context::v0::BlockExecutionContextV0 {
352355
block_state_info: block_state_info.into(),
353-
epoch_info: epoch_info.clone(),
356+
epoch_info,
354357
unsigned_withdrawal_transactions: unsigned_withdrawal_transaction_bytes,
355358
block_platform_state,
356359
proposer_results: None,

packages/rs-drive-abci/src/execution/platform_events/withdrawals/pool_withdrawals_into_transactions_queue/v0/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,21 @@ where
1919
platform_version: &PlatformVersion,
2020
) -> Result<(), Error> {
2121
// Currently Core only supports using the first 2 quorums (out of 24 for mainnet).
22-
// For us, we just use the latest quorum to be extra safe.
22+
// For extra safety, we use only the first quorum because our quorum info based
23+
// on core chain locked height which is always late comparing with Core.
2324
let Some(position_of_current_quorum) =
2425
last_committed_platform_state.current_validator_set_position_in_list_by_most_recent()
2526
else {
26-
tracing::warn!("Current quorum not in current validator set, not making withdrawals");
27+
tracing::warn!("Current quorum not in current validator set, do not pool withdrawals");
28+
2729
return Ok(());
2830
};
2931
if position_of_current_quorum != 0 {
3032
tracing::debug!(
31-
"Current quorum is not most recent, it is in position {}, not making withdrawals",
33+
"Current quorum is not most recent, it is in position {}, do not pool withdrawals",
3234
position_of_current_quorum
3335
);
36+
3437
return Ok(());
3538
}
3639
// Just use the v1 as to not duplicate code

packages/rs-drive-abci/src/execution/platform_events/withdrawals/pool_withdrawals_into_transactions_queue/v1/mod.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use dpp::block::block_info::BlockInfo;
2+
use metrics::gauge;
23

34
use dpp::data_contract::accessors::v0::DataContractV0Getters;
45
use dpp::document::DocumentV0Getters;
@@ -9,6 +10,9 @@ use drive::grovedb::TransactionArg;
910
use dpp::system_data_contracts::withdrawals_contract;
1011
use dpp::system_data_contracts::withdrawals_contract::v1::document_types::withdrawal;
1112

13+
use crate::metrics::{
14+
GAUGE_CREDIT_WITHDRAWAL_LIMIT_AVAILABLE, GAUGE_CREDIT_WITHDRAWAL_LIMIT_TOTAL,
15+
};
1216
use crate::{
1317
error::{execution::ExecutionError, Error},
1418
platform_types::platform::Platform,
@@ -42,10 +46,16 @@ where
4246
}
4347

4448
// Only take documents up to the withdrawal amount
45-
let current_withdrawal_limit = self
49+
let withdrawals_info = self
4650
.drive
4751
.calculate_current_withdrawal_limit(transaction, platform_version)?;
4852

53+
let current_withdrawal_limit = withdrawals_info.available();
54+
55+
// Store prometheus metrics
56+
gauge!(GAUGE_CREDIT_WITHDRAWAL_LIMIT_AVAILABLE).set(current_withdrawal_limit as f64);
57+
gauge!(GAUGE_CREDIT_WITHDRAWAL_LIMIT_TOTAL).set(withdrawals_info.daily_maximum as f64);
58+
4959
// Only process documents up to the current withdrawal limit.
5060
let mut total_withdrawal_amount = 0u64;
5161

@@ -65,8 +75,12 @@ where
6575
))
6676
})?;
6777

78+
// If adding this withdrawal would exceed the limit, stop processing further.
6879
if potential_total_withdrawal_amount > current_withdrawal_limit {
69-
// If adding this withdrawal would exceed the limit, stop processing further.
80+
tracing::debug!(
81+
"Pooling is limited due to daily withdrawals limit. {} credits left",
82+
current_withdrawal_limit
83+
);
7084
break;
7185
}
7286

packages/rs-drive-abci/src/metrics.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::time::Duration;
66
use std::{sync::Once, time::Instant};
77

88
use dapi_grpc::tonic::Code;
9-
use metrics::{counter, describe_counter, describe_histogram, histogram, Label};
9+
use metrics::{counter, describe_counter, describe_gauge, describe_histogram, histogram, Label};
1010
use metrics_exporter_prometheus::PrometheusBuilder;
1111

1212
/// Default Prometheus port (29090)
@@ -29,6 +29,10 @@ pub const LABEL_STATE_TRANSITION_NAME: &str = "st_name";
2929
const LABEL_STATE_TRANSITION_EXECUTION_CODE: &str = "st_exec_code";
3030
/// Metrics label to specify check tx mode: 0 - first time check, 1 - recheck
3131
pub const LABEL_CHECK_TX_MODE: &str = "check_tx_mode";
32+
/// Withdrawal daily limit available credits
33+
pub const GAUGE_CREDIT_WITHDRAWAL_LIMIT_AVAILABLE: &str = "credit_withdrawal_limit_available";
34+
/// Total withdrawal daily limit in credits
35+
pub const GAUGE_CREDIT_WITHDRAWAL_LIMIT_TOTAL: &str = "credit_withdrawal_limit_total";
3236

3337
/// Error returned by metrics subsystem
3438
#[derive(thiserror::Error, Debug)]
@@ -210,7 +214,17 @@ impl Prometheus {
210214
HISTOGRAM_QUERY_DURATION,
211215
metrics::Unit::Seconds,
212216
"Duration of query request execution inside Drive per endpoint, in seconds"
213-
)
217+
);
218+
219+
describe_gauge!(
220+
GAUGE_CREDIT_WITHDRAWAL_LIMIT_AVAILABLE,
221+
"Available withdrawal limit for last 24 hours in credits"
222+
);
223+
224+
describe_gauge!(
225+
GAUGE_CREDIT_WITHDRAWAL_LIMIT_TOTAL,
226+
"Total withdrawal limit for last 24 hours in credits"
227+
);
214228
});
215229
}
216230
}

packages/rs-drive/src/drive/identity/withdrawals/calculate_current_withdrawal_limit/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,22 @@ use platform_version::version::PlatformVersion;
77

88
mod v0;
99

10+
/// Daily withdrawal limit information
11+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12+
pub struct WithdrawalLimitInfo {
13+
/// The total maximum withdrawal amount allowed in a 24-hour period.
14+
pub daily_maximum: Credits,
15+
/// The amount already withdrawn in the last 24 hours.
16+
pub withdrawals_amount: Credits,
17+
}
18+
19+
impl WithdrawalLimitInfo {
20+
/// Calculates the available credits to withdraw
21+
pub fn available(&self) -> Credits {
22+
self.daily_maximum.saturating_sub(self.withdrawals_amount)
23+
}
24+
}
25+
1026
impl Drive {
1127
/// Calculates the current withdrawal limit based on the total credits available in the platform
1228
/// and the amount already withdrawn in the last 24 hours, using the appropriate version-specific logic.
@@ -34,7 +50,7 @@ impl Drive {
3450
&self,
3551
transaction: TransactionArg,
3652
platform_version: &PlatformVersion,
37-
) -> Result<Credits, Error> {
53+
) -> Result<WithdrawalLimitInfo, Error> {
3854
match platform_version
3955
.drive
4056
.methods

packages/rs-drive/src/drive/identity/withdrawals/calculate_current_withdrawal_limit/v0/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::drive::balances::TOTAL_SYSTEM_CREDITS_STORAGE_KEY;
2+
use crate::drive::identity::withdrawals::calculate_current_withdrawal_limit::WithdrawalLimitInfo;
23
use crate::drive::identity::withdrawals::paths::{
34
get_withdrawal_root_path, WITHDRAWAL_TRANSACTIONS_SUM_AMOUNT_TREE_KEY,
45
};
@@ -7,7 +8,6 @@ use crate::drive::Drive;
78
use crate::error::drive::DriveError;
89
use crate::error::Error;
910
use crate::util::grove_operations::DirectQueryType;
10-
use dpp::fee::Credits;
1111
use dpp::withdrawal::daily_withdrawal_limit::daily_withdrawal_limit;
1212
use grovedb::TransactionArg;
1313
use platform_version::version::PlatformVersion;
@@ -42,7 +42,7 @@ impl Drive {
4242
&self,
4343
transaction: TransactionArg,
4444
platform_version: &PlatformVersion,
45-
) -> Result<Credits, Error> {
45+
) -> Result<WithdrawalLimitInfo, Error> {
4646
// The current withdrawal limit has two components
4747
// 1. The total maximum that we are allowed to do in 24 hours
4848
// 2. The amount that we have already withdrawn in the last 24 hours
@@ -81,6 +81,9 @@ impl Drive {
8181
))
8282
})?;
8383

84-
Ok(daily_maximum.saturating_sub(withdrawal_amount_in_last_day))
84+
Ok(WithdrawalLimitInfo {
85+
daily_maximum,
86+
withdrawals_amount: withdrawal_amount_in_last_day,
87+
})
8588
}
8689
}

packages/rs-drive/src/drive/identity/withdrawals/transaction/queue/dequeue_untied_withdrawal_transactions/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ use grovedb::TransactionArg;
99
use platform_version::version::PlatformVersion;
1010

1111
impl Drive {
12-
/// Get specified amount of withdrawal transactions from the DB
12+
/// Deque specified amount of untiled withdrawal transactions
13+
/// and move them to broadcasted queue
1314
pub fn dequeue_untied_withdrawal_transactions(
1415
&self,
1516
limit: u16,

0 commit comments

Comments
 (0)