Skip to content

Unchecked extrinsic: lazily decode the Call#4296

Closed
serban300 wants to merge 12 commits intoparitytech:masterfrom
serban300:unchecked-extrinsic
Closed

Unchecked extrinsic: lazily decode the Call#4296
serban300 wants to merge 12 commits intoparitytech:masterfrom
serban300:unchecked-extrinsic

Conversation

@serban300
Copy link
Copy Markdown
Contributor

Related to #4255

I hope I understood the idea correctly.

There are a 2 things I should mention:

  1. I think in the initial discussion, the idea was to store the encoded Call directly as a blob, without decoding it. However I think we need to decode it, in order to check if it's valid. I'm talking about this line. If we're not sure if it's valid, the decode_function() method will have to return a Result and I don't know if this would be acceptable for some of the call sites.

  2. With this new approach we have to decode the Call each time it's needed. So there can be a performance penalty more or less significant depending on how often the decoded call is actually needed. If it's not accessed very often, this implementation should be ok. If it's accessed often, we can try to cache the decoded call also. However for caching the decoded call there are 2 options, and both are problematic:

    • modifying the signature of the decode_call() method to take a mut reference to self. And in many places we don't have access to the mut UncheckedExtrinsic
    • using a mutex for internal mutability. Doesn't seem to be easy to do this from a no-std environment

@serban300 serban300 self-assigned this Apr 25, 2024
@serban300 serban300 requested a review from a team as a code owner April 25, 2024 14:29
@serban300 serban300 marked this pull request as draft April 25, 2024 14:29
@serban300 serban300 added R0-no-crate-publish-required The change does not require any crates to be re-published. I9-optimisation An enhancement to provide better overall performance in terms of time-to-completion for a task. labels Apr 25, 2024
@paritytech paritytech deleted a comment from paritytech-cicd-pr Apr 25, 2024
@serban300 serban300 marked this pull request as ready for review April 25, 2024 15:32
@serban300 serban300 changed the title [Draft] Unchecked extrinsic: lazy decode the Call Unchecked extrinsic: lazy decode the Call Apr 25, 2024
@serban300 serban300 changed the title Unchecked extrinsic: lazy decode the Call Unchecked extrinsic: lazily decode the Call Apr 25, 2024
@serban300 serban300 requested a review from bkchr April 29, 2024 06:37
@xlc
Copy link
Copy Markdown
Contributor

xlc commented Apr 29, 2024

I think we can do a quick check on how many times the decode_function is getting called per each extrinisc? Just add a log statement and run the node and submit transaction and check the logs. If it is 2 or 3, I think it is fine. If it is say 10, then we should optimize something.

@serban300
Copy link
Copy Markdown
Contributor Author

I think we can do a quick check on how many times the decode_function is getting called per each extrinisc? Just add a log statement and run the node and submit transaction and check the logs. If it is 2 or 3, I think it is fine. If it is say 10, then we should optimize something.

Sounds good. Will do that.

@serban300
Copy link
Copy Markdown
Contributor Author

serban300 commented Apr 30, 2024

Added a log statement and started a Rococo + Bridge Hub zombienet. This is what I'm getting in the bridge hub collator logs for a random block for example:

