Skip to content

Commit

Permalink
Adapt Storage and SnapshotSource to use Rc only.
Browse files Browse the repository at this point in the history
Fix build
  • Loading branch information
jayz22 committed Feb 23, 2023
1 parent 54b8148 commit 1bd2cac
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 265 deletions.
61 changes: 32 additions & 29 deletions soroban-env-host/src/auth.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::rc::Rc;

use soroban_env_common::xdr::{
ContractAuth, ContractDataEntry, HashIdPreimage, HashIdPreimageContractAuth, LedgerEntry,
Expand Down Expand Up @@ -894,23 +895,24 @@ impl Host {
contract_id.metered_clone(self.budget_ref())?,
nonce_key_scval,
);
let curr_nonce: u64 =
if self.with_mut_storage(|storage| storage.has(&nonce_key, self.budget_ref()))? {
let sc_val = self.with_mut_storage(|storage| {
match storage.get(&nonce_key, self.budget_ref())?.data {
LedgerEntryData::ContractData(ContractDataEntry { val, .. }) => Ok(val),
_ => Err(self.err_general("unexpected missing nonce entry")),
}
})?;
match sc_val {
ScVal::Object(Some(ScObject::U64(val))) => val,
let curr_nonce: u64 = if self
.with_mut_storage(|storage| storage.has(Rc::clone(&nonce_key), self.budget_ref()))?
{
let entry = self.with_mut_storage(|storage| {
storage.get(Rc::clone(&nonce_key), self.budget_ref())
})?;
match &entry.data {
LedgerEntryData::ContractData(ContractDataEntry { val, .. }) => match val {
ScVal::Object(Some(ScObject::U64(val))) => val.clone(),
_ => {
return Err(self.err_general("unexpected nonce entry type"));
}
}
} else {
0
};
},
_ => return Err(self.err_general("unexpected missing nonce entry")),
}
} else {
0
};
Ok(curr_nonce)
}

Expand All @@ -926,23 +928,24 @@ impl Host {
contract_id.metered_clone(self.budget_ref())?,
nonce_key_scval.clone(),
);
let curr_nonce: u64 =
if self.with_mut_storage(|storage| storage.has(&nonce_key, self.budget_ref()))? {
let sc_val = self.with_mut_storage(|storage| {
match storage.get(&nonce_key, self.budget_ref())?.data {
LedgerEntryData::ContractData(ContractDataEntry { val, .. }) => Ok(val),
_ => Err(self.err_general("unexpected missing nonce entry")),
}
})?;
match sc_val {
ScVal::Object(Some(ScObject::U64(val))) => val,
let curr_nonce: u64 = if self
.with_mut_storage(|storage| storage.has(Rc::clone(&nonce_key), self.budget_ref()))?
{
let entry = self.with_mut_storage(|storage| {
storage.get(Rc::clone(&nonce_key), self.budget_ref())
})?;
match &entry.data {
LedgerEntryData::ContractData(ContractDataEntry { val, .. }) => match val {
ScVal::Object(Some(ScObject::U64(val))) => val.clone(),
_ => {
return Err(self.err_general("unexpected nonce entry type"));
}
}
} else {
0
};
},
_ => return Err(self.err_general("unexpected missing nonce entry")),
}
} else {
0
};
let data = LedgerEntryData::ContractData(ContractDataEntry {
contract_id: contract_id.metered_clone(self.budget_ref())?,
key: nonce_key_scval,
Expand All @@ -953,7 +956,7 @@ impl Host {
data,
ext: LedgerEntryExt::V0,
};
self.with_mut_storage(|storage| storage.put(&nonce_key, &entry, self.budget_ref()))?;
self.with_mut_storage(|storage| storage.put(nonce_key, Rc::new(entry), self.budget_ref()))?;
Ok(curr_nonce)
}
}
56 changes: 30 additions & 26 deletions soroban-env-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,32 +767,30 @@ impl Host {
contract_source: ScContractCode,
) -> Result<(), HostError> {
let new_contract_id = self.hash_from_obj_input("id_obj", contract_id)?;
let storage_key =
self.contract_source_ledger_key(new_contract_id.metered_clone(&self.0.budget)?);
let storage_key = self.contract_source_ledger_key(&new_contract_id)?;
if self
.0
.storage
.borrow_mut()
.has(&storage_key, self.as_budget())?
.has(Rc::clone(&storage_key), self.as_budget())?
{
return Err(self.err_general("Contract already exists"));
}
// Make sure the contract code exists. With immutable contracts and
// without this check it would be possible to accidentally create a
// contract that never may be invoked (just by providing a bad hash).
if let ScContractCode::WasmRef(wasm_hash) = &contract_source {
let wasm_storage_key =
self.contract_code_ledger_key(wasm_hash.metered_clone(&self.0.budget)?);
let wasm_storage_key = self.contract_code_ledger_key(wasm_hash)?;
if !self
.0
.storage
.borrow_mut()
.has(&wasm_storage_key, self.as_budget())?
.has(wasm_storage_key, self.as_budget())?
{
return Err(self.err_general("Contract code was not installed"));
}
}
self.store_contract_source(contract_source, new_contract_id, &storage_key)?;
self.store_contract_source(contract_source, new_contract_id, storage_key)?;
Ok(())
}

