Skip to content
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

💥 Deprecate PoW evaluation #3789

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,27 @@ Version 4.6.0

To be released.

Due to changes in [#3789], a network ran with a prior version
may not be compatible with this version. The native implementation of
`IActionEvaluator`, which is `ActionEvaluator`, no longer supports
evaluation of PoW `Block`s. That is, it is no longer possible to
reconstruct states with valid state root hashes purely from past
`Block`s that includes PoW `Block`s.

### Deprecated APIs

- (Libplanet.Common) Removed `Nonce` struct. [[#3793], [#3794]]
- Removed `AtomicActionRenderer` class. [[#3795]]

### Backward-incompatible API changes

- (Libplanet.Action) Changed `ActionEvaluate.Evaluate()` to no longer
accept `IPreEvaluationBlock` with a protocol version less than
`BlockMetadata.PBFTProtocolVersion`. [[#3789]]
- (Libplanet.Action) Changed the description of `IActionEvaluate.Evaluate()`
so that it may throw `BlockProtocolVersionNotSupportedException` if
its implementation is not able to handle `IPreEvaluationBlock` with
certain `BlockMetadata.ProtocolVersion`s. [[#3789]]
- (Libplanet.Types) Removed `nonce` parameter from
`BlockMetadata.DerivePreEvaluationHash()` and
`BlockMetadata.MakeCandidateData()` methods. [[#3793], [#3794]]
Expand All @@ -26,6 +40,9 @@ To be released.

### Added APIs

- (Libplanet.Action) Added `BlockProtocolVersionNotSupportedException` class.
[[#3789]]

### Behavioral changes

### Bug fixes
Expand All @@ -34,6 +51,7 @@ To be released.

### CLI tools

[#3789]: https://github.com/planetarium/libplanet/pull/3789
[#3793]: https://github.com/planetarium/libplanet/issues/3793
[#3794]: https://github.com/planetarium/libplanet/pull/3794
[#3795]: https://github.com/planetarium/libplanet/pull/3795
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Runtime.Serialization.Formatters.Binary;
using Xunit;

namespace Libplanet.Action.Tests
{
public class BlockProtocolVersionNotSupportedExceptionTest
{
[Fact]
public void Serializable()
{
var exc = new BlockProtocolVersionNotSupportedException("Foo", 5);

var formatter = new BinaryFormatter();
using (var ms = new MemoryStream())
{
formatter.Serialize(ms, exc);

ms.Seek(0, SeekOrigin.Begin);
var deserialized = Assert.IsType<BlockProtocolVersionNotSupportedException>(
formatter.Deserialize(ms));
Assert.Equal("Foo", deserialized.Message);
Assert.Equal(5, deserialized.BlockProtocolVersion);
}
}
}
}
10 changes: 10 additions & 0 deletions Libplanet.Action/ActionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ public IReadOnlyList<ICommittedActionEvaluation> Evaluate(
IPreEvaluationBlock block,
HashDigest<SHA256>? baseStateRootHash)
{
if (block.ProtocolVersion < BlockMetadata.PBFTProtocolVersion)
{
throw new BlockProtocolVersionNotSupportedException(
$"The native implementation does not support an evaluation of a block " +
$"#{block.Index} pre-evaluation hash {block.PreEvaluationHash} " +
$"with protocol version less than {BlockMetadata.PBFTProtocolVersion}: " +
$"{block.ProtocolVersion}",
block.ProtocolVersion);
}

riemannulus marked this conversation as resolved.
Show resolved Hide resolved
_logger.Information(
"Evaluating actions in the block #{BlockIndex} " +
"pre-evaluation hash {PreEvaluationHash}...",
Expand Down
52 changes: 52 additions & 0 deletions Libplanet.Action/BlockProtocolVersionNotSupportedException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Runtime.Serialization;
using Libplanet.Types.Blocks;

namespace Libplanet.Action
{
/// <summary>
/// The exception that is thrown when an <see cref="IPreEvaluationBlock"/> with
/// a protocol version that is not supported by an implementation of
/// <see cref="IActionEvaluator"/> is passed as an argument to
/// <see cref="IActionEvaluator.Evaluate"/>.
/// </summary>
[Serializable]
public sealed class BlockProtocolVersionNotSupportedException : Exception
{
/// <summary>
/// Creates a new <see cref="BlockProtocolVersionNotSupportedException"/> object.
/// </summary>
/// <param name="message">Specifies a <see cref="Exception.Message"/>.</param>
/// <param name="blockProtocolVersion">The <see cref="Block.ProtocolVersion"/> of the
/// <see cref="Block"/> that <paramref name="action"/> belongs to.</param>
public BlockProtocolVersionNotSupportedException(
string message,
int blockProtocolVersion)
: base(message)
{
BlockProtocolVersion = blockProtocolVersion;
}

private BlockProtocolVersionNotSupportedException(
SerializationInfo info,
StreamingContext context)
: base(info, context)
{
BlockProtocolVersion = (int)info.GetValue(
nameof(BlockProtocolVersion),
typeof(int))!;
}

/// <summary>
/// The <see cref="Block.ProtocolVersion"/> of the <see cref="Block"/> that is
/// not supported by an implementation of <see cref="IActionEvaluator"/>.
/// </summary>
public int BlockProtocolVersion { get; }

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue(nameof(BlockProtocolVersion), BlockProtocolVersion, typeof(int));
}
}
}
4 changes: 4 additions & 0 deletions Libplanet.Action/IActionEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public interface IActionEvaluator
/// the end.
/// </para>
/// </remarks>
/// <exception cref="BlockProtocolVersionNotSupportedException">Thrown when
/// <paramref name="block"/> has a <see cref="IPreEvaluationBlock.ProtocolVersion"/>
/// that is not supported by an implementation of <see cref="IActionEvaluator"/>.
/// </exception>
[Pure]
IReadOnlyList<ICommittedActionEvaluation> Evaluate(
IPreEvaluationBlock block,
Expand Down
13 changes: 13 additions & 0 deletions Libplanet.Tests/Action/ActionEvaluatorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using Libplanet.Action.Tests.Common;
using Libplanet.Blockchain;
using Libplanet.Blockchain.Policies;
using Libplanet.Common;
using Libplanet.Crypto;
using Libplanet.Mocks;
using Libplanet.Store;
Expand Down Expand Up @@ -1226,6 +1227,18 @@ public void CheckRandomSeedInAction()
}
}

[Fact]
public void BlockProtocolVersionNotSupported()
{
Block block = BlockMarshaler.UnmarshalBlock(LegacyBlocks.BencodedV1Block);
var actionEvaluator = new ActionEvaluator(
_ => null,
new TrieStateStore(new MemoryKeyValueStore()),
new SingleActionLoader(typeof(DumbAction)));
Assert.Throws<BlockProtocolVersionNotSupportedException>(
() => actionEvaluator.Evaluate(block, null));
}

private (Address[], Transaction[]) MakeFixturesForAppendTests(
PrivateKey privateKey = null,
DateTimeOffset epoch = default)
Expand Down
Loading
Loading