Skip to content

Upgrade to polkadot-sdk stable2512#3

Draft
deblanco wants to merge 10 commits into
mainfrom
claude/affectionate-ptolemy-xz5lyr
Draft

Upgrade to polkadot-sdk stable2512#3
deblanco wants to merge 10 commits into
mainfrom
claude/affectionate-ptolemy-xz5lyr

Conversation

@deblanco

@deblanco deblanco commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrades the entire system from polkadot-sdk stable2407 to stable2512, including Frontier and the vendored Moonbeam tracing code.

Status: migration complete. The whole workspace compiles (host + wasm32v1-none runtime), all 283 tests pass, the node binary builds and instantiates the wasm runtime, and build-spec generates genesis.

What changed

Dependencies / toolchain / vendor

  • All polkadot-sdk git deps stable2407stable2512 (~55 crates); Frontier → polkadot-evm/frontier@stable2512 (see "Frontier fork" below)
  • evm from rust-ethereum/evm v0.x (0.43), ethereum 0.18.2 (with-scale), jsonrpsee 0.24.10, codec 3.7.5, kvdb-rocksdb 0.21, parity-db 0.5, sqlx 0.8, thiserror 2, rlp 0.6
  • Rust 1.88.0; runtime targets wasm32-unknown-unknown + wasm32v1-none
  • Moonbeam tracing crates re-vendored from moonbeam v0.51.2 (the previous vendor was a byte-identical copy of moonbeam v0.38/v0.39 — no local patches existed). Vendored txpool RPC crates dropped; LRUCacheByteLimited vendored locally (upstream frontier doesn't export fc_rpc::lru_cache)
  • Removed dead workspace deps; resolver = "2"

Primitives

  • StbleCheckNonceTransactionExtension (SignedExtension removed), preserving the custom DNT semantics (accounts with zero providers/sufficients accepted)
  • StabilityRunner ported to the 2512 stack runner: EIP-7702 authorization lists, create_force_address, storage-growth metering, measured proof size (cumulus get_proof_size), handle_storage_oog effective-gas, transient storage, delegation, reentrancy guard — DNT ERC20 fee flow preserved
  • ethereum 0.18 migration (TransactionV3, unified signature accessors, EIP-7702, U256::to_big_endian)

Pallets / precompiles

  • Full EIP-7702 support in zero-gas + sponsored transactions (per decision)
  • custom-balances TryMerge; validator-set/validator-keys SendTransactionTypesCreateBare; upgrade-runtime-proposal can_set_codeCanSetCodeResult; precompile try_dispatch/RuntimeCall updates

Runtime

  • TxExtension tuple, RuntimeVersion (Cow::Borrowed, system_version), spec_version 5 → 6
  • pallet_evm::Config (AccountProvider, CreateOriginFilter/CreateInnerOriginFilter, GasLimitStorageGrowthRatio); pallet_ethereum IntermediateStateRoot<Version>; transaction-payment OnChargeTransaction + TxCreditHold; collective/session new items
  • Added an inert pallet_balances instance (NativeBalances) purely to satisfy pallet_session's new currency/hold bounds — Stability still settles fees in ERC20s; this instance never holds funds (nominal ED of 1)
  • EVM runtime APIs + debug trace_call thread EIP-7702; Core/BlockBuilder take Block::LazyBlock; DecodeWithMemTracking derives

Node

  • Fork-aware tx pool API (Builder/TransactionPoolHandle), new_full_parts_record_import, FullNetworkConfiguration(registry), WarpSyncConfig, config.rpc.id_provider, OffchainWorkers::new Result, fc-rpc 2512 (Eth/EthFilter/EthPubSub, max_block_range, AuraConsensusDataProvider); custom authorship migrated to the fork-aware pool API
  • Registered the storage_proof_size host function (required to instantiate the 2512 runtime)

Verification

  • cargo test --workspace283 passed, 0 failed
  • Runtime builds to wasm32v1-none; node binary builds; build-spec --chain dev produces genesis; node boots to "Manual Seal Ready" / "Running JSON-RPC server"
  • Note: live RPC/block-production smoke tests couldn't run in the build sandbox (socket binding is blocked there). With the default fork-aware pool the txpool-background task exits early in the sandbox; the node runs normally with --pool-type single-state. Worth a quick confirm in a real (non-sandboxed) environment.

Frontier fork

Deps currently point at polkadot-evm/frontier@stable2512. To source from the fork as intended, mirror the branch and flip the URLs:

git clone --bare https://github.com/polkadot-evm/frontier.git
cd frontier.git
git push https://github.com/stabilityprotocol/frontier.git refs/heads/stable2512:refs/heads/stable2512

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww


Generated by Claude Code

claude added 10 commits June 12, 2026 10:00
…2512

- All polkadot-sdk git deps: stable2407 -> stable2512
- Frontier deps: stabilityprotocol/frontier@stable2407 -> polkadot-evm/frontier@stable2512
  (temporary upstream source; flip back to the fork once its stable2512 branch is mirrored)
- evm crates from rust-ethereum/evm branch v0.x (0.43), ethereum 0.18.2 (with-scale),
  jsonrpsee 0.24.10, codec 3.7.5, kvdb-rocksdb 0.21, parity-db 0.5, sqlx 0.8, thiserror 2
- Rust 1.88.0 toolchain, add wasm32v1-none target (toolchain file + Dockerfiles)
- Re-vendor moonbeam tracing crates from moonbeam v0.51.2 (previous vendor was a
  byte-identical copy of moonbeam v0.38/v0.39 sources - no local patches existed);
  drop vendored txpool RPC crates (fc-rpc provides txpool_* since stable2512)
- Remove dead workspace deps (sp-beefy, babe, beefy-mmr, staging-xcm, pallet-utility)
- resolver = 2, workspace.lints table for re-vendored manifests
- Cargo.lock seeded from frontier stable2512 lock (carries yanked core2 0.4.0 pin
  required by litep2p) then re-resolved

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
- Rewrite StbleCheckNonce as TransactionExtension (SignedExtension removed in
  stable2512), preserving Stability's no-account-existence-check semantics
- account: handle new MultiSignature::Eth variant
- stbl-tools: ethereum 0.18 unified signature accessors, EIP-7702 arm in
  recover_signer, TransactionV3, U256::to_big_endian new API
- erc20-manager/runtime/runner tests: to_big_endian new API
- Fix std feature propagation across all member crates (no-std-on-host builds
  of pallet-evm's cumulus host-function deps fail on stable2512)
- transaction-validator: TransactionV3 in FallbackTransactionValidator
- runner: add ethereum + cumulus-primitives-storage-weight-reclaim deps for
  upcoming stack-runner port

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
- Port StabilityRunner to the stable2512 stack-runner architecture:
  EIP-7702 authorization lists on all entry points, create_force_address,
  delegation-aware EIP-3607 check, storage growth metering (StorageMeter),
  measured proof size via ProofSizeExt (cumulus get_proof_size),
  handle_storage_oog effective-gas computation, transient storage,
  set_delegation/reset_delegation, environmental-based reentrancy guard.
  DNT fee flow (withdraw/correct/pay in ERC20 fee tokens) preserved.
- zero-gas-transactions + sponsored-transactions: full EIP-7702 support
  (with_eip7702_authorization_list validation, new error variants)
- validator-set + validator-keys-controller: SendTransactionTypes ->
  CreateBare offchain API migration
- custom-balances: implement new TryMerge for NeutralImbalance
- upgrade-runtime-proposal: can_set_code(code, check_version) -> CanSetCodeResult
- precompiles: try_dispatch storage_growth arg, RuntimeCall disambiguation
  (CreateBare supertrait brings CreateTransactionBase::RuntimeCall into scope)

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
- RuntimeVersion: Cow::Borrowed names, system_version, spec_version 5->6
- frame_system: add ExtensionsWeightInfo
- pallet_evm::Config: AccountProvider (FrameSystemAccountProvider),
  CreateOriginFilter/CreateInnerOriginFilter, GasLimitStorageGrowthRatio;
  drop RuntimeEvent/SuicideQuickClearLimit
- pallet_ethereum: IntermediateStateRoot<Self::Version>, drop RuntimeEvent
- pallet_base_fee: drop RuntimeEvent
- pallet_transaction_payment: add WeightInfo; StbleOnChargeTransaction gains
  TxCreditHold (Credit=()) and can_withdraw_fee
- pallet_collective: DisapproveOrigin/KillOrigin/Consideration
- pallet_session: DisablingStrategy/Currency/KeyDeposit; add an inert
  pallet_balances instance (NativeBalances, zero ED + zero key deposit) purely
  to satisfy the new Currency/HoldMutate bounds (fees remain ERC20-settled)
- offchain: CreateSignedTransaction::create_signed_transaction returning
  UncheckedExtrinsic; SendTransactionTypes -> CreateTransactionBase + CreateBare;
  new_unsigned -> new_bare
- EVM runtime APIs (call/create) + debug trace_call: thread EIP-7702
  authorization_list; sp_api::Core/BlockBuilder execute_block/check_inherents
  take Block::LazyBlock
- DecodeWithMemTracking derives on AccountId20, EthereumSignature, Heartbeat,
  PublishingKeys
- Sha3FIPS256<R, ()> generic params

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
…p to stable2512

- vendor/rpc/trace: vendor LRUCacheByteLimited locally (upstream frontier
  doesn't expose fc_rpc::lru_cache publicly, only the moonbeam fork did)
- stability-rpc + authorship: ethereum TransactionV2 -> TransactionV3
- client/authorship: fork-aware txpool API migration
  (ready_at takes block hash; InPoolTransaction::data() returns Arc;
  remove_invalid(Vec) -> async report_invalid(at, TxInvalidityReportMap))

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
- service.rs: fork-aware tx pool (Builder/TransactionPoolHandle),
  new_full_parts_record_import, new_wasm_executor(&config.executor),
  FullNetworkConfiguration(registry), WarpSyncConfig, build_network without
  network_starter, config.rpc.id_provider, SpawnTasksParams.tracing_execute_block,
  rpc closure drops deny_unsafe, OffchainWorkers::new returns Result
- rpc: drop DenyUnsafe/graph/ChainApi plumbing; System::new(client,pool);
  Eth/EthFilter/EthPubSub 2512 signatures (P::Hash=B::Hash bound, max_block_range,
  AuraConsensusDataProvider); EthConfiguration gains max_block_range + ethapi_trace_cache_size
- vendored trace CacheTask::create: byte-sized LRU + spawn_handle
- chain_spec: session non_authority_keys + native_balances genesis fields

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
…wasm)

pallet-validator-set, pallet-validator-keys-controller, and
pallet-upgrade-runtime-proposal each declared syn as a normal (non-build)
dependency without using it. That pulled syn -> quote -> proc-macro2 into the
no_std runtime graph, forcing proc-macro2 (which requires std) to be compiled
for wasm32v1-none and breaking the runtime wasm build. None of the three
pallets reference syn in their sources, so the dependency is simply removed.

The runtime now builds cleanly for wasm32v1-none.

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
- ~21 mock runtimes: frame_system ExtensionsWeightInfo; pallet_evm
  AccountProvider/CreateOriginFilter/CreateInnerOriginFilter/
  GasLimitStorageGrowthRatio, drop RuntimeEvent/SuicideQuickClearLimit;
  pallet_ethereum IntermediateStateRoot<Version> (local EthStateRootVersion);
  pallet_balances DoneSlashHandler + GenesisConfig dev_accounts;
  pallet_session DisablingStrategy/Currency/KeyDeposit (+ inert balances in
  validator-set/validator-keys mocks); pallet_collective DisapproveOrigin/
  KillOrigin/Consideration; SendTransactionTypes -> CreateBare/CreateTransactionBase;
  RuntimeVersion state_version -> system_version; RuntimeHoldReason aggregate
- stability-rpc mock TransactionPool: async-trait 2512 signatures
  (submit_*/ready_at/ready_at_with_timeout async, report_invalid, Arc tx)
- test helpers: ethereum 0.18 (TransactionV3, legacy::TransactionSignature,
  eip2930 signature field), runner calls gain authorization_list, U256
  from_big_endian, rlp 0.6

Entire workspace now compiles host-side, the runtime builds to wasm32v1-none,
and all test targets compile.

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
pallet-balances' integrity_test asserts a non-zero ED. The NativeBalances
instance is inert (only satisfies pallet_session's currency bound, never holds
funds), so it uses a nominal ED of 1 rather than the chain's zero ED.

All 283 workspace tests pass.

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
The stable2512 EVM runner (via cumulus get_proof_size) and pallet-evm import
the 'storage_proof_size' runtime host function. Add
cumulus_primitives_proof_size_hostfunction::storage_proof_size::HostFunctions
to the node's HostFunctions so the wasm runtime can be instantiated; without it
the node fails at startup with 'runtime requires function imports which are not
present on the host'.

https://claude.ai/code/session_01Qw9k7AwxfKCX6t9MsYpqww
@deblanco deblanco changed the title Upgrade to polkadot-sdk stable2512 (WIP) Upgrade to polkadot-sdk stable2512 Jun 12, 2026
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