Premise
- Substrate will, by default, store every event in a block in a storage value
Event
of typeVec<EventRecord>
in the system module, which involves reading & writing this full vector each time, as explained here https://stackoverflow.com/questions/57219830/what-is-the-cost-of-event-storage-in-substrate. - The time it takes to read/write to the database increases with the size of the object being read, at least eventually in expectation.
Problem
If an extrinsic emits an event with has some payload with some size, say like a user provided Vec<u8>
, then an attacker can submit a series of such extrinsics, radically increasing the size of this vector, and as a result making the real computational weight of all subsequent extrinsics in that same block much greater than what is reported by their weight functions, and also no fee is paid for this computation. In essence all weight functions for those extrinsics are wrong now. This problem increases in severity independently with block weight/length limits, and the size of individual events, because both independently can be used to bloat the size of Events
.
Unfortunately, it's also in practice not feasible to opt out of the default behavior in the System module, as there is no storage of logs or events in Substrate that can be exposed to the myriad of tools that need to inspect this, they all rely on storage state snapshots in archival nodes.
Questions
- Is this an accurate summary?
- How was it determined that this is already not a problem in Polkadot or Kusama?