From d29f47dc3d42626b5014ea4c9d203d3324f8b9b5 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 10:43:03 +0900 Subject: [PATCH 1/8] Remove `activationStatus` mutation --- .../GraphTypes/ActivationStatusMutation.cs | 75 ------------------- .../GraphTypes/StandaloneMutation.cs | 5 -- 2 files changed, 80 deletions(-) delete mode 100644 NineChronicles.Headless/GraphTypes/ActivationStatusMutation.cs diff --git a/NineChronicles.Headless/GraphTypes/ActivationStatusMutation.cs b/NineChronicles.Headless/GraphTypes/ActivationStatusMutation.cs deleted file mode 100644 index 4575105f5..000000000 --- a/NineChronicles.Headless/GraphTypes/ActivationStatusMutation.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using Bencodex.Types; -using GraphQL; -using GraphQL.Types; -using Libplanet.Action; -using Nekoyume.Action; -using Nekoyume.Model; -using Nekoyume.Model.State; -using Nekoyume.Module; - -namespace NineChronicles.Headless.GraphTypes -{ - public class ActivationStatusMutation : ObjectGraphType - { - public ActivationStatusMutation(NineChroniclesNodeService service) - { - DeprecationReason = "Since NCIP-15, it doesn't care account activation."; - - Field>("activateAccount", - deprecationReason: "Since NCIP-15, it doesn't care account activation.", - arguments: new QueryArguments( - new QueryArgument> - { - Name = "encodedActivationKey", - }), - resolve: context => - { - try - { - string encodedActivationKey = - context.GetArgument("encodedActivationKey"); - // FIXME: Private key may not exists at this moment. - if (!(service.MinerPrivateKey is { } privateKey)) - { - throw new InvalidOperationException($"{nameof(privateKey)} is null."); - } - - ActivationKey activationKey = ActivationKey.Decode(encodedActivationKey); - if (!(service.Swarm?.BlockChain is { } blockChain)) - { - throw new InvalidOperationException($"{nameof(blockChain)} is null."); - } - - IValue state = blockChain.GetWorldState().GetLegacyState(activationKey.PendingAddress); - - if (!(state is Bencodex.Types.Dictionary asDict)) - { - context.Errors.Add(new ExecutionError("The given key was already expired.")); - return false; - } - - var pendingActivationState = new PendingActivationState(asDict); - ActivateAccount action = activationKey.CreateActivateAccount( - pendingActivationState.Nonce); - - var actions = new IAction[] { action }; - blockChain.MakeTransaction(privateKey, actions); - } - catch (ArgumentException ae) - { - context.Errors.Add(new ExecutionError("The given key isn't in the correct format.", ae)); - return false; - } - catch (Exception e) - { - var msg = "Unexpected exception occurred during ActivatedAccountsMutation: {e}"; - context.Errors.Add(new ExecutionError(msg, e)); - return false; - } - - return true; - }); - } - } -} diff --git a/NineChronicles.Headless/GraphTypes/StandaloneMutation.cs b/NineChronicles.Headless/GraphTypes/StandaloneMutation.cs index 6285a00e1..826e9bb42 100644 --- a/NineChronicles.Headless/GraphTypes/StandaloneMutation.cs +++ b/NineChronicles.Headless/GraphTypes/StandaloneMutation.cs @@ -42,11 +42,6 @@ IConfiguration configuration deprecationReason: "Use `planet key` command instead. https://www.npmjs.com/package/@planetarium/cli", resolve: context => standaloneContext.KeyStore); - Field( - name: "activationStatus", - resolve: _ => new ActivationStatusMutation(nodeService), - deprecationReason: "Since NCIP-15, it doesn't care account activation."); - Field( name: "action", resolve: _ => new ActionMutation(nodeService)); From 8640b538f2293e222c21eff3ad4ccca3b9c8b944 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 10:43:58 +0900 Subject: [PATCH 2/8] Remove `actionQuery.activateAccount` field --- .../GraphTypes/ActionQuery.cs | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/NineChronicles.Headless/GraphTypes/ActionQuery.cs b/NineChronicles.Headless/GraphTypes/ActionQuery.cs index 4c2c6fc0d..4462dcbf2 100644 --- a/NineChronicles.Headless/GraphTypes/ActionQuery.cs +++ b/NineChronicles.Headless/GraphTypes/ActionQuery.cs @@ -424,35 +424,6 @@ public ActionQuery(StandaloneContext standaloneContext) return Encode(context, action); } ); - Field>( - "activateAccount", - deprecationReason: "Since NCIP-15, it doesn't care account activation.", - arguments: new QueryArguments( - new QueryArgument> - { - Name = "activationCode", - Description = "Activation code that you've get." - } - ), - resolve: context => - { - var activationCode = context.GetArgument("activationCode"); - var activationKey = ActivationKey.Decode(activationCode); - if (standaloneContext.BlockChain!.GetWorldState().GetLegacyState(activationKey.PendingAddress) is Dictionary dictionary) - { - var pending = new PendingActivationState(dictionary); - var action = activationKey.CreateActivateAccount(pending.Nonce); - if (pending.Verify(action)) - { - return Encode(context, action); - } - - throw new ExecutionError("Failed to verify activateAccount action."); - } - - throw new InvalidOperationException("BlockChain not found in the context"); - } - ); Field>( "createAvatar", arguments: new QueryArguments( From ab034a2cdf40ec75f15720491856c84671a982c2 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 11:16:58 +0900 Subject: [PATCH 3/8] Remove `ActivateAccount` support of `tx sign` command --- .../Commands/TxCommandTest.cs | 14 -------------- .../Commands/TxCommand.cs | 1 - 2 files changed, 15 deletions(-) diff --git a/NineChronicles.Headless.Executable.Tests/Commands/TxCommandTest.cs b/NineChronicles.Headless.Executable.Tests/Commands/TxCommandTest.cs index dc09855de..ab3a1f487 100644 --- a/NineChronicles.Headless.Executable.Tests/Commands/TxCommandTest.cs +++ b/NineChronicles.Headless.Executable.Tests/Commands/TxCommandTest.cs @@ -31,20 +31,6 @@ public TxCommandTest() _blockHash = BlockHash.FromHashDigest(default); } - [Theory] - [InlineData(1)] - [InlineData(2)] - public void Sign_ActivateAccount(int txNonce) - { - var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; - (ActivationKey activationKey, PendingActivationState _) = - ActivationKey.Create(_privateKey, nonce); - var filePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); - var actionCommand = new ActionCommand(_console); - actionCommand.ActivateAccount(activationKey.Encode(), ByteUtil.Hex(nonce), filePath); - Assert_Tx(txNonce, filePath, false); - } - [Theory] [InlineData(1, false)] [InlineData(10, true)] diff --git a/NineChronicles.Headless.Executable/Commands/TxCommand.cs b/NineChronicles.Headless.Executable/Commands/TxCommand.cs index 6c6ddaf94..a4dfb1bc2 100644 --- a/NineChronicles.Headless.Executable/Commands/TxCommand.cs +++ b/NineChronicles.Headless.Executable/Commands/TxCommand.cs @@ -65,7 +65,6 @@ public void Sign( ActionBase action = type switch { - nameof(ActivateAccount) => new ActivateAccount(), nameof(Stake) => new Stake(), nameof(ClaimStakeReward) => new ClaimStakeReward(), nameof(TransferAsset) => new TransferAsset(), From e3953c5ce744f61ce33d8c4bf626dc466920b5c4 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 11:17:43 +0900 Subject: [PATCH 4/8] Remove `action activate-account` command --- .../Commands/ActionCommandTest.cs | 32 -------------- .../Commands/ActionCommand.cs | 43 ------------------- 2 files changed, 75 deletions(-) diff --git a/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs b/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs index 29eade8fb..130b74caa 100644 --- a/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs +++ b/NineChronicles.Headless.Executable.Tests/Commands/ActionCommandTest.cs @@ -26,38 +26,6 @@ public ActionCommandTest() _command = new ActionCommand(_console); } - [Theory] - [InlineData(true, -1)] - [InlineData(false, 0)] - public void ActivateAccount(bool invalid, int expectedCode) - { - var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; - var privateKey = new PrivateKey(); - (ActivationKey activationKey, PendingActivationState _) = ActivationKey.Create(privateKey, nonce); - string invitationCode = invalid ? "invalid_code" : activationKey.Encode(); - var filePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); - var resultCode = _command.ActivateAccount(invitationCode, ByteUtil.Hex(nonce), filePath); - Assert.Equal(expectedCode, resultCode); - - if (resultCode == 0) - { - var rawAction = Convert.FromBase64String(File.ReadAllText(filePath)); - var decoded = (List)_codec.Decode(rawAction); - string type = (Text)decoded[0]; - Assert.Equal(nameof(Nekoyume.Action.ActivateAccount), type); - - Dictionary plainValue = (Dictionary)decoded[1]; - var action = new ActivateAccount(); - action.LoadPlainValue(plainValue); - Assert.Equal(activationKey.PrivateKey.Sign(nonce), action.Signature); - Assert.Equal(activationKey.PendingAddress, action.PendingAddress); - } - else - { - Assert.Contains("hexWithSlash seems invalid. [invalid_code]", _console.Error.ToString()); - } - } - [Theory] [InlineData(10, 0, "transfer asset test1.")] [InlineData(100, 0, "transfer asset test2.")] diff --git a/NineChronicles.Headless.Executable/Commands/ActionCommand.cs b/NineChronicles.Headless.Executable/Commands/ActionCommand.cs index 1ddabd47c..ca0752db6 100644 --- a/NineChronicles.Headless.Executable/Commands/ActionCommand.cs +++ b/NineChronicles.Headless.Executable/Commands/ActionCommand.cs @@ -33,49 +33,6 @@ public void Help([FromService] ICoconaHelpMessageBuilder helpMessageBuilder) _console.Error.WriteLine(helpMessageBuilder.BuildAndRenderForCurrentContext()); } - [Command(Description = "Create ActivateAccount action.")] - public int ActivateAccount( - [Argument("INVITATION-CODE", Description = "An invitation code.")] - string invitationCode, - [Argument("NONCE", Description = "A hex-encoded nonce for activation.")] - string nonceEncoded, - [Argument("PATH", Description = "A file path of base64 encoded action.")] - string? filePath = null - ) - { - try - { - ActivationKey activationKey = ActivationKey.Decode(invitationCode); - byte[] nonce = ByteUtil.ParseHex(nonceEncoded); - Nekoyume.Action.ActivateAccount action = activationKey.CreateActivateAccount(nonce); - var list = new List( - new[] - { - (Text) nameof(Nekoyume.Action.ActivateAccount), - action.PlainValue - } - ); - - byte[] raw = Codec.Encode(list); - string encoded = Convert.ToBase64String(raw); - if (filePath is null) - { - _console.Out.Write(encoded); - } - else - { - File.WriteAllText(filePath, encoded); - } - - return 0; - } - catch (Exception e) - { - _console.Error.WriteLine(e); - return -1; - } - } - [Command(Description = "Lists all actions' type ids.")] public IOrderedEnumerable List( [Option( From aa57f5085fdb9f6b816fbb0fdcaf6fbbc89ac508 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 10:41:54 +0900 Subject: [PATCH 5/8] Bump lib9c submodule --- Lib9c | 2 +- .../GraphTypes/ActionQueryTest.cs | 19 --- .../GraphTypes/StandaloneMutationTest.cs | 39 ------ .../GraphTypes/StandaloneQueryTest.cs | 127 +----------------- .../GraphTypes/ActivationStatusQuery.cs | 56 -------- .../GraphTypes/StandaloneQuery.cs | 4 +- 6 files changed, 4 insertions(+), 243 deletions(-) diff --git a/Lib9c b/Lib9c index 31cbd41a9..a34287b88 160000 --- a/Lib9c +++ b/Lib9c @@ -1 +1 @@ -Subproject commit 31cbd41a99ed7b17a33fd1ea2597600dfd9b9906 +Subproject commit a34287b886cc6791598decfd2d3888888df60018 diff --git a/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs b/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs index 8b4b1a2e5..7953d2bdb 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/ActionQueryTest.cs @@ -582,25 +582,6 @@ public async Task TransferAssets(bool exc) } } - [Fact] - public async Task ActivateAccount() - { - var activationCode = _activationKey.Encode(); - var signature = _activationKey.PrivateKey.Sign(_nonce); - - var query = $"{{ activateAccount(activationCode: \"{activationCode}\") }}"; - var queryResult = await ExecuteQueryAsync(query, standaloneContext: _standaloneContext); - - Assert.Null(queryResult.Errors); - var data = (Dictionary)((ExecutionNode)queryResult.Data!).ToValue()!; - var plainValue = _codec.Decode(ByteUtil.ParseHex((string)data["activateAccount"])); - Assert.IsType(plainValue); - var actionBase = DeserializeNCAction(plainValue); - var action = Assert.IsType(actionBase); - - Assert.Equal(signature, action.Signature); - } - [Theory] [InlineData(-1, "ab", null, null, null, null, false)] [InlineData(0, "ab", null, null, null, null, true)] diff --git a/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs b/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs index 556a0deaa..2d8854eda 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs @@ -846,45 +846,6 @@ public async Task Tx_V2() Assert.Null(result.Errors); } - [Fact] - public async Task Tx_ActivateAccount() - { - var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; - var privateKey = new PrivateKey(); - (ActivationKey activationKey, PendingActivationState pendingActivation) = - ActivationKey.Create(privateKey, nonce); - ActionBase action = new CreatePendingActivation(pendingActivation); - BlockChain.MakeTransaction(AdminPrivateKey, new[] { action }); - Block block = BlockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - BlockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - AppendEmptyBlock(GenesisValidators); - var encodedActivationKey = activationKey.Encode(); - var actionCommand = new ActionCommand(new StandardConsole()); - var filePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); - actionCommand.ActivateAccount(encodedActivationKey, ByteUtil.Hex(nonce), filePath); - var console = new StringIOConsole(); - var txCommand = new TxCommand(console); - var timeStamp = DateTimeOffset.UtcNow; - txCommand.Sign(ByteUtil.Hex(privateKey.ByteArray), BlockChain.GetNextTxNonce(privateKey.Address), ByteUtil.Hex(BlockChain.Genesis.Hash.ByteArray), timeStamp.ToString(), new[] { filePath }); - var output = console.Out.ToString(); - output = output.Trim(); - var queryResult = await ExecuteQueryAsync( - $"mutation {{ stageTx(payload: \"{output}\") }}"); - var data = (Dictionary)((ExecutionNode)queryResult.Data!).ToValue()!; - block = BlockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - BlockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - - var result = (bool)data["stageTx"]; - Assert.True(result); - - IValue? state = BlockChain.GetNextWorldState().GetLegacyState(privateKey.Address.Derive(ActivationKey.DeriveKey)); - Assert.True((Bencodex.Types.Boolean)state); - } - [Fact] public async Task StageTransaction() { diff --git a/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs b/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs index 43385b869..5f4bd8ef4 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs @@ -453,130 +453,6 @@ public async Task ConvertPrivateKey(bool compress) Assert.Equal(privateKey.Address.ToString(), publicKeyResult["address"]); } - [Theory] - [InlineData(true)] - [InlineData(false)] - public async Task ActivationStatus(bool existsActivatedAccounts) - { - var adminPrivateKey = new PrivateKey(); - var adminAddress = adminPrivateKey.Address; - var activatedAccounts = ImmutableHashSet
.Empty; - - if (existsActivatedAccounts) - { - activatedAccounts = new[] { adminAddress }.ToImmutableHashSet(); - } - - ValidatorSet validatorSetCandidate = new ValidatorSet(new[] - { - new Libplanet.Types.Consensus.Validator(ProposerPrivateKey.PublicKey, BigInteger.One), - }.ToList()); - Block genesis = - BlockChain.ProposeGenesisBlock( - transactions: ImmutableList.Empty - .Add(Transaction.Create(0, ProposerPrivateKey, null, - new ActionBase[] - { - new InitializeStates( - rankingState: new RankingState0(), - shopState: new ShopState(), - gameConfigState: new GameConfigState(), - redeemCodeState: new RedeemCodeState(Bencodex.Types.Dictionary.Empty - .Add("address", RedeemCodeState.Address.Serialize()) - .Add("map", Bencodex.Types.Dictionary.Empty) - ), - adminAddressState: new AdminState(adminAddress, 1500000), - activatedAccountsState: new ActivatedAccountsState(activatedAccounts), -#pragma warning disable CS0618 - // Use of obsolete method Currency.Legacy(): - // https://github.com/planetarium/lib9c/discussions/1319 - goldCurrencyState: new GoldCurrencyState(Currency.Legacy("NCG", 2, null)), -#pragma warning restore CS0618 - goldDistributions: new GoldDistribution[0], - tableSheets: _sheets, - pendingActivationStates: new PendingActivationState[] { } - ), - }.ToPlainValues())) - .AddRange(new IAction[] - { - new Initialize( - validatorSet: validatorSetCandidate, - states: ImmutableDictionary.Empty), - }.Select((sa, nonce) => - Transaction.Create(nonce + 1, ProposerPrivateKey, null, - new[] { sa.PlainValue })) - ), - privateKey: ProposerPrivateKey - ); - - var apvPrivateKey = new PrivateKey(); - var apv = AppProtocolVersion.Sign(apvPrivateKey, 0); - var userPrivateKey = new PrivateKey(); - var consensusPrivateKey = new PrivateKey(); - var properties = new LibplanetNodeServiceProperties - { - Host = System.Net.IPAddress.Loopback.ToString(), - AppProtocolVersion = apv, - GenesisBlock = genesis, - StorePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), - StoreStatesCacheSize = 2, - SwarmPrivateKey = new PrivateKey(), - ConsensusPrivateKey = consensusPrivateKey, - ConsensusPort = null, - Port = null, - NoMiner = true, - Render = false, - Peers = ImmutableHashSet.Empty, - TrustedAppProtocolVersionSigners = null, - IceServers = ImmutableList.Empty, - ConsensusSeeds = ImmutableList.Empty, - ConsensusPeers = ImmutableList.Empty - }; - var blockPolicy = new BlockPolicySource().GetPolicy(); - - var service = new NineChroniclesNodeService( - userPrivateKey, properties, blockPolicy, Planet.Odin, StaticActionLoaderSingleton.Instance); - StandaloneContextFx.NineChroniclesNodeService = service; - StandaloneContextFx.BlockChain = service.Swarm?.BlockChain; - - var blockChain = StandaloneContextFx.BlockChain!; - AppendEmptyBlock(GenesisValidators); - - var queryResult = await ExecuteQueryAsync("query { activationStatus { activated } }"); - var data = (Dictionary)((ExecutionNode)queryResult.Data!).ToValue()!; - var result = (bool) - ((Dictionary)data["activationStatus"])["activated"]; - - // If we don't use activated accounts, bypass check (always true). - Assert.Equal(!existsActivatedAccounts, result); - - var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; - var privateKey = new PrivateKey(); - (ActivationKey activationKey, PendingActivationState pendingActivation) = - ActivationKey.Create(privateKey, nonce); - ActionBase action = new CreatePendingActivation(pendingActivation); - blockChain.MakeTransaction(adminPrivateKey, new[] { action }); - Block block = blockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - - action = activationKey.CreateActivateAccount(nonce); - blockChain.MakeTransaction(userPrivateKey, new[] { action }); - block = blockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - AppendEmptyBlock(GenesisValidators); - - queryResult = await ExecuteQueryAsync("query { activationStatus { activated } }"); - data = (Dictionary)((ExecutionNode)queryResult.Data!).ToValue()!; - result = (bool) - ((Dictionary)data["activationStatus"])["activated"]; - - Assert.True(result); - } - [Fact] public async Task GoldBalance() { @@ -628,8 +504,7 @@ Transaction MakeTx(long nonce, ActionBase action) var currency = Currency.Uncapped("NCG", 2, null); var txs = new[] { - MakeTx(0, new TransferAsset0(sender, recipient, new FungibleAssetValue(currency, 1, 0), memo)), - MakeTx(1, new TransferAsset(sender, recipient, new FungibleAssetValue(currency, 1, 0), memo)), + MakeTx(0, new TransferAsset(sender, recipient, new FungibleAssetValue(currency, 1, 0), memo)), }; var block = new Domain.Model.BlockChain.Block( blockHash, diff --git a/NineChronicles.Headless/GraphTypes/ActivationStatusQuery.cs b/NineChronicles.Headless/GraphTypes/ActivationStatusQuery.cs index 542fcdc69..fc810c6da 100644 --- a/NineChronicles.Headless/GraphTypes/ActivationStatusQuery.cs +++ b/NineChronicles.Headless/GraphTypes/ActivationStatusQuery.cs @@ -18,62 +18,6 @@ public ActivationStatusQuery(StandaloneContext standaloneContext) { DeprecationReason = "Since NCIP-15, it doesn't care account activation."; - Field>( - name: "activated", - deprecationReason: "Since NCIP-15, it doesn't care account activation.", - resolve: context => - { - var service = standaloneContext.NineChroniclesNodeService; - - if (service is null) - { - return false; - } - - try - { - if (!(service.MinerPrivateKey is { } privateKey)) - { - throw new InvalidOperationException($"{nameof(service.MinerPrivateKey)} is null."); - } - - if (!(service.Swarm?.BlockChain is { } blockChain)) - { - throw new InvalidOperationException($"{nameof(service.Swarm.BlockChain)} is null."); - } - - Address userAddress = privateKey.Address; - Address activatedAddress = userAddress.Derive(ActivationKey.DeriveKey); - - if (blockChain.GetWorldState().GetLegacyState(activatedAddress) is Bencodex.Types.Boolean) - { - return true; - } - - // Preserve previous check code due to migration period. - // TODO: Remove this code after v100061+ - IValue state = blockChain.GetWorldState().GetLegacyState(ActivatedAccountsState.Address); - - if (state is Bencodex.Types.Dictionary asDict) - { - var activatedAccountsState = new ActivatedAccountsState(asDict); - var activatedAccounts = activatedAccountsState.Accounts; - return activatedAccounts.Count == 0 - || activatedAccounts.Contains(userAddress); - } - - return true; - } - catch (Exception e) - { - var msg = "Unexpected exception occurred during ActivationStatusQuery: {e}"; - context.Errors.Add(new ExecutionError(msg, e)); - Log.Error(msg, e); - return false; - } - } - ); - Field>( name: "addressActivated", deprecationReason: "Since NCIP-15, it doesn't care account activation.", diff --git a/NineChronicles.Headless/GraphTypes/StandaloneQuery.cs b/NineChronicles.Headless/GraphTypes/StandaloneQuery.cs index cc9e97804..3cfeb63ff 100644 --- a/NineChronicles.Headless/GraphTypes/StandaloneQuery.cs +++ b/NineChronicles.Headless/GraphTypes/StandaloneQuery.cs @@ -485,8 +485,8 @@ public StandaloneQuery(StandaloneContext standaloneContext, IKeyStore keyStore, if (worldState.GetLegacyState(activationKey.PendingAddress) is Dictionary dictionary) { var pending = new PendingActivationState(dictionary); - ActivateAccount action = activationKey.CreateActivateAccount(pending.Nonce); - if (pending.Verify(action)) + var signature = activationKey.PrivateKey.Sign(pending.Nonce); + if (pending.Verify(signature)) { return false; } From 204fbcf84bf99c371c4dfaf1599e664d56449748 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 16:56:52 +0900 Subject: [PATCH 6/8] Make tests as comment --- .../TransactionHeadlessQueryTest.cs | 118 +++++++++--------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/NineChronicles.Headless.Tests/GraphTypes/TransactionHeadlessQueryTest.cs b/NineChronicles.Headless.Tests/GraphTypes/TransactionHeadlessQueryTest.cs index 8dcb7bd86..a1a9a1002 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/TransactionHeadlessQueryTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/TransactionHeadlessQueryTest.cs @@ -316,65 +316,65 @@ public async Task TransactionResultIsInvalid() Assert.Equal("INVALID", txStatus); } - [Fact] - public async Task TransactionResultIsSuccess() - { - var privateKey = new PrivateKey(); - // Because `AddActivatedAccount` doesn't need any prerequisites. - var action = new AddActivatedAccount(default); - Transaction tx = _blockChain.MakeTransaction(privateKey, new ActionBase[] { action }); - Block block = _blockChain.ProposeBlock(_proposer); - _blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, _proposer)); - var queryFormat = @"query {{ - transactionResult(txId: ""{0}"") {{ - blockHash - txStatus - }} - }}"; - var result = await ExecuteAsync(string.Format( - queryFormat, - tx.Id.ToString())); - Assert.NotNull(result.Data); - var transactionResult = - ((Dictionary)((ExecutionNode)result.Data!).ToValue()!)["transactionResult"]; - var txStatus = (string)((Dictionary)transactionResult)["txStatus"]; - Assert.Equal("SUCCESS", txStatus); - } - - [Fact] - public async Task TransactionResults() - { - var privateKey = new PrivateKey(); - // Because `AddActivatedAccount` doesn't need any prerequisites. - var action = new AddActivatedAccount(default); - Transaction tx = _blockChain.MakeTransaction(privateKey, new ActionBase[] { action }); - var action2 = new DailyReward - { - avatarAddress = default - }; - Transaction tx2 = _blockChain.MakeTransaction(new PrivateKey(), new ActionBase[] { action2 }); - Block block = _blockChain.ProposeBlock(_proposer); - _blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, _proposer)); - var queryFormat = @"query {{ - transactionResults(txIds: [""{0}"", ""{1}""]) {{ - blockHash - txStatus - }} - }}"; - var result = await ExecuteAsync(string.Format( - queryFormat, - tx.Id.ToString(), - tx2.Id.ToString() - )); - Assert.NotNull(result.Data); - var transactionResults = - (object[])((Dictionary)((ExecutionNode)result.Data!).ToValue()!)["transactionResults"]; - Assert.Equal(2, transactionResults.Length); - var txStatus = (string)((Dictionary)transactionResults[0])["txStatus"]; - Assert.Equal("SUCCESS", txStatus); - txStatus = (string)((Dictionary)transactionResults[1])["txStatus"]; - Assert.Equal("FAILURE", txStatus); - } + // [Fact] + // public async Task TransactionResultIsSuccess() + // { + // var privateKey = new PrivateKey(); + // // Because `AddActivatedAccount` doesn't need any prerequisites. + // var action = new AddActivatedAccount(default); + // Transaction tx = _blockChain.MakeTransaction(privateKey, new ActionBase[] { action }); + // Block block = _blockChain.ProposeBlock(_proposer); + // _blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, _proposer)); + // var queryFormat = @"query {{ + // transactionResult(txId: ""{0}"") {{ + // blockHash + // txStatus + // }} + // }}"; + // var result = await ExecuteAsync(string.Format( + // queryFormat, + // tx.Id.ToString())); + // Assert.NotNull(result.Data); + // var transactionResult = + // ((Dictionary)((ExecutionNode)result.Data!).ToValue()!)["transactionResult"]; + // var txStatus = (string)((Dictionary)transactionResult)["txStatus"]; + // Assert.Equal("SUCCESS", txStatus); + // } + // + // [Fact] + // public async Task TransactionResults() + // { + // var privateKey = new PrivateKey(); + // // Because `AddActivatedAccount` doesn't need any prerequisites. + // var action = new AddActivatedAccount(default); + // Transaction tx = _blockChain.MakeTransaction(privateKey, new ActionBase[] { action }); + // var action2 = new DailyReward + // { + // avatarAddress = default + // }; + // Transaction tx2 = _blockChain.MakeTransaction(new PrivateKey(), new ActionBase[] { action2 }); + // Block block = _blockChain.ProposeBlock(_proposer); + // _blockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, _proposer)); + // var queryFormat = @"query {{ + // transactionResults(txIds: [""{0}"", ""{1}""]) {{ + // blockHash + // txStatus + // }} + // }}"; + // var result = await ExecuteAsync(string.Format( + // queryFormat, + // tx.Id.ToString(), + // tx2.Id.ToString() + // )); + // Assert.NotNull(result.Data); + // var transactionResults = + // (object[])((Dictionary)((ExecutionNode)result.Data!).ToValue()!)["transactionResults"]; + // Assert.Equal(2, transactionResults.Length); + // var txStatus = (string)((Dictionary)transactionResults[0])["txStatus"]; + // Assert.Equal("SUCCESS", txStatus); + // txStatus = (string)((Dictionary)transactionResults[1])["txStatus"]; + // Assert.Equal("FAILURE", txStatus); + // } [Fact] public async Task NcTransactionsOnTip() From bafa20bfa344210343ac70040fc0916b4d1fff44 Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 17:00:46 +0900 Subject: [PATCH 7/8] Remove staled tests --- .../GraphTypes/StandaloneMutationTest.cs | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs b/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs index 2d8854eda..075b60c14 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/StandaloneMutationTest.cs @@ -114,40 +114,6 @@ public async Task RevokePrivateKey() Assert.Equal(address.ToString(), revokedPrivateKeyAddress); } - [Fact] - public async Task ActivateAccount() - { - var nonce = new byte[] { 0x00, 0x01, 0x02, 0x03 }; - var privateKey = new PrivateKey(); - (ActivationKey activationKey, PendingActivationState pendingActivation) = - ActivationKey.Create(privateKey, nonce); - ActionBase action = new CreatePendingActivation(pendingActivation); - BlockChain.MakeTransaction(AdminPrivateKey, new[] { action }); - Block block = BlockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - BlockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - AppendEmptyBlock(GenesisValidators); - - var encodedActivationKey = activationKey.Encode(); - var queryResult = await ExecuteQueryAsync( - $"mutation {{ activationStatus {{ activateAccount(encodedActivationKey: \"{encodedActivationKey}\") }} }}"); - var data = (Dictionary)((ExecutionNode)queryResult.Data!).ToValue()!; - block = BlockChain.ProposeBlock( - ProposerPrivateKey, - lastCommit: GenerateBlockCommit(BlockChain.Tip.Index, BlockChain.Tip.Hash, GenesisValidators)); - BlockChain.Append(block, GenerateBlockCommit(block.Index, block.Hash, GenesisValidators)); - - var result = - (bool)((Dictionary) - data["activationStatus"])["activateAccount"]; - Assert.True(result); - - Address userAddress = StandaloneContextFx.NineChroniclesNodeService!.MinerPrivateKey!.Address; - IValue? state = BlockChain.GetNextWorldState().GetLegacyState(userAddress.Derive(ActivationKey.DeriveKey)); - Assert.True((Bencodex.Types.Boolean)state); - } - [Theory] [InlineData(null, false)] [InlineData("", false)] From bc75b9eda0e7c4f4cd960f3f19d52d372d04141c Mon Sep 17 00:00:00 2001 From: Moreal Date: Mon, 23 Sep 2024 17:06:46 +0900 Subject: [PATCH 8/8] Fix tests --- .../GraphTypes/StandaloneQueryTest.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs b/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs index 5f4bd8ef4..0e8a91c3f 100644 --- a/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs +++ b/NineChronicles.Headless.Tests/GraphTypes/StandaloneQueryTest.cs @@ -521,9 +521,6 @@ Transaction MakeTx(long nonce, ActionBase action) TransactionRepository.Setup(repo => repo.GetTxExecution(blockHash, txs[0].Id)) .Returns(new TxExecution( blockHash, txs[0].Id, false, MerkleTrie.EmptyRootHash, MerkleTrie.EmptyRootHash, new List())); - TransactionRepository.Setup(repo => repo.GetTxExecution(blockHash, txs[1].Id)) - .Returns(new TxExecution( - blockHash, txs[1].Id, false, MerkleTrie.EmptyRootHash, MerkleTrie.EmptyRootHash, new List())); var blockHashHex = ByteUtil.Hex(block.Hash.ToByteArray()); var result =