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

Remove use of rand from generated addresses, nonces, salts, and issuer pks #1135

Merged
merged 9 commits into from
Nov 8, 2023
15 changes: 8 additions & 7 deletions soroban-sdk/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::{unwrap::UnwrapInfallible, Bytes, Vec};
/// that allow customizing authentication logic and adding custom authorization
/// rules.
///
/// In tests Addresses should be generated via `Address::random()`.
/// In tests Addresses should be generated via `Address::generate()`.
#[derive(Clone)]
pub struct Address {
env: Env,
Expand Down Expand Up @@ -299,18 +299,19 @@ impl Address {
}
}

#[cfg(not(target_family = "wasm"))]
#[cfg(any(not(target_family = "wasm"), test, feature = "testutils"))]
use crate::env::xdr::Hash;
#[cfg(any(test, feature = "testutils"))]
use crate::testutils::random;
use crate::unwrap::UnwrapOptimized;

#[cfg(any(test, feature = "testutils"))]
#[cfg_attr(feature = "docs", doc(cfg(feature = "testutils")))]
impl crate::testutils::Address for Address {
fn random(env: &Env) -> Self {
let sc_addr = ScVal::Address(ScAddress::Contract(Hash(random())));
Self::try_from_val(env, &sc_addr).unwrap()
fn generate(env: &Env) -> Self {
Self::try_from_val(
env,
&ScAddress::Contract(Hash(env.with_generator(|mut g| g.address()))),
)
.unwrap()
}
}

Expand Down
72 changes: 53 additions & 19 deletions soroban-sdk/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ pub struct MaybeEnv {
maybe_env_impl: internal::MaybeEnvImpl,
#[cfg(any(test, feature = "testutils"))]
snapshot: Option<Rc<LedgerSnapshot>>,
#[cfg(any(test, feature = "testutils"))]
generators: Option<Rc<RefCell<Generators>>>,
}

#[cfg(target_family = "wasm")]
Expand All @@ -143,6 +145,8 @@ impl TryFrom<MaybeEnv> for Env {
env_impl: internal::EnvImpl {},
#[cfg(any(test, feature = "testutils"))]
snapshot: value.snapshot,
#[cfg(any(test, feature = "testutils"))]
generators: value.generators,
})
}
}
Expand All @@ -161,6 +165,8 @@ impl MaybeEnv {
maybe_env_impl: internal::EnvImpl {},
#[cfg(any(test, feature = "testutils"))]
snapshot: None,
#[cfg(any(test, feature = "testutils"))]
generators: None,
}
}
}
Expand All @@ -173,6 +179,8 @@ impl MaybeEnv {
maybe_env_impl: None,
#[cfg(any(test, feature = "testutils"))]
snapshot: None,
#[cfg(any(test, feature = "testutils"))]
generators: None,
}
}
}
Expand All @@ -184,6 +192,8 @@ impl From<Env> for MaybeEnv {
maybe_env_impl: value.env_impl,
#[cfg(any(test, feature = "testutils"))]
snapshot: value.snapshot,
#[cfg(any(test, feature = "testutils"))]
generators: Some(value.generators),
}
}
}
Expand All @@ -198,6 +208,10 @@ impl TryFrom<MaybeEnv> for Env {
env_impl,
#[cfg(any(test, feature = "testutils"))]
snapshot: value.snapshot,
#[cfg(any(test, feature = "testutils"))]
generators: value
.generators
.unwrap_or_else(|| Rc::new(RefCell::new(Generators::new()))),
})
} else {
Err(ConversionError)
Expand All @@ -212,6 +226,8 @@ impl From<Env> for MaybeEnv {
maybe_env_impl: Some(value.env_impl),
#[cfg(any(test, feature = "testutils"))]
snapshot: value.snapshot,
#[cfg(any(test, feature = "testutils"))]
generators: Some(value.generators),
}
}
}
Expand All @@ -229,6 +245,8 @@ pub struct Env {
env_impl: internal::EnvImpl,
#[cfg(any(test, feature = "testutils"))]
snapshot: Option<Rc<LedgerSnapshot>>,
#[cfg(any(test, feature = "testutils"))]
generators: Rc<RefCell<Generators>>,
}

