indexer-manager

module
v0.3.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 3, 2021 License: Apache-2.0

README

This repository contains an indexer for transactions. It consists of two parts: Manager and Worker. Manager is process maintaining database and serving traffic. Worker acts as a stateless scraper.

Structure

Connectivity

Manager and Worker are linked by GRPC bidirectional streams. To connect with each other, worker needs to know manager's http interface. After initial request is done - GRPC connection is started in another direction - from client to manager. All the following communication between services happen after. For every request, worker should sent a x number of responses marked with request's taskID. Response set should be terminated by one message with status being final.

Activity

Workers are meant to be stateless, this is why the main responsibility of managers is to serve requests from outside. Managers are not creating intermediate states. Every operation done on data is atomic. This allows to run more than one instance of manager in the same time.

Scheduling

To fulfill current goals, system needs to operate on actions that are triggered periodically. Because system may work with multiple instances of manager, this creates an obvious problem of reoccurring activities. This is why scheduler was created as separated package. It allows to connect to multiple managers in the form of SDS-like service. For the simplest scenarios with only one manager - scheduler is embedded into manager binary, skipping connectivity part.

Manager

Process that is responsible for maintaining current state of system. It is operating with the persistence layer. It is also serving traffic from/to external users.

Client

Manager's business logic. It should not contain any transport related operations such as data conversions of parameter checks. All the input and output structures should be as carrier-agnostic as possible.

Connectivity

Manager's Package for maintaining connections with workers. Currently allows to start the abstract connection with workers, match request with the response and direct that to proper client handles. Also implements simple round robin strategy for sending every next request to another currently connected worker.

Store

Persistent layer with only database operations. This package should not contain any business logic checks. Currently supports postgres database.

Transport
  • GRPC transport for connectivity package. Bidirectional stream implementation for worker connectivity.
  • HTTP transport containing set of user-facing endpoints with non-business logic data validation.

Worker

Stateless worker is responsible for connecting with the chain, getting information, converting it to a common format and sending it back to manager. Worker can be connected with multiple managers but should always answer only to the one that sent request.

Transport

Currently implemented transport allow worker to run using grpc.

Connectivity

Basic functions for initial simple service discovery. Right now, http queries to every manager triggered periodically.

API

Implementation of bare requests for network.

Client

Worker's business logic wiring of messages to client's functions.

Installation

This system can be put together in many different ways. This readme will describe only the simplest one worker, one manager with embedded scheduler approach.

Docker-Compose

