Skip to content

Commit f919b7a

Browse files
ismp weight base fee handler (#474)
Co-authored-by: Seun Lanlege <seun@polytope.technology>
1 parent daef340 commit f919b7a

File tree

37 files changed

+703
-452
lines changed

37 files changed

+703
-452
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ members = [
8585
# Utilities
8686
"modules/utils/subxt",
8787
"modules/utils/serde",
88+
"modules/utils/crypto",
8889

8990
# tesseract
9091
"tesseract/messaging/primitives",
@@ -148,6 +149,7 @@ strip = true
148149
polkadot-sdk = { version = "=2506.0.0", default-features = false }
149150

150151
# crates that can't be used in polkadot-sdk
152+
sp-weights = { version = "32.0.0", default-features = false }
151153
sp-core = { version = "37.0.0", default-features = false }
152154
frame-benchmarking = { version = "41.0.0", default-features = false }
153155
sp-io = { version = "41.0.0", default-features = false }
@@ -213,6 +215,7 @@ ics23 = { version = "0.12.0", default-features = false }
213215
# published crates
214216
ismp = { version = "1.2.0", path = "./modules/ismp/core", default-features = false }
215217
serde-hex-utils = { version = "0.1.0", path = "modules/utils/serde", default-features = false }
218+
crypto-utils = { path = "modules/utils/crypto", default-features = false }
216219
grandpa-verifier-primitives = { version = "2.1.0", path = "./modules/consensus/grandpa/primitives", default-features = false }
217220
grandpa-verifier = { version = "2.1.0", path = "./modules/consensus/grandpa/verifier", default-features = false }
218221
ismp-grandpa = { version = "2506.0.0", path = "./modules/ismp/clients/grandpa", default-features = false }
@@ -365,4 +368,4 @@ features = ["derive"]
365368

366369
[workspace.dependencies.reconnecting-jsonrpsee-ws-client]
367370
version = "0.5.0"
368-
default-features = false
371+
default-features = false

modules/ismp/core/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ hex = { workspace = true, features = ["alloc"] }
3131
anyhow = { workspace = true, default-features = false }
3232
thiserror = { workspace = true }
3333
serde-hex-utils = { workspace = true, default-features = false }
34+
sp-weights = {workspace = true, default-features = false}
3435

3536
[features]
3637
default = ["std"]
@@ -46,4 +47,5 @@ std = [
4647
"thiserror/std",
4748
"displaydoc/std",
4849
"anyhow/std",
49-
]
50+
"sp-weights/std"
51+
]

modules/ismp/core/src/handlers.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::{
2525
use crate::{consensus::ConsensusStateId, module::DispatchResult};
2626
use alloc::{boxed::Box, vec::Vec};
2727
pub use consensus::create_client;
28+
use sp_weights::Weight;
2829

2930
mod consensus;
3031
mod request;
@@ -46,12 +47,39 @@ pub enum MessageResult {
4647
ConsensusMessage(Vec<Event>),
4748
/// Result of freezing a consensus state.
4849
FrozenClient(ConsensusStateId),
49-
/// The [`DispatchResult`] for requests
50-
Request(Vec<DispatchResult>),
51-
/// The [`DispatchResult`] for responses
52-
Response(Vec<DispatchResult>),
53-
/// The [`DispatchResult`] for timeouts
54-
Timeout(Vec<DispatchResult>),
50+
/// The result of processing a batch of requests.
51+
Request {
52+
/// A Vec containing the results of each individual request dispatch.
53+
events: Vec<DispatchResult>,
54+
/// The total weight consumed by all module `on_accept` calls for this batch.
55+
weight: Weight,
56+
},
57+
/// The result of processing a batch of responses.
58+
Response {
59+
/// A Vec containing the results of each individual response dispatch.
60+
events: Vec<DispatchResult>,
61+
/// The total weight consumed by all module `on_accept` calls for this batch.
62+
weight: Weight,
63+
},
64+
/// The result of processing a timeouts.
65+
Timeout {
66+
/// A Vec containing the results of each individual response dispatch.
67+
events: Vec<DispatchResult>,
68+
/// The total weight consumed by all module `on_accept` calls for this batch.
69+
weight: Weight,
70+
},
71+
}
72+
73+
impl MessageResult {
74+
/// Returns the total weight consumed by this message
75+
pub fn weight(&self) -> Weight {
76+
match self {
77+
MessageResult::Request { weight, .. } => *weight,
78+
MessageResult::Response { weight, .. } => *weight,
79+
MessageResult::Timeout { weight, .. } => *weight,
80+
MessageResult::ConsensusMessage(_) | MessageResult::FrozenClient(_) => Weight::zero(),
81+
}
82+
}
5583
}
5684

5785
/// This function serves as an entry point to handle the message types provided by the ISMP protocol

modules/ismp/core/src/handlers/request.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::{
2424
router::{Request, RequestResponse},
2525
};
2626
use alloc::vec::Vec;
27+
use sp_weights::Weight;
2728

2829
/// Validate the state machine, verify the request message and dispatch the message to the modules
2930
pub fn handle<H>(host: &H, msg: RequestMessage) -> Result<MessageResult, anyhow::Error>
@@ -81,16 +82,19 @@ where
8182
&msg.proof,
8283
)?;
8384

85+
let mut total_weights = Weight::zero();
8486
let result = msg
8587
.requests
8688
.into_iter()
8789
.map(|request| {
8890
let wrapped_req = Request::Post(request.clone());
89-
let lambda = || {
91+
let mut lambda = || {
9092
let cb = router.module_for_id(request.to.clone())?;
9193
// Store request receipt to prevent reentrancy attack
9294
host.store_request_receipt(&wrapped_req, &msg.signer)?;
93-
let res = cb.on_accept(request.clone()).map(|_| {
95+
let res = cb.on_accept(request.clone()).map(|weight| {
96+
total_weights.saturating_accrue(weight);
97+
9498
let commitment = hash_request::<H>(&wrapped_req);
9599
Event::PostRequestHandled(RequestResponseHandled {
96100
commitment,
@@ -109,5 +113,5 @@ where
109113
})
110114
.collect::<Vec<_>>();
111115

112-
Ok(MessageResult::Request(result))
116+
Ok(MessageResult::Request { events: result, weight: total_weights })
113117
}

modules/ismp/core/src/handlers/response.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::{
2424
router::{GetResponse, Request, RequestResponse, Response, StorageValue},
2525
};
2626
use alloc::{vec, vec::Vec};
27+
use sp_weights::Weight;
2728

2829
/// Validate the state machine, verify the response message and dispatch the message to the modules
2930
pub fn handle<H>(host: &H, msg: ResponseMessage) -> Result<MessageResult, anyhow::Error>
@@ -44,6 +45,7 @@ where
4445
.is_none()
4546
};
4647

48+
let mut total_weights = Weight::zero();
4749
let result = match &msg.datagram {
4850
RequestResponse::Response(responses) => {
4951
for response in responses.iter() {
@@ -91,7 +93,8 @@ where
9193
let cb = router.module_for_id(response.destination_module())?;
9294
// Store response receipt to prevent reentrancy attack
9395
host.store_response_receipt(&response, &msg.signer)?;
94-
let res = cb.on_response(response.clone()).map(|_| {
96+
let res = cb.on_response(response.clone()).map(|weight| {
97+
total_weights.saturating_accrue(weight);
9598
let commitment = hash_response::<H>(&response);
9699
Event::PostResponseHandled(RequestResponseHandled {
97100
commitment,
@@ -164,7 +167,8 @@ where
164167
host.store_response_receipt(&response, &msg.signer)?;
165168
let res = cb
166169
.on_response(Response::Get(GetResponse { get: request.clone(), values }))
167-
.map(|_| {
170+
.map(|weight| {
171+
total_weights.saturating_accrue(weight);
168172
let commitment = hash_request::<H>(&wrapped_req);
169173
Event::GetRequestHandled(RequestResponseHandled {
170174
commitment,
@@ -181,5 +185,5 @@ where
181185
},
182186
};
183187

184-
Ok(MessageResult::Response(result))
188+
Ok(MessageResult::Response { events: result, weight: total_weights })
185189
}

modules/ismp/core/src/handlers/timeout.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::{
2424
router::Response,
2525
};
2626
use alloc::vec::Vec;
27+
use sp_weights::Weight;
2728

2829
/// This function handles timeouts
2930
pub fn handle<H>(host: &H, msg: TimeoutMessage) -> Result<MessageResult, anyhow::Error>
@@ -38,6 +39,7 @@ where
3839
.find_map(|client| client.state_machine(state_machine).ok())
3940
.is_none()
4041
};
42+
let mut total_module_weight = Weight::zero();
4143

4244
let results = match msg {
4345
TimeoutMessage::Post { requests, timeout_proof } => {
@@ -90,7 +92,8 @@ where
9092
if host.host_state_machine() != request.source_chain() {
9193
signer = host.delete_request_receipt(&request).ok();
9294
}
93-
let res = cb.on_timeout(request.clone().into()).map(|_| {
95+
let res = cb.on_timeout(request.clone().into()).map(|weight| {
96+
total_module_weight.saturating_accrue(weight);
9497
let commitment = hash_request::<H>(&request);
9598
Event::PostRequestTimeoutHandled(TimeoutHandled {
9699
commitment,
@@ -163,7 +166,8 @@ where
163166
signer =
164167
host.delete_response_receipt(&Response::Post(response.clone())).ok();
165168
}
166-
let res = cb.on_timeout(response.clone().into()).map(|_| {
169+
let res = cb.on_timeout(response.clone().into()).map(|weight| {
170+
total_module_weight.saturating_accrue(weight);
167171
let commitment = hash_post_response::<H>(&response);
168172
Event::PostResponseTimeoutHandled(TimeoutHandled {
169173
commitment,
@@ -211,7 +215,8 @@ where
211215
let cb = router.module_for_id(request.source_module())?;
212216
// Delete commitment to prevent reentrancy
213217
let meta = host.delete_request_commitment(&request)?;
214-
let res = cb.on_timeout(request.clone().into()).map(|_| {
218+
let res = cb.on_timeout(request.clone().into()).map(|weight| {
219+
total_module_weight.saturating_accrue(weight);
215220
let commitment = hash_request::<H>(&request);
216221
Event::GetRequestTimeoutHandled(TimeoutHandled {
217222
commitment,
@@ -229,5 +234,5 @@ where
229234
},
230235
};
231236

232-
Ok(MessageResult::Timeout(results))
237+
Ok(MessageResult::Timeout { events: results, weight: total_module_weight })
233238
}

modules/ismp/core/src/messaging.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use crate::{
3030
};
3131
use alloc::{string::ToString, vec::Vec};
3232
use codec::{Decode, DecodeWithMemTracking, Encode};
33+
use sp_weights::Weight;
3334
use primitive_types::H256;
3435

3536
/// A consensus message is used to update the state of a consensus client and its children state
@@ -234,6 +235,17 @@ pub enum Message {
234235
Timeout(TimeoutMessage),
235236
}
236237

238+
/// The ISMP Message with Weight consumed by the message
239+
#[derive(
240+
Debug, Clone, Encode, Decode, DecodeWithMemTracking, scale_info::TypeInfo, PartialEq, Eq,
241+
)]
242+
pub struct MessageWithWeight {
243+
/// The message itself
244+
pub message: Message,
245+
/// The weight consumed by the message
246+
pub weight: Weight,
247+
}
248+
237249
/// A trait that returns a 256 bit keccak has of some bytes
238250
pub trait Keccak256 {
239251
/// Returns a keccak256 hash of a byte slice

modules/ismp/core/src/module.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
router::{PostRequest, Response, Timeout},
2121
Error,
2222
};
23-
23+
use sp_weights::Weight;
2424
/// A type alias for dispatch results
2525
pub type DispatchResult = Result<Event, anyhow::Error>;
2626

@@ -29,19 +29,19 @@ pub type DispatchResult = Result<Event, anyhow::Error>;
2929
pub trait IsmpModule {
3030
/// Called by the message handler on a module, to notify module of a new POST request
3131
/// the module may choose to respond immediately, or in a later block
32-
fn on_accept(&self, _request: PostRequest) -> Result<(), anyhow::Error> {
32+
fn on_accept(&self, _request: PostRequest) -> Result<Weight, anyhow::Error> {
3333
Err(Error::CannotHandleMessage)?
3434
}
3535

3636
/// Called by the message handler on a module, to notify module of a response to a previously
3737
/// sent out request
38-
fn on_response(&self, _response: Response) -> Result<(), anyhow::Error> {
38+
fn on_response(&self, _response: Response) -> Result<Weight, anyhow::Error> {
3939
Err(Error::CannotHandleMessage)?
4040
}
4141

4242
/// Called by the message handler on a module, to notify module of requests that were previously
4343
/// sent but have now timed-out
44-
fn on_timeout(&self, _request: Timeout) -> Result<(), anyhow::Error> {
44+
fn on_timeout(&self, _request: Timeout) -> Result<Weight, anyhow::Error> {
4545
Err(Error::CannotHandleMessage)?
4646
}
4747
}

modules/ismp/testsuite/src/mocks.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use codec::Encode;
2-
use polkadot_sdk::*;
2+
use polkadot_sdk::{sp_runtime::Weight, *};
33
use primitive_types::H256;
44
use std::{
55
cell::RefCell,
@@ -415,19 +415,23 @@ impl Keccak256 for Host {
415415
pub struct MockModule;
416416

417417
impl IsmpModule for MockModule {
418-
fn on_accept(&self, _request: PostRequest) -> Result<(), anyhow::Error> {
419-
Ok(())
418+
fn on_accept(&self, _request: PostRequest) -> Result<Weight, anyhow::Error> {
419+
Ok(weight())
420420
}
421421

422-
fn on_response(&self, _response: Response) -> Result<(), anyhow::Error> {
423-
Ok(())
422+
fn on_response(&self, _response: Response) -> Result<Weight, anyhow::Error> {
423+
Ok(weight())
424424
}
425425

426-
fn on_timeout(&self, _request: Timeout) -> Result<(), anyhow::Error> {
427-
Ok(())
426+
fn on_timeout(&self, _request: Timeout) -> Result<Weight, anyhow::Error> {
427+
Ok(weight())
428428
}
429429
}
430430

431+
fn weight() -> Weight {
432+
Weight::from_parts(0, 0)
433+
}
434+
431435
pub struct MockRouter(pub Host);
432436

433437
impl IsmpRouter for MockRouter {

0 commit comments

Comments
 (0)