This question is about these lines in FRAME Executive's apply_extrinsic function

    pub fn apply_extrinsic(uxt: Block::Extrinsic) -> ApplyExtrinsicResult {
        // --snip--

        // We don't need to make sure to `note_extrinsic` only after we know it's going to be
        // executed to prevent it from leaking in storage since at this point, it will either
        // execute or panic (and revert storage changes).

        // AUDIT: Under no circumstances may this function panic from here onwards.

        // --snip--

The comment before the extrinsic is noted explains that if the extrinsic turns out to be bad, this function will panic and revert the storage changes. Therefore, it is okay to note the extrinsic right away before it has even been applied (where noting means recording it in temporary storage to later calculate the extrinsics root). This makes sense to me.

However, the comment after the extrinsic is noted emphasizes that it is not okay to panic anywhere else in that function.

So how are these comments consistent with each other? They seem to contradict each other.

1 Answer 1


Yes the function can panic and then the node side should revert the storage changes (there is no guarantee for that from the runtime). However, if a transaction is panicking it means there is a DOS vector. An attacker could send a transaction that makes it into the pool and while applying it to a block it panics. The attacker doesn't need to pay for it and thus can send a lot of these transactions, preventing the inclusion of any other transaction. Even if it doesn't prevent the inclusion of other transactions, it will still waste resources of the block builder preventing them from including the maximum possible amount of transactions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.