This repo also comes with partially preconfigured docker-compose setup. To run using docker-compose you need to

  • Create scheduler configuration as stated below in ./scheduler/scheduler.json (or empty structure if you don't need scraping)
[
    {
        "network": "cosmos",
        "chainID": "cosmoshub-3",
        "version": "0.0.1",
        "duration": "30s",
        "kind": "lastdata"
    }
]
  • Start docker-compose (If you're running that for the first time you may need to run docker swarm init )
    docker-compose build
    docker-compose up

First manager would (the main api) would be available under http://0.0.0.0:8085

Docker-compose version comes also with preconfigured prometheus and grafana, serving content on :3000 and :9090

Tip: To purge database simply run docker volume rm indexer-manager_postgresdatabase after fully stopping the run

Compile

To compile sources you need to have go 1.14.1+ installed. For Worker and Manager it's respectively

    make build-cosmos
    make build-manager-migration
    make build-manager-w-scheduler
Running

The mandatory env variables (or json file) for both manager with embedded scheduler and migration the parameters are:

    ADDRESS=0.0.0.0:8085
    DATABASE_URL=postgres://cosmos:cosmos@cosmosdatabase/cosmos?sslmode=disable
    SCHEDULER_INITIAL_CONFIG_PATH=./schedules/
    ENABLE_SCHEDULER=true

Where ADDRESS is the ip:port string with http interface. It is possible to set the same parameters in json file under --config config.json

After setting up the database you need to run migration script it takes database from DATABASE_URL env var. (migrations are inside cmd/manager-migration/migrations directory)

    manager_migration_bin  --path "./path/to/migrations"

The embedded scheduler still needs it's configuration to scrape cosmos, cosmoshub-3 for the last data, every 30s the scheduler.json file needs to be would be following:

[
    {
        "network": "cosmos",
        "chainID": "cosmoshub-3",
        "version": "0.0.1",
        "duration": "30s",
        "kind": "lastdata"
    }
]

Where duration is a time.Duration parsed string, so valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". (https://golang.org/pkg/time/#ParseDuration)

After setting all of it just run the binary.

Worker also need some basic config:

    MANAGERS=0.0.0.0:8085
    TENDERMINT_RPC_ADDR=https://cosmoshub-3.address
    DATAHUB_KEY=1QAZXSW23EDCvfr45TGB
    CHAIN_ID=cosmoshub-3

Where - TENDERMINT_RPC_ADDR is a http address to node's RPC endpoint - MANAGERS a comma-separated list of manager ip:port addresses that worker will connect to. In this case only one

After running both binaries worker should successfully register itself to the manager.

Initial Chain Synchronization

Scheduler allows to apply many different events to be emitted periodically over time. One of such is lastdata which is used for getting latest records from chain. Running lastdata would effect in taking up to 1000 last heights that system haven't scraped yet. Every time scheduler runs, it checks fot last scrape information and starts from there. If there isn't any scraped data yet, process is starting from last block minus 1000 heights. If current height is smaller than 1000 - it starts from the first block.

To synchronize with missing height range you need to manually start the process by calling the /check_missing and/or /get_missing endpoints.

To check missing transactions simply call manager as:

GET http://0.0.0.0:8085/check_missing?start_height=1&end_height=3500000&network=cosmos&chain_id=cosmoshub-3

Where start_height/end_height is range existing in chain.

The get_missing endpoint is prepared to run big queries asynchronously. It is running as goroutines and it's not persisting any state. In case of process crash, just rerun operation. It should start with consistency check and begin scraping from the highest height it didn't have.

To start scraping, make following request within existing range.

GET http://0.0.0.0:8085/get_missing?force=true&async=true&start_height=1&end_height=3500000&network=cosmos&chain_id=cosmoshub-3

Where - force indicate the start/restart of scraping process. The next call without this parameter will return current state of scraping - async runs scraping process as goroutine. otherwise the process will die on any network timeout. - simplified returns only approximated progress from get missing process, helpful with very big ranges. - overwrite_all skips any checks and forcefully overwrites records found for given range .

Transaction Search is available by making a POST request on /transaction_search. The detailed description of parameters and response is available in swagger.json.

Current implementation allows to query entire range, however some complex queries take time. You can however, speed up every query by setting after_time, before_time or after_height, before_height parameters to narrow down known time/height range. All times are RFC3339.

Example list of cosmos defined types (listed by modules):

  • bank: multisend , send
  • crisis: verify_invariant
  • distribution: withdraw_validator_commission , set_withdraw_address , withdraw_delegator_reward , fund_community_pool
  • evidence: submit_evidence
  • gov: deposit , vote , submit_proposal
  • slashing: unjail
  • staking: begin_unbonding , edit_validator , create_validator , delegate , begin_redelegate
  • internal: error
Rewards

Rewards are available via a GET request to /rewards.

GET /rewards?network=cosmos&start_time=2021-04-01T02:00:00.00Z&chain_id=cosmoshub-4&end_time=2021-04-05T02:00:00.00Z&account=cosmos13axkauxjxulmvjyskppf8kxec56fyl96njm8qq&validators=cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxerarrl
Parameter JSON Type Description
account string Required. Account identifier
network string Required. Network identifier to search (eg. cosmos)
chain_id string Required. ChainID (eg. cosmoshub-4)
start_time string Required. Start time in RFC3339Nano format
end_time string Required. End time in RFC3339Nano format
validators string Coma separated list of validator accounts to query (eg. cosmosvaloper1xxx,cosmosvaloper2xxx,cosmosvaloper3xxx)

All times are in UTC. To get daily reward summaries for your local timezone, apply the UTC offset to midnight of your desired timezone. The response is an array of total rewards per currency for an account in 24 hour periods from the provided UTC start_time:

[{
  "start": 5699521,
  "end": 5711391,
  "time": "2021-04-01T02:00:00Z",
  "validator": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxerarrl",
  "rewards": [{
    "text": "14485183.076655587945uatom",
    "currency": "uatom",
    "numeric": 14485183076655587945173239,
    "exp": 18
  }]
}, {
  "start": 5711391,
  "end": 5723284,
  "time": "2021-04-02T02:00:00Z",
  "validator": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxerarrl",
  "rewards": [{
    "text": "14524615.642913129133uatom",
    "currency": "uatom",
    "numeric": 14524615642913129133835499,
    "exp": 18
  }]
}, {
  "start": 5723284,
  "end": 5735178,
  "time": "2021-04-03T02:00:00Z",
  "validator": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxerarrl",
  "rewards": [{
    "text": "14554430.583334477875uatom",
    "currency": "uatom",
    "numeric": 14554430583334477874950230,
    "exp": 18
  }]
}, {
  "start": 5735178,
  "end": 5747087,
  "time": "2021-04-04T02:00:00Z",
  "validator": "cosmosvaloper1lzhlnpahvznwfv4jmay2tgaha5kmz5qxerarrl",
  "rewards": [{
    "text": "14582108.999563571208uatom",
    "currency": "uatom",
    "numeric": 14582108999563571207321173,
    "exp": 18
  }]
}]
Parameter JSON Type Go Type Description
start number int64 Period start height
end number int64 Period end height
time string time.Time Period start time in RFC3339Nano format
validator string string Validator account from which reward was earned from
rewards array int64 Array of total reward amounts earned for each currency
text string string Optional Total amount with currency in text format
currency string string Currency type (eg. uatom)
numeric number big.Int an integer representation of amount without decimal places, such that amount = numeric * 10^(-exp)
exp number int32 the number of decimal places in amount, such that amount = numeric * 10^(-exp)
Account Balances

Account Balances are available via a GET request to /account/balance.

GET /account/balance?network=kava&chain_id=kava-4&account=kava1u84mr5ndzx29q0pxvv9zyqq0wcth780hycrt0m&start_time=2021-01-14T02:00:00.000000Z&end_time=2021-01-15T02:00:00.000000Z
Parameter JSON Type Description
account string Required. Account identifier
network string Required. Network identifier to search (eg. cosmos)
chain_id string Required. ChainID (eg. cosmoshub-3)
start_time string Required. Start time in RFC3339Nano format
end_time string Required. End time in RFC3339Nano format

All times are in UTC. To get daily account balance summaries for your local timezone, apply the UTC offset to midnight of your desired timezone. The response is an array of account balance per currency for an account in 24 hour periods from the provided UTC start_time:

[
    {
        "height": 867288,
        "time": "2021-01-14T02:00:00.000000Z",
        "balances": [
            {
                "text": "1.023320944447133110740ukava",
                "currency": "ukava",
                "numeric": 1023320944447133110740,
            }
        ]
    }
]
Parameter JSON Type Go Type Description
height number int64 Period (end) height which shows the account balance info for
time string time.Time Period start time in RFC3339Nano format
balances array int64 Array of account balances
text string string Balance amount with currency in text format
currency string string Currency type (eg. ukava)
numeric number big.Int an integer representation of amount without decimal places, such that amount = numeric * 10^(-exp)
exp number int32 the number of decimal places in amount, such that amount = numeric * 10^(-exp)
Reward's Annualized Percentage Rate (APR)

Reward APRs are available via a GET request to /apr.

GET /apr?network=cosmos&start_time=2021-05-01T14:19:46Z&chain_id=cosmoshub-4&end_time=2021-05-05T14:19:46Z&account=cosmos16k3ujc0wn8n4ynm5sgewdpwyxx8mn49a5l8cwm&validators=cosmosvaloper14kn0kk33szpwus9nh8n87fjel8djx0y070ymmj,cosmosvaloper1z66j0z75a9flwnez7sa8jxx46cqu4rfhd9q82w
Parameter JSON Type Description
account string Required. Account identifier
network string Required. Network identifier to search (eg. cosmos)
chain_id string Required. ChainID (eg. cosmoshub-3)
start_time string Required. Start time in RFC3339Nano format
end_time string Required. End time in RFC3339Nano format
validators string Coma separated list of validator accounts to query (eg. cosmosvaloper1xxx,cosmosvaloper2xxx,cosmosvaloper3xxx)

All times are in UTC. To get the response calculated for your local timezone, apply the UTC offset to midnight of your desired timezone. The response is an array of aprs for an account calculated from the bonded balance and rewards earned in 24 hour periods from the provided UTC start_time:

[{
    "start_height": 6061573,
    "time_bucket": "2021-05-01T14:19:46Z",
    "apr": "0.0834",
    "bonded": {
        "text": "120000000",
        "currency": "uatom",
        "numeric": 120000000
    },
    "total_rewards": {
        "text": "27424.74898911416uatom",
        "currency": "uatom",
        "numeric": 27424748989114160000000,
        "exp": 18
    },
    "validator": "cosmosvaloper14kn0kk33szpwus9nh8n87fjel8djx0y070ymmj"
}, {
    "start_height": 6073429,
    "time_bucket": "2021-05-02T14:19:46Z",
    "apr": "0.0930",
    "bonded": {
        "text": "473999999",
        "currency": "uatom",
        "numeric": 473999999
    },
    "total_rewards": {
        "text": "120778.6541629169562uatom",
        "currency": "uatom",
        "numeric": 120778654162916956198894,
        "exp": 18
    },
    "validator": "cosmosvaloper1z66j0z75a9flwnez7sa8jxx46cqu4rfhd9q82w"
}]
Parameter JSON Type Go Type Description
start_height number int64 Period (end) height which shows the account balance info for
time_bucket string time.Time Start time in RFC3339Nano format for a 24h period
apr string string reward's annualized percentage rate, 0.0930 = 9.3%
bonded string string Balance amount that was bonded/staked to validator at beginning of time_bucket
total_rewards string string Rewards earned during time_bucket
text string string Balance amount with currency in text format
currency string string Currency type (eg. uatom)
numeric number big.Int an integer representation of amount without decimal places, such that amount = numeric * 10^(-exp)
exp number int32 the number of decimal places in amount, such that amount = numeric * 10^(-exp)
validator string string Validator account where bonded balance was staked

Directories

Path Synopsis
cmd
manager
client/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
store/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
scheduler
worker
transport/grpc
Package GRPC incorporate GRPC interface of worker allows it to accept new streams and forward messages
Package GRPC incorporate GRPC interface of worker allows it to accept new streams and forward messages

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL