diff --git a/CHANGES.md b/CHANGES.md index 01b09e332a8..74f6cbb2275 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -68,6 +68,10 @@ To be released. - (Libplanet.Action) Type of `Initialize.States` property became `IImmutableDictionary>?`. (was `IImmutableDictionary?`) [[#3462]] + - (Libplanet.Action) New property `SystemAccounts` added to `IActionContext` + interface. [[#3462]] + - (Libplanet.Action) New property `SystemAccountsGetter` added to `IBlockPolicy` + interface. [[#3462]] ### Backward-incompatible network protocol changes @@ -85,6 +89,8 @@ To be released. - Added `WorldBaseState` class. - (Libplanet.Action) Added `ReservedAddresses` static class. [[#3462]] - (Libplanet.Action) Added `WorldDeltaExtensions` static class. [[#3462]] + - (Libplanet.Action) Added `ISystemAccounts` interface. [[#3462]] + - (Libplanet.Action) Added `ISystemAccountsGetter` interface. [[#3462]] - (Libplanet.Explorer) Added `AccountStateType` class. [[#3462]] - (Libplanet.Explorer) Added `WorldStateType` class. [[#3462]] - (Libplanet.Explorer) Added `WorldStateType` class. [[#3462]] diff --git a/Libplanet.Action.Tests/ActionContextTest.cs b/Libplanet.Action.Tests/ActionContextTest.cs index 555fcd3e0da..dabe0131387 100644 --- a/Libplanet.Action.Tests/ActionContextTest.cs +++ b/Libplanet.Action.Tests/ActionContextTest.cs @@ -12,12 +12,15 @@ public class ActionContextTest private readonly System.Random _random; private readonly Address _address; private readonly TxId _txid; + private readonly ISystemAccounts _systemAccounts; public ActionContextTest() { _random = new System.Random(); _address = _random.NextAddress(); _txid = _random.NextTxId(); + _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); } [Fact] @@ -34,6 +37,7 @@ public void RandomShouldBeDeterministic() signer: _address, txid: _txid, miner: _address, + systemAccounts: _systemAccounts, blockIndex: 1, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: new World(new MockWorldState()), @@ -52,6 +56,7 @@ public void GuidShouldBeDeterministic() signer: _address, txid: _txid, miner: _address, + systemAccounts: _systemAccounts, blockIndex: 1, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: new World(new MockWorldState()), @@ -63,6 +68,7 @@ public void GuidShouldBeDeterministic() signer: _address, txid: _txid, miner: _address, + systemAccounts: _systemAccounts, blockIndex: 1, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: new World(new MockWorldState()), @@ -74,6 +80,7 @@ public void GuidShouldBeDeterministic() signer: _address, txid: _txid, miner: _address, + systemAccounts: _systemAccounts, blockIndex: 1, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: new World(new MockWorldState()), @@ -113,6 +120,7 @@ public void GuidVersionAndVariant() signer: _address, txid: _txid, miner: _address, + systemAccounts: _systemAccounts, blockIndex: 1, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: new World(new MockWorldState()), diff --git a/Libplanet.Action.Tests/ActionEvaluationExtensions.cs b/Libplanet.Action.Tests/ActionEvaluationExtensions.cs index 7fd1b273ab4..9597fd6ed67 100644 --- a/Libplanet.Action.Tests/ActionEvaluationExtensions.cs +++ b/Libplanet.Action.Tests/ActionEvaluationExtensions.cs @@ -15,7 +15,7 @@ this IEnumerable evaluations ImmutableDictionary.Empty, (dirty, ev) => dirty.SetItems( ev.OutputState.GetAccount( - ReservedAddresses.LegacyAccount).GetUpdatedStates()) + ReservedAddresses.DefaultAccount).GetUpdatedStates()) ); public static IImmutableDictionary<(Address, Currency), FungibleAssetValue> @@ -26,7 +26,7 @@ this IEnumerable evaluations ImmutableDictionary<(Address, Currency), FungibleAssetValue>.Empty, (dirty, ev) => dirty.SetItems( ev.OutputState.GetAccount( - ReservedAddresses.LegacyAccount).GetUpdatedBalances()) + ReservedAddresses.DefaultAccount).GetUpdatedBalances()) ); public static IImmutableDictionary @@ -35,7 +35,7 @@ public static IImmutableDictionary ImmutableDictionary.Empty, (dirty, ev) => dirty.SetItems( ev.OutputState.GetAccount( - ReservedAddresses.LegacyAccount).GetUpdatedTotalSupplies()) + ReservedAddresses.DefaultAccount).GetUpdatedTotalSupplies()) ); } } diff --git a/Libplanet.Action.Tests/ActionEvaluationTest.cs b/Libplanet.Action.Tests/ActionEvaluationTest.cs index 1c0c1cfc3f6..f21168726f0 100644 --- a/Libplanet.Action.Tests/ActionEvaluationTest.cs +++ b/Libplanet.Action.Tests/ActionEvaluationTest.cs @@ -13,6 +13,8 @@ namespace Libplanet.Action.Tests public class ActionEvaluationTest { private readonly ILogger _logger; + private readonly ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); public ActionEvaluationTest(ITestOutputHelper output) { @@ -35,6 +37,7 @@ public void Constructor() address, txid, address, + _systemAccounts, 1, Block.CurrentProtocolVersion, new World(new MockWorldState()), @@ -43,7 +46,7 @@ public void Constructor() false), new World( new MockWorldState().SetAccountState( - ReservedAddresses.LegacyAccount, + ReservedAddresses.DefaultAccount, new Account(new MockAccountState().SetState(address, (Text)"item")))) ); var action = (DumbAction)evaluation.Action; @@ -56,11 +59,11 @@ public void Constructor() Assert.Equal(1, evaluation.InputContext.BlockIndex); Assert.Null( evaluation.InputContext.PreviousState.GetAccount( - ReservedAddresses.LegacyAccount).GetState(address) + ReservedAddresses.DefaultAccount).GetState(address) ); Assert.Equal( (Text)"item", - evaluation.OutputState.GetAccount(ReservedAddresses.LegacyAccount).GetState(address) + evaluation.OutputState.GetAccount(ReservedAddresses.DefaultAccount).GetState(address) ); } } diff --git a/Libplanet.Action.Tests/Common/Attack.cs b/Libplanet.Action.Tests/Common/Attack.cs index 62b3ad40bcc..7656950e5c7 100644 --- a/Libplanet.Action.Tests/Common/Attack.cs +++ b/Libplanet.Action.Tests/Common/Attack.cs @@ -34,7 +34,7 @@ public override IWorld Execute(IActionContext context) IImmutableSet usedWeapons = ImmutableHashSet.Empty; IImmutableSet targets = ImmutableHashSet.Empty; IWorld previousState = context.PreviousState; - IAccount legacyAccount = previousState.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = previousState.GetAccount(ReservedAddresses.DefaultAccount); object value = legacyAccount.GetState(TargetAddress); if (!ReferenceEquals(value, null)) @@ -49,7 +49,7 @@ public override IWorld Execute(IActionContext context) var result = new BattleResult(usedWeapons, targets); legacyAccount = legacyAccount.SetState(TargetAddress, result.ToBencodex()); - return previousState.SetAccount(ReservedAddresses.LegacyAccount, legacyAccount); + return previousState.SetAccount(ReservedAddresses.DefaultAccount, legacyAccount); } } } diff --git a/Libplanet.Action.Tests/Common/DelayAction.cs b/Libplanet.Action.Tests/Common/DelayAction.cs index bac1f8f75a1..26d199717bf 100644 --- a/Libplanet.Action.Tests/Common/DelayAction.cs +++ b/Libplanet.Action.Tests/Common/DelayAction.cs @@ -42,9 +42,9 @@ public IWorld Execute(IActionContext context) Thread.Sleep(MilliSecond); var ended = DateTimeOffset.UtcNow; var delayAccount = state - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .SetState(TrivialUpdatedAddress, new Bencodex.Types.Integer(MilliSecond)); - state = state.SetAccount(ReservedAddresses.LegacyAccount, delayAccount); + state = state.SetAccount(ReservedAddresses.DefaultAccount, delayAccount); Log.Debug( "{MethodName} Total Executed Time: {Elapsed}. Delay target: {MilliSecond}", nameof(DelayAction), diff --git a/Libplanet.Action.Tests/Common/DetectRehearsal.cs b/Libplanet.Action.Tests/Common/DetectRehearsal.cs index a0c7fc948ef..8f716242654 100644 --- a/Libplanet.Action.Tests/Common/DetectRehearsal.cs +++ b/Libplanet.Action.Tests/Common/DetectRehearsal.cs @@ -25,10 +25,10 @@ public override void LoadPlainValue(IValue plainValue) public override IWorld Execute(IActionContext context) { IWorld previousState = context.PreviousState; - IAccount legacyAccount = previousState.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = previousState.GetAccount(ReservedAddresses.DefaultAccount); ResultState = context.Rehearsal; return previousState.SetAccount( - ReservedAddresses.LegacyAccount, + ReservedAddresses.DefaultAccount, legacyAccount.SetState( TargetAddress, new Bencodex.Types.Boolean(context.Rehearsal) diff --git a/Libplanet.Action.Tests/Common/DumbAction.cs b/Libplanet.Action.Tests/Common/DumbAction.cs index fe2d64ec9be..7aa25ec9aad 100644 --- a/Libplanet.Action.Tests/Common/DumbAction.cs +++ b/Libplanet.Action.Tests/Common/DumbAction.cs @@ -150,7 +150,7 @@ public IWorld Execute(IActionContext context) return world; } - IAccount account = world.GetAccount(ReservedAddresses.LegacyAccount); + IAccount account = world.GetAccount(ReservedAddresses.DefaultAccount); string items = (Text?)account.GetState(TargetAddress); string item = RecordRehearsal ? $"{Item}:{context.Rehearsal}" @@ -221,7 +221,7 @@ public IWorld Execute(IActionContext context) Rehearsal = context.Rehearsal, }); - return world.SetAccount(ReservedAddresses.LegacyAccount, account); + return world.SetAccount(ReservedAddresses.DefaultAccount, account); } public void LoadPlainValue(IValue plainValue) diff --git a/Libplanet.Action.Tests/Common/MinerReward.cs b/Libplanet.Action.Tests/Common/MinerReward.cs index 957c30bdec6..90adf200749 100644 --- a/Libplanet.Action.Tests/Common/MinerReward.cs +++ b/Libplanet.Action.Tests/Common/MinerReward.cs @@ -39,7 +39,7 @@ public void LoadPlainValue(Dictionary plainValue) public IWorld Execute(IActionContext ctx) { IWorld states = ctx.PreviousState; - IAccount legacyAccount = states.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = states.GetAccount(ReservedAddresses.DefaultAccount); string rewardRecord = (Text?)legacyAccount.GetState(RewardRecordAddress); @@ -54,7 +54,7 @@ public IWorld Execute(IActionContext ctx) int reward = previousReward + Reward; legacyAccount = legacyAccount.SetState(ctx.Miner, (Integer)reward); - return states.SetAccount(ReservedAddresses.LegacyAccount, legacyAccount); + return states.SetAccount(ReservedAddresses.DefaultAccount, legacyAccount); } } } diff --git a/Libplanet.Action.Tests/Common/RandomAction.cs b/Libplanet.Action.Tests/Common/RandomAction.cs index f91d86b8406..f1e2ce03eb8 100644 --- a/Libplanet.Action.Tests/Common/RandomAction.cs +++ b/Libplanet.Action.Tests/Common/RandomAction.cs @@ -31,16 +31,16 @@ public void LoadPlainValue(IValue plainValue) public IWorld Execute(IActionContext context) { IWorld states = context.PreviousState; - IAccount legacyAccount = states.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = states.GetAccount(ReservedAddresses.DefaultAccount); if (context.Rehearsal) { return states.SetAccount( - ReservedAddresses.LegacyAccount, + ReservedAddresses.DefaultAccount, legacyAccount.SetState(Address, Null.Value)); } legacyAccount = legacyAccount.SetState(Address, (Integer)context.GetRandom().Next()); - return states.SetAccount(ReservedAddresses.LegacyAccount, legacyAccount); + return states.SetAccount(ReservedAddresses.DefaultAccount, legacyAccount); } } } diff --git a/Libplanet.Action.Tests/Common/SetValidator.cs b/Libplanet.Action.Tests/Common/SetValidator.cs index 20fde9391df..42d9573fe65 100644 --- a/Libplanet.Action.Tests/Common/SetValidator.cs +++ b/Libplanet.Action.Tests/Common/SetValidator.cs @@ -40,9 +40,9 @@ public void LoadPlainValue(IValue plainValue) public IWorld Execute(IActionContext context) { IWorld states = context.PreviousState; - IAccount legacyAccount = states.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = states.GetAccount(ReservedAddresses.DefaultAccount); return states.SetAccount( - ReservedAddresses.LegacyAccount, legacyAccount.SetValidator(Validator)); + ReservedAddresses.DefaultAccount, legacyAccount.SetValidator(Validator)); } /// diff --git a/Libplanet.Action.Tests/Loader/TypedActionLoaderTest.cs b/Libplanet.Action.Tests/Loader/TypedActionLoaderTest.cs index c386f58ee21..0f90d0afbcc 100644 --- a/Libplanet.Action.Tests/Loader/TypedActionLoaderTest.cs +++ b/Libplanet.Action.Tests/Loader/TypedActionLoaderTest.cs @@ -49,7 +49,7 @@ public void LoadAction() new List() { new Validator(new PrivateKey().PublicKey, 1) }).Bencoded, Dictionary.Empty.Add( - ReservedAddresses.LegacyAccount.ToByteArray(), + ReservedAddresses.DefaultAccount.ToByteArray(), Dictionary.Empty.Add( default(Address).ToByteArray(), "initial value")))); var action = new Initialize(); diff --git a/Libplanet.Action.Tests/Mocks/MockWorldState.cs b/Libplanet.Action.Tests/Mocks/MockWorldState.cs index a7545671be0..af77a9834b7 100644 --- a/Libplanet.Action.Tests/Mocks/MockWorldState.cs +++ b/Libplanet.Action.Tests/Mocks/MockWorldState.cs @@ -26,7 +26,7 @@ public MockWorldState( Legacy = Trie .Get(new[] { - ToStateKey(ReservedAddresses.LegacyAccount), + ToStateKey(ReservedAddresses.DefaultAccount), }) .Any(v => v == null); } @@ -36,13 +36,13 @@ public MockWorldState( public bool Legacy { get; private set; } public IAccount GetAccount(Address address) - => Legacy && address.Equals(ReservedAddresses.LegacyAccount) + => Legacy && address.Equals(ReservedAddresses.DefaultAccount) ? 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) + => Legacy && address.Equals(ReservedAddresses.DefaultAccount) ? new MockWorldState(_stateStore, account.Trie.Hash) : new MockWorldState( _stateStore, diff --git a/Libplanet.Action.Tests/Sys/InitializeTest.cs b/Libplanet.Action.Tests/Sys/InitializeTest.cs index 51b2287aeb4..811a07c6c39 100644 --- a/Libplanet.Action.Tests/Sys/InitializeTest.cs +++ b/Libplanet.Action.Tests/Sys/InitializeTest.cs @@ -27,6 +27,9 @@ private static readonly IImmutableDictionary [default] = (Text)"initial value", }.ToImmutableDictionary(); + private readonly ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + [Fact] public void Constructor() { @@ -44,11 +47,11 @@ public void Execute() var random = new System.Random(); Address signer = random.NextAddress(); var prevState = new World(new MockWorldState()); - BlockHash genesisHash = random.NextBlockHash(); var context = new ActionContext( signer: signer, txid: random.NextTxId(), miner: random.NextAddress(), + systemAccounts: _systemAccounts, blockIndex: 0, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: prevState, @@ -64,7 +67,7 @@ public void Execute() Assert.Equal( _validatorSet, - nextState.GetAccount(ReservedAddresses.LegacyAccount).GetValidatorSet()); + nextState.GetAccount(ReservedAddresses.DefaultAccount).GetValidatorSet()); Assert.Equal( _states[default], nextState.GetAccount(default).GetState(default)); @@ -81,6 +84,7 @@ public void ExecuteInNonGenesis() signer: signer, txid: random.NextTxId(), miner: random.NextAddress(), + systemAccounts: _systemAccounts, blockIndex: 10, blockProtocolVersion: Block.CurrentProtocolVersion, previousState: prevState, diff --git a/Libplanet.Action/ActionContext.cs b/Libplanet.Action/ActionContext.cs index f6cb0903329..60e81f89789 100644 --- a/Libplanet.Action/ActionContext.cs +++ b/Libplanet.Action/ActionContext.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics.Contracts; using System.Threading; using Libplanet.Action.State; using Libplanet.Crypto; @@ -17,6 +16,7 @@ public ActionContext( Address signer, TxId? txid, Address miner, + ISystemAccounts systemAccounts, long blockIndex, int blockProtocolVersion, IWorld previousState, @@ -27,6 +27,7 @@ public ActionContext( Signer = signer; TxId = txid; Miner = miner; + SystemAccounts = systemAccounts; BlockIndex = blockIndex; BlockProtocolVersion = blockProtocolVersion; Rehearsal = rehearsal; @@ -46,6 +47,9 @@ public ActionContext( /// public Address Miner { get; } + /// + public ISystemAccounts SystemAccounts { get; } + /// public long BlockIndex { get; } diff --git a/Libplanet.Action/ActionEvaluator.cs b/Libplanet.Action/ActionEvaluator.cs index 237a59d631b..ee4dea361cd 100644 --- a/Libplanet.Action/ActionEvaluator.cs +++ b/Libplanet.Action/ActionEvaluator.cs @@ -24,6 +24,7 @@ namespace Libplanet.Action public class ActionEvaluator : IActionEvaluator { private readonly ILogger _logger; + private readonly ISystemAccountsGetter _systemAccountsGetter; private readonly PolicyBlockActionGetter _policyBlockActionGetter; private readonly IStateStore _stateStore; private readonly IActionLoader _actionLoader; @@ -33,17 +34,21 @@ public class ActionEvaluator : IActionEvaluator /// /// A delegator to get policy block action to evaluate /// at the end for each that gets evaluated. + /// The to determine + /// with . /// The to use to retrieve /// the states for a provided . /// A implementation using /// action type lookup. public ActionEvaluator( + ISystemAccountsGetter systemAccountsGetter, PolicyBlockActionGetter policyBlockActionGetter, IStateStore stateStore, IActionLoader actionTypeLoader) { _logger = Log.ForContext() .ForContext("Source", nameof(ActionEvaluator)); + _systemAccountsGetter = systemAccountsGetter; _policyBlockActionGetter = policyBlockActionGetter; _stateStore = stateStore; _actionLoader = actionTypeLoader; @@ -130,6 +135,8 @@ public IReadOnlyList Evaluate( /// /// The of /// the that belong to. + /// The to determine + /// with . /// The that /// belong to. This should be if /// do not belong to a , i.e. @@ -167,6 +174,7 @@ public IReadOnlyList Evaluate( [Pure] internal static IEnumerable EvaluateActions( IPreEvaluationBlockHeader blockHeader, + ISystemAccountsGetter systemAccountsGetter, ITransaction? tx, IWorld previousState, IImmutableList actions, @@ -181,6 +189,7 @@ IActionContext CreateActionContext( signer: tx?.Signer ?? blockHeader.Miner, txid: tx?.Id ?? null, miner: blockHeader.Miner, + systemAccounts: new SystemAccounts(systemAccountsGetter, blockHeader), blockIndex: blockHeader.Index, blockProtocolVersion: blockHeader.ProtocolVersion, previousState: prevState, @@ -241,6 +250,7 @@ IActionContext CreateActionContext(IWorld newPrevState) signer: inputContext.Signer, txid: inputContext.TxId, miner: inputContext.Miner, + systemAccounts: inputContext.SystemAccounts, blockIndex: inputContext.BlockIndex, blockProtocolVersion: inputContext.BlockProtocolVersion, previousState: newPrevState, @@ -433,6 +443,7 @@ internal IEnumerable EvaluateTx( ImmutableList.CreateRange(LoadActions(blockHeader.Index, tx)); return EvaluateActions( blockHeader: blockHeader, + systemAccountsGetter: _systemAccountsGetter, tx: tx, previousState: previousState, actions: actions, @@ -470,6 +481,7 @@ internal ActionEvaluation EvaluatePolicyBlockAction( return EvaluateActions( blockHeader: blockHeader, + systemAccountsGetter: _systemAccountsGetter, tx: null, previousState: previousState, actions: new[] { policyBlockAction }.ToImmutableList()).Single(); @@ -569,7 +581,7 @@ internal IReadOnlyList stopwatch.Start(); var totalDelta = evaluation.OutputState.GetAccount( - ReservedAddresses.LegacyAccount).Delta.ToRawDelta(); + ReservedAddresses.DefaultAccount).Delta.ToRawDelta(); int setCount = 0; @@ -644,7 +656,7 @@ internal IReadOnlyList { Stopwatch stopwatch = new Stopwatch(); worldTrie = _stateStore.GetStateRoot(null).Set( - KeyConverters.ToStateKey(ReservedAddresses.LegacyAccount), + KeyConverters.ToStateKey(ReservedAddresses.DefaultAccount), new Binary(worldTrie.Hash.ByteArray)); _logger diff --git a/Libplanet.Action/IActionContext.cs b/Libplanet.Action/IActionContext.cs index 673918e2a02..cbc53f04345 100644 --- a/Libplanet.Action/IActionContext.cs +++ b/Libplanet.Action/IActionContext.cs @@ -37,6 +37,13 @@ public interface IActionContext [Pure] Address Miner { get; } + /// + /// The es of the s that are used on + /// the . + /// + [Pure] + ISystemAccounts SystemAccounts { get; } + /// /// The of the that contains /// the . diff --git a/Libplanet.Action/ISystemAccounts.cs b/Libplanet.Action/ISystemAccounts.cs new file mode 100644 index 00000000000..0d652c48515 --- /dev/null +++ b/Libplanet.Action/ISystemAccounts.cs @@ -0,0 +1,32 @@ +using Libplanet.Action.State; +using Libplanet.Crypto; + +namespace Libplanet.Action +{ + public interface ISystemAccounts + { + /// + /// of that stores state metadata. + /// + public Address StateMetadataAccount { get; } + + /// + /// of that stores + /// . + /// + public Address ValidatorSetAccount { get; } + + /// + /// of that + /// stores default . + /// + public Address DefaultAccount { get; } + + /// + /// of that + /// stores used as fee on + /// . + /// + public Address FeeAccount { get; } + } +} diff --git a/Libplanet.Action/ISystemAccountsGetter.cs b/Libplanet.Action/ISystemAccountsGetter.cs new file mode 100644 index 00000000000..a4239bfbc0d --- /dev/null +++ b/Libplanet.Action/ISystemAccountsGetter.cs @@ -0,0 +1,23 @@ +using Libplanet.Crypto; +using Libplanet.Types.Blocks; + +namespace Libplanet.Action +{ + /// + /// A delegate to determine of account with + /// . + /// + /// to determine + /// account . + /// Retrieved of account. + public delegate Address AccountAddressGetter(IPreEvaluationBlockHeader blockHeader); + + /// + /// Set of for + /// that have to be defined on the application. + /// + public interface ISystemAccountsGetter + { + public AccountAddressGetter FeeAccountGetter { get; } + } +} diff --git a/Libplanet.Action/State/ReservedAddresses.cs b/Libplanet.Action/State/ReservedAddresses.cs index cd002b6033a..466cec62a8b 100644 --- a/Libplanet.Action/State/ReservedAddresses.cs +++ b/Libplanet.Action/State/ReservedAddresses.cs @@ -4,13 +4,13 @@ namespace Libplanet.Action.State { public static class ReservedAddresses { - public static readonly Address LegacyAccount + public static readonly Address StateMetadataAccount = new Address("1000000000000000000000000000000000000000"); - public static readonly Address FungibleAssetsAccount + public static readonly Address ValidatorSetAccount = new Address("1000000000000000000000000000000000000001"); - public static readonly Address ValidatorSetAddress + public static readonly Address DefaultAccount = new Address("1000000000000000000000000000000000000002"); } } diff --git a/Libplanet.Action/State/World.cs b/Libplanet.Action/State/World.cs index 220a6938887..c999cf51591 100644 --- a/Libplanet.Action/State/World.cs +++ b/Libplanet.Action/State/World.cs @@ -73,14 +73,14 @@ public IAccount GetAccount(Address address) [Pure] public IWorld SetAccount(Address address, IAccount account) { - if (!address.Equals(ReservedAddresses.LegacyAccount) + if (!address.Equals(ReservedAddresses.DefaultAccount) && account.Delta.UpdatedFungibleAssets.Count > 0) { return this; } return new World(this, new WorldDelta(Delta.Accounts.SetItem(address, account))) - { Legacy = Legacy && address.Equals(ReservedAddresses.LegacyAccount) }; + { Legacy = Legacy && address.Equals(ReservedAddresses.DefaultAccount) }; } } } diff --git a/Libplanet.Action/State/WorldBaseState.cs b/Libplanet.Action/State/WorldBaseState.cs index e36506e905e..3cc9da280b9 100644 --- a/Libplanet.Action/State/WorldBaseState.cs +++ b/Libplanet.Action/State/WorldBaseState.cs @@ -25,7 +25,7 @@ public WorldBaseState(ITrie trie, IStateStore stateStore) Legacy = Trie .Get(new[] { - ToStateKey(ReservedAddresses.LegacyAccount), + ToStateKey(ReservedAddresses.DefaultAccount), }) .Any(v => v == null); } @@ -67,7 +67,7 @@ private IReadOnlyList GetAccountStateRoots(IReadOnlyList
address } private ITrie GetLegacyTrieOnly(Address address) => - address == ReservedAddresses.LegacyAccount + address == ReservedAddresses.DefaultAccount ? Trie : _stateStore.GetStateRoot(null); diff --git a/Libplanet.Action/State/WorldExtensions.cs b/Libplanet.Action/State/WorldExtensions.cs index 4235700fc56..e63d4de27b8 100644 --- a/Libplanet.Action/State/WorldExtensions.cs +++ b/Libplanet.Action/State/WorldExtensions.cs @@ -7,14 +7,14 @@ namespace Libplanet.Action.State internal static class WorldExtensions { internal static IAccount GetFungibleAssetsAccount(this IWorldState world) => - world.GetAccount(ReservedAddresses.LegacyAccount); + world.GetAccount(ReservedAddresses.DefaultAccount); internal static IAccount GetValidatorSetAccount(this IWorldState world) => - world.GetAccount(ReservedAddresses.LegacyAccount); + world.GetAccount(ReservedAddresses.DefaultAccount); internal static IWorld SetFungibleAssetsAccount( this IWorld world, IAccount account) => - world.SetAccount(ReservedAddresses.LegacyAccount, account); + world.SetAccount(ReservedAddresses.DefaultAccount, account); } } diff --git a/Libplanet.Action/Sys/Initialize.cs b/Libplanet.Action/Sys/Initialize.cs index a249fd9240f..017d17d88ac 100644 --- a/Libplanet.Action/Sys/Initialize.cs +++ b/Libplanet.Action/Sys/Initialize.cs @@ -66,7 +66,7 @@ public IValue PlainValue public IWorld Execute(IActionContext context) { IWorld world = context.PreviousState; - IAccount legacyAccount = world.GetAccount(ReservedAddresses.LegacyAccount); + IAccount legacyAccount = world.GetAccount(ReservedAddresses.DefaultAccount); if (context.BlockIndex != 0) { @@ -91,7 +91,7 @@ public IWorld Execute(IActionContext context) } } - world = world.SetAccount(ReservedAddresses.LegacyAccount, legacyAccount); + world = world.SetAccount(ReservedAddresses.DefaultAccount, legacyAccount); return world; } diff --git a/Libplanet.Action/SystemAccounts.cs b/Libplanet.Action/SystemAccounts.cs new file mode 100644 index 00000000000..1f847cd25bd --- /dev/null +++ b/Libplanet.Action/SystemAccounts.cs @@ -0,0 +1,32 @@ +using Libplanet.Action.State; +using Libplanet.Crypto; +using Libplanet.Types.Blocks; + +namespace Libplanet.Action +{ + public class SystemAccounts : ISystemAccounts + { + private readonly ISystemAccountsGetter _systemAccountsGetter; + private readonly IPreEvaluationBlockHeader _blockHeader; + + public SystemAccounts( + ISystemAccountsGetter systemAccountsGetter, + IPreEvaluationBlockHeader blockHeader) + { + _systemAccountsGetter = systemAccountsGetter; + _blockHeader = blockHeader; + } + + /// + public Address StateMetadataAccount => ReservedAddresses.StateMetadataAccount; + + /// + public Address ValidatorSetAccount => ReservedAddresses.ValidatorSetAccount; + + /// + public Address DefaultAccount => ReservedAddresses.DefaultAccount; + + /// + public Address FeeAccount => _systemAccountsGetter.FeeAccountGetter(_blockHeader); + } +} diff --git a/Libplanet.Action/SystemAccountsGetter.cs b/Libplanet.Action/SystemAccountsGetter.cs new file mode 100644 index 00000000000..9f88bd2e763 --- /dev/null +++ b/Libplanet.Action/SystemAccountsGetter.cs @@ -0,0 +1,12 @@ +namespace Libplanet.Action +{ + public class SystemAccountsGetter : ISystemAccountsGetter + { + public SystemAccountsGetter(AccountAddressGetter feeAccountGetter) + { + FeeAccountGetter = feeAccountGetter; + } + + public AccountAddressGetter FeeAccountGetter { get; } + } +} diff --git a/Libplanet.Benchmarks/AppendBlock.cs b/Libplanet.Benchmarks/AppendBlock.cs index d028c3f67ff..3da380ce262 100644 --- a/Libplanet.Benchmarks/AppendBlock.cs +++ b/Libplanet.Benchmarks/AppendBlock.cs @@ -1,13 +1,13 @@ using BenchmarkDotNet.Attributes; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; -using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; using Libplanet.Crypto; -using Libplanet.Types.Blocks; using Libplanet.Tests; using Libplanet.Tests.Store; +using Libplanet.Types.Blocks; namespace Libplanet.Benchmarks { @@ -23,12 +23,13 @@ public AppendBlock() { var fx = new DefaultStoreFixture(); _blockChain = Libplanet.Blockchain.BlockChain.Create( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), new VolatileStagePolicy(), fx.Store, fx.StateStore, fx.GenesisBlock, new ActionEvaluator( + systemAccountsGetter: new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), policyBlockActionGetter: _ => null, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Benchmarks/BlockChain.cs b/Libplanet.Benchmarks/BlockChain.cs index 7f78615a258..fe112014316 100644 --- a/Libplanet.Benchmarks/BlockChain.cs +++ b/Libplanet.Benchmarks/BlockChain.cs @@ -1,8 +1,8 @@ using BenchmarkDotNet.Attributes; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; -using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; using Libplanet.Crypto; using Libplanet.Tests.Store; @@ -29,12 +29,13 @@ public void SetupChain() { _fx = new DefaultStoreFixture(); _blockChain = Libplanet.Blockchain.BlockChain.Create( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), new VolatileStagePolicy(), _fx.Store, _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), policyBlockActionGetter: _ => null, stateStore: _fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Benchmarks/ProposeBlock.cs b/Libplanet.Benchmarks/ProposeBlock.cs index ab29b8214c2..6fc1e106b3b 100644 --- a/Libplanet.Benchmarks/ProposeBlock.cs +++ b/Libplanet.Benchmarks/ProposeBlock.cs @@ -1,13 +1,13 @@ using BenchmarkDotNet.Attributes; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; -using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; using Libplanet.Crypto; -using Libplanet.Types.Blocks; using Libplanet.Tests; using Libplanet.Tests.Store; +using Libplanet.Types.Blocks; namespace Libplanet.Benchmarks { @@ -22,12 +22,13 @@ public ProposeBlock() { var fx = new DefaultStoreFixture(); _blockChain = Libplanet.Blockchain.BlockChain.Create( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), new VolatileStagePolicy(), fx.Store, fx.StateStore, fx.GenesisBlock, new ActionEvaluator( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), policyBlockActionGetter: _ => null, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Explorer.Executable/Options.cs b/Libplanet.Explorer.Executable/Options.cs index 43c3c44b92e..1655dc10402 100644 --- a/Libplanet.Explorer.Executable/Options.cs +++ b/Libplanet.Explorer.Executable/Options.cs @@ -27,6 +27,7 @@ public Options( string mysqlUsername, string mysqlPassword, string mysqlDatabase, + string feeAccountAddressString, int maxTransactionsPerBlock, int maxTransactionsBytes, int maxGenesisTransactionsBytes, @@ -48,6 +49,7 @@ string genesisBlockPath MySQLUsername = mysqlUsername; MySQLPassword = mysqlPassword; MySQLDatabase = mysqlDatabase; + FeeAccountAddressString = feeAccountAddressString; MaxTransactionsPerBlock = maxTransactionsPerBlock; MaxTransactionsBytes = maxTransactionsBytes; MaxGenesisTransactionsBytes = maxGenesisTransactionsBytes; @@ -80,6 +82,17 @@ string genesisBlockPath public string MySQLDatabase { get; set; } + public string FeeAccountAddressString + { + get => FeeAccountAddress.ToHex(); + set + { + FeeAccountAddress = new Address(value); + } + } + + public Address FeeAccountAddress { get; set; } + public int MaxTransactionsPerBlock { get; set; } public int MaxTransactionsBytes { get; set; } diff --git a/Libplanet.Explorer.Executable/Program.cs b/Libplanet.Explorer.Executable/Program.cs index e82c1442f35..1f89fee5aa5 100644 --- a/Libplanet.Explorer.Executable/Program.cs +++ b/Libplanet.Explorer.Executable/Program.cs @@ -146,6 +146,10 @@ public async Task Serve( "mysql-database", Description = "The name of MySQL database to use.")] string mysqlDatabase = null, + [Option( + "fee-account-address", + Description = "The account address where fee stored.")] + string feeAccountAddress = null, [Option( "max-transactions-per-block", Description = @"The number of maximum transactions able to be included @@ -188,6 +192,7 @@ If omitted (default) explorer only the local blockchain store.")] mysqlUsername, mysqlPassword, mysqlDatabase, + feeAccountAddress, maxTransactionsPerBlock, maxTransactionsBytes, maxGenesisTransactionsBytes, @@ -224,6 +229,7 @@ If omitted (default) explorer only the local blockchain store.")] stateStore, options.GetGenesisBlock(policy), new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore, new SingleActionLoader(typeof(NullAction)))); @@ -396,6 +402,7 @@ private static IRichStore LoadStore(Options options) private static BlockPolicy LoadBlockPolicy(Options options) { return new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter(_ => options.FeeAccountAddress), blockAction: null, blockInterval: TimeSpan.FromMilliseconds(options.BlockIntervalMilliseconds), getMaxTransactionsBytes: i => i > 0 @@ -439,6 +446,8 @@ public DumbBlockPolicy(BlockPolicy blockPolicy) _impl = blockPolicy; } + public ISystemAccountsGetter SystemAccountsGetter => _impl.SystemAccountsGetter; + public IAction BlockAction => _impl.BlockAction; public int GetMinTransactionsPerBlock(long index) => diff --git a/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs b/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs index 734db62b40b..c8f79ecbf77 100644 --- a/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs +++ b/Libplanet.Explorer.Tests/GeneratedBlockChainFixture.cs @@ -79,11 +79,13 @@ public GeneratedBlockChainFixture( var privateKey = new PrivateKey(); var policy = new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), blockInterval: TimeSpan.FromMilliseconds(1), getMaxTransactionsPerBlock: _ => int.MaxValue, getMaxTransactionsBytes: _ => long.MaxValue); IStore store = new MemoryStore(); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore, TypedActionLoader.Create(typeof(SimpleAction).Assembly, typeof(SimpleAction))); @@ -188,7 +190,7 @@ private Transaction { var random = new System.Random(seed); var addr = pk.ToAddress(); - var bal = (int)(Chain.GetBalance(addr, TestCurrency, ReservedAddresses.LegacyAccount).MajorUnit & int.MaxValue); + var bal = (int)(Chain.GetBalance(addr, TestCurrency, ReservedAddresses.DefaultAccount).MajorUnit & int.MaxValue); return Transaction.Create( nonce, pk, diff --git a/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs b/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs index 1c164efb36c..7d08e8baafe 100644 --- a/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs +++ b/Libplanet.Explorer.Tests/Queries/StateQueryTest.cs @@ -29,7 +29,8 @@ public class StateQueryTest public async Task WorldStates() { (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy() + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -57,7 +58,8 @@ public async Task WorldStates() public async Task AccountStates() { (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy() + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -84,7 +86,8 @@ public async Task AccountStates() public async Task State() { (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy() + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -110,7 +113,7 @@ public async Task Balance() { (IBlockChainStates, IBlockPolicy) source = ( new MockChainStates(), - new BlockPolicy() + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -155,7 +158,8 @@ public async Task TotalSupply() var legacyToken = Currency.Legacy("LEG", 0, null); #pragma warning restore CS0618 (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy()); + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount))); ExecutionResult result = await ExecuteQueryAsync(@" { totalSupply( @@ -209,7 +213,7 @@ public async Task Validators() { (IBlockChainStates, IBlockPolicy) source = ( new MockChainStates(), - new BlockPolicy() + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -238,7 +242,8 @@ public async Task Validators() public async Task ThrowExecutionErrorIfViolateMutualExclusive() { (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy() + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -259,7 +264,8 @@ public async Task StateBySrh() { var currency = Currency.Uncapped("ABC", 2, minters: null); (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy() + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -285,7 +291,7 @@ public async Task BalanceBySrh() { (IBlockChainStates, IBlockPolicy) source = ( new MockChainStates(), - new BlockPolicy() + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { @@ -330,7 +336,8 @@ public async Task TotalSupplyBySrh() var legacyToken = Currency.Legacy("LEG", 0, null); #pragma warning restore CS0618 (IBlockChainStates, IBlockPolicy) source = ( - new MockChainStates(), new BlockPolicy()); + new MockChainStates(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount))); ExecutionResult result = await ExecuteQueryAsync(@" { totalSupply( @@ -385,7 +392,7 @@ public async Task ValidatorsBySrh() { (IBlockChainStates, IBlockPolicy) source = ( new MockChainStates(), - new BlockPolicy() + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)) ); ExecutionResult result = await ExecuteQueryAsync(@" { diff --git a/Libplanet.Explorer.Tests/Queries/TransactionQueryTest.cs b/Libplanet.Explorer.Tests/Queries/TransactionQueryTest.cs index 13e4dd48d47..1e5eaadee49 100644 --- a/Libplanet.Explorer.Tests/Queries/TransactionQueryTest.cs +++ b/Libplanet.Explorer.Tests/Queries/TransactionQueryTest.cs @@ -15,12 +15,12 @@ using Libplanet.Types.Assets; using Libplanet.Types.Consensus; using Libplanet.Types.Tx; -using Libplanet.Consensus; using Libplanet.Explorer.Queries; using Libplanet.Store; using Libplanet.Store.Trie; using Xunit; using static Libplanet.Explorer.Tests.GraphQLTestUtils; +using Libplanet.Action.State; namespace Libplanet.Explorer.Tests.Queries; @@ -33,7 +33,7 @@ public class TransactionQueryTest public TransactionQueryTest() { Chain = Libplanet.Tests.TestUtils.MakeBlockChain( - new BlockPolicy(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)), new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore()), privateKey: new PrivateKey(), diff --git a/Libplanet.Extensions.Cocona.Tests/BlockPolicyParamsTest.cs b/Libplanet.Extensions.Cocona.Tests/BlockPolicyParamsTest.cs index 7e6bd2863e1..de34a0eb560 100644 --- a/Libplanet.Extensions.Cocona.Tests/BlockPolicyParamsTest.cs +++ b/Libplanet.Extensions.Cocona.Tests/BlockPolicyParamsTest.cs @@ -1,8 +1,8 @@ namespace Libplanet.Extensions.Cocona.Tests; using System; -using System.Collections.Immutable; using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Blockchain.Policies; using Xunit; @@ -134,10 +134,12 @@ public void GetBlockAction() } internal static BlockPolicy BlockPolicyFactory() => - new BlockPolicy(blockAction: new NullAction()); + new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + blockAction: new NullAction()); internal static BlockPolicy BlockPolicyFactoryWithParams(bool param) => - new BlockPolicy(); + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); internal static int BlockPolicyFactoryWithWrongReturnType() => 0; @@ -145,5 +147,5 @@ internal static BlockPolicy BlockPolicyFactoryReturningNull() => null!; internal BlockPolicy BlockPolicyFactoryInstanceMethod() => - new BlockPolicy(); + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); } diff --git a/Libplanet.Extensions.Cocona/BlockPolicyParams.cs b/Libplanet.Extensions.Cocona/BlockPolicyParams.cs index 5a982efe5ef..c3330e1a4c4 100644 --- a/Libplanet.Extensions.Cocona/BlockPolicyParams.cs +++ b/Libplanet.Extensions.Cocona/BlockPolicyParams.cs @@ -1,7 +1,6 @@ namespace Libplanet.Extensions.Cocona; using System; -using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; @@ -74,6 +73,9 @@ public Assembly[] LoadAssemblies() public IAction? GetBlockAction() => GetBlockAction(LoadAssemblies()); + public ISystemAccountsGetter? GetSystemAccountsGetter() => + GetSystemAccountsGetter(LoadAssemblies()); + [SuppressMessage( "Major Code Smell", "S3011:Reflection should not be used to increase accessibility of classes, methods, " + @@ -145,4 +147,18 @@ public Assembly[] LoadAssemblies() .GetProperty(nameof(IBlockPolicy.BlockAction)); return (IAction?)prop!.GetValue(policy); } + + internal ISystemAccountsGetter? GetSystemAccountsGetter(Assembly[] assemblies) + { + object? policy = GetBlockPolicy(assemblies); + if (policy is null) + { + return null; + } + + PropertyInfo? prop = policy + .GetType() + .GetProperty(nameof(IBlockPolicy.SystemAccountsGetter)); + return (ISystemAccountsGetter?)prop!.GetValue(policy); + } } diff --git a/Libplanet.Extensions.Cocona/Commands/BlockCommand.cs b/Libplanet.Extensions.Cocona/Commands/BlockCommand.cs index 55f34fdb16b..736e1191c9c 100644 --- a/Libplanet.Extensions.Cocona/Commands/BlockCommand.cs +++ b/Libplanet.Extensions.Cocona/Commands/BlockCommand.cs @@ -156,8 +156,11 @@ public void GenerateGenesis( }.Select(x => x.PlainValue))) .ToImmutableList(); + var systemAccountsGetter = blockPolicyParams.GetSystemAccountsGetter() + ?? throw new NullReferenceException("SystemAccountGetter is absent from Policy"); var blockAction = blockPolicyParams.GetBlockAction(); var actionEvaluator = new ActionEvaluator( + systemAccountsGetter, _ => blockAction, new TrieStateStore(new DefaultKeyValueStore(null)), new SingleActionLoader(typeof(NullAction))); diff --git a/Libplanet.Net.Tests/Consensus/ConsensusReactorTest.cs b/Libplanet.Net.Tests/Consensus/ConsensusReactorTest.cs index 4b4318f2338..d795158e0ff 100644 --- a/Libplanet.Net.Tests/Consensus/ConsensusReactorTest.cs +++ b/Libplanet.Net.Tests/Consensus/ConsensusReactorTest.cs @@ -66,6 +66,7 @@ public async void StartAsync() stateStore, fx.GenesisBlock, new ActionEvaluator( + systemAccountsGetter: TestUtils.Policy.SystemAccountsGetter, policyBlockActionGetter: _ => TestUtils.Policy.BlockAction, stateStore: stateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs b/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs index 287284d5da7..c189038b594 100644 --- a/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextNonProposerTest.cs @@ -5,6 +5,8 @@ using System.Text.Json; using System.Threading.Tasks; using Bencodex.Types; +using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -259,6 +261,8 @@ public async Task EnterPreVoteNilOnInvalidBlockContent() var nilPreVoteSent = new AsyncAutoResetEvent(); var invalidKey = new PrivateKey(); var policy = new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter( + _ => ReservedAddresses.DefaultAccount), blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024, validateNextBlockTx: IsSignerValid); @@ -331,6 +335,8 @@ public async Task EnterPreVoteNilOnInvalidAction() var nilPreCommitSent = new AsyncAutoResetEvent(); var txSigner = new PrivateKey(); var policy = new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter( + _ => ReservedAddresses.DefaultAccount), blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024); diff --git a/Libplanet.Net.Tests/Consensus/ContextTest.cs b/Libplanet.Net.Tests/Consensus/ContextTest.cs index 6f138e00dcc..bf36baad3b1 100644 --- a/Libplanet.Net.Tests/Consensus/ContextTest.cs +++ b/Libplanet.Net.Tests/Consensus/ContextTest.cs @@ -6,6 +6,7 @@ using Bencodex; using Bencodex.Types; using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain.Policies; using Libplanet.Consensus; @@ -286,10 +287,13 @@ public async Task CanPreCommitOnEndCommit() var enteredEndCommit = new AsyncAutoResetEvent(); var blockHeightOneAppended = new AsyncAutoResetEvent(); var enteredHeightTwo = new AsyncAutoResetEvent(); + var systemAccountsGetter = new SystemAccountsGetter( + _ => ReservedAddresses.DefaultAccount); TimeSpan newHeightDelay = TimeSpan.FromSeconds(1); var policy = new BlockPolicy( + systemAccountsGetter: systemAccountsGetter, blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024); var fx = new MemoryStoreFixture(policy.BlockAction); diff --git a/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs b/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs index 12ac58e29d1..b738d8673d9 100644 --- a/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs +++ b/Libplanet.Net.Tests/Messages/NetMQMessageCodecTest.cs @@ -3,6 +3,8 @@ using System.Collections.Immutable; using System.Net; using Bencodex; +using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -77,7 +79,8 @@ private MessageContent CreateMessage(MessageContent.MessageType type) { var privateKey = new PrivateKey(); var boundPeer = new BoundPeer(privateKey.PublicKey, new DnsEndPoint("127.0.0.1", 1000)); - IBlockPolicy policy = new BlockPolicy(); + IBlockPolicy policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); BlockChain chain = MakeBlockChain( policy, new MemoryStore(), diff --git a/Libplanet.Net.Tests/SwarmTest.Broadcast.cs b/Libplanet.Net.Tests/SwarmTest.Broadcast.cs index e866975e125..43cd87b3ff5 100644 --- a/Libplanet.Net.Tests/SwarmTest.Broadcast.cs +++ b/Libplanet.Net.Tests/SwarmTest.Broadcast.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -40,7 +41,7 @@ public partial class SwarmTest public async Task BroadcastBlock() { const int numBlocks = 5; - var policy = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var genesis = new MemoryStoreFixture(policy.BlockAction).GenesisBlock; var swarmA = await CreateSwarm( @@ -92,7 +93,7 @@ public async Task BroadcastBlock() public async Task BroadcastBlockToReconnectedPeer() { var miner = new PrivateKey(); - var policy = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var fx = new MemoryStoreFixture(policy.BlockAction); var minerChain = MakeBlockChain(policy, fx.Store, fx.StateStore); foreach (int i in Enumerable.Range(0, 10)) @@ -449,7 +450,8 @@ public async Task BroadcastTxAsyncMany() { int size = 5; - var policy = new BlockPolicy(); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); StoreFixture[] fxs = new StoreFixture[size]; BlockChain[] blockChains = new BlockChain[size]; Swarm[] swarms = new Swarm[size]; @@ -464,6 +466,7 @@ public async Task BroadcastTxAsyncMany() fxs[i].StateStore, fxs[i].GenesisBlock, new ActionEvaluator( + systemAccountsGetter: policy.SystemAccountsGetter, policyBlockActionGetter: _ => policy.BlockAction, stateStore: fxs[i].StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -698,7 +701,9 @@ public async Task CanBroadcastBlock() [Fact(Timeout = Timeout)] public async Task BroadcastBlockWithSkip() { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var fx1 = new MemoryStoreFixture(); var blockChain = MakeBlockChain(policy, fx1.Store, fx1.StateStore); var privateKey = new PrivateKey(); diff --git a/Libplanet.Net.Tests/SwarmTest.Fixtures.cs b/Libplanet.Net.Tests/SwarmTest.Fixtures.cs index 5b0036abe00..d31d51b1316 100644 --- a/Libplanet.Net.Tests/SwarmTest.Fixtures.cs +++ b/Libplanet.Net.Tests/SwarmTest.Fixtures.cs @@ -5,6 +5,8 @@ using System.Linq; using System.Net; using System.Threading.Tasks; +using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -32,7 +34,9 @@ private static (Address, Block[]) if (blocks is null) { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); using (var storeFx = new MemoryStoreFixture()) { var chain = @@ -111,7 +115,9 @@ private async Task CreateSwarm( Block genesis = null, ConsensusReactorOption? consensusReactorOption = null) { - policy = policy ?? new BlockPolicy(new MinerReward(1)); + policy = policy ?? new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var fx = new MemoryStoreFixture(policy.BlockAction); var blockchain = MakeBlockChain( policy, diff --git a/Libplanet.Net.Tests/SwarmTest.Preload.cs b/Libplanet.Net.Tests/SwarmTest.Preload.cs index e2b11a8cd48..1fc118b4679 100644 --- a/Libplanet.Net.Tests/SwarmTest.Preload.cs +++ b/Libplanet.Net.Tests/SwarmTest.Preload.cs @@ -107,7 +107,7 @@ public async Task InitialBlockDownloadStates() await receiverSwarm.PreloadAsync(); var state = receiverChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address1); + ReservedAddresses.DefaultAccount).GetState(address1); Assert.Equal((Text)"foo,bar,baz", state); Assert.Equal(minerChain.BlockHashes, receiverChain.BlockHashes); @@ -264,8 +264,8 @@ public async Task PreloadWithMaliciousPeer() const int initialSharedTipHeight = 3; const int maliciousTipHeight = 5; const int honestTipHeight = 7; - var policy = new NullBlockPolicy(); - var policyB = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); + var policyB = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var genesis = new MemoryStoreFixture(policy.BlockAction).GenesisBlock; var swarmA = await CreateSwarm( @@ -376,7 +376,9 @@ public async Task PreloadWithMaliciousPeer() [RetryFact(Timeout = Timeout)] public async Task NoRenderInPreload() { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var renderer = new RecordingActionRenderer(); var chain = MakeBlockChain( policy, @@ -431,7 +433,8 @@ public async Task NoRenderInPreload() [Fact(Timeout = Timeout)] public async Task PreloadWithFailedActions() { - var policy = new BlockPolicy(); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); var fx1 = new MemoryStoreFixture(); var fx2 = new MemoryStoreFixture(); var minerChain = MakeBlockChain(policy, fx1.Store, fx1.StateStore); @@ -497,7 +500,9 @@ public async Task PreloadFromNominer() Swarm minerSwarm = await CreateSwarm(minerKey).ConfigureAwait(false); Swarm receiverSwarm = await CreateSwarm().ConfigureAwait(false); var fxForNominers = new StoreFixture[2]; - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); fxForNominers[0] = new MemoryStoreFixture(policy.BlockAction); fxForNominers[1] = new MemoryStoreFixture(policy.BlockAction); var blockChainsForNominers = new[] @@ -746,7 +751,7 @@ public async Task PreloadAsyncCancellation(int cancelAfter) Assert.Equal( (Text)string.Join(",", Enumerable.Range(0, 5).Select(j => $"Item0.{j}")), receiverChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address) + ReservedAddresses.DefaultAccount).GetState(address) ); } else @@ -760,7 +765,7 @@ public async Task PreloadAsyncCancellation(int cancelAfter) ) ), receiverChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address) + ReservedAddresses.DefaultAccount).GetState(address) ); } @@ -1005,7 +1010,8 @@ public async Task PreloadIgnorePeerWithDifferentGenesisBlock() { var key1 = new PrivateKey(); var key2 = new PrivateKey(); - var policy = new BlockPolicy(); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); BlockChain receiverChain = MakeBlockChain( policy, @@ -1070,7 +1076,9 @@ await receiverSwarm.AddPeersAsync( [Fact(Timeout = Timeout)] public async Task ActionExecutionWithBranchpoint() { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var fx1 = new MemoryStoreFixture(policy.BlockAction); var fx2 = new MemoryStoreFixture(policy.BlockAction); var seedChain = MakeBlockChain(policy, fx1.Store, fx1.StateStore); @@ -1131,7 +1139,9 @@ public async Task ActionExecutionWithBranchpoint() public async Task UpdateTxExecution() { PrivateKey seedKey = new PrivateKey(); - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var fx1 = new MemoryStoreFixture(policy.BlockAction); var fx2 = new MemoryStoreFixture(policy.BlockAction); var seedChain = MakeBlockChain(policy, fx1.Store, fx1.StateStore); diff --git a/Libplanet.Net.Tests/SwarmTest.cs b/Libplanet.Net.Tests/SwarmTest.cs index 5f4ecb5920a..13259636e0c 100644 --- a/Libplanet.Net.Tests/SwarmTest.cs +++ b/Libplanet.Net.Tests/SwarmTest.cs @@ -396,7 +396,7 @@ public async Task BootstrapContext() var roundChangedToOnes = Enumerable.Range(0, 4).Select(i => new AsyncAutoResetEvent()).ToList(); var roundOneProposed = new AsyncAutoResetEvent(); - var policy = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var genesis = new MemoryStoreFixture(policy.BlockAction).GenesisBlock; var consensusPeers = Enumerable.Range(0, 4).Select(i => @@ -678,7 +678,8 @@ await swarmA.GetTxsAsync( public async Task ThrowArgumentExceptionInConstructor() { var fx = new MemoryStoreFixture(); - var policy = new BlockPolicy(); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); var blockchain = MakeBlockChain(policy, fx.Store, fx.StateStore); var key = new PrivateKey(); var apv = AppProtocolVersion.Sign(key, 1); @@ -875,7 +876,9 @@ async Task MineAndBroadcast(CancellationToken cancellationToken) [Fact(Timeout = Timeout)] public async Task RenderInFork() { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); var renderer = new RecordingActionRenderer(); var chain = MakeBlockChain( policy, @@ -942,7 +945,9 @@ public async Task RenderInFork() [Fact(Skip = "This should be fixed to work deterministically.")] public async Task HandleReorgInSynchronizing() { - var policy = new BlockPolicy(new MinerReward(1)); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + new MinerReward(1)); async Task MakeSwarm(PrivateKey key = null) => await CreateSwarm( @@ -1056,9 +1061,9 @@ public async void RestageTransactionsOnceLocallyMinedAfterReorg(bool restage) minerB.BlockChain.Append(blockC, TestUtils.CreateBlockCommit(blockC)); Assert.Equal((Text)dumbItem, minerA.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress1)); + ReservedAddresses.DefaultAccount).GetState(targetAddress1)); Assert.Equal((Text)dumbItem, minerB.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress2)); + ReservedAddresses.DefaultAccount).GetState(targetAddress2)); await StartAsync(minerA); await StartAsync(minerB); @@ -1074,9 +1079,9 @@ public async void RestageTransactionsOnceLocallyMinedAfterReorg(bool restage) Assert.Equal( restage ? null : (Text?)dumbItem, minerA.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress1)); + ReservedAddresses.DefaultAccount).GetState(targetAddress1)); Assert.Equal((Text)dumbItem, minerA.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress2)); + ReservedAddresses.DefaultAccount).GetState(targetAddress2)); Log.Debug("Check if txs in unrendered blocks staged again"); Assert.Equal( @@ -1091,9 +1096,9 @@ public async void RestageTransactionsOnceLocallyMinedAfterReorg(bool restage) Assert.Equal(minerA.BlockChain.Tip, minerB.BlockChain.Tip); Assert.Equal((Text)dumbItem, minerA.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress1)); + ReservedAddresses.DefaultAccount).GetState(targetAddress1)); Assert.Equal((Text)dumbItem, minerA.BlockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(targetAddress2)); + ReservedAddresses.DefaultAccount).GetState(targetAddress2)); } finally { @@ -1117,7 +1122,9 @@ TxPolicyViolationException IsSignerValid( : new TxPolicyViolationException("invalid signer", tx.Id); } - var policy = new BlockPolicy(validateNextBlockTx: IsSignerValid); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + validateNextBlockTx: IsSignerValid); var fx1 = new MemoryStoreFixture(); var fx2 = new MemoryStoreFixture(); @@ -1176,7 +1183,9 @@ TxPolicyViolationException IsSignerValid( : new TxPolicyViolationException("invalid signer", tx.Id); } - var policy = new BlockPolicy(validateNextBlockTx: IsSignerValid); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), + validateNextBlockTx: IsSignerValid); var fx1 = new MemoryStoreFixture(); var fx2 = new MemoryStoreFixture(); @@ -1233,9 +1242,9 @@ public async Task CreateNewChainWhenBranchPointNotExist() PrivateKey keyC = PrivateKey.FromString( "941bc2edfab840d79914d80fe3b30840628ac37a5d812d7f922b5d2405a223d3"); - var policy = new NullBlockPolicy(); - var policyA = new NullBlockPolicy(); - var policyB = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); + var policyA = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); + var policyB = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var fx = new DefaultStoreFixture(); var genesis = fx.GenesisBlock; Block aBlock1 = ProposeNextBlock( @@ -1351,7 +1360,7 @@ public async Task DoNotReceiveBlockFromNodeHavingDifferenceGenesisBlock() var actionsB = new[] { new DumbAction(signerAddress, "2") }; var genesisChainA = MakeBlockChain( - new BlockPolicy(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)), new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore()), actionsA, @@ -1359,14 +1368,14 @@ public async Task DoNotReceiveBlockFromNodeHavingDifferenceGenesisBlock() privateKeyA); var genesisBlockA = genesisChainA.Genesis; var genesisChainB = MakeBlockChain( - new BlockPolicy(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)), new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore()), actionsB, null, privateKeyB); var genesisChainC = MakeBlockChain( - new BlockPolicy(), + new BlockPolicy(new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)), new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore()), genesisBlock: genesisBlockA); @@ -1402,11 +1411,11 @@ public async Task DoNotReceiveBlockFromNodeHavingDifferenceGenesisBlock() Assert.Equal(2, genesisChainC.Count); Assert.Equal("1", (Text)genesisChainA.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(signerAddress)); + ReservedAddresses.DefaultAccount).GetState(signerAddress)); Assert.Equal("2", (Text)genesisChainB.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(signerAddress)); + ReservedAddresses.DefaultAccount).GetState(signerAddress)); Assert.Equal("1", (Text)genesisChainC.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(signerAddress)); + ReservedAddresses.DefaultAccount).GetState(signerAddress)); } finally { diff --git a/Libplanet.Net.Tests/TestUtils.cs b/Libplanet.Net.Tests/TestUtils.cs index 8f55848a9db..f6d33050065 100644 --- a/Libplanet.Net.Tests/TestUtils.cs +++ b/Libplanet.Net.Tests/TestUtils.cs @@ -5,6 +5,8 @@ using System.Net; using System.Threading.Tasks; using Bencodex; +using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -44,6 +46,7 @@ public static class TestUtils public static readonly ValidatorSet ValidatorSet = Libplanet.Tests.TestUtils.ValidatorSet; public static readonly IBlockPolicy Policy = new BlockPolicy( + systemAccountsGetter: new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024); diff --git a/Libplanet.Net.Tests/Transports/BoundPeerExtensionsTest.cs b/Libplanet.Net.Tests/Transports/BoundPeerExtensionsTest.cs index 29f496ee1d9..5540bb204df 100644 --- a/Libplanet.Net.Tests/Transports/BoundPeerExtensionsTest.cs +++ b/Libplanet.Net.Tests/Transports/BoundPeerExtensionsTest.cs @@ -3,6 +3,8 @@ using System.Net; using System.Net.Sockets; using System.Threading.Tasks; +using Libplanet.Action; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain.Policies; using Libplanet.Crypto; @@ -28,7 +30,8 @@ public void Dispose() public async Task QueryAppProtocolVersion() { var fx = new MemoryStoreFixture(); - var policy = new BlockPolicy(); + var policy = new BlockPolicy( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount)); var blockchain = MakeBlockChain(policy, fx.Store, fx.StateStore); var swarmKey = new PrivateKey(); var consensusKey = new PrivateKey(); diff --git a/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs b/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs index d11c0f37b6d..4fe0889d770 100644 --- a/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs +++ b/Libplanet.RocksDBStore.Tests/RocksDBStoreTest.cs @@ -4,6 +4,7 @@ using System.Reflection; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -80,12 +81,13 @@ public void ReopenStoreAfterDispose() var store = new RocksDBStore(path); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var blocks = BlockChain.Create( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), new VolatileStagePolicy(), store, stateStore, Fx.GenesisBlock, new ActionEvaluator( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), policyBlockActionGetter: _ => null, stateStore: stateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Tests/Action/AccountDiffTest.cs b/Libplanet.Tests/Action/AccountDiffTest.cs index a47fdec6bb6..a41515c8889 100644 --- a/Libplanet.Tests/Action/AccountDiffTest.cs +++ b/Libplanet.Tests/Action/AccountDiffTest.cs @@ -14,6 +14,9 @@ namespace Libplanet.Tests.Action { public class AccountDiffTest { + private readonly ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + public AccountDiffTest() { USD = Currency.Uncapped("USD", 2, null); @@ -146,6 +149,7 @@ public IActionContext CreateActionContext(Address signer, ITrie trie) => signer, null, signer, + _systemAccounts, 0, Block.CurrentProtocolVersion, new World( diff --git a/Libplanet.Tests/Action/AccountTest.cs b/Libplanet.Tests/Action/AccountTest.cs index 0ce9e29055e..143aa5fb976 100644 --- a/Libplanet.Tests/Action/AccountTest.cs +++ b/Libplanet.Tests/Action/AccountTest.cs @@ -208,7 +208,7 @@ public virtual BlockChain TransferAssetInBlock() var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var privateKey = new PrivateKey(); BlockChain chain = TestUtils.MakeBlockChain( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), store, stateStore, protocolVersion: ProtocolVersion, @@ -238,11 +238,13 @@ public virtual BlockChain TransferAssetInBlock() ); Assert.Equal( DumbAction.DumbCurrency * 5, - chain.GetBalance(_addr[0], DumbAction.DumbCurrency, ReservedAddresses.LegacyAccount) + chain.GetBalance( + _addr[0], DumbAction.DumbCurrency, ReservedAddresses.DefaultAccount) ); Assert.Equal( DumbAction.DumbCurrency * -5, - chain.GetBalance(_addr[1], DumbAction.DumbCurrency, ReservedAddresses.LegacyAccount) + chain.GetBalance( + _addr[1], DumbAction.DumbCurrency, ReservedAddresses.DefaultAccount) ); return chain; diff --git a/Libplanet.Tests/Action/AccountV0Test.cs b/Libplanet.Tests/Action/AccountV0Test.cs index b2de5edc7fc..da7e5af7968 100644 --- a/Libplanet.Tests/Action/AccountV0Test.cs +++ b/Libplanet.Tests/Action/AccountV0Test.cs @@ -16,6 +16,9 @@ public class AccountV0Test : AccountTest private readonly Address _accountAddress = new Address("2000000000000000000000000000000000000000"); + private readonly ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + public AccountV0Test(ITestOutputHelper output) : base(output) { @@ -32,6 +35,7 @@ public override IActionContext CreateContext( signer, null, signer, + _systemAccounts, 0, ProtocolVersion, world, @@ -81,7 +85,8 @@ public override BlockChain TransferAssetInBlock() chain.Append(block, TestUtils.CreateBlockCommit(block)); Assert.Equal( DumbAction.DumbCurrency * 6, - chain.GetBalance(_addr[0], DumbAction.DumbCurrency, ReservedAddresses.LegacyAccount) + chain.GetBalance( + _addr[0], DumbAction.DumbCurrency, ReservedAddresses.DefaultAccount) ); return chain; diff --git a/Libplanet.Tests/Action/AccountV1Test.cs b/Libplanet.Tests/Action/AccountV1Test.cs index 25c31e782d1..92632339a96 100644 --- a/Libplanet.Tests/Action/AccountV1Test.cs +++ b/Libplanet.Tests/Action/AccountV1Test.cs @@ -19,6 +19,9 @@ public class AccountV1Test : AccountTest private readonly Address _accountAddress = new Address("2000000000000000000000000000000000000000"); + private readonly ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + public AccountV1Test(ITestOutputHelper output) : base(output) { @@ -34,6 +37,7 @@ public override IActionContext CreateContext(IAccount delta, Address signer) signer, null, signer, + _systemAccounts, 0, ProtocolVersion, world, @@ -85,7 +89,8 @@ public override BlockChain TransferAssetInBlock() ); Assert.Equal( DumbAction.DumbCurrency * 5, - chain.GetBalance(_addr[0], DumbAction.DumbCurrency, ReservedAddresses.LegacyAccount) + chain.GetBalance( + _addr[0], DumbAction.DumbCurrency, ReservedAddresses.DefaultAccount) ); return chain; diff --git a/Libplanet.Tests/Action/ActionEvaluatorTest.cs b/Libplanet.Tests/Action/ActionEvaluatorTest.cs index 44f6a09ac02..9fb13d7925f 100644 --- a/Libplanet.Tests/Action/ActionEvaluatorTest.cs +++ b/Libplanet.Tests/Action/ActionEvaluatorTest.cs @@ -37,6 +37,8 @@ public class ActionEvaluatorTest private readonly BlockPolicy _policy; private readonly StoreFixture _storeFx; private readonly TxFixture _txFx; + private readonly ISystemAccountsGetter _systemAccountsGetter = + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount); public ActionEvaluatorTest(ITestOutputHelper output) { @@ -49,6 +51,7 @@ public ActionEvaluatorTest(ITestOutputHelper output) _output = output; _policy = new BlockPolicy( + _systemAccountsGetter, blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024); _storeFx = new MemoryStoreFixture(_policy.BlockAction); @@ -85,6 +88,7 @@ public void Idempotent() lastCommit: null), transactions: txs).Propose(); var actionEvaluator = new ActionEvaluator( + _systemAccountsGetter, _ => null, stateStore, new SingleActionLoader(typeof(RandomAction))); @@ -104,13 +108,13 @@ public void Idempotent() generatedRandomNumbers.Add( (Integer)new WorldBaseState( stateStore.GetStateRoot(actionEvaluations[0].OutputState), stateStore) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState(txAddress)); actionEvaluations = actionEvaluator.Evaluate(stateRootBlock, null); generatedRandomNumbers.Add( (Integer)new WorldBaseState( stateStore.GetStateRoot(actionEvaluations[0].OutputState), stateStore) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState(txAddress)); } @@ -137,7 +141,7 @@ public void Evaluate() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), store: store, stateStore: stateStore); var tx = Transaction.Create( @@ -159,14 +163,14 @@ public void Evaluate() Assert.Null(evaluations.Single().Exception); Assert.Equal( chain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(action.SignerKey), + .GetAccount(ReservedAddresses.DefaultAccount).GetState(action.SignerKey), (Text)address.ToHex()); Assert.Equal( chain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(action.MinerKey), + .GetAccount(ReservedAddresses.DefaultAccount).GetState(action.MinerKey), (Text)miner.ToAddress().ToHex()); var state = chain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(action.BlockIndexKey); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(action.BlockIndexKey); Assert.Equal((long)(Integer)state, blockIndex); } @@ -181,7 +185,7 @@ public void EvaluateWithException() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), store: store, stateStore: stateStore); var tx = Transaction.Create( @@ -223,7 +227,7 @@ public void EvaluateWithCriticalException() new TrieStateStore(new MemoryKeyValueStore()); var (chain, actionEvaluator) = TestUtils.MakeBlockChainAndActionEvaluator( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), store: store, stateStore: stateStore); var genesis = chain.Genesis; @@ -281,6 +285,7 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu Block genesis = ProposeGenesisBlock(TestUtils.GenesisProposer); var actionEvaluator = new ActionEvaluator( + _systemAccountsGetter, policyBlockActionGetter: _ => null, stateStore: new TrieStateStore(new MemoryKeyValueStore()), actionTypeLoader: new SingleActionLoader(typeof(DumbAction))); @@ -350,13 +355,13 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu randomValue = eval.InputContext.GetRandom().Next(); Assert.Equal( (Integer)eval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState(DumbAction.RandomRecordsAddress), (Integer)randomValue); Assert.Equal( expect.UpdatedStates, addresses.Select( - eval.OutputState.GetAccount(ReservedAddresses.LegacyAccount).GetState) + eval.OutputState.GetAccount(ReservedAddresses.DefaultAccount).GetState) .Select(x => x is Text t ? t.Value : null)); } @@ -460,7 +465,7 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu foreach (var (expect, eval) in expectations.Zip(evals, (x, y) => (x, y))) { List updatedStates = addresses - .Select(eval.OutputState.GetAccount(ReservedAddresses.LegacyAccount).GetState) + .Select(eval.OutputState.GetAccount(ReservedAddresses.DefaultAccount).GetState) .Select(x => x is Text t ? t.Value : null) .ToList(); Assert.Equal(expect.UpdatedStates, updatedStates); @@ -476,7 +481,7 @@ DumbAction MakeAction(Address address, char identifier, Address? transferTo = nu randomValue = eval.InputContext.GetRandom().Next(); Assert.Equal( eval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState(DumbAction.RandomRecordsAddress), (Integer)randomValue); } @@ -540,6 +545,7 @@ public void EvaluateTx() lastCommit: null), transactions: txs).Propose(); var actionEvaluator = new ActionEvaluator( + systemAccountsGetter: _systemAccountsGetter, policyBlockActionGetter: _ => null, stateStore: new TrieStateStore(new MemoryKeyValueStore()), actionTypeLoader: new SingleActionLoader(typeof(DumbAction))); @@ -581,7 +587,7 @@ public void EvaluateTx() Assert.Equal(1, eval.InputContext.BlockIndex); Assert.Equal( (Integer)eval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState(DumbAction.RandomRecordsAddress), (Integer)eval.InputContext.GetRandom().Next()); IActionEvaluation prevEval = i > 0 ? evaluations[i - 1] : null; @@ -590,16 +596,16 @@ prevEval is null ? initStates : addresses.Select( prevEval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState), addresses.Select( eval.InputContext.PreviousState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState)); Assert.Equal( expectedStates[i], addresses.Select(eval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetState) .Select(x => x is Text t ? t.Value : null)); Assert.Equal( @@ -607,16 +613,16 @@ prevEval is null ? initBalances : addresses.Select(a => prevEval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(a, currency).RawValue), addresses.Select( a => eval.InputContext.PreviousState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(a, currency).RawValue)); Assert.Equal( expectedBalances[i], addresses.Select(a => eval.OutputState - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(a, currency).RawValue)); } @@ -633,8 +639,8 @@ prevEval is null previousState: previousState).Last().OutputState; Assert.Equal( evaluations[3].OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetUpdatedStates(), - delta.GetAccount(ReservedAddresses.LegacyAccount).GetUpdatedStates()); + .GetAccount(ReservedAddresses.DefaultAccount).GetUpdatedStates(), + delta.GetAccount(ReservedAddresses.DefaultAccount).GetUpdatedStates()); Assert.DoesNotContain( (addresses[2], "R"), @@ -657,6 +663,7 @@ public void EvaluateTxResultThrowingException() var txs = new Transaction[] { tx }; var hash = new BlockHash(GetRandomBytes(BlockHash.Size)); var actionEvaluator = new ActionEvaluator( + systemAccountsGetter: _systemAccountsGetter, policyBlockActionGetter: _ => null, stateStore: new TrieStateStore(new MemoryKeyValueStore()), actionTypeLoader: new SingleActionLoader(typeof(ThrowException)) @@ -676,7 +683,7 @@ public void EvaluateTxResultThrowingException() tx: tx, previousState: previousState).Last().OutputState; - Assert.Empty(nextState.GetAccount(ReservedAddresses.LegacyAccount).GetUpdatedStates()); + Assert.Empty(nextState.GetAccount(ReservedAddresses.DefaultAccount).GetUpdatedStates()); } [Fact] @@ -695,6 +702,7 @@ public void EvaluateActions() fx.Append(blockA); ActionEvaluation[] evalsA = ActionEvaluator.EvaluateActions( blockHeader: blockA, + systemAccountsGetter: _systemAccountsGetter, tx: txA, previousState: fx.CreateWorld(blockA.PreviousHash), actions: txA.Actions @@ -705,7 +713,7 @@ public void EvaluateActions() Assert.Equal( new Integer(15), evalsA.Last().OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetState(txA.Signer)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(txA.Signer)); for (int i = 0; i < evalsA.Length; i++) { @@ -724,16 +732,17 @@ public void EvaluateActions() Assert.False(context.BlockAction); Assert.Equal( i > 0 ? new[] { txA.Signer } : new Address[0], - prevState.GetAccount(ReservedAddresses.LegacyAccount).Delta.UpdatedAddresses); + prevState.GetAccount(ReservedAddresses.DefaultAccount).Delta.UpdatedAddresses); Assert.Equal( (Integer)deltaA[i].Value, - prevState.GetAccount(ReservedAddresses.LegacyAccount).GetState(txA.Signer)); + prevState.GetAccount(ReservedAddresses.DefaultAccount).GetState(txA.Signer)); Assert.Equal( new[] { txA.Signer }, - outputState.GetAccount(ReservedAddresses.LegacyAccount).Delta.UpdatedAddresses); + outputState.GetAccount(ReservedAddresses.DefaultAccount) + .Delta.UpdatedAddresses); Assert.Equal( (Integer)deltaA[i + 1].Value, - outputState.GetAccount(ReservedAddresses.LegacyAccount).GetState(txA.Signer)); + outputState.GetAccount(ReservedAddresses.DefaultAccount).GetState(txA.Signer)); Assert.Null(eval.Exception); } @@ -749,6 +758,7 @@ public void EvaluateActions() fx.Append(blockB); ActionEvaluation[] evalsB = ActionEvaluator.EvaluateActions( blockHeader: blockB, + systemAccountsGetter: _systemAccountsGetter, tx: txB, previousState: fx.CreateWorld(blockB.PreviousHash), actions: txB.Actions @@ -759,7 +769,7 @@ public void EvaluateActions() Assert.Equal( new Integer(6), evalsB.Last().OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetState(txB.Signer)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(txB.Signer)); for (int i = 0; i < evalsB.Length; i++) { @@ -779,16 +789,17 @@ public void EvaluateActions() Assert.False(context.BlockAction); Assert.Equal( i > 0 ? new[] { txB.Signer } : new Address[0], - prevState.GetAccount(ReservedAddresses.LegacyAccount).Delta.UpdatedAddresses); + prevState.GetAccount(ReservedAddresses.DefaultAccount).Delta.UpdatedAddresses); Assert.Equal( (Integer)deltaB[i].Value, - prevState.GetAccount(ReservedAddresses.LegacyAccount).GetState(txB.Signer)); + prevState.GetAccount(ReservedAddresses.DefaultAccount).GetState(txB.Signer)); Assert.Equal( new[] { txB.Signer }, - outputState.GetAccount(ReservedAddresses.LegacyAccount).Delta.UpdatedAddresses); + outputState.GetAccount(ReservedAddresses.DefaultAccount) + .Delta.UpdatedAddresses); Assert.Equal( (Integer)deltaB[i + 1].Value, - outputState.GetAccount(ReservedAddresses.LegacyAccount).GetState(txB.Signer)); + outputState.GetAccount(ReservedAddresses.DefaultAccount).GetState(txB.Signer)); if (i == 1) { Assert.IsType(eval.Exception); @@ -822,7 +833,7 @@ public void EvaluatePolicyBlockAction() Assert.Equal( (Integer)1, (Integer)evaluation.OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetState(genesis.Miner)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(genesis.Miner)); Assert.True(evaluation.InputContext.BlockAction); previousState = evaluation.OutputState; @@ -832,7 +843,7 @@ public void EvaluatePolicyBlockAction() Assert.Equal( (Integer)2, (Integer)evaluation.OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetState(block.Miner)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(block.Miner)); Assert.True(evaluation.InputContext.BlockAction); chain.Append(block, CreateBlockCommit(block), render: true); @@ -846,7 +857,7 @@ public void EvaluatePolicyBlockAction() Assert.Equal( (Integer)2, (Integer)evaluation.OutputState - .GetAccount(ReservedAddresses.LegacyAccount).GetState(block.Miner)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(block.Miner)); } [Theory] @@ -980,18 +991,18 @@ public void TotalUpdatedFungibleAssets() Assert.Equal( 2, latest - .GetAccount(ReservedAddresses.LegacyAccount).TotalUpdatedFungibleAssets.Count); + .GetAccount(ReservedAddresses.DefaultAccount).TotalUpdatedFungibleAssets.Count); Assert.Contains( (addresses[0], currency), latest - .GetAccount(ReservedAddresses.LegacyAccount).TotalUpdatedFungibleAssets); + .GetAccount(ReservedAddresses.DefaultAccount).TotalUpdatedFungibleAssets); Assert.Contains( (addresses[1], currency), - latest.GetAccount(ReservedAddresses.LegacyAccount).TotalUpdatedFungibleAssets); + latest.GetAccount(ReservedAddresses.DefaultAccount).TotalUpdatedFungibleAssets); Assert.DoesNotContain( addresses[2], latest - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .TotalUpdatedFungibleAssets.Select(pair => pair.Item1)); } @@ -1023,7 +1034,7 @@ public void EvaluateActionAndCollectFee() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), actions: new[] { freeGasAction, }, store: store, stateStore: stateStore); @@ -1051,12 +1062,12 @@ public void EvaluateActionAndCollectFee() Assert.Equal( FungibleAssetValue.FromRawValue(foo, 9), chain.GetWorldState(evaluations.Single().OutputState) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(address, foo)); Assert.Equal( FungibleAssetValue.FromRawValue(foo, 1), chain.GetWorldState(evaluations.Single().OutputState) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(miner.ToAddress(), foo)); } @@ -1088,7 +1099,7 @@ public void EvaluateThrowingExceedGasLimit() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), actions: new[] { freeGasAction, @@ -1124,12 +1135,12 @@ public void EvaluateThrowingExceedGasLimit() Assert.Equal( FungibleAssetValue.FromRawValue(foo, 5), chain.GetWorldState(evaluations.Single().OutputState) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(address, foo)); Assert.Equal( FungibleAssetValue.FromRawValue(foo, 5), chain.GetWorldState(evaluations.Single().OutputState) - .GetAccount(ReservedAddresses.LegacyAccount) + .GetAccount(ReservedAddresses.DefaultAccount) .GetBalance(miner.ToAddress(), foo)); } @@ -1161,7 +1172,7 @@ public void EvaluateThrowingInsufficientBalanceForGasFee() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), actions: new[] { freeGasAction, @@ -1223,7 +1234,7 @@ public void EvaluateMinusGasFee() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = TestUtils.MakeBlockChain( - policy: new BlockPolicy(), + policy: new BlockPolicy(_systemAccountsGetter), actions: new[] { freeGasAction, @@ -1348,6 +1359,7 @@ private void CheckRandomSeedInAction() Block blockA = fx.Propose(); ActionEvaluation[] evalsA = ActionEvaluator.EvaluateActions( blockHeader: blockA, + systemAccountsGetter: _systemAccountsGetter, tx: txA, previousState: fx.CreateWorld(blockA.PreviousHash), actions: txA.Actions @@ -1399,8 +1411,8 @@ public void LoadPlainValue(IValue plainValue) public IWorld Execute(IActionContext context) => context.PreviousState .SetAccount( - ReservedAddresses.LegacyAccount, - context.PreviousState.GetAccount(ReservedAddresses.LegacyAccount) + ReservedAddresses.DefaultAccount, + context.PreviousState.GetAccount(ReservedAddresses.DefaultAccount) .SetState(SignerKey, (Text)context.Signer.ToHex()) .SetState(MinerKey, (Text)context.Miner.ToHex()) .SetState(BlockIndexKey, (Integer)context.BlockIndex)); @@ -1444,14 +1456,14 @@ public IWorld Execute(IActionContext context) context.UseGas(GasUsage); var state = context.PreviousState .SetAccount( - ReservedAddresses.LegacyAccount, - context.PreviousState.GetAccount(ReservedAddresses.LegacyAccount) + ReservedAddresses.DefaultAccount, + context.PreviousState.GetAccount(ReservedAddresses.DefaultAccount) .SetState(context.Signer, (Text)Memo)); if (!(Receiver is null) && !(MintValue is null)) { state = state.SetAccount( - ReservedAddresses.LegacyAccount, - state.GetAccount(ReservedAddresses.LegacyAccount) + ReservedAddresses.DefaultAccount, + state.GetAccount(ReservedAddresses.DefaultAccount) .MintAsset(context, Receiver.Value, MintValue.Value)); } @@ -1472,8 +1484,8 @@ public void LoadPlainValue(IValue plainValue) public IWorld Execute(IActionContext context) => context.PreviousState.SetAccount( - ReservedAddresses.LegacyAccount, - context.PreviousState.GetAccount(ReservedAddresses.LegacyAccount) + ReservedAddresses.DefaultAccount, + context.PreviousState.GetAccount(ReservedAddresses.DefaultAccount) .MintAsset( context, context.Signer, FungibleAssetValue.FromRawValue(Currency, 1))); } diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.Append.cs b/Libplanet.Tests/Blockchain/BlockChainTest.Append.cs index 640db5a7e5c..509363f258c 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.Append.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.Append.cs @@ -82,53 +82,53 @@ Func getTxExecution new IValue[] { null, null, null, null, (Integer)1 }, addresses.Select( _blockChain.GetWorldState(renders[0].Context.PreviousState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal( new IValue[] { (Text)"foo", null, null, null, (Integer)1 }, addresses.Select( _blockChain.GetWorldState(renders[0].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal("bar", actions[1].Item); Assert.Equal(2, renders[1].Context.BlockIndex); Assert.Equal( addresses.Select(_blockChain.GetWorldState(renders[0].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState), + .GetAccount(ReservedAddresses.DefaultAccount).GetState), addresses.Select(_blockChain.GetWorldState(renders[1].Context.PreviousState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal( new IValue[] { (Text)"foo", (Text)"bar", null, null, (Integer)1 }, addresses.Select( _blockChain.GetWorldState(renders[1].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal("baz", actions[2].Item); Assert.Equal(2, renders[2].Context.BlockIndex); Assert.Equal( addresses.Select( _blockChain.GetWorldState(renders[1].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState), + .GetAccount(ReservedAddresses.DefaultAccount).GetState), addresses.Select( _blockChain.GetWorldState(renders[2].Context.PreviousState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal( new IValue[] { (Text)"foo", (Text)"bar", (Text)"baz", null, (Integer)1 }, addresses.Select( _blockChain.GetWorldState(renders[2].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal("qux", actions[3].Item); Assert.Equal(2, renders[3].Context.BlockIndex); Assert.Equal( addresses.Select( _blockChain.GetWorldState(renders[2].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState), + .GetAccount(ReservedAddresses.DefaultAccount).GetState), addresses.Select( _blockChain.GetWorldState(renders[3].Context.PreviousState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState) + .GetAccount(ReservedAddresses.DefaultAccount).GetState) ); Assert.Equal( new IValue[] @@ -136,7 +136,7 @@ Func getTxExecution (Text)"foo", (Text)"bar", (Text)"baz", (Text)"qux", (Integer)1, }, _blockChain.GetWorldState(renders[3].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetStates(addresses) + .GetAccount(ReservedAddresses.DefaultAccount).GetStates(addresses) ); Address minerAddress = addresses[4]; @@ -145,7 +145,7 @@ Func getTxExecution .ToArray(); Assert.Equal((Integer)2, (Integer)_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(minerAddress)); + ReservedAddresses.DefaultAccount).GetState(minerAddress)); Assert.Equal(2, blockRenders.Length); Assert.True(blockRenders.All(r => r.Render)); Assert.Equal(1, blockRenders[0].Context.BlockIndex); @@ -154,17 +154,17 @@ Func getTxExecution Assert.Equal( (Integer)1, (Integer)_blockChain.GetWorldState(blockRenders[0].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState(minerAddress) + .GetAccount(ReservedAddresses.DefaultAccount).GetState(minerAddress) ); Assert.Equal( (Integer)1, (Integer)_blockChain.GetWorldState(blockRenders[1].Context.PreviousState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState(minerAddress) + .GetAccount(ReservedAddresses.DefaultAccount).GetState(minerAddress) ); Assert.Equal( (Integer)2, (Integer)_blockChain.GetWorldState(blockRenders[1].NextState) - .GetAccount(ReservedAddresses.LegacyAccount).GetState(minerAddress) + .GetAccount(ReservedAddresses.DefaultAccount).GetState(minerAddress) ); foreach (Transaction tx in txs) @@ -178,10 +178,10 @@ Func getTxExecution Assert.Equal(tx.Id, e.TxId); var inputAccount = _blockChain.GetWorldState(Assert.IsType>(e.InputState)) - .GetAccount(ReservedAddresses.LegacyAccount); + .GetAccount(ReservedAddresses.DefaultAccount); var outputAccount = _blockChain.GetWorldState(Assert.IsType>(e.OutputState)) - .GetAccount(ReservedAddresses.LegacyAccount); + .GetAccount(ReservedAddresses.DefaultAccount); var accountDiff = AccountDiff.Create(inputAccount, outputAccount); Assert.Empty(accountDiff.FungibleAssetValueDiffs); } @@ -224,10 +224,10 @@ Func getTxExecution Assert.False(txExecution1.Fail); var inputAccount1 = _blockChain.GetWorldState( Assert.IsType>(txExecution1.InputState)) - .GetAccount(ReservedAddresses.LegacyAccount); + .GetAccount(ReservedAddresses.DefaultAccount); var outputAccount1 = _blockChain.GetWorldState( Assert.IsType>(txExecution1.OutputState)) - .GetAccount(ReservedAddresses.LegacyAccount); + .GetAccount(ReservedAddresses.DefaultAccount); var accountDiff1 = AccountDiff.Create(inputAccount1, outputAccount1); Assert.Equal( @@ -268,7 +268,7 @@ Func getTxExecution Assert.False(txExecution3.Fail); var outputAccount3 = _blockChain.GetWorldState( Assert.IsType>(txExecution3.OutputState)) - .GetAccount(ReservedAddresses.LegacyAccount); + .GetAccount(ReservedAddresses.DefaultAccount); Assert.Equal( DumbAction.DumbCurrency * -35, outputAccount3.GetBalance(pk.ToAddress(), DumbAction.DumbCurrency)); @@ -281,7 +281,7 @@ Func getTxExecution public void AppendModern() { _blockChain = TestUtils.MakeBlockChain( - new NullBlockPolicy(), + new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount), new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore())); var genesis = _blockChain.Genesis; @@ -383,7 +383,7 @@ public void AppendFailDueToInvalidTxCount() [SkippableFact] public void AppendWhenActionEvaluationFailed() { - var policy = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); @@ -424,7 +424,9 @@ TxPolicyViolationException IsSignerValid( : new TxPolicyViolationException("invalid signer", tx.Id); } - var policy = new BlockPolicy(validateNextBlockTx: IsSignerValid); + var policy = new BlockPolicy( + _systemAccountsGetter, + validateNextBlockTx: IsSignerValid); using (var fx = new MemoryStoreFixture()) { var blockChain = BlockChain.Create( @@ -434,7 +436,8 @@ TxPolicyViolationException IsSignerValid( fx.StateStore, fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + systemAccountsGetter: policy.SystemAccountsGetter, + policyBlockActionGetter: _ => policy.BlockAction, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -554,6 +557,7 @@ public void DoesNotUnstageOnAppendForForkedChain() public void AppendValidatesBlock() { var policy = new NullBlockPolicy( + _ => ReservedAddresses.DefaultAccount, new BlockPolicyViolationException(string.Empty)); var blockChain = new BlockChain( policy, @@ -562,6 +566,7 @@ public void AppendValidatesBlock() _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs b/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs index 74b907f42d7..43b5109506d 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.ProposeBlock.cs @@ -30,7 +30,7 @@ public void ProposeBlock() AssertBencodexEqual( (Text)$"{GenesisProposer.ToAddress()}", _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default)); + ReservedAddresses.DefaultAccount).GetState(default)); var proposerA = new PrivateKey(); Block block = _blockChain.ProposeBlock(proposerA); @@ -42,7 +42,7 @@ public void ProposeBlock() AssertBencodexEqual( (Text)$"{GenesisProposer.ToAddress()},{proposerA.ToAddress()}", _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default) + ReservedAddresses.DefaultAccount).GetState(default) ); var proposerB = new PrivateKey(); @@ -60,7 +60,7 @@ public void ProposeBlock() AssertBencodexEqual( expected, _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default) + ReservedAddresses.DefaultAccount).GetState(default) ); Block block3 = _blockChain.ProposeBlock( @@ -75,7 +75,7 @@ public void ProposeBlock() AssertBencodexEqual( expected, _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default) + ReservedAddresses.DefaultAccount).GetState(default) ); // Tests if ProposeBlock() method automatically fits the number of transactions @@ -119,7 +119,7 @@ public void ProposeBlock() AssertBencodexEqual( expected, _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default) + ReservedAddresses.DefaultAccount).GetState(default) ); } @@ -128,9 +128,9 @@ public void CanProposeInvalidGenesisBlock() { using (var fx = new MemoryStoreFixture()) { - var policy = new BlockPolicy(); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _policy.SystemAccountsGetter, + _ => _policy.BlockAction, fx.StateStore, new SingleActionLoader(typeof(DumbAction))); var genesis = BlockChain.ProposeGenesisBlock( @@ -148,7 +148,7 @@ public void CanProposeInvalidGenesisBlock() }.ToPlainValues()), }.ToImmutableList()); Assert.Throws(() => BlockChain.Create( - policy, + _policy, new VolatileStagePolicy(), fx.Store, fx.StateStore, @@ -162,15 +162,15 @@ public void CanProposeInvalidBlock() { using (var fx = new MemoryStoreFixture()) { - var policy = new BlockPolicy(); var blockChain = BlockChain.Create( - policy, + _policy, new VolatileStagePolicy(), fx.Store, fx.StateStore, fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + _policy.SystemAccountsGetter, + _ => _policy.BlockAction, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); var txs = new[] @@ -277,15 +277,15 @@ public void ProposeBlockWithPendingTxs() StageTransactions(txs); Assert.Null(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrA)); + ReservedAddresses.DefaultAccount).GetState(addrA)); Assert.Null(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrB)); + ReservedAddresses.DefaultAccount).GetState(addrB)); Assert.Null(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrC)); + ReservedAddresses.DefaultAccount).GetState(addrC)); Assert.Null(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrD)); + ReservedAddresses.DefaultAccount).GetState(addrD)); Assert.Null(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrE)); + ReservedAddresses.DefaultAccount).GetState(addrE)); foreach (Transaction tx in txs) { @@ -307,21 +307,21 @@ public void ProposeBlockWithPendingTxs() Assert.Contains(txs[3].Id, txIds); Assert.Equal(new Integer(1), _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrA)); + ReservedAddresses.DefaultAccount).GetState(addrA)); Assert.Equal(new Text("1b"), _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrB)); + ReservedAddresses.DefaultAccount).GetState(addrB)); Assert.Equal(new Text("2a"), _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrC)); + ReservedAddresses.DefaultAccount).GetState(addrC)); Assert.IsType(_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrD)); + ReservedAddresses.DefaultAccount).GetState(addrD)); Assert.Equal( new HashSet { "2b", "5a" }, ((string)(Text)_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrD)).Split(new[] { ',' }) + ReservedAddresses.DefaultAccount).GetState(addrD)).Split(new[] { ',' }) .ToHashSet() ); Assert.Equal(new Text("5b"), _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addrE)); + ReservedAddresses.DefaultAccount).GetState(addrE)); foreach (Transaction tx in new[] { txs[0], txs[1], txs[4] }) { @@ -354,7 +354,9 @@ TxPolicyViolationException IsSignerValid( : new TxPolicyViolationException("invalid signer", tx.Id); } - var policy = new BlockPolicy(validateNextBlockTx: IsSignerValid); + var policy = new BlockPolicy( + _systemAccountsGetter, + validateNextBlockTx: IsSignerValid); using (var fx = new MemoryStoreFixture()) { var blockChain = BlockChain.Create( @@ -364,6 +366,7 @@ TxPolicyViolationException IsSignerValid( fx.StateStore, fx.GenesisBlock, new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -465,7 +468,9 @@ public void ProposeBlockWithBlockAction() var address2 = privateKey2.ToAddress(); var blockAction = new DumbAction(address1, "foo"); - var policy = new BlockPolicy(blockAction); + var policy = new BlockPolicy( + _systemAccountsGetter, + blockAction); var blockChain = new BlockChain( policy, @@ -474,6 +479,7 @@ public void ProposeBlockWithBlockAction() _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); @@ -483,9 +489,9 @@ public void ProposeBlockWithBlockAction() blockChain.Append(block, CreateBlockCommit(block)); var state1 = blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address1); + ReservedAddresses.DefaultAccount).GetState(address1); var state2 = blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address2); + ReservedAddresses.DefaultAccount).GetState(address2); Assert.Equal(0, blockChain.GetNextTxNonce(address1)); Assert.Equal(1, blockChain.GetNextTxNonce(address2)); @@ -497,9 +503,9 @@ public void ProposeBlockWithBlockAction() blockChain.Append(block, CreateBlockCommit(block)); state1 = blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address1); + ReservedAddresses.DefaultAccount).GetState(address1); state2 = blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address2); + ReservedAddresses.DefaultAccount).GetState(address2); Assert.Equal(1, blockChain.GetNextTxNonce(address1)); Assert.Equal(1, blockChain.GetNextTxNonce(address2)); diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs b/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs index 35159affd0a..8448ac23593 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.ValidateNextBlock.cs @@ -176,11 +176,13 @@ public void ValidateNextBlockInvalidStateRootHash() { IKeyValueStore stateKeyValueStore = new MemoryKeyValueStore(); var policy = new BlockPolicy( + _systemAccountsGetter, blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000) ); var stateStore = new TrieStateStore(stateKeyValueStore); IStore store = new MemoryStore(); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); @@ -213,6 +215,7 @@ public void ValidateNextBlockInvalidStateRootHash() TestUtils.GenesisProposer); var policyWithBlockAction = new BlockPolicy( + _systemAccountsGetter, new SetStatesAtBlock(default, (Text)"foo", default, 1), policy.BlockInterval ); @@ -223,6 +226,7 @@ public void ValidateNextBlockInvalidStateRootHash() stateStore, genesisBlock, new ActionEvaluator( + policy.SystemAccountsGetter, _ => policyWithBlockAction.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction)))); @@ -488,7 +492,7 @@ public void ValidateBlockCommitFailsInsufficientPower() var validatorSet = new ValidatorSet( new[] { validator1, validator2, validator3, validator4 }.ToList()); BlockChain blockChain = TestUtils.MakeBlockChain( - new NullBlockPolicy(), + _nullBlockPolicy, new MemoryStore(), new TrieStateStore(new MemoryKeyValueStore()), validatorSet: validatorSet); diff --git a/Libplanet.Tests/Blockchain/BlockChainTest.cs b/Libplanet.Tests/Blockchain/BlockChainTest.cs index 81c166f21a2..20a45ce3d76 100644 --- a/Libplanet.Tests/Blockchain/BlockChainTest.cs +++ b/Libplanet.Tests/Blockchain/BlockChainTest.cs @@ -36,7 +36,9 @@ public partial class BlockChainTest : IDisposable { private readonly ILogger _logger; private StoreFixture _fx; + private ISystemAccountsGetter _systemAccountsGetter; private BlockPolicy _policy; + private NullBlockPolicy _nullBlockPolicy; private BlockChain _blockChain; private ValidatingActionRenderer _renderer; private Block _validNext; @@ -51,9 +53,12 @@ public BlockChainTest(ITestOutputHelper output) .CreateLogger() .ForContext(); + _systemAccountsGetter = new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount); _policy = new BlockPolicy( + systemAccountsGetter: _systemAccountsGetter, blockAction: new MinerReward(1), getMaxTransactionsBytes: _ => 50 * 1024); + _nullBlockPolicy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); _stagePolicy = new VolatileStagePolicy(); _fx = GetStoreFixture(_policy.BlockAction); _renderer = new ValidatingActionRenderer(); @@ -64,6 +69,7 @@ public BlockChainTest(ITestOutputHelper output) _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore: _fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction))), @@ -127,15 +133,15 @@ public void CanonicalId() chain2.Append(block3, CreateBlockCommit(block3)); Assert.Equal(chain1.Id, _fx.Store.GetCanonicalChainId()); - var policy = new BlockPolicy(new MinerReward(1)); var z = new BlockChain( - policy, + _policy, new VolatileStagePolicy(), _fx.Store, _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + _policy.SystemAccountsGetter, + _ => _policy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); @@ -176,11 +182,11 @@ public void ProcessActions() { var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); - var policy = new BlockPolicy(); var actionLoader = TypedActionLoader.Create( typeof(BaseAction).Assembly, typeof(BaseAction)); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _policy.SystemAccountsGetter, + _ => _policy.BlockAction, stateStore, actionLoader); var nonce = 0; @@ -200,7 +206,7 @@ public void ProcessActions() .ToImmutableList(); var genesis = BlockChain.ProposeGenesisBlock(actionEvaluator, transactions: txs); var chain = BlockChain.Create( - policy, + _policy, new VolatileStagePolicy(), store, stateStore, @@ -240,7 +246,7 @@ public void ProcessActions() Block block1 = chain.ProposeBlock(new PrivateKey()); chain.Append(block1, CreateBlockCommit(block1)); IValue state = chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1); Assert.NotNull(state); var result = BattleResult.FromBencodex((Bencodex.Types.Dictionary)state); @@ -271,7 +277,7 @@ public void ProcessActions() chain.Append(block2, CreateBlockCommit(block2)); state = chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1); result = BattleResult.FromBencodex((Bencodex.Types.Dictionary)state); Assert.Contains("bow", result.UsedWeapons); @@ -294,7 +300,7 @@ public void ProcessActions() chain.StageTransaction(tx3); chain.Append(block3, CreateBlockCommit(block3)); state = chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1); Assert.NotNull(state); } @@ -302,7 +308,6 @@ public void ProcessActions() [SkippableFact] public void ActionRenderersHaveDistinctContexts() { - var policy = new NullBlockPolicy(); var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var generatedRandomValueLogs = new List(); @@ -319,7 +324,7 @@ public void ActionRenderersHaveDistinctContexts() ) ).ToArray(); BlockChain blockChain = MakeBlockChain( - policy, + _nullBlockPolicy, store, stateStore, renderers: renderers @@ -340,13 +345,12 @@ public void ActionRenderersHaveDistinctContexts() [SkippableFact] public void RenderActionsAfterBlockIsRendered() { - var policy = new NullBlockPolicy(); var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var recordingRenderer = new RecordingActionRenderer(); var renderer = new LoggedActionRenderer(recordingRenderer, Log.Logger); BlockChain blockChain = MakeBlockChain( - policy, store, stateStore, renderers: new[] { renderer }); + _nullBlockPolicy, store, stateStore, renderers: new[] { renderer }); var privateKey = new PrivateKey(); var action = new DumbAction(default, string.Empty); @@ -375,7 +379,6 @@ public void RenderActionsAfterBlockIsRendered() [SkippableFact] public void RenderActionsAfterAppendComplete() { - var policy = new NullBlockPolicy(); var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); @@ -393,7 +396,7 @@ public void RenderActionsAfterAppendComplete() }; renderer = new LoggedActionRenderer(renderer, Log.Logger); BlockChain blockChain = MakeBlockChain( - policy, store, stateStore, renderers: new[] { renderer }); + _nullBlockPolicy, store, stateStore, renderers: new[] { renderer }); var privateKey = new PrivateKey(); var action = new DumbAction(default, string.Empty); @@ -572,18 +575,18 @@ public void StateAfterForkingAndAddingExistingBlock() miner, lastCommit: CreateBlockCommit(_blockChain.Tip)); _blockChain.Append(b2, CreateBlockCommit(b2)); var state = _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address); + ReservedAddresses.DefaultAccount).GetState(address); Assert.Equal((Text)"foo,bar", state); var forked = _blockChain.Fork(b1.Hash); state = forked.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address); + ReservedAddresses.DefaultAccount).GetState(address); Assert.Equal((Text)"foo", state); forked.Append(b2, CreateBlockCommit(b2)); state = forked.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address); + ReservedAddresses.DefaultAccount).GetState(address); Assert.Equal((Text)"foo,bar", state); } @@ -597,6 +600,7 @@ public void ForkShouldSkipExecuteAndRenderGenesis() using (var stateStore = new TrieStateStore(new MemoryKeyValueStore())) { var actionEvaluator = new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); @@ -628,6 +632,7 @@ public void ForkShouldSkipExecuteAndRenderGenesis() stateStore, genesis, new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore: stateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction))), @@ -918,7 +923,7 @@ public void Swap(bool render) Assert.Equal( (Integer)(totalBlockCount - 1), (Integer)_blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(minerAddress) + ReservedAddresses.DefaultAccount).GetState(minerAddress) ); Assert.Single(blockActionRenders); // #1 -> #2' Assert.True(blockActionRenders.All(r => r.Render)); @@ -1019,6 +1024,7 @@ public void ReorgIsUnableToHeterogenousChain(bool render) using (var fx2 = new MemoryStoreFixture(_policy.BlockAction)) { var actionEvaluator = new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore: fx2.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction))); @@ -1076,6 +1082,7 @@ public void GetStatesOnCreatingBlockChain() IStore store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); @@ -1108,16 +1115,16 @@ public void GetStatesOnCreatingBlockChain() [SkippableFact] public void GetStateOnlyDrillsDownUntilRequestedAddressesAreFound() { - var policy = new NullBlockPolicy(); var tracker = new StoreTracker(_fx.Store); var chain = new BlockChain( - policy, + _nullBlockPolicy, new VolatileStagePolicy(), tracker, _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); @@ -1151,7 +1158,7 @@ public void GetStateOnlyDrillsDownUntilRequestedAddressesAreFound() Assert.All( chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(targetAddresses), + ReservedAddresses.DefaultAccount).GetStates(targetAddresses), Assert.NotNull); var callCount = tracker.Logs.Where( @@ -1163,16 +1170,16 @@ public void GetStateOnlyDrillsDownUntilRequestedAddressesAreFound() [SkippableFact] public void GetStateReturnsEarlyForNonexistentAccount() { - var policy = new NullBlockPolicy(); var tracker = new StoreTracker(_fx.Store); var chain = new BlockChain( - policy, + _nullBlockPolicy, new VolatileStagePolicy(), tracker, _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); @@ -1186,7 +1193,7 @@ public void GetStateReturnsEarlyForNonexistentAccount() tracker.ClearLogs(); Address nonexistent = new PrivateKey().ToAddress(); IValue result = chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(nonexistent); + ReservedAddresses.DefaultAccount).GetState(nonexistent); Assert.Null(result); var callCount = tracker.Logs.Where( trackLog => trackLog.Method == "GetBlockStates" @@ -1205,12 +1212,12 @@ public void GetStateReturnsValidStateAfterFork() var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var chain = MakeBlockChain( - new NullBlockPolicy(), + _nullBlockPolicy, store, stateStore, new[] { new DumbAction(_fx.Address1, "item0.0", idempotent: true) }); Assert.Equal("item0.0", (Text)chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1)); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1)); chain.MakeTransaction( privateKey, @@ -1222,20 +1229,20 @@ public void GetStateReturnsValidStateAfterFork() Assert.Equal( new IValue[] { (Text)"item0.0,item1.0" }, chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(new[] { _fx.Address1 }) + ReservedAddresses.DefaultAccount).GetStates(new[] { _fx.Address1 }) ); Assert.Equal("item0.0,item1.0", (Text)chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1)); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1)); var forked = chain.Fork(chain.Tip.Hash); Assert.Equal(2, forked.Count); Assert.Equal( new IValue[] { (Text)"item0.0,item1.0" }, forked.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(new[] { _fx.Address1 }) + ReservedAddresses.DefaultAccount).GetStates(new[] { _fx.Address1 }) ); Assert.Equal("item0.0,item1.0", (Text)forked.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(_fx.Address1)); + ReservedAddresses.DefaultAccount).GetState(_fx.Address1)); } [SkippableFact] @@ -1243,26 +1250,26 @@ public void GetStateReturnsLatestStatesWhenMultipleAddresses() { var privateKeys = Enumerable.Range(1, 10).Select(_ => new PrivateKey()).ToList(); var addresses = privateKeys.Select(AddressExtensions.ToAddress).ToList(); - var policy = new NullBlockPolicy(); var chain = new BlockChain( - policy, + _nullBlockPolicy, new VolatileStagePolicy(), _fx.Store, _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, _fx.StateStore, new SingleActionLoader(typeof(DumbAction)))); Assert.All( chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(addresses), + ReservedAddresses.DefaultAccount).GetStates(addresses), Assert.Null); foreach (var address in addresses) { Assert.Null(chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address)); + ReservedAddresses.DefaultAccount).GetState(address)); } var privateKeysAndAddresses10 = privateKeys.Zip(addresses, (k, a) => (k, a)); @@ -1278,12 +1285,12 @@ public void GetStateReturnsLatestStatesWhenMultipleAddresses() Assert.All( chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(addresses), + ReservedAddresses.DefaultAccount).GetStates(addresses), v => Assert.Equal((Text)"1", v)); foreach (var address in addresses) { Assert.Equal((Text)"1", chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address)); + ReservedAddresses.DefaultAccount).GetState(address)); } chain.MakeTransaction(privateKeys[0], new[] { new DumbAction(addresses[0], "2") }); @@ -1291,10 +1298,10 @@ public void GetStateReturnsLatestStatesWhenMultipleAddresses() privateKeys[0], lastCommit: CreateBlockCommit(chain.Tip)); chain.Append(block2, CreateBlockCommit(block2)); Assert.Equal((Text)"1,2", chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(addresses[0])); + ReservedAddresses.DefaultAccount).GetState(addresses[0])); Assert.All( chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(addresses.Skip(1).ToArray()), + ReservedAddresses.DefaultAccount).GetStates(addresses.Skip(1).ToArray()), v => Assert.Equal((Text)"1", v) ); } @@ -1333,6 +1340,7 @@ public void FindBranchPoint() emptyFx.StateStore, emptyFx.GenesisBlock, new ActionEvaluator( + _blockChain.Policy.SystemAccountsGetter, _ => _blockChain.Policy.BlockAction, stateStore: emptyFx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -1343,6 +1351,7 @@ public void FindBranchPoint() forkFx.StateStore, forkFx.GenesisBlock, new ActionEvaluator( + _blockChain.Policy.SystemAccountsGetter, _ => _blockChain.Policy.BlockAction, stateStore: forkFx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -1634,11 +1643,11 @@ public void BlockActionWithMultipleAddress() _blockChain.Append(block3, CreateBlockCommit(block3)); IValue miner1state = _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(miner1.ToAddress()); + ReservedAddresses.DefaultAccount).GetState(miner1.ToAddress()); IValue miner2state = _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(miner2.ToAddress()); + ReservedAddresses.DefaultAccount).GetState(miner2.ToAddress()); IValue rewardState = _blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(rewardRecordAddress); + ReservedAddresses.DefaultAccount).GetState(rewardRecordAddress); AssertBencodexEqual((Integer)2, miner1state); AssertBencodexEqual((Integer)1, miner2state); @@ -1692,10 +1701,11 @@ internal static (Address, Address[] Addresses, BlockChain Chain) List presentIndices = new List() { 4, 7 }; List presentBlocks = new List(); - IBlockPolicy blockPolicy = new NullBlockPolicy(); + IBlockPolicy blockPolicy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); store = new StoreTracker(store); Guid chainId = Guid.NewGuid(); var actionEvaluator = new ActionEvaluator( + blockPolicy.SystemAccountsGetter, _ => blockPolicy.BlockAction, stateStore: stateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction))); @@ -1870,7 +1880,6 @@ private void TipChanged() private void CreateWithGenesisBlock() { var storeFixture = new MemoryStoreFixture(); - var policy = new NullBlockPolicy(); var addresses = ImmutableList
.Empty .Add(storeFixture.Address1) @@ -1917,11 +1926,12 @@ private void CreateWithGenesisBlock() }; var txs = systemTxs.Concat(customTxs).ToImmutableList(); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, storeFixture.StateStore, new SingleActionLoader(typeof(DumbAction))); BlockChain blockChain = BlockChain.Create( - policy, + _nullBlockPolicy, new VolatileStagePolicy(), storeFixture.Store, storeFixture.StateStore, @@ -1941,7 +1951,7 @@ private void CreateWithGenesisBlock() tx.Actions.All(a => !Registry.IsSystemAction(a))).UpdatedAddresses); var states = addresses.Select(address => blockChain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(address)) + ReservedAddresses.DefaultAccount).GetState(address)) .ToArray(); for (int i = 0; i < states.Length; ++i) { @@ -1952,19 +1962,19 @@ private void CreateWithGenesisBlock() [SkippableFact] private void ConstructWithUnexpectedGenesisBlock() { - var policy = new NullBlockPolicy(); var stagePolicy = new VolatileStagePolicy(); IStore store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); var genesisBlockA = BlockChain.ProposeGenesisBlock(actionEvaluator); var genesisBlockB = BlockChain.ProposeGenesisBlock(actionEvaluator); var blockChain = BlockChain.Create( - policy, + _nullBlockPolicy, stagePolicy, store, stateStore, @@ -1974,7 +1984,7 @@ private void ConstructWithUnexpectedGenesisBlock() Assert.Throws(() => { var blockchain = new BlockChain( - policy, + _nullBlockPolicy, stagePolicy, store, stateStore, @@ -2024,9 +2034,9 @@ private void CheckIfTxPolicyExceptionHasInnerException() // ReSharper disable AccessToModifiedClosure // The following method calls should not throw any exceptions: x?.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetStates(new[] { default(Address) }); + ReservedAddresses.DefaultAccount).GetStates(new[] { default(Address) }); x?.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(default); + ReservedAddresses.DefaultAccount).GetState(default); // ReSharper restore AccessToModifiedClosure }); IStore store = new MemoryStore(); @@ -2037,6 +2047,7 @@ private void CheckIfTxPolicyExceptionHasInnerException() null, List.Empty); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); @@ -2069,7 +2080,6 @@ private void CheckIfTxPolicyExceptionHasInnerException() private void ValidateNextBlockCommitOnValidatorSetChange() { var storeFixture = new MemoryStoreFixture(); - var policy = new NullBlockPolicy(); var addresses = ImmutableList
.Empty .Add(storeFixture.Address1) @@ -2100,7 +2110,8 @@ private void ValidateNextBlockCommitOnValidatorSetChange() .ToImmutableList(); var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, + _nullBlockPolicy.SystemAccountsGetter, + _ => _nullBlockPolicy.BlockAction, storeFixture.StateStore, new SingleActionLoader(typeof(SetValidator))); Block genesis = BlockChain.ProposeGenesisBlock( @@ -2108,7 +2119,7 @@ private void ValidateNextBlockCommitOnValidatorSetChange() privateKey: privateKey, transactions: txs); BlockChain blockChain = BlockChain.Create( - policy, + _nullBlockPolicy, new VolatileStagePolicy(), storeFixture.Store, storeFixture.StateStore, @@ -2217,9 +2228,8 @@ private class NullPolicyForGetStatesOnCreatingBlockChain : NullBlockPolicy { protected readonly Action _hook; - public NullPolicyForGetStatesOnCreatingBlockChain( - Action hook - ) + public NullPolicyForGetStatesOnCreatingBlockChain(Action hook) + : base(_ => ReservedAddresses.DefaultAccount) { _hook = hook; } diff --git a/Libplanet.Tests/Blockchain/Policies/BlockPolicyTest.cs b/Libplanet.Tests/Blockchain/Policies/BlockPolicyTest.cs index 947c0bf12d5..40aae582eb2 100644 --- a/Libplanet.Tests/Blockchain/Policies/BlockPolicyTest.cs +++ b/Libplanet.Tests/Blockchain/Policies/BlockPolicyTest.cs @@ -2,6 +2,7 @@ using System.Linq; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -20,6 +21,9 @@ public class BlockPolicyTest : IDisposable private static readonly DateTimeOffset FixtureEpoch = new DateTimeOffset(2018, 1, 1, 0, 0, 0, TimeSpan.Zero); + private readonly ISystemAccountsGetter _systemAccountsGetter + = new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount); + private readonly ITestOutputHelper _output; private StoreFixture _fx; @@ -32,6 +36,7 @@ public BlockPolicyTest(ITestOutputHelper output) _fx = new MemoryStoreFixture(); _output = output; _policy = new BlockPolicy( + systemAccountsGetter: _systemAccountsGetter, blockAction: null, blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000)); _stagePolicy = new VolatileStagePolicy(); @@ -42,6 +47,7 @@ public BlockPolicyTest(ITestOutputHelper output) _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore: _fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); @@ -57,17 +63,19 @@ public void Constructors() { var tenSec = new TimeSpan(0, 0, 10); var a = new BlockPolicy( + _systemAccountsGetter, blockAction: null, blockInterval: tenSec); Assert.Equal(tenSec, a.BlockInterval); var b = new BlockPolicy( + _systemAccountsGetter, blockInterval: TimeSpan.FromMilliseconds(65000)); Assert.Equal( new TimeSpan(0, 1, 5), b.BlockInterval); - var c = new BlockPolicy(); + var c = new BlockPolicy(_systemAccountsGetter); Assert.Equal( new TimeSpan(0, 0, 5), c.BlockInterval); @@ -87,7 +95,8 @@ TxPolicyViolationException IsSignerValid( : new TxPolicyViolationException("invalid signer", tx.Id); } - var policy = new BlockPolicy(validateNextBlockTx: IsSignerValid); + var policy = new BlockPolicy( + _systemAccountsGetter, validateNextBlockTx: IsSignerValid); // Valid Transaction var validTx = _chain.MakeTransaction(validKey, new DumbAction[] { }); @@ -131,6 +140,7 @@ TxPolicyViolationException IsSignerValidWithInnerException( // Invalid Transaction without Inner-exception var policy = new BlockPolicy( + _systemAccountsGetter, validateNextBlockTx: IsSignerValid); var invalidTx = _chain.MakeTransaction(invalidKey, new DumbAction[] { }); @@ -140,6 +150,7 @@ TxPolicyViolationException IsSignerValidWithInnerException( // Invalid Transaction with Inner-exception. policy = new BlockPolicy( + _systemAccountsGetter, validateNextBlockTx: IsSignerValidWithInnerException); invalidTx = _chain.MakeTransaction(invalidKey, new DumbAction[] { }); @@ -156,6 +167,7 @@ public void GetMinTransactionsPerBlock() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var policy = new BlockPolicy( + systemAccountsGetter: _systemAccountsGetter, blockAction: new MinerReward(1), getMinTransactionsPerBlock: index => index == 0 ? 0 : policyLimit); var privateKey = new PrivateKey(); @@ -179,6 +191,7 @@ public void GetMaxTransactionsPerBlock() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var policy = new BlockPolicy( + systemAccountsGetter: _systemAccountsGetter, getMaxTransactionsPerBlock: _ => policyLimit); var privateKey = new PrivateKey(); var chain = TestUtils.MakeBlockChain(policy, store, stateStore); @@ -203,6 +216,7 @@ public void GetMaxTransactionsPerSignerPerBlock() var store = new MemoryStore(); var stateStore = new TrieStateStore(new MemoryKeyValueStore()); var policy = new BlockPolicy( + systemAccountsGetter: _systemAccountsGetter, getMaxTransactionsPerSignerPerBlock: _ => policyLimit); var privateKeys = Enumerable.Range(0, keyCount).Select(_ => new PrivateKey()).ToList(); var minerKey = privateKeys.First(); diff --git a/Libplanet.Tests/Blockchain/Policies/StagePolicyTest.cs b/Libplanet.Tests/Blockchain/Policies/StagePolicyTest.cs index 421547e65f5..922e127bd77 100644 --- a/Libplanet.Tests/Blockchain/Policies/StagePolicyTest.cs +++ b/Libplanet.Tests/Blockchain/Policies/StagePolicyTest.cs @@ -2,6 +2,7 @@ using System.Linq; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Blockchain.Policies; @@ -19,10 +20,12 @@ public abstract class StagePolicyTest protected readonly BlockChain _chain; protected readonly PrivateKey _key; protected readonly Transaction[] _txs; + protected readonly ISystemAccountsGetter _systemAccountsGetter + = new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount); protected StagePolicyTest() { - _policy = new BlockPolicy(); + _policy = new BlockPolicy(_systemAccountsGetter); _fx = new MemoryStoreFixture(); _chain = BlockChain.Create( _policy, @@ -31,6 +34,7 @@ protected StagePolicyTest() _fx.StateStore, _fx.GenesisBlock, new ActionEvaluator( + _policy.SystemAccountsGetter, _ => _policy.BlockAction, stateStore: _fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(DumbAction)))); diff --git a/Libplanet.Tests/Blockchain/Renderers/AnonymousActionRendererTest.cs b/Libplanet.Tests/Blockchain/Renderers/AnonymousActionRendererTest.cs index 12a7b9883c8..24c4fd075ce 100644 --- a/Libplanet.Tests/Blockchain/Renderers/AnonymousActionRendererTest.cs +++ b/Libplanet.Tests/Blockchain/Renderers/AnonymousActionRendererTest.cs @@ -16,6 +16,9 @@ public class AnonymousActionRendererTest { private static IValue _action = new DumbAction().PlainValue; + private static ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + private static IWorld _world = new World(new MockWorldState()); private static ICommittedActionContext _actionContext = @@ -23,8 +26,9 @@ public class AnonymousActionRendererTest default, default, default, - Block.CurrentProtocolVersion, + _systemAccounts, default, + Block.CurrentProtocolVersion, _world, default, 0)); diff --git a/Libplanet.Tests/Blockchain/Renderers/LoggedActionRendererTest.cs b/Libplanet.Tests/Blockchain/Renderers/LoggedActionRendererTest.cs index c2893af9b56..2d7cef50fc9 100644 --- a/Libplanet.Tests/Blockchain/Renderers/LoggedActionRendererTest.cs +++ b/Libplanet.Tests/Blockchain/Renderers/LoggedActionRendererTest.cs @@ -23,6 +23,9 @@ public class LoggedActionRendererTest : IDisposable { private static IValue _action = new DumbAction().PlainValue; + private static ISystemAccounts _systemAccounts = new SystemAccounts( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), null); + private static IWorld _world = new World(new MockWorldState()); private static Block _genesis = @@ -73,8 +76,9 @@ public void ActionRenderings(bool error, bool rehearsal, bool exception) default, default, default, - Block.CurrentProtocolVersion, + _systemAccounts, 123, + Block.CurrentProtocolVersion, _world, default, 0, diff --git a/Libplanet.Tests/Blocks/PreEvaluationBlockTest.cs b/Libplanet.Tests/Blocks/PreEvaluationBlockTest.cs index 55316b4dd6b..4796fc71d44 100644 --- a/Libplanet.Tests/Blocks/PreEvaluationBlockTest.cs +++ b/Libplanet.Tests/Blocks/PreEvaluationBlockTest.cs @@ -22,6 +22,9 @@ public class PreEvaluationBlockTest : PreEvaluationBlockHeaderTest { private readonly ITestOutputHelper _output; + private readonly ISystemAccountsGetter _systemAccountsGetter + = new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount); + public PreEvaluationBlockTest(ITestOutputHelper output) { _output = output; @@ -32,8 +35,9 @@ public void Evaluate() { Address address = _contents.Block1Tx0.Signer; var blockAction = new SetStatesAtBlock( - address, (Bencodex.Types.Integer)123, ReservedAddresses.LegacyAccount, 0); + address, (Bencodex.Types.Integer)123, ReservedAddresses.DefaultAccount, 0); var policy = new BlockPolicy( + _systemAccountsGetter, blockAction: blockAction, blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000)); var stagePolicy = new VolatileStagePolicy(); @@ -44,6 +48,7 @@ public void Evaluate() using (var fx = new MemoryStoreFixture()) { var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, fx.StateStore, new SingleActionLoader(typeof(Arithmetic))); @@ -62,7 +67,7 @@ public void Evaluate() genesis, actionEvaluator); AssertBencodexEqual((Bencodex.Types.Integer)123, blockChain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(address)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(address)); HashDigest identicalGenesisStateRootHash = blockChain.DetermineBlockStateRootHash(preEvalGenesis, out _); @@ -90,7 +95,7 @@ public void Evaluate() blockChain.Append(block1, TestUtils.CreateBlockCommit(block1)); AssertBencodexEqual((Bencodex.Types.Integer)158, blockChain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(address)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(address)); } } @@ -99,8 +104,9 @@ public void DetermineStateRootHash() { Address address = _contents.Block1Tx0.Signer; var blockAction = new SetStatesAtBlock( - address, (Bencodex.Types.Integer)123, ReservedAddresses.LegacyAccount, 0); + address, (Bencodex.Types.Integer)123, ReservedAddresses.DefaultAccount, 0); var policy = new BlockPolicy( + _systemAccountsGetter, blockAction: blockAction, blockInterval: TimeSpan.FromMilliseconds(3 * 60 * 60 * 1000)); var stagePolicy = new VolatileStagePolicy(); @@ -110,6 +116,7 @@ public void DetermineStateRootHash() using (var fx = new MemoryStoreFixture()) { var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, stateStore: fx.StateStore, actionTypeLoader: new SingleActionLoader(typeof(Arithmetic))); @@ -129,7 +136,7 @@ public void DetermineStateRootHash() genesis, actionEvaluator); AssertBencodexEqual((Bencodex.Types.Integer)123, blockChain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(address)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(address)); HashDigest identicalGenesisStateRootHash = blockChain.DetermineBlockStateRootHash(preEvalGenesis, out _); @@ -155,7 +162,7 @@ public void DetermineStateRootHash() blockChain.Append(block1, TestUtils.CreateBlockCommit(block1)); AssertBencodexEqual((Bencodex.Types.Integer)158, blockChain.GetWorldState() - .GetAccount(ReservedAddresses.LegacyAccount).GetState(address)); + .GetAccount(ReservedAddresses.DefaultAccount).GetState(address)); } } } diff --git a/Libplanet.Tests/Fixtures/Arithmetic.cs b/Libplanet.Tests/Fixtures/Arithmetic.cs index fda0c7cc0f9..e83813cebd7 100644 --- a/Libplanet.Tests/Fixtures/Arithmetic.cs +++ b/Libplanet.Tests/Fixtures/Arithmetic.cs @@ -114,7 +114,7 @@ public IWorld Execute(IActionContext context) throw new InvalidOperationException(Error); } - IValue v = context.PreviousState.GetAccount(ReservedAddresses.LegacyAccount) + IValue v = context.PreviousState.GetAccount(ReservedAddresses.DefaultAccount) .GetState(context.Signer) ?? (Bencodex.Types.Integer)0; if (!(v is Bencodex.Types.Integer value)) { @@ -126,9 +126,9 @@ public IWorld Execute(IActionContext context) Func func = Operator.ToFunc(); BigInteger result = func(value, Operand); return context.PreviousState.SetAccount( - ReservedAddresses.LegacyAccount, + ReservedAddresses.DefaultAccount, context.PreviousState.GetAccount( - ReservedAddresses.LegacyAccount).SetState( + ReservedAddresses.DefaultAccount).SetState( context.Signer, (Bencodex.Types.Integer)result)); } diff --git a/Libplanet.Tests/Fixtures/IntegerSet.cs b/Libplanet.Tests/Fixtures/IntegerSet.cs index 99966d63b4b..321cd267685 100644 --- a/Libplanet.Tests/Fixtures/IntegerSet.cs +++ b/Libplanet.Tests/Fixtures/IntegerSet.cs @@ -70,11 +70,12 @@ public IntegerSet( .OrderBy(tx => tx.Id) .ToImmutableArray(); Miner = new PrivateKey(); - policy = policy ?? new NullBlockPolicy(); + policy = policy ?? new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); Store = new MemoryStore(); KVStore = new MemoryKeyValueStore(); StateStore = new TrieStateStore(KVStore); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, StateStore, new SingleActionLoader(typeof(Arithmetic))); @@ -113,9 +114,10 @@ public TxWithContext Sign(PrivateKey signer, params Arithmetic[] actions) Transaction tx = Transaction.Create(nonce, signer, Genesis.Hash, actions.ToPlainValues()); BigInteger prevState = Chain.GetWorldState().GetAccount( - ReservedAddresses.LegacyAccount).GetState(signerAddress) is Bencodex.Types.Integer i - ? i.Value - : 0; + ReservedAddresses.DefaultAccount) + .GetState(signerAddress) is Bencodex.Types.Integer i + ? i.Value + : 0; HashDigest prevStateRootHash = Chain.Tip.StateRootHash; ITrie prevTrie = GetTrie(Chain.Tip.Hash); (BigInteger, HashDigest) prevPair = (prevState, prevStateRootHash); diff --git a/Libplanet.Tests/Store/StoreFixture.cs b/Libplanet.Tests/Store/StoreFixture.cs index 6661eb2b7ca..3ec87d11bf9 100644 --- a/Libplanet.Tests/Store/StoreFixture.cs +++ b/Libplanet.Tests/Store/StoreFixture.cs @@ -4,6 +4,7 @@ using System.Security.Cryptography; using Libplanet.Action; using Libplanet.Action.Loader; +using Libplanet.Action.State; using Libplanet.Action.Tests.Common; using Libplanet.Blockchain; using Libplanet.Common; @@ -104,6 +105,7 @@ protected StoreFixture(IAction blockAction = null) proposer: Proposer.PublicKey, validatorSet: TestUtils.ValidatorSet); var actionEvaluator = new ActionEvaluator( + new SystemAccountsGetter(_ => ReservedAddresses.DefaultAccount), _ => blockAction, stateStore, new SingleActionLoader(typeof(DumbAction))); diff --git a/Libplanet.Tests/Store/StoreTest.cs b/Libplanet.Tests/Store/StoreTest.cs index bbef746a61d..3c9ca70c6f4 100644 --- a/Libplanet.Tests/Store/StoreTest.cs +++ b/Libplanet.Tests/Store/StoreTest.cs @@ -1006,9 +1006,10 @@ public void Copy() using (StoreFixture fx2 = FxConstructor()) { IStore s1 = fx.Store, s2 = fx2.Store; - var policy = new NullBlockPolicy(); + var policy = new NullBlockPolicy(_ => ReservedAddresses.DefaultAccount); var preEval = ProposeGenesis(proposer: GenesisProposer.PublicKey); var actionEvaluator = new ActionEvaluator( + policy.SystemAccountsGetter, _ => policy.BlockAction, fx.StateStore, new SingleActionLoader(typeof(DumbAction))); diff --git a/Libplanet.Tests/TestUtils.cs b/Libplanet.Tests/TestUtils.cs index 303f2e34921..b10b83881a3 100644 --- a/Libplanet.Tests/TestUtils.cs +++ b/Libplanet.Tests/TestUtils.cs @@ -607,9 +607,10 @@ public static (BlockChain BlockChain, ActionEvaluator ActionEvaluator) }; var actionEvaluator = new ActionEvaluator( - _ => policy.BlockAction, - stateStore: stateStore, - actionTypeLoader: new SingleActionLoader(typeof(T))); + policy.SystemAccountsGetter, + _ => policy.BlockAction, + stateStore: stateStore, + actionTypeLoader: new SingleActionLoader(typeof(T))); if (genesisBlock is null) { diff --git a/Libplanet/Blockchain/BlockChain.States.cs b/Libplanet/Blockchain/BlockChain.States.cs index 0820505a7ee..efb4a559a7f 100644 --- a/Libplanet/Blockchain/BlockChain.States.cs +++ b/Libplanet/Blockchain/BlockChain.States.cs @@ -161,30 +161,30 @@ public ValidatorSet GetValidatorSet(Address accountAddress) /// /// Returns the validator set in the /// at and - /// . + /// . /// /// The of the to fetch /// the states from. /// The validator set of type at - /// and . + /// and . /// /// Thrown when at - /// and + /// and /// cannot be created. /// public ValidatorSet GetValidatorSet(BlockHash? offset) - => GetValidatorSet(ReservedAddresses.LegacyAccount, offset); + => GetValidatorSet(ReservedAddresses.DefaultAccount, offset); /// /// Returns the current validator set in the . /// /// The validator set of type at - /// and . + /// and . /// /// Thrown when of - /// cannot be created. + /// cannot be created. /// public ValidatorSet GetValidatorSet() - => GetValidatorSet(ReservedAddresses.LegacyAccount); + => GetValidatorSet(ReservedAddresses.DefaultAccount); } } diff --git a/Libplanet/Blockchain/Policies/BlockPolicy.cs b/Libplanet/Blockchain/Policies/BlockPolicy.cs index e3895050a63..867090ee311 100644 --- a/Libplanet/Blockchain/Policies/BlockPolicy.cs +++ b/Libplanet/Blockchain/Policies/BlockPolicy.cs @@ -34,6 +34,8 @@ public class BlockPolicy : IBlockPolicy /// description for more detail. /// ///
+ /// A to + /// determine . /// A to executed for /// every . Set to by default, which results /// in no additional execution other than those included in s. @@ -66,6 +68,7 @@ public class BlockPolicy : IBlockPolicy /// Goes to . Set to /// by default. public BlockPolicy( + ISystemAccountsGetter systemAccountsGetter, IAction? blockAction = null, TimeSpan? blockInterval = null, Func? @@ -77,6 +80,7 @@ public BlockPolicy( Func? getMaxTransactionsPerBlock = null, Func? getMaxTransactionsPerSignerPerBlock = null) { + SystemAccountsGetter = systemAccountsGetter; BlockAction = blockAction; BlockInterval = blockInterval ?? DefaultTargetBlockInterval; _getMaxTransactionsBytes = getMaxTransactionsBytes ?? (_ => 100L * 1024L); @@ -151,6 +155,9 @@ public BlockPolicy( } } + /// + public ISystemAccountsGetter SystemAccountsGetter { get; } + /// public IAction? BlockAction { get; } diff --git a/Libplanet/Blockchain/Policies/IBlockPolicy.cs b/Libplanet/Blockchain/Policies/IBlockPolicy.cs index d95285985e6..9e4c4ac42a1 100644 --- a/Libplanet/Blockchain/Policies/IBlockPolicy.cs +++ b/Libplanet/Blockchain/Policies/IBlockPolicy.cs @@ -20,6 +20,11 @@ namespace Libplanet.Blockchain.Policies /// public interface IBlockPolicy { + /// + /// The to determine . + /// + ISystemAccountsGetter SystemAccountsGetter { get; } + /// /// An to execute and be rendered for every block, if any. /// diff --git a/Libplanet/Blockchain/Policies/NullBlockPolicy.cs b/Libplanet/Blockchain/Policies/NullBlockPolicy.cs index a1145ed46db..73766db7385 100644 --- a/Libplanet/Blockchain/Policies/NullBlockPolicy.cs +++ b/Libplanet/Blockchain/Policies/NullBlockPolicy.cs @@ -10,18 +10,19 @@ namespace Libplanet.Blockchain.Policies public class NullBlockPolicy : IBlockPolicy { private readonly BlockPolicyViolationException _exceptionToThrow; - private readonly long _difficulty; public NullBlockPolicy( - BlockPolicyViolationException exceptionToThrow = null, - long difficulty = 1) + AccountAddressGetter feeAccountGetter, + BlockPolicyViolationException exceptionToThrow = null) { + SystemAccountsGetter = new SystemAccountsGetter(feeAccountGetter); _exceptionToThrow = exceptionToThrow; - _difficulty = difficulty; } public ISet
BlockedMiners { get; } = new HashSet
(); + public ISystemAccountsGetter SystemAccountsGetter { get; } + public IAction BlockAction => null; public int GetMinTransactionsPerBlock(long index) => 0;