-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Add persistent unique identifiers for objects #14135
base: master
Are you sure you want to change the base?
Conversation
If I get it well, APi of Guids should be updated, related to #11050 (comment) (@sorcerykid or anybody else)? |
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.
(Unofficial conceptual review, I'm not a core dev)
Concept looks good to me. However the implementation of the GUID generator feels overengineered. Why not use random UIDs, say, 128 bit? These would be 16 bytes, or 32 hex digits.
If I'm not mistaken, the probability of a collision would be around 5e-20 with that. The probability of a hardware fault would be many orders of magnitude higher.
With random UIDs, you don't have to worry about persisting and parsing the largest UID. You basically need just one function: Get next UID, which can be very simple, because C++'s builtin random sources do the heavy lifting.
(About persistence: Are you sure that the if an entity is persisted, the corresponding max UID will always be persisted as well? Otherwise you could get collisions.)
Potential bug: v1guid<x>
would also be a valid playername, no? Couldn't malicious players abuse this to cause GUID collisions? Perhaps you should use some character which can't appear in player names in GUIDs.
Thanks for the feedback. At this moment, this is only a rebased PR that has been abandoned. So no changes mentioned by @sorcerykid in the old PR have been applied. He required also removing GUID from the player, because Yes, it looks like a really strong GUID generator. I have been thinking about changing it and using the value returned by |
i've never been a fan of UUIDs. i feel like they are over-engineered for most purposes, unless you need ID generation that isn't controlled by a single thread on a single machine. they require way more storage space and creation time than just incrementing some integer, and are also conceptually more complicated. if you make sure the integer is incremented and written before the id is actually assigned to some entity, you don't have to worry about collisions due to most hardware faults in practice. sequential IDs have the additional benefit of giving you some vague idea of the age of the object in question. with this proposal's built-in versioning scheme, using something like UUIDs would always be possible in the future if minetest's architecture gets much more distributed, or if the current scheme turns out to cause problems that i'm not correctly imagining. i've been musing about writing a mob API for a couple years now, and adding unique IDs for persistent mobs has been part of the intention since nearly the beginning. but i'd much prefer that the game engine manage those IDs. i'm don't feel like i'm totally fit to judge the functionality of this request, but i do se a couple possible problems - it seems to be assigning IDs to objects before incrementing the value, and seems to assign a single value ( |
Hard disagree. Most of the code in
If you persist the counter immediately you will have much worse performance than generating 128 random bits. If you don't, you have to worry about collisions. |
You could increment a counter by some big number, e.g. 1024, and persist the result, and allocate from this range until it runs out.
That player would then have id (Idk what the right thing to do here is, btw..) |
I suggest making the player id the name, and the entity id a guid in a form that isn't a valid player name (like shown with angle brackets) |
So I have made some changes, based on the discussion here and under the previous PR.
GUId for luaentities looks like There is also a new |
Definitely agree with @appgurueu. These can just be an UUIDv4. It's not the most minimal solution but that's exactly why it really just works. By the way for players I suggest supporting this function too and using an UUIDv5 (SHA1 of the name). |
@fan5 So, it will be probably again over-engineered as @appgurueu mentioned before. And much worse performance can be expected from it in comparison with the solution with game time and incremental counter. Do you think that the need to save the value into |
So, last commit... GUId generator state is no longer stored in Until someone manages to start the server with the same If this solution is acceptable, I will prepare this for review. |
Thankfully we have the liberty to write a simple UUID generation function that does exactly what we need, instead of pulling in SIMD-accelerated library that we can't even use.
I don't see this claim supported with an argument.
This question bases on an incorrect premise but let me say: yes, being able to generate an unique ID without needing to synchronize with the disk/database is an important property.
Not a good idea btw. |
I agree with this - also reduces the impact of |
So, I have done some research about this. It looks like it should be ok to use Or, if the encryption is planned to be added to UDP protocol, something like DTLS from openSSL, I can use some strong random number generator from it. |
So a new variant is available. It uses std::random_device. Usage depends on the entropy of the random source to eliminate the risk of duplicates on systems with poor random_device. |
3f5645a
to
0337e3f
Compare
PR prepared for review. |
@sfence rebase needed |
@sfence rebase needed |
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.
Just a spelling error I noticed
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.
Summarizing the major points:
- Despite documentation in
doc/world_format.md
, the GUID does not currently seem to be deserialized in theLuaEntitySAO
ctor. This needs to be implemented; the currentset_guid
Lua API method and everything pertaining to it need to be removed 1. For backwards compatibility this must use a newversion2
. Entities which do not have a GUID should be assigned one. Conversely, inLuaEntitySAO::getStaticData
, the GUID needs to be persisted. - As sfan5 pointed out, the "objects by guid" table should contain the same object references. There should not be multiple references to the same object.
- The current unit test seems unsuitable. It essentially primarily tests
set_guid
, which is to be removed. What I would like to see instead is something like (ideally we'd also test persistence, but we don't really have a good framework for that yet so I'm fine with testing that manually):- Add an object, get its GUID
- Add a second object
- Check that we can retrieve both objects (the exact same references) by their GUIDs
- Remove the first object, check that we can no longer retrieve it
Footnotes
-
It seems sfence's intention might have been to let modders manage this themselves, but that is not what we want, because it requires modder cooperation, greatly diminishing the value of the feature. We want the GUID to be separately stored in "engine" staticdata, not mixed into modder staticdata. ↩
This is the adoption of #11050.
on_activate
call by the methodset_guid
.core.objects_by_guid
.To do
This PR is a Ready for Review
How to test
Run unittests from devtest game.