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()
{