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

feat: Remove ContractsInfo #673

Merged
merged 25 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

- [#1632](https://github.com/FuelLabs/fuel-core/pull/1632): Introduce a new enum `ContractsInfoType` to store versioned non-protocol-level Contract information in the `ContractsInfo` table.

## [Version 0.45.0]

### Changed
Expand Down
6 changes: 3 additions & 3 deletions fuel-vm/src/interpreter/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,13 +895,13 @@ impl<'vm, S, I: Iterator<Item = &'vm ContractId>> CodeRootCtx<'vm, S, I> {

self.input_contracts.check(contract_id)?;

let (_, root) = self
let root = self
.storage
.storage_contract_root(contract_id)
.storage_contract(contract_id)
.transpose()
.ok_or(PanicReason::ContractNotFound)?
.map_err(RuntimeError::Storage)?
.into_owned();
.root();

try_mem_write(a, root.as_ref(), self.owner, self.memory)?;

Expand Down
16 changes: 8 additions & 8 deletions fuel-vm/src/interpreter/blockchain/other_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use core::{
use super::*;
use crate::interpreter::PanicContext;
use fuel_storage::StorageAsMut;
use fuel_types::Salt;
use fuel_tx::Contract;
use test_case::test_case;

#[test_case(false, 0, None, 0, [0; 32] => Ok(()); "Burn nothing")]
Expand Down Expand Up @@ -264,13 +264,13 @@ fn test_code_root() {
.expect_err("Contract is not found");
assert_eq!(pc, 4);

let data = alloc::vec![0xffu8; 512];
let contract: Contract = data.into();
let root = contract.root();
storage
.storage_contract_root_insert(
&ContractId::from([3u8; 32]),
&Salt::from([5u8; 32]),
&Bytes32::from([6u8; 32]),
)
.unwrap();
.storage_contract_insert(&contract_id, &contract)
.expect("Failed to insert contract");

let owner = OwnershipRegisters {
sp: 1000,
ssp: 1,
Expand All @@ -290,7 +290,7 @@ fn test_code_root() {
.code_root(20, 0)
.unwrap();
assert_eq!(pc, 8);
assert_eq!(memory[20..20 + 32], [6u8; 32]);
assert_eq!(memory[20..20 + 32], *root.as_slice());

let owner = OwnershipRegisters {
sp: 1000,
Expand Down
12 changes: 6 additions & 6 deletions fuel-vm/src/interpreter/diff/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use super::{
pub(super) enum StorageDelta {
State(MappableDelta<ContractsStateKey, Bytes32>),
Assets(MappableDelta<ContractsAssetKey, u64>),
Info(MappableDelta<ContractId, (fuel_types::Salt, Bytes32)>),
Info(MappableDelta<ContractId, <ContractsInfo as Mappable>::Value>),
RawCode(MappableDelta<ContractId, Contract>),
}

Expand All @@ -38,7 +38,7 @@ pub(super) enum StorageDelta {
pub(super) enum StorageState {
State(MappableState<ContractsStateKey, Bytes32>),
Assets(MappableState<ContractsAssetKey, u64>),
Info(MappableState<ContractId, (fuel_types::Salt, Bytes32)>),
Info(MappableState<ContractId, <ContractsInfo as Mappable>::Value>),
RawCode(MappableState<ContractId, Contract>),
}

Expand Down Expand Up @@ -474,15 +474,15 @@ impl StorageType for ContractsAssets {
impl StorageType for ContractsInfo {
fn record_insert(
key: &ContractId,
value: &(fuel_types::Salt, Bytes32),
existing: Option<(fuel_types::Salt, Bytes32)>,
value: &<ContractsInfo as Mappable>::Value,
existing: Option<<ContractsInfo as Mappable>::Value>,
) -> StorageDelta {
StorageDelta::Info(MappableDelta::Insert(*key, *value, existing))
StorageDelta::Info(MappableDelta::Insert(*key, value.clone(), existing))
}

fn record_remove(
key: &ContractId,
value: (fuel_types::Salt, Bytes32),
value: <ContractsInfo as Mappable>::Value,
) -> StorageDelta {
StorageDelta::Info(MappableDelta::Remove(*key, value))
}
Expand Down
2 changes: 1 addition & 1 deletion fuel-vm/src/interpreter/executors/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ where
}

storage
.deploy_contract_with_id(salt, storage_slots, &contract, &root, &id)
.deploy_contract_with_id(salt, storage_slots, &contract, &id)
.map_err(RuntimeError::Storage)?;
Self::finalize_outputs(
create,
Expand Down
23 changes: 19 additions & 4 deletions fuel-vm/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,31 @@ impl Mappable for ContractsRawCode {
type Value = [u8];
}

/// The storage table for contract's additional information as salt, root hash, etc.
/// The storage table for contract's additional information
pub struct ContractsInfo;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not even sure that we need this table here=) Since we don't use salt in any logic, we can simply skip it, and it can be fully off-chain information.


/// The versioned type to describe additional contract information.
#[derive(Debug, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ContractsInfoType {
/// V1: the salt used during creation of the contract for uniqueness.
V1(Salt),
}

impl ContractsInfoType {
/// Get the contract's salt
pub fn salt(&self) -> &Salt {
match self {
ContractsInfoType::V1(salt) => salt,
}
}
}

impl Mappable for ContractsInfo {
type Key = Self::OwnedKey;
type OwnedKey = ContractId;
type OwnedValue = Self::Value;
/// `Salt` - is the salt used during creation of the contract for uniques.
/// `Bytes32` - is the root hash of the contract's code.
type Value = (Salt, Bytes32);
type Value = ContractsInfoType;
}

/// The storage table for contract's assets balances.
Expand Down
26 changes: 14 additions & 12 deletions fuel-vm/src/storage/interpreter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Trait definitions for storage backend

use fuel_storage::{
Mappable,
MerkleRootStorage,
StorageAsRef,
StorageInspect,
Expand Down Expand Up @@ -29,6 +30,7 @@ use crate::{
storage::{
ContractsAssets,
ContractsInfo,
ContractsInfoType,
ContractsRawCode,
ContractsState,
},
Expand Down Expand Up @@ -81,11 +83,12 @@ pub trait InterpreterStorage:
salt: &Salt,
slots: &[StorageSlot],
contract: &Contract,
root: &Bytes32,
id: &ContractId,
) -> Result<(), Self::DataError> {
self.storage_contract_insert(id, contract)?;
self.storage_contract_root_insert(id, salt, root)?;

let info = ContractsInfoType::V1(*salt);
self.storage_contract_info_insert(id, &info)?;

// On the `fuel-core` side it is done in more optimal way
slots.iter().try_for_each(|s| {
Expand Down Expand Up @@ -137,23 +140,22 @@ pub trait InterpreterStorage:
self.storage::<ContractsRawCode>().contains_key(id)
}

/// Fetch a previously inserted salt+root tuple from the chain state for a
/// given contract.
fn storage_contract_root(
/// Fetch a previously inserted contract's info
fn storage_contract_info(
&self,
id: &ContractId,
) -> Result<Option<Cow<'_, (Salt, Bytes32)>>, Self::DataError> {
) -> Result<Option<Cow<'_, <ContractsInfo as Mappable>::Value>>, Self::DataError>
{
StorageInspect::<ContractsInfo>::get(self, id)
}

/// Append the salt+root of a contract that was appended to the chain.
fn storage_contract_root_insert(
/// Append the contract's info that was appended to the chain.
fn storage_contract_info_insert(
&mut self,
id: &ContractId,
salt: &Salt,
root: &Bytes32,
) -> Result<Option<(Salt, Bytes32)>, Self::DataError> {
StorageMutate::<ContractsInfo>::insert(self, id, &(*salt, *root))
info: &<ContractsInfo as Mappable>::Value,
) -> Result<Option<<ContractsInfo as Mappable>::Value>, Self::DataError> {
StorageMutate::<ContractsInfo>::insert(self, id, info)
}

/// Fetch the value form a key-value mapping in a contract storage.
Expand Down
13 changes: 6 additions & 7 deletions fuel-vm/src/storage/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use fuel_types::{
BlockHeight,
Bytes32,
ContractId,
Salt,
Word,
};
use itertools::Itertools;
Expand All @@ -48,7 +47,7 @@ struct MemoryStorageInner {
contracts: BTreeMap<ContractId, Contract>,
balances: BTreeMap<ContractsAssetKey, Word>,
contract_state: BTreeMap<ContractsStateKey, Bytes32>,
contract_code_root: BTreeMap<ContractId, (Salt, Bytes32)>,
contract_code_root: BTreeMap<ContractId, <ContractsInfo as Mappable>::Value>,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -222,7 +221,7 @@ impl StorageInspect<ContractsInfo> for MemoryStorage {
fn get(
&self,
key: &ContractId,
) -> Result<Option<Cow<'_, (Salt, Bytes32)>>, Infallible> {
) -> Result<Option<Cow<'_, <ContractsInfo as Mappable>::Value>>, Infallible> {
Ok(self.memory.contract_code_root.get(key).map(Cow::Borrowed))
}

Expand All @@ -235,15 +234,15 @@ impl StorageMutate<ContractsInfo> for MemoryStorage {
fn insert(
&mut self,
key: &ContractId,
value: &(Salt, Bytes32),
) -> Result<Option<(Salt, Bytes32)>, Infallible> {
Ok(self.memory.contract_code_root.insert(*key, *value))
value: &<ContractsInfo as Mappable>::Value,
) -> Result<Option<<ContractsInfo as Mappable>::Value>, Infallible> {
Ok(self.memory.contract_code_root.insert(*key, value.clone()))
}

fn remove(
&mut self,
key: &ContractId,
) -> Result<Option<(Salt, Bytes32)>, Infallible> {
) -> Result<Option<<ContractsInfo as Mappable>::Value>, Infallible> {
Ok(self.memory.contract_code_root.remove(key))
}
}
Expand Down
Loading