impl Default for Env {
Expand Down Expand Up @@ -417,12 +435,14 @@ impl Env {
use crate::auth;
#[cfg(any(test, feature = "testutils"))]
use crate::testutils::{
budget::Budget, random, Address as _, AuthorizedInvocation, ContractFunctionSet, Ledger as _,
MockAuth, MockAuthContract,
budget::Budget, Address as _, AuthorizedInvocation, ContractFunctionSet, Generators,
Ledger as _, MockAuth, MockAuthContract,
};
#[cfg(any(test, feature = "testutils"))]
use crate::{Bytes, BytesN};
#[cfg(any(test, feature = "testutils"))]
use core::{cell::RefCell, cell::RefMut};
#[cfg(any(test, feature = "testutils"))]
use soroban_ledger_snapshot::LedgerSnapshot;
#[cfg(any(test, feature = "testutils"))]
use std::{path::Path, rc::Rc};
Expand All @@ -440,6 +460,12 @@ impl Env {
&self.env_impl
}

#[doc(hidden)]
pub(crate) fn with_generator<T>(&self, f: impl FnOnce(RefMut<'_, Generators>) -> T) -> T {
let g = (*self.generators).borrow_mut();
f(g)
}

fn default_with_testutils() -> Env {
struct EmptySnapshotSource();

Expand Down Expand Up @@ -484,14 +510,18 @@ impl Env {
let env_impl = internal::EnvImpl::with_storage_and_budget(storage, budget.clone());
env_impl
.set_source_account(xdr::AccountId(xdr::PublicKey::PublicKeyTypeEd25519(
xdr::Uint256(random()),
xdr::Uint256([0; 32]),
)))
.unwrap();
env_impl
.set_diagnostic_level(internal::DiagnosticLevel::Debug)
.unwrap();
env_impl.set_base_prng_seed([0; 32]).unwrap();
let env = Env { env_impl, snapshot };
let env = Env {
env_impl,
snapshot,
generators: Rc::new(RefCell::new(Generators::new())),
};

env.ledger().set(ledger_info);

Expand All @@ -501,8 +531,8 @@ impl Env {
/// Register a contract with the [Env] for testing.
///
/// Passing a contract ID for the first arguments registers the contract
/// with that contract ID. Providing `None` causes a random ID to be
/// assigned to the contract.
/// with that contract ID. Providing `None` causes the Env to generate a new
/// contract ID that is assigned to the contract.
///
/// Registering a contract that is already registered replaces it.
///
Expand Down Expand Up @@ -558,7 +588,7 @@ impl Env {
let contract_id = if let Some(contract_id) = contract_id.into() {
contract_id.clone()
} else {
Address::random(self)
Address::generate(self)
};
self.env_impl
.register_test_contract(
Expand All @@ -572,8 +602,8 @@ impl Env {
/// Register a contract in a WASM file with the [Env] for testing.
///
/// Passing a contract ID for the first arguments registers the contract
/// with that contract ID. Providing `None` causes a random ID to be
/// assigned to the contract.
/// with that contract ID. Providing `None` causes the Env to generate a new
/// contract ID that is assigned to the contract.
///
/// Registering a contract that is already registered replaces it.
///
Expand Down Expand Up @@ -613,7 +643,7 @@ impl Env {
/// is useful for using in the tests when an arbitrary token contract
/// instance is needed.
pub fn register_stellar_asset_contract(&self, admin: Address) -> Address {
let issuer_pk = random();
let issuer_pk = self.with_generator(|mut g| g.address());
let issuer_id = xdr::AccountId(xdr::PublicKey::PublicKeyTypeEd25519(xdr::Uint256(
issuer_pk.clone(),
)));
Expand Down Expand Up @@ -656,7 +686,7 @@ impl Env {
.unwrap();

let asset = xdr::Asset::CreditAlphanum4(xdr::AlphaNum4 {
asset_code: xdr::AssetCode4([b'a', b'a', b'a', b'a']),
asset_code: xdr::AssetCode4([b'a', b'a', b'a', 0]),
issuer: issuer_id.clone(),
});
let create = xdr::HostFunction::CreateContract(xdr::CreateContractArgs {
Expand Down Expand Up @@ -704,8 +734,10 @@ impl Env {
.invoke_function(xdr::HostFunction::CreateContract(xdr::CreateContractArgs {
contract_id_preimage: xdr::ContractIdPreimage::Address(
xdr::ContractIdPreimageFromAddress {
address: xdr::ScAddress::Contract(xdr::Hash(random())),
salt: xdr::Uint256(random()),
address: xdr::ScAddress::Contract(xdr::Hash(
self.with_generator(|mut g| g.address()),
)),
salt: xdr::Uint256([0; 32]),
},
),
executable,
Expand Down Expand Up @@ -770,7 +802,7 @@ impl Env {
/// let contract_id = env.register_contract(None, HelloContract);
///
/// let client = HelloContractClient::new(&env, &contract_id);
/// let addr = Address::random(&env);
/// let addr = Address::generate(&env);
/// client.mock_auths(&[
/// MockAuth {
/// address: &addr,
Expand Down Expand Up @@ -841,7 +873,7 @@ impl Env {
/// env.mock_all_auths();
///
/// let client = HelloContractClient::new(&env, &contract_id);
/// let addr = Address::random(&env);
/// let addr = Address::generate(&env);
/// client.hello(&addr);
/// }
/// ```
Expand Down Expand Up @@ -896,7 +928,7 @@ impl Env {
/// env.mock_all_auths_allowing_non_root_auth();
///
/// let client = ContractBClient::new(&env, &contract_b);
/// let addr = Address::random(&env);
/// let addr = Address::generate(&env);
/// client.call_a(&contract_a, &addr);
/// }
/// ```
Expand Down Expand Up @@ -953,7 +985,7 @@ impl Env {
/// let contract_id = env.register_contract(None, Contract);
/// let client = ContractClient::new(&env, &contract_id);
/// env.mock_all_auths();
/// let address = Address::random(&env);
/// let address = Address::generate(&env);
/// client.transfer(&address, &1000_i128);
/// assert_eq!(
/// env.auths(),
Expand Down Expand Up @@ -1055,7 +1087,7 @@ impl Env {
/// assert_eq!(
/// e.try_invoke_contract_check_auth::<NoopAccountError>(
/// &account_contract.address,
/// &BytesN::random(&e),
/// &BytesN::from_array(&e, &[0; 32]),
/// ().into(),
/// &vec![&e],
/// ),
Expand All @@ -1068,7 +1100,7 @@ impl Env {
/// assert_eq!(
/// e.try_invoke_contract_check_auth::<soroban_sdk::Error>(
/// &account_contract.address,
/// &BytesN::random(&e),
/// &BytesN::from_array(&e, &[0; 32]),
/// 0_i32.into(),
/// &vec![&e],
/// ),
Expand Down Expand Up @@ -1210,6 +1242,8 @@ impl Env {
env_impl,
#[cfg(any(test, feature = "testutils"))]
snapshot: None,
#[cfg(any(test, feature = "testutils"))]
generators: Rc::new(RefCell::new(Generators::new())),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion soroban-sdk/src/tests/auth/auth_10_one.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn test() {
let contract_id = e.register_contract(None, Contract);
let client = ContractClient::new(&e, &contract_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down
2 changes: 1 addition & 1 deletion soroban-sdk/src/tests/auth/auth_15_one_repeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ fn test() {
let contract_id = e.register_contract(None, Contract);
let client = ContractClient::new(&e, &contract_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn test() {
let contract_id = e.register_contract(None, Contract);
let client = ContractClient::new(&e, &contract_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/tests/auth/auth_20_deep_one_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn test() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down Expand Up @@ -65,7 +65,7 @@ fn test_auth_tree() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/tests/auth/auth_30_deep_one_address_repeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn test() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[
Expand Down Expand Up @@ -80,7 +80,7 @@ fn test_auth_tree() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn test() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[
Expand Down Expand Up @@ -80,7 +80,7 @@ fn test_auth_tree() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down
4 changes: 2 additions & 2 deletions soroban-sdk/src/tests/auth/auth_40_multi_one_address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn test_auth_not_allowed_with_separated_tree() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

assert!(client
.mock_auths(&[
Expand Down Expand Up @@ -70,7 +70,7 @@ fn test_auth_as_tree() {
let contract_b_id = e.register_contract(None, ContractB);
let client = ContractAClient::new(&e, &contract_a_id);

let a = Address::random(&e);
let a = Address::generate(&e);

let c = client
.mock_auths(&[MockAuth {
Expand Down
Loading