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!: autoload storage slots #1120

Merged
merged 13 commits into from
Sep 1, 2023
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- [The `abigen!` macro](abigen/the-abigen-macro.md)
- [Deploying contracts](./deploying/index.md)
- [Configurable constants](./deploying/configurable-constants.md)
- [Storage slots](./deploying/storage-slots.md)
- [Interacting with contracts](./deploying/interacting-with-contracts.md)
- [The FuelVM Binary file](./deploying/the-fuelvm-binary-file.md)
- [Calling contracts](./calling-contracts/index.md)
Expand Down
13 changes: 13 additions & 0 deletions docs/src/deploying/storage-slots.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Overriding storage slots

If you use storage in your contract the default storage values are going to be generated in a JSON file (e.g. `my_contract-storage_slots.json`) by the Sway compiler. These are loaded automatically for you when you load a contract binary. If you wish to override some of the defaults you need to provide the corresponding storage slots manually:
segfault-magnet marked this conversation as resolved.
Show resolved Hide resolved

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:storage_slots_override}}
```

If you don't have the slot storage file (`my_contract-storage_slots.json` example from above) for some reason, or you don't wish to load any of the default values, you can disable the auto-loading of storage slots:

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:storage_slots_disable_autoload}}
```
41 changes: 38 additions & 3 deletions examples/contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#[cfg(test)]
mod tests {
use fuels::types::errors::{error, Error, Result};
use fuels::types::Bits256;
use fuels::{
prelude::{LoadConfiguration, StorageConfiguration},
types::{
errors::{error, Error, Result},
Bits256,
},
};

#[tokio::test]
async fn instantiate_client() -> Result<()> {
Expand Down Expand Up @@ -138,7 +143,8 @@ mod tests {
let key = Bytes32::from([1u8; 32]);
let value = Bytes32::from([2u8; 32]);
let storage_slot = StorageSlot::new(key, value);
let storage_configuration = StorageConfiguration::from(vec![storage_slot]);
let storage_configuration =
StorageConfiguration::default().add_slot_overrides([storage_slot]);
let configuration = LoadConfiguration::default()
.with_storage_configuration(storage_configuration)
.with_salt(salt);
Expand Down Expand Up @@ -791,4 +797,33 @@ mod tests {

Ok(())
}

#[tokio::test]
async fn storage_slots_override() -> Result<()> {
{
// ANCHOR: storage_slots_override
use fuels::{programs::contract::Contract, tx::StorageSlot};
let slot_override = StorageSlot::new([1; 32].into(), [2; 32].into());
digorithm marked this conversation as resolved.
Show resolved Hide resolved
let storage_config =
StorageConfiguration::default().add_slot_overrides([slot_override]);

let load_config =
LoadConfiguration::default().with_storage_configuration(storage_config);
let _: Result<Contract> = Contract::load_from("...", load_config);
// ANCHOR_END: storage_slots_override
}

{
// ANCHOR: storage_slots_disable_autoload
use fuels::programs::contract::Contract;
let storage_config = StorageConfiguration::default().with_autoload(false);

let load_config =
LoadConfiguration::default().with_storage_configuration(storage_config);
let _: Result<Contract> = Contract::load_from("...", load_config);
// ANCHOR_END: storage_slots_disable_autoload
}

Ok(())
}
}
6 changes: 4 additions & 2 deletions examples/cookbook/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#[cfg(test)]
mod tests {
use fuels::types::Bits256;
use fuels::{
prelude::Result,
types::transaction_builders::{ScriptTransactionBuilder, TransactionBuilder},
types::{
transaction_builders::{ScriptTransactionBuilder, TransactionBuilder},
Bits256,
},
};

#[tokio::test]
Expand Down
8 changes: 4 additions & 4 deletions packages/fuels-code-gen/src/program_bindings/abigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ impl Abigen {
}
fn wasm_paths_hotfix(code: &TokenStream) -> TokenStream {
[
(r#"::\s*std\s*::\s*string"#, "::alloc::string"),
(r#"::\s*std\s*::\s*format"#, "::alloc::format"),
(r#"::\s*std\s*::\s*vec"#, "::alloc::vec"),
(r#"::\s*std\s*::\s*boxed"#, "::alloc::boxed"),
(r"::\s*std\s*::\s*string", "::alloc::string"),
(r"::\s*std\s*::\s*format", "::alloc::format"),
(r"::\s*std\s*::\s*vec", "::alloc::vec"),
(r"::\s*std\s*::\s*boxed", "::alloc::boxed"),
]
.map(|(reg_expr_str, substitute)| (Regex::new(reg_expr_str).unwrap(), substitute))
.into_iter()
Expand Down
6 changes: 4 additions & 2 deletions packages/fuels-core/src/types/bech32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ use std::{
str::FromStr,
};

use crate::types::Bits256;
use bech32::{FromBase32, ToBase32, Variant::Bech32m};
use fuel_tx::{Address, Bytes32, ContractId, ContractIdExt};
use fuel_types::AssetId;

use crate::types::errors::{Error, Result};
use crate::types::{
errors::{Error, Result},
Bits256,
};

// Fuel Network human-readable part for bech32 encoding
pub const FUEL_BECH32_HRP: &str = "fuel";
Expand Down
3 changes: 2 additions & 1 deletion packages/fuels-core/src/types/core/sized_ascii_string.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::fmt::{Debug, Display, Formatter};

use crate::types::errors::{error, Error, Result};
use serde::{Deserialize, Serialize};

use crate::types::errors::{error, Error, Result};

// To be used when interacting with contracts which have string slices in their ABI.
// The FuelVM strings only support ascii characters.
#[derive(Debug, PartialEq, Clone, Eq)]
Expand Down
2 changes: 0 additions & 2 deletions packages/fuels-core/src/types/param_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,6 @@ fn try_str_slice(the_type: &Type) -> Result<Option<ParamType>> {

fn try_array(the_type: &Type) -> Result<Option<ParamType>> {
if let Some(len) = extract_array_len(&the_type.type_field) {
if the_type.components.len() != 1 {}

return match the_type.components.as_slice() {
[single_type] => {
let array_type = single_type.try_into()?;
Expand Down
8 changes: 4 additions & 4 deletions packages/fuels-core/src/types/transaction_builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use fuel_tx::{
StorageSlot, Transaction as FuelTransaction, TransactionFee, TxPointer, UniqueIdentifier,
Witness,
};
use fuel_types::{bytes::padded_len_usize, Bytes32, Salt};
use fuel_types::{bytes::padded_len_usize, Bytes32, MemLayout, Salt};
use fuel_vm::{checked_transaction::EstimatePredicates, gas::GasCosts};

use super::unresolved_bytes::UnresolvedBytes;
use crate::{
constants::{BASE_ASSET_ID, WORD_SIZE},
offsets,
Expand All @@ -27,8 +28,6 @@ use crate::{
},
};

use super::unresolved_bytes::UnresolvedBytes;

#[derive(Debug, Clone, Default)]
struct UnresolvedSignatures {
addr_idx_offset_map: HashMap<Bech32Address, u8>,
Expand Down Expand Up @@ -373,6 +372,7 @@ impl CreateTransactionBuilder {
num_witnesses: u8,
consensus_parameters: &ConsensusParameters,
) -> Result<Create> {
let num_of_storage_slots = self.storage_slots.len();
let mut tx = FuelTransaction::create(
self.gas_price,
self.gas_limit,
Expand All @@ -382,7 +382,7 @@ impl CreateTransactionBuilder {
self.storage_slots,
resolve_fuel_inputs(
self.inputs,
base_offset,
base_offset + num_of_storage_slots * StorageSlot::LEN,
num_witnesses,
&self.unresolved_signatures,
)?,
Expand Down
12 changes: 1 addition & 11 deletions packages/fuels-macros/src/setup_program_test/code_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,10 @@ fn contract_deploying_code(
.get(&command.contract.value())
.expect("Project should be in lookup");
let bin_path = project.bin_path();
let storage_path = project.storage_path();

quote! {
let #contract_instance_name = {
let storage_config = StorageConfiguration::load_from(#storage_path)
.expect("Failed to load storage slots from path");
let load_config =
LoadConfiguration::default()
.with_storage_configuration(storage_config)
.with_salt([#(#salt),*]);
let load_config = LoadConfiguration::default().with_salt([#(#salt),*]);

let loaded_contract = Contract::load_from(#bin_path, load_config).expect("Failed to load the contract");

Expand Down Expand Up @@ -212,8 +206,4 @@ impl Project {
fn bin_path(&self) -> String {
self.compile_file_path(".bin", "the binary file")
}

fn storage_path(&self) -> String {
self.compile_file_path("-storage_slots.json", "the storage slots file")
}
}
8 changes: 4 additions & 4 deletions packages/fuels-programs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ strum_macros = { workspace = true }
thiserror = { workspace = true, default-features = false }
tokio = { workspace = true }

[dev-dependencies]
tempfile = "3.8"

[features]
default = ["std"]
std = [
"fuels-core/std",
"fuels-accounts/std",
]
std = ["fuels-core/std", "fuels-accounts/std"]
6 changes: 3 additions & 3 deletions packages/fuels-programs/src/call_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ pub(crate) fn get_instructions(
.iter()
.zip(&offsets)
.flat_map(|(call, offset)| get_single_call_instructions(offset, &call.output_param))
.chain(op::ret(RegId::ONE).to_bytes().into_iter())
.chain(op::ret(RegId::ONE).to_bytes())
.collect()
}

Expand Down Expand Up @@ -558,13 +558,13 @@ mod test {
Bech32ContractId::new("test", Bytes32::new([1u8; 32])),
];

let asset_ids = vec![
let asset_ids = [
AssetId::from([4u8; 32]),
AssetId::from([5u8; 32]),
AssetId::from([6u8; 32]),
];

let selectors = vec![[7u8; 8], [8u8; 8], [9u8; 8]];
let selectors = [[7u8; 8], [8u8; 8], [9u8; 8]];

// Call 2 has multiple inputs, compute_custom_input_offset will be true

Expand Down
Loading
Loading