Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("node"),
impl_name: create_runtime_str!("substrate-node"),
authoring_version: 10,
spec_version: 78,
impl_version: 79,
spec_version: 80,
impl_version: 80,
apis: RUNTIME_API_VERSIONS,
};

Expand Down
70 changes: 55 additions & 15 deletions srml/contract/src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ pub type CallOf<T> = <T as Trait>::Call;
pub type MomentOf<T> = <T as timestamp::Trait>::Moment;
pub type SeedOf<T> = <T as system::Trait>::Hash;

/// A type that represents a topic of an event. At the moment a hash is used.
pub type TopicOf<T> = <T as system::Trait>::Hash;

#[cfg_attr(test, derive(Debug))]
pub struct InstantiateReceipt<AccountId> {
pub address: AccountId,
Expand Down Expand Up @@ -106,8 +109,10 @@ pub trait Ext {
/// Returns a reference to the random seed for the current block
fn random_seed(&self) -> &SeedOf<Self::T>;

/// Deposit an event.
fn deposit_event(&mut self, data: Vec<u8>);
/// Deposit an event with the given topics.
///
/// There should not be any duplicates in `topics`.
fn deposit_event(&mut self, topics: Vec<TopicOf<Self::T>>, data: Vec<u8>);

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

/// Struct that records a request to deposit an event with a list of topics.
#[cfg_attr(any(feature = "std", test), derive(Debug, PartialEq, Eq))]
pub struct IndexedEvent<T: Trait> {
/// A list of topics this event will be deposited with.
pub topics: Vec<T::Hash>,
/// The event to deposit.
pub event: Event<T>,
}

/// A trait that represent a virtual machine.
///
/// You can view a virtual machine as something that takes code, an input data buffer,
Expand Down Expand Up @@ -238,7 +252,7 @@ pub struct ExecutionContext<'a, T: Trait + 'a, V, L> {
pub self_trie_id: Option<TrieId>,
pub overlay: OverlayAccountDb<'a, T>,
pub depth: usize,
pub events: Vec<Event<T>>,
pub events: Vec<IndexedEvent<T>>,
pub calls: Vec<(T::AccountId, T::Call)>,
pub config: &'a Config<T>,
pub vm: &'a V,
Expand Down Expand Up @@ -418,7 +432,10 @@ where
.into_result()?;

// Deposit an instantiation event.
nested.events.push(RawEvent::Instantiated(self.self_account.clone(), dest.clone()));
nested.events.push(IndexedEvent {
event: RawEvent::Instantiated(self.self_account.clone(), dest.clone()),
topics: Vec::new(),
});

(nested.overlay.into_change_set(), nested.events, nested.calls)
};
Expand Down Expand Up @@ -545,8 +562,10 @@ fn transfer<'a, T: Trait, V: Vm<T>, L: Loader<T>>(
if transactor != dest {
ctx.overlay.set_balance(transactor, new_from_balance);
ctx.overlay.set_balance(dest, new_to_balance);
ctx.events
.push(RawEvent::Transfer(transactor.clone(), dest.clone(), value));
ctx.events.push(IndexedEvent {
event: RawEvent::Transfer(transactor.clone(), dest.clone(), value),
topics: Vec::new(),
});
}

Ok(())
Expand Down Expand Up @@ -631,8 +650,11 @@ where
&self.timestamp
}

fn deposit_event(&mut self, data: Vec<u8>) {
self.ctx.events.push(RawEvent::Contract(self.ctx.self_account.clone(), data));
fn deposit_event(&mut self, topics: Vec<T::Hash>, data: Vec<u8>) {
self.ctx.events.push(IndexedEvent {
topics,
event: RawEvent::Contract(self.ctx.self_account.clone(), data),
});
}

fn set_rent_allowance(&mut self, rent_allowance: BalanceOf<T>) {
Expand All @@ -659,7 +681,7 @@ where
mod tests {
use super::{
BalanceOf, ExecFeeToken, ExecutionContext, Ext, Loader, EmptyOutputBuf, TransferFeeKind, TransferFeeToken,
Vm, VmExecResult, InstantiateReceipt, RawEvent,
Vm, VmExecResult, InstantiateReceipt, RawEvent, IndexedEvent,
};
use crate::account_db::AccountDb;
use crate::gas::GasMeter;
Expand Down Expand Up @@ -1262,8 +1284,14 @@ mod tests {
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, created_contract_address, 100),
RawEvent::Instantiated(ALICE, created_contract_address),
IndexedEvent {
event: RawEvent::Transfer(ALICE, created_contract_address, 100),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Instantiated(ALICE, created_contract_address),
topics: Vec::new(),
}
]);
}
);
Expand Down Expand Up @@ -1314,9 +1342,18 @@ mod tests {
// there are instantiation event.
assert_eq!(ctx.overlay.get_code_hash(&created_contract_address).unwrap(), dummy_ch);
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, BOB, 20),
RawEvent::Transfer(BOB, created_contract_address, 15),
RawEvent::Instantiated(BOB, created_contract_address),
IndexedEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Transfer(BOB, created_contract_address, 15),
topics: Vec::new(),
},
IndexedEvent {
event: RawEvent::Instantiated(BOB, created_contract_address),
topics: Vec::new(),
},
]);
}
);
Expand Down Expand Up @@ -1362,7 +1399,10 @@ mod tests {
// The contract wasn't created so we don't expect to see an instantiation
// event here.
assert_eq!(&ctx.events, &[
RawEvent::Transfer(ALICE, BOB, 20),
IndexedEvent {
event: RawEvent::Transfer(ALICE, BOB, 20),
topics: Vec::new(),
},
]);
}
);
Expand Down
26 changes: 22 additions & 4 deletions srml/contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,12 @@ decl_module! {
DirectAccountDb.commit(ctx.overlay.into_change_set());

// Then deposit all events produced.
ctx.events.into_iter().for_each(Self::deposit_event);
ctx.events.into_iter().for_each(|indexed_event| {
<system::Module<T>>::deposit_event_indexed(
&*indexed_event.topics,
<T as Trait>::Event::from(indexed_event.event).into(),
);
});
}

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

