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

Expose exception in IAction.Execute() #875

Merged
merged 3 commits into from
May 21, 2020
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
12 changes: 11 additions & 1 deletion CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ To be released.

### Backward-incompatible API changes

- Added `IAction.RenderError()` and `IAction.UnrenderError()` methods.
[[#860], [#875]]

### Backward-incompatible network protocol changes

### Backward-incompatible storage format changes

### Added APIs

- Added `TurnClient.BindProxies()` method. [[#756], [#868]]
- Added `TurnClient.BindProxies()` method. [[#756], [#868]]
- Added `ActionEvaluation.Exception` property. [[#860], [[#875]]]

### Behavioral changes

- Improved performance of `Swarm<T>` by multiplexing response and
broadcast. [[#858], [#859]]
- `Transaction<T>.Create()`, `Transaction<T>.EvaluateActions()` and
`Transaction<T>.EvaluateActionsGradually()` no longer throw
`UnexpectedlyTerminatedActionException` directly. Instead, it records
an exception to `ActionEvalution`s. [[#860], [#875]]

### Bug fixes

Expand All @@ -28,7 +36,9 @@ To be released.
[#756]: https://github.com/planetarium/libplanet/issues/756
[#858]: https://github.com/planetarium/libplanet/issues/858
[#859]: https://github.com/planetarium/libplanet/pull/859
[#860]: https://github.com/planetarium/libplanet/issues/860
[#868]: https://github.com/planetarium/libplanet/pull/868
[#875]: https://github.com/planetarium/libplanet/pull/875


Version 0.9.2
Expand Down
9 changes: 9 additions & 0 deletions Libplanet.Tests/Action/PolymorphicActionTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Bencodex.Types;
using Libplanet.Action;
Expand Down Expand Up @@ -122,6 +123,14 @@ public void Unrender(
IAccountStateDelta nextStates)
{
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
}
25 changes: 20 additions & 5 deletions Libplanet.Tests/Blockchain/BlockChainTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using Libplanet.Tx;
using Serilog;
using Xunit;
using static Libplanet.Tests.Common.Action.ThrowException;

namespace Libplanet.Tests.Blockchain
{
Expand Down Expand Up @@ -483,15 +484,21 @@ public async Task AppendWhenActionEvaluationFailed()
var privateKey = new PrivateKey();

var action = new ThrowException { ThrowOnExecution = true };
var onRenderErrorCalled = false;
action.OnRenderError = (ctx, exc) =>
{
onRenderErrorCalled = true;
Assert.IsType<UnexpectedlyTerminatedActionException>(exc);
Assert.IsType<SomeException>(exc.InnerException);
};

var actions = new[] { action };
blockChain.MakeTransaction(privateKey, actions);

UnexpectedlyTerminatedActionException e =
await Assert.ThrowsAsync<UnexpectedlyTerminatedActionException>(async () =>
await blockChain.MineBlock(_fx.Address1));
Assert.IsType<ThrowException.SomeException>(e.InnerException);
await blockChain.MineBlock(_fx.Address1);

Assert.Equal(1, blockChain.Count);
Assert.Equal(2, blockChain.Count);
Assert.True(onRenderErrorCalled);
}

[Fact]
Expand Down Expand Up @@ -2214,6 +2221,14 @@ public void Unrender(
IAccountStateDelta nextStates)
{
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
}
9 changes: 9 additions & 0 deletions Libplanet.Tests/Common/Action/BaseAction.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Bencodex.Types;
using Libplanet.Action;

Expand All @@ -22,5 +23,13 @@ public virtual void Unrender(
}

public abstract void LoadPlainValue(IValue plainValue);

public virtual void RenderError(IActionContext context, Exception exception)
{
}

public virtual void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
8 changes: 8 additions & 0 deletions Libplanet.Tests/Common/Action/DumbAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,14 @@ public void Unrender(
});
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}

public void LoadPlainValue(IValue plainValue)
{
LoadPlainValue((Bencodex.Types.Dictionary)plainValue);
Expand Down
9 changes: 9 additions & 0 deletions Libplanet.Tests/Common/Action/MinerReward.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading;
Expand Down Expand Up @@ -91,5 +92,13 @@ public void Unrender(IActionContext context, IAccountStateDelta nextStates)
NextStates = nextStates,
});
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
20 changes: 20 additions & 0 deletions Libplanet.Tests/Common/Action/ThrowException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ public ThrowException()

public bool ThrowOnRendering { get; set; }

public Action<IActionContext, Exception> OnRenderError { get; set; }

public Action<IActionContext, Exception> OnUnrenderError { get; set; }

public IValue PlainValue =>
new Bencodex.Types.Dictionary(new Dictionary<IKey, IValue>
{
Expand Down Expand Up @@ -64,6 +68,22 @@ public void Unrender(
{
}

public void RenderError(IActionContext context, Exception exception)
{
if (!(OnRenderError is null))
{
OnRenderError(context, exception);
}
}

public void UnrenderError(IActionContext context, Exception exception)
{
if (!(OnUnrenderError is null))
{
OnUnrenderError(context, exception);
}
}

public class SomeException : Exception
{
public SomeException(string message)
Expand Down
10 changes: 5 additions & 5 deletions Libplanet.Tests/Net/SwarmTest.Preload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using System.Threading;
using System.Threading.Tasks;
using Bencodex.Types;
using Libplanet.Action;
using Libplanet.Blockchain;
using Libplanet.Blockchain.Policies;
using Libplanet.Blocks;
Expand Down Expand Up @@ -283,7 +282,7 @@ void Handler(object sender, PreloadBlockDownloadFailEventArgs e)
}

[Fact(Timeout = Timeout)]
public async Task PreloadFailureWhileExecuteActions()
public async Task PreloadWithFailedActions()
{
var policy = new BlockPolicy<ThrowException>();
var fx1 = new DefaultStoreFixture(memory: true);
Expand Down Expand Up @@ -324,9 +323,10 @@ public async Task PreloadFailureWhileExecuteActions()
blockInterval: TimeSpan.FromSeconds(1));
minerSwarm.BlockChain.Append(block, DateTimeOffset.UtcNow, false, false);

await Assert.ThrowsAsync<UnexpectedlyTerminatedActionException>(async () =>
await receiverSwarm.PreloadAsync(TimeSpan.FromSeconds(1)));
Assert.Equal(chainId, fx2.Store.GetCanonicalChainId());
await receiverSwarm.PreloadAsync(TimeSpan.FromSeconds(1));

// Preloading should succeed even if action throws exception.
Assert.Equal(minerChain.Tip, receiverChain.Tip);
}
finally
{
Expand Down
8 changes: 8 additions & 0 deletions Libplanet.Tests/Net/SwarmTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1879,9 +1879,17 @@ public void Render(IActionContext context, IAccountStateDelta nextStates)
{
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void Unrender(IActionContext context, IAccountStateDelta nextStates)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
}
8 changes: 8 additions & 0 deletions Libplanet.Tests/Store/StoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,14 @@ public void Render(IActionContext context, IAccountStateDelta nextStates)
public void Unrender(IActionContext context, IAccountStateDelta nextStates)
{
}

public void RenderError(IActionContext context, Exception exception)
{
}

public void UnrenderError(IActionContext context, Exception exception)
{
}
}
}
}
45 changes: 9 additions & 36 deletions Libplanet.Tests/Tx/TransactionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,6 @@ public void CreateWithMissingRequiredArguments()
);
}

[Fact]
public void CreateWithActionsThrowingException()
{
var action = new ThrowException { ThrowOnRehearsal = true };
UnexpectedlyTerminatedActionException e =
Assert.Throws<UnexpectedlyTerminatedActionException>(() =>
Transaction<ThrowException>.Create(
0,
_fx.PrivateKey1,
new[] { action },
ImmutableHashSet<Address>.Empty,
DateTimeOffset.UtcNow
)
);
Assert.Null(e.BlockHash);
Assert.Null(e.BlockIndex);
Assert.Null(e.TxId);
Assert.Same(action, e.Action);
Assert.IsType<ThrowException.SomeException>(e.InnerException);
}

[Fact]
public void MakeWithSignature()
{
Expand Down Expand Up @@ -672,21 +651,15 @@ public void EvaluateActionsThrowingException()
DateTimeOffset.UtcNow
);
var hash = new HashDigest<SHA256>(GetRandomBytes(HashDigest<SHA256>.Size));
UnexpectedlyTerminatedActionException e =
Assert.Throws<UnexpectedlyTerminatedActionException>(() =>
tx.EvaluateActions(
blockHash: hash,
blockIndex: 123,
previousStates: new AccountStateDeltaImpl(_ => null),
minerAddress: GenesisMinerAddress,
rehearsal: false
)
);
Assert.Equal(hash, e.BlockHash);
Assert.Equal(123, e.BlockIndex);
Assert.Equal(tx.Id, e.TxId);
Assert.IsType<ThrowException>(e.Action);
Assert.IsType<ThrowException.SomeException>(e.InnerException);
var nextStates = tx.EvaluateActions(
blockHash: hash,
blockIndex: 123,
previousStates: new AccountStateDeltaImpl(_ => null),
minerAddress: GenesisMinerAddress,
rehearsal: false
);

Assert.Empty(nextStates.GetUpdatedStates());
}

[Fact]
Expand Down
Loading