Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 63f6c81

Browse files
pepyakingavofyork
authored andcommitted
Pass topics along with events (#2563)
* Introduce an IndexedEvent * Plumb topics through the Ext interface. * Add topics to ext_deposit_event * Charging for events. * Check the number of topics. * Check for duplicate topics. * Bump API version. * Move derive(*Eq) under test. * Use sorting for finding duplicates.
1 parent 94871c1 commit 63f6c81

File tree

6 files changed

+272
-52
lines changed

6 files changed

+272
-52
lines changed

node/runtime/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
5858
spec_name: create_runtime_str!("node"),
5959
impl_name: create_runtime_str!("substrate-node"),
6060
authoring_version: 10,
61-
spec_version: 78,
62-
impl_version: 79,
61+
spec_version: 80,
62+
impl_version: 80,
6363
apis: RUNTIME_API_VERSIONS,
6464
};
6565

srml/contract/src/exec.rs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ pub type CallOf<T> = <T as Trait>::Call;
2929
pub type MomentOf<T> = <T as timestamp::Trait>::Moment;
3030
pub type SeedOf<T> = <T as system::Trait>::Hash;
3131

32+
/// A type that represents a topic of an event. At the moment a hash is used.
33+
pub type TopicOf<T> = <T as system::Trait>::Hash;
34+
3235
#[cfg_attr(test, derive(Debug))]
3336
pub struct InstantiateReceipt<AccountId> {
3437
pub address: AccountId,
@@ -106,8 +109,10 @@ pub trait Ext {
106109
/// Returns a reference to the random seed for the current block
107110
fn random_seed(&self) -> &SeedOf<Self::T>;
108111

109-
/// Deposit an event.
110-
fn deposit_event(&mut self, data: Vec<u8>);
112+
/// Deposit an event with the given topics.
113+
///
114+
/// There should not be any duplicates in `topics`.
115+
fn deposit_event(&mut self, topics: Vec<TopicOf<Self::T>>, data: Vec<u8>);
111116

112117
/// Set rent allowance of the contract
113118
fn set_rent_allowance(&mut self, rent_allowance: BalanceOf<Self::T>);
@@ -189,6 +194,15 @@ impl VmExecResult {
189194
}
190195
}
191196

197+
/// Struct that records a request to deposit an event with a list of topics.
198+
#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq))]
199+
pub struct IndexedEvent<T: Trait> {
200+
/// A list of topics this event will be deposited with.
201+
pub topics: Vec<T::Hash>,
202+
/// The event to deposit.
203+
pub event: Event<T>,
204+
}
205+
192206
/// A trait that represent a virtual machine.
193207
///
194208
/// You can view a virtual machine as something that takes code, an input data buffer,
@@ -238,7 +252,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> {
238252
pub self_trie_id: Option<TrieId>,
239253
pub overlay: OverlayAccountDb<'a, T>,
240254
pub depth: usize,
241-
pub events: Vec<Event<T>>,
255+
pub events: Vec<IndexedEvent<T>>,
242256
pub calls: Vec<(T::AccountId, T::Call)>,
243257
pub config: &'a Config<T>,
244258
pub vm: &'a V,
@@ -418,7 +432,10 @@ where
418432
.into_result()?;
419433

420434
// Deposit an instantiation event.
421-
nested.events.push(RawEvent::Instantiated(self.self_account.clone(), dest.clone()));
435+
nested.events.push(IndexedEvent {
436+
event: RawEvent::Instantiated(self.self_account.clone(), dest.clone()),
437+
topics: Vec::new(),
438+
});
422439

423440
(nested.overlay.into_change_set(), nested.events, nested.calls)
424441
};
@@ -545,8 +562,10 @@ fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
545562
if transactor != dest {
546563
ctx.overlay.set_balance(transactor, new_from_balance);
547564
ctx.overlay.set_balance(dest, new_to_balance);
548-
ctx.events
549-
.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value));
565+
ctx.events.push(IndexedEvent {
566+
event: RawEvent::Transfer(transactor.clone(), dest.clone(), value),
567+
topics: Vec::new(),
568+
});
550569
}
551570