// Then deposit all events produced.
ctx.events.into_iter().for_each(Self::deposit_event);
ctx.events.into_iter().for_each(|indexed_event| {
<system::Module<T>>::deposit_event_indexed(
&*indexed_event.topics,
<T as Trait>::Event::from(indexed_event.event).into(),
);
});
}

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

/// Gas cost to deposit an event; the cost per topic.
pub event_per_topic_cost: Gas,

/// Gas cost to deposit an event; the base.
pub event_data_base_cost: Gas,
pub event_base_cost: Gas,

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

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

/// The maximum number of topics supported by an event.
pub max_event_topics: u32,

/// Maximum allowed stack height.
///
/// See https://wiki.parity.io/WebAssembly-StackHeight to find out
Expand All @@ -685,9 +701,11 @@ impl<Gas: As<u64>> Default for Schedule<Gas> {
regular_op_cost: Gas::sa(1),
return_data_per_byte_cost: Gas::sa(1),
event_data_per_byte_cost: Gas::sa(1),
event_data_base_cost: Gas::sa(1),
event_per_topic_cost: Gas::sa(1),
event_base_cost: Gas::sa(1),
sandbox_data_read_cost: Gas::sa(1),
sandbox_data_write_cost: Gas::sa(1),
max_event_topics: 4,
max_stack_height: 64 * 1024,
max_memory_pages: 16,
enable_println: false,
Expand Down
12 changes: 7 additions & 5 deletions srml/contract/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl_outer_dispatch! {
}
}

#[derive(Clone, Eq, PartialEq)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct Test;
impl system::Trait for Test {
type Origin = Origin;
Expand Down Expand Up @@ -313,14 +313,16 @@ fn account_removal_removes_storage() {
const CODE_RETURN_FROM_START_FN: &str = r#"
(module
(import "env" "ext_return" (func $ext_return (param i32 i32)))
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32)))
(import "env" "ext_deposit_event" (func $ext_deposit_event (param i32 i32 i32 i32)))
(import "env" "memory" (memory 1 1))

(start $start)
(func $start
(call $ext_deposit_event
(i32.const 8)
(i32.const 4)
(i32.const 0) ;; The topics buffer
(i32.const 0) ;; The topics buffer's length
(i32.const 8) ;; The data buffer
(i32.const 4) ;; The data buffer's length
)
(call $ext_return
(i32.const 8)
Expand All @@ -337,7 +339,7 @@ const CODE_RETURN_FROM_START_FN: &str = r#"
(data (i32.const 8) "\01\02\03\04")
)
"#;
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("abb4194bdea47b2904fe90b4fd674bd40d96f423956627df8c39d2b1a791ab9d");
const HASH_RETURN_FROM_START_FN: [u8; 32] = hex!("66c45bd7c473a1746e1d241176166ef53b1f207f56c5e87d1b6650140704181b");

#[test]
fn instantiate_and_call_and_deposit_event() {
Expand Down
Loading