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

refactor: fees to use version system #1911

Merged
merged 51 commits into from
Jul 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
09531c7
start of work
QuantumExplorer Jun 24, 2024
083323a
more work
ogabrielides Jun 27, 2024
11957fc
made cached_fee_version static ref
ogabrielides Jun 27, 2024
2e4e8b1
more work
ogabrielides Jun 27, 2024
d04d626
fmt
ogabrielides Jun 27, 2024
1b9ca71
more work
ogabrielides Jun 27, 2024
26e0209
more work
ogabrielides Jun 27, 2024
cebc0ed
fmt
ogabrielides Jun 27, 2024
ca29a8f
comment
ogabrielides Jun 27, 2024
a23d9dd
partialeq for fee versions
ogabrielides Jun 27, 2024
3a1a3b4
insert fee version only if it was changed
ogabrielides Jun 27, 2024
0bebf1f
fmt
ogabrielides Jun 27, 2024
40c6724
fmt
ogabrielides Jun 27, 2024
12d3eec
clippy fixes
ogabrielides Jun 27, 2024
818bf45
remove comment
ogabrielides Jun 27, 2024
1e924c2
fmt
ogabrielides Jun 27, 2024
5812e83
undo work in platform state
ogabrielides Jun 27, 2024
952bd58
renamed variable
ogabrielides Jun 27, 2024
e63b138
suggestions
ogabrielides Jun 28, 2024
9f3b13b
more work
ogabrielides Jun 28, 2024
0121c9e
comments
ogabrielides Jun 28, 2024
dfca1bd
clippy
ogabrielides Jun 29, 2024
28e4286
more linter fixes
ogabrielides Jun 29, 2024
1710dbd
more suggestions
ogabrielides Jun 29, 2024
09f3c14
suggestion
ogabrielides Jun 29, 2024
62aacc6
Merge branch 'v1.0-dev' into refactor/FeesToUseVersionSystem
shumkov Jun 30, 2024
72c766b
Merge branch 'v1.0-dev' into refactor/FeesToUseVersionSystem
ogabrielides Jun 30, 2024
834c882
suggestions
ogabrielides Jun 30, 2024
3e95442
suggestions
ogabrielides Jun 30, 2024
f7512b1
new system using platform state and fixes
QuantumExplorer Jun 30, 2024
a099d2e
more work
ogabrielides Jul 3, 2024
83fa45d
suggestion
ogabrielides Jul 4, 2024
7da6121
suggestion
ogabrielides Jul 4, 2024
6c440dd
suggestion
ogabrielides Jul 4, 2024
86228f3
suggestion
ogabrielides Jul 4, 2024
e79449e
suggestion
ogabrielides Jul 4, 2024
2d6b7b9
suggestion
ogabrielides Jul 4, 2024
e1a0c56
suggestion
ogabrielides Jul 4, 2024
ed7d1b6
restored partialeq instead of hashing
ogabrielides Jul 4, 2024
199cfb7
tests
ogabrielides Jul 4, 2024
33ab299
clippy + fmt
ogabrielides Jul 4, 2024
1ef064e
None previous_fee_versions when overwrite (insert) is false
ogabrielides Jul 4, 2024
d915afd
fmt
ogabrielides Jul 4, 2024
53d1c91
added test for FeeVersion
ogabrielides Jul 5, 2024
ac6dcfd
Merge branch 'v1.0-dev' into refactor/FeesToUseVersionSystem
ogabrielides Jul 8, 2024
ae90169
Merge branch 'v1.0-dev' into refactor/FeesToUseVersionSystem
ogabrielides Jul 12, 2024
a079258
conflict resolutions
ogabrielides Jul 12, 2024
91f8952
suggestions
ogabrielides Jul 12, 2024
86394d4
more work
ogabrielides Jul 12, 2024
3a9e940
fmt
ogabrielides Jul 12, 2024
4c383bc
refactoring
ogabrielides Jul 12, 2024
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions packages/rs-dpp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ tokio = { version = "1.17", features = ["full"] }
pretty_assertions = { version = "1.3.0" }
dpp = { path = ".", features = ["all_features_without_client"] }
assert_matches = "1.5.0"
once_cell = "1.7"

[features]
default = ["platform-value", "state-transitions"]
Expand Down
141 changes: 95 additions & 46 deletions packages/rs-dpp/src/fee/default_costs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@
//! Fee costs for Known Platform operations
//!

use crate::block::epoch::Epoch;
use crate::block::epoch::EpochIndex;
use lazy_static::lazy_static;
use std::collections::HashMap;
use crate::block::epoch::{Epoch, EpochIndex};
use crate::fee::Credits;
use platform_version::version::fee::FeeVersion;
use platform_version::version::PlatformVersion;
use std::collections::BTreeMap;

