From 0b34c4995306721a48a986a92d0b29374e0c5fef Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Fri, 22 Mar 2019 15:47:07 +0900 Subject: [PATCH] Throw exception when action type is not annotated --- CHANGES.md | 3 +++ Libplanet.Tests/Blockchain/BlockChainTest.cs | 27 ++++++++++++++++++++ Libplanet/Action/ActionTypeAttribute.cs | 12 ++++++++- Libplanet/Tx/InvalidActionTypeException.cs | 24 +++++++++++++++++ 4 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 Libplanet/Tx/InvalidActionTypeException.cs diff --git a/CHANGES.md b/CHANGES.md index 8d1ed753d1..d7c811790d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -99,6 +99,8 @@ To be released. from `IImmutableList` to `IPEndPoint`. [[#120], [#123] by Yang Chun Ung, [#126], [#127]] - Added `IStore.ListNamespaces()` method. + - `Transaction` now throws an `InvalidActionTypeException` if an action type + is not annotated with `ActionTypeAttribute`. [#144] [#98]: https://github.com/planetarium/libplanet/issues/98 [#99]: https://github.com/planetarium/libplanet/issues/99 @@ -113,6 +115,7 @@ To be released. [#132]: https://github.com/planetarium/libplanet/issues/132 [#135]: https://github.com/planetarium/libplanet/pull/135 [#136]: https://github.com/planetarium/libplanet/pull/136 +[#144]: https://github.com/planetarium/libplanet/pull/144 [RFC 5389]: https://tools.ietf.org/html/rfc5389 [RFC 5766]: https://tools.ietf.org/html/rfc5766 diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.cs b/Libplanet.Tests/Blockchain/BlockChainTest.cs index 2cf093b21d..6cf39ffe5c 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.cs @@ -279,6 +279,17 @@ public void EvaluateActions() Assert.Equal(states[TestEvaluateAction.BlockIndexKey], blockIndex); } + [Fact] + public void DetectInvalidActionType() + { + var privateKey = new PrivateKey(); + var action = new ActionNotAttributeAnnotated(); + + Assert.Throws( + () => Transaction.Create( + privateKey, new[] { action })); + } + [ActionType("test")] private class TestEvaluateAction : BaseAction { @@ -303,5 +314,21 @@ public override IAccountStateDelta Execute(IActionContext context) .SetState(BlockIndexKey, context.BlockIndex); } } + + private class ActionNotAttributeAnnotated : BaseAction + { + public override IImmutableDictionary PlainValue => + new Dictionary().ToImmutableDictionary(); + + public override void LoadPlainValue( + IImmutableDictionary plainValue) + { + } + + public override IAccountStateDelta Execute(IActionContext context) + { + return context.PreviousStates; + } + } } } diff --git a/Libplanet/Action/ActionTypeAttribute.cs b/Libplanet/Action/ActionTypeAttribute.cs index dfb40c0f5e..7f5d774cc8 100644 --- a/Libplanet/Action/ActionTypeAttribute.cs +++ b/Libplanet/Action/ActionTypeAttribute.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Reflection; +using Libplanet.Tx; namespace Libplanet.Action { @@ -40,11 +41,20 @@ public ActionTypeAttribute(string typeIdentifier) /// null. public static string ValueOf(Type actionType) { - return actionType + string typeIdentifier = actionType .GetCustomAttributes() .OfType() .Select(attr => attr.TypeIdentifier) .FirstOrDefault(); + + if (typeIdentifier is null) + { + throw new InvalidActionTypeException( + "Action type should be annotated with ActionTypeAttribute." + ); + } + + return typeIdentifier; } } } diff --git a/Libplanet/Tx/InvalidActionTypeException.cs b/Libplanet/Tx/InvalidActionTypeException.cs new file mode 100644 index 0000000000..bfc9078aab --- /dev/null +++ b/Libplanet/Tx/InvalidActionTypeException.cs @@ -0,0 +1,24 @@ +using System; +using System.Runtime.Serialization; + +namespace Libplanet.Tx +{ + [Serializable] + public sealed class InvalidActionTypeException : Exception + { + public InvalidActionTypeException() + { + } + + public InvalidActionTypeException(string message) + : base(message) + { + } + + public InvalidActionTypeException( + string message, Exception innerException) + : base(message, innerException) + { + } + } +}