Skip to content

Commit 1965b2f

Browse files
committed
runtime-sdk: Add support for reporting sender metadata
1 parent 7af475d commit 1965b2f

5 files changed

Lines changed: 77 additions & 4 deletions

File tree

runtime-sdk/src/dispatcher.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ use crate::{
3636
modules::core::API as _,
3737
runtime::Runtime,
3838
schedule_control::ScheduleControlHost,
39+
sender::SenderMeta,
3940
storage::{self, NestedStore, Prefix},
4041
types,
4142
types::transaction::{AuthProof, Transaction},
@@ -77,6 +78,8 @@ pub struct DispatchResult {
7778
pub tags: Tags,
7879
/// Transaction priority.
7980
pub priority: u64,
81+
/// Transaction sender metadata.
82+
pub sender_metadata: SenderMeta,
8083
/// Call format metadata.
8184
pub call_format_metadata: callformat::Metadata,
8285
}
@@ -91,6 +94,7 @@ impl DispatchResult {
9194
result,
9295
tags,
9396
priority: 0,
97+
sender_metadata: Default::default(),
9498
call_format_metadata,
9599
}
96100
}
@@ -258,8 +262,10 @@ impl<R: Runtime> Dispatcher<R> {
258262
);
259263
}
260264

261-
// Load priority, weights.
265+
// Load priority.
262266
let priority = R::Core::take_priority(&mut ctx);
267+
// Load sender metadata.
268+
let sender_metadata = R::Core::take_sender_meta(&mut ctx);
263269

264270
if ctx.is_check_only() {
265271
// Rollback state during checks.
@@ -270,6 +276,7 @@ impl<R: Runtime> Dispatcher<R> {
270276
result,
271277
tags: Vec::new(),
272278
priority,
279+
sender_metadata,
273280
call_format_metadata,
274281
},
275282
Vec::new(),
@@ -282,6 +289,7 @@ impl<R: Runtime> Dispatcher<R> {
282289
result,
283290
tags: etags.into_tags(),
284291
priority,
292+
sender_metadata,
285293
call_format_metadata,
286294
},
287295
messages,
@@ -338,9 +346,9 @@ impl<R: Runtime> Dispatcher<R> {
338346
error: Default::default(),
339347
meta: Some(CheckTxMetadata {
340348
priority: dispatch.priority,
341-
sender: vec![], // TODO: Support indicating senders.
342-
sender_seq: 0, // TODO: Support indicating senders.
343-
sender_state_seq: 0, // TODO: Support indicating senders.
349+
sender: dispatch.sender_metadata.id(),
350+
sender_seq: dispatch.sender_metadata.tx_nonce,
351+
sender_state_seq: dispatch.sender_metadata.state_nonce,
344352
}),
345353
}),
346354

runtime-sdk/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod module;
1616
pub mod modules;
1717
pub mod runtime;
1818
pub mod schedule_control;
19+
pub mod sender;
1920
pub mod storage;
2021
pub mod testing;
2122
pub mod types;

runtime-sdk/src/modules/core/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::{
1818
self, CallResult, InvariantHandler as _, MethodHandler as _, Module as _,
1919
ModuleInfoHandler as _,
2020
},
21+
sender::SenderMeta,
2122
types::{
2223
token,
2324
transaction::{self, AddressSpec, AuthProof, Call, CallFormat, UnverifiedTransaction},
@@ -266,6 +267,12 @@ pub trait API {
266267
/// Takes and returns the stored transaction priority.
267268
fn take_priority<C: Context>(ctx: &mut C) -> u64;
268269

270+
/// Set transaction sender metadata.
271+
fn set_sender_meta<C: Context>(ctx: &mut C, meta: SenderMeta);
272+
273+
/// Takes and returns the stored transaction sender metadata.
274+
fn take_sender_meta<C: Context>(ctx: &mut C) -> SenderMeta;
275+
269276
/// Returns the configured max iterations in the binary search for the estimate
270277
/// gas.
271278
fn estimate_gas_search_max_iters<C: Context>(ctx: &C) -> u64;
@@ -342,6 +349,7 @@ pub struct Module<Cfg: Config> {
342349

343350
const CONTEXT_KEY_GAS_USED: &str = "core.GasUsed";
344351
const CONTEXT_KEY_PRIORITY: &str = "core.Priority";
352+
const CONTEXT_KEY_SENDER_META: &str = "core.SenderMeta";
345353

346354
impl<Cfg: Config> Module<Cfg> {
347355
/// Initialize state from genesis.
@@ -447,6 +455,16 @@ impl<Cfg: Config> API for Module<Cfg> {
447455
.unwrap_or_default()
448456
}
449457

458+
fn set_sender_meta<C: Context>(ctx: &mut C, meta: SenderMeta) {
459+
ctx.value::<SenderMeta>(CONTEXT_KEY_SENDER_META).set(meta);
460+
}
461+
462+
fn take_sender_meta<C: Context>(ctx: &mut C) -> SenderMeta {
463+
ctx.value::<SenderMeta>(CONTEXT_KEY_SENDER_META)
464+
.take()
465+
.unwrap_or_default()
466+
}
467+
450468
fn estimate_gas_search_max_iters<C: Context>(ctx: &C) -> u64 {
451469
ctx.local_config(MODULE_NAME)
452470
.as_ref()

runtime-sdk/src/modules/core/test.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use crate::{
1010
module::{self, Module as _, TransactionHandler as _},
1111
runtime::Runtime,
1212
sdk_derive,
13+
sender::SenderMeta,
1314
testing::{configmap, keys, mock},
1415
types::{token, transaction, transaction::CallerAddress},
1516
};
@@ -749,6 +750,25 @@ fn test_add_priority_overflow() {
749750
);
750751
}
751752

753+
#[test]
754+
fn test_set_sender_meta() {
755+
let mut mock = mock::Mock::default();
756+
let mut ctx = mock.create_ctx();
757+
758+
let sender_meta = SenderMeta {
759+
address: keys::alice::address(),
760+
tx_nonce: 42,
761+
state_nonce: 43,
762+
};
763+
Core::set_sender_meta(&mut ctx, sender_meta.clone());
764+
765+
let taken_sender_meta = Core::take_sender_meta(&mut ctx);
766+
assert_eq!(
767+
taken_sender_meta, sender_meta,
768+
"setting sender metadata should work"
769+
);
770+
}
771+
752772
#[test]
753773
fn test_min_gas_price() {
754774
let mut mock = mock::Mock::default();

runtime-sdk/src/sender.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//! Transaction sender metadata.
2+
use crate::types::address::Address;
3+
4+
/// Transaction sender metadata.
5+
#[derive(Clone, Debug, Eq, PartialEq, Default)]
6+
pub struct SenderMeta {
7+
/// Sender address.
8+
pub address: Address,
9+
/// Sender nonce contained in the transaction.
10+
pub tx_nonce: u64,
11+
/// Sender nonce contained in runtime state.
12+
pub state_nonce: u64,
13+
}
14+
15+
impl SenderMeta {
16+
/// Unique identifier of the sender, currently derived from the sender address.
17+
pub fn id(&self) -> Vec<u8> {
18+
if self.address == Default::default() {
19+
// Use an empty value for the default address as that signals to the host that the
20+
// sender should be ignored.
21+
vec![]
22+
} else {
23+
self.address.into_bytes().to_vec()
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)