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

Graydon code review #1044

Merged
merged 11 commits into from
Sep 8, 2023
Prev Previous commit
Next Next commit
Move code in host to match env.json and add region markers
  • Loading branch information
graydon committed Sep 7, 2023
commit 164d403d3cf654cee28927a86ce7db90f72b2a28
192 changes: 113 additions & 79 deletions soroban-env-host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,8 @@ impl EnvBase for Host {
impl VmCallerEnv for Host {
type VmUserState = Host;

// region: "context" module functions

// Notes on metering: covered by the components
fn log_from_linear_memory(
&self,
Expand Down Expand Up @@ -1341,6 +1343,79 @@ impl VmCallerEnv for Host {
Ok(Val::VOID)
}

fn get_ledger_version(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U32Val, Self::Error> {
self.with_ledger_info(|li| Ok(li.protocol_version.into()))
}

fn get_ledger_sequence(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U32Val, Self::Error> {
self.with_ledger_info(|li| Ok(li.sequence_number.into()))
}

fn get_ledger_timestamp(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U64Val, Self::Error> {
self.with_ledger_info(|li| Ok(self.add_host_object(li.timestamp)?.into()))
}

fn get_current_call_stack(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<VecObject, HostError> {
let contexts = self.try_borrow_context()?;

let get_host_val_tuple = |id: &Hash, function: &Symbol| -> Result<[Val; 2], HostError> {
let addr_val = self
.add_host_object(ScAddress::Contract(id.metered_clone(self)?))?
.into();
let function_val = (*function).into();
Ok([addr_val, function_val])
};

let mut outer = Vec::with_capacity(contexts.len());
for context in contexts.iter() {
let vals = match &context.frame {
Frame::ContractVM { vm, fn_name, .. } => {
get_host_val_tuple(&vm.contract_id, fn_name)?
}
Frame::HostFunction(_) => continue,
Frame::Token(id, function, ..) => get_host_val_tuple(id, function)?,
#[cfg(any(test, feature = "testutils"))]
Frame::TestContract(tc) => get_host_val_tuple(&tc.id, &tc.func)?,
};
let inner = MeteredVector::from_array(&vals, self.as_budget())?;
outer.push(self.add_host_object(inner)?.into());
}
self.add_host_object(HostVec::from_vec(outer)?)
}

fn fail_with_error(
&self,
vmcaller: &mut VmCaller<Self::VmUserState>,
error: Error,
) -> Result<Void, Self::Error> {
if error.is_type(ScErrorType::Contract) {
Err(self.error(
error,
"failing with contract error",
&[U32Val::from(error.get_code()).to_val()],
))
} else {
Err(self.err(
ScErrorType::Context,
ScErrorCode::UnexpectedType,
"contract attempted to fail with non-ContractError status code",
&[error.to_val()],
))
}
}

fn get_ledger_network_id(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<BytesObject, Self::Error> {
self.with_ledger_info(|li| {
self.add_host_object(self.scbytes_from_slice(li.network_id.as_slice())?)
})
}

// Notes on metering: covered by the components.
fn get_current_contract_address(
&self,
Expand All @@ -1351,6 +1426,17 @@ impl VmCallerEnv for Host {
))
}

fn get_max_expiration_ledger(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<U32Val, Self::Error> {
Ok(self.max_expiration_ledger()?.into())
}

// endregion "context" module functions

// region: "int" module functions

impl_wrapping_obj_from_num!(obj_from_u64, u64, u64);
impl_wrapping_obj_to_num!(obj_to_u64, u64, u64);
impl_wrapping_obj_from_num!(obj_from_i64, i64, i64);
Expand Down Expand Up @@ -1600,6 +1686,9 @@ impl VmCallerEnv for Host {
self.add_host_object(HostMap::new())
}

// endregion "int" module functions
// region: "map" module functions

fn map_put(
&self,
_vmcaller: &mut VmCaller<Host>,
Expand Down Expand Up @@ -1822,6 +1911,9 @@ impl VmCallerEnv for Host {
Ok(Val::VOID)
}

// endregion "map" module functions
// region: "vec" module functions

fn vec_new(&self, _vmcaller: &mut VmCaller<Host>) -> Result<VecObject, HostError> {
self.add_host_object(HostVec::new())
}
Expand Down Expand Up @@ -2068,6 +2160,9 @@ impl VmCallerEnv for Host {
Ok(Val::VOID)
}

// endregion "vec" module functions
// region: "ledger" module functions

// Notes on metering: covered by components
fn put_contract_data(
&self,
Expand Down Expand Up @@ -2381,6 +2476,9 @@ impl VmCallerEnv for Host {
Ok(Val::VOID)
}

// endregion "ledger" module functions
// region: "call" module functions

// Notes on metering: here covers the args unpacking. The actual VM work is changed at lower layers.
fn call(
&self,
Expand Down Expand Up @@ -2455,6 +2553,9 @@ impl VmCallerEnv for Host {
}
}

// endregion "call" module functions
// region: "buf" module functions

// Notes on metering: covered by components
fn serialize_to_bytes(
&self,
Expand Down Expand Up @@ -2843,6 +2944,9 @@ impl VmCallerEnv for Host {
self.add_host_object(self.scbytes_from_vec(vnew)?)
}

// endregion "buf" module functions
// region: "crypto" module functions

// Notes on metering: covered by components.
fn compute_hash_sha256(
&self,
Expand Down Expand Up @@ -2892,90 +2996,16 @@ impl VmCallerEnv for Host {
self.recover_key_ecdsa_secp256k1_internal(&hash, &sig, rid)
}

fn get_ledger_version(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U32Val, Self::Error> {
self.with_ledger_info(|li| Ok(li.protocol_version.into()))
}

fn get_ledger_sequence(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U32Val, Self::Error> {
self.with_ledger_info(|li| Ok(li.sequence_number.into()))
}

fn get_ledger_timestamp(&self, _vmcaller: &mut VmCaller<Host>) -> Result<U64Val, Self::Error> {
self.with_ledger_info(|li| Ok(self.add_host_object(li.timestamp)?.into()))
}

fn get_max_expiration_ledger(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<U32Val, Self::Error> {
Ok(self.max_expiration_ledger()?.into())
}

fn get_ledger_network_id(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<BytesObject, Self::Error> {
self.with_ledger_info(|li| {
self.add_host_object(self.scbytes_from_slice(li.network_id.as_slice())?)
})
}

fn get_current_call_stack(
&self,
_vmcaller: &mut VmCaller<Host>,
) -> Result<VecObject, HostError> {
let contexts = self.try_borrow_context()?;

let get_host_val_tuple = |id: &Hash, function: &Symbol| -> Result<[Val; 2], HostError> {
let addr_val = self
.add_host_object(ScAddress::Contract(id.metered_clone(self)?))?
.into();
let function_val = (*function).into();
Ok([addr_val, function_val])
};

let mut outer = Vec::with_capacity(contexts.len());
for context in contexts.iter() {
let vals = match &context.frame {
Frame::ContractVM { vm, fn_name, .. } => {
get_host_val_tuple(&vm.contract_id, fn_name)?
}
Frame::HostFunction(_) => continue,
Frame::Token(id, function, ..) => get_host_val_tuple(id, function)?,
#[cfg(any(test, feature = "testutils"))]
Frame::TestContract(tc) => get_host_val_tuple(&tc.id, &tc.func)?,
};
let inner = MeteredVector::from_array(&vals, self.as_budget())?;
outer.push(self.add_host_object(inner)?.into());
}
self.add_host_object(HostVec::from_vec(outer)?)
}

fn fail_with_error(
&self,
vmcaller: &mut VmCaller<Self::VmUserState>,
error: Error,
) -> Result<Void, Self::Error> {
if error.is_type(ScErrorType::Contract) {
Err(self.error(
error,
"failing with contract error",
&[U32Val::from(error.get_code()).to_val()],
))
} else {
Err(self.err(
ScErrorType::Context,
ScErrorCode::UnexpectedType,
"contract attempted to fail with non-ContractError status code",
&[error.to_val()],
))
}
}
// endregion "crypto" module functions
// region: "test" module functions

fn dummy0(&self, vmcaller: &mut VmCaller<Self::VmUserState>) -> Result<Val, Self::Error> {
Ok(().into())
}

// endregion "test" module functions
// region: "address" module functions

fn require_auth_for_args(
&self,
vmcaller: &mut VmCaller<Self::VmUserState>,
Expand Down Expand Up @@ -3075,6 +3105,9 @@ impl VmCallerEnv for Host {
}
}

// endregion "address" module functions
// region: "prng" module functions

fn prng_reseed(
&self,
vmcaller: &mut VmCaller<Self::VmUserState>,
Expand Down Expand Up @@ -3136,6 +3169,7 @@ impl VmCallerEnv for Host {
})?;
self.add_host_object(vnew)
}
// endregion "prng" module functions
}

#[cfg(any(test, feature = "testutils"))]
Expand Down