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

unified syntax - interactors #1486

Merged
merged 2 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 55 additions & 49 deletions contracts/examples/adder/interact/src/basic_interact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,24 @@ mod basic_interact_cli;
mod basic_interact_config;
mod basic_interact_state;

use adder::ProxyTrait;
use adder::{temp_proxy, ProxyTrait};
use basic_interact_config::Config;
use basic_interact_state::State;
use clap::Parser;
use multiversx_sc_snippets::{
env_logger,
multiversx_sc::{storage::mappers::SingleValue, types::Address},
multiversx_sc::types::{Address, ReturnsNewAddress, ReturnsSimilar},
multiversx_sc_scenario::{
api::StaticApi,
bech32,
mandos_system::ScenarioRunner,
num_bigint::BigUint,
scenario_format::interpret_trait::{InterpretableFrom, InterpreterContext},
scenario_model::{
BytesValue, ScCallStep, ScDeployStep, ScQueryStep, Scenario, TransferStep, TxExpect,
},
scenario_model::{BytesValue, ScDeployStep, Scenario},
standalone::retrieve_account_as_scenario_set_state,
test_wallets, ContractInfo,
test_wallets, ContractInfo, WithRawTxResponse,
},
tokio, Interactor, StepBuffer,
tokio, Interactor, InteractorPrepareAsync, StepBuffer,
};

const INTERACTOR_SCENARIO_TRACE_PATH: &str = "interactor_trace.scen.json";
Expand Down Expand Up @@ -100,28 +98,32 @@ impl AdderInteract {
async fn deploy(&mut self) {
self.set_state().await;

self.interactor
.sc_deploy_use_result(
ScDeployStep::new()
.call(self.state.default_adder().init(BigUint::from(0u64)))
.from(&self.wallet_address)
.code(&self.adder_code),
|new_address, tr| {
tr.result.unwrap_or_else(|err| {
panic!(
"deploy failed: status: {}, message: {}",
err.status, err.message
)
});

let new_address_bech32 = bech32::encode(&new_address);
println!("new address: {new_address_bech32}");

let new_address_expr = format!("bech32:{new_address_bech32}");
self.state.set_adder_address(&new_address_expr);
},
)
let new_address = self
.interactor
.tx()
.from(&self.wallet_address)
.typed(temp_proxy::AdderProxy)
.init(0u32)
.code(&self.adder_code)
.with_result(WithRawTxResponse(|response| {
let err = &response.tx_error;
assert!(
err.is_success(),
"deploy failed: status: {}, message: {}",
err.status,
err.message
);
}))
.returns(ReturnsNewAddress)
.prepare_async()
.run()
.await;

let new_address_bech32 = bech32::encode(&new_address.to_address());
println!("new address: {new_address_bech32}");

let new_address_expr = format!("bech32:{new_address_bech32}");
self.state.set_adder_address(&new_address_expr);
}

async fn multi_deploy(&mut self, count: &u8) {
Expand Down Expand Up @@ -164,38 +166,42 @@ impl AdderInteract {
}

async fn feed_contract_egld(&mut self) {
let _ = self
.interactor
.transfer(
TransferStep::new()
.from(&self.wallet_address)
.to(self.state.adder())
.egld_value("0,050000000000000000"),
)
self.interactor
.tx()
.from(&self.wallet_address)
.to(self.state.adder().to_address())
.egld(50000000000000000u64.into()) // TODO: annotate "0,050000000000000000"
.prepare_async()
.run()
.await;
}

async fn add(&mut self, value: u64) {
self.interactor
.sc_call(
ScCallStep::new()
.call(self.state.adder().add(value))
.from(&self.wallet_address)
.expect(
TxExpect::ok().additional_error_message("performing add failed with: "),
),
)
.tx()
.from(&self.wallet_address)
.to(self.state.adder().to_address())
.typed(temp_proxy::AdderProxy)
.add(value)
.prepare_async()
.run()
.await;

println!("successfully performed add");
}

async fn print_sum(&mut self) {
self.interactor
.sc_query_use_result(ScQueryStep::new().call(self.state.adder().sum()), |tr| {
let sum: SingleValue<BigUint> = tr.result.unwrap();
println!("sum: {}", sum.into());
})
let sum = self
.interactor
.query()
.to(self.state.adder().to_address())
.typed(temp_proxy::AdderProxy)
.sum()
.returns(ReturnsSimilar::<BigUint>::new())
.prepare_async()
.run()
.await;

println!("sum: {sum}");
}
}
28 changes: 27 additions & 1 deletion framework/base/src/types/interaction/annotated.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::types::{ManagedAddress, ManagedBuffer};
use crate::types::{heap::Address, ManagedAddress, ManagedBuffer};

use super::TxEnv;

Expand Down Expand Up @@ -37,6 +37,32 @@ where
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for Address
where
Env: TxEnv,
{
fn annotation(&self, _env: &Env) -> ManagedBuffer<Env::Api> {
ManagedAddress::from(self).hex_expr()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.into()
}
}

impl<Env> AnnotatedValue<Env, ManagedAddress<Env::Api>> for &Address
where
Env: TxEnv,
{
fn annotation(&self, _env: &Env) -> ManagedBuffer<Env::Api> {
ManagedAddress::from(*self).hex_expr()
}

fn into_value(self, _env: &Env) -> ManagedAddress<Env::Api> {
self.into()
}
}

impl<Env> AnnotatedValue<Env, ManagedBuffer<Env::Api>> for ManagedBuffer<Env::Api>
where
Env: TxEnv,
Expand Down
24 changes: 23 additions & 1 deletion framework/base/src/types/interaction/tx_from.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::types::ManagedAddress;
use crate::types::{heap::Address, ManagedAddress};

use super::{AnnotatedValue, TxEnv};

Expand Down Expand Up @@ -44,3 +44,25 @@ where
}
}
impl<Env> TxFromSpecified<Env> for &ManagedAddress<Env::Api> where Env: TxEnv {}

