Skip to content

Commit

Permalink
Host code review, minor cleanups and code reorganization (#1086)
Browse files Browse the repository at this point in the history
This round does not involve any significant functional changes, though
some might be observable. It's mostly cleanup, code reorg (including a
new file `lifecycle.rs`), a bit of refactoring and some making stuff
private.
  • Loading branch information
graydon authored Sep 26, 2023
1 parent 8dead89 commit 6d12921
Show file tree
Hide file tree
Showing 8 changed files with 607 additions and 588 deletions.
105 changes: 105 additions & 0 deletions soroban-env-host/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,111 @@ impl Host {
)
})
}

// Returns the recorded per-address authorization payloads that would cover the
// top-level contract function invocation in the enforcing mode.
// This should only be called in the recording authorization mode, i.e. only
// if `switch_to_recording_auth` has been called.
pub fn get_recorded_auth_payloads(&self) -> Result<Vec<RecordedAuthPayload>, HostError> {
#[cfg(not(any(test, feature = "testutils")))]
{
self.try_borrow_authorization_manager()?
.get_recorded_auth_payloads(self)
}
#[cfg(any(test, feature = "testutils"))]
{
self.try_borrow_previous_authorization_manager()?
.as_ref()
.ok_or_else(|| {
self.err(
ScErrorType::Auth,
ScErrorCode::InvalidAction,
"previous invocation is missing - no auth data to get",
&[],
)
})?
.get_recorded_auth_payloads(self)
}
}
}

#[cfg(any(test, feature = "testutils"))]
use crate::{host::frame::ContractReentryMode, xdr::SorobanAuthorizedInvocation, BytesObject};
#[cfg(any(test, feature = "testutils"))]
impl Host {
/// Invokes the reserved `__check_auth` function on a provided contract.
///
/// This is useful for testing the custom account contracts. Otherwise, the
/// host prohibits calling `__check_auth` outside of internal implementation
/// of `require_auth[_for_args]` calls.
pub fn call_account_contract_check_auth(
&self,
contract: BytesObject,
args: VecObject,
) -> Result<Val, 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_vec = self.call_args_from_obj(args)?;
let res = self.call_n_internal(
&contract_id,
ACCOUNT_CONTRACT_CHECK_AUTH_FN_NAME.try_into_val(self)?,
args_vec.as_slice(),
ContractReentryMode::Prohibited,
true,
);
if let Err(e) = &res {
self.error(
e.error,
"check auth invocation for a custom account contract failed",
&[contract.to_val(), args.to_val()],
);
}
res
}

/// Returns the current state of the authorization manager.
///
/// Use this in conjunction with `set_auth_manager` to do authorized
/// operations without breaking the current authorization state (useful for
/// preserving the auth state while doing the generic test setup).
pub fn snapshot_auth_manager(&self) -> Result<AuthorizationManager, HostError> {
Ok(self.try_borrow_authorization_manager()?.clone())
}

/// Replaces authorization manager with the provided new instance.
///
/// Use this in conjunction with `snapshot_auth_manager` to do authorized
/// operations without breaking the current authorization state (useful for
/// preserving the auth state while doing the generic test setup).
pub fn set_auth_manager(&self, auth_manager: AuthorizationManager) -> Result<(), HostError> {
*self.try_borrow_authorization_manager_mut()? = auth_manager;
Ok(())
}

// Returns the authorizations that have been authenticated for the last
// contract invocation.
//
// Authenticated means that either the authorization was authenticated using
// the actual authorization logic for that authorization in enforced mode,
// or that it was recorded in recording mode and authorization was assumed
// successful.
pub fn get_authenticated_authorizations(
&self,
) -> Result<Vec<(ScAddress, SorobanAuthorizedInvocation)>, HostError> {
Ok(self
.try_borrow_previous_authorization_manager_mut()?
.as_mut()
.ok_or_else(|| {
self.err(
ScErrorType::Auth,
ScErrorCode::InvalidAction,
"previous invocation is missing - no auth data to get",
&[],
)
})?
.get_authenticated_authorizations(self))
}
}

// metering: free for testutils
Expand Down
4 changes: 2 additions & 2 deletions soroban-env-host/src/cost_runner/runner.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::hint::black_box;

use crate::{xdr::ContractCostType, Host};
use crate::{budget::AsBudget, xdr::ContractCostType, Host};
/// `CostRunner` is an interface to running a host cost entity of a `CostType` (usually a block of
/// WASM bytecode or a host function), given a sample of `SampleType`.
pub trait CostRunner: Sized {
Expand Down Expand Up @@ -66,6 +66,6 @@ pub trait CostRunner: Sized {
/// actual input from the host's perspective. So use it carefully. This should be
/// after the `run`, outside of the CPU-and-memory tracking machineary.
fn get_tracker(host: &Host) -> (u64, Option<u64>) {
host.0.budget.get_tracker(Self::COST_TYPE).unwrap()
host.as_budget().get_tracker(Self::COST_TYPE).unwrap()
}
}
Loading

0 comments on commit 6d12921

Please sign in to comment.