mrLSD
mrLSD

Reputation: 698

NEAR SmartContract promises usage

It's not an obvious thing when I should use Promises when developing SmartConract in NEAR Protocol. And when it's redundant.

For example, I have some logic that finalize some public methods:

    #[private]
    fn record_data(&mut self, key: &Vec<u8>) -> Balance {
        let initial_storage = env::storage_usage();
        assert!(
            !self.used_events.contains(&key),
            "Proof event cannot be reused. Proof already exist."
        );
        self.used_events.insert(&key);
        let current_storage = env::storage_usage();
        let attached_deposit = env::attached_deposit();
        let required_deposit =
            Balance::from(current_storage - initial_storage) * STORAGE_PRICE_PER_BYTE;
        attached_deposit - required_deposit
    }

And in the same contract I have a function:

    #[payable]
    fn deposit(&mut self, amount: Balance) {
        // ...some logic
        self.record_data(&data)
    }

So with Promises, I can call record_data in async way. But it's not clear when I must use that way (Promise call). And when I can call in a very simple manner:

self.record_data(&data)

It's an obvious fact, that cross-contract call always via Promises. But it the same contract call specific inner Contract functions -it's not clear when we should use Promises.

So I need good clarification when I must use Promises and when it will redundant.

Upvotes: 1

Views: 151

Answers (1)

sirwillem
sirwillem

Reputation: 722

You can make the call to record_data async, but it comes at a cost. You are paying a base fee to make another transaction + the gas cost to run the code + the gas to interact with the host calls (e.g. env::*). So the reason to make internal calls asynchronous is to take advantage of the concurrency: see the rust-sdk's merge sort

    pub fn merge_sort(&self, arr: Vec<u8>) -> PromiseOrValue<Vec<u8>> {
        if arr.len() <= 1 {
            return PromiseOrValue::Value(arr);
        }
        let pivot = arr.len() / 2;
        let arr0 = arr[..pivot].to_vec();
        let arr1 = arr[pivot..].to_vec();
        let prepaid_gas = env::prepaid_gas();
        let account_id = env::current_account_id();

        ext::merge_sort(arr0, &account_id, 0, prepaid_gas / 4)
            .and(ext::merge_sort(arr1, &account_id, 0, prepaid_gas / 4))
            .then(ext::merge(&account_id, 0, prepaid_gas / 4))
            .into()
    }

Upvotes: 2

Related Questions