pub mod constants;

pub type CachedEpochIndexFeeVersions = BTreeMap<EpochIndex, FeeVersion>;

/// A Known Cost Item is an item that changes costs depending on the Epoch
#[derive(Eq, PartialEq, Copy, Clone, Hash)]
pub enum KnownCostItem {
Expand All @@ -57,10 +60,10 @@ pub enum KnownCostItem {
FetchIdentityBalanceProcessingCost,
/// The cost for fetching an identity key
FetchSingleIdentityKeyProcessingCost,
/// The cost for a Double SHA256 operation
DoubleSHA256,
/// The cost for a Single SHA256 operation
SingleSHA256,
/// The cost for a Single SHA256 operation, with a specific size
SingleSHA256(usize),
/// The cost for a Blake3 operation, with a specific size
Blake3(usize),
/// The cost for a EcdsaSecp256k1 signature verification
VerifySignatureEcdsaSecp256k1,
/// The cost for a BLS12_381 signature verification
Expand All @@ -73,58 +76,104 @@ pub enum KnownCostItem {
VerifySignatureEddsa25519Hash160,
}

const EPOCH_COST_UPDATE_VERSIONS: [u16; 1] = [0];
impl KnownCostItem {
#[inline]
pub fn lookup_cost(&self, fee_version: &FeeVersion) -> Credits {
match self {
KnownCostItem::StorageDiskUsageCreditPerByte => {
fee_version.storage.storage_disk_usage_credit_per_byte
}
KnownCostItem::StorageProcessingCreditPerByte => {
fee_version.storage.storage_processing_credit_per_byte
}
KnownCostItem::StorageLoadCreditPerByte => {
fee_version.storage.storage_load_credit_per_byte
}
KnownCostItem::NonStorageLoadCreditPerByte => {
fee_version.storage.non_storage_load_credit_per_byte
}
KnownCostItem::StorageSeekCost => fee_version.storage.storage_seek_cost,
KnownCostItem::FetchIdentityBalanceProcessingCost => {
fee_version
.processing
.fetch_identity_balance_processing_cost
}
KnownCostItem::FetchSingleIdentityKeyProcessingCost => {
fee_version
.processing
.fetch_single_identity_key_processing_cost
}
KnownCostItem::Blake3(size) => {
fee_version.hashing.blake3_base
+ fee_version.hashing.blake3_per_block * *size as u64
}
KnownCostItem::SingleSHA256(size) => {
fee_version.hashing.single_sha256_base
+ fee_version.hashing.sha256_per_block * *size as u64
}
KnownCostItem::VerifySignatureEcdsaSecp256k1 => {
fee_version.signature.verify_signature_ecdsa_secp256k1
}
KnownCostItem::VerifySignatureBLS12_381 => {
fee_version.signature.verify_signature_bls12_381
}
KnownCostItem::VerifySignatureEcdsaHash160 => {
fee_version.signature.verify_signature_ecdsa_hash160
}
KnownCostItem::VerifySignatureBip13ScriptHash => {
fee_version.signature.verify_signature_bip13_script_hash
}
KnownCostItem::VerifySignatureEddsa25519Hash160 => {
fee_version.signature.verify_signature_eddsa25519_hash160
}
}
}

lazy_static! {
static ref EPOCH_COSTS: HashMap<EpochIndex, HashMap<KnownCostItem, u64>> = HashMap::from([(
0,
HashMap::from([
(KnownCostItem::StorageDiskUsageCreditPerByte, 27000u64),
(KnownCostItem::StorageProcessingCreditPerByte, 400u64),
(KnownCostItem::StorageLoadCreditPerByte, 400u64),
(KnownCostItem::NonStorageLoadCreditPerByte, 30u64),
(KnownCostItem::StorageSeekCost, 4000u64),
(KnownCostItem::FetchIdentityBalanceProcessingCost, 10000u64),
(
KnownCostItem::FetchSingleIdentityKeyProcessingCost,
10000u64
),
(KnownCostItem::DoubleSHA256, 800u64),
(KnownCostItem::SingleSHA256, 500u64),
(KnownCostItem::VerifySignatureEcdsaSecp256k1, 3000u64),
(KnownCostItem::VerifySignatureBLS12_381, 6000u64),
(KnownCostItem::VerifySignatureEcdsaHash160, 4000u64),
(KnownCostItem::VerifySignatureBip13ScriptHash, 6000u64),
(KnownCostItem::VerifySignatureEddsa25519Hash160, 3000u64),
])
)]);
pub fn lookup_cost_on_epoch<T: EpochCosts>(
&self,
epoch: &T,
cached_fee_version: &CachedEpochIndexFeeVersions,
) -> Credits {
let version = epoch.active_fee_version(cached_fee_version);
self.lookup_cost(&version)
}
}

/// Costs for Epochs
pub trait EpochCosts {
//todo: should just have a static lookup table
/// Get the closest epoch in the past that has a cost table
/// This is where the base costs last changed
fn get_closest_epoch_index_cost_update_version(&self) -> EpochIndex;
fn active_fee_version(&self, cached_fee_version: &CachedEpochIndexFeeVersions) -> FeeVersion;
/// Get the cost for the known cost item
fn cost_for_known_cost_item(&self, cost_item: KnownCostItem) -> u64;
fn cost_for_known_cost_item(
&self,
cached_fee_version: &CachedEpochIndexFeeVersions,
cost_item: KnownCostItem,
) -> Credits;
}

impl EpochCosts for Epoch {
//todo: should just have a static lookup table
/// Get the closest epoch in the past that has a cost table
/// This is where the base costs last changed
fn get_closest_epoch_index_cost_update_version(&self) -> EpochIndex {
match EPOCH_COST_UPDATE_VERSIONS.binary_search(&self.index) {
Ok(_) => self.index,
Err(pos) => EPOCH_COST_UPDATE_VERSIONS[pos - 1],
/// Get the active fee version for an epoch
fn active_fee_version(&self, cached_fee_version: &CachedEpochIndexFeeVersions) -> FeeVersion {
// If the exact EpochIndex is matching to a FeeVersion update
if let Some(fee_version) = cached_fee_version.get(&self.index) {
return fee_version.clone();
}
// else return the FeeVersion at lower adjacent EpochIndex (if available, else the FeeVersion of first PlatformVersion)
cached_fee_version
.range(..=self.index)
.next_back()
.map(|(_, fee_version)| fee_version)
.unwrap_or_else(|| &PlatformVersion::first().fee_version)
.clone()
}

/// Get the cost for the known cost item
fn cost_for_known_cost_item(&self, cost_item: KnownCostItem) -> u64 {
let epoch = self.get_closest_epoch_index_cost_update_version();
let specific_epoch_costs = EPOCH_COSTS.get(&epoch).unwrap();
*specific_epoch_costs.get(&cost_item).unwrap()
fn cost_for_known_cost_item(
&self,
cached_fee_version: &CachedEpochIndexFeeVersions,
cost_item: KnownCostItem,
) -> Credits {
cost_item.lookup_cost_on_epoch(self, cached_fee_version)
}
}
19 changes: 15 additions & 4 deletions packages/rs-dpp/src/fee/fee_result/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
//!

use crate::block::epoch::{Epoch, EpochIndex};
use crate::fee::default_costs::EpochCosts;
use crate::fee::default_costs::KnownCostItem::StorageDiskUsageCreditPerByte;
use crate::fee::default_costs::{CachedEpochIndexFeeVersions, EpochCosts};
use crate::fee::epoch::distribution::calculate_storage_fee_refund_amount_and_leftovers;
use crate::fee::epoch::{BytesPerEpoch, CreditsPerEpoch};
use crate::fee::Credits;
Expand Down Expand Up @@ -38,6 +38,7 @@ impl FeeRefunds {
storage_removal: I,
current_epoch_index: EpochIndex,
epochs_per_era: u16,
previous_fee_versions: &CachedEpochIndexFeeVersions,
) -> Result<Self, ProtocolError>
where
I: IntoIterator<Item = ([u8; 32], C)>,
Expand All @@ -56,7 +57,7 @@ impl FeeRefunds {
// TODO We should use multipliers

let credits: Credits = (bytes as Credits)
.checked_mul(Epoch::new(current_epoch_index)?.cost_for_known_cost_item(StorageDiskUsageCreditPerByte))
.checked_mul(Epoch::new(current_epoch_index)?.cost_for_known_cost_item(previous_fee_versions, StorageDiskUsageCreditPerByte))
.ok_or(ProtocolError::Overflow("storage written bytes cost overflow"))?;

let (amount, _) = calculate_storage_fee_refund_amount_and_leftovers(
Expand Down Expand Up @@ -180,6 +181,11 @@ impl IntoIterator for FeeRefunds {
#[cfg(test)]
mod tests {
use super::*;
use once_cell::sync::Lazy;
use platform_version::version::PlatformVersion;

static EPOCH_CHANGE_FEE_VERSION_TEST: Lazy<CachedEpochIndexFeeVersions> =
Lazy::new(|| BTreeMap::from([(0, PlatformVersion::first().fee_version.clone())]));

mod from_storage_removal {
use super::*;
Expand All @@ -194,8 +200,13 @@ mod tests {
let storage_removal =
BytesPerEpochByIdentifier::from_iter([(identity_id, bytes_per_epoch)]);

let fee_refunds = FeeRefunds::from_storage_removal(storage_removal, 3, 20)
.expect("should create fee refunds");
let fee_refunds = FeeRefunds::from_storage_removal(
storage_removal,
3,
20,
&EPOCH_CHANGE_FEE_VERSION_TEST,
)
.expect("should create fee refunds");

let credits_per_epoch = fee_refunds.get(&identity_id).expect("should exists");

Expand Down
1 change: 1 addition & 0 deletions packages/rs-dpp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub use async_trait;
pub use bls::*;

pub mod prelude {

pub use crate::data_contract::DataContract;
#[cfg(feature = "extended-document")]
pub use crate::document::ExtendedDocument;
Expand Down
18 changes: 10 additions & 8 deletions packages/rs-drive-abci/src/execution/check_tx/v0/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ where
state_read_guard.last_block_info(),
transaction,
platform_ref.state.current_platform_version()?,
platform_ref.state.previous_fee_versions(),
)
} else {
Ok(UnpaidConsensusExecutionError(
Expand Down Expand Up @@ -177,6 +178,7 @@ where
platform_ref.state.last_block_info(),
None,
platform_version,
platform_ref.state.previous_fee_versions(),
)?;

let (estimated_fee_result, errors) = validation_result.into_data_and_errors()?;
Expand Down Expand Up @@ -475,7 +477,7 @@ mod tests {
)
.expect("expected to process state transition");

assert_eq!(processing_result.aggregated_fees().processing_fee, 3055480);
assert_eq!(processing_result.aggregated_fees().processing_fee, 3085850); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

let check_result = platform
.check_tx(
Expand Down Expand Up @@ -677,7 +679,7 @@ mod tests {
// We have one invalid paid for state transition
assert_eq!(processing_result.invalid_paid_count(), 1);

assert_eq!(processing_result.aggregated_fees().processing_fee, 905380);
assert_eq!(processing_result.aggregated_fees().processing_fee, 909400); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

let check_result = platform
.check_tx(
Expand Down Expand Up @@ -829,7 +831,7 @@ mod tests {
// since a fee multiplier of 100 means 100% more of 1 (gives 2)
assert_eq!(
processing_result.aggregated_fees().processing_fee,
3055480 * 2
3085850 * 2 // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised
);

let check_result = platform
Expand Down Expand Up @@ -1087,7 +1089,7 @@ mod tests {
)
.expect("expected to process state transition");

assert_eq!(processing_result.aggregated_fees().processing_fee, 3055480);
assert_eq!(processing_result.aggregated_fees().processing_fee, 3085850); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

platform
.drive
Expand Down Expand Up @@ -1171,8 +1173,8 @@ mod tests {

assert_eq!(
update_processing_result.aggregated_fees().processing_fee,
7420280
);
7446290
); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

let check_result = platform
.check_tx(
Expand Down Expand Up @@ -1293,7 +1295,7 @@ mod tests {
)
.expect("expected to process state transition");

assert_eq!(processing_result.aggregated_fees().processing_fee, 3055480);
assert_eq!(processing_result.aggregated_fees().processing_fee, 3085850); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

platform
.drive
Expand Down Expand Up @@ -1413,7 +1415,7 @@ mod tests {
// We have one invalid paid for state transition
assert_eq!(processing_result.invalid_paid_count(), 1);

assert_eq!(processing_result.aggregated_fees().processing_fee, 1231050);
assert_eq!(processing_result.aggregated_fees().processing_fee, 1238700); // TODO: Readjust this test when FeeHashingVersion blake3_base, sha256_ripe_md160_base, blake3_per_block values are finalised

let check_result = platform
.check_tx(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ where
block_fees_v0.into(),
transaction,
platform_version,
block_execution_context
.block_platform_state()
.previous_fee_versions(),
)?;

tracing::debug!(block_fees = ?processed_block_fees, "block fees are processed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ mod tests {
use crate::platform_types::platform_state::PlatformState;
use dpp::block::block_info::BlockInfo;
use dpp::fee::epoch::CreditsPerEpoch;

use drive::drive::defaults::INITIAL_PROTOCOL_VERSION;

/// Process and validate an epoch change
Expand Down Expand Up @@ -211,6 +212,7 @@ mod tests {
&BlockInfo::default(),
Some(transaction),
platform_version,
None,
)
.expect("should apply batch");
}
Expand Down Expand Up @@ -285,6 +287,7 @@ mod tests {
&BlockInfo::default(),
Some(transaction),
platform_version,
None,
)
.expect("should apply batch");

Expand Down
Loading
Loading