2024-04-30 11:12:30 Executed decode_function(): "0xfb4d44fb3460263937e57f5d0bf95d2ce4340019bdab7276e6fdb554d46933f4"    
2024-04-30 11:12:30 Executed decode_function(): "0xfb4d44fb3460263937e57f5d0bf95d2ce4340019bdab7276e6fdb554d46933f4"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0xfb4d44fb3460263937e57f5d0bf95d2ce4340019bdab7276e6fdb554d46933f4"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0xfb4d44fb3460263937e57f5d0bf95d2ce4340019bdab7276e6fdb554d46933f4"    
2024-04-30 11:12:30 Executed decode_function(): "0xfb4d44fb3460263937e57f5d0bf95d2ce4340019bdab7276e6fdb554d46933f4"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0x47b2318c44183fd580190a33ee1a7a75c97cecd53de3c6e7c92903ecb3bc4969"    
2024-04-30 11:12:30 Executed decode_function(): "0x52a397e48c0f9e75afcfc18a5692591016a25b02e3bbb578c041ff6095e46960"    
2024-04-30 11:12:30 Executed decode_function(): "0x52a397e48c0f9e75afcfc18a5692591016a25b02e3bbb578c041ff6095e46960"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0x52a397e48c0f9e75afcfc18a5692591016a25b02e3bbb578c041ff6095e46960"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0x52a397e48c0f9e75afcfc18a5692591016a25b02e3bbb578c041ff6095e46960"    
2024-04-30 11:12:30 Executed decode_function(): "0x52a397e48c0f9e75afcfc18a5692591016a25b02e3bbb578c041ff6095e46960"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0xf1e033d8058a7db6def218da2e536b3b33e1adaacb0cc2cccfb9f5cb12d075c0"    
2024-04-30 11:12:30 Executed decode_function(): "0xcea9a5e826d41aea4a00f1bd9f0aae9551bdeeb2427d4d665fb6c22a9953369f"    
2024-04-30 11:12:30 Executed decode_function(): "0x0ebd58300ee0d9b2588a4b435457e9dccc54c7387a05d88f3ab42515379ebef0"    
2024-04-30 11:12:30 Executed decode_function(): "0xd10927d4c9b07f5c219bed41f1d1f4c45e37df88bc1107fc474b706c69c1a7d5"    
2024-04-30 11:12:30 Executed decode_function(): "0x0c206bf261b17f99b6f8351cb9cdd501cc85ad910587fa8bbafb927150390228"    
2024-04-30 11:12:30 Executed decode_function(): "0xbb9bd4926a0077e2c75072a2cbe9d34dc018c1d5f8f5d3dd16baaff29dd2bd13"    
2024-04-30 11:12:30 Executed decode_function(): "0xbb9bd4926a0077e2c75072a2cbe9d34dc018c1d5f8f5d3dd16baaff29dd2bd13"    

Some calls are decoded 5 times, some 7 times, some 1 time. I'll check where this calls come from.

Later edit:
No, sorry, in the worst case scenario decode_function() is called more times:

2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0xf4f6448e12c6f02faa110712cddd43fd05bc91636b1a670672e81388a12d6800"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b"    
2024-04-30 17:18:48 Executed decode_function(): "0x69e3e926aba36fcf027c46cd939b77345c0ca23e783b5075edd9183fd248980f"    
2024-04-30 17:18:48 Executed decode_function(): "0x69e3e926aba36fcf027c46cd939b77345c0ca23e783b5075edd9183fd248980f"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0x392a6c711175b477500b4f06b435010f9c33f14e824db58becad22a6f979e9ed"    
2024-04-30 17:18:48 Executed decode_function(): "0x392a6c711175b477500b4f06b435010f9c33f14e824db58becad22a6f979e9ed"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xbc190426d8e754db9222deda4317dc2aa9c5adf6848f946feca6cc6f7b67dc1d"    
2024-04-30 17:18:48 Executed decode_function(): "0xbc190426d8e754db9222deda4317dc2aa9c5adf6848f946feca6cc6f7b67dc1d"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    
2024-04-30 17:18:48 Executed decode_function(): "0xed2ab3d8b1cd4e8899cd80e18911d5bf161368a4145a4bff58a4b40dcf918a70"    

21 times for 0x279d985234d70fb3649e8f0eaa328414c8d4104aad38aa2b5dd1d4de89f6584b for example

@serban300
Copy link
Copy Markdown
Contributor Author

Did some optimizations in this commit

Now it's something like:

