gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
849 stars 345 forks source link

Package calls + deployments cost a fixed number of `ugnot` #649

Closed zivkovicmilos closed 1 month ago

zivkovicmilos commented 1 year ago

Description

This issue is meant to start a discussion on how we can improve the pricing model for package calls and deployments, as they currently cost a fixed 1000000ugnot:

These fees should probably be outlined somewhere so users are aware of them upfront

nir1218 commented 1 year ago

@zivkovicmilos One option is to set cost per byte. Assume the cost per byte is set to 1ugnot, and the message length is 100000, the total cost will be 100000ugnot.

Another option is to set a percentage amount from the deposit/coins sent in the message.

grepsuzette commented 1 year ago

Not directly answering anything but I a question about fees:

Suppose a package do involved stuffs, or maybe the complexity of an algo is bad.

Does gno currently have mechanism(s) to limit the actual resources used in that case and when it's not a transaction? (because then supposedly, fee=0, does my question make sense? In essence I am asking if the VM will refuse to work after some maximum mileage has been done for free).

(edit: I guess that would be gas like on other blockchains, so I suppose gno also has it :p).

thehowl commented 1 year ago

I think the fee for call should probably be something like $c + k \Delta m$, c = vm cpu cycles, $\Delta m$ = difference in persisted data (after compression?) in bytes, with k being a value that puts in relation memory to cpu cycles.

I like the idea that in the future, the economic value of a single ugnot should roughly match the economic cost of doing 1 gnovm cycle (= an infinitesimal amount of USD). As for the value of k, I think it's very very tricky. It's essentially the cost of storing 1 byte of data for ""eternity"" with potentially infinite replication, which from a theoretical point of view is probably on the order of a few thousand dollars, but for practical terms this should be closer to something like 1 USD = 10kb (the core idea being, if we are to have social platforms like a twitter clone on Gno, my yearly cost for participating shouldn't be more than 4$). But really, I think it should be much more expensive than VM cycles (storing data is expensive, verifying a transaction is comparatively cheap) and it needs to be defined after we give full answers to questions like "what do we do when the size of all transactions reaches 100TB?".

One other thing is that counting bytes when doing addpkg creates an incentive to write smaller packages with less code. Which leads to obfuscation, short variable names, no comments. Which is why I think that it makes sense for addpkg to instead count the number of AST nodes, for instance, instead of rough code size.

There should then also probably be a fixed fee for storing a single transaction, call it "overhead", but roughly still $k\Delta m$ given by the amount of bytes we require to store tx data.


@grepsuzette "free" operations (like qeval, qrender) should have some form of limit. Transactions have gas (mem allocations + cpu cycles), public operations which are not transactions should probably be either removed before mainnet or limited in some way for safety. (ie. rate-limit cycles/allocs per ip per hour, make them in general low-priority so that blockchain TXs are executed first). Right now the only limit is vm.maxCycles, I guess.

Seeing as they are executed on a single node and it's not data that is propagated to other nodes, we could even make it that nodes can disable public calls entirely (including qrender, which is used for gnoweb). A bit extreme, but definitely creates some security against DoS attacks.

MichaelFrazzy commented 1 year ago

I think the fee for call should probably be something like c+kΔm, c = vm cpu cycles, Δm = difference in persisted data (after compression?) in bytes, with k being a value that puts in relation memory to cpu cycles.

I like the idea that in the future, the economic value of a single ugnot should roughly match the economic cost of doing 1 gnovm cycle (= an infinitesimal amount of USD). As for the value of k, I think it's very very tricky. It's essentially the cost of storing 1 byte of data for ""eternity"" with potentially infinite replication, which from a theoretical point of view is probably on the order of a few thousand dollars, but for practical terms this should be closer to something like 1 USD = 10kb (the core idea being, if we are to have social platforms like a twitter clone on Gno, my yearly cost for participating shouldn't be more than 4$). But really, I think it should be much more expensive than VM cycles (storing data is expensive, verifying a transaction is comparatively cheap) and it needs to be defined after we give full answers to questions like "what do we do when the size of all transactions reaches 100TB?".

One other thing is that counting bytes when doing addpkg creates an incentive to write smaller packages with less code. Which leads to obfuscation, short variable names, no comments. Which is why I think that it makes sense for addpkg to instead count the number of AST nodes, for instance, instead of rough code size.

There should then also probably be a fixed fee for storing a single transaction, call it "overhead", but roughly still kΔm given by the amount of bytes we require to store tx data.

@grepsuzette "free" operations (like qeval, qrender) should have some form of limit. Transactions have gas (mem allocations + cpu cycles), public operations which are not transactions should probably be either removed before mainnet or limited in some way for safety. (ie. rate-limit cycles/allocs per ip per hour, make them in general low-priority so that blockchain TXs are executed first). Right now the only limit is vm.maxCycles, I guess.

Seeing as they are executed on a single node and it's not data that is propagated to other nodes, we could even make it that nodes can disable public calls entirely (including qrender, which is used for gnoweb). A bit extreme, but definitely creates some security against DoS attacks.

I love these ideas and the equation as a starting point. Will dig in more here after wrapping up another doc, for now I have some initial thoughts on how we can further improve the equation to bounce around!

I think using a logistic relationship between delta m and the fee instead of linear should be considered. Potentially exponential if we don't want there to be an upper bound/limit for fees, but if we set the top of the logistic curve high enough... an upper bound (logistic) is probably preferable overall. Logistic will also be easier to test vs expo, since we can define an upper fee bound and then I can model different coefficients to control how quickly it reaches that cap before I stress test the final version. Another nice side effect is it results in a slow fee ramp up when the network isn't as congested, with extreme fee increases only after a certain threshold we can set. I can start drafting up some different logistic equations that can be added within the existing equation, for now just to see how it plays out. Would be curious to see if CPU cycles themselves are more linear or logistic in nature as they ramp up.

Probably worth brainstorming dynamic k range ideas instead of a fixed value too, I think your concerns are spot on when it comes to defining an exact value there. We could talk through some sliding scale ideas here based on transaction rate, block fullness, or whatever network metric is deemed the best overall while not being crazy to implement.

A couple questions as well, do we want a feature where similar to EVM you can pay extra fees to prioritize your transaction and speed up how quickly it's processed? So adding a time variable into the equation with most transactions using a base time value we'd define for normal transactions that aren't expedited? And will certain transactions have the ability to work similarly to signing a message on ETH (for free)? Think when casting a snapshot vote, signing a multi-sig, or something else where no gas is required. What comes to mind here is some of the social media applications (maybe with a subscription fee model), certain voting actions, etc. Then anything free we could limit per amount of time or per number of blocks to prevent spam for these particular operations, if it's possible to implement in the first place.

zivkovicmilos commented 1 month ago

This fixed pricing was removed as part of #1430, closing this issue