From c0c0284961da43f5dbc0c1157b201f6dd3d5d6aa Mon Sep 17 00:00:00 2001 From: ilgyu Date: Thu, 9 Nov 2023 15:37:45 +0900 Subject: [PATCH] test: Reimplement MockStates --- .../ActionEvaluationTest.cs | 4 +- .../Mocks/MockAccountState.cs | 57 ++++++++++--------- .../Mocks/MockWorldState.cs | 46 +++++++++------ Libplanet.Tests/Action/AccountTest.cs | 2 +- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/Libplanet.Action.Tests/ActionEvaluationTest.cs b/Libplanet.Action.Tests/ActionEvaluationTest.cs index fe799e5030d..1c0c1cfc3f6 100644 --- a/Libplanet.Action.Tests/ActionEvaluationTest.cs +++ b/Libplanet.Action.Tests/ActionEvaluationTest.cs @@ -42,9 +42,9 @@ public void Constructor() 0, false), new World( - new MockWorldState().SetAccount( + new MockWorldState().SetAccountState( ReservedAddresses.LegacyAccount, - new Account(MockAccountState.Empty.SetState(address, (Text)"item")))) + new Account(new MockAccountState().SetState(address, (Text)"item")))) ); var action = (DumbAction)evaluation.Action; diff --git a/Libplanet.Action.Tests/Mocks/MockAccountState.cs b/Libplanet.Action.Tests/Mocks/MockAccountState.cs index 78544f3de9e..5c0737696e4 100644 --- a/Libplanet.Action.Tests/Mocks/MockAccountState.cs +++ b/Libplanet.Action.Tests/Mocks/MockAccountState.cs @@ -1,12 +1,14 @@ using System.Numerics; +using System.Security.Cryptography; using Bencodex.Types; using Libplanet.Action.State; +using Libplanet.Common; using Libplanet.Crypto; using Libplanet.Store; using Libplanet.Store.Trie; using Libplanet.Types.Assets; -using Libplanet.Types.Blocks; using Libplanet.Types.Consensus; +using static Libplanet.Action.State.KeyConverters; namespace Libplanet.Action.Tests.Mocks { @@ -47,34 +49,31 @@ namespace Libplanet.Action.Tests.Mocks /// public class MockAccountState : IAccountState { - private static readonly MockAccountState _empty = new MockAccountState(); + private readonly IStateStore _stateStore; public MockAccountState() - : this(new TrieStateStore(new MemoryKeyValueStore()).GetStateRoot(null)) + : this(new TrieStateStore(new MemoryKeyValueStore()), null) { } - private MockAccountState(ITrie trie) + public MockAccountState( + IStateStore stateStore, + HashDigest? stateRootHash = null) { - Trie = trie; + _stateStore = stateStore; + Trie = stateStore.GetStateRoot(stateRootHash); } - public static MockAccountState Empty => _empty; - - public Address Address { get; } - public ITrie Trie { get; } - public BlockHash? BlockHash { get; } - public IValue GetState(Address address) => - Trie.Get(KeyConverters.ToStateKey(address)); + Trie.Get(ToStateKey(address)); public IReadOnlyList GetStates(IReadOnlyList
addresses) => addresses.Select(GetState).ToList(); public FungibleAssetValue GetBalance(Address address, Currency currency) => - Trie.Get(KeyConverters.ToFungibleAssetKey(address, currency)) is Integer rawValue + Trie.Get(ToFungibleAssetKey(address, currency)) is Integer rawValue ? FungibleAssetValue.FromRawValue(currency, rawValue) : currency * 0; @@ -89,19 +88,20 @@ public FungibleAssetValue GetTotalSupply(Currency currency) throw new TotalSupplyNotTrackableException(msg, currency); } - return Trie.Get(KeyConverters.ToTotalSupplyKey(currency)) is Integer rawValue + return Trie.Get(ToTotalSupplyKey(currency)) is Integer rawValue ? FungibleAssetValue.FromRawValue(currency, rawValue) : currency * 0; } public ValidatorSet GetValidatorSet() => - Trie.Get(KeyConverters.ValidatorSetKey) is List list + Trie.Get(ValidatorSetKey) is List list ? new ValidatorSet(list) : new ValidatorSet(); public MockAccountState SetState(Address address, IValue state) => new MockAccountState( - Trie.Set(KeyConverters.ToStateKey(address), state)); + _stateStore, + _stateStore.Commit(Trie.Set(ToStateKey(address), state)).Hash); public MockAccountState SetBalance( Address address, FungibleAssetValue amount) => @@ -114,9 +114,11 @@ public MockAccountState SetBalance( public MockAccountState SetBalance( (Address Address, Currency Currency) pair, BigInteger rawAmount) => new MockAccountState( - Trie.Set( - KeyConverters.ToFungibleAssetKey(pair.Address, pair.Currency), - new Integer(rawAmount))); + _stateStore, + _stateStore.Commit( + Trie.Set( + ToFungibleAssetKey(pair.Address, pair.Currency), + new Integer(rawAmount))).Hash); public MockAccountState AddBalance(Address address, FungibleAssetValue amount) => AddBalance((address, amount.Currency), amount.RawValue); @@ -129,7 +131,7 @@ public MockAccountState AddBalance( (Address Address, Currency Currency) pair, BigInteger rawAmount) => SetBalance( pair, - (Trie.Get(KeyConverters.ToFungibleAssetKey(pair.Address, pair.Currency)) is + (Trie.Get(ToFungibleAssetKey(pair.Address, pair.Currency)) is Integer amount ? amount : 0) + rawAmount); public MockAccountState SubtractBalance( @@ -144,7 +146,7 @@ public MockAccountState SubtractBalance( (Address Address, Currency Currency) pair, BigInteger rawAmount) => SetBalance( pair, - (Trie.Get(KeyConverters.ToFungibleAssetKey(pair.Address, pair.Currency)) is + (Trie.Get(ToFungibleAssetKey(pair.Address, pair.Currency)) is Integer amount ? amount : 0) - rawAmount); public MockAccountState TransferBalance( @@ -163,7 +165,9 @@ public MockAccountState SetTotalSupply(Currency currency, BigInteger rawAmount) ? !(currency.MaximumSupply is FungibleAssetValue maximumSupply) || rawAmount <= maximumSupply.RawValue ? new MockAccountState( - Trie.Set(KeyConverters.ToTotalSupplyKey(currency), new Integer(rawAmount))) + _stateStore, + _stateStore.Commit( + Trie.Set(ToTotalSupplyKey(currency), new Integer(rawAmount))).Hash) : throw new ArgumentException( $"Given {currency}'s total supply is capped at {maximumSupply.RawValue} " + $"and cannot be set to {rawAmount}.") @@ -176,7 +180,7 @@ public MockAccountState AddTotalSupply(FungibleAssetValue amount) => public MockAccountState AddTotalSupply(Currency currency, BigInteger rawAmount) => SetTotalSupply( currency, - (Trie.Get(KeyConverters.ToTotalSupplyKey(currency)) is + (Trie.Get(ToTotalSupplyKey(currency)) is Integer amount ? amount : 0) + rawAmount); public MockAccountState SubtractTotalSupply(FungibleAssetValue amount) => @@ -185,12 +189,13 @@ public MockAccountState SubtractTotalSupply(FungibleAssetValue amount) => public MockAccountState SubtractTotalSupply(Currency currency, BigInteger rawAmount) => SetTotalSupply( currency, - (Trie.Get(KeyConverters.ToTotalSupplyKey(currency)) is + (Trie.Get(ToTotalSupplyKey(currency)) is Integer amount ? amount : 0) - rawAmount); public MockAccountState SetValidator(Validator validator) => new MockAccountState( - Trie.Set( - KeyConverters.ValidatorSetKey, GetValidatorSet().Update(validator).Bencoded)); + _stateStore, + _stateStore.Commit( + Trie.Set(ValidatorSetKey, GetValidatorSet().Update(validator).Bencoded)).Hash); } } diff --git a/Libplanet.Action.Tests/Mocks/MockWorldState.cs b/Libplanet.Action.Tests/Mocks/MockWorldState.cs index 5c4f259c528..a7545671be0 100644 --- a/Libplanet.Action.Tests/Mocks/MockWorldState.cs +++ b/Libplanet.Action.Tests/Mocks/MockWorldState.cs @@ -1,30 +1,34 @@ -using System.Collections.Immutable; +using System.Security.Cryptography; +using Bencodex.Types; using Libplanet.Action.State; +using Libplanet.Common; using Libplanet.Crypto; using Libplanet.Store; using Libplanet.Store.Trie; +using static Libplanet.Action.State.KeyConverters; namespace Libplanet.Action.Tests.Mocks { public class MockWorldState : IWorldState { - private readonly IImmutableDictionary _accounts; + private readonly IStateStore _stateStore; public MockWorldState() - : this(ImmutableDictionary.Empty) + : this(new TrieStateStore(new MemoryKeyValueStore()), null) { } - public MockWorldState(IImmutableDictionary accounts) - : this(new TrieStateStore(new MemoryKeyValueStore()).GetStateRoot(null), accounts) + public MockWorldState( + IStateStore stateStore, + HashDigest? stateRootHash = null) { - } - - public MockWorldState(ITrie trie, IImmutableDictionary accounts) - { - Trie = trie; - Legacy = true; - _accounts = accounts; + Trie = stateStore.GetStateRoot(stateRootHash); + Legacy = Trie + .Get(new[] + { + ToStateKey(ReservedAddresses.LegacyAccount), + }) + .Any(v => v == null); } public ITrie Trie { get; } @@ -32,11 +36,17 @@ public MockWorldState(ITrie trie, IImmutableDictionary accoun public bool Legacy { get; private set; } public IAccount GetAccount(Address address) - => _accounts.TryGetValue(address, out IAccount account) - ? account - : new Account(new MockAccountState()); - - public IWorldState SetAccount(Address address, IAccount account) => - new MockWorldState(_accounts.SetItem(address, account)); + => Legacy && address.Equals(ReservedAddresses.LegacyAccount) + ? new Account(new MockAccountState(_stateStore, Trie.Hash)) + : new Account(new MockAccountState( + _stateStore, new HashDigest(Trie.Get(ToStateKey(address))))); + + public IWorldState SetAccountState(Address address, IAccount account) + => Legacy && address.Equals(ReservedAddresses.LegacyAccount) + ? new MockWorldState(_stateStore, account.Trie.Hash) + : new MockWorldState( + _stateStore, + _stateStore.Commit( + Trie.Set(ToStateKey(address), new Binary(account.Trie.Hash.ByteArray))).Hash); } } diff --git a/Libplanet.Tests/Action/AccountTest.cs b/Libplanet.Tests/Action/AccountTest.cs index c79bc25b0d3..0ce9e29055e 100644 --- a/Libplanet.Tests/Action/AccountTest.cs +++ b/Libplanet.Tests/Action/AccountTest.cs @@ -51,7 +51,7 @@ protected AccountTest(ITestOutputHelper output) Currency.Capped("QUUX", 0, (100, 0), minter: _addr[0]), }; - _initAccount = new Account(MockAccountState.Empty + _initAccount = new Account(new MockAccountState() .SetState(_addr[0], (Text)"a") .SetState(_addr[1], (Text)"b") .SetBalance(_addr[0], _currencies[0], 5)