Unfortunately this is wildly incorrect. (: You’re right that it’s possible, but the details are wrong.
- Implementing safe gas metering isn’t as simple as just assigning a best-case cycle value to each instruction and calling it a day. For example, looking at your list of costs for each instruction I can see that you’ve assigned a cost of 3 cycles to each memory load instruction. It’s possible to relatively easily write a program that will make this instruction takes orders of magnitudes more cycles by deliberately triggering cache misses (and a cache miss can be hundreds of CPU cycles, which is a little more than just 3!). Even if you severely limit the maximum amount of memory the program can access (so that its working set fits in L3 cache) its still possible to exploit various microarchitectural corner cases to make memory accesses significantly more expensive. You can use such simple gas cost model in the average case and it will work, but as soon as someone is motivated enough to take down your chain they can launch a denial of service attack exploiting this.
- You cannot use hardware performance counters to do gas metering, simply because they are not portable across different hardware and they are non deterministic - even if you run exactly the same program on exactly the same hardware you will get a different cycle count!