Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #185 from dashpay/fix-contract-cache-sam-changes
Browse files Browse the repository at this point in the history
a few fixes for storage flags
  • Loading branch information
shumkov authored Nov 16, 2022
2 parents 88972e0 + 985c13b commit b6b49ac
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 28 deletions.
11 changes: 11 additions & 0 deletions dpp/src/data_contract/extra/drive_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub trait DriveContractExt {
fn keeps_history(&self) -> bool;
fn set_keeps_history(&mut self, value: bool);

fn can_be_deleted(&self) -> bool;
fn set_can_be_deleted(&mut self, can_be_deleted: bool);

fn readonly(&self) -> bool;
fn set_readonly(&mut self, is_read_only: bool);

Expand Down Expand Up @@ -88,6 +91,13 @@ impl DriveContractExt for DataContract {
self.config.keeps_history = value
}

fn can_be_deleted(&self) -> bool {
self.config.can_be_deleted
}
fn set_can_be_deleted(&mut self, can_be_deleted: bool) {
self.config.can_be_deleted = can_be_deleted;
}

fn readonly(&self) -> bool {
self.config.readonly
}
Expand Down Expand Up @@ -464,6 +474,7 @@ mod test {
assert!(matches!(
deserialized_contract.config,
ContractConfig {
can_be_deleted: false,
readonly: true,
keeps_history: true,
documents_mutable_contract_default: false,
Expand Down
9 changes: 8 additions & 1 deletion dpp/src/data_contract/extra/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::collections::BTreeMap;

use ciborium::value::Value as CborValue;

use crate::data_contract::extra::mutability::DEFAULT_CONTRACT_CAN_BE_DELETED;
use mutability::{
DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY, DEFAULT_CONTRACT_DOCUMENT_MUTABILITY,
DEFAULT_CONTRACT_KEEPS_HISTORY, DEFAULT_CONTRACT_MUTABILITY,
Expand Down Expand Up @@ -39,6 +40,11 @@ pub fn get_mutability(
mutability::property::KEEPS_HISTORY,
DEFAULT_CONTRACT_KEEPS_HISTORY,
)?;
let can_be_deleted: bool = common::bool_for_system_value_from_tree_map(
contract,
mutability::property::CAN_BE_DELETED,
DEFAULT_CONTRACT_CAN_BE_DELETED,
)?;
let readonly: bool = common::bool_for_system_value_from_tree_map(
contract,
mutability::property::READONLY,
Expand All @@ -57,8 +63,9 @@ pub fn get_mutability(
)?;

Ok(ContractConfig {
keeps_history,
can_be_deleted,
readonly,
keeps_history,
documents_keep_history_contract_default,
documents_mutable_contract_default,
})
Expand Down
5 changes: 5 additions & 0 deletions dpp/src/data_contract/extra/mutability.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use serde::{Deserialize, Serialize};

pub const DEFAULT_CONTRACT_KEEPS_HISTORY: bool = false;
pub const DEFAULT_CONTRACT_CAN_BE_DELETED: bool = false;
pub const DEFAULT_CONTRACT_MUTABILITY: bool = true;
pub const DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY: bool = false;
pub const DEFAULT_CONTRACT_DOCUMENT_MUTABILITY: bool = true;

pub mod property {
pub const CAN_BE_DELETED: &str = "canBeDeleted";
pub const READONLY: &str = "readonly";
pub const KEEPS_HISTORY: &str = "keepsHistory";
pub const DOCUMENTS_KEEP_HISTORY_CONTRACT_DEFAULT: &str = "documentsKeepHistoryContractDefault";
Expand All @@ -15,6 +17,8 @@ pub mod property {
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
#[serde(rename_all = "camelCase", default)]
pub struct ContractConfig {
/// Can the contract ever be deleted
pub can_be_deleted: bool,
/// Is the contract mutable
pub readonly: bool,
/// Does the contract keep history when the contract itself changes
Expand All @@ -28,6 +32,7 @@ pub struct ContractConfig {
impl std::default::Default for ContractConfig {
fn default() -> Self {
ContractConfig {
can_be_deleted: DEFAULT_CONTRACT_CAN_BE_DELETED,
readonly: !DEFAULT_CONTRACT_MUTABILITY,
keeps_history: DEFAULT_CONTRACT_KEEPS_HISTORY,
documents_keep_history_contract_default: DEFAULT_CONTRACT_DOCUMENTS_KEEPS_HISTORY,
Expand Down
63 changes: 36 additions & 27 deletions drive/src/drive/contract/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,18 @@ impl Drive {

let contract = <Contract as DriveContractExt>::from_cbor(&contract_cbor, contract_id)?;

let storage_flags = StorageFlags::new_single_epoch(
block_info.epoch.index,
Some(contract.owner_id.to_buffer()),
);
let storage_flags = if contract.can_be_deleted() || !contract.readonly() {
Some(StorageFlags::new_single_epoch(
block_info.epoch.index,
Some(contract.owner_id.to_buffer()),
))
} else {
None
};

let contract_element = Element::Item(
contract_cbor,
StorageFlags::map_to_some_element_flags(Some(storage_flags).as_ref()),
StorageFlags::map_to_some_element_flags(storage_flags.as_ref()),
);

self.insert_contract_element(
Expand Down Expand Up @@ -347,14 +351,15 @@ impl Drive {

let contract_id = contract_id.unwrap_or_else(|| *contract.id().as_bytes());

let storage_flags = StorageFlags::new_single_epoch(
// Since we can update the contract by definition it already has storage flags
let storage_flags = Some(StorageFlags::new_single_epoch(
block_info.epoch.index,
Some(contract.owner_id.to_buffer()),
);
));

let contract_element = Element::Item(
contract_cbor,
StorageFlags::map_to_some_element_flags(Some(storage_flags).as_ref()),
StorageFlags::map_to_some_element_flags(storage_flags.as_ref()),
);

let original_contract_fetch_info = self
Expand All @@ -365,9 +370,15 @@ impl Drive {
&mut drive_operations,
)?
.ok_or(Error::Drive(DriveError::CorruptedCodeExecution(
"Contract should exists",
"contract should exist",
)))?;

if original_contract_fetch_info.contract.readonly() {
return Err(Error::Drive(DriveError::UpdatingReadOnlyImmutableContract(
"original contract is readonly",
)));
}

self.update_contract_element(
contract_element,
&contract,
Expand Down Expand Up @@ -639,25 +650,23 @@ impl Drive {
.fetch_contract(contract_id, epoch, transaction)
.unwrap_add_cost(&mut cost)?;

// we only need to pay if epoch is set
if epoch.is_some() {
if let Some(contract_fetch_info) = &result {
// Store a contract in cache
cache
.cached_contracts
.insert(Arc::clone(contract_fetch_info), transaction);

if epoch.is_some() {
let fee = contract_fetch_info.fee.as_ref().ok_or(
Error::Drive(DriveError::CorruptedCodeExecution(
"should be impossible to not have fee on something just fetched with an epoch",
))
)?;
drive_operations.push(PreCalculatedFeeResult(fee.clone()));
}
} else if epoch.is_some() {
drive_operations.push(CalculatedCostOperation(cost));
if let Some(contract_fetch_info) = &result {
// Store a contract in cache
cache
.cached_contracts
.insert(Arc::clone(contract_fetch_info), transaction);

// we only need to pay if epoch is set
if epoch.is_some() {
let fee = contract_fetch_info.fee.as_ref().ok_or(
Error::Drive(DriveError::CorruptedCodeExecution(
"should be impossible to not have fee on something just fetched with an epoch",
))
)?;
drive_operations.push(PreCalculatedFeeResult(fee.clone()));
}
} else if epoch.is_some() {
drive_operations.push(CalculatedCostOperation(cost));
}
Ok(result)
}
Expand Down

0 comments on commit b6b49ac

Please sign in to comment.