GithubHelp home page GithubHelp logo

api's Introduction

CircleCI

NDID API (Node.js)

Modules

  • Main
  • MQ service
  • Telemetry
    • Documentation can be found here

Prerequisites

  • Node.js 15 or later (Recommended: latest version of Node.js 16 LTS)
  • npm 8 or later
  • Redis 3.2 or later

Getting started

  1. Install dependencies

    # from repository root directory
    ./scripts/install_deps.sh
  2. Run smart contract (tendermint ABCI app) server in smart-contract repository and wait for first commit to show up in an output.

  3. Add development keys to the system (for development mode only)

    # from repository root directory
    cd main-server
    
    TENDERMINT_IP=$TENDERMINT_IP \
    TENDERMINT_PORT=$TENDERMINT_PORT \
    NODE_ID=ndid1 \
    npm run initDev
  4. Run a MQ service server

    # from repository root directory
    cd mq-server
    
    NODE_ID=$NODE_ID \
    MQ_BINDING_PORT=$MQ_BINDING_PORT \
    npm start

Environment variable options

  • NODE_ID: (Must be the same as its server pair) Description below [Required]
  • MQ_BINDING_PORT: (Must be the same as its server pair) Description below [Required]
  • SERVER_PORT: gRPC server port [Default: 50051]
  • MAX_CONCURRENT_MESSAGES_PER_MQ_SOCKET: Maximum concurrent messages for each MQ sending socket [Default: 16]
  • MAX_MQ_SOCKET: Maximum limit for MQ sending sockets [Default: 10000]
  • GRPC_PING_INTERVAL_MS: gRPC ping interval in milliseconds [Default: 300000]
  • GRPC_PING_TIMEOUT_MS: gRPC ping timeout in milliseconds [Default: 20000]
  • GRPC_EXPECTED_CLIENT_PING_INTERVAL_MS: gRPC expected client ping interval in milliseconds. Must be less than GRPC_PING_INTERVAL_MS config on API server pair. [Default: 30000]
  • LOG_LEVEL: Description below
  • LOG_PRETTY_PRINT: Description below
  • LOG_COLOR: Description below
  • LOG_ONE_LINE: Description below
  • PROMETHEUS
  • PROMETHEUS_SERVER_PORT
  • PROMETHEUS_HTTPS
  • PROMETHEUS_HTTPS_KEY_PATH
  • PROMETHEUS_HTTPS_CERT_PATH
  1. Run a main server

    # from repository root directory
    cd main-server
    
    NODE_ID=$NODE_ID \
    MQ_CONTACT_IP=$MQ_CONTACT_IP \
    ENABLE_TELEMETRY_LOGGING=true \
    npm start