impl<Env> TxFrom<Env> for Address
where
Env: TxEnv,
{
fn resolve_address(&self, _env: &Env) -> ManagedAddress<Env::Api> {
self.into()
}
}

impl<Env> TxFromSpecified<Env> for Address where Env: TxEnv {}

impl<Env> TxFrom<Env> for &Address
where
Env: TxEnv,
{
fn resolve_address(&self, _env: &Env) -> ManagedAddress<Env::Api> {
ManagedAddress::from_address(self)
}
}

impl<Env> TxFromSpecified<Env> for &Address where Env: TxEnv {}
92 changes: 92 additions & 0 deletions framework/base/src/types/interaction/tx_payment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{
api::ManagedTypeApi,
contract_base::SendRawWrapper,
formatter::FormatBuffer,
imports::{BigUint, ManagedBuffer, ManagedBufferCachedBuilder, ManagedVec},
types::{
EgldOrEsdtTokenPayment, EgldOrMultiEsdtPayment, EgldPayment, EsdtTokenPayment,
ManagedAddress, MultiEsdtPayment,
Expand All @@ -19,6 +21,50 @@ where
pub fc: FunctionCall<Api>,
}

#[derive(Clone)]
pub struct AnnotatedEgldPayment<Api>
where
Api: ManagedTypeApi,
{
pub value: BigUint<Api>,
pub annotation: ManagedBuffer<Api>,
}

impl<Api> AnnotatedEgldPayment<Api>
where
Api: ManagedTypeApi,
{
pub fn new_egld(value: BigUint<Api>) -> Self {
let mut annotation = ManagedBufferCachedBuilder::default();
annotation.append_display(&value);
AnnotatedEgldPayment {
value,
annotation: annotation.into_managed_buffer(),
}
}
}

#[derive(Clone)]
pub struct FullPaymentData<Api>
where
Api: ManagedTypeApi,
{
pub egld: Option<AnnotatedEgldPayment<Api>>,
pub multi_esdt: MultiEsdtPayment<Api>,
}

impl<Api> Default for FullPaymentData<Api>
where
Api: ManagedTypeApi,
{
fn default() -> Self {
Self {
egld: None,
multi_esdt: Default::default(),
}
}
}

/// Describes a payment that is part of a transaction.
pub trait TxPayment<Env>
where
Expand All @@ -44,6 +90,8 @@ where
gas_limit: u64,
fc: FunctionCall<Env::Api>,
);

fn into_full_payment_data(self) -> FullPaymentData<Env::Api>;
}

/// Marks a payment object that only contains EGLD or nothing at all.
Expand Down Expand Up @@ -88,6 +136,10 @@ where
) {
EgldPayment::no_payment().perform_transfer_execute(env, to, gas_limit, fc);
}

fn into_full_payment_data(self) -> FullPaymentData<Env::Api> {
FullPaymentData::default()
}
}

impl<Env> TxPaymentEgldOnly<Env> for ()
Expand Down Expand Up @@ -139,6 +191,13 @@ where
&fc.arg_buffer,
);
}

fn into_full_payment_data(self) -> FullPaymentData<<Env as TxEnv>::Api> {
FullPaymentData {
egld: Some(AnnotatedEgldPayment::new_egld(self.value)),
multi_esdt: ManagedVec::new(),
}
}
}

impl<Env> TxPaymentEgldOnly<Env> for EgldPayment<Env::Api>
Expand Down Expand Up @@ -184,6 +243,13 @@ where
) {
MultiEsdtPayment::from_single_item(self).perform_transfer_execute(env, to, gas_limit, fc);
}

fn into_full_payment_data(self) -> FullPaymentData<<Env as TxEnv>::Api> {
FullPaymentData {
egld: None,
multi_esdt: MultiEsdtPayment::from_single_item(self),
}
}
}

impl<Env> TxPayment<Env> for MultiEsdtPayment<Env::Api>
Expand Down Expand Up @@ -226,6 +292,13 @@ where
&fc.arg_buffer,
);
}

fn into_full_payment_data(self) -> FullPaymentData<<Env as TxEnv>::Api> {
FullPaymentData {
egld: None,
multi_esdt: self,
}
}
}

impl<Env> TxPayment<Env> for EgldOrEsdtTokenPayment<Env::Api>
Expand Down Expand Up @@ -268,6 +341,14 @@ where
|(to, fc), esdt_payment| esdt_payment.perform_transfer_execute(env, to, gas_limit, fc),
)
}

fn into_full_payment_data(self) -> FullPaymentData<Env::Api> {
self.map_egld_or_esdt(
(),
|(), amount| TxPayment::<Env>::into_full_payment_data(EgldPayment::from(amount)),
|(), esdt_payment| TxPayment::<Env>::into_full_payment_data(esdt_payment),
)
}
}

impl<Env> TxPayment<Env> for EgldOrMultiEsdtPayment<Env::Api>
Expand Down Expand Up @@ -314,6 +395,17 @@ where
},
}
}

fn into_full_payment_data(self) -> FullPaymentData<Env::Api> {
match self {
EgldOrMultiEsdtPayment::Egld(egld_amount) => {
TxPayment::<Env>::into_full_payment_data(EgldPayment::from(egld_amount))
},
EgldOrMultiEsdtPayment::MultiEsdt(multi_esdt_payment) => {
TxPayment::<Env>::into_full_payment_data(multi_esdt_payment)
},
}
}
}

fn convert_tx_data_fungible<Api>(
Expand Down
Loading
Loading