Skip to content

Commit

Permalink
Stop treating storage errors as missing entries (#934)
Browse files Browse the repository at this point in the history
* Stop treating storage errors as missing entries

* Use if let Some
  • Loading branch information
sisuresh authored Jul 7, 2023
1 parent 6845f9c commit a824e15
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
1 change: 1 addition & 0 deletions soroban-env-host/src/native_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub(crate) mod base_types;
pub(crate) mod common_types;
pub(crate) mod contract_error;
pub(crate) mod invoker_contract_auth;
pub(crate) mod storage_utils;
pub(crate) mod token;

use crate::host::{Host, HostError};
Expand Down
15 changes: 15 additions & 0 deletions soroban-env-host/src/native_contract/storage_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use soroban_env_common::{Env, StorageType, Val};

use crate::{Host, HostError};

pub(crate) struct StorageUtils {}

impl StorageUtils {
pub(crate) fn try_get(e: &Host, k: Val, t: StorageType) -> Result<Option<Val>, HostError> {
if e.has_contract_data(k, t.clone())?.into() {
Ok(Some(e.get_contract_data(k, t)?))
} else {
Ok(None)
}
}
}
8 changes: 6 additions & 2 deletions soroban-env-host/src/native_contract/token/allowance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::host::Host;
use crate::native_contract::base_types::Address;
use crate::native_contract::contract_error::ContractError;
use crate::native_contract::storage_utils::StorageUtils;
use crate::native_contract::token::storage_types::{AllowanceDataKey, DataKey};
use crate::{err, HostError};
use soroban_env_common::{Env, StorageType, TryIntoVal};
Expand All @@ -10,7 +11,8 @@ use super::storage_types::AllowanceValue;
// Metering: covered by components
pub fn read_allowance(e: &Host, from: Address, spender: Address) -> Result<i128, HostError> {
let key = DataKey::Allowance(AllowanceDataKey { from, spender });
if let Ok(allowance) = e.get_contract_data(key.try_into_val(e)?, StorageType::Temporary) {
if let Some(allowance) = StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Temporary)?
{
let val: AllowanceValue = allowance.try_into_val(e)?;
if val.expiration_ledger < e.get_ledger_sequence()?.into() {
Ok(0)
Expand Down Expand Up @@ -63,7 +65,9 @@ pub fn write_allowance(
// Returns the allowance to write and the previous expiration of the existing allowance.
// If an allowance didn't exist, then the previous expiration will be None.
let allowance_with_old_expiration_option: Option<(AllowanceValue, Option<u32>)> =
if let Ok(allowance) = e.get_contract_data(key.try_into_val(e)?, StorageType::Temporary) {
if let Some(allowance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Temporary)?
{
let mut updated_allowance: AllowanceValue = allowance.try_into_val(e)?;
updated_allowance.amount = amount;

Expand Down
25 changes: 13 additions & 12 deletions soroban-env-host/src/native_contract/token/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::budget::AsBudget;
use crate::host::Host;
use crate::native_contract::base_types::{Address, BytesN};
use crate::native_contract::contract_error::ContractError;
use crate::native_contract::storage_utils::StorageUtils;
use crate::native_contract::token::asset_info::read_asset_info;
use crate::native_contract::token::public_types::AssetInfo;
use crate::native_contract::token::storage_types::DataKey;
Expand Down Expand Up @@ -30,8 +31,8 @@ pub fn read_balance(e: &Host, addr: Address) -> Result<i128, HostError> {
ScAddress::Account(acc_id) => Ok(get_classic_balance(e, acc_id)?.0.into()),
ScAddress::Contract(_) => {
let key = DataKey::Balance(addr);
if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
let balance: BalanceValue = raw_balance.try_into_val(e)?;
Ok(balance.amount)
Expand Down Expand Up @@ -84,8 +85,8 @@ pub fn receive_balance(e: &Host, addr: Address, amount: i128) -> Result<(), Host
}
ScAddress::Contract(_) => {
let key = DataKey::Balance(addr.clone());
let mut balance = if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
let mut balance = if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
raw_balance.try_into_val(e)?
} else {
Expand Down Expand Up @@ -132,8 +133,8 @@ pub fn spend_balance_no_authorization_check(
// If a balance exists, calculate new amount and write the existing authorized state as is because
// this can be used to clawback when deauthorized.
let key = DataKey::Balance(addr.clone());
if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
let mut balance: BalanceValue = raw_balance.try_into_val(e)?;
if balance.amount < amount {
Expand Down Expand Up @@ -188,8 +189,8 @@ pub fn is_authorized(e: &Host, addr: Address) -> Result<bool, HostError> {
ScAddress::Account(acc_id) => is_account_authorized(e, acc_id),
ScAddress::Contract(_) => {
let key = DataKey::Balance(addr);
if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
let balance: BalanceValue = raw_balance.try_into_val(e)?;
Ok(balance.authorized)
Expand All @@ -214,8 +215,8 @@ pub fn write_authorization(e: &Host, addr: Address, authorize: bool) -> Result<(
ScAddress::Account(acc_id) => set_authorization(e, acc_id, authorize),
ScAddress::Contract(_) => {
let key = DataKey::Balance(addr.clone());
if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
let mut balance: BalanceValue = raw_balance.try_into_val(e)?;
balance.authorized = authorize;
Expand Down Expand Up @@ -282,8 +283,8 @@ pub fn check_clawbackable(e: &Host, addr: Address) -> Result<(), HostError> {
},
ScAddress::Contract(_) => {
let key = DataKey::Balance(addr);
if let Ok(raw_balance) =
e.get_contract_data(key.try_into_val(e)?, StorageType::Persistent)
if let Some(raw_balance) =
StorageUtils::try_get(e, key.try_into_val(e)?, StorageType::Persistent)?
{
let balance: BalanceValue = raw_balance.try_into_val(e)?;
if !balance.clawback {
Expand Down

0 comments on commit a824e15

Please sign in to comment.