stacks-network / clarity-wasm

`clar2wasm` is a compiler for generating WebAssembly from Clarity.
GNU General Public License v3.0
14 stars 15 forks source link

Cost tracking in wasm #344

Open krl opened 9 months ago

krl commented 9 months ago

wasm cost differences

All the type checking happens at compile time, which makes runtime costs based on type checking redundant.

wasm compiled contracts

Compiling the cost contract into webassembly, and dynamically linking it seems like a possibility, however calling into the cost contract at each call, each arithmetic operation seems expensive, and might completely negate any gains from compilation in the first place.

I see a few alternatives.

Instead of calling into the cost contract at each point, global counters are incremented as we execute, and then all called into the cost contract at the end of the execution, or more often than that (for example, as functions return)

This would be more performant in the good path, but could lead to larger rollbacks in the bad cases.

Keep globals of the running amount for each operation, this would neccesitate around 22 globals, and we could use the current cost contract as is. If we assume we can use 32 bit values for these, that might be acceptabe.

Another alternative is to use globals directly for runtime/read/write, tallying up the costs as we run, which would make it neccesary to hardcode the values in the compiled contract itself, which would neccesitate re-complilation of contracts at cost function upgrades. This might be acceptable, since the cached compiled contracts could just be invalidated and re-compiled as they are called.

creating a new cost tracking logic from scratch

Also what we've discussed, is to create a new cost tracking with specifically wasm in mind. This would also make unnecesary any 1-to-1 matching with the old cost calculations (that are unfortunately not very well covered by tests).

In this case we would need to have a meeting to figure out exactly what problem it is we want to solve, and how it differs from the interpreted case.

krl commented 8 months ago

After taking discussions and future-compatability into account, I now believe the best way forward is to use the built-in metering fuel of wasmtime for the runtime cost calculations.

This has several advantages,

  1. It simplifies the implementation and optimization of the code, since this is an approach based on compiler middleware that has already been through optimization.
  2. It removes the restriction of using only clarity as the input language, and allows running wasm from other sources, such as compatability layers, without having to change the code.
  3. It is more accurate to measure on the wasm instruction level rather than the clarity level, since for example shortcuts in multiplication with smaller numbers will consume less fuel, whereas in clarity a large and a small multiplication costs the same.

Note that this is for the runtime cost only, for the read/write count of bytes it makes more sense to do it at the linker level, i.e when the code calls out to the host, which is also compatible with point 2 above.

krl commented 7 months ago

i know you're busy now, but could you have a look @obycode ?

smcclellan commented 7 months ago

@krl Is this in progress? I'll assign it to you until it's complete. When it's in In Review stage, you'll keep the assignment as you own it getting reviewed.

smcclellan commented 5 months ago

Blocked on https://github.com/stacks-network/clarity-wasm/issues/409 (removing circular dependencies in code).