Skip to content

Commit

Permalink
Use ConstructorArgs trait for args on deploy with constructor (#1349)
Browse files Browse the repository at this point in the history
### What
Use ConstructorArgs trait for args on deploy with constructor, and
rename deploy with constructor to deploy_v2.

### Why
So that types can be passed directly to the deploy function like they
can now be passed to the register function since #1343.

I renamed the function to deploy_v2 for consistency with what we did
when we added a second register for stellar asset contract function. I
considered merging with the deploy function which would have been a
breaking change, that I think we agreed would be worthwhile, but
breaking is just such a bad experience and I think a _v2 is almost as
good. We can consider merging the deploy functions at a later date.

Close #1347
  • Loading branch information
leighmcculloch authored Sep 28, 2024
1 parent 9b7ac44 commit 01f27c1
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 47 deletions.
32 changes: 32 additions & 0 deletions soroban-sdk/src/constructor_args.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use crate::{Env, IntoVal, Val, Vec};

pub trait ConstructorArgs: IntoVal<Env, Vec<Val>> {}

impl<T> ConstructorArgs for Vec<T> {}

macro_rules! impl_constructor_args_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> ConstructorArgs for ($($typ,)*)
where
$($typ: IntoVal<Env, Val>),*
{
}
};
}

// 0 topics
impl ConstructorArgs for () {}
// 1-13 topics
impl_constructor_args_for_tuple! { T0 0 }
impl_constructor_args_for_tuple! { T0 0 T1 1 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }
28 changes: 18 additions & 10 deletions soroban-sdk/src/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
//! // Deployed contract address is deterministic and can be accessed
//! // before deploying the contract.
//! let _ = deployer.deployed_address();
//! let contract_address = deployer.deploy(wasm_hash);
//! let contract_address = deployer.deploy_v2(wasm_hash, ());
//! }
//! }
//! #[test]
Expand Down Expand Up @@ -61,8 +61,10 @@
//! // Deployed contract address is deterministic and can be accessed
//! // before deploying the contract.
//! let _ = deployer.deployed_address();
//! let contract_address = deployer.deploy_with_constructor(
//! wasm_hash, (1_u32, 2_i64).into_val(&env));
//! let contract_address = deployer.deploy_v2(
//! wasm_hash,
//! (1_u32, 2_i64),
//! );
//! }
//! }
//! #[test]
Expand All @@ -82,8 +84,8 @@
//! ```

use crate::{
env::internal::Env as _, unwrap::UnwrapInfallible, Address, Bytes, BytesN, Env, IntoVal, Val,
Vec,
env::internal::Env as _, unwrap::UnwrapInfallible, Address, Bytes, BytesN, ConstructorArgs,
Env, IntoVal,
};

/// Deployer provides access to deploying contracts.
Expand Down Expand Up @@ -258,6 +260,7 @@ impl DeployerWithAddress {
/// and provided salt.
///
/// Returns the deployed contract's address.
#[deprecated(note = "use deploy_v2")]
pub fn deploy(&self, wasm_hash: impl IntoVal<Env, BytesN<32>>) -> Address {
let env = &self.env;
let address_obj = env
Expand All @@ -272,24 +275,29 @@ impl DeployerWithAddress {

/// Deploy a contract that uses Wasm executable with provided hash.
///
/// `constructor_args` will be passed to the contract's constructor.
/// The constructor args will be passed to the contract's constructor. Pass
/// `()` for contract's with no constructor or a constructor with zero
/// arguments.
///
/// The address of the deployed contract is defined by the deployer address
/// and provided salt.
///
/// Returns the deployed contract's address.
pub fn deploy_with_constructor(
pub fn deploy_v2<A>(
&self,
wasm_hash: impl IntoVal<Env, BytesN<32>>,
constructor_args: Vec<Val>,
) -> Address {
constructor_args: A,
) -> Address
where
A: ConstructorArgs,
{
let env = &self.env;
let address_obj = env
.create_contract_with_constructor(
self.address.to_object(),
wasm_hash.into_val(env).to_object(),
self.salt.to_object(),
constructor_args.to_object(),
constructor_args.into_val(env).to_object(),
)
.unwrap_infallible();
unsafe { Address::unchecked_new(env.clone(), address_obj) }
Expand Down
10 changes: 5 additions & 5 deletions soroban-sdk/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,11 +453,11 @@ impl Env {
use crate::{
auth,
testutils::{
budget::Budget, Address as _, AuthSnapshot, AuthorizedInvocation, ConstructorArgs,
ContractFunctionSet, EventsSnapshot, Generators, Ledger as _, MockAuth, MockAuthContract,
Register, Snapshot, StellarAssetContract, StellarAssetIssuer,
budget::Budget, Address as _, AuthSnapshot, AuthorizedInvocation, ContractFunctionSet,
EventsSnapshot, Generators, Ledger as _, MockAuth, MockAuthContract, Register, Snapshot,
StellarAssetContract, StellarAssetIssuer,
},
Bytes, BytesN,
Bytes, BytesN, ConstructorArgs,
};
#[cfg(any(test, feature = "testutils"))]
use core::{cell::RefCell, cell::RefMut};
Expand Down Expand Up @@ -588,7 +588,7 @@ impl Env {
/// contract id passed in.
///
/// If you need to specify the address the contract should be registered at,
/// use [`register_at`].
/// use [`Env::register_at`].
///
/// ### Examples
/// Register a contract defined in the current crate, by specifying the type
Expand Down
3 changes: 3 additions & 0 deletions soroban-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,9 @@ mod string;
pub use string::String;
mod tuple;

mod constructor_args;
pub use constructor_args::ConstructorArgs;

pub mod xdr;

pub mod testutils;
Expand Down
33 changes: 1 addition & 32 deletions soroban-sdk/src/testutils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use soroban_env_host::TryIntoVal;

pub mod storage;

use crate::{xdr, Env, IntoVal, Val, Vec};
use crate::{xdr, ConstructorArgs, Env, Val, Vec};
use soroban_ledger_snapshot::LedgerSnapshot;

pub use crate::env::EnvTestConfig;
Expand Down Expand Up @@ -53,37 +53,6 @@ impl<'w> Register for &'w [u8] {
}
}

pub trait ConstructorArgs: IntoVal<Env, Vec<Val>> {}

impl<T> ConstructorArgs for Vec<T> {}

macro_rules! impl_constructor_args_for_tuple {
( $($typ:ident $idx:tt)* ) => {
impl<$($typ),*> ConstructorArgs for ($($typ,)*)
where
$($typ: IntoVal<Env, Val>),*
{
}
};
}

// 0 topics
impl ConstructorArgs for () {}
// 1-13 topics
impl_constructor_args_for_tuple! { T0 0 }
impl_constructor_args_for_tuple! { T0 0 T1 1 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 }
impl_constructor_args_for_tuple! { T0 0 T1 1 T2 2 T3 3 T4 4 T5 5 T6 6 T7 7 T8 8 T9 9 T10 10 T11 11 T12 12 }

#[derive(Default, Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct Snapshot {
Expand Down

0 comments on commit 01f27c1

Please sign in to comment.