ink icon indicating copy to clipboard operation
ink copied to clipboard

Reworked message dispatch logic

Open xgreenx opened this issue 4 years ago • 13 comments

In this PR I moved common parts of each message to execute_dispatchable(pull of the contract). In the future, we can optimize it to do one push of the contract.

Introduced an additional static buffer to store input. Now the user has access to the input buffer at any time during the execution of the contract(it is loaded only one time). This buffer is needed to rework the decoding process.

Moved the decode logic to the CALLABLE part. It allows the compiler to use value after decoding and do some optimization.

Call unwrap instead of passing error upper during execute dispatchable and decoding. It allows the compiler to optimize the code better.

Optimized return_value function to simply use buffer for encoding the result. We don't need complex methods from ScoppedBuffer because after the call of that method the program will exit.

All these optimizations allow reducing the code of optimized contracts well.

Erc20 takes 7862 bytes instead of 10282(saved 2420).

The more methods in the contract, the stronger the effect of the change. That contract contains a lot of methods and the chagne saved 6489 bytes: Original wasm size: 71.8K, Optimized: 38.8K(38844) -> Original wasm size: 81.7K, Optimized: 32.4K(32355)

xgreenx avatar Nov 15 '21 23:11 xgreenx

@xgreenx You can get the ink-waterfall stage to run by removing the failing CI checks altogether from .gitlab-ci.yml. So just remove all failing stages (clippy-std, clippy-wasm, etc.) and push these changes to this PR.

cmichi avatar Nov 16 '21 16:11 cmichi

@xgreenx You can get the ink-waterfall stage to run by removing the failing CI checks altogether from .gitlab-ci.yml. So just remove all failing stages (clippy-std, clippy-wasm, etc.) and push these changes to this PR.

