Skip to content

WIP: pallet-revive: Raise contract size limit to one megabyte and raise call depth to 25 #9267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

athei
Copy link
Member

@athei athei commented Jul 18, 2025

This PR changes the contract code limit from roughly 100KiB to exactly 1MiB. It also raises the call stack depth from 5 to 25.

Those limits were in place because of memory constraints within the runtime. We work around them in those ways:

  1. Removing the 4x safety margin for allocations which is no longer needed due to the new allocator.
  2. Limiting the size of the compilation cache to a fixed size.
  3. Resetting the compilation cache and flat map every time we call into a new contract.
  4. Limiting the size of calldata and return data to 128KiB (only capped by tx size and RAM before). While this is a breaking change nobody will be affected since Geth effectively limits the call data to 128KiB.

1MiB contracts

This is large enough so that all known contracts won't fail for size issues anymore.

The new limit is also much simpler to understand since it does not depend on the number of instructions. Just those two constraints:

PVM_BLOB.len() < 1 MiB
PVM_BLOB.len() + (rw/ro/stack) < 1MiB + 512KiB

This means:

  1. A contract is guaranteed to have at least 512KiB of memory available.
  2. A contract that is smaller in code can use more memory.
  3. Limit is exactly 1MiB unless a user manually increase the memory usage of a contract to be larger than 512KiB.

Call stack depth 5 -> 25

The limit of 5 was problematic because there are use cases which require deeper stacks. With the raise to 25 there should be no benign use cases anymore that won't work.

Please note that even with the low limit of 25 contracts are not vulnerable to stack depth exhaustion attacks: We do trap the caller's context when the depth limit is reached. This is different from Eth where this error can be handled and failure to do so leaves the contract vulnerable.

TODO

We are still missing the actual things that make those bigger contracts possible. However, all the calculations are in place.

@paritytech-workflow-stopper
Copy link

All GitHub workflows were cancelled due to failure one of the required jobs.
Failed workflow url: https://github.com/paritytech/polkadot-sdk/actions/runs/16373373170
Failed job name: build-rustdoc

@athei
Copy link
Member Author

athei commented Jul 20, 2025

/cmd bench --runtime dev --pallet pallet_revive

Copy link
Contributor

Command "bench --runtime dev --pallet pallet_revive" has started 🚀 See logs here

@athei athei requested review from xermicus, pgherveou and koute and removed request for xermicus July 20, 2025 07:44
Copy link
Contributor

Command "bench --runtime dev --pallet pallet_revive" has finished ✅ See logs here

Subweight results:
File Extrinsic Old New Change [%]
substrate/frame/revive/src/weights.rs instr 1.20ms 1.64ms +36.95
substrate/frame/revive/src/weights.rs identity 117.21us 158.45us +35.18
substrate/frame/revive/src/weights.rs seal_call_data_copy 119.70us 158.59us +32.49
substrate/frame/revive/src/weights.rs seal_ref_time_left 227.00ns 289.00ns +27.31
substrate/frame/revive/src/weights.rs seal_block_number 246.00ns 306.00ns +24.39
substrate/frame/revive/src/weights.rs seal_copy_to_contract 210.35us 252.04us +19.82
substrate/frame/revive/src/weights.rs seal_return 53.10us 63.06us +18.75
substrate/frame/revive/src/weights.rs seal_return_data_size 253.00ns 297.00ns +17.39
substrate/frame/revive/src/weights.rs seal_value_transferred 273.00ns 320.00ns +17.22
substrate/frame/revive/src/weights.rs seal_call_data_size 248.00ns 288.00ns +16.13
substrate/frame/revive/src/weights.rs seal_call_data_load 250.00ns 285.00ns +14.00
substrate/frame/revive/src/weights.rs seal_own_code_hash 279.00ns 318.00ns +13.98
substrate/frame/revive/src/weights.rs seal_address 290.00ns 329.00ns +13.45
substrate/frame/revive/src/weights.rs seal_minimum_balance 264.00ns 298.00ns +12.88
substrate/frame/revive/src/weights.rs seal_base_fee 256.00ns 284.00ns +10.94
substrate/frame/revive/src/weights.rs instantiate_with_code 4.11ms 4.55ms +10.61
substrate/frame/revive/src/weights.rs call_with_code_per_byte 641.99us 693.26us +7.99
substrate/frame/revive/src/weights.rs seal_caller 330.00ns 355.00ns +7.58
substrate/frame/revive/src/weights.rs seal_take_transient_storage 2.66us 2.85us +7.50
substrate/frame/revive/src/weights.rs seal_call_precompile 256.36us 274.85us +7.21
substrate/frame/revive/src/weights.rs seal_caller_is_origin 331.00ns 352.00ns +6.34
substrate/frame/revive/src/weights.rs seal_contains_transient_storage 1.86us 1.98us +6.27
substrate/frame/revive/src/weights.rs seal_set_transient_storage 2.59us 2.74us +5.88
substrate/frame/revive/src/weights.rs seal_gas_price 258.00ns 273.00ns +5.81
substrate/frame/revive/src/weights.rs seal_clear_transient_storage 2.43us 2.57us +5.74
substrate/frame/revive/src/weights.rs seal_weight_left 668.00ns 702.00ns +5.09
substrate/frame/revive/src/weights.rs rollback_transient_storage 1.15us 1.21us +5.04
substrate/frame/revive/src/weights.rs seal_get_transient_storage 2.11us 2.22us +5.03
substrate/frame/revive/src/weights.rs seal_balance 5.28us 4.68us -11.22
Command output:

✅ Successful benchmarks of runtimes/pallets:
-- dev: ['pallet_revive']

@@ -46,6 +51,9 @@ pub const NUM_EVENT_TOPICS: u32 = 4;
/// Maximum size of events (including topics) and storage values.
pub const PAYLOAD_BYTES: u32 = 416;

/// The maximum size for calldata and return data.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC this value matches the current practical limit on Ethereum. Might point that out here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants