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

Add host function for bumping contract instance #875

Merged
merged 8 commits into from
Jun 23, 2023
14 changes: 13 additions & 1 deletion soroban-env-common/env.json
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,18 @@
},
{
"export": "8",
"name": "bump_current_contract_instance_and_code",
"args": [
{
"name": "min",
"type": "U32Val"
}
],
"return": "Void",
"docs": "Bumps the expiration ledger the current contract instance and code (if applicable), so they will live for `min` ledgers from now. If the current expiration ledger is already large enough (>= last closed ledger + `min` more ledgers), it is untouched."
},
{
"export": "9",
"name": "get_contract_id",
"args": [
{
Expand All @@ -1406,7 +1418,7 @@
"docs": "Get the id of a contract without creating it. `deployer` is address of the contract deployer. `salt` is used to create a unique contract id. Returns the address of the would-be contract."
},
{
"export": "9",
"export": "10",
"name": "get_asset_contract_id",
"args": [
{
Expand Down
31 changes: 31 additions & 0 deletions soroban-env-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1902,6 +1902,37 @@ impl VmCallerEnv for Host {
Ok(Val::VOID)
}

fn bump_current_contract_instance_and_code(
&self,
_vmcaller: &mut VmCaller<Host>,
min: U32Val,
) -> Result<Void, HostError> {
let min_expiration =
self.with_ledger_info(|li| Ok(li.sequence_number.saturating_add(min.into())))?;

let contract_id = self.get_current_contract_id_internal()?;
let key = self.contract_instance_ledger_key(&contract_id)?;
self.0.expiration_bumps.borrow_mut().0.push(LedgerBump {
key: key.metered_clone(self.as_budget())?,
jayz22 marked this conversation as resolved.
Show resolved Hide resolved
min_expiration,
});

match self
.retrieve_contract_instance_from_storage(&key)?
.executable
{
ContractExecutable::Wasm(wasm_hash) => {
let key = self.contract_code_ledger_key(&wasm_hash)?;
self.0.expiration_bumps.borrow_mut().0.push(LedgerBump {
key,
min_expiration,
});
}
ContractExecutable::Token => {}
}
Ok(Val::VOID)
}

// Notes on metering: covered by the components.
fn create_contract(
&self,
Expand Down
22 changes: 4 additions & 18 deletions soroban-env-host/src/host/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,6 @@ impl Host {
self.storage_key_from_scval(self.from_host_val(k)?, durability)
}

pub(crate) fn storage_key_for_contract(
&self,
contract_id: Hash,
key: ScVal,
durability: ContractDataDurability,
) -> Rc<LedgerKey> {
self.storage_key_for_address(ScAddress::Contract(contract_id), key, durability)
}

pub(crate) fn storage_key_for_address(
&self,
contract_address: ScAddress,
Expand All @@ -183,22 +174,17 @@ impl Host {
}))
}

pub fn storage_key_from_scval(
pub(crate) fn storage_key_from_scval(
&self,
key: ScVal,
durability: ContractDataDurability,
) -> Result<Rc<LedgerKey>, HostError> {
Ok(
self.storage_key_for_contract(
self.get_current_contract_id_internal()?,
key,
durability,
),
)
let contract_id = self.get_current_contract_id_internal()?;
Ok(self.storage_key_for_address(ScAddress::Contract(contract_id), key, durability))
}

// Notes on metering: covered by components.
pub fn contract_data_key_from_rawval(
pub(crate) fn contract_data_key_from_rawval(
&self,
k: Val,
durability: ContractDataDurability,
Expand Down
9 changes: 6 additions & 3 deletions soroban-env-host/src/host/data_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ impl Host {
}
}

pub(crate) fn wasm_ledger_key(&self, wasm_hash: &Hash) -> Result<Rc<LedgerKey>, HostError> {
pub(crate) fn contract_code_ledger_key(
&self,
wasm_hash: &Hash,
) -> Result<Rc<LedgerKey>, HostError> {
let wasm_hash = wasm_hash.metered_clone(self.as_budget())?;
Ok(Rc::new(LedgerKey::ContractCode(LedgerKeyContractCode {
hash: wasm_hash,
Expand All @@ -75,7 +78,7 @@ impl Host {
}

pub(crate) fn retrieve_wasm_from_storage(&self, wasm_hash: &Hash) -> Result<BytesM, HostError> {
let key = self.wasm_ledger_key(wasm_hash)?;
let key = self.contract_code_ledger_key(wasm_hash)?;
match &self
.0
.storage
Expand All @@ -101,7 +104,7 @@ impl Host {
}

pub(crate) fn wasm_exists(&self, wasm_hash: &Hash) -> Result<bool, HostError> {
let key = self.wasm_ledger_key(wasm_hash)?;
let key = self.contract_code_ledger_key(wasm_hash)?;
self.0.storage.borrow_mut().has(&key, self.as_budget())
}

Expand Down
6 changes: 3 additions & 3 deletions soroban-env-host/src/test/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ fn get_contract_wasm_ref(host: &Host, contract_id: Hash) -> Hash {
}

fn get_contract_wasm(host: &Host, wasm_hash: Hash) -> Vec<u8> {
let storage_key = host.wasm_ledger_key(&wasm_hash).unwrap();
let storage_key = host.contract_code_ledger_key(&wasm_hash).unwrap();
host.with_mut_storage(|s: &mut Storage| {
assert!(s.has(&storage_key, host.as_budget()).unwrap());

Expand Down Expand Up @@ -110,7 +110,7 @@ fn test_create_contract_from_source_account(host: &Host, wasm: &[u8]) -> Hash {
.unwrap();
s.footprint
.record_access(
&host.wasm_ledger_key(&wasm_hash).unwrap(),
&host.contract_code_ledger_key(&wasm_hash).unwrap(),
AccessType::ReadWrite,
host.as_budget(),
)
Expand Down Expand Up @@ -192,7 +192,7 @@ fn create_contract_using_parent_id_test() {
.unwrap();
s.footprint
.record_access(
&host.wasm_ledger_key(&wasm_hash).unwrap(),
&host.contract_code_ledger_key(&wasm_hash).unwrap(),
AccessType::ReadWrite,
host.as_budget(),
)
Expand Down