Giter VIP home page Giter VIP logo

cardano-graphql's People

Contributors

adascanbovich avatar alexey1935 avatar arturwieczorek avatar catch-21 avatar cherrydt avatar craigem avatar dependabot[bot] avatar dermetfan avatar disassembler avatar iadmytro avatar islishude avatar jbgi avatar johnalotoski avatar kammerlo avatar ktorz avatar lgobbi-atix avatar manveru avatar mebassett avatar mmahut avatar oneedoubled avatar rcmorano avatar rhyslbw avatar sam-jeston avatar sweeetland avatar tatyanavych avatar toaspzoo avatar trevorbenson avatar trueblueaddie avatar wout avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cardano-graphql's Issues

Check limit does not restrict results when logically selecting using an `_in` statement

This is a UX tweak that makes sense to handle as a specific case. Consider the following query:

{
  blocks(
  # limit is defaulting to 1 here since not specified
    where: {
      number: {
        _in: [1,2] # implied to be asking for more than the default
      }
    }
  ) {
    number
  }
}

result:

{
  "data": {
    "blocks": [
      {
        "number": 1
      }
    ]
  }
}

It's a reasonable expectation to omit the limit argument when asking for a specific set of items without exceeding the limit

Expose additional aggregation queries

The current implementation exposes basic aggregation queries for fields appropriate for the domain. There are more complex queries that can easily be exposed, however this requires an alternative data source to make assertions to prove validity

  • stddev_samp
  • stddev_pop
  • stddev
  • var_pop
  • var_samp
  • variance

Add e2e test

The current test scope does not include the full request, as the HTTP server gets in the way of tooling such as WallabyJS, and the GraphQL executable schema can be tested directly. It would be best to add an e2e test with Cardano GraphQL started in a Docker container, to be hooked into the CI for full assurance in one of our supported targets.

Add addresses query

type Address {
  balance: BigInt!
  inputs: [TransactionInput]
  outputs: [TransactionOutput]
  transactions(
    limit: PositiveInt
    offset: PositiveInt
    order_by: transactions_order_by
    where: transactions_filter
  ): [Transaction]
}

type Query {
  addresses(
    limit: PositiveInt
    offset: PositiveInt
    order: address_order_by
    where: address_filter
  ) [Address!]!
}

Add epoch model

Commented fields should be considered for future designs, not included in the MVP

enum Currency {
  ADA 
}

type CurrencyValue {
  currency: Currency!
  value: Int!
}

type Epoch {
  blocks: [Block]!
  output: [CurrencyValue]!
  number: Int
  slots: [Slot!]!
  startedAt: DateTime!
  endedAt: DateTime
  transactions: [Transaction]
  transactionsCount: Int
}

input EpochFilter {
  numbers: [Int],
  # beforeDate: DateTime,
  # afterDate: DateTime
}

type Query {
  epoch(filter: EpochFilter) Epoch
}

Merge Meta view into Cardano view

The meta fields can be added to the Cardano view instead of defining a separate view, which then simplifies the resolver to:

    cardano: (_root, _args, context, info) => {
      // Could optimise, but there's little performance gain
      return delegateToSchema({
        context,
        fieldName: 'Cardano',
        info,
        operation: 'query',
        schema: context.hasura
      })
    }

...instead of
https://github.com/input-output-hk/cardano-graphql/blob/977ab3e44c321981b368f61d2dfb0749cffab2c4/src/resolvers/hasura_resolvers.ts#L36-L57

Optimise sql queries to more closely match data requirements

Currently we're over-fetching data from postgres when the GraphQL query only requires a subset. This is an improvement over a REST API since we've moved the burden to the server, however ideally the SQL queries should be build dynamically with an exact query

This is an optimisation that has no impact on the API consumers.

Adding transaction count field directly to `Block`

The database now offers a denormalised field that would be the most performant over the aggregated query we currently have. It's worth exposing it at the top level

Block {
  ...
  transactionCount: BigInt!
  transactions_aggregate: Transaction_aggregate!
}

Apply views on application boot, if they don't exist

To remove the dependance on cardano-explorer, we want cardano-graphql to apply the views it depends on at boot.

retry-as-promised will be used to attempt the application of the views until it succeeds (as we have no control over when the underlying tables will be created by cardano-explorer)

There are 2 potential pitfalls with this approach:

  1. cardano-explorer, if it crashes, will fail to start again due to the sql in this file: https://github.com/input-output-hk/cardano-explorer/blob/master/schema/migration-1-0002-20190912.sql
  2. We have no way of migrating the views, outside of explicitly dropping the database such that the create view if not exists statements execute

Add `Transaction.size`

The write service now stores the transaction size in the db, which is good information to have in our API

Add comparison filtering, ordering control, limits, and offsets

The current interface has basic selection controls with no control over ordering, and does not include pagination parameters.

Current:

{
  blocks(filter: { numbers: [1,3,4] } ) {
    id
    number
  }
}

Desired

{
  blocks(limit: 250, offset: 100, where: { number: { _gt: 30, _lt: 100 }}) {
    id
    number
  }
}

Add additional fields from the PostgreSQL meta table

We can use this information to flesh out the Cardano type:

protocolConst
slotDuration
startTime
type Cardano {
  blockHeight: Int!
  currentEpoch: Epoch!
  protocolConst: Int
  slotDuration: Int!
  slotsPerEpoch: Int!
  startTime: DateTime
}

Also need to make the current slot in the current epoch known, to enable a UI to display a percentage indicator

Known limitation relating to Epoch querying

Currently querying epochs using an order_by argument performs poorly due since the nature of the database design is not optimised for read performance.

{
  epochs(limit: 5, order_by: { number: desc }) {
    ...
  }
}

Instead, the recommended approach is to get the current epoch:

{
  cardano {
    currentEpoch
  }
}

then select the epochs by number (eg latest from the above query is 35):

{
 epochs(where: { number: { in: [35,34,33,32,31]}}) {
    ...
  }
}

Staging Continuous Deployment

When creating a release we should update our running task definition to use these most recent containers.

This will probably be achieved best with a deploy.js that leverages the aws-sdk to describe the currently running task, and apply updates to the container version of task defs.

Remove default limits, enforce explicit queries

Currently the limit param on queries have default values, but this can lead to confusion as the limit is applied transparently. It would be better to remove defaults, and instead require explicit values based on use-case

Slots without blocks will be missing from the dataset

Due to the underlying data structure slots without blocks will not appear in the current query result sets. Initially this was implemented but presented a significant performance tax when joining objects to a view already derived from a recursive CTE.

This is an important domain-specific query relating to Stake Pool performance, so while a natural query expression of:

{
  Slot(where: {block: {id: {_is_null: true}}}) {
    number
  }
}

...will return no results, a specific query for stakePoolPerformance can be implemented without compromising performance, and provide greater value to the consumer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.