paritytech / polkadot-sdk

The Parity Polkadot Blockchain SDK
https://polkadot.com/
1.9k stars 696 forks source link

Event improvment: independent from frame-system, stored in multiples values, ensure not in PoV #309

Open gui1117 opened 3 years ago

gui1117 commented 3 years ago

From last calls here are the point we highlighted for event:

gui1117 commented 3 years ago

from my undestanding of PoV, events are currently not part of PoV as long as nobody read them in on_runtime_ugprade. This should be improved by moving on_runtime_ugprade after the deletion of event probably. EDIT: anyhow pallet should rather not read the events, maybe we can make the storage private as well to discourage it

For the splitting of events in multiple values, I think we should first look into the limit of the database.

Isolating event deposit in its own crate can be done it should be quite easy, I would like to know an example usecase if possible

bkchr commented 3 years ago
* Also I think we could move system initialize before on_runtime_upgrade.

Why? on_runtime_upgrade should be executed before anything else is done.

gui1117 commented 3 years ago

unfortunately I couldn't solve this before my off days here are the step I will take to resolve this:

h4x3rotab commented 3 years ago

In Phala's implementation, we have separated our MessageQueue notification events from the system events (to walk-around the event decoding problem). We've made a separate Vec<> storage item, allowing to append to it, and kill it at on_initilaize just like the system events. For reasons, we don't want to merge it back to the system event.

My question is, can we also utilize the PoV erasure feature also for our customized event buffer?

bkchr commented 3 years ago

What PoV erasure feature are you meaning?

gui1117 commented 3 years ago

for now we don't plan any specific PoV erasure feature for event. When https://github.com/paritytech/substrate/pull/8931 lands, the event won't be part of PoV if they are not read from the runtime.

(I believe runtime can still read event without putting them in the PoV as long as they do so after the first kill in on_initialize put I am not sure).

bkchr commented 3 years ago

(I believe runtime can still read event without putting them in the PoV as long as they do so after the first kill in on_initialize put I am not sure).

Yes that is correct.

shawntabrizi commented 1 year ago

Not sure if this is said elsewhere, but what we need is actually to split the current events into two:

If I understand correctly, Ethereum, Cosmos, and probably many other blockchains do not place the overhead of events into the state.

I believe the main reason we events in state is to help support light clients. Specifically, if they are not in state, a light client would not be able to know if an event occured on chain.

However, many events are probably just "logs". Things that would be super useful to track in block explorers, or for fully fledged front-ends backed by a full node. But not super relevant for light clients. In fact, I would potentially argue that most events which are relevant to a light client, might actually be replaced with logic around just checking extrinsic and success.

bkchr commented 1 year ago
  • Events: Basically what we have now, which are stored in state and part of the state proof.

  • Logs: Another form of events which are not stored in state, but still provide help to nodes.

We already have this, we have the events and then we got logs aka digests. So, it is actually the other way around as you described it. Logs/digests can be found in the header and are easily trackable by light clients as they don't need to look into the state to find out what kind of events have been posted.

On the long run we will also move events offchain: https://github.com/paritytech/polkadot-sdk/issues/245

xlc commented 1 year ago

We already have the real logs (the one we print out things). Logs are not stored anywhere but can be easily reproduced by re-execute the block. Right now they are mostly only used for debugging but there is no reason we can't use them for tracing purpose as well.

kianenigma commented 1 year ago

Based on @bkchr's comment, we actually have 3 levels of things:

  1. Digests
  2. Events
  3. Logs

Digests are information places in the header for light clients. We could have done the same for events as well, by putting a event_root in header.

Events as they stand now are not kept in state forever and are useful for light clients to get strong evidence that a certain transition happened.

What is being proposed here as Logs is something like Events but without the ability of any proof to be generated based on it. We can simply call them Unprovable Events, as opposed to the runtime events that are prove-able.

In the simplest case, it can be implement dead-simple via a new storage item that is deleted at the end of the block, and a new runtime api called fn get_unprovable_events() -> RuntimeEvent (the return type can be something different, or an arbitrary key value or something). The client can call this at the end of each block (prior to them being deleted), and then flush it out to stdout, as a HTTP endpoint or whatever other services need to listen to.


In any case, as far as I know this line of work, as described in the issue, will not be continued and we will focus more on https://github.com/paritytech/polkadot-sdk/issues/245