Skip to content

Commit

Permalink
feat(platform)!: withdrawal limits (#2182)
Browse files Browse the repository at this point in the history
  • Loading branch information
QuantumExplorer authored Sep 29, 2024
1 parent 8b847ea commit c8317da
Show file tree
Hide file tree
Showing 82 changed files with 4,460 additions and 324 deletions.
21 changes: 11 additions & 10 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion packages/dashpay-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ license = "MIT"

[dependencies]
platform-version = { path = "../rs-platform-version" }
thiserror = "1.0.58"
thiserror = "1.0.64"
serde_json = { version = "1.0" }
platform-value = { path = "../rs-platform-value" }
2 changes: 1 addition & 1 deletion packages/data-contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rust-version.workspace = true
license = "MIT"

[dependencies]
thiserror = "1.0.58"
thiserror = "1.0.64"
platform-version = { path = "../rs-platform-version" }
serde_json = { version = "1.0" }
withdrawals-contract = { path = "../withdrawals-contract" }
Expand Down
2 changes: 1 addition & 1 deletion packages/dpns-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rust-version.workspace = true
license = "MIT"

[dependencies]
thiserror = "1.0.58"
thiserror = "1.0.64"
platform-version = { path = "../rs-platform-version" }
serde_json = { version = "1.0" }
platform-value = { path = "../rs-platform-value" }
2 changes: 1 addition & 1 deletion packages/feature-flags-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rust-version.workspace = true
license = "MIT"

[dependencies]
thiserror = "1.0.58"
thiserror = "1.0.64"
platform-version = { path = "../rs-platform-version" }
serde_json = { version = "1.0" }
platform-value = { path = "../rs-platform-value" }
2 changes: 1 addition & 1 deletion packages/masternode-reward-shares-contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rust-version.workspace = true
license = "MIT"

[dependencies]
thiserror = "1.0.58"
thiserror = "1.0.64"
platform-version = { path = "../rs-platform-version" }
serde_json = { version = "1.0" }
platform-value = { path = "../rs-platform-value" }
2 changes: 1 addition & 1 deletion packages/rs-dapi-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ dapi-grpc = { path = "../dapi-grpc" }
futures = "0.3.28"
http-serde = { version = "1.1.3", optional = true }
rand = { version = "0.8.5", features = ["small_rng"] }
thiserror = "1.0.58"
thiserror = "1.0.64"
tracing = "0.1.40"
tokio = { version = "1.32.0", default-features = false }
sha2 = { version = "0.10", optional = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use bincode::{Decode, Encode};
#[derive(
Error, Debug, Clone, PartialEq, Eq, Encode, Decode, PlatformSerialize, PlatformDeserialize,
)]
#[error("Credit withdrawal amount {amount} must be greater or equal to {min_amount}")]
#[error("Credit withdrawal amount {amount} must be greater or equal to {min_amount} and less than {max_amount}")]
#[platform_serialize(unversioned)]
pub struct InvalidIdentityCreditWithdrawalTransitionAmountError {
/*
Expand All @@ -20,11 +20,16 @@ pub struct InvalidIdentityCreditWithdrawalTransitionAmountError {
*/
pub amount: u64,
pub min_amount: u64,
pub max_amount: u64,
}

