-
Notifications
You must be signed in to change notification settings - Fork 196
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
fix(world): inline debug constants [L-11] #1976
Conversation
🦋 Changeset detectedLatest commit: ca84b88 The changes in this PR will be included in the next version bump. This PR includes changesets to release 30 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@@ -10,7 +10,7 @@ import { RESOURCE_NAMESPACE, MASK_RESOURCE_NAMESPACE } from "./worldResourceType | |||
uint256 constant NAMESPACE_BITS = 14 * 8; | |||
uint256 constant NAME_BITS = 16 * 8; | |||
|
|||
bytes16 constant ROOT_NAMESPACE_STRING = bytes16("ROOT_NAMESPACE"); | |||
bytes14 constant ROOT_NAMESPACE_STRING = bytes14("ROOT_NAMESPACE"); | |||
bytes16 constant ROOT_NAME_STRING = bytes16("ROOT_NAME"); |
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.
@alvrs A few notes/questions for us:
- Since these strings are just for debugging, they don't need to be type-aligned with the actual namespace/name types, right? They could technically be any length?
- I have been using an empty string for root namespace/name in ~all of the client code, and wonder if we should align on that here. Alternatively, I wonder if we should use a less likely string like
<root>
or something. - Should we inline this into
toString
(since that's the only place it's used) instead of defining up here, so we don't need to specify the type? - Should we use
toTrimmedString
for namespace and name insidetoString
?
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.
Since these strings are just for debugging, they don't need to be type-aligned with the actual namespace/name types, right? They could technically be any length?
Correct (but kinda agree using something else than bytes14
can lead to confusion)
I have been using an empty string for root namespace/name in ~all of the client code, and wonder if we should align on that here. Alternatively, I wonder if we should use a less likely string like or something.
If we do that we don't even need the ternary operator here anymore since the actual namespace/name is already empty. The original reason why we replaced the empty string here with a more explicit one was that ns::
might be less easy to understand than ns:ROOT_NAMESPACE:ROOT_NAME
. (No strong opinion on which string we use, also happy to make it ns:<root>:<root>
)
Should we inline this into toString (since that's the only place it's used) instead of defining up here, so we don't need to specify the type?
Yeah that makes sense! (still need to specify the type tho because the ternary operator is unhappy if the result is string | bytes14
)
Should we use toTrimmedString for namespace and name inside toString?
We could, but if it's logged as string the 0
's are already not displayed, and if it's logged as raw bytes it might be a tiny little bit easier to figure out what the log means if it always has the same length (34 bytes). On the other hand advantage of using toTrimmedString
would mean it's possible to compare the result with an inline string, which also might be useful.
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.
How about the new changes? Use the inline and shorter string <root>
for root namespace and name.
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 it!
Given that this method is meant to be for debug/human-readability purposes and comparison/parsing should be done against the resource ID itself, I am keen for this to be more string like and use toTrimmedString
around the whole thing. But would be curious to see gas differences before making the final call.
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.
With test code:
function testToString() public {
ResourceId resourceId = WorldResourceIdLib.encode({
typeId: RESOURCE_SYSTEM,
namespace: "namespace",
name: "name"
});
startGasReport("convert resource ID to string");
string memory resourceIdString = resourceId.toString();
endGasReport();
// assertEq(resourceIdString, "sy:namespace:name");
}
It turns out that:
GAS REPORT: 460 convert resource ID to string
After using toTrimmedString
inside of toString
in the following form:
string(
abi.encodePacked(
resourceType,
":",
resourceNamespace == bytes14("") ? "<root>" : WorldResourceIdLib.toTrimmedString(resourceNamespace),
":",
resourceName == bytes16("") ? "<root>" : WorldResourceIdLib.toTrimmedString(resourceName)
)
);
We got:
GAS REPORT: 3287 convert resource ID to string
toString
is actually used in error message, so we might not care much about its gas consumption?
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.
fbc0ac1
to
9b4f570
Compare
resourceNamespace == bytes14("") ? "<root>" : WorldResourceIdLib.toTrimmedString(resourceNamespace), | ||
":", | ||
resourceName == ROOT_NAME ? ROOT_NAME_STRING : resourceName | ||
resourceName == bytes16("") ? "<root>" : WorldResourceIdLib.toTrimmedString(resourceName) |
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.
small nit: let's use the ROOT_NAMESPACE
and ROOT_NAME
constants (imported from constants.sol
) here instead of the inline bytes14
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.
Good to be merged and replace #2030. @yonadaaa can you take this over and finish it up (using the ROOT_NAMESPACE
and ROOT_NAME
constants and adding a short changeset)
Thanks @ClaudeZsb! Sorry for the delay in getting back to this: we all took a long winter break :) |
Description
The original type of
ROOT_NAMESPACE_STRING
defined inWorldResourceId.sol
isObviously its length is supposed to be
14
. And then problem is coming when we use it in a conditional operator? :
and put it in thetrue
condition. See code here:Although
resourceNamespace
is defined asbytes14
, the type of the value packed will be converted tobytes16
just because the type of value at the true condition isbytes16
. As a result,ResourceId.toString()
will return a string of length36=2+1+16+1+16
instead of34=2+1+14+1+16
.Reproduction
Try the following test code
And you'll get
where
bytes14("false")
is packed as abytes16
.