Skip to content

Commit

Permalink
feat: Versionable ContractUtxoInfo for the ContractsLatestUtxo ta…
Browse files Browse the repository at this point in the history
…ble (#1712)

Related issues:
- #1552

This PR remodels the existing `ContractUtxoInfo` type as an enum for the
purpose of representing different versions of the data. This PR
introduces `ContractUtxoInfoV1` which simply holds the existing data
types for `ContractUtxoInfo`. This allows the `ContractsLatestUtxo`
table to now use a versioned data type.
  • Loading branch information
Brandon Vrooman committed Feb 28, 2024
1 parent ac62a0f commit d0edfb3
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

#### Breaking

- [#1712](https://github.com/FuelLabs/fuel-core/pull/1712): Make `ContractUtxoInfo` type a version-able enum for use in the `ContractsLatestUtxo`table.
- [#1657](https://github.com/FuelLabs/fuel-core/pull/1657): Changed `CROO` gas price type from `Word` to `DependentGasPrice`. The dependent gas price values are dummy values while awaiting updated benchmarks.
- [#1671](https://github.com/FuelLabs/fuel-core/pull/1671): The GraphQL API uses block height instead of the block id where it is possible. The transaction status contains `block_height` instead of the `block_id`.
- [#1675](https://github.com/FuelLabs/fuel-core/pull/1675): Simplify GQL schema by disabling contract resolvers in most cases, and just return a ContractId scalar instead.
Expand Down
20 changes: 8 additions & 12 deletions crates/fuel-core/src/database/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ use fuel_core_storage::{
Result as StorageResult,
StorageAsRef,
};
use fuel_core_types::{
entities::contract::ContractUtxoInfo,
fuel_types::{
AssetId,
Bytes32,
ContractId,
Word,
},
use fuel_core_types::fuel_types::{
AssetId,
Bytes32,
ContractId,
Word,
};

impl Database {
Expand All @@ -42,15 +39,14 @@ impl Database {
.expect("Contract does not exist")
.salt();

let ContractUtxoInfo {
utxo_id,
tx_pointer,
} = self
let latest_utxo = self
.storage::<ContractsLatestUtxo>()
.get(&contract_id)
.unwrap()
.expect("contract does not exist")
.into_owned();
let utxo_id = latest_utxo.utxo_id();
let tx_pointer = latest_utxo.tx_pointer();

let state = Some(
self.iter_all_by_prefix::<ContractsState, _>(Some(contract_id.as_ref()))
Expand Down
5 changes: 1 addition & 4 deletions crates/fuel-core/src/service/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,7 @@ fn init_contracts(
.storage::<ContractsLatestUtxo>()
.insert(
&contract_id,
&ContractUtxoInfo {
utxo_id,
tx_pointer,
},
&ContractUtxoInfo::V1((utxo_id, tx_pointer).into()),
)?
.is_some()
{
Expand Down
22 changes: 8 additions & 14 deletions crates/services/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1353,8 +1353,8 @@ where
let mut contract = ContractRef::new(&mut *db, *contract_id);
let utxo_info =
contract.validated_utxo(self.options.utxo_validation)?;
*utxo_id = utxo_info.utxo_id;
*tx_pointer = utxo_info.tx_pointer;
*utxo_id = *utxo_info.utxo_id();
*tx_pointer = utxo_info.tx_pointer();
*balance_root = contract.balance_root()?;
*state_root = contract.state_root()?;
}
Expand Down Expand Up @@ -1402,10 +1402,8 @@ where
..
}) => {
let mut contract = ContractRef::new(&mut *db, *contract_id);
let provided_info = ContractUtxoInfo {
utxo_id: *utxo_id,
tx_pointer: *tx_pointer,
};
let provided_info =
ContractUtxoInfo::V1((*utxo_id, *tx_pointer).into());
if provided_info
!= contract
.validated_utxo(self.options.utxo_validation)?
Expand Down Expand Up @@ -1592,12 +1590,10 @@ where
if let Some(Input::Contract(Contract { contract_id, .. })) =
inputs.get(contract.input_index as usize)
{
let tx_pointer = TxPointer::new(block_height, tx_idx);
db.storage::<ContractsLatestUtxo>().insert(
contract_id,
&ContractUtxoInfo {
utxo_id,
tx_pointer: TxPointer::new(block_height, tx_idx),
},
&ContractUtxoInfo::V1((utxo_id, tx_pointer).into()),
)?;
} else {
return Err(ExecutorError::TransactionValidity(
Expand Down Expand Up @@ -1632,12 +1628,10 @@ where
db,
)?,
Output::ContractCreated { contract_id, .. } => {
let tx_pointer = TxPointer::new(block_height, tx_idx);
db.storage::<ContractsLatestUtxo>().insert(
contract_id,
&ContractUtxoInfo {
utxo_id,
tx_pointer: TxPointer::new(block_height, tx_idx),
},
&ContractUtxoInfo::V1((utxo_id, tx_pointer).into()),
)?;
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/services/executor/src/refs/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,13 @@ where
{
fn root(&self) -> anyhow::Result<MerkleRoot> {
let contract_id = *self.contract_id();
let utxo = self
let utxo = *self
.database()
.storage::<ContractsLatestUtxo>()
.get(&contract_id)?
.ok_or(not_found!(ContractsLatestUtxo))?
.into_owned()
.utxo_id;
.utxo_id();

let state_root = self
.database()
Expand Down
42 changes: 41 additions & 1 deletion crates/types/src/entities/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,55 @@ use crate::fuel_tx::{
use fuel_vm_private::fuel_tx::UtxoId;

/// Contains information related to the latest contract utxo
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[non_exhaustive]
pub enum ContractUtxoInfo {
/// V1 ContractUtxoInfo
V1(ContractUtxoInfoV1),
}

impl Default for ContractUtxoInfo {
fn default() -> Self {
Self::V1(Default::default())
}
}

impl ContractUtxoInfo {
/// Get the Contract UTXO's id
pub fn utxo_id(&self) -> &UtxoId {
match self {
ContractUtxoInfo::V1(info) => &info.utxo_id,
}
}

/// Get the Contract UTXO's transaction pointer
pub fn tx_pointer(&self) -> TxPointer {
match self {
ContractUtxoInfo::V1(info) => info.tx_pointer,
}
}
}

/// Version 1 of the ContractUtxoInfo
#[derive(Debug, Default, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ContractUtxoInfo {
pub struct ContractUtxoInfoV1 {
/// the utxo id of the contract
pub utxo_id: UtxoId,
/// the tx pointer to the utxo
pub tx_pointer: TxPointer,
}

impl From<(UtxoId, TxPointer)> for ContractUtxoInfoV1 {
fn from((utxo_id, tx_pointer): (UtxoId, TxPointer)) -> Self {
Self {
utxo_id,
tx_pointer,
}
}
}

/// Versioned type for storing information about a contract. Contract
/// information is off-chain data.
// TODO: Move ContractsInfoType to off-chain data storage https://github.com/FuelLabs/fuel-core/issues/1654
Expand Down

0 comments on commit d0edfb3

Please sign in to comment.