ink-waterfall failed=( tests::delegator::delegator_works. I tried it on local node and it works(manually, didn't try to run a test). Maybe it is not enough gas?

xgreenx avatar Nov 16 '21 18:11 xgreenx

@xgreenx You can get the ink-waterfall stage to run by removing the failing CI checks altogether from .gitlab-ci.yml. So just remove all failing stages (clippy-std, clippy-wasm, etc.) and push these changes to this PR.

ink-waterfall failed=( tests::delegator::delegator_works. I tried it on local node and it works(manually, didn't try to run a test). Maybe it is not enough gas?

Oh, after my change the contract requires 53k additional gas=D Because I'm allocating 16MB in stack=D But I think we can decide in this PR how to optimize it(for example use static buffer form instance)

xgreenx avatar Nov 16 '21 18:11 xgreenx

🦑 📈 ink! Example Contracts ‒ Changes Report 📉 🦑

These are the results when building the examples/* contracts from this branch with cargo-contract 0.17.0-06c5598 and comparing them to ink! master:

Δ Optimized Size Δ Used Gas Total Optimized Size Total Used Gas
accumulator +1.62 K 1.62 K
adder +2.82 K 2.82 K
contract-terminate -0.12 K -1 1.19 K 200_777
contract-transfer -0.05 K +16 7.94 K 1_415
delegator -0.86 K -1_063 9.20 K 8_447
dns -1.14 K -1_816 9.33 K 12_472
erc1155 -2.88 K -3_718 24.62 K 44_093
erc20 -2.06 K -1_929 8.16 K 7_828
erc721 -2.44 K +1_264 11.26 K 35_966
flipper +0.04 K +21 1.81 K 368
incrementer +0.05 K +23 1.69 K 363
multisig -1.20 K -6_313 27.36 K 48_583
proxy -0.23 K -80 3.58 K 2_549
rand-extension -1.07 K -92 4.04 K 6_562
subber +2.83 K 2.83 K
trait-erc20 -2.08 K -1_928 8.44 K 8_716
trait-flipper +1.62 K +22 1.62 K 364
trait-incrementer +1.73 K +47 1.73 K 727

Link to the run | Last update: Thu Jan 27 10:40:02 CET 2022

paritytech-ci avatar Nov 16 '21 18:11 paritytech-ci

I want to clarify, that it is draft PR to show the idea=) I will add documentation and tests when you will agree with the idea(=

xgreenx avatar Nov 19 '21 11:11 xgreenx

Codecov Report

Merging #1017 (2b808cc) into master (2785a90) will increase coverage by 2.74%. The diff coverage is 88.48%.

@@            Coverage Diff             @@
##           master    #1017      +/-   ##
==========================================
+ Coverage   75.69%   78.44%   +2.74%     
==========================================
  Files         252      253       +1     
  Lines        9395     9487      +92     
==========================================
+ Hits         7112     7442     +330     
+ Misses       2283     2045     -238     
Impacted Files Coverage Δ
crates/env/src/api.rs 40.90% <0.00%> (+4.54%) :arrow_up:
crates/env/src/backend.rs 83.87% <ø> (+3.22%) :arrow_up:
...tes/env/src/engine/experimental_off_chain/impls.rs 53.15% <0.00%> (-0.98%) :arrow_down:
crates/lang/codegen/src/generator/arg_list.rs 100.00% <ø> (ø)
crates/lang/codegen/src/generator/mod.rs 100.00% <ø> (ø)
crates/lang/src/reflect/dispatch.rs 70.00% <ø> (+70.00%) :arrow_up:
crates/env/src/engine/off_chain/impls.rs 46.55% <20.00%> (+4.17%) :arrow_up:
.../tests/ui/contract/pass/dispatch-executor-works.rs 94.59% <94.59%> (ø)
crates/lang/codegen/src/generator/dispatch.rs 98.98% <95.12%> (+4.41%) :arrow_up:
...rates/env/src/engine/experimental_off_chain/mod.rs 100.00% <100.00%> (ø)
... and 68 more

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more

codecov-commenter avatar Nov 28 '21 01:11 codecov-commenter

The change reduces the size of each contract except subcontracts of the delegator example. I will check why and how we can improve it too.

The open question is: Are we okay to have a separate static buffer to store input of the contract?

xgreenx avatar Nov 28 '21 01:11 xgreenx

I found that all contracts from workspace contain debug information(stuff related to Debug and Display). It increases the size of all contracts there.

Removing [workspace] decreases the size of each contract. I think it is better to remove it to see the actual size of the contracts.

xgreenx avatar Nov 28 '21 03:11 xgreenx

The change is ready, so I'm waiting for your comments=)

The change affects delegator sub-contract in a positive direction too is saves ~300 bytes.

xgreenx avatar Nov 29 '21 13:11 xgreenx

@xgreenx can you update this for the latest master? I'm curious as to how the size improvements look. Since this is a big change to the dispatch logic I think we should only move forward with it if the savings look good

HCastano avatar Jan 26 '22 23:01 HCastano

ink-waterfall didn't update the sizes=)

xgreenx avatar Jan 27 '22 01:01 xgreenx

ink-waterfall didn't update the sizes=)

Yep, looks like there's a problem (https://github.com/paritytech/ink-waterfall/issues/20).

The job did succeed though, and here are the results (link to run):

|                      | Δ Optimized Size | Δ Used Gas | Total Optimized Size | Total Used Gas |
|----------------------|------------------|------------|----------------------|----------------|
| `accumulator`        | +0.19 K          |            | 1.62 K               |                |
| `adder`              | -0.12 K          |            | 2.82 K               |                |
| `contract-terminate` | -0.12 K          | -1         | 1.19 K               | 200_777        |
| `contract-transfer`  | -0.05 K          | +16        | 7.94 K               | 1_415          |
| `delegator`          | -0.86 K          | -1_063     | 9.20 K               | 8_447          |
| `dns`                | -1.14 K          | -1_816     | 9.33 K               | 12_472         |
| `erc1155`            | -2.88 K          | -3_718     | 24.62 K              | 44_093         |
| `erc20`              | -2.06 K          | -1_929     | 8.16 K               | 7_828          |
| `erc721`             | -2.44 K          | +1_264     | 11.26 K              | 35_966         |
| `flipper`            | +0.04 K          | +21        | 1.81 K               | 368            |
| `incrementer`        | +0.05 K          | +23        | 1.69 K               | 363            |
| `multisig`           | -1.20 K          | -6_313     | 27.36 K              | 48_583         |
| `proxy`              | -0.23 K          | -80        | 3.58 K               | 2_549          |
| `rand-extension`     | -1.07 K          | -92        | 4.04 K               | 6_562          |
| `subber`             | -0.13 K          |            | 2.83 K               |                |
| `trait-erc20`        | -2.08 K          | -1_928     | 8.44 K               | 8_716          |
| `trait-flipper`      | +0.09 K          | +22        | 1.62 K               | 364            |
| `trait-incrementer`  | +0.11 K          | +47        | 1.73 K               | 727            |

So the savings are alright, but they're not mindblowing either. I'm on the fence about this given the nature of the changes, but give me some time to try and better understand the new dispatch logic you're proposing before we decide what to do

HCastano avatar Jan 27 '22 04:01 HCastano

So the savings are alright, but they're not mindblowing either

The more methods in the contract, the stronger the effect of the change. That contract contains a lot of methods and the change saved 6489 bytes

xgreenx avatar Jan 27 '22 09:01 xgreenx

@xgreenx This has been neglected for a while (I guess mostly by us, sorry).

If you want to revive it please open a new PR so we can a fresh perspective and set of sizes

HCastano avatar Feb 23 '23 22:02 HCastano