diff --git a/.gitallowed b/.gitallowed
new file mode 100644
index 000000000..0bd84f123
--- /dev/null
+++ b/.gitallowed
@@ -0,0 +1,19 @@
+# For BUILD_GENESIS.md
+e87a05d05506b73570e80f6e99beeceae6a9891333b2e8e8951197050fad96e2
+
+# For ConversionCommandTest.cs
+a1262b4f0911a9cec5e64344c0c9b50d64f8781ade0e09fa79faaa127ccdff89
+
+# For ValidationCommandTest.cs
+ab8d591ccdcce263c39eb1f353e44b64869f0afea2df643bf6839ebde650d244
+d6c3e0d525dac340a132ae05aaa9f3e278d61b70d2b71326570e64aee249e566
+761f68d68426549df5904395b5ca5bce64a3da759085d8565242db42a5a1b0b9
+
+# For Fixtures.cs
+b934cb79757b1dec9f89caa01c4b791a6de6937dbecdc102fbdca217156cc2f5
+
+# For AddressQueryTest.cs
+b8ce43967d7270348906c3b30efd41c30ab834ce07a36ee8ac5fd52cb7a3f579
+
+# For StandaloneQueryTest.cs
+9330b3287bd2bbc38770c69ae7cd380350c60a1dff9ec41254f3048d5b3eb01c
diff --git a/Lib9c b/Lib9c
index 8132d8023..fe86a78e2 160000
--- a/Lib9c
+++ b/Lib9c
@@ -1 +1 @@
-Subproject commit 8132d80236b7a586fb202d9be5101619917640a5
+Subproject commit fe86a78e29d7d15486779b133bea21ba0ec63f30
diff --git a/Libplanet.Headless.Tests/Hosting/LibplanetNodeServiceTest.cs b/Libplanet.Headless.Tests/Hosting/LibplanetNodeServiceTest.cs
index 85d414fb5..938e5e305 100644
--- a/Libplanet.Headless.Tests/Hosting/LibplanetNodeServiceTest.cs
+++ b/Libplanet.Headless.Tests/Hosting/LibplanetNodeServiceTest.cs
@@ -88,7 +88,7 @@ private class DummyAction : IAction
{
IValue IAction.PlainValue => Dictionary.Empty;
- IAccountStateDelta IAction.Execute(IActionContext context)
+ IAccount IAction.Execute(IActionContext context)
{
return context.PreviousState;
}
diff --git a/Libplanet.Headless/ReducedStore.cs b/Libplanet.Headless/ReducedStore.cs
index e55be9d65..389597d0b 100644
--- a/Libplanet.Headless/ReducedStore.cs
+++ b/Libplanet.Headless/ReducedStore.cs
@@ -113,7 +113,6 @@ public void PutTxExecution(TxSuccess txSuccess)
txSuccess.BlockHash,
txSuccess.TxId,
updatedStates: txSuccess.UpdatedStates.ToImmutableDictionary(pair => pair.Key, _ => (IValue)Null.Value),
- fungibleAssetsDelta: txSuccess.FungibleAssetsDelta,
updatedFungibleAssets: txSuccess.UpdatedFungibleAssets
);
InternalStore.PutTxExecution(reducedTxSuccess);
diff --git a/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs b/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs
index 8721e29b7..a0745ed60 100644
--- a/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs
+++ b/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs
@@ -198,7 +198,9 @@ public void ClaimStakeReward(string addressString, int expectedCode)
[InlineData(ClaimStakeReward6.ObsoleteBlockIndex, typeof(ClaimStakeReward6))]
[InlineData(ClaimStakeReward6.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward7))]
[InlineData(ClaimStakeReward7.ObsoleteBlockIndex, typeof(ClaimStakeReward7))]
- [InlineData(ClaimStakeReward7.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward))]
+ [InlineData(ClaimStakeReward7.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward8))]
+ [InlineData(ClaimStakeReward8.ObsoleteBlockIndex, typeof(ClaimStakeReward8))]
+ [InlineData(ClaimStakeReward8.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward))]
[InlineData(long.MaxValue, typeof(ClaimStakeReward))]
public void ClaimStakeRewardWithBlockIndex(long blockIndex, Type expectedActionType)
{
@@ -224,8 +226,8 @@ public void ClaimStakeRewardWithBlockIndex(long blockIndex, Type expectedActionT
[Theory]
[InlineData(0, 0, -1)]
- [InlineData(1, 8, 0)]
- [InlineData(9, 9, -1)]
+ [InlineData(1, 9, 0)]
+ [InlineData(10, 10, -1)]
public void ClaimStakeRewardWithActionVersion(
int actionVersionMin,
int actionVersionMax,
diff --git a/NineChronicles.Headless.Executable.Tests/Commands/ChainCommandTest.cs b/NineChronicles.Headless.Executable.Tests/Commands/ChainCommandTest.cs
index 893ddef93..17f04ca9a 100644
--- a/NineChronicles.Headless.Executable.Tests/Commands/ChainCommandTest.cs
+++ b/NineChronicles.Headless.Executable.Tests/Commands/ChainCommandTest.cs
@@ -255,7 +255,7 @@ public void PruneState(StoreType storeType)
_command.PruneStates(storeType, _storePath);
IStore outputStore = storeType.CreateStore(_storePath);
var outputStateKeyValueStore = new RocksDBKeyValueStore(statesPath);
- var outputStateStore = new TrieStateStore(outputStateKeyValueStore, true);
+ var outputStateStore = new TrieStateStore(outputStateKeyValueStore);
int outputStatesCount = outputStateKeyValueStore.ListKeys().Count();
outputStore.Dispose();
outputStateStore.Dispose();
diff --git a/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs b/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs
index 05046254b..9581815f3 100644
--- a/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs
+++ b/NineChronicles.Headless.Executable/Commands/ReplayCommand.Privates.cs
@@ -2,10 +2,8 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
-using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
-using System.Numerics;
using System.Security.Cryptography;
using Bencodex;
using Bencodex.Types;
@@ -13,481 +11,19 @@
using Libplanet.Common;
using Libplanet.Crypto;
using Libplanet.Action;
+using Libplanet.Action.State;
using Libplanet.Types.Assets;
using Libplanet.Types.Consensus;
-using Libplanet.Action.State;
using Libplanet.Types.Blocks;
using Libplanet.Types.Tx;
using RocksDbSharp;
using Serilog;
+using Libplanet.Store.Trie;
namespace NineChronicles.Headless.Executable.Commands
{
public partial class ReplayCommand : CoconaLiteConsoleAppBase
{
- ///
- /// Almost duplicate https://github.com/planetarium/libplanet/blob/main/Libplanet/State/AccountStateDelta.cs.
- ///
- [Pure]
- private sealed class AccountStateDelta : IAccountStateDelta
- {
- private readonly IAccountState _baseState;
-
- private AccountStateDelta(IAccountState baseState)
- : this(baseState, new AccountDelta())
- {
- }
-
- private AccountStateDelta(IAccountState baseState, IAccountDelta delta)
- {
- _baseState = baseState;
- Delta = delta;
- TotalUpdatedFungibles = ImmutableDictionary<(Address, Currency), BigInteger>.Empty;
- }
-
- ///
- public IAccountDelta Delta { get; private set; }
-
- ///
- public IImmutableSet<(Address, Currency)> TotalUpdatedFungibleAssets =>
- TotalUpdatedFungibles.Keys.ToImmutableHashSet();
-
- public IImmutableDictionary<(Address, Currency), BigInteger> TotalUpdatedFungibles { get; private set; }
-
- ///
- [Pure]
- public IValue? GetState(Address address)
- {
- IValue? state = GetStates(new[] { address })[0];
- return state;
- }
-
- ///
- [Pure]
- public IReadOnlyList GetStates(IReadOnlyList addresses)
- {
- int length = addresses.Count;
- IValue?[] values = new IValue?[length];
- var notFoundIndices = new List(length);
- for (int i = 0; i < length; i++)
- {
- Address address = addresses[i];
- if (Delta.States.TryGetValue(address, out IValue? updatedValue))
- {
- values[i] = updatedValue;
- }
- else
- {
- notFoundIndices.Add(i);
- }
- }
-
- if (notFoundIndices.Count > 0)
- {
- IReadOnlyList restValues = _baseState.GetStates(
- notFoundIndices.Select(index => addresses[index]).ToArray());
- foreach ((var v, var i) in notFoundIndices.Select((v, i) => (v, i)))
- {
- values[v] = restValues[i];
- }
- }
-
- return values;
- }
-
- ///
- [Pure]
- public IAccountStateDelta SetState(Address address, IValue state) =>
- UpdateStates(Delta.States.SetItem(address, state));
-
- ///
- [Pure]
- public FungibleAssetValue GetBalance(Address address, Currency currency) =>
- GetBalance(address, currency, Delta.Fungibles);
-
- ///
- [Pure]
- public FungibleAssetValue GetTotalSupply(Currency currency)
- {
- if (!currency.TotalSupplyTrackable)
- {
- throw new TotalSupplyNotTrackableException(
- $"Given currency {currency} is not trackable for its total supply",
- currency);
- }
-
- // Return dirty state if it exists.
- if (Delta.TotalSupplies.TryGetValue(currency, out BigInteger totalSupplyValue))
- {
- return FungibleAssetValue.FromRawValue(currency, totalSupplyValue);
- }
-
- return _baseState.GetTotalSupply(currency);
- }
-
- ///
- [Pure]
- public ValidatorSet GetValidatorSet() =>
- Delta.ValidatorSet ?? _baseState.GetValidatorSet();
-
- ///
- [Pure]
- public IAccountStateDelta MintAsset(
- IActionContext context, Address recipient, FungibleAssetValue value)
- {
- if (value.Sign <= 0)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- "The value to mint has to be greater than zero."
- );
- }
-
- Currency currency = value.Currency;
- if (!currency.AllowsToMint(context.Signer))
- {
- throw new CurrencyPermissionException(
- $"The account {context.Signer} has no permission to mint currency {currency}.",
- context.Signer,
- currency
- );
- }
-
- FungibleAssetValue balance = GetBalance(recipient, currency);
- (Address, Currency) assetKey = (recipient, currency);
- BigInteger rawBalance = (balance + value).RawValue;
-
- if (currency.TotalSupplyTrackable)
- {
- var currentTotalSupply = GetTotalSupply(currency);
- if (currency.MaximumSupply < currentTotalSupply + value)
- {
- var msg = $"The amount {value} attempted to be minted added to the current"
- + $" total supply of {currentTotalSupply} exceeds the"
- + $" maximum allowed supply of {currency.MaximumSupply}.";
- throw new SupplyOverflowException(msg, value);
- }
-
- return UpdateFungibleAssets(
- Delta.Fungibles.SetItem(assetKey, rawBalance),
- TotalUpdatedFungibles.SetItem(assetKey, rawBalance),
- Delta.TotalSupplies.SetItem(currency, (currentTotalSupply + value).RawValue)
- );
- }
-
- return UpdateFungibleAssets(
- Delta.Fungibles.SetItem(assetKey, rawBalance),
- TotalUpdatedFungibles.SetItem(assetKey, rawBalance)
- );
- }
-
- ///
- [Pure]
- public IAccountStateDelta TransferAsset(
- IActionContext context,
- Address sender,
- Address recipient,
- FungibleAssetValue value,
- bool allowNegativeBalance = false) => context.BlockProtocolVersion > 0
- ? TransferAssetV1(sender, recipient, value, allowNegativeBalance)
- : TransferAssetV0(sender, recipient, value, allowNegativeBalance);
-
- ///
- [Pure]
- public IAccountStateDelta BurnAsset(
- IActionContext context, Address owner, FungibleAssetValue value)
- {
- string msg;
-
- if (value.Sign <= 0)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- "The value to burn has to be greater than zero."
- );
- }
-
- Currency currency = value.Currency;
- if (!currency.AllowsToMint(context.Signer))
- {
- msg = $"The account {context.Signer} has no permission to burn assets of " +
- $"the currency {currency}.";
- throw new CurrencyPermissionException(msg, context.Signer, currency);
- }
-
- FungibleAssetValue balance = GetBalance(owner, currency);
-
- if (balance < value)
- {
- msg = $"The account {owner}'s balance of {currency} is insufficient to burn: " +
- $"{balance} < {value}.";
- throw new InsufficientBalanceException(msg, owner, balance);
- }
-
- (Address, Currency) assetKey = (owner, currency);
- BigInteger rawBalance = (balance - value).RawValue;
- if (currency.TotalSupplyTrackable)
- {
- return UpdateFungibleAssets(
- Delta.Fungibles.SetItem(assetKey, rawBalance),
- TotalUpdatedFungibles.SetItem(assetKey, rawBalance),
- Delta.TotalSupplies.SetItem(
- currency,
- (GetTotalSupply(currency) - value).RawValue)
- );
- }
-
- return UpdateFungibleAssets(
- Delta.Fungibles.SetItem(assetKey, rawBalance),
- TotalUpdatedFungibles.SetItem(assetKey, rawBalance)
- );
- }
-
- ///
- [Pure]
- public IAccountStateDelta SetValidator(Validator validator)
- {
- return UpdateValidatorSet(GetValidatorSet().Update(validator));
- }
-
- ///
- /// Creates a null state delta from given .
- ///
- /// The previous to use as
- /// a basis.
- /// A null state delta created from .
- ///
- internal static IAccountStateDelta Create(IAccountState previousState) =>
- new AccountStateDelta(previousState);
-
- ///
- /// Creates a null state delta while inheriting s
- /// total updated fungibles.
- ///
- /// The previous to use.
- /// A null state delta that is of the same type as .
- ///
- /// Thrown if given
- /// is not .
- ///
- ///
- /// This inherits 's
- /// .
- ///
- internal static IAccountStateDelta Flush(IAccountStateDelta stateDelta) =>
- stateDelta is AccountStateDelta impl
- ? new AccountStateDelta(stateDelta)
- {
- TotalUpdatedFungibles = impl.TotalUpdatedFungibles,
- }
- : throw new ArgumentException(
- $"Unknown type for {nameof(stateDelta)}: {stateDelta.GetType()}");
-
- [Pure]
- private FungibleAssetValue GetBalance(
- Address address,
- Currency currency,
- IImmutableDictionary<(Address, Currency), BigInteger> balances) =>
- balances.TryGetValue((address, currency), out BigInteger balance)
- ? FungibleAssetValue.FromRawValue(currency, balance)
- : _baseState.GetBalance(address, currency);
-
- [Pure]
- private AccountStateDelta UpdateStates(
- IImmutableDictionary updatedStates) =>
- new AccountStateDelta(
- _baseState,
- new AccountDelta(
- updatedStates,
- Delta.Fungibles,
- Delta.TotalSupplies,
- Delta.ValidatorSet))
- {
- TotalUpdatedFungibles = TotalUpdatedFungibles,
- };
-
- [Pure]
- private AccountStateDelta UpdateFungibleAssets(
- IImmutableDictionary<(Address, Currency), BigInteger> updatedFungibleAssets,
- IImmutableDictionary<(Address, Currency), BigInteger> totalUpdatedFungibles
- ) =>
- UpdateFungibleAssets(
- updatedFungibleAssets,
- totalUpdatedFungibles,
- Delta.TotalSupplies);
-
- [Pure]
- private AccountStateDelta UpdateFungibleAssets(
- IImmutableDictionary<(Address, Currency), BigInteger> updatedFungibleAssets,
- IImmutableDictionary<(Address, Currency), BigInteger> totalUpdatedFungibles,
- IImmutableDictionary updatedTotalSupply
- ) =>
- new AccountStateDelta(
- _baseState,
- new AccountDelta(
- Delta.States,
- updatedFungibleAssets,
- updatedTotalSupply,
- Delta.ValidatorSet))
- {
- TotalUpdatedFungibles = totalUpdatedFungibles,
- };
-
- [Pure]
- private AccountStateDelta UpdateValidatorSet(
- ValidatorSet updatedValidatorSet) =>
- new AccountStateDelta(
- _baseState,
- new AccountDelta(
- Delta.States,
- Delta.Fungibles,
- Delta.TotalSupplies,
- updatedValidatorSet))
- {
- TotalUpdatedFungibles = TotalUpdatedFungibles,
- };
-
- [Pure]
- private IAccountStateDelta TransferAssetV0(
- Address sender,
- Address recipient,
- FungibleAssetValue value,
- bool allowNegativeBalance = false)
- {
- if (value.Sign <= 0)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- "The value to transfer has to be greater than zero."
- );
- }
-
- Currency currency = value.Currency;
- FungibleAssetValue senderBalance = GetBalance(sender, currency);
- FungibleAssetValue recipientBalance = GetBalance(recipient, currency);
-
- if (!allowNegativeBalance && senderBalance < value)
- {
- var msg = $"The account {sender}'s balance of {currency} is insufficient to " +
- $"transfer: {senderBalance} < {value}.";
- throw new InsufficientBalanceException(msg, sender, senderBalance);
- }
-
- return UpdateFungibleAssets(
- Delta.Fungibles
- .SetItem((sender, currency), (senderBalance - value).RawValue)
- .SetItem((recipient, currency), (recipientBalance + value).RawValue),
- TotalUpdatedFungibles
- .SetItem((sender, currency), (senderBalance - value).RawValue)
- .SetItem((recipient, currency), (recipientBalance + value).RawValue)
- );
- }
-
- [Pure]
- private IAccountStateDelta TransferAssetV1(
- Address sender,
- Address recipient,
- FungibleAssetValue value,
- bool allowNegativeBalance = false)
- {
- if (value.Sign <= 0)
- {
- throw new ArgumentOutOfRangeException(
- nameof(value),
- "The value to transfer has to be greater than zero."
- );
- }
-
- Currency currency = value.Currency;
- FungibleAssetValue senderBalance = GetBalance(sender, currency);
-
- if (!allowNegativeBalance && senderBalance < value)
- {
- var msg = $"The account {sender}'s balance of {currency} is insufficient to " +
- $"transfer: {senderBalance} < {value}.";
- throw new InsufficientBalanceException(msg, sender, senderBalance);
- }
-
- (Address, Currency) senderAssetKey = (sender, currency);
- BigInteger senderRawBalance = (senderBalance - value).RawValue;
-
- IImmutableDictionary<(Address, Currency), BigInteger> updatedFungibleAssets =
- Delta.Fungibles.SetItem(senderAssetKey, senderRawBalance);
- IImmutableDictionary<(Address, Currency), BigInteger> totalUpdatedFungibles =
- TotalUpdatedFungibles.SetItem(senderAssetKey, senderRawBalance);
-
- FungibleAssetValue recipientBalance = GetBalance(
- recipient,
- currency,
- updatedFungibleAssets);
- (Address, Currency) recipientAssetKey = (recipient, currency);
- BigInteger recipientRawBalance = (recipientBalance + value).RawValue;
-
- return UpdateFungibleAssets(
- updatedFungibleAssets.SetItem(recipientAssetKey, recipientRawBalance),
- totalUpdatedFungibles.SetItem(recipientAssetKey, recipientRawBalance)
- );
- }
- }
-
- ///
- /// Almost duplicate https://github.com/planetarium/libplanet/blob/main/Libplanet/State/AccountDelta.cs.
- ///
- private sealed class AccountDelta : IAccountDelta
- {
- internal AccountDelta()
- {
- States = ImmutableDictionary.Empty;
- Fungibles = ImmutableDictionary<(Address, Currency), BigInteger>.Empty;
- TotalSupplies = ImmutableDictionary.Empty;
- ValidatorSet = null;
- }
-
- internal AccountDelta(
- IImmutableDictionary statesDelta,
- IImmutableDictionary<(Address, Currency), BigInteger> fungiblesDelta,
- IImmutableDictionary totalSuppliesDelta,
- ValidatorSet? validatorSetDelta)
- {
- States = statesDelta;
- Fungibles = fungiblesDelta;
- TotalSupplies = totalSuppliesDelta;
- ValidatorSet = validatorSetDelta;
- }
-
- ///
- public IImmutableSet UpdatedAddresses =>
- StateUpdatedAddresses.Union(FungibleUpdatedAddresses);
-
- ///
- public IImmutableSet StateUpdatedAddresses =>
- States.Keys.ToImmutableHashSet();
-
- ///
- public IImmutableDictionary States { get; }
-
- ///
- public IImmutableSet FungibleUpdatedAddresses =>
- Fungibles.Keys.Select(pair => pair.Item1).ToImmutableHashSet();
-
- ///
- public IImmutableSet<(Address, Currency)> UpdatedFungibleAssets =>
- Fungibles.Keys.ToImmutableHashSet();
-
- ///
- public IImmutableDictionary<(Address, Currency), BigInteger> Fungibles { get; }
-
- ///
- public IImmutableSet UpdatedTotalSupplyCurrencies =>
- TotalSupplies.Keys.ToImmutableHashSet();
-
- ///
- public IImmutableDictionary TotalSupplies { get; }
-
- ///
- public ValidatorSet? ValidatorSet { get; }
- }
-
///
/// Almost duplicate https://github.com/planetarium/libplanet/blob/main/Libplanet/Action/ActionContext.cs.
///
@@ -501,7 +37,7 @@ public ActionContext(
Address miner,
long blockIndex,
int blockProtocolVersion,
- IAccountStateDelta previousState,
+ IAccount previousState,
int randomSeed,
bool rehearsal = false)
{
@@ -528,7 +64,7 @@ public ActionContext(
public bool Rehearsal { get; }
- public IAccountStateDelta PreviousState { get; }
+ public IAccount PreviousState { get; }
public IRandom Random { get; }
@@ -584,47 +120,54 @@ public LocalCacheBlockChainStates(IBlockChainStates source, string cacheDirector
public IValue? GetState(Address address, BlockHash? offset)
{
- return GetBlockState(offset).GetState(address);
+ return GetAccountState(offset).GetState(address);
}
public IReadOnlyList GetStates(IReadOnlyList addresses, BlockHash? offset)
{
- return GetBlockState(offset).GetStates(addresses);
+ return GetAccountState(offset).GetStates(addresses);
}
public FungibleAssetValue GetBalance(Address address, Currency currency, BlockHash? offset)
{
- return GetBlockState(offset).GetBalance(address, currency);
+ return GetAccountState(offset).GetBalance(address, currency);
}
public FungibleAssetValue GetTotalSupply(Currency currency, BlockHash? offset)
{
- return GetBlockState(offset).GetTotalSupply(currency);
+ return GetAccountState(offset).GetTotalSupply(currency);
}
public ValidatorSet GetValidatorSet(BlockHash? offset)
{
- return GetBlockState(offset).GetValidatorSet();
+ return GetAccountState(offset).GetValidatorSet();
}
- public IBlockState GetBlockState(BlockHash? offset)
+ public IAccountState GetAccountState(BlockHash? offset)
{
- return new LocalCacheBlockState(_rocksDb, _source.GetBlockState(offset));
+ return new LocalCacheAccountState(_rocksDb, _source.GetAccountState, offset);
}
}
- private sealed class LocalCacheBlockState : IBlockState
+ private sealed class LocalCacheAccountState : IAccountState
{
private static readonly Codec _codec = new Codec();
private readonly RocksDb _rocksDb;
- private readonly IBlockState _sourceBlockState;
+ private readonly Func _sourceAccountStateGetter;
+ private readonly BlockHash? _offset;
- public LocalCacheBlockState(RocksDb rocksDb, IBlockState sourceBlockState)
+ public LocalCacheAccountState(
+ RocksDb rocksDb,
+ Func sourceAccountStateGetter,
+ BlockHash? offset)
{
_rocksDb = rocksDb;
- _sourceBlockState = sourceBlockState;
+ _sourceAccountStateGetter = sourceAccountStateGetter;
+ _offset = offset;
}
+ public ITrie Trie => _sourceAccountStateGetter(_offset).Trie;
+
public IValue? GetState(Address address)
{
var key = WithBlockHash(address.ToByteArray());
@@ -634,7 +177,7 @@ public LocalCacheBlockState(RocksDb rocksDb, IBlockState sourceBlockState)
}
catch (KeyNotFoundException)
{
- var state = _sourceBlockState.GetState(address);
+ var state = _sourceAccountStateGetter(_offset).GetState(address);
SetValue(key, state);
return state;
}
@@ -660,7 +203,7 @@ public FungibleAssetValue GetBalance(Address address, Currency currency)
}
catch (KeyNotFoundException)
{
- var fav = _sourceBlockState.GetBalance(address, currency);
+ var fav = _sourceAccountStateGetter(_offset).GetBalance(address, currency);
SetValue(key, (Integer)fav.RawValue);
return fav;
}
@@ -681,7 +224,7 @@ public FungibleAssetValue GetTotalSupply(Currency currency)
}
catch (KeyNotFoundException)
{
- var fav = _sourceBlockState.GetTotalSupply(currency);
+ var fav = _sourceAccountStateGetter(_offset).GetTotalSupply(currency);
SetValue(key, (Integer)fav.RawValue);
return fav;
}
@@ -697,14 +240,12 @@ public ValidatorSet GetValidatorSet()
}
catch (KeyNotFoundException)
{
- var validatorSet = _sourceBlockState.GetValidatorSet();
+ var validatorSet = _sourceAccountStateGetter(_offset).GetValidatorSet();
SetValue(key, validatorSet.Bencoded);
return validatorSet;
}
}
- public BlockHash? BlockHash => _sourceBlockState.BlockHash;
-
private IValue? GetValue(byte[] key)
{
if (_rocksDb.Get(key) is not { } bytes)
@@ -722,7 +263,7 @@ private void SetValue(byte[] key, IValue? value)
private byte[] WithBlockHash(params byte[][] suffixes)
{
- if (BlockHash is not { } blockHash)
+ if (_offset is not { } blockHash)
{
throw new InvalidOperationException();
}
@@ -746,7 +287,7 @@ private static IEnumerable EvaluateActions(
long blockIndex,
int blockProtocolVersion,
TxId? txid,
- IAccountStateDelta previousStates,
+ IAccount previousStates,
Address miner,
Address signer,
byte[] signature,
@@ -754,7 +295,7 @@ private static IEnumerable EvaluateActions(
ILogger? logger = null)
{
ActionContext CreateActionContext(
- IAccountStateDelta prevState,
+ IAccount prevState,
int randomSeed)
{
return new ActionContext(
@@ -776,11 +317,11 @@ ActionContext CreateActionContext(
byte[] preEvaluationHashBytes = preEvaluationHash.ToByteArray();
int seed = ActionEvaluator.GenerateRandomSeed(preEvaluationHashBytes, hashedSignature, signature, 0);
- IAccountStateDelta states = previousStates;
+ IAccount states = previousStates;
foreach (IAction action in actions)
{
Exception? exc = null;
- IAccountStateDelta nextStates = states;
+ IAccount nextStates = states;
ActionContext context = CreateActionContext(nextStates, seed);
try
diff --git a/NineChronicles.Headless.Executable/Commands/ReplayCommand.cs b/NineChronicles.Headless.Executable/Commands/ReplayCommand.cs
index 02a7f1218..19ebea278 100644
--- a/NineChronicles.Headless.Executable/Commands/ReplayCommand.cs
+++ b/NineChronicles.Headless.Executable/Commands/ReplayCommand.cs
@@ -100,8 +100,8 @@ public int Tx(
}
// Evaluate tx.
- IAccountState previousBlockStates = blockChain.GetBlockState(previousBlock.Hash);
- IAccountStateDelta previousStates = AccountStateDelta.Create(previousBlockStates);
+ IAccountState previousBlockStates = blockChain.GetAccountState(previousBlock.Hash);
+ IAccount previousStates = new Account(previousBlockStates);
var actions = tx.Actions.Select(a => ToAction(a));
var actionEvaluations = EvaluateActions(
preEvaluationHash: targetBlock.PreEvaluationHash,
@@ -398,8 +398,7 @@ public int RemoteTx(
cacheDirectory ?? Path.Join(Path.GetTempPath(), "ncd-replay-remote-tx-cache"));
var previousBlockHash = BlockHash.FromString(previousBlockHashValue);
- var previousStates =
- AccountStateDelta.Create(blockChainStates.GetBlockState(previousBlockHash));
+ var previousStates = new Account(blockChainStates.GetAccountState(previousBlockHash));
var actions = transaction.Actions
.Select(ToAction)
diff --git a/NineChronicles.Headless.Executable/Commands/StateCommand.cs b/NineChronicles.Headless.Executable/Commands/StateCommand.cs
index 513a7e90b..235e7bbd8 100644
--- a/NineChronicles.Headless.Executable/Commands/StateCommand.cs
+++ b/NineChronicles.Headless.Executable/Commands/StateCommand.cs
@@ -461,7 +461,7 @@ private static ImmutableDictionary GetTotalDelta(
return ImmutableDictionary.Empty;
}
- IAccountStateDelta lastStates = actionEvaluations[actionEvaluations.Count - 1].OutputState;
+ IAccount lastStates = actionEvaluations[actionEvaluations.Count - 1].OutputState;
ImmutableDictionary totalDelta =
stateUpdatedAddresses.ToImmutableDictionary(
diff --git a/NineChronicles.Headless.Executable/Commands/TxCommand.cs b/NineChronicles.Headless.Executable/Commands/TxCommand.cs
index 235d2a96c..88bef4faa 100644
--- a/NineChronicles.Headless.Executable/Commands/TxCommand.cs
+++ b/NineChronicles.Headless.Executable/Commands/TxCommand.cs
@@ -76,6 +76,7 @@ public void Sign(
nameof(ClaimStakeReward4) => new ClaimStakeReward4(),
nameof(ClaimStakeReward5) => new ClaimStakeReward5(),
nameof(ClaimStakeReward7) => new ClaimStakeReward7(),
+ nameof(ClaimStakeReward8) => new ClaimStakeReward8(),
nameof(ClaimStakeReward) => new ClaimStakeReward(),
nameof(TransferAsset) => new TransferAsset(),
nameof(MigrateMonsterCollection) => new MigrateMonsterCollection(),
diff --git a/NineChronicles.Headless.Tests/Common/Actions/EmptyAction.cs b/NineChronicles.Headless.Tests/Common/Actions/EmptyAction.cs
index de3b21288..a33c0ecb2 100644
--- a/NineChronicles.Headless.Tests/Common/Actions/EmptyAction.cs
+++ b/NineChronicles.Headless.Tests/Common/Actions/EmptyAction.cs
@@ -11,12 +11,12 @@ public void LoadPlainValue(IValue plainValue)
{
}
- public IAccountStateDelta Execute(IActionContext context)
+ public IAccount Execute(IActionContext context)
{
return context.PreviousState;
}
- public void Render(IActionContext context, IAccountStateDelta nextStates)
+ public void Render(IActionContext context, IAccount nextStates)
{
}
@@ -24,7 +24,7 @@ public void RenderError(IActionContext context, Exception exception)
{
}
- public void Unrender(IActionContext context, IAccountStateDelta nextStates)
+ public void Unrender(IActionContext context, IAccount nextStates)
{
}
diff --git a/NineChronicles.Headless.Tests/Common/Fixtures.cs b/NineChronicles.Headless.Tests/Common/Fixtures.cs
index c53218f24..59cdc950b 100644
--- a/NineChronicles.Headless.Tests/Common/Fixtures.cs
+++ b/NineChronicles.Headless.Tests/Common/Fixtures.cs
@@ -53,8 +53,11 @@ public static ShopState ShopStateFX()
{
var row = TableSheetsFX.EquipmentItemSheet.OrderedList[index];
var equipment = ItemFactory.CreateItemUsable(row, Guid.Empty, 0);
- var shopItem = new ShopItem(UserAddress, AvatarAddress, Guid.NewGuid(), index * CurrencyFX, equipment);
- shopState.Register(shopItem);
+ if (equipment is ITradableItem tradableItem)
+ {
+ var shopItem = new ShopItem(UserAddress, AvatarAddress, Guid.NewGuid(), index * CurrencyFX, tradableItem);
+ shopState.Register(shopItem);
+ }
}
for (var i = 0; i < TableSheetsFX.CostumeItemSheet.OrderedList.Count; i++)
diff --git a/NineChronicles.Headless.Tests/Common/MockState.cs b/NineChronicles.Headless.Tests/Common/MockState.cs
index 8ad33c2d0..2ca86f1b0 100644
--- a/NineChronicles.Headless.Tests/Common/MockState.cs
+++ b/NineChronicles.Headless.Tests/Common/MockState.cs
@@ -6,6 +6,7 @@
using Bencodex.Types;
using Libplanet.Action.State;
using Libplanet.Crypto;
+using Libplanet.Store.Trie;
using Libplanet.Types.Assets;
using Libplanet.Types.Consensus;
@@ -85,6 +86,8 @@ private MockState(
public ValidatorSet ValidatorSet => _validatorSet;
+ public ITrie Trie => throw new NotSupportedException();
+
public IValue? GetState(Address address) => _states.TryGetValue(address, out IValue? value)
? value
: null;
diff --git a/NineChronicles.Headless.Tests/GraphQLTestUtils.cs b/NineChronicles.Headless.Tests/GraphQLTestUtils.cs
index 12b3ba9bb..ce2ad8c6b 100644
--- a/NineChronicles.Headless.Tests/GraphQLTestUtils.cs
+++ b/NineChronicles.Headless.Tests/GraphQLTestUtils.cs
@@ -92,7 +92,7 @@ public static StandaloneContext CreateStandaloneContext()
stateStore,
genesisBlock,
actionEvaluator);
- var currencyFactory = new CurrencyFactory(blockchain.GetBlockState);
+ var currencyFactory = new CurrencyFactory(() => blockchain.GetAccountState(blockchain.Tip.Hash));
var fungibleAssetValueFactory = new FungibleAssetValueFactory(currencyFactory);
return new StandaloneContext
{
@@ -133,7 +133,7 @@ PrivateKey minerPrivateKey
actionEvaluator);
var ncg = new GoldCurrencyState((Dictionary)blockchain.GetState(Addresses.GoldCurrency))
.Currency;
- var currencyFactory = new CurrencyFactory(blockchain.GetBlockState, ncg);
+ var currencyFactory = new CurrencyFactory(() => blockchain.GetAccountState(blockchain.Tip.Hash), ncg);
var fungibleAssetValueFactory = new FungibleAssetValueFactory(currencyFactory);
return new StandaloneContext
{
diff --git a/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs b/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs
index b964d7416..8e720b2ce 100644
--- a/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs
+++ b/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs
@@ -1311,5 +1311,34 @@ private static IEnumerable