massa
massa copied to clipboard
Expose storage config in node api + AS abi
To compute storage cost of an operation some constants must be known and may be specific to a network. To avoid these constants to be hardcoded and to easily support changes when they are not the same among networks, these constants should be somewhere in the node API and in the AS vm ABI.
Here i am thinking of storage constants like "StorageCostPerByte" or "AccountCreationCost", but there is most likely other constant that should be dynamically available
We already have endpoints to expose config data both in JSON and GRPC. This issue consists in adding the following constants there as well:
- LEDGER_COST_PER_BYTE: Amount
- LEDGER_ENTRY_BASE_COST: Amount
- LEDGER_ENTRY_DATASTORE_BASE_SIZE: u64
And also adding it somewhere in AS VM to be used in SmartContracts
And also adding it somewhere in AS VM to be used in SmartContracts
in which exact situation is that needed ?
everytime you need to call a smartContract from another. To compute the "coin" param
everytime you need to call a smartContract from another. To compute the "coin" param
How critical is this need currently on your side ?
not really critical. Its just to avoid hardcoded value. And it will allow to write smartContract compatible for different network configuration. like today where buildnet and testnet 26 have different storage costs.
But more generally, i think this coin parameters is really painfull to use. If you think about a possible way of automatically compute the storage cost, i ll take it
You could do the following for now:
- have the smart contract exported functions do this:
- at the beginning of the function:
let begin_balance = get_balance()
- at the end of the function:
let what_caller_had_to_pay = get_balance() - begin_balance; // can be negative, for example if storage was freed // TODO adjust what_caller_had_to_pay if some gains/expenses that happened during the call SC are not to be charged on the caller but on the SC itself let what_caller_paid = get_coins(); if what_caller_paid < what_caller_had_to_pay { abort("not enough coins provided to cover expenses"); // revert the whole call to avoid balance loss from the SC itself } else if what_caller_paid > what_caller_had_to_pay { transfer(to: get_caller(), amount: what_caller_paid - what_caller_had_to_pay); // refund any excess to the caller }
- at the beginning of the function:
- instruct developers to document coin costs (and gas costs as well) when documenting the usage of an exported function. That way, callers know how much to put, it crashes if not enough is given, and any excess is refunded so callers can even take some margin (eg. 10% or so).
Until we come up with a better solution
ok good to know but my main issue is not about refunding the user. its to be able to put a correct value in the "coin" parameter. when calling an SC. Indeed if this SC implements the code you provided, i can put a dummy high value knowing the coins left will be refunded.
If you think its the way to go, This behaviour should be implemented for every contract, without the need of writing code yourself. (Or maybe activated by a config option)
About documenting the cost for an exported function, it may be difficult to achieve when cost is variable and depends on the smartContracts (or even other smartContracts) state.
but the point of the issue was only to avoid hardcoded values ^^ like here: https://github.com/massalabs/massa-standards/blob/b2e665cc62831de4dc5c0a33cb29e2b5e714b494/smart-contracts/assembly/contracts/website-deployer/websiteDeployer.ts#L20-L30
I prefer us to take time to decide on an unified way of doing coin, gas, fee estimates and automate it as much as possible. In the meantime, here are some ideas on how to improve things on your side without heavy changes.
Conceptually, instead of the caller speculating some calculations on how much coins the callee will possibly use, it's up to the callee to provide information on how its exported functions are supposed to be called in terms of gas and coins. That information can be conveyed either through human or automatic documentation, or through a callee-exported exported read-only estimate function in the format:
export re1_estimate_call_coins(called_function_name, function_params) → amount
Then it's up to the callee to have the things I mentioned above to mitigate cases of under/over payment.
Yeah totally agree on that, and this idea of estimate_call_coins
is nice!
But to implement it, i still need to have the value of LEDGER_COST_PER_BYTE, which lead us back to my first need expressed!
Well, for now let's stick to constants (ideally on the callee side) until we prioritize that ABI