public RpcInformationQuery(ActionEvaluationPublisher publisher)
 {
     Field <NonNullGraphType <IntGraphType> >(
         name: "totalCount",
         description: "total count by connected to this node.",
         resolve: context => publisher.GetClients().Count);
     Field <NonNullGraphType <ListGraphType <AddressType> > >(
         name: "clients",
         description: "List of address connected to this node.",
         resolve: context => publisher.GetClients());
 }
Ejemplo n.º 2
0
        public StandaloneQuery(StandaloneContext standaloneContext, IConfiguration configuration, ActionEvaluationPublisher publisher)
        {
            bool useSecretToken = configuration[GraphQLService.SecretTokenKey] is { };

            Field <NonNullGraphType <StateQuery> >(name: "stateQuery", arguments: new QueryArguments(
                                                       new QueryArgument <ByteStringType>
            {
                Name        = "hash",
                Description = "Offset block hash for query.",
            }),
                                                   resolve: context =>
            {
                BlockHash?blockHash = context.GetArgument <byte[]>("hash") switch
                {
                    byte[] bytes => new BlockHash(bytes),
                    null => null,
                };

                if (standaloneContext.BlockChain is { } blockChain)
                {
                    DelayedRenderer <NCAction>?delayedRenderer = blockChain.GetDelayedRenderer();
                    blockHash = delayedRenderer?.Tip?.Hash;
                }

                return(standaloneContext.BlockChain?.ToAccountStateGetter(blockHash),
                       standaloneContext.BlockChain?.ToAccountBalanceGetter(blockHash));
            }
                                                   );

            Field <ByteStringType>(
                name: "state",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <AddressType> > {
                Name = "address", Description = "The address of state to fetch from the chain."
            },
                    new QueryArgument <ByteStringType> {
                Name = "hash", Description = "The hash of the block used to fetch state from chain."
            }
                    ),
                resolve: context =>
            {
                if (!(standaloneContext.BlockChain is BlockChain <PolymorphicAction <ActionBase> > blockChain))
                {
                    throw new ExecutionError(
                        $"{nameof(StandaloneContext)}.{nameof(StandaloneContext.BlockChain)} was not set yet!");
                }

                var address            = context.GetArgument <Address>("address");
                var blockHashByteArray = context.GetArgument <byte[]>("hash");
                var blockHash          = blockHashByteArray is null
                        ? blockChain.Tip.Hash
                        : new BlockHash(blockHashByteArray);

                var state = blockChain.GetState(address, blockHash);

                return(new Codec().Encode(state));
            }
                );

            Field <NonNullGraphType <ListGraphType <NonNullGraphType <TransferNCGHistoryType> > > >(
                "transferNCGHistories",
                arguments: new QueryArguments(
                    new QueryArgument <NonNullGraphType <ByteStringType> >
            {
                Name = "blockHash"
            },
                    new QueryArgument <AddressType>
            {
                Name = "recipient"
            }
                    ), resolve: context =>
            {
                BlockHash blockHash = new BlockHash(context.GetArgument <byte[]>("blockHash"));

                if (!(standaloneContext.Store is { } store))
                {
                    throw new InvalidOperationException();
                }

                if (!(store.GetBlockDigest(blockHash) is { } digest))
                {
                    throw new ArgumentException("blockHash");
                }

                var recipient = context.GetArgument <Address?>("recipient");

                IEnumerable <Transaction <NCAction> > txs = digest.TxIds
                                                            .Select(b => new TxId(b.ToBuilder().ToArray()))
                                                            .Select(store.GetTransaction <NCAction>);
                var filteredTransactions = txs.Where(tx =>
                                                     tx.Actions.Count == 1 &&
                                                     tx.Actions.First().InnerAction is TransferAsset transferAsset &&
                                                     (!recipient.HasValue || transferAsset.Recipient == recipient) &&
                                                     transferAsset.Amount.Currency.Ticker == "NCG" &&
                                                     store.GetTxExecution(blockHash, tx.Id) is TxSuccess);

                TransferNCGHistory ToTransferNCGHistory(TxSuccess txSuccess, string memo)
                {
                    var rawTransferNcgHistories = txSuccess.FungibleAssetsDelta.Select(pair =>
                                                                                       (pair.Key, pair.Value.Values.First(fav => fav.Currency.Ticker == "NCG")))
                                                  .ToArray();
                    var((senderAddress, _), (recipientAddress, amount)) =
                        rawTransferNcgHistories[0].Item2.RawValue > rawTransferNcgHistories[1].Item2.RawValue
                                ? (rawTransferNcgHistories[1], rawTransferNcgHistories[0])
                                : (rawTransferNcgHistories[0], rawTransferNcgHistories[1]);
                    return(new TransferNCGHistory(
                               txSuccess.BlockHash,
                               txSuccess.TxId,
                               senderAddress,
                               recipientAddress,
                               amount,
                               memo));
                }

                var histories = filteredTransactions.Select(tx =>
                                                            ToTransferNCGHistory((TxSuccess)store.GetTxExecution(blockHash, tx.Id),
                                                                                 tx.Actions.Single().InnerAction.As <TransferAsset>().Memo));

                return(histories);
            });
        public GraphQLTestBase(ITestOutputHelper output)
        {
            Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.Console().CreateLogger();

            _output = output;

            var goldCurrency = new Currency("NCG", 2, minter: null);

            var fixturePath  = Path.Combine("..", "..", "..", "..", "Lib9c", ".Lib9c.Tests", "Data", "TableCSV");
            var sheets       = TableSheetsImporter.ImportSheets(fixturePath);
            var blockAction  = new RewardGold();
            var genesisBlock = BlockChain <NCAction> .MakeGenesisBlock(
                HashAlgorithmType.Of <SHA256>(),
                new NCAction[]
            {
                new InitializeStates(
                    rankingState: new RankingState(),
                    shopState: new ShopState(),
                    gameConfigState: new GameConfigState(sheets[nameof(GameConfigSheet)]),
                    redeemCodeState: new RedeemCodeState(Bencodex.Types.Dictionary.Empty
                                                         .Add("address", RedeemCodeState.Address.Serialize())
                                                         .Add("map", Bencodex.Types.Dictionary.Empty)
                                                         ),
                    adminAddressState: new AdminState(AdminAddress, 10000),
                    activatedAccountsState: new ActivatedAccountsState(),
                    goldCurrencyState: new GoldCurrencyState(goldCurrency),
                    goldDistributions: new GoldDistribution[] { },
                    tableSheets: sheets,
                    pendingActivationStates: new PendingActivationState[] { }
                    ),
            }, blockAction : blockAction);

            var ncService        = ServiceBuilder.CreateNineChroniclesNodeService(genesisBlock, new PrivateKey());
            var tempKeyStorePath = Path.Join(Path.GetTempPath(), Path.GetRandomFileName());
            var keyStore         = new Web3KeyStore(tempKeyStorePath);

            StandaloneContextFx = new StandaloneContext
            {
                KeyStore = keyStore,
            };
            ncService.ConfigureContext(StandaloneContextFx);

            var configurationBuilder = new ConfigurationBuilder();
            var configuration        = configurationBuilder.Build();

            var services  = new ServiceCollection();
            var publisher = new ActionEvaluationPublisher(
                ncService.BlockRenderer,
                ncService.ActionRenderer,
                ncService.ExceptionRenderer,
                ncService.NodeStatusRenderer,
                "",
                0,
                new RpcContext()
                );

            services.AddSingleton(publisher);
            services.AddSingleton(StandaloneContextFx);
            services.AddSingleton <IConfiguration>(configuration);
            services.AddGraphTypes();
            services.AddLibplanetExplorer <NCAction>();
            services.AddSingleton <StateQuery>();
            services.AddSingleton(ncService);
            ServiceProvider serviceProvider = services.BuildServiceProvider();

            Schema = new StandaloneSchema(serviceProvider);

            DocumentExecutor = new DocumentExecuter();
        }