-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SYS-3965: added first stage migration of processed events mechanism to eth-bridge #390
SYS-3965: added first stage migration of processed events mechanism to eth-bridge #390
Conversation
Introduces the data structures and the voting mechanism for accepting events ranges from ethereum. Ranges that are too big will be broken down into smaller partitions, voted upon individually, and accepted as one. Follow up commit will do the validate unsigned and processing of the partitions. Jira tickets: - SYS-3635 - SYS-3930
Updates the validate unsigned function to support submit_discovered_events extrinsic. Jira tickets: - SYS-3635 - SYS-3930
This PR introduces support for processing votes upon achieving consensus. It extends extrinsics and data structures accordingly. Once the final vote is cast, the voting round for the Ethereum range partition is finalized, and the partition is processed. Additionally, this PR extends the subscription mechanism of the eth-bridge pallet. By default, pallets ignore processed events, requiring the implementation of a handler to process them. Benchmarking for certain actions will be addressed in a separate PR. Jira Tasks: - SYS-3930 - SYS-3635
Signed-off-by: Ivan Cholakov <icholakov1@gmail.com> Co-authored-by: Thanos Doukoudakis <56822898+thadouk@users.noreply.github.com>
Signed-off-by: Ivan Cholakov <icholakov1@gmail.com> Co-authored-by: Thanos Doukoudakis <56822898+thadouk@users.noreply.github.com>
pallets/eth-bridge/src/lib.rs
Outdated
} | ||
|
||
fn process_ethereum_event<T: Config>(event: &EthEvent) { | ||
fn process_ethereum_event<T: Config>(event: &EthEvent) -> Result<(), DispatchError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should consume any errors here, rather than bubbling up the error
pallets/token-manager/src/mock.rs
Outdated
@@ -376,6 +377,10 @@ impl ProcessedEventsChecker for TestRuntime { | |||
fn check_event(event_id: &EthEventId) -> bool { | |||
return PROCESSED_EVENTS.with(|l| l.borrow_mut().iter().any(|event| event == event_id)) | |||
} | |||
|
|||
fn add_event(event_id: &EthEventId, processed: bool) -> DispatchResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need an overwrite of the default one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not possible to implement only one of the trait items without the other, this change was to resolve errors occurring as a result of adding trait functions
@@ -350,6 +351,10 @@ impl ProcessedEventsChecker for TestRuntime { | |||
}) | |||
}) | |||
} | |||
|
|||
fn add_event(event_id: &EthEventId, processed: bool) -> DispatchResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
Adds a new endpoint that allows the chain to reach consenus over the initial ethereum range to be used. This allows to simplify the voting logic for active ranges, eliminating the special case of the first range. Jira ticket: - SYS-3930
Extends the runtime API for initial range consensus mechanism Jira task - SYS-3930
Adds basic unit tests that check the submit_ethereum_events interface Jira task: - SYS-3930 - SYS-3635
…on-processed-events-mechanism-first
@nahuseyoum I have written some comments for the tests. So far I had created the values in the mock (although partially incorrectly as the successful test case does not pass) and identified the edge cases. The tests themselves still need to reach the required function process_ethereum_event(). |
- General cleanup - Rename of storage items - Removal of mocks - Wire up with runtime, implementing different events filters for each runtime.
…' into SYS-3965-migration-processed-events-mechanism-first
commit 842e507 Merge: 5b1abf1 c483d18 Author: Thanos <56822898+thadouk@users.noreply.github.com> Date: Fri May 3 14:57:01 2024 +0100 Merge remote-tracking branch 'origin/feat/SYS-3560-add-event-listener' into SYS-3965-migration-processed-events-mechanism-first commit 5b1abf1 Author: Michael Brozhko <michael@brozhko.org> Date: Thu May 2 20:03:48 2024 +0300 fix merge issue, add more comments commit 0bf2b26 Author: Michael Brozhko <michael@brozhko.org> Date: Thu May 2 19:43:01 2024 +0300 tidy-up, add comments commit 787caa3 Merge: bc8a0fd 13b32f3 Author: Michael Brozhko <michael@brozhko.org> Date: Thu May 2 19:28:22 2024 +0300 Merge branch 'feat/SYS-3560-add-event-listener' into SYS-3965-migration-processed-events-mechanism-first commit bc8a0fd Author: Michael Brozhko <michael@brozhko.org> Date: Thu May 2 11:26:03 2024 +0300 tests, mock, more changes commit b535a33 Author: Michael Brozhko <michael@brozhko.org> Date: Wed Apr 24 16:23:01 2024 +0100 added functionality
…ion-processed-events-mechanism-first
c483d18
to
22ed41e
Compare
… github.com:Aventus-Network-Services/avn-parachain into SYS-3965-migration-processed-events-mechanism-first
10b59ba
to
0b52c39
Compare
pallets/eth-bridge/src/lib.rs
Outdated
}); | ||
// Add record of succesful processing via ProcessedEventsChecker | ||
T::ProcessedEventsChecker::add_processed_event(&event.event_id.clone(), event_accepted); | ||
<Pallet<T>>::deposit_event(Event::<T>::DuplicateEventSubmission { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see why you are emitting an event here, I am assuming its because we don't want to error here which is correct. But in this particular case, the event we are processing has already been processed so Its "safe" to return an error and undo any storage changes related to processing this event.
pallets/avn/src/lib.rs
Outdated
@@ -703,13 +703,17 @@ impl<ValidatorId: Member> Enforcer<ValidatorId> for () { | |||
} | |||
|
|||
pub trait ProcessedEventsChecker { | |||
fn check_event(event_id: &EthEventId) -> bool; | |||
fn processed_event_exists(event_id: &EthEventId) -> bool; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EventAccepted { | ||
eth_event_id: EthEventId, | ||
}, | ||
EventRejected { | ||
eth_event_id: EthEventId, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use two events for signaling the processing events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it not be due to the fact that there are two possibilities in the event being accepted vs rejected and to distinguish between these two circumstances?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have connected components that are currently looking for these events and its a lesser change to maintain the interface. Its also easier to search and filter instead of using event args.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I beg to differ. It is much more lean to maintain a single event with a flag.
Reduces codebase size and code repetition.
Its also outside the scope of the task to change this interface.
pallets/eth-bridge/src/lib.rs
Outdated
@@ -794,48 +806,62 @@ pub mod pallet { | |||
fn process_ethereum_events_partition<T: Config>( | |||
active_range: &ActiveEthRange, | |||
partition: &EthereumEventsPartition, | |||
) { | |||
) -> Result<(), DispatchError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function should be infallible.
Once a voting round is concluded, the processing of each event should not affect the processing of the batch.
The errors should be handled, the appropriate events emited and processing continues.
Otherwise, the chain will be stuck in a loop of voting for the last vote and rejecting the processing.
// TODO before processing ensure that the event has not already been processed | ||
match T::BridgeInterfaceNotification::on_event_processed(&event) { | ||
fn process_ethereum_event<T: Config>(event: &EthEvent) -> Result<(), DispatchError> { | ||
ensure!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't error here. If the event has been processed, we avoid double processing, signal/log/emit the appropriate info and return.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we call this function with an event that has already been processed, it's because the upstream functions did not validate properly. I understand we shouldn't error here if we need to mark the transaction as processed (and failed) but for a case where its already processed, why shouldn't we error?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the authors/collators have reached consensus on the tier1 state then we shouldn't block it.
There are valid cases that this can occur:
- events added and being processed while upgrading.
- events added to tier2 due starting from an earlier last block
We should definitely mark the case, but not block the event processing mechanism.
The error will cause the last vote to be stuck and recasted, only to be rejected again and again in a loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both of these scenarios, and possibly others, I would expect the collators to check first if the event is valid before submitting it (ex: already processed or 0x000
..).
But in any case, this function is too low level to be required to be infallible. I think we can still throw an error here and catch it on process_ethereum_events_partition
and log it there and move on to the next event?
It feels like making an distinction between a bad event (one that is already processed, or is 0
something we should add in the validation i guess 😄 ) and a valid event that fails to be processed makes sense which is what this low level function is doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am happy with either solution, although perhaps handling the error within the process_ethereum_events_partition
function is the best solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have pushed a commit the changes @nahuseyoum suggested @thadouk . This can be reverted if necessary although I believe it should be ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nahuseyoum collators don't filter events based on their processing status, as this can change and create inconsistency.
The collators report the events found in a range blocks based on the type of the event that are determined by the active ethereum range.
9be69d1
to
e19db3b
Compare
// TODO before processing ensure that the event has not already been processed | ||
match T::BridgeInterfaceNotification::on_event_processed(&event) { | ||
fn process_ethereum_event<T: Config>(event: &EthEvent) -> Result<(), DispatchError> { | ||
ensure!( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nahuseyoum collators don't filter events based on their processing status, as this can change and create inconsistency.
The collators report the events found in a range blocks based on the type of the event that are determined by the active ethereum range.
EventAccepted { | ||
eth_event_id: EthEventId, | ||
}, | ||
EventRejected { | ||
eth_event_id: EthEventId, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I beg to differ. It is much more lean to maintain a single event with a flag.
Reduces codebase size and code repetition.
Its also outside the scope of the task to change this interface.
Co-authored-by: Thanos Doukoudakis <56822898+thadouk@users.noreply.github.com> Signed-off-by: Michael <62653655+MBrozhko34@users.noreply.github.com>
…o eth-bridge (#390) Co-authored-by: Thanos <56822898+thadouk@users.noreply.github.com> Co-authored-by: nahuseyoum <nahu.seyoum@aventus.io>
…o eth-bridge (#390) Co-authored-by: Thanos <56822898+thadouk@users.noreply.github.com> Co-authored-by: nahuseyoum <nahu.seyoum@aventus.io>
…o eth-bridge (#390) Co-authored-by: Thanos <56822898+thadouk@users.noreply.github.com> Co-authored-by: nahuseyoum <nahu.seyoum@aventus.io>
…o eth-bridge (#390) Co-authored-by: Thanos <56822898+thadouk@users.noreply.github.com> Co-authored-by: nahuseyoum <nahu.seyoum@aventus.io>
Proposed changes
Type of change/Merge
🚨What type of change is this PR?
Put an
x
in the boxes that applyChecklist
Put an
x
in the boxes that apply. You can also fill these out after creating the PR.Further comments