-
Notifications
You must be signed in to change notification settings - Fork 404
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: storage deposit #4035
base: master
Are you sure you want to change the base?
feat: storage deposit #4035
Conversation
🛠 PR Checks SummaryAll Automated Checks passed. ✅ Manual Checks (for Reviewers):
Read More🤖 This bot helps streamline PR reviews by verifying automated checks and providing guidance for contributors and reviewers. ✅ Automated Checks (for Contributors):🟢 Maintainers must be able to edit this pull request (more info) ☑️ Contributor Actions:
☑️ Reviewer Actions:
📚 Resources:Debug
|
Codecov ReportAttention: Patch coverage is 📢 Thoughts on this report? Let us know! |
Closes #3418 |
@@ -24,7 +24,7 @@ func main() { | |||
|
|||
// Realm: | |||
// switchrealm["gno.land/r/test"] | |||
// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4]= | |||
// u[a8ada09dee16d791fd406d629fe29bb0ed084a30:4](2)= |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i like this syntax.
@@ -0,0 +1,80 @@ | |||
# test the storage rent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't rent. It's ownership. (but we already use "owner" for objects so need a different term).
Rent is when you pay an upkeep for something.
GNOT deposits are forever.
just "deposit".
@@ -328,6 +330,7 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) (err error) { | |||
creator := msg.Creator | |||
pkgPath := msg.Package.Path | |||
memPkg := msg.Package | |||
send := msg.Send |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self: is send amount segregated from storage deposits?
(the realm should not be able to spend its storage deposits)
m2.RunMemPackage(memPkg, true) | ||
|
||
// use the parameters before executing the message, as they may change during execution. | ||
// The message should not fail due to parameter changes in the same transaction. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wild edge case!
// QueryStorage returns storage and deposit for a realm. | ||
func (vm *VMKeeper) QueryStorage(ctx sdk.Context, pkgPath string) (string, error) { | ||
store := vm.newGnoTransactionStore(ctx) // throwaway (never committed) | ||
// Ensure pkgPath is realm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not allow the query for packages? could be good to know, even if it is not mutable.
// An error is returned if there's insufficient deposit, a transfer error occurs, | ||
// or an invariant violation happens during deposit or storage adjustments. | ||
|
||
func (vm *VMKeeper) processDeposit(ctx sdk.Context, caller crypto.Address, deposit std.Coins, gnostore gno.Store, params Params) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
process storage deposit
} else { | ||
// release storage used and return deposit | ||
released := -diff | ||
if rlm.Storage < uint64(released) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to self: why is this check needed?
rlmPath, rlm.Deposit, ugnot.Denom, depositUnlocked, ugnot.Denom)) | ||
} | ||
|
||
err := vm.refundStorageDeposit(ctx, caller, rlm, depositUnlocked, released) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the refund should happen aggregated once, not per realm.
@@ -87,6 +87,24 @@ func Quotient8(a, b int8) (int8, int8, bool) { | |||
return c, a % b, status | |||
} | |||
|
|||
// AddUint8 performs + operation on two uint8 operands, returning a result and status. | |||
func AddUint8(a, b uint8) (uint8, bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is cool, is it used?
// Unstable. | ||
// This function is used to clear the object cache every transaction. | ||
// It also sets a new allocator. | ||
func (ds *defaultStore) ClearObjectCache() { | ||
ds.alloc.Reset() | ||
ds.cacheObjects = make(map[ObjectID]Object) // new cache. | ||
ds.opslog = nil // new ops log. | ||
ds.objectSizeCache = make(map[ObjectID]int64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's put this in ObjectInfo as unexposed lastObjectSize
so as to avoid a map lookup.
@@ -86,6 +87,7 @@ func (msg MsgAddPackage) GetReceived() std.Coins { | |||
type MsgCall struct { | |||
Caller crypto.Address `json:"caller" yaml:"caller"` | |||
Send std.Coins `json:"send" yaml:"send"` | |||
Deposit std.Coins `json:"deposit" yaml:"deposit"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest "MaxDeposit" so it's clear it's not just sending coins, it's doing something and you get something back.
Also json omitempty so that users don't have to worry about it usually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall direction looks great, just needs some changes. Please call me after changes.
sysNamesPkgDefault = "gno.land/r/sys/names" | ||
chainDomainDefault = "gno.land" | ||
defaultDepositDefault = "600000000ugnot" | ||
storagePriceDefault = "1000ugnot" // cost per byte (1 gnot per KB) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
100, 1B GNOT == 10TB.
Solution for : #3418
BREAKING CHANGES
New Message Flag
AddPkg Additional Logic
send
flag to send tokens to the realm.deposit
flag to specify how much GNOT to include for storage fees.-deposit
flag was used in place of-send
within AddPkg.Purpose
Paying for Storage
Whenever data is stored in a realm (e.g., via
SetObject
), an amount of GNOT is locked as a “storage deposit.”Reclaiming Storage & Deposit
When stored data is removed, the corresponding deposit is released back to the user.
Encouraging Efficient Storage
Users must pay to keep data on-chain, incentivizing them to store only what is necessary.
High-Level Design
The system imposes a GNOT deposit for stored data. Each realm tracks its total number of bytes in use and the total tokens locked for that storage. After each message is processed, the net change in storage usage is calculated, and the appropriate amount of GNOT is locked or unlocked. By default, deposit tracking is aggregated per realm rather than per user. Any user refunds or reward mechanisms for freeing storage are determined by the realm.
Usage Tracking
Realm-Level Tracking
Global VM Parameters
Message-Level Fields
MsgCall
/MsgRun
/AddPkg
): The user can specify how many GNOT to deposit for potential storage usage.Deposit & Retrieval Flow
Make a
MsgCall
/MsgRun
/AddPkg
CallDuring Execution
Anyone Can Free Storage
Tools
gnokey query vm/qstorage -data <realm_path>
: Shows a realm’s locked tokens and current storage usage.Storage:
directive can be added to file tests to display storage usage across realms.Future Improvements