2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0x7aa7bfde63a9072f9602b83cdbd56e9ec69ce235f2c7b7b474b5c2e574e498bb"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0xeebd7bbb74f07e7fc789b4b43390f0a33b1b3d303f2e68fd125326f8947160de"    
2024-04-30 17:38:54 Executed decode_function(): "0xe9d6757ff16002fbefb89475eccaa35add7b73c5e83f4b2f15f00fb727b66db2"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0xe9d6757ff16002fbefb89475eccaa35add7b73c5e83f4b2f15f00fb727b66db2"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0xe9d6757ff16002fbefb89475eccaa35add7b73c5e83f4b2f15f00fb727b66db2"    
2024-04-30 17:38:54 Executed decode_function(): "0xe9d6757ff16002fbefb89475eccaa35add7b73c5e83f4b2f15f00fb727b66db2"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0x7ddc64ac5789980a9cec6d5e0d557a044e60e061d021f8747c1c58638d09662a"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0x7ddc64ac5789980a9cec6d5e0d557a044e60e061d021f8747c1c58638d09662a"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0x7ddc64ac5789980a9cec6d5e0d557a044e60e061d021f8747c1c58638d09662a"    
2024-04-30 17:38:54 Executed decode_function(): "0x7ddc64ac5789980a9cec6d5e0d557a044e60e061d021f8747c1c58638d09662a"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977"    
2024-04-30 17:38:54 Executed decode_function(): "0x4b436b034c8e83ae0860d39f04827f4698f2d8f5dd4ac58cbb975084a6d6e977" 

The number of decodings for each function is down to around 8 times.

But from what I understand this is only happening for inherents because of calls to check_extrinsics() and is_inherent(). I guess that the inherents are normally pretty small.

@serban300
Copy link
Copy Markdown
Contributor Author

@xlc addressed/answered to your comment above. Please let me know if you have any thoughts on that.

@bkchr could you please take a look on the PR ? Any feedback would be helpful.

acatangiu
acatangiu previously approved these changes May 7, 2024
Comment thread cumulus/pallets/parachain-system/src/validate_block/implementation.rs Outdated
Comment thread substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs Outdated
Comment thread substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs Outdated
Copy link
Copy Markdown
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be more careful with these changes. They introduce a lot of extra decodings that mainly can be prevented if we rewrite some code.

Comment thread substrate/frame/support/src/dispatch.rs Outdated

/// Implementation for unchecked extrinsic.
impl<Address, Call, Signature, Extra> GetDispatchInfo
impl<Address, Call: Encode + Decode, Signature, Extra> GetDispatchInfo
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
impl<Address, Call: Encode + Decode, Signature, Extra> GetDispatchInfo
impl<Address, Call: Decode, Signature, Extra> GetDispatchInfo

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you check if we maybe can remove this implementation? That we need to decode here again the call to get this info is a little bit inconvenient.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't remove it. It is needed here. One option would be to cache the dispatch info.

Comment thread substrate/frame/support/src/traits/misc.rs
Comment thread substrate/frame/support/procedural/src/construct_runtime/expand/inherent.rs Outdated
// We use the dedicated `is_inherent` check here, since just relying on `Mandatory` dispatch
// class does not capture optional inherents.
let is_inherent = System::is_inherent(&uxt);
if !<frame_system::Pallet<System>>::inherents_applied() && !System::is_inherent(&uxt) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here we decode the function and then do it directly again inside check below.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed together with the comment regarding EnsureInherentsAreFirst. Added a way of caching the decoded function.

