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 18 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
1 change: 1 addition & 0 deletions Cargo.lock

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

132 changes: 92 additions & 40 deletions packages/rs-dpp/src/fee/default_costs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@

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

pub mod constants;

Expand Down Expand Up @@ -73,58 +75,108 @@ pub enum KnownCostItem {
VerifySignatureEddsa25519Hash160,
}

const EPOCH_COST_UPDATE_VERSIONS: [u16; 1] = [0];
impl KnownCostItem {
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::DoubleSHA256 => {
//TODO: double_sha256_base or double_sha256_per_block?
fee_version.hashing.double_sha256_base
}
KnownCostItem::SingleSHA256 => {
//TODO: single_sha256_base or single_sha256_per_block?
ogabrielides marked this conversation as resolved.
Show resolved Hide resolved
fee_version.hashing.single_sha256_base
}
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(
&self,
epoch: &Epoch,
ogabrielides marked this conversation as resolved.
Show resolved Hide resolved
cached_fee_version: &BTreeMap<EpochIndex, &'static FeeVersion>,
ogabrielides marked this conversation as resolved.
Show resolved Hide resolved
) -> 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: &BTreeMap<EpochIndex, &'static FeeVersion>,
) -> &'static 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: &BTreeMap<EpochIndex, &'static FeeVersion>,
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: &BTreeMap<EpochIndex, &'static FeeVersion>,
) -> &'static 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;
}
// 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)
}

/// 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: &BTreeMap<EpochIndex, &'static FeeVersion>,
cost_item: KnownCostItem,
) -> Credits {
cost_item.lookup_cost_on_epoch(self, cached_fee_version)
}
}
20 changes: 17 additions & 3 deletions packages/rs-dpp/src/fee/fee_result/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ use crate::fee::Credits;
use crate::ProtocolError;
use bincode::{Decode, Encode};

use lazy_static::lazy_static;
use platform_value::Identifier;
use platform_version::version::fee::FeeVersion;
use platform_version::version::PlatformVersion;
use serde::{Deserialize, Serialize};
use std::collections::btree_map::Iter;
use std::collections::BTreeMap;
Expand All @@ -38,6 +41,7 @@ impl FeeRefunds {
storage_removal: I,
current_epoch_index: EpochIndex,
epochs_per_era: u16,
cached_fee_version: &BTreeMap<EpochIndex, &'static FeeVersion>,
) -> Result<Self, ProtocolError>
where
I: IntoIterator<Item = ([u8; 32], C)>,
Expand All @@ -56,7 +60,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(cached_fee_version, StorageDiskUsageCreditPerByte))
.ok_or(ProtocolError::Overflow("storage written bytes cost overflow"))?;

let (amount, _) = calculate_storage_fee_refund_amount_and_leftovers(
Expand Down Expand Up @@ -168,6 +172,11 @@ impl FeeRefunds {
}
}

lazy_static! {
ogabrielides marked this conversation as resolved.
Show resolved Hide resolved
static ref EPOCH_CHANGE_FEE_VERSION_TEST: BTreeMap<EpochIndex, &'static FeeVersion> =
BTreeMap::from([(0, &PlatformVersion::first().fee_version)]);
}

