Skip to content
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
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
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Sep 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential overflow when casting to u64

The final conversion credits as u64 may cause an overflow for large Dash amounts. Consider adding a check to ensure the value fits within u64 before casting.

You could add a runtime check:

if credits > u64::MAX as u128 {
    panic!("Dash amount too large to convert to Duffs");
}
credits as u64

Or, for a compile-time check (which would be preferable), you could use the TryInto trait:

use std::convert::TryInto;
credits.try_into().expect("Dash amount too large to convert to Duffs")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need as this is not used in production code.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@QuantumExplorer, understood. Thanks for the clarification.

(•.•)?


✏️ Learnings added
Learnt from: QuantumExplorer
PR: dashpay/platform#2182
File: packages/rs-dpp/src/util/units.rs:57-57
Timestamp: 2024-09-29T09:35:10.905Z
Learning: The macro `dash_to_duffs` in `units.rs` is not used in production code.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Copy link
Copy Markdown
Collaborator

@shumkov shumkov Sep 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@QuantumExplorer Please add test flag then if it's not using in production code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

}};
}
Comment on lines +31 to +59
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication

The dash_to_duffs macro is very similar to the existing dash_to_credits macro. Consider refactoring these macros to share common logic, which would improve maintainability and reduce the risk of inconsistencies.

You could create a helper macro that takes the multiplication factors as parameters:

macro_rules! dash_to_units {
    ($dash:expr, $whole_multiplier:expr, $fraction_digits:expr) => {{
        // Common logic here
    }};
}

macro_rules! dash_to_credits {
    ($dash:expr) => {
        dash_to_units!($dash, 100_000_000_000, 11)
    };
}

macro_rules! dash_to_duffs {
    ($dash:expr) => {
        dash_to_units!($dash, 100_000_000, 8)
    };
}

This approach would centralize the conversion logic and make it easier to maintain and extend in the future.


⚠️ Potential issue

Add input validation for negative numbers and invalid characters

The current implementation doesn't validate the input for negative numbers or invalid characters. This could lead to unexpected behavior or panics.

Consider adding input validation at the beginning of the macro:

let dash_str = stringify!($dash);
if dash_str.starts_with('-') {
    panic!("Negative Dash amounts are not supported");
}
if !dash_str.chars().all(|c| c.is_digit(10) || c == '.') {
    panic!("Invalid characters in Dash amount");
}

This will ensure that only valid, positive Dash amounts are processed.

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 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it credits in dash?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it's credits

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, fixed.

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