Are cross contract call atomic?

Viewed 98

Take for example this code:

    #[payable]
    pub fn add_liquidity(&mut self, min_liquidity: u128, max_tokens: u128) -> U128 {
        let deposit = env::attached_deposit();
        let contract_near_balance = env::account_balance();
        let user_address = env::predecessor_account_id();
        let contract_address = env::current_account_id();
        
        let token_amount = max_tokens;
        println!("{}", token_amount);
        let initial_liquidity = contract_near_balance;
        println!("initial liquidity{}", initial_liquidity);

        self.uni_totalsupply = initial_liquidity;
        let balance_option = self.uni_balances.get(&user_address);
        match balance_option {
            Some(_) => {
                self.uni_balances.insert(&user_address, &initial_liquidity);
            }
            None => {
                self.uni_balances.insert(&user_address, &initial_liquidity);
            }
        }
        Promise::new(self.avrit_token_id.clone()).function_call(
            b"transfer_from".to_vec(),
            json!({"owner_id":contract_address, "new_owner_id":"avrit.testnet", "amount": U128(token_amount)}).to_string().as_bytes().to_vec(),
            DEPOSIT,
            env::prepaid_gas() - GAS_FOR_SWAP,
        );

        initial_liquidity.into()
        
    }

Even if the promise fails, will it set uni_balances in the storage? How can I make the transaction atomic?

1 Answers

Contract calls are not atomic. In order to make the chain of promises atomic is to use a then callback which is called after the initial promise. In the callback function you can check the success of the previous promise like here:

pub fn check_promise(&mut self) {
        match env::promise_result(0) {
            PromiseResult::Successful(_) => {
                env::log(b"Check_promise successful");
                self.checked_promise = true;
            }
            _ => panic!("Promise with index 0 failed"),
        };
    }

At this point you can make a state change that is final and could only happen if the whole transaction was successful.

Related