Skip to content

Commit

Permalink
Merge pull request #3738 from greymistcube/refactor/trie-metadata
Browse files Browse the repository at this point in the history
♻️ Refactor `TrieMetadata`
  • Loading branch information
greymistcube authored Apr 11, 2024
2 parents 70aeb47 + faf1294 commit 9ab2062
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 6 deletions.
9 changes: 7 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ To be released.

### Backward-incompatible API changes

- (Libplanet.Action) Removed `IWorld.SetValidator()` extension method.
Use `IWorld.SetValidatorSet()` extension method instead. [[#3735]]
- (Libplanet.Types) Renamed `BlockMetadata.PoWProtocolVersion` to
`BlockMetadata.PBFTProtocolVersion` and `BlockMetadata.LegacyStateVersion`
to `BlockMetadata.WorldStateProtocolVersion` while increasing each value
by 1. [[#3376]]
- (Libplanet.Action) Removed `IWorld.SetValidator()` extension method.
Use `IWorld.SetValidatorSet()` extension method instead. [[#3735]]
- (Libplanet.Store) Changed the type of `TrieMetadata.Version` from
`BigInteger` to `int`. [[#3378]]
- (Libplanet.Store) Changed `TrieMetadata` to throw an `ArgumentException`
when trying to create an instance with an invalid version. [[#3378]]

### Backward-incompatible network protocol changes

Expand All @@ -33,6 +37,7 @@ To be released.

[#3735]: https://github.com/planetarium/libplanet/pull/3735
[#3376]: https://github.com/planetarium/libplanet/pull/3736
[#3378]: https://github.com/planetarium/libplanet/pull/3738


Version 4.3.0
Expand Down
51 changes: 47 additions & 4 deletions Libplanet.Store/Trie/TrieMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
using System;
using System.Numerics;
using Bencodex;
using Bencodex.Types;
using Libplanet.Types.Blocks;

namespace Libplanet.Store.Trie
{
/// <summary>
/// <para>
/// A metadata object to be injected to an <see cref="ITrie"/> to identify
/// and validate the data model. The is to be injected at the root of
/// an <see cref="ITrie"/> with the zero byte array path.
/// </para>
/// <para>
/// <see cref="Version"/> represents under which <see cref="IBlockMetadata.ProtocolVersion"/>
/// the <see cref="ITrie"/> is to be interpreted.
/// </para>
/// <para>
/// This is newly introduced since <see cref="BlockMetadata.WorldStateProtocolVersion"/> and
/// every <see cref="ITrie"/> handled prior to
/// <see cref="BlockMetadata.WorldStateProtocolVersion"/> lacks this data.
/// </para>
/// </summary>
/// <remarks>
/// Due to some backward compatibility constraints, and in particular an empty
/// <see cref="Block"/> being allowed with no state transition, an <see cref="ITrie"/>
/// associated with the <see cref="Block.StateRootHash"/> of a <see cref="Block"/> with
/// <see cref="IBlockMetadata.ProtocolVersion"/> is <em>not guaranteed</em> to have
/// the same <see cref=Version"/> as the <see cref="Block"/>'s
/// <see cref="IBlockMetadata.ProtocolVersion"/>.
/// </remarks>
public class TrieMetadata : IBencodable
{
/// <summary>
/// Creates a <see cref="TrieMetadata"/> instance.
/// </summary>
/// <param name="version">The version of the <see cref="TrieMetadata"/> to create.
/// This must equal to the version of <see cref="IPreEvaluationBlock"/> that is
/// under evaluation.</param>
/// <exception cref="ArgumentException">Thrown when either <paramref name="version"/>
/// is less than <see cref="BlockMetadata.WorldStateProtocolVersion"/> or
/// greater than <see cref="BlockMetadata.CurrentProtocolVersion"/>.</exception>
public TrieMetadata(int version)
{
if (version < BlockMetadata.WorldStateProtocolVersion ||
version > BlockMetadata.CurrentProtocolVersion)
{
throw new ArgumentException(
$"Given {nameof(version)} cannot be less than " +
$"{BlockMetadata.WorldStateProtocolVersion} or greater than " +
$"{BlockMetadata.CurrentProtocolVersion}.",
nameof(version));
}

Version = version;
}

Expand All @@ -23,12 +66,12 @@ public TrieMetadata(IValue bencoded)
}

private TrieMetadata(List list)
: this((int)((Integer)list[0]).Value)
{
Version = ((Integer)list[0]).Value;
}

public BigInteger Version { get; }
public int Version { get; }

public IValue Bencoded => new List((Integer)Version);
public IValue Bencoded => new List(new Integer(Version));
}
}
29 changes: 29 additions & 0 deletions Libplanet.Tests/Store/Trie/TrieMetadataTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using Bencodex.Types;
using Libplanet.Store.Trie;
using Libplanet.Types.Blocks;
using Xunit;

namespace Libplanet.Tests.Store.Trie
{
public class TrieMetadataTest
{
[Fact]
public void CannotCreateWithInvalidVersion()
{
Assert.Throws<ArgumentException>(
() => new TrieMetadata(BlockMetadata.WorldStateProtocolVersion - 1));
Assert.Throws<ArgumentException>(
() => new TrieMetadata(BlockMetadata.CurrentProtocolVersion + 1));
}

[Fact]
public void Bencoded()
{
var meta = new TrieMetadata(BlockMetadata.WorldStateProtocolVersion);
IValue bencoded = meta.Bencoded;
var decoded = new TrieMetadata(bencoded);
Assert.Equal(meta.Version, decoded.Version);
}
}
}

0 comments on commit 9ab2062

Please sign in to comment.