Skip to content

Commit

Permalink
Make all the functions starting with "__" reserved. (#748)
Browse files Browse the repository at this point in the history
This allows adding special functions like `__check_auth` without risking breaking the existing contracts.
  • Loading branch information
dmkozh committed Apr 10, 2023
1 parent 5ef8705 commit 2ceaad2
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions soroban-env-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ use soroban_env_common::{
U128Object, U32Val, U64Object, U64Val, VecObject, VmCaller, VmCallerEnv, Void, I256, U256,
};

use crate::auth::{AuthorizationManager, AuthorizationManagerSnapshot, RecordedAuthPayload};
use crate::events::{
DebugError, DebugEvent, Events, InternalContractEvent, InternalEvent, InternalEventsBuffer,
};
use crate::storage::{Storage, StorageMap};
use crate::{
auth::{AuthorizationManager, AuthorizationManagerSnapshot, RecordedAuthPayload},
native_contract::account_contract::ACCOUNT_CONTRACT_CHECK_AUTH_FN_NAME,
};
use crate::{
budget::{AsBudget, Budget, CostType},
storage::{TempStorage, TempStorageMap},
Expand Down Expand Up @@ -59,6 +56,11 @@ use self::metered_vector::MeteredVector;
use self::{invoker_type::InvokerType, metered_clone::MeteredClone};
use crate::Compare;

/// All the contract functions starting with double underscore are considered
/// to be reserved by the Soroban host and can't be directly called by another
/// contracts.
const RESERVED_CONTRACT_FN_PREFIX: &str = "__";

/// Saves host state (storage and objects) for rolling back a (sub-)transaction
/// on error. A helper type used by [`FrameGuard`].
// Notes on metering: `RollbackPoint` are metered under Frame operations
Expand Down Expand Up @@ -587,6 +589,8 @@ impl Host {
contract: BytesObject,
args: VecObject,
) -> Result<RawVal, HostError> {
use crate::native_contract::account_contract::ACCOUNT_CONTRACT_CHECK_AUTH_FN_NAME;

let contract_id = self.hash_from_bytesobj_input("contract", contract)?;
let args = self.call_args_from_obj(args)?;
let res = self.call_n_internal(
Expand Down Expand Up @@ -1001,12 +1005,14 @@ impl Host {
// Internal host calls may call some special functions that otherwise
// aren't allowed to be called.
if !internal_host_call {
if SymbolStr::try_from_val(self, &func)?.to_string().as_str()
== ACCOUNT_CONTRACT_CHECK_AUTH_FN_NAME
if SymbolStr::try_from_val(self, &func)?
.to_string()
.as_str()
.starts_with(RESERVED_CONTRACT_FN_PREFIX)
{
return Err(self.err_status_msg(
ScHostContextErrorCode::UnknownError,
"can't invoke a custom account contract directly",
"can't invoke a reserved function directly",
));
}
}
Expand Down

0 comments on commit 2ceaad2

Please sign in to comment.