Environment variable options

  • MODE: Allowed values are standalone, master, and worker. There can be only one master process per Node ID [Default: standalone]
  • MASTER_SERVER_IP: Master process gRPC server IP address. Required when MODE=master [Default: localhost]
  • MASTER_SERVER_PORT: Master process gRPC server port. Required when MODE=master and MODE=worker [Default: 7000]
  • CALL_TO_MASTER_RETRY_TIMEOUT_MS: gRPC call from worker process to master process retry timeout in milliseconds [Default: 120000]
  • NODE_ID: Node ID ties to public key, in dev mode we have rp1, rp2, rp3, idp1, idp2, idp3, as1, as2, as3 [Required]
  • NDID_NODE: Set to true to skip getting role from blockchain and skip waiting for blockchain initialization ended. [Default: false]
  • TENDERMINT_IP: IP Address to contact tendermint RPC [Default: localhost]
  • TENDERMINT_PORT: Port to contact tendermint RPC [Default: 45000]
  • TENDERMINT_WS_CONNECTIONS: Number of Tendermint RPC WebSocket connections in connection pool. [Default: 10]
  • MQ_CONTACT_IP: An IP address where this NDID node message queue can be contacted [Required when role is set to idp, rp, or as]
  • MQ_BINDING_PORT: A port to bind message queue [Default: 5555]
  • MQ_SERVICE_SERVER_IP: IP address of MQ service server [Default: localhost]
  • MQ_SERVICE_SERVER_PORT: Port of MQ service server [Default: 50051]
  • COMPRESS_MQ_MESSAGE: Compress MQ message before sending to other nodes [Default: false]
  • MQ_MESSAGE_COMPRESS_MIN_LENGTH: Minimum message (to send over MQ) length in bytes to compress [Default: 1000]
  • SERVER_PORT: API server port [Default: 8080]
  • PRIVATE_KEY_PATH: Path to node's private key (if call back to create signature is not set) [Default: use pre-generated development key in development mode]
  • PRIVATE_KEY_PASSPHRASE: Passphrase for node's private key
  • MASTER_PRIVATE_KEY_PATH: Path to node's master private key (if call back to create signature is not set) [Default: use pre-generated development key in development mode]
  • MASTER_PRIVATE_KEY_PASSPHRASE: Passphrase for node's master private key
  • NODE_BEHIND_PROXY_PRIVATE_KEY_DIRECTORY_PATH: Directory path for nodes behind proxy private keys and passphrases [Default: use pre-generated development key in development mode]
  • NODE_BEHIND_PROXY_MASTER_PRIVATE_KEY_DIRECTORY_PATH: Directory path for nodes behind proxy master private keys and passphrases [Default: use pre-generated development key in development mode]
  • DATA_DIRECTORY_PATH: Directory path for persistence data files [Default: __dirname/../data (data directory in repository's directory)]
  • DEFAULT_API_VERSION: API version to serve on default path (without version path prefix) [Default: 5]
  • CALLBACK_API_VERSION: Callback API version [Default: 5]
  • DB_IP: IP address of DB (redis) server [Default: localhost]
  • DB_PORT: Port of DB (redis) server [Default: 6379]
  • DB_PASSWORD: Authentication password for DB (redis) connection
  • LOG_LEVEL: Log level. Allowed values are fatal, error, warn, info, debug, trace, and silent [Default: debug in development, info in production]
  • LOG_PRETTY_PRINT: Log prettifier (easy to read format). If not set to true, log will be in JSON format [Default: true in development, false otherwise]
  • LOG_COLOR: Log highlight color [Default: true in development, false otherwise]
  • LOG_ONE_LINE: Log one-line pretty print when LOG_PRETTY_PRINT is set to true [Default: false]
  • CLIENT_HTTP_ERROR_CODE: HTTP error code when responding a client error [Default: 400]
  • SERVER_HTTP_ERROR_CODE: HTTP error code when responding a server error [Default: 500]
  • USE_EXTERNAL_CRYPTO_SERVICE: Use external service for decrypting and signing (e.g. HSM) [Default: false]
  • AUTO_CLOSE_REQUEST_ON_COMPLETED: Automatically close a request as soon as status is completed (and when all IdP response signatures are valid in mode 2 and 3). (For RP role) [Default: true]
  • AUTO_CLOSE_REQUEST_ON_REJECTED: Automatically close a request as soon as status is rejected (and when all IdP response signatures are valid in mode 2 and 3). (For RP role) [Default: false]
  • AUTO_CLOSE_REQUEST_ON_COMPLICATED: Automatically close a request as soon as status is complicated (and when all IdP response signatures are valid in mode 2 and 3). (For RP role) [Default: false]
  • AUTO_CLOSE_REQUEST_ON_ERRORED: Automatically close a request as soon as status is errored. (For RP role) [Default: true]
  • AS_DATA_COMPRESS_MIN_LENGTH: Minimum AS response data (to send over P2P/MQ) length in bytes to compress [Default: 1000]
  • HTTPS: Use HTTPS server [Default: false]
  • HTTPS_KEY_PATH: HTTPS private key file path. Required when HTTPS=true [Default: pre-generated development key]
  • HTTPS_CERT_PATH: HTTPS certificate file path. Required when HTTPS=true [Default: pre-generated development cert]
  • CALLBACK_RETRY_TIMEOUT: Callback retry timeout in seconds. Only applies to some callbacks (that do not have shouldRetry function check e.g. request status update callback to RP client) [Default: 600]
  • REGISTER_MQ_AT_STARTUP: Flag to tell API node whether to register message queue address when start (will override previously registered address) [Default: true for RP, IdP, and AS roles, false for NDID role]
  • MAX_INTERVAL_TENDERMINT_SYNC_CHECK: Maximum time interval in milliseconds for polling Tendermint syncing status on server start [Default: 15000]
  • GRPC_PING_INTERVAL_MS: gRPC ping interval in milliseconds [Default: 60000]
  • GRPC_PING_TIMEOUT_MS: gRPC ping timeout in milliseconds [Default: 20000]
  • GRPC_EXPECTED_CLIENT_PING_INTERVAL_MS: gRPC expected client ping interval in milliseconds. Used by master mode process. Must be less than GRPC_PING_INTERVAL_MS config on worker processes. [Default: 30000]
  • GRPC_CALL_TIMEOUT_MS: gRPC call timeout in milliseconds [Default: 60000]
  • PROMETHEUS: Enable prometheus metrics and HTTP server for querying metrics [Default: false]
  • PROMETHEUS_SERVER_PORT: HTTP server port for querying Prometheus metrics [Default: 8888]
  • PROMETHEUS_HTTPS: Use HTTPS server for Prometheus metrics HTTP server [Default: false]
  • PROMETHEUS_HTTPS_KEY_PATH: HTTPS private key file path for Prometheus metrics HTTP server. Required when PROMETHEUS_HTTPS=true [Default: pre-generated development key]
  • PROMETHEUS_HTTPS_CERT_PATH: HTTPS certificate file path for Prometheus metrics HTTP server. Required when PROMETHEUS_HTTPS=true [Default: pre-generated development cert]
  • ENABLE_TELEMETRY_LOGGING: Enable/disable telemetry logging. Options are true and false [Default: true]
  • TELEMETRY_DB_HOST: Host/IP of Redis DB database for telemetry [Default: Same as DB_IP]
  • TELEMETRY_DB_PORT: Port of Redis DB database for telemetry [Default: Same as DB_PORT]
  • TELEMETRY_DB_PASSWORD: Password of Redis DB database for telemetry [Default: Same as DB_PASSWORD]
  • DCONTRACT_REQUEST_TYPE: Request type name for requests with dcontract document link(s) in request message. [Default: dsign.dcontract]
  • DCONTRACT_VALIDATE: Enable dcontract document validation automatically on IdP node. To disable this feature, set to false and IdP is required to validate document by themselves. [Default: true]
  • DCONTRACT_FETCH_TIMEOUT: Timeout for fetching documents from document source in miliseconds [ Default: 30000 ]

Debug APIs (Only in development mode)

  • POST /debug/tmQuery/:ABCI_FunctionName with BODY to pass to ABCI app
  • POST /debug/tmTransact/:ABCI_FunctionName with BODY to pass to ABCI app with extra 3 parameter (not pass to ABCI)
    • debug_callbackUrl: Callback url to receive result (MUST SET debug_sync to true)
    • debug_useMasterKey: Use master key to sign tx or not (boolean)
    • debug_sync: Wait for tx commit, or will callback (boolean)

Examples

  • Run a server as an IDP

    TENDERMINT_IP=127.0.0.1 \
    TENDERMINT_PORT=45000 \
    MQ_CONTACT_IP=127.0.0.1 \
    MQ_BINDING_PORT=5555 \
    SERVER_PORT=8100 \
    NODE_ID=idp1 \
    ENABLE_TELEMETRY_LOGGING=true \
    npm start
  • Run a server as a RP

    TENDERMINT_IP=127.0.0.1 \
    TENDERMINT_PORT=45001 \
    MQ_CONTACT_IP=127.0.0.1 \
    MQ_BINDING_PORT=5556 \
    SERVER_PORT=8200 \
    NODE_ID=rp1 \
    ENABLE_TELEMETRY_LOGGING=true \
    npm start
  • Run a server as a AS

    TENDERMINT_IP=127.0.0.1 \
    TENDERMINT_PORT=45000 \
    MQ_CONTACT_IP=127.0.0.1 \
    MQ_BINDING_PORT=5557 \
    SERVER_PORT=8300 \
    NODE_ID=as1 \
    ENABLE_TELEMETRY_LOGGING=true \
    npm start

Don't forget to

  1. Set SERVER_PORT when running on the same machine to avoid port collision.
  2. Set TENDERMINT_IP and/or TENDERMINT_PORT when running smart-contract/tendermint on another machine.

Run in Docker

Required

Build

./docker/build.sh

Run

docker-compose -f docker/docker-compose.yml up

Note

  • To run docker container without building image, run command show in Run section (no building required). It will run docker container with image from Dockerhub (https://hub.docker.com/r/ndidplatform/api/).
  • To pull latest image from Dockerhub, run docker pull ndidplatform/api and docker pull ndidplatform/mq
  • Docker container can be run with -u or --user flag (e.g. -u 65534:65534). In case you are using docker-compose, user can be specified in docker-compose file (e.g. user: 65534:65534) (see Compose file reference for more detail).
  • When running docker container with non-root user, source directories that will be mounted into the container as DATA_DIRECTORY_PATH must be created beforehand with the non-root user as owner.

Logging

Both main server and MQ service server only log to stdout. For log rotation, see http://getpino.io/#/docs/help?id=log-rotation.

Note

  • When running as a proxy node:
    • DB (Redis) should not be shared with other proxy node.
    • NODE_BEHIND_PROXY_PRIVATE_KEY_DIRECTORY_PATH is where node behind proxy private keys are stored. The server expects key filename to be node's ID. If keys have a passphrase, it should be in a text file with filename <NODE_ID>_passphrase
    • NODE_BEHIND_PROXY_MASTER_PRIVATE_KEY_DIRECTORY_PATH is where node behind proxy master private keys are stored. The server expects key filename to be <NODE_ID>_master. If keys have a passphrase, it should be in a text file with filename <NODE_ID>_master_passphrase
  • When working in development, if you clear/delete the blockchain, you need to delete latest block height files by running npm run delete-local-data-cache. (Automatically run when running npm run initDev) For docker, run npm run docker-down or docker-compose -f docker/docker-compose.yml down before starting containers again.

api's People

Contributors

0x0d01 avatar apemon avatar bomu-bomu avatar crossknight avatar dependabot[bot] avatar jirapusnon avatar krissdap avatar niponchi avatar oatsaysai avatar panikt avatar phirasit avatar re7eal avatar taneekpet avatar tansinee avatar yzi-afk 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

api's Issues

Master Public Key is not registered when start up a new node in docker

Reproduce Steps

  • Start up a new node in docker
  • Query to function GetNodeMasterPublicKey via Tendermint RPC

Current Result

  • Get {"master_public_key":""}

Expected Result

  • Get {"master_public_key":"<key_in_pem_format>"}

Cause

  • Typo in start up script start-api.sh when setting path to MASTER_PUBLIC_KEY_PATH

Request status was reject when reject before accept

Scenario:
Create Request with
min_idp: 1
idp_id_list: [idp1, idp2]
mode: 3

When reject at idp1 and accept at idp2, the request was rejected.

I think this case the request status should be completed by 1 IdP accept.

Hash algorithm unsafe

I mentioned this to @taneekpek at Barcamp. I would like to propose that bcrypt is used as a hash algorithm instead of sha256.

Wait for blockchain sync on start

Issue

When starting a new tendermint node, it will sync/replay all the transactions.

Possible Solution

Track chain sync status by checking the result returned from calling /status to tendermint.

Wait for genesis block to be committed and signed on start

Issue

Having to wait for ABCI app output:

Commit
Commit

before starting api server.

Possible Solution

Listen for 'NewBlock' event from tendermint and check if height >= 2 (Genesis block committed and signed) before receiving/processing any requests.

Configurable callback retry timeout

Add CALLBACK_RETRY_TIMEOUT as an environment variable for configurable callback retry timeout.

This config applies ONLY to callback retries that have not set a pre-retry hook function (shouldRetry function). The timeout value is in seconds. Default is 600 seconds or 10 minutes.

No defaultMqBindingPort for ndid role, cause process exit if no MQ_BINDING_PORT set

from mq.js

export const defaultMqBindingPort = (() => {
  if (process.env.ROLE === 'as') return 5557;
  if (process.env.ROLE === 'idp') return 5555;
  if (process.env.ROLE === 'rp') return 5556;
})();

If we not set MQ_BINDING_PORT before start process as ndid role, the process will be crashed with

/home/circleci/project/node_modules/zeromq/lib/index.js:451
  this._zmq.bindSync(addr);
            ^
Error: Invalid argument
    at exports.Socket.Socket.bindSync (/home/circleci/project/node_modules/zeromq/lib/index.js:451:13)
    at Object.<anonymous> (/home/circleci/project/src/mq/index.js:12:17)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/circleci/project/src/core/rp.js:10:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/circleci/project/src/routes/rp.js:4:1)
    at Module._compile (module.js:652:30)
    at Object.Module._extensions..js (module.js:663:10)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)

Callback request status to RP has duplicate response_valid_list

I have two IDP, AS nodes and RP create request with data request (min_idp=1, min_as=2)
two IDP nodes are respond request at the same time and final callback request status to RP has duplicate response_valid_list like this.

response_valid_list: [ { idp_id: 'idp2', valid_proof: true, valid_ial: true },
{ idp_id: 'idp2', valid_proof: true, valid_ial: true } ]

GET /utility/requests/:request_id response with error 500 when request_id does not exist

error: Responded Internal Server Error with HTTP code 500 { responseBody: 
api-idp-1_1  |    { error: 
api-idp-1_1  |       { code: 10000,
api-idp-1_1  |         message: 'Cannot destructure property `special` of \'undefined\' or \'null\'.',
api-idp-1_1  |         stack: 'CustomError: Cannot get request details from blockchain\n    at Object.getRequestDetail (/api/src/tendermint/ndid.js:410:11)\n    at <anonymous>\n    at process._tickCallback (internal/process/next_tick.js:188:7)\nCaused By: TypeError: Cannot destructure property `special` of \'undefined\' or \'null\'.\n    at Object.getRequestDetail (/api/src/tendermint/ndid.js:396:5)\n    at <anonymous>\n    at process._tickCallback (internal/process/next_tick.js:188:7)' } } }

/ndid/initNDID should not respond with array of [success_status, height]

/ndid/initNDID, if success, will respond with [true, <height>]. Instead, it should respond with success status (true/false) only.

As I have investigated, the issue seems to be caused by

init = await tendermint.transact(
.

Since tendermint.transact() returns an array, the line should destructure the returned array and return only success status instead of the whole array.

So it should be something like:

const [ result, height ] = tendermint.transact(
...
init = result;
return init; 

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.