-
Notifications
You must be signed in to change notification settings - Fork 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
Fix storage encoding #3130
Fix storage encoding #3130
Conversation
@@ -29,8 +30,22 @@ public class KeyBuilder | |||
/// <param name="prefix">The prefix of the key.</param> | |||
public KeyBuilder(int id, byte prefix) | |||
{ | |||
Add(id); |
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.
@Jim8y The bug was here, it was stored in the OS format, but it was readed in LittleEndian
, in our test is the same, but in a BigEndian
machine, it will fault.
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.
Its still wrong. You need to check the machine. Use
if (BitConverter.IsLittleEndian)
Id = BinaryPrimitives.ReadInt32LittleEndian(cache);
else
Id = BinaryPrimitives.ReadInt32BigEndian(cache);
Every machine OS is different. Some use |
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.
Need more tests. @superboyiii needs to check states after this is finished.
Why? We need to write always in the same way, that's why I removed the unsafe methods |
In big endian machine the states will change, but it becomes to be the same as little endian. Note: no one use it in |
The reason it didn't work because the OS stores in if (BitConverter.IsLittleEndian)
Id = BinaryPrimitives.ReadInt32LittleEndian(cache);
else
Id = BinaryPrimitives.ReadInt32BigEndian(cache); Also if the OS is |
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 fix itself is correct, maybe we can improve Add
and constructor documentation though to mention endianness.
Is LevelDB binary format endian-agnostic, btw?
We want deterministic storage, no sense to store in different format in different os. |
So when you go to read it would be in |
How about banning BigEndian machine once for all. Now its the world of little endian. Kill the bigendian from neo. If none of you can not even find a Bigendian machine to test, what is the debating means here. Just little endian everywhere. |
if (BitConverter.IsLittleEndian){throw exception "sorry, we dont like bigendian"} |
Nevermind after checking dotnet does it no matter what. [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteInt64BigEndian(Span<byte> destination, long value)
{
if (BitConverter.IsLittleEndian)
{
long tmp = ReverseEndianness(value);
MemoryMarshal.Write(destination, ref tmp);
}
else
{
MemoryMarshal.Write(destination, ref value);
}
} |
Description
We wrote the id in the OS format, but we always read it in
LittleEndian
neo/src/Neo/SmartContract/StorageKey.cs
Line 40 in 95708b5
Type of change