552571
Ok(())
@@ -631,8 +650,11 @@ where
631650
&self.timestamp
632651
}
633652

634-
fn deposit_event(&mut self, data: Vec<u8>) {
635-
self.ctx.events.push(RawEvent::Contract(self.ctx.self_account.clone(), data));
653+
fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
654+
self.ctx.events.push(IndexedEvent {
655+
topics,
656+
event: RawEvent::Contract(self.ctx.self_account.clone(), data),
657+
});
636658
}
637659

638660
fn set_rent_allowance(&mut self, rent_allowance: BalanceOf<T>) {
@@ -659,7 +681,7 @@ where
659681
mod tests {
660682
use super::{
661683
BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, EmptyOutputBuf, TransferFeeKind, TransferFeeToken,
662-
Vm, VmExecResult, InstantiateReceipt, RawEvent,
684+
Vm, VmExecResult, InstantiateReceipt, RawEvent, IndexedEvent,
663685
};
664686
use crate::account_db::AccountDb;
665687
use crate::gas::GasMeter;
@@ -1262,8 +1284,14 @@ mod tests {
12621284
// there are instantiation event.
12631285
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
12641286
assert_eq!(&ctx.events, &[
1265-
RawEvent::Transfer(ALICE, created_contract_address, 100),
1266-
RawEvent::Instantiated(ALICE, created_contract_address),
1287+
IndexedEvent {
1288+
event: RawEvent::Transfer(ALICE, created_contract_address, 100),
1289+
topics: Vec::new(),
1290+
},
1291+
IndexedEvent {
1292+
event: RawEvent::Instantiated(ALICE, created_contract_address),
1293+
topics: Vec::new(),
1294+
}
12671295
]);
12681296
}
12691297
);
@@ -1314,9 +1342,18 @@ mod tests {
13141342
// there are instantiation event.
13151343
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
13161344
assert_eq!(&ctx.events, &[
1317-
RawEvent::Transfer(ALICE, BOB, 20),
1318-
RawEvent::Transfer(BOB, created_contract_address, 15),
1319-
RawEvent::Instantiated(BOB, created_contract_address),
1345+
IndexedEvent {
1346+
event: RawEvent::Transfer(ALICE, BOB, 20),
1347+
topics: Vec::new(),
1348+
},
1349+
IndexedEvent {
1350+
event: RawEvent::Transfer(BOB, created_contract_address, 15),
1351+
topics: Vec::new(),
1352+
},
1353+
IndexedEvent {
1354+
event: RawEvent::Instantiated(BOB, created_contract_address),
1355+
topics: Vec::new(),
1356+
},
13201357
]);
13211358
}
13221359
);
@@ -1362,7 +1399,10 @@ mod tests {
13621399
// The contract wasn't created so we don't expect to see an instantiation
13631400
// event here.
13641401
assert_eq!(&ctx.events, &[
1365-
RawEvent::Transfer(ALICE, BOB, 20),
1402+
IndexedEvent {
1403+
event: RawEvent::Transfer(ALICE, BOB, 20),
1404+
topics: Vec::new(),
1405+
},
13661406
]);
13671407
}
13681408
);

srml/contract/src/lib.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,12 @@ decl_module! {
393393
DirectAccountDb.commit(ctx.overlay.into_change_set());
394394

395395
// Then deposit all events produced.
396-
ctx.events.into_iter().for_each(Self::deposit_event);
396+
ctx.events.into_iter().for_each(|indexed_event| {
397+
<system::Module<T>>::deposit_event_indexed(
398+
&*indexed_event.topics,
399+
<T as Trait>::Event::from(indexed_event.event).into(),
400+
);
401+
});
397402
}
398403