impl InvalidIdentityCreditWithdrawalTransitionAmountError {
pub fn new(amount: u64, min_amount: u64) -> Self {
Self { amount, min_amount }
pub fn new(amount: u64, min_amount: u64, max_amount: u64) -> Self {
Self {
amount,
min_amount,
max_amount,
}
}

pub fn amount(&self) -> u64 {
Expand All @@ -34,6 +39,10 @@ impl InvalidIdentityCreditWithdrawalTransitionAmountError {
pub fn min_amount(&self) -> u64 {
self.min_amount
}

pub fn max_amount(&self) -> u64 {
self.max_amount
}
}

impl From<InvalidIdentityCreditWithdrawalTransitionAmountError> for ConsensusError {
Expand Down
16 changes: 10 additions & 6 deletions packages/rs-dpp/src/identity/core_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,23 @@ impl CoreScript {
Self::from_bytes(bytes)
}

pub fn random_p2pkh(rng: &mut StdRng) -> Self {
Self::new_p2pkh(rng.gen::<[u8; 20]>())
}

pub fn random_p2sh(rng: &mut StdRng) -> Self {
pub fn new_p2sh(script_hash: [u8; 20]) -> Self {
let mut bytes = vec![
opcodes::all::OP_HASH160.to_u8(),
opcodes::all::OP_PUSHBYTES_20.to_u8(),
];
bytes.append(&mut rng.gen::<[u8; 20]>().to_vec());
bytes.extend_from_slice(&script_hash);
bytes.push(opcodes::all::OP_EQUAL.to_u8());
Self::from_bytes(bytes)
}

pub fn random_p2sh(rng: &mut StdRng) -> Self {
Self::new_p2sh(rng.gen())
}

pub fn random_p2pkh(rng: &mut StdRng) -> Self {
Self::new_p2pkh(rng.gen())
}
}

impl From<Vec<u8>> for CoreScript {
Expand Down
30 changes: 30 additions & 0 deletions packages/rs-dpp/src/util/units.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,33 @@ macro_rules! dash_to_credits {
credits as u64
}};
}

#[macro_export]
macro_rules! dash_to_duffs {
// The macro takes a string literal representing the Dash amount.
($dash:expr) => {{
let dash_str = stringify!($dash);

// Parsing the input string to separate the whole and fractional parts.
let parts: Vec<&str> = dash_str.split('.').collect();
let mut credits: u128 = 0;

// Process the whole number part if it exists.
if let Some(whole) = parts.get(0) {
if let Ok(whole_number) = whole.parse::<u128>() {
credits += whole_number * 100_000_000; // Whole Dash amount to credits
}
}

// Process the fractional part if it exists.
if let Some(fraction) = parts.get(1) {
let fraction_length = fraction.len();
let fraction_number = fraction.parse::<u128>().unwrap_or(0);
// Calculate the multiplier based on the number of digits in the fraction.
let multiplier = 10u128.pow(8 - fraction_length as u32);
credits += fraction_number * multiplier; // Fractional Dash to credits
}

credits as u64
}};
}
18 changes: 18 additions & 0 deletions packages/rs-dpp/src/withdrawal/daily_withdrawal_limit/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::fee::Credits;
use crate::withdrawal::daily_withdrawal_limit::v0::daily_withdrawal_limit_v0;
use crate::ProtocolError;
use platform_version::version::PlatformVersion;

mod v0;

pub fn daily_withdrawal_limit(
total_credits_in_platform: Credits,
platform_version: &PlatformVersion,
) -> Result<Credits, ProtocolError> {
match platform_version.dpp.methods.daily_withdrawal_limit {
0 => Ok(daily_withdrawal_limit_v0(total_credits_in_platform)),
v => Err(ProtocolError::UnknownVersionError(format!(
"Unknown daily_withdrawal_limit version {v}"
))),
}
}
54 changes: 54 additions & 0 deletions packages/rs-dpp/src/withdrawal/daily_withdrawal_limit/v0/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::fee::Credits;

/// Calculates the daily withdrawal limit based on the total credits available in the platform.
///
/// The function enforces the following rules:
///
/// 1. If the total credits are 1000 Dash in Credits or more:
/// - The withdrawal limit is set to 10% of the total credits.
/// 2. If the total credits are between 100 and 999 Dash in Credits:
/// - The withdrawal limit is capped at 100 credits.
/// 3. If the total credits are less than 100 Dash in Credits:
/// - The withdrawal limit is the total available credits, as no more than the available amount can be withdrawn.
///
/// # Parameters
///
/// * `total_credits_in_platform`: The total amount of credits available in the platform.
///
/// # Returns
///
/// * `Credits`: The calculated daily withdrawal limit based on the available credits.
///
pub fn daily_withdrawal_limit_v0(total_credits_in_platform: Credits) -> Credits {
if total_credits_in_platform >= 100_000_000_000_000 {
// 1000 Dash
total_credits_in_platform / 10
} else if total_credits_in_platform >= 10_000_000_000_000 {
// 100 Dash
10_000_000_000_000
} else {
total_credits_in_platform
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::dash_to_credits;

#[test]
fn test_daily_withdrawal_limit() {
assert_eq!(
daily_withdrawal_limit_v0(dash_to_credits!(2000)),
dash_to_credits!(200)
);
assert_eq!(
daily_withdrawal_limit_v0(dash_to_credits!(500)),
dash_to_credits!(100)
);
assert_eq!(
daily_withdrawal_limit_v0(dash_to_credits!(50)),
dash_to_credits!(50)
);
}
}
2 changes: 2 additions & 0 deletions packages/rs-dpp/src/withdrawal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod daily_withdrawal_limit;
#[cfg(feature = "system_contracts")]
mod document_try_into_asset_unlock_base_transaction_info;

Expand All @@ -19,4 +20,5 @@ pub enum Pooling {
pub type WithdrawalTransactionIndex = u64;

/// Simple type alias for withdrawal transaction with it's index
pub type WithdrawalTransactionIndexAndBytes = (WithdrawalTransactionIndex, Vec<u8>);
2 changes: 1 addition & 1 deletion packages/rs-drive-abci/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ drive = { path = "../rs-drive", default-features = false, features = [
"server",
"grovedb_operations_logging",
] }
thiserror = "1.0.58"
thiserror = "1.0.64"
rand = "0.8.5"
tempfile = "3.3.0"
hex = "0.4.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::platform_types::platform_state::PlatformState;
use crate::platform_types::validator_set::ValidatorSetExt;
use dpp::version::PlatformVersion;
use std::sync::Arc;
use tenderdash_abci::proto::abci::{RequestInitChain, ResponseInitChain, ValidatorSetUpdate};
use tenderdash_abci::proto::abci::{RequestInitChain, ResponseInitChain};
use tenderdash_abci::proto::google::protobuf::Timestamp;
use tenderdash_abci::proto::serializers::timestamp::FromMilis;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,19 @@ Your software version: {}, latest supported protocol version: {}."#,
);
};

// Set current protocol version to the block platform state
block_platform_state.set_current_protocol_version_in_consensus(next_protocol_version);
let old_protocol_version = block_platform_state.current_protocol_version_in_consensus();

if old_protocol_version != next_protocol_version {
// Set current protocol version to the block platform state
block_platform_state
.set_current_protocol_version_in_consensus(next_protocol_version);
// This is for events like adding stuff to the root tree, or making structural changes/fixes
self.perform_events_on_first_block_of_protocol_change(
transaction,
old_protocol_version,
next_platform_version,
)?;
}

next_platform_version
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,17 @@ where
platform_version,
)?;

// Cleans up the expired locks for withdrawal amounts
// This is for example when we make a withdrawal for 30 Dash
// But we can only withdraw 1000 Dash a day
// after the withdrawal we should only be able to withdraw 970 Dash
// But 24 hours later that locked 30 comes back
self.clean_up_expired_locks_of_withdrawal_amounts(
&block_info,
transaction,
platform_version,
)?;

// Create a new block execution context

let mut block_execution_context: BlockExecutionContext =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
mod check_for_desired_protocol_upgrade;
mod perform_events_on_first_block_of_protocol_change;
mod upgrade_protocol_version;
Loading

0 comments on commit c8317da

Please sign in to comment.