diff --git a/CHANGES.md b/CHANGES.md index c37e288901e..56706756833 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,11 @@ Version 5.1.2 To be released. + - Fix an issue where currency does not work correctly in dotnet6. + [[#3880]] + +[#3880]: https://github.com/planetarium/libplanet/pull/3880 + Version 5.1.1 ------------- diff --git a/src/Libplanet.Types/Assets/Currency.cs b/src/Libplanet.Types/Assets/Currency.cs index c0c1e0ec12a..97d7e4cd670 100644 --- a/src/Libplanet.Types/Assets/Currency.cs +++ b/src/Libplanet.Types/Assets/Currency.cs @@ -80,12 +80,7 @@ namespace Libplanet.Types.Assets /// The deterministic hash derived from other fields. /// [JsonInclude] -#if NETSTANDARD2_0_OR_GREATER public readonly HashDigest Hash; -#else -#pragma warning disable SA1201 - public HashDigest Hash => GetHash(); -#endif /// /// Whether the total supply of this instance of is trackable. @@ -248,9 +243,7 @@ public Currency(IValue serialized) Minters = null; } -#if NETSTANDARD2_0_OR_GREATER - Hash = GetHash(); -#endif // NETSTANDARD2_0_OR_GREATER + Hash = GetHash(Minters, Ticker, DecimalPlaces, _maximumSupply, TotalSupplyTrackable); } /// @@ -280,8 +273,8 @@ maximumSupply is { } v #pragma warning restore SA1118 { TotalSupplyTrackable = totalSupplyTrackable; -#if NETSTANDARD2_0_OR_GREATER - HashDigest expectedHash = GetHash(); + HashDigest expectedHash = GetHash( + Minters, Ticker, DecimalPlaces, _maximumSupply, TotalSupplyTrackable); if (!expectedHash.Equals(hash)) { var msg = $"Invalid currency hash; expected {expectedHash}, but got {hash}. " + @@ -294,7 +287,6 @@ maximumSupply is { } v } Hash = hash; -#endif // NETSTANDARD2_0_OR_GREATER } private Currency(SerializationInfo info, StreamingContext context) @@ -358,9 +350,7 @@ private Currency(SerializationInfo info, StreamingContext context) } } -#if NETSTANDARD2_0_OR_GREATER - Hash = GetHash(); -#endif // NETSTANDARD2_0_OR_GREATER + Hash = GetHash(Minters, Ticker, DecimalPlaces, _maximumSupply, TotalSupplyTrackable); } /// @@ -408,9 +398,7 @@ private Currency( _maximumSupply = maximumSupply; } -#if NETSTANDARD2_0_OR_GREATER - Hash = GetHash(); -#endif // NETSTANDARD2_0_OR_GREATER + Hash = GetHash(Minters, Ticker, DecimalPlaces, _maximumSupply, TotalSupplyTrackable); } /// @@ -448,9 +436,7 @@ private Currency( DecimalPlaces = decimalPlaces; _maximumSupply = null; TotalSupplyTrackable = totalSupplyTrackable; -#if NETSTANDARD2_0_OR_GREATER - Hash = GetHash(); -#endif // NETSTANDARD2_0_OR_GREATER + Hash = GetHash(Minters, Ticker, DecimalPlaces, _maximumSupply, TotalSupplyTrackable); } /// @@ -742,40 +728,40 @@ private static SHA1 GetSHA1() #endif } - [Pure] - private IValue SerializeForHash() + // NOTE: This uses a different serialization scheme from + // Serialize() due to backward compatibility issues. + private static HashDigest GetHash( + IImmutableSet
? minters, + string ticker, + byte decimalPlaces, + (BigInteger Major, BigInteger Minor)? maximumSupply, + bool totalSupplyTrackable + ) { - IValue minters = Minters is ImmutableHashSet
a + using var buffer = new MemoryStream(); + using var sha1 = GetSHA1(); + using var stream = new CryptoStream(buffer, sha1, CryptoStreamMode.Write); + var codec = new Codec(); + IValue mintersValue = minters is ImmutableHashSet
a ? new List(a.OrderBy(m => m).Select(m => m.Bencoded)) : (IValue)Null.Value; - var serialized = Dictionary.Empty - .Add("ticker", Ticker) - .Add("decimals", (int)DecimalPlaces) - .Add("minters", minters); + .Add("ticker", ticker) + .Add("decimals", (int)decimalPlaces) + .Add("minters", mintersValue); - if (_maximumSupply is var (major, minor)) + if (maximumSupply is var (major, minor)) { serialized = serialized.Add("maximumSupplyMajor", new Integer(major)) .Add("maximumSupplyMinor", new Integer(minor)); } - if (TotalSupplyTrackable) + if (totalSupplyTrackable) { serialized = serialized.Add("totalSupplyTrackable", true); } - return serialized; - } - - [Pure] - private HashDigest GetHash() - { - using var buffer = new MemoryStream(); - using var sha1 = GetSHA1(); - using var stream = new CryptoStream(buffer, sha1, CryptoStreamMode.Write); - var codec = new Codec(); - codec.Encode(SerializeForHash(), stream); + codec.Encode(serialized, stream); stream.FlushFinalBlock(); if (sha1.Hash is { } hash) {