impl IntoIterator for FeeRefunds {
type Item = ([u8; 32], CreditsPerEpoch);
type IntoIter = std::collections::btree_map::IntoIter<[u8; 32], CreditsPerEpoch>;
Expand All @@ -194,8 +203,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
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ impl<C> Platform<C> {
.clear_version_information(Some(transaction), &platform_version.drive)
.map_err(Error::Drive)?;

let platform_version = PlatformVersion::get(current_block_protocol_version)?;
shumkov marked this conversation as resolved.
Show resolved Hide resolved
let mut cached_fee_version = self.drive.cache.cached_fee_version.write();
if let Some((_, &last_fee_version)) = cached_fee_version.iter().last() {
shumkov marked this conversation as resolved.
Show resolved Hide resolved
if *last_fee_version != platform_version.fee_version {
cached_fee_version.insert(
epoch_info.current_epoch_index(),
&platform_version.fee_version,
);
}
} else {
cached_fee_version.insert(
epoch_info.current_epoch_index(),
&platform_version.fee_version,
);
}

// We clean voting counter cache only on finalize block because:
// 1. The voting counter global cache uses for querying of voting information in Drive queries
// 2. There might be multiple rounds so on the next round we will lose all previous epoch votes
Expand Down
1 change: 1 addition & 0 deletions packages/rs-drive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ grovedb = { git = "https://github.com/dashpay/grovedb", rev = "d9292aa20bd8f3bda
grovedb-costs = { git = "https://github.com/dashpay/grovedb", rev = "d9292aa20bd8f3bda7c5d25d62db06ac341b0677", optional = true }
grovedb-path = { git = "https://github.com/dashpay/grovedb", rev = "d9292aa20bd8f3bda7c5d25d62db06ac341b0677" }
grovedb-storage = { git = "https://github.com/dashpay/grovedb", rev = "d9292aa20bd8f3bda7c5d25d62db06ac341b0677", optional = true }
lazy_static = "1.4.0"
ogabrielides marked this conversation as resolved.
Show resolved Hide resolved

[dev-dependencies]
criterion = "0.3.5"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,14 @@ impl Drive {
task.execute(self, platform_version);
}

let cached_fee_versions = self.cache.cached_fee_version.read();
Drive::calculate_fee(
None,
Some(cost_operations),
&block_info.epoch,
self.config.epochs_per_era,
platform_version,
&cached_fee_versions,
)
}
}
5 changes: 5 additions & 0 deletions packages/rs-drive/src/drive/cache.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use dpp::identity::TimestampMillis;
use std::collections::BTreeMap;

mod data_contract;
mod protocol_version;
mod system_contracts;

pub use data_contract::DataContractCache;
use dpp::block::epoch::EpochIndex;
use platform_version::version::fee::FeeVersion;
pub use protocol_version::ProtocolVersionsCache;
pub use system_contracts::SystemDataContracts;

Expand All @@ -20,4 +23,6 @@ pub struct DriveCache {
pub protocol_versions_counter: parking_lot::RwLock<ProtocolVersionsCache>,
/// Versioned system data contracts
pub system_data_contracts: SystemDataContracts,
/// Cached Epoch changed FeeVersion
pub cached_fee_version: parking_lot::RwLock<BTreeMap<EpochIndex, &'static FeeVersion>>,
shumkov marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,15 @@ impl Drive {
&platform_version.drive,
)?;
cost_operations.push(CalculatedCostOperation(fetch_cost));

let cached_fee_versions = self.cache.cached_fee_version.read();
let fees = Drive::calculate_fee(
None,
Some(cost_operations),
&block_info.epoch,
self.config.epochs_per_era,
platform_version,
&cached_fee_versions,
)?;
Ok(fees)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ impl Drive {
.map_err(Error::Protocol)
);
let drive_operation = CalculatedCostOperation(cost.clone());
let cached_fee_versions = self.cache.cached_fee_version.read();
let fee = if let Some(epoch) = epoch {
Some(cost_return_on_error_no_add!(
&cost,
Expand All @@ -92,7 +93,8 @@ impl Drive {
Some(vec![drive_operation]),
epoch,
self.config.epochs_per_era,
platform_version
platform_version,
&cached_fee_versions
)
))
} else {
Expand Down Expand Up @@ -138,6 +140,7 @@ impl Drive {
.map_err(Error::Protocol)
);
let drive_operation = CalculatedCostOperation(cost.clone());
let cached_fee_versions = self.cache.cached_fee_version.read();
let fee = if let Some(epoch) = epoch {
Some(cost_return_on_error_no_add!(
&cost,
Expand All @@ -146,7 +149,8 @@ impl Drive {
Some(vec![drive_operation]),
epoch,
self.config.epochs_per_era,
platform_version
platform_version,
&cached_fee_versions
)
))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,15 @@ impl Drive {
&mut drive_operations,
platform_version,
)?;
let cached_fee_versions = self.cache.cached_fee_version.read();
let fee_result = epoch.map_or(Ok(None), |epoch| {
Drive::calculate_fee(
None,
Some(drive_operations),
epoch,
self.config.epochs_per_era,
platform_version,
&cached_fee_versions,
)
.map(Some)
})?;
Expand Down Expand Up @@ -148,13 +150,15 @@ impl Drive {
known_fee.clone()
} else {
// we need to calculate new fee
let cached_fee_versions = self.cache.cached_fee_version.read();
let op = vec![CalculatedCostOperation(contract_fetch_info.cost.clone())];
let fee = Drive::calculate_fee(
None,
Some(op),
epoch,
self.config.epochs_per_era,
platform_version,
&cached_fee_versions,
)?;

let updated_contract_fetch_info = Arc::new(DataContractFetchInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ impl Drive {
platform_version,
)?;

let cached_fee_versions = self.cache.cached_fee_version.read();
Drive::calculate_fee(
None,
Some(drive_operations),
&block_info.epoch,
self.config.epochs_per_era,
platform_version,
&cached_fee_versions,
)
}

Expand Down
Loading
Loading