diff --git a/CHANGES.md b/CHANGES.md index 37928d3d604..c06bb5bc2d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -40,6 +40,8 @@ be compatible with this version, specifically, those that ran with - (Libplanet.Store) Removed `BaseNode`. [[#3574]] - (Libplanet.Store) Added `ITrie.Remove()` interface method. [[#3576]] - (Libplanet.Store) Added `FullNode.RemoveChild()` method. [[#3576]] + - (Libplanet.Action) Added `IAccount.RemoveState()` interface method. + [[#3577]] [#3559]: https://github.com/planetarium/libplanet/pull/3559 [#3560]: https://github.com/planetarium/libplanet/pull/3560 @@ -51,6 +53,7 @@ be compatible with this version, specifically, those that ran with [#3573]: https://github.com/planetarium/libplanet/pull/3573 [#3574]: https://github.com/planetarium/libplanet/pull/3574 [#3576]: https://github.com/planetarium/libplanet/pull/3576 +[#3577]: https://github.com/planetarium/libplanet/pull/3577 Version 3.9.2 diff --git a/Libplanet.Action/State/Account.cs b/Libplanet.Action/State/Account.cs index 5d455c0dcec..c10dc2c0684 100644 --- a/Libplanet.Action/State/Account.cs +++ b/Libplanet.Action/State/Account.cs @@ -52,6 +52,10 @@ public Account( [Pure] public IAccount SetState(Address address, IValue state) => UpdateState(address, state); + /// + [Pure] + public IAccount RemoveState(Address address) => UpdateState(address, null); + /// [Pure] public FungibleAssetValue GetBalance(Address address, Currency currency) => @@ -182,11 +186,15 @@ public IAccount SetValidator(Validator validator) => [Pure] private Account UpdateState( Address address, - IValue value) => - new Account( - new AccountState( - Trie.Set(ToStateKey(address), value)), - TotalUpdatedFungibleAssets); + IValue? value) => value is { } v + ? new Account( + new AccountState( + Trie.Set(ToStateKey(address), v)), + TotalUpdatedFungibleAssets) + : new Account( + new AccountState( + Trie.Remove(ToStateKey(address))), + TotalUpdatedFungibleAssets); [Pure] private Account UpdateFungibleAssets( diff --git a/Libplanet.Action/State/IAccount.cs b/Libplanet.Action/State/IAccount.cs index 4103f2399ea..d82723e83ae 100644 --- a/Libplanet.Action/State/IAccount.cs +++ b/Libplanet.Action/State/IAccount.cs @@ -67,6 +67,23 @@ public interface IAccount : IAccountState [Pure] IAccount SetState(Address address, IValue state); + /// + /// Gets a new instance that the account state of the given + /// is removed. + /// + /// The referring + /// the account to remove its state. + /// A new instance that + /// the account state of the given + /// is removed. + /// + /// This method method does not manipulate the instance, + /// but returns a new instance + /// with updated states instead. + /// + [Pure] + IAccount RemoveState(Address address); + /// /// Mints the fungible asset (i.e., in-game monetary), /// and give it to the . diff --git a/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs b/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs index fc731709368..f820cab6bbf 100644 --- a/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs +++ b/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs @@ -398,6 +398,11 @@ public IAccount SetState(Address address, IValue state) throw new System.NotImplementedException(); } + public IAccount RemoveState(Address address) + { + throw new System.NotImplementedException(); + } + public IAccount MintAsset(IActionContext context, Address recipient, FungibleAssetValue value) { throw new System.NotImplementedException(); diff --git a/Libplanet.Tests/Action/AccountTest.cs b/Libplanet.Tests/Action/AccountTest.cs index 3aead7e452a..b7ffe10b0d3 100644 --- a/Libplanet.Tests/Action/AccountTest.cs +++ b/Libplanet.Tests/Action/AccountTest.cs @@ -143,6 +143,23 @@ public virtual void States() Assert.Equal("z", (Text)b.GetState(_addr[0])); } + [Fact] + public void RemoveState() + { + IAccount a = _initAccount.SetState(_addr[0], (Text)"A"); + a = a.SetState(_addr[1], (Text)"B"); + Assert.Equal((Text)"A", a.GetState(_addr[0])); + Assert.Equal((Text)"B", a.GetState(_addr[1])); + + a = a.RemoveState(_addr[0]); + Assert.Null(a.GetState(_addr[0])); + Assert.Equal((Text)"B", a.GetState(_addr[1])); + + a = a.RemoveState(_addr[1]); + Assert.Null(a.GetState(_addr[0])); + Assert.Null(a.GetState(_addr[1])); + } + [Fact] public virtual void FungibleAssets() {