Expand Down Expand Up @@ -842,11 +840,18 @@ impl Host {
args: &[RawVal],
) -> Result<RawVal, HostError> {
// Create key for storage
let storage_key = self.contract_source_ledger_key(id.metered_clone(&self.0.budget)?);
match self.retrieve_contract_source_from_storage(&storage_key)? {
let storage_key = self.contract_source_ledger_key(id)?;
match self.retrieve_contract_source_from_storage(storage_key)? {
#[cfg(feature = "vm")]
ScContractCode::WasmRef(wasm_hash) => {
let code_entry = self.retrieve_contract_code_from_storage(wasm_hash)?;
let key = self.contract_code_ledger_key(&wasm_hash)?;
let entry = &self.0.storage.borrow_mut().get(key, self.as_budget())?;
let code_entry = if let LedgerEntryData::ContractCode(e) = &entry.data {
Ok(e)
} else {
Err(self.err_status(ScHostStorageErrorCode::AccessToUnknownEntry))
}?;

let vm = Vm::new(
self,
id.metered_clone(&self.0.budget)?,
Expand Down Expand Up @@ -1053,10 +1058,10 @@ impl Host {
#[cfg(any(test, feature = "testutils"))]
pub fn add_ledger_entry(
&self,
key: LedgerKey,
val: soroban_env_common::xdr::LedgerEntry,
key: Rc<LedgerKey>,
val: Rc<soroban_env_common::xdr::LedgerEntry>,
) -> Result<(), HostError> {
self.with_mut_storage(|storage| storage.put(&key, &val, self.as_budget()))
self.with_mut_storage(|storage| storage.put(key, val, self.as_budget()))
}

// Returns the top-level authorizations that have been recorded for the last
Expand Down Expand Up @@ -1114,14 +1119,14 @@ impl Host {
fn install_contract(&self, args: InstallContractCodeArgs) -> Result<Object, HostError> {
let hash_bytes = self.metered_hash_xdr(&args)?;
let hash_obj = self.add_host_object(hash_bytes.to_vec())?;
let code_key = LedgerKey::ContractCode(LedgerKeyContractCode {
let code_key = Rc::new(LedgerKey::ContractCode(LedgerKeyContractCode {
hash: Hash(hash_bytes.metered_clone(self.budget_ref())?),
});
}));
if !self
.0
.storage
.borrow_mut()
.has(&code_key, self.as_budget())?
.has(Rc::clone(&code_key), self.as_budget())?
{
self.with_mut_storage(|storage| {
let data = LedgerEntryData::ContractCode(ContractCodeEntry {
Expand All @@ -1130,8 +1135,8 @@ impl Host {
ext: ExtensionPoint::V0,
});
storage.put(
&code_key,
&Host::ledger_entry_from_data(data),
code_key,
Host::ledger_entry_from_data(data),
self.as_budget(),
)
})?;
Expand Down Expand Up @@ -1850,8 +1855,8 @@ impl VmCallerEnv for Host {
val: self.from_host_val(v)?,
});
self.0.storage.borrow_mut().put(
&key,
&Host::ledger_entry_from_data(data),
key,
Host::ledger_entry_from_data(data),
self.as_budget(),
)?;
Ok(().into())
Expand All @@ -1864,7 +1869,7 @@ impl VmCallerEnv for Host {
k: RawVal,
) -> Result<RawVal, HostError> {
let key = self.storage_key_from_rawval(k)?;
let res = self.0.storage.borrow_mut().has(&key, self.as_budget())?;
let res = self.0.storage.borrow_mut().has(key, self.as_budget())?;
Ok(RawVal::from_bool(res))
}

Expand All @@ -1875,13 +1880,12 @@ impl VmCallerEnv for Host {
k: RawVal,
) -> Result<RawVal, HostError> {
let key = self.storage_key_from_rawval(k)?;
match self
let entry = self
.0
.storage
.borrow_mut()
.get(&key, self.as_budget())?
.data
{
.get(Rc::clone(&key), self.as_budget())?;
match &entry.data {
LedgerEntryData::ContractData(ContractDataEntry {
contract_id,
key,
Expand All @@ -1901,7 +1905,7 @@ impl VmCallerEnv for Host {
k: RawVal,
) -> Result<RawVal, HostError> {
let key = self.contract_data_key_from_rawval(k)?;
self.0.storage.borrow_mut().del(&key, self.as_budget())?;
self.0.storage.borrow_mut().del(key, self.as_budget())?;
Ok(().into())
}

Expand Down
24 changes: 14 additions & 10 deletions soroban-env-host/src/host/conversion.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::rc::Rc;

use super::metered_clone::MeteredClone;
use crate::xdr::{
Hash, LedgerKey, LedgerKeyContractData, ScHostFnErrorCode, ScHostObjErrorCode,
Expand Down Expand Up @@ -192,26 +194,29 @@ impl Host {
/// Converts a [`RawVal`] to an [`ScVal`] and combines it with the currently-executing
/// [`ContractID`] to produce a [`Key`], that can be used to access ledger [`Storage`].
// Notes on metering: covered by components.
pub fn storage_key_from_rawval(&self, k: RawVal) -> Result<LedgerKey, HostError> {
Ok(LedgerKey::ContractData(LedgerKeyContractData {
pub fn storage_key_from_rawval(&self, k: RawVal) -> Result<Rc<LedgerKey>, HostError> {
Ok(Rc::new(LedgerKey::ContractData(LedgerKeyContractData {
contract_id: self.get_current_contract_id_internal()?,
key: self.from_host_val(k)?,
}))
})))
}

pub(crate) fn storage_key_for_contract(&self, contract_id: Hash, key: ScVal) -> LedgerKey {
LedgerKey::ContractData(LedgerKeyContractData { contract_id, key })
pub(crate) fn storage_key_for_contract(&self, contract_id: Hash, key: ScVal) -> Rc<LedgerKey> {
Rc::new(LedgerKey::ContractData(LedgerKeyContractData {
contract_id,
key,
}))
}

pub fn storage_key_from_scval(&self, key: ScVal) -> Result<LedgerKey, HostError> {
Ok(LedgerKey::ContractData(LedgerKeyContractData {
pub fn storage_key_from_scval(&self, key: ScVal) -> Result<Rc<LedgerKey>, HostError> {
Ok(Rc::new(LedgerKey::ContractData(LedgerKeyContractData {
contract_id: self.get_current_contract_id_internal()?,
key,
}))
})))
}

// Notes on metering: covered by components.
pub fn contract_data_key_from_rawval(&self, k: RawVal) -> Result<LedgerKey, HostError> {
pub fn contract_data_key_from_rawval(&self, k: RawVal) -> Result<Rc<LedgerKey>, HostError> {
let key_scval = self.from_host_val(k)?;
match &key_scval {
ScVal::Static(ScStatic::LedgerKeyContractCode) => {
Expand All @@ -228,7 +233,6 @@ impl Host {
}
_ => (),
};

self.storage_key_from_scval(key_scval)
}

Expand Down
Loading

0 comments on commit 1bd2cac

Please sign in to comment.