-
Notifications
You must be signed in to change notification settings - Fork 371
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: add realm r/demo/keystore #958
Conversation
this realm provides a way to interact with the avl.Tree through gno.land as well as through transactions so that users can have individualized keystores.
Hi @schollz! do you mind adding the checks from the PR template? thanks! |
Yes. Sorry about that @ajnavarro , will do so |
Checklist added! Looks like I'm missing benchmarks...let me know if that's something that should be added. |
Thanks a lot, @schollz , if you didn't add any new benchmarks, you can check that too. These are just reminders of things that we usually miss but they help with the reviews and to keep the repo up and running. |
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.
Looks good 💯
I've left a few comments that would simplify the code.
I love the idea of using this as a DB for user public keys, I think it eases that part of knowledge sharing
var ( | ||
BaseURL = "/r/demo/keystore" | ||
StatusOK = "ok" | ||
StatusNoUser = "user not found" | ||
StatusNotFound = "key not found" | ||
StatusNoWriteAccess = "no write access" | ||
StatusCouldNotExecute = "could not execute" | ||
) | ||
|
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.
These can be constants
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.
Thanks, fixed in 76b7131
origOwner := std.GetOrigCaller() | ||
if origOwner.String() != owner { | ||
return StatusNoWriteAccess | ||
} | ||
keystoreInterface, exists := data.Get(owner) |
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.
What do you think about extracting this out into a specific helper method?
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'm of the mind to leave it - it only occurs twice in the code and moving out into a function may only reduce the code by a few lines.
data.Set(owner, &KeyStore{ | ||
Owner: origOwner, | ||
Data: avl.Tree{}, | ||
}) | ||
keystoreInterface, _ = data.Get(owner) | ||
} | ||
keystore := keystoreInterface.(*KeyStore) | ||
keystore.Data.Set(k, v) | ||
return StatusOK |
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 are you setting the keystore, and then fetching it again from the map (avl)?
Why not simply define a var keystore KeyStore
outside the condition, and if it doesn't exist, assign it in the branch?
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.
You are totally right, thanks for that. Its fixed in 61079bb
data.Set(owner, &KeyStore{ | ||
Owner: origOwner, | ||
Data: avl.Tree{}, | ||
}) | ||
keystoreInterface, _ = data.Get(owner) | ||
} | ||
keystore := keystoreInterface.(*KeyStore) | ||
_, removed := keystore.Data.Remove(k) |
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.
Same comment as for set
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.
Fixed in 61079bb
// "owner:set:key:value" -> sets a key-value pair for owner's keystore (owner must be caller) | ||
// "owner:remove:key" -> removes key from owner keystore (owner must be caller) | ||
func Render(p string) string { |
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 keep Render
to be read-only?
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.
Agreed, usage of Render()
should probably be universally understood as read-only for consistency across realm examples though there isn't anything in the docs stating this
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.
Thanks. Was not aware that Render()
should be read-only. Fixed in dd50037
args := strings.Split(p, ":") | ||
numArgs := len(args) | ||
if p == "" { | ||
if data.Size() > 0 { |
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.
You can simplify this code segment by:
if data.Size() == 0 {
return "no databases"
}
data.Iterate(...)
// ...
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.
Thanks, I do prefer that pattern. Fixed in 292dc1e
var response string | ||
args := strings.Split(p, ":") | ||
numArgs := len(args) | ||
if p == "" { |
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 use a switch
, instead? You have return logic for each branch, and only one branch can execute
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.
Ah yeah! I'm not a huge fan of switches but I agree its nice here, fixed in 8854a13
Ping @schollz for visibility |
This realm implements the
avl.Tree
as a user-addressable key-store. I wanted to have this realm to possibly usegno.land
as a database where writes may cost gnots but reads are free because they can be performed throughRender
(related discussion: #947). As a nice additional feature it provides a UI for the database (throughgno.land
).Data can be set/removed if the caller is the same as the owner of the key-store (i.e. only owner's have write-access). For example:
All data is public and accessible as read-only from any user, as well as from gno.land.
The main page lists all the available databases by owner (
/r/demo/keystore
):Clicking on a user will show all the keys in their key-store (
/r/demo/keystore:USER
):And the key values are accessible as well (
r/demo/keystore:USER:get:KEY
)Contributors Checklist
BREAKING CHANGE: xxx
message was included in the descriptionMaintainers Checklist
CONTRIBUTING.md
BREAKING CHANGE:
in the body)