From 3e7d98bcb0c36c52a7b6891cb611b8474057acdb Mon Sep 17 00:00:00 2001 From: Uladzislau Hubar <71610423+u-hubar@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:19:25 +0200 Subject: [PATCH] Bugfix/gas limit estimation (#103) * Mainnet release v1.11.0 (#98) * Add sudo for Devnet * Dependency update to Polkadot v0.9.42 * Dependency update to Polkadot v0.9.43 * Dependency update to Polkadot v1.1.0 * Integrating metadata hash verification into runtime * Dependency update to Polkadot v1.3.0 * Lift dependencies to the workspace * Dependency update to Polkadot v1.5.0 * Add genesis builder * Dependency update to Polkadot v1.9.0 * Setup chain id for evm * Updated Devnet to Polkadot 1.9.0 * Fix chain id in chainspec * Bump spec version * Adjust base fee * Adjust base fee * Update ChainId * Remove native executor * Remove commented out code * Update chain id * Async backing phase 1 - runtime updates * Plug new lookahead collator node * Revert milisec per block * Compiling * rm .vscode * Remove unused * Remove comments and log file * Add sudo pallet * Feature/polkadot v1.11.0 (#92) * Update chain id * Compiling * rm .vscode * Remove unused * Remove comments and log file * Add sudo pallet --------- Co-authored-by: Nikola Todorovic * Move polkadot-service to mooneam implementation (#94) * Updates * version bump * version bump * version for devnet * update lock * Update chainId for testnet * Remove sudo for testnet * Update chainId for mainnet --------- Co-authored-by: Nikola Todorovic * Mainnet v1.5.1 Async Backing (#100) * Add sudo for Devnet * Dependency update to Polkadot v0.9.42 * Dependency update to Polkadot v0.9.43 * Dependency update to Polkadot v1.1.0 * Integrating metadata hash verification into runtime * Dependency update to Polkadot v1.3.0 * Lift dependencies to the workspace * Dependency update to Polkadot v1.5.0 * Add genesis builder * Dependency update to Polkadot v1.9.0 * Setup chain id for evm * Updated Devnet to Polkadot 1.9.0 * Fix chain id in chainspec * Bump spec version * Adjust base fee * Adjust base fee * Update ChainId * Remove native executor * Remove commented out code * Update chain id * Async backing phase 1 - runtime updates * Plug new lookahead collator node * Revert milisec per block * Phase 3 - Enable async backing in runtime * Compiling * rm .vscode * Remove unused * Remove comments and log file * Add sudo pallet * Move polkadot-service to mooneam implementation (#94) * Updates * version bump * version bump * Enable AB * Update spec version * Testnet release v1.11.0 (#96) * Add sudo for Devnet * Setup chain id for evm * Updated Devnet to Polkadot 1.9.0 * Adjust base fee * Update chain id * Async backing phase 1 - runtime updates * Plug new lookahead collator node * Revert milisec per block * Compiling * rm .vscode * Remove unused * Remove comments and log file * Add sudo pallet * Feature/polkadot v1.11.0 (#92) * Update chain id * Compiling * rm .vscode * Remove unused * Remove comments and log file * Add sudo pallet --------- Co-authored-by: Nikola Todorovic * Move polkadot-service to mooneam implementation (#94) * Updates * version bump * version bump * version for devnet * update lock * Update chainId for testnet * Remove sudo for testnet --------- Co-authored-by: Nikola Todorovic * Update chainId for testnet evm * remove new line --------- Co-authored-by: Nikola Todorovic * Updated call/create functions in the runtime apis * Return is_transactional and validate vars --------- Co-authored-by: Nikola Todorovic Co-authored-by: Mihajlo Pavlovic Co-authored-by: Mihajlo Pavlovic --- README.md | 1 - runtime/src/lib.rs | 107 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a224890..a8fb13b 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,6 @@ To start a relay chain we recommend reading and following instructions in [Cumul NeuroWeb is currently compatible with Polkadot v1.11.0 version. - #### Parachain Nodes (Collators) From the OriginTrail parachain working directory: diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e99e89b..9885b6d 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1456,6 +1456,8 @@ impl_runtime_apis! { estimate: bool, access_list: Option)>>, ) -> Result { + use pallet_evm::GasWeightMapping as _; + let config = if estimate { let mut config = ::config().clone(); config.estimate = true; @@ -1464,8 +1466,49 @@ impl_runtime_apis! { None }; - let is_transactional = false; + let is_transactional = false; let validate = true; + + // Estimated encoded transaction size must be based on the heaviest transaction + // type (EIP1559Transaction) to be compatible with all transaction types. + let mut estimated_transaction_len = data.len() + + // pallet ethereum index: 1 + // transact call index: 1 + // Transaction enum variant: 1 + // chain_id 8 bytes + // nonce: 32 + // max_priority_fee_per_gas: 32 + // max_fee_per_gas: 32 + // gas_limit: 32 + // action: 21 (enum varianrt + call address) + // value: 32 + // access_list: 1 (empty vec size) + // 65 bytes signature + 258; + + if access_list.is_some() { + estimated_transaction_len += access_list.encoded_size(); + } + + + let gas_limit = if gas_limit > U256::from(u64::MAX) { + u64::MAX + } else { + gas_limit.low_u64() + }; + let without_base_extrinsic_weight = true; + + let (weight_limit, proof_size_base_cost) = + match ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ) { + weight_limit if weight_limit.proof_size() > 0 => { + (Some(weight_limit), Some(estimated_transaction_len as u64)) + } + _ => (None, None), + }; + ::Runner::call( from, to, @@ -1477,11 +1520,10 @@ impl_runtime_apis! { nonce, access_list.unwrap_or_default(), is_transactional, - validate, - // TODO we probably want to support external cost recording in non-transactional calls - None, - None, - config.as_ref().unwrap_or_else(|| ::config()), + validate, + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } @@ -1496,6 +1538,8 @@ impl_runtime_apis! { estimate: bool, access_list: Option)>>, ) -> Result { + use pallet_evm::GasWeightMapping as _; + let config = if estimate { let mut config = ::config().clone(); config.estimate = true; @@ -1504,8 +1548,48 @@ impl_runtime_apis! { None }; - let is_transactional = false; + let is_transactional = false; let validate = true; + + let mut estimated_transaction_len = data.len() + + // from: 20 + // value: 32 + // gas_limit: 32 + // nonce: 32 + // 1 byte transaction action variant + // chain id 8 bytes + // 65 bytes signature + 190; + + if max_fee_per_gas.is_some() { + estimated_transaction_len += 32; + } + if max_priority_fee_per_gas.is_some() { + estimated_transaction_len += 32; + } + if access_list.is_some() { + estimated_transaction_len += access_list.encoded_size(); + } + + + let gas_limit = if gas_limit > U256::from(u64::MAX) { + u64::MAX + } else { + gas_limit.low_u64() + }; + let without_base_extrinsic_weight = true; + + let (weight_limit, proof_size_base_cost) = + match ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ) { + weight_limit if weight_limit.proof_size() > 0 => { + (Some(weight_limit), Some(estimated_transaction_len as u64)) + } + _ => (None, None), + }; + ::Runner::create( from, data, @@ -1515,12 +1599,11 @@ impl_runtime_apis! { max_priority_fee_per_gas, nonce, access_list.unwrap_or_default(), - is_transactional, + is_transactional, validate, - // TODO we probably want to support external cost recording in non-transactional calls - None, - None, - config.as_ref().unwrap_or_else(|| ::config()), + weight_limit, + proof_size_base_cost, + config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) }