1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use std::sync::Arc;

use async_trait::async_trait;
use multiversx_sc::types::CodeMetadata;
use num_bigint::BigUint;
use tokio::sync::Mutex;

use novax_data::{Address, NativeConvertible};

use crate::call_result::CallResult;
use crate::error::executor::ExecutorError;
use crate::TopDecodeMulti;

/// A trait defining the contract for executing smart contract deployment operations asynchronously.
#[async_trait]
pub trait DeployExecutor: Send + Sync {
    /// Executes a smart contract deployment step asynchronously.
    async fn sc_deploy<
        OutputManaged
    >(
        &mut self,
        bytes: Vec<u8>,
        code_metadata: CodeMetadata,
        egld_value: BigUint,
        arguments: Vec<Vec<u8>>,
        gas_limit: u64
    ) -> Result<(Address, CallResult<OutputManaged::Native>), ExecutorError>
        where
            OutputManaged: TopDecodeMulti + NativeConvertible + Send + Sync;
}

/// An implementation of `DeployExecutor` for `Arc<Mutex<T>>` where `T: DeployExecutor`.
/// This wrapper allows for thread-safe, shared ownership of a deploy executor.
#[async_trait]
impl<T: DeployExecutor> DeployExecutor for Arc<Mutex<T>> {
    /// Executes a smart contract deployment step asynchronously, delegating to the inner `DeployExecutor`.
    async fn sc_deploy<
        OutputManaged
    >(
        &mut self,
        bytes: Vec<u8>,
        code_metadata: CodeMetadata,
        egld_value: BigUint,
        arguments: Vec<Vec<u8>>,
        gas_limit: u64
    ) -> Result<(Address, CallResult<OutputManaged::Native>), ExecutorError>
        where
            OutputManaged: TopDecodeMulti + NativeConvertible + Send + Sync
    {
        {
            let mut locked = self.lock().await;
            locked.sc_deploy::<OutputManaged>(bytes, code_metadata, egld_value, arguments, gas_limit).await
        }
    }
}