399404
// Refund cost of the unused gas.
@@ -447,7 +452,12 @@ decl_module! {
447452
DirectAccountDb.commit(ctx.overlay.into_change_set());
448453

449454
// Then deposit all events produced.
450-
ctx.events.into_iter().for_each(Self::deposit_event);
455+
ctx.events.into_iter().for_each(|indexed_event| {
456+
<system::Module<T>>::deposit_event_indexed(
457+
&*indexed_event.topics,
458+
<T as Trait>::Event::from(indexed_event.event).into(),
459+
);
460+
});
451461
}
452462

453463
// Refund cost of the unused gas.
@@ -653,15 +663,21 @@ pub struct Schedule<Gas> {
653663
/// Gas cost to deposit an event; the per-byte portion.
654664
pub event_data_per_byte_cost: Gas,
655665

666+
/// Gas cost to deposit an event; the cost per topic.
667+
pub event_per_topic_cost: Gas,
668+
656669
/// Gas cost to deposit an event; the base.
657-
pub event_data_base_cost: Gas,
670+
pub event_base_cost: Gas,
658671

659672
/// Gas cost per one byte read from the sandbox memory.
660673
pub sandbox_data_read_cost: Gas,
661674

662675
/// Gas cost per one byte written to the sandbox memory.
663676
pub sandbox_data_write_cost: Gas,
664677

678+
/// The maximum number of topics supported by an event.
679+
pub max_event_topics: u32,
680+
665681
/// Maximum allowed stack height.
666682
///
667683
/// See https://wiki.parity.io/WebAssembly-StackHeight to find out
@@ -685,9 +701,11 @@ impl<Gas: As<u64>> Default for Schedule<Gas> {
685701
regular_op_cost: Gas::sa(1),
686702
return_data_per_byte_cost: Gas::sa(1),
687703
event_data_per_byte_cost: Gas::sa(1),
688-
event_data_base_cost: Gas::sa(1),
704+
event_per_topic_cost: Gas::sa(1),
705+
event_base_cost: Gas::sa(1),
689706
sandbox_data_read_cost: Gas::sa(1),
690707
sandbox_data_write_cost: Gas::sa(1),
708+
max_event_topics: 4,
691709
max_stack_height: 64 * 1024,
692710
max_memory_pages: 16,
693711
enable_println: false,

srml/contract/src/tests.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ impl_outer_dispatch! {
6464
}
6565
}
6666

67-
#[derive(Clone, Eq, PartialEq)]
67+
#[derive(Clone, Eq, PartialEq, Debug)]
6868
pub struct Test;
6969
impl system::Trait for Test {
7070
type Origin = Origin;
@@ -313,14 +313,16 @@ fn account_removal_removes_storage() {
313313
const CODE_RETURN_FROM_START_FN: &str = r#"
314314
(module
315315
(import "env" "ext_return" (func $ext_return (param i32 i32)))
316-
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32)))
316+
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
317317
(import "env" "memory" (memory 1 1))
318318
319319
(start $start)
320320
(func $start
321321
(call $ext_deposit_event
322-
(i32.const 8)
323-
(i32.const 4)
322+
(i32.const 0) ;; The topics buffer
323+
(i32.const 0) ;; The topics buffer's length
324+
(i32.const 8) ;; The data buffer
325+
(i32.const 4) ;; The data buffer's length
324326
)
325327
(call $ext_return
326328
(i32.const 8)
@@ -337,7 +339,7 @@ const CODE_RETURN_FROM_START_FN: &str = r#"
337339
(data (i32.const 8) "\01\02\03\04")
338340
)
339341
"#;
340-
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("abb4194bdea47b2904fe90b4fd674bd40d96f423956627df8c39d2b1a791ab9d");
342+
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("66c45bd7c473a1746e1d241176166ef53b1f207f56c5e87d1b6650140704181b");
341343

342344
#[test]
343345
fn instantiate_and_call_and_deposit_event() {

0 commit comments

Comments
 (0)