Comment thread substrate/primitives/runtime/src/generic/unchecked_extrinsic.rs Outdated
Comment thread substrate/primitives/io/src/lib.rs Outdated
pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic {
/// Get the call of the extrinsic.
fn call(&self) -> &Self::Call;
fn call(&self) -> Self::Call;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably return Result here to make it more obvious that this maybe includes decoding or maybe any better approach.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't return result since it would complicate things and normally it should also be decodable. We could rename the method maybe. WDYT ?

if let Some(call) = IsSubType::<_>::is_sub_type(&call) {
if <#pallet_names as ProvideInherent>::is_inherent(&call) {
return true;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EnsureInherentsAreFirst below should be able to be replaced with some logic in Executive. Otherwise we are decoding twice.

Copy link
Copy Markdown
Contributor Author

@serban300 serban300 May 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Also added a way of caching the decoded function. PTAL

The relevant commits are:

input.remaining_len()?.and_then(|a| before_length.map(|b| (b, a)))
let mut input = CopyReader::new(input);
// We have to check that the function decodes correctly.
Call::decode(&mut input)?;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really finally need to get some proper skip implemented.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand on this please ? I'm not sure if I understand.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you mean to just skip the encoded function bytes without decoding it, the problem is that we will have to return a Result<> from the methods that decode the function and:

  1. I'm not sure how hard it will be to propagate this Result<> to all the call sites
  2. I'm not sure if it's ok to panic at a later time for example if the function can't be decoded

I will look into it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think I finally got it. I replaced this with Call::skip(&mut input), but from what I understand it still does decode internally. I agree we should implement a proper skip, but maybe in a separate PR ? I guess it's something that we should do in the parity-scale-codec crate, right ?

Comment on lines +252 to +258
if let Some(call) = xt.call().is_sub_type() {
match call {
crate::Call::set_validation_data { data: validation_data } =>
return validation_data.clone(),
_ => {},
}
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the old logic with an early return on finding the set_validation_data. Now we decode multiple calls before we check them.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you don't need to clone validation_data because you own the call

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the old logic with an early return on finding the set_validation_data. Now we decode multiple calls before we check them.

Reverted to something closer to the old logic.

Also you don't need to clone validation_data because you own the call

The problem is that is_sub_type() returns a reference. And the call is owned by the current method. I couldn't find a straightforward way to avoid cloning. There would be options like:

  • adding a try_into_sub_type() method
  • Returning the call and executing is_sub_type() again from the calling function
  • moving this logic outside of the function. I see that it's only used once.
  • some unsafe {} code block maybe

Moving the logic out of the function seems like the easiest thing right now in my opinion.

Copy link
Copy Markdown
Contributor Author

@serban300 serban300 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed only some of the easier comments so far

Comment thread substrate/frame/support/src/dispatch.rs Outdated

/// Implementation for unchecked extrinsic.
impl<Address, Call, Signature, Extra> GetDispatchInfo
impl<Address, Call: Encode + Decode, Signature, Extra> GetDispatchInfo
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't remove it. It is needed here. One option would be to cache the dispatch info.

pub trait ExtrinsicCall: sp_runtime::traits::Extrinsic {
/// Get the call of the extrinsic.
fn call(&self) -> &Self::Call;
fn call(&self) -> Self::Call;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't return result since it would complicate things and normally it should also be decodable. We could rename the method maybe. WDYT ?

input.remaining_len()?.and_then(|a| before_length.map(|b| (b, a)))
let mut input = CopyReader::new(input);
// We have to check that the function decodes correctly.
Call::decode(&mut input)?;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand on this please ? I'm not sure if I understand.

Comment on lines +252 to +258
if let Some(call) = xt.call().is_sub_type() {
match call {
crate::Call::set_validation_data { data: validation_data } =>
return validation_data.clone(),
_ => {},
}
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep the old logic with an early return on finding the set_validation_data. Now we decode multiple calls before we check them.

Reverted to something closer to the old logic.

Also you don't need to clone validation_data because you own the call

The problem is that is_sub_type() returns a reference. And the call is owned by the current method. I couldn't find a straightforward way to avoid cloning. There would be options like:

  • adding a try_into_sub_type() method
  • Returning the call and executing is_sub_type() again from the calling function
  • moving this logic outside of the function. I see that it's only used once.
  • some unsafe {} code block maybe

Moving the logic out of the function seems like the easiest thing right now in my opinion.

Comment thread substrate/frame/support/src/traits/misc.rs
@paritytech-review-bot paritytech-review-bot bot requested a review from a team May 21, 2024 11:12
@acatangiu acatangiu dismissed their stale review October 28, 2024 12:21

stale, needs rework

@serban300 serban300 closed this by deleting the head repository Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I9-optimisation An enhancement to provide better overall performance in terms of time-to-completion for a task. R0-no-crate-publish-required The change does not require any crates to be re-published.

Projects

Status: Audited

Development

Successfully merging this pull request may close these issues.

5 participants