mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 09:31:12 +00:00
Allow duplicate topics in smart contract events (#13065)
* Removed `has_duplicates` check form the `deposit_event`. Removed the usage of `Error::DuplicateTopics`. * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_contracts Co-authored-by: command-bot <>
This commit is contained in:
@@ -816,8 +816,6 @@ pub mod pallet {
|
||||
RandomSubjectTooLong,
|
||||
/// The amount of topics passed to `seal_deposit_events` exceeds the limit.
|
||||
TooManyTopics,
|
||||
/// The topics passed to `seal_deposit_events` contains at least one duplicate.
|
||||
DuplicateTopics,
|
||||
/// The chain does not provide a chain extension. Calling the chain extension results
|
||||
/// in this error. Note that this usually shouldn't happen as deploying such contracts
|
||||
/// is rejected.
|
||||
|
||||
@@ -1988,6 +1988,52 @@ mod tests {
|
||||
assert!(mock_ext.gas_meter.gas_left().ref_time() > 0);
|
||||
}
|
||||
|
||||
const CODE_DEPOSIT_EVENT_DUPLICATES: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_deposit_event
|
||||
(i32.const 32) ;; Pointer to the start of topics buffer
|
||||
(i32.const 129) ;; The length of the topics buffer.
|
||||
(i32.const 8) ;; Pointer to the start of the data buffer
|
||||
(i32.const 13) ;; Length of the buffer
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
|
||||
(data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00")
|
||||
|
||||
;; Encoded Vec<TopicOf<T>>, the buffer has length of 129 bytes.
|
||||
(data (i32.const 32) "\10"
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
"\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02"
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04")
|
||||
)
|
||||
"#;
|
||||
|
||||
/// Checks that the runtime allows duplicate topics.
|
||||
#[test]
|
||||
fn deposit_event_duplicates_allowed() {
|
||||
let mut mock_ext = MockExt::default();
|
||||
assert_ok!(execute(CODE_DEPOSIT_EVENT_DUPLICATES, vec![], &mut mock_ext,));
|
||||
|
||||
assert_eq!(
|
||||
mock_ext.events,
|
||||
vec![(
|
||||
vec![
|
||||
H256::repeat_byte(0x01),
|
||||
H256::repeat_byte(0x02),
|
||||
H256::repeat_byte(0x01),
|
||||
H256::repeat_byte(0x04)
|
||||
],
|
||||
vec![0x00, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00]
|
||||
)]
|
||||
);
|
||||
}
|
||||
|
||||
const CODE_DEPOSIT_EVENT_MAX_TOPICS: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
@@ -2027,44 +2073,6 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
const CODE_DEPOSIT_EVENT_DUPLICATES: &str = r#"
|
||||
(module
|
||||
(import "seal0" "seal_deposit_event" (func $seal_deposit_event (param i32 i32 i32 i32)))
|
||||
(import "env" "memory" (memory 1 1))
|
||||
|
||||
(func (export "call")
|
||||
(call $seal_deposit_event
|
||||
(i32.const 32) ;; Pointer to the start of topics buffer
|
||||
(i32.const 129) ;; The length of the topics buffer.
|
||||
(i32.const 8) ;; Pointer to the start of the data buffer
|
||||
(i32.const 13) ;; Length of the buffer
|
||||
)
|
||||
)
|
||||
(func (export "deploy"))
|
||||
|
||||
(data (i32.const 8) "\00\01\2A\00\00\00\00\00\00\00\E5\14\00")
|
||||
|
||||
;; Encoded Vec<TopicOf<T>>, the buffer has length of 129 bytes.
|
||||
(data (i32.const 32) "\10"
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
"\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02"
|
||||
"\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01"
|
||||
"\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04\04")
|
||||
)
|
||||
"#;
|
||||
|
||||
/// Checks that the runtime traps if there are duplicates.
|
||||
#[test]
|
||||
fn deposit_event_duplicates() {
|
||||
assert_eq!(
|
||||
execute(CODE_DEPOSIT_EVENT_DUPLICATES, vec![], MockExt::default(),),
|
||||
Err(ExecError {
|
||||
error: Error::<Test>::DuplicateTopics.into(),
|
||||
origin: ErrorOrigin::Caller,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/// calls `seal_block_number` compares the result with the constant 121.
|
||||
const CODE_BLOCK_NUMBER: &str = r#"
|
||||
(module
|
||||
|
||||
@@ -2085,15 +2085,6 @@ pub mod env {
|
||||
data_ptr: u32,
|
||||
data_len: u32,
|
||||
) -> Result<(), TrapReason> {
|
||||
fn has_duplicates<T: Ord>(items: &mut Vec<T>) -> bool {
|
||||
items.sort();
|
||||
// Find any two consecutive equal elements.
|
||||
items.windows(2).any(|w| match &w {
|
||||
&[a, b] => a == b,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
let num_topic = topics_len
|
||||
.checked_div(sp_std::mem::size_of::<TopicOf<E::T>>() as u32)
|
||||
.ok_or("Zero sized topics are not allowed")?;
|
||||
@@ -2102,7 +2093,7 @@ pub mod env {
|
||||
return Err(Error::<E::T>::ValueTooLarge.into())
|
||||
}
|
||||
|
||||
let mut topics: Vec<TopicOf<<E as Ext>::T>> = match topics_len {
|
||||
let topics: Vec<TopicOf<<E as Ext>::T>> = match topics_len {
|
||||
0 => Vec::new(),
|
||||
_ => ctx.read_sandbox_memory_as_unbounded(memory, topics_ptr, topics_len)?,
|
||||
};
|
||||
@@ -2112,13 +2103,6 @@ pub mod env {
|
||||
return Err(Error::<E::T>::TooManyTopics.into())
|
||||
}
|
||||
|
||||
// Check for duplicate topics. If there are any, then trap.
|
||||
// Complexity O(n * log(n)) and no additional allocations.
|
||||
// This also sorts the topics.
|
||||
if has_duplicates(&mut topics) {
|
||||
return Err(Error::<E::T>::DuplicateTopics.into())
|
||||
}
|
||||
|
||||
let event_data = ctx.read_sandbox_memory(memory, data_ptr, data_len)?;
|
||||
|
||||
ctx.ext.deposit_event(topics, event_data);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user