Skip to content

Commit

Permalink
fix: exceeded prepaid gas error in mirror_erc20_token (#951)
Browse files Browse the repository at this point in the history
## Description

After some investigation, we realised that the problem was caused by a
change in gas costs after switching to near protocol version 66. The
change relates to the amount of gas used to load contract data, which
was
[changed](https://github.com/near/nearcore/blob/master/core/parameters/res/runtime_configs/66.yaml#L15)
from 216750 to 1089295 Gas per byte. The change increases the amount of
gas used in the `mirror_erc20_token_callback` to approximately to 1TGas.
So, more than 5TGas is needed now. Thanks to @birchmd for his help with
this investigation.

## Performance / NEAR gas cost considerations

There are no changes in the performance.

## Testing

#950 bumps `near-workspace` to 0.12, which contains updated
`near-sandbox` 2.1.1. on which the error is reproduced.

## How should this be reviewed

Check that the problem no longer reproduces after this commit is
included in #950.
  • Loading branch information
aleksuss authored Sep 3, 2024
1 parent c505f58 commit 880b2c1
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 5 deletions.
12 changes: 8 additions & 4 deletions engine/src/contract_methods/connector/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ pub const ERR_NOT_ENOUGH_BALANCE_FOR_FEE: &str = "ERR_NOT_ENOUGH_BALANCE_FOR_FEE
/// Indicate zero attached balance for promise call
pub const ZERO_ATTACHED_BALANCE: Yocto = Yocto::new(0);
/// Amount of attached gas for read-only promises.
const READ_PROMISE_ATTACHED_GAS: NearGas = NearGas::new(5_000_000_000_000);
const READ_PROMISE_ATTACHED_GAS: NearGas = NearGas::new(6_000_000_000_000);
/// Amount of attached gas for the `mirror_erc20_token_callback`.
const MIRROR_ERC20_TOKEN_CALLBACK_ATTACHED_GAS: NearGas = NearGas::new(10_000_000_000_000);

/// Create new eth-connector;
pub fn new_eth_connector<I: IO + Copy, E: Env>(io: I, env: &E) -> Result<(), ContractError> {
Expand Down Expand Up @@ -465,7 +467,9 @@ pub fn mirror_erc20_token<I: IO + Env + Copy, H: PromiseHandler>(
let args = MirrorErc20TokenArgs::try_from_slice(&input)
.map_err(|_| crate::errors::ERR_BORSH_DESERIALIZE)?;

let promise = vec![
// We can't use a batch of actions here, since we need to get responses from both
// view transactions in the `mirror_erc20_token_callback` callback.
let promises = vec![
PromiseCreateArgs {
target_account_id: args.contract_id.clone(),
method: "get_erc20_from_nep141".to_string(),
Expand All @@ -491,12 +495,12 @@ pub fn mirror_erc20_token<I: IO + Env + Copy, H: PromiseHandler>(
method: "mirror_erc20_token_callback".to_string(),
args: input,
attached_balance: Yocto::new(0),
attached_gas: READ_PROMISE_ATTACHED_GAS,
attached_gas: MIRROR_ERC20_TOKEN_CALLBACK_ATTACHED_GAS,
};
// Safe because these promises are read-only calls to the main engine contract
// and this transaction could be executed by the owner of the contract only.
let promise_id = unsafe {
let promise_id = handler.promise_create_and_combine(&promise);
let promise_id = handler.promise_create_and_combine(&promises);
handler.promise_attach_callback(promise_id, &callback)
};

Expand Down
2 changes: 1 addition & 1 deletion engine/src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2674,7 +2674,7 @@ mod tests {
// Check the storage value and hit the cache
let actual_value = engine.storage(origin.raw(), index);
assert_eq!(expected_value, actual_value);
// Cache should exists
// Cache should exist
let cache_val = engine
.contract_storage_cache
.borrow()
Expand Down

0 comments on commit 880b2c1

Please sign in to comment.