Skip to content

Commit

Permalink
Merge pull request #1627 from multiversx/composability-interact
Browse files Browse the repository at this point in the history
composability interact migration
  • Loading branch information
andrei-marinica authored May 20, 2024
2 parents bed7468 + 66f50e9 commit 5a41da5
Show file tree
Hide file tree
Showing 12 changed files with 639 additions and 193 deletions.
5 changes: 1 addition & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@ name = "forwarder-queue"
name = "forwarder-queue-promises"
add-labels = ["promises-callback"]
ei = "1.3"

[[proxy]]
path = "../interact/src/forwarder_queue_proxy.rs"
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,17 @@
multiversx_sc::imports!();
multiversx_sc::derive_imports!();

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)]
#[type_abi]
#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)]
pub enum QueuedCallType {
Sync,
LegacyAsync,
TransferExecute,
Promise,
}

#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, TypeAbi, Clone)]
#[type_abi]
#[derive(TopEncode, TopDecode, NestedEncode, NestedDecode, Clone)]
pub struct QueuedCall<M: ManagedTypeApi> {
pub call_type: QueuedCallType,
pub to: ManagedAddress<M>,
Expand Down
13 changes: 2 additions & 11 deletions contracts/feature-tests/composability/interact/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,9 @@ clap = { version = "4.4.7", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
toml = "0.8.6"

[dependencies.vault]
path = "../vault"

[dependencies.forwarder-queue]
path = "../forwarder-queue"

[dependencies.promises-features]
path = "../promises-features"

[dependencies.multiversx-sc-modules]
[dependencies.multiversx-sc]
version = "0.50.1"
path = "../../../../contracts/modules"
path = "../../../../framework/base"

[dependencies.multiversx-sc-snippets]
version = "0.50.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use std::{cell::RefCell, rc::Rc};

use forwarder_queue::QueuedCallType;

use multiversx_sc_snippets::imports::*;
use num_bigint::BigUint;

use crate::{
call_tree::{CallNode, CallState, ForwarderQueueTarget},
comp_interact_controller::ComposabilityInteract,
forwarder_queue_proxy::{self, QueuedCallType},
};
use forwarder_queue::ProxyTrait;

const FORWARD_QUEUED_CALLS_ENDPOINT: &str = "forward_queued_calls";
const DEFAULT_GAS_LIMIT: u64 = 10_000_000;
Expand All @@ -24,7 +22,7 @@ impl ComposabilityInteract {
payment_nonce: u64,
payment_amount: BigUint,
) {
let mut steps = Vec::new();
let mut buffer = self.interactor.homogenous_call_buffer();

for fwd_rc in forwarders {
let (fwd_name, fwd_children) = {
Expand All @@ -35,8 +33,6 @@ impl ComposabilityInteract {
let fwd = fwd_rc.borrow();
fwd.address.clone().unwrap()
};
let fwd_addr_bech32 = bech32::encode(&fwd_addr);
let fwd_addr_expr = format!("bech32:{fwd_addr_bech32}");

for child in &fwd_children {
match child {
Expand All @@ -48,29 +44,26 @@ impl ComposabilityInteract {
child_fwd.address.clone().unwrap()
};

let typed_sc_call = ScCallStep::new()
.call(
self.state
.forwarder_queue_from_addr(&fwd_addr_expr)
.add_queued_call(
call_type.clone(),
child_fwd_addr,
DEFAULT_GAS_LIMIT,
FORWARD_QUEUED_CALLS_ENDPOINT,
MultiValueEncoded::<StaticApi, _>::new(),
)
.with_egld_or_single_esdt_transfer(
EgldOrEsdtTokenPayment::new(
payment_token.clone(),
payment_nonce,
payment_amount.clone().into(),
),
),
)
.from(&self.wallet_address)
.gas_limit("70,000,000");

steps.push(typed_sc_call);
buffer.push_tx(|tx| {
tx.from(&self.wallet_address)
.to(&fwd_addr)
.gas(70_000_000u64)
.typed(forwarder_queue_proxy::ForwarderQueueProxy)
.add_queued_call(
call_type.clone(),
child_fwd_addr,
DEFAULT_GAS_LIMIT,
FORWARD_QUEUED_CALLS_ENDPOINT,
MultiValueEncoded::<StaticApi, _>::new(),
)
.payment(EgldOrEsdtTokenPayment::new(
payment_token.clone(),
payment_nonce,
payment_amount.clone().into(),
))
.returns(ReturnsStatus)
.returns(ReturnsResult)
});
},
CallNode::Vault(vault_rc) => {
// Call Vault
Expand All @@ -80,46 +73,41 @@ impl ComposabilityInteract {
vault.address.clone().unwrap()
};

let typed_sc_call = ScCallStep::new()
.call(
self.state
.forwarder_queue_from_addr(&fwd_addr_expr)
.add_queued_call(
call_type.clone(),
vault_addr,
DEFAULT_GAS_LIMIT,
endpoint_name,
MultiValueEncoded::<StaticApi, _>::new(),
)
.with_egld_or_single_esdt_transfer(
EgldOrEsdtTokenPayment::new(
payment_token.clone(),
payment_nonce,
payment_amount.clone().into(),
),
),
)
.from(&self.wallet_address)
.gas_limit("70,000,000");

steps.push(typed_sc_call);
buffer.push_tx(|tx| {
tx.from(&self.wallet_address)
.to(&fwd_addr)
.gas(70_000_000u64)
.typed(forwarder_queue_proxy::ForwarderQueueProxy)
.add_queued_call(
call_type.clone(),
vault_addr,
DEFAULT_GAS_LIMIT,
endpoint_name,
MultiValueEncoded::<StaticApi, _>::new(),
)
.payment(EgldOrEsdtTokenPayment::new(
payment_token.clone(),
payment_nonce,
payment_amount.clone().into(),
))
.returns(ReturnsStatus)
.returns(ReturnsResult)
});
},
}
}
}
self.interactor
.multi_sc_exec(StepBuffer::from_sc_call_vec(&mut steps))
.await;

for step in steps.iter() {
if !step.response().is_success() {
println!(
"perform 'add_queued_call' failed with: {}",
step.response().tx_error
);
let results = buffer.run().await;

for (index, (status, result)) in results.iter().enumerate() {
if !status == 0u64 {
println!("perform 'add_queued_call' failed with error code {status}");
continue;
}
println!("successfully performed action 'add_queued_call'");
println!(
"successfully performed action {index} 'add_queued_call' with result {result:?}"
);
}
}

Expand All @@ -128,21 +116,16 @@ impl ComposabilityInteract {
let root_addr_ref = call_state.root.borrow();
root_addr_ref.address.clone().unwrap()
};
let root_addr_bech32 = bech32::encode(&root_addr);
let root_addr_expr = format!("bech32:{root_addr_bech32}");

self.interactor
.sc_call(
ScCallStep::new()
.call(
self.state
.forwarder_queue_from_addr(&root_addr_expr)
.forward_queued_calls(),
)
.from(&self.wallet_address)
.gas_limit("70,000,000")
.expect(TxExpect::ok().additional_error_message("calling root failed with: ")),
)
.tx()
.from(&self.wallet_address)
.gas(70_000_000u64)
.to(&root_addr)
.typed(forwarder_queue_proxy::ForwarderQueueProxy)
.forward_queued_calls()
.prepare_async()
.run()
.await;

println!("successfully called root");
Expand Down
113 changes: 39 additions & 74 deletions contracts/feature-tests/composability/interact/src/call_tree_deploy.rs
Original file line number Diff line number Diff line change
@@ -1,100 +1,65 @@
use crate::{call_tree::CallState, comp_interact_controller::ComposabilityInteract};

use forwarder_queue::ProxyTrait as _;
use vault::ProxyTrait as _;
use crate::{
call_tree::CallState, comp_interact_controller::ComposabilityInteract, forwarder_queue_proxy, vault_proxy
};

use multiversx_sc_snippets::imports::*;

impl ComposabilityInteract {
pub async fn deploy_call_tree_contracts(&mut self, call_state: &CallState) {
let mut typed_vault_deploys = self.typed_sc_deploy_vault(call_state).await;
let mut typed_forwarder_deploys = self.typed_sc_deploy_forwarder_queue(call_state).await;

let mut steps = Vec::new();
for typed_sc_deploy in &mut typed_vault_deploys {
steps.push(typed_sc_deploy.as_mut());
}
for typed_sc_deploy in &mut typed_forwarder_deploys {
steps.push(typed_sc_deploy.as_mut());
}

self.interactor
.multi_sc_exec(StepBuffer::from_sc_deploy_vec(&mut steps))
.await;
let vault_deploy_addresses = self.typed_sc_deploy_vault(call_state).await;
let forwarder_deploy_addresses = self.typed_sc_deploy_forwarder_queue(call_state).await;

let mut vault_iter = call_state.vaults.iter();
for step in typed_vault_deploys.iter() {
if let Some(new_address) = step.response().new_deployed_address.clone() {
let new_address_bech32 = bech32::encode(&new_address);
let rc_vault = vault_iter.next().unwrap();
let mut vault = rc_vault.borrow_mut();
println!(
"New vault {0} deployed address: {1}",
vault.name, new_address_bech32
);
for address in vault_deploy_addresses.iter() {
let rc_vault = vault_iter.next().unwrap();
let mut vault = rc_vault.borrow_mut();
println!("New vault {0} deployed address: {1}", vault.name, address);

vault.address = Some(new_address);
} else {
println!("deploy failed");
return;
}
vault.address = Some(address.to_address());
}

let mut fwd_iter = call_state.forwarders.iter();
for step in typed_forwarder_deploys.iter() {
if let Some(new_address) = step.response().new_deployed_address.clone() {
let new_address_bech32 = bech32::encode(&new_address);
let rc_fwd = fwd_iter.next().unwrap();
let mut fwd = rc_fwd.borrow_mut();
println!(
"New forwarder {0} deployed address: {1}",
fwd.name, new_address_bech32
);
for address in forwarder_deploy_addresses.iter() {
let rc_fwd = fwd_iter.next().unwrap();
let mut fwd = rc_fwd.borrow_mut();
println!("New forwarder {0} deployed address: {1}", fwd.name, address);

fwd.address = Some(new_address);
} else {
println!("deploy failed");
return;
}
fwd.address = Some(address.to_address());
}
}

pub async fn typed_sc_deploy_vault(
&mut self,
call_state: &CallState,
) -> Vec<TypedScDeploy<OptionalValue<ManagedBuffer<StaticApi>>>> {
let mut typed_vault_deploys = Vec::new();
pub async fn typed_sc_deploy_vault(&mut self, call_state: &CallState) -> Vec<Bech32Address> {
let mut buffer = self.interactor.homogenous_call_buffer();
for _ in call_state.vaults.iter() {
let typed_sc_deploy = ScDeployStep::new()
.call(
self.state
.default_vault_address()
.init(OptionalValue::<BoxedBytes>::None),
)
.from(&self.wallet_address)
.code(&self.vault_code)
.gas_limit("70,000,000");

typed_vault_deploys.push(typed_sc_deploy);
buffer.push_tx(|tx| {
tx.from(&self.wallet_address)
.typed(vault_proxy::VaultProxy)
.init(OptionalValue::<BoxedBytes>::None)
.code(&self.vault_code)
.gas(NumExpr("70,000,000"))
.returns(ReturnsNewBech32Address)
});
}
typed_vault_deploys

buffer.run().await
}

pub async fn typed_sc_deploy_forwarder_queue(
&mut self,
call_state: &CallState,
) -> Vec<TypedScDeploy<()>> {
let mut typed_forwarder_deploys = Vec::new();

) -> Vec<Bech32Address> {
let mut buffer = self.interactor.homogenous_call_buffer();
for _ in call_state.forwarders.iter() {
let typed_sc_deploy = ScDeployStep::new()
.call(self.state.default_forwarder_queue_address().init())
.from(&self.wallet_address)
.code(&self.forw_queue_code)
.gas_limit("70,000,000");

typed_forwarder_deploys.push(typed_sc_deploy);
buffer.push_tx(|tx| {
tx.from(&self.wallet_address)
.typed(forwarder_queue_proxy::ForwarderQueueProxy)
.init()
.code(&self.forw_queue_code)
.gas(NumExpr("70,000,000"))
.returns(ReturnsNewBech32Address)
});
}
typed_forwarder_deploys

buffer.run().await
}
}
Loading

0 comments on commit 5a41da5

Please sign in to comment.