Skip to content

Commit 3f3fbb8

Browse files
Wasm upgrade (#1345)
* targeted codesubstitute for fees * update blob with current release chain spec * latest spec * 473 * update wasm * release 4.7.4 * add logging for test * add codesub * update chain spec * get clippy green * update
1 parent 141760a commit 3f3fbb8

File tree

13 files changed

+416
-19925
lines changed

13 files changed

+416
-19925
lines changed

Cargo.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

node/Cargo.toml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "framenode"
3-
version = "4.7.1"
3+
version = "4.7.5"
44
authors = ["Parity Technologies <admin@parity.io>"]
55
build = "build.rs"
66
edition = "2021"
@@ -111,6 +111,11 @@ tokio = "=1.40.0"
111111
finality-grandpa = "=0.16.2"
112112
pest = "=2.7.14"
113113

114+
[target.'cfg(target_os = "linux")'.dependencies]
115+
# Netlink-based watchers rely on Linux-specific libc types; keep them off macOS builds.
116+
if-watch = "=3.2.0"
117+
netlink-proto = "=0.10.0"
118+
114119
[build-dependencies]
115120
substrate-build-script-utils = "3"
116121

node/chain_spec/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "framenode-chain-spec"
3-
version = "4.7.0"
3+
version = "4.7.5"
44
authors = ["Parity Technologies <admin@parity.io>"]
55
edition = "2021"
66

@@ -33,6 +33,8 @@ xor-fee = { path = "../../pallets/xor-fee" }
3333

3434
[dev-dependencies]
3535
common = { path = "../../common", features = ["test"] }
36+
hex = "0.4"
37+
serde_json = "1"
3638

3739
[features]
3840
include-real-files = []

node/chain_spec/src/bytes/chain_spec_bridge_staging.json

Lines changed: 224 additions & 19904 deletions
Large diffs are not rendered by default.

node/chain_spec/src/bytes/chain_spec_main.json

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

node/chain_spec/src/bytes/chain_spec_test.json

Lines changed: 47 additions & 6 deletions
Large diffs are not rendered by default.

node/chain_spec/src/lib.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2890,6 +2890,10 @@ mod tests {
28902890

28912891
use common::eth::EthAddress;
28922892
use common::{balance, Balance};
2893+
#[cfg(not(feature = "private-net"))]
2894+
use serde_json::Value;
2895+
#[cfg(not(feature = "private-net"))]
2896+
use sp_core::blake2_256;
28932897

28942898
#[test]
28952899
fn calculate_reserves() {
@@ -2912,4 +2916,46 @@ mod tests {
29122916
balance!(123.45678)
29132917
);
29142918
}
2919+
2920+
#[cfg(not(feature = "private-net"))]
2921+
#[test]
2922+
fn mainnet_code_substitute_matches_expected_wasm() {
2923+
// The live chain is upgraded via codeSubstitutes, so we verify the embedded JSON still
2924+
// carries the correct Wasm blob for the emergency fork height.
2925+
let raw_spec = include_str!("./bytes/chain_spec_main.json");
2926+
let json: Value = serde_json::from_str(raw_spec).expect("parse mainnet spec json");
2927+
let code_substitutes = json
2928+
.get("codeSubstitutes")
2929+
.and_then(Value::as_object)
2930+
.expect("codeSubstitutes object missing");
2931+
let wasm_hex = code_substitutes
2932+
.get("23234813")
2933+
.and_then(Value::as_str)
2934+
.expect("missing codeSubstitute for block 23234813");
2935+
let wasm_bytes = hex::decode(wasm_hex.trim_start_matches("0x"))
2936+
.expect("codeSubstitutes entry must be valid hex");
2937+
assert_eq!(
2938+
blake2_256(&wasm_bytes),
2939+
hex!("311d77b61faf6950680f520333e2c8af5ad3155f0d3e60ec9439fcf2bbceef3e"),
2940+
"unexpected Wasm hash for 23234813 code substitute"
2941+
);
2942+
}
2943+
2944+
#[cfg(not(feature = "private-net"))]
2945+
#[test]
2946+
fn mainnet_code_substitute_has_expected_wasm_size() {
2947+
let raw_spec = include_str!("./bytes/chain_spec_main.json");
2948+
let json: Value = serde_json::from_str(raw_spec).expect("parse mainnet spec json");
2949+
let code_substitutes = json
2950+
.get("codeSubstitutes")
2951+
.and_then(Value::as_object)
2952+
.expect("codeSubstitutes object missing");
2953+
let wasm_hex = code_substitutes
2954+
.get("23234813")
2955+
.and_then(Value::as_str)
2956+
.expect("missing codeSubstitute for block 23234813");
2957+
let wasm_bytes = hex::decode(wasm_hex.trim_start_matches("0x"))
2958+
.expect("codeSubstitutes entry must be valid hex");
2959+
assert_eq!(wasm_bytes.len(), 2_815_465);
2960+
}
29152961
}

node/src/service.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use framenode_runtime::opaque::Block;
4141
use framenode_runtime::{self, Runtime, RuntimeApi};
4242
use log::debug;
4343
use prometheus_endpoint::Registry;
44-
use sc_client_api::{Backend, BlockBackend};
44+
use sc_client_api::{execution_extensions::ExecutionStrategy, Backend, BlockBackend};
4545
use sc_consensus_aura::SlotDuration;
4646
pub use sc_executor::NativeElseWasmExecutor;
4747
use sc_service::config::PrometheusConfig;
@@ -125,6 +125,26 @@ pub fn new_partial(
125125
)));
126126
}
127127
set_prometheus_registry(config)?;
128+
// Force wasm execution paths when users rely on code substitutes while keeping the on-chain
129+
// spec version unchanged. Native execution would otherwise run the embedded runtime (with the
130+
// post-fix logic) against historical blocks that expect the old code, causing storage root
131+
// mismatches. Honour any explicit `--execution` flags by only overriding non-wasm defaults.
132+
let strategies = &mut config.execution_strategies;
133+
if !matches!(strategies.syncing, ExecutionStrategy::AlwaysWasm) {
134+
strategies.syncing = ExecutionStrategy::AlwaysWasm;
135+
}
136+
if !matches!(strategies.importing, ExecutionStrategy::AlwaysWasm) {
137+
strategies.importing = ExecutionStrategy::AlwaysWasm;
138+
}
139+
if !matches!(strategies.block_construction, ExecutionStrategy::AlwaysWasm) {
140+
strategies.block_construction = ExecutionStrategy::AlwaysWasm;
141+
}
142+
if !matches!(strategies.offchain_worker, ExecutionStrategy::AlwaysWasm) {
143+
strategies.offchain_worker = ExecutionStrategy::AlwaysWasm;
144+
}
145+
if !matches!(strategies.other, ExecutionStrategy::AlwaysWasm) {
146+
strategies.other = ExecutionStrategy::AlwaysWasm;
147+
}
128148

129149
let telemetry = config
130150
.telemetry_endpoints

pallets/xor-fee/src/mock.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ use common::{
4747
LiquidityProxyTrait, LiquiditySourceFilter, LiquiditySourceType, OnValBurned,
4848
ReferrerAccountProvider, KUSD, PSWAP, TBCD, VAL, XOR,
4949
};
50-
use sp_arithmetic::FixedU128;
51-
5250
use currencies::BasicCurrencyAdapter;
5351
use frame_support::dispatch::{DispatchInfo, Pays, PostDispatchInfo};
5452
use frame_support::pallet_prelude::{Hooks, ValueQuery};
@@ -60,6 +58,7 @@ use frame_support::{construct_runtime, parameter_types, storage_alias};
6058
use frame_system::pallet_prelude::BlockNumberFor;
6159
use frame_system::EnsureRoot;
6260
use permissions::{Scope, BURN, MINT};
61+
use sp_arithmetic::FixedU128;
6362
use sp_core::H256;
6463
use sp_runtime::{AccountId32, DispatchError, Percent};
6564
use traits::MultiCurrency;

pallets/xor-fee/src/tests.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,55 @@ fn non_root_update_fails() {
139139
});
140140
}
141141

142+
#[test]
143+
fn fees_remain_stable_on_codesub_block_without_forced_override() {
144+
// This block matches mainnet codeSubstitute activation height.
145+
const CODESUB_BLOCK: u64 = 23_234_813;
146+
147+
ExtBuilder::build().execute_with(|| {
148+
set_weight_to_fee_multiplier(2);
149+
System::set_block_number(CODESUB_BLOCK - 1);
150+
151+
let tracked_call = RuntimeCall::Assets(assets::Call::transfer {
152+
to: alice(),
153+
asset_id: common::VAL,
154+
amount: 10,
155+
});
156+
let tracked_info = info_from_weight(100.into());
157+
let tracked_len = 100;
158+
159+
let (fee_before, _) = XorFee::compute_fee(tracked_len, &tracked_call, &tracked_info, 0);
160+
assert_eq!(fee_before, balance!(0.0014));
161+
162+
let multiplier_events_before = System::events()
163+
.iter()
164+
.filter(|record| {
165+
matches!(
166+
&record.event,
167+
RuntimeEvent::XorFee(crate::Event::WeightToFeeMultiplierUpdated(_))
168+
)
169+
})
170+
.count();
171+
172+
run_to_block(CODESUB_BLOCK);
173+
174+
assert_eq!(XorFee::multiplier(), FixedU128::saturating_from_integer(2));
175+
let (fee_after, _) = XorFee::compute_fee(tracked_len, &tracked_call, &tracked_info, 0);
176+
assert_eq!(fee_after, fee_before);
177+
178+
let multiplier_events_after = System::events()
179+
.iter()
180+
.filter(|record| {
181+
matches!(
182+
&record.event,
183+
RuntimeEvent::XorFee(crate::Event::WeightToFeeMultiplierUpdated(_))
184+
)
185+
})
186+
.count();
187+
assert_eq!(multiplier_events_before, multiplier_events_after);
188+
});
189+
}
190+
142191
#[test]
143192
fn it_works_postpone() {
144193
ExtBuilder::build().execute_with(|| {

0 commit comments

Comments
 (0)