Code Monkey home page Code Monkey logo

unchained's Introduction

Introduction

ShapeShift ShapeShift ShapeShift GitPOAP Badge CircleCI

Unchained is a multi-blockchain backend interface with three main goals:

  1. Provide a common interface to multiple blockchains
  2. Provide additional information not always accessible from the node directly
  3. Provide realtime updates about blockchain transactions (pending and confirmed)

Table Of Contents

Helpful Docs

Coin Stack Components

  • Node - coin specific node daemon providing historical blockchain data (ex. bitcoind, geth, etc)
  • Indexer - optional service that indexes transaction and balance history by address, or any other applicable information, if not provided by the node directly
  • API - provides a base set of functionality via REST and WebSocket that can be extended with coin specific logic

Architecture Diagrams

With Indexer No Indexer

Notes

  • The ethereum coinstack is used in all examples. If you wish to run a different coinstack, just replace ethereum with the coinstack name you wish to run
  • All paths are relative to the root unchained project directory (ex. unchained/[go|node]/{path})
  • All pulumi commands should be run in a pulumi/ directory (ex. pulumi/, coinstacks/ethereum/pulumi/)

Local Networking

We use traefik as a reverse-proxy to expose all of our docker containers. Traefik is exposed at port 80. Traefik Dashboard is exposed at port 8080

Traefik routes requests based on host name. which includes the coinstack name. For Example:

  • api.ethereum.localhost

Setup

  • Each language subdirectory has setup requirements before running a coinstack locally
    • Go - unchained/go
    • Node - unchained/node
  • Both go and node module have linter installed in git pre-commit hook. To set up the hook:
    yarn

Docker-Compose Local Dev Instructions

Prerequisites

Running

  • Install node dependencies

    yarn
  • Start the reverse proxy and any common service (ex. hot reloading):

    docker-compose up -d

    Note: -d runs the containers in daemon (background) mode. If you want to see logs, -d can be omitted.

  • Start a coinstack:

    cd node/coinstacks/ethereum
    cp sample.env .env // make sure to populate the .env file with valid API keys if required
    docker-compose up
  • Visit http://api.ethereum.localhost/docs to view the OpenAPI documentation for the API

  • Tear down a coinstack (including docker volumes):

    cd node/coinstacks/ethereum && docker-compose down

Common Issues

  • If you are running Docker Desktop and see any SIGKILL errors, increase your resource limits in the Resources Tab.

  • Mac OS: when running one of the go coinstacks via docker-compose on, you might encounter an issue with the service failing to start indefinitely. This is due to Mac OS network security blocking the service from starting. To work around that issue, run the coinstack directly from CLI:

    cd go && go run cmd/cosmos/main.go -env=cmd/cosmos/.env

    This will trigger the security popup, allow the go process to make the network calls. Once you approve it, you can kill the process and restart docker-compose. The app should start immediately.

  • Mac OS: once you start a coinstack you should be able to access unchained in the browser without further config, but for CLI access to work you need to modify /etc/hosts and add a valid DNS entry:

    127.0.0.1 localhost api.cosmos.localhost // add a new alias for the coinstack

unchained's People

Contributors

0xapotheosis avatar 0xdef1cafe avatar 0xean avatar asamere avatar bielwenass avatar boyin0x avatar cjthompson avatar con5cience avatar daodev44 avatar dependabot[bot] avatar elmutt avatar fastwin0 avatar gomesalexandre avatar kaladinlight avatar lmyslinski avatar mrnerdhair avatar mvpratt avatar notatooyou avatar pastaghost avatar phewitt avatar samortaylor avatar soptq avatar sterl avatar theoboldfrazier avatar toshisat avatar trungtin avatar woodenfurniture 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

Watchers

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

unchained's Issues

Ethereum Ropsten Support

AC:

  • Veryify working coinstack locally (init.sh, readiness.sh)
  • Deploy to personal aws account
  • Update .circleci/config.yml to deploy develop and production public coinstacks

Steps:

  • Verify indexer.daemon.chain (specified in your copy of coinstacks/ethereum/pulumi/Pulumi.sample.yaml) parameter works correctly to deploy a local kubernetes instance of an ethereum ropsten coinstack
    • There will be pulumi resource naming conflicts that need to be handled. It would make the most sense to update the asset name in coinstack/ethereum/pulumi/index.ts to append the chain type if it is not mainnet.
  • Ensure signal catching works correctly still as defined in coinstacks/ethereum/daemon/init.sh (should work the same as mainnet node)
  • Ensure readiness check works as defined in coinstacks/ethereum/daemon/readiness.sh (should work the same as mainnet node)
  • Deploy and sync ethereum ropsten coinstack to personal aws account
  • Update .circleci/config.yml with jobs to deploy ethereum ropsten coinstacks to the develop and production environments, specifying the correct daemon-chain paramter

Add BTC fee estimation

The BTC chain adapter currently fetches network fee estimations from bitcoinfees.earn.com. This is effective, but fragile in the case of unforeseen external service interruptions. Unchained should provide BTC fee estimates via API call, with the network fees determined independently, without the use of any external service. For reference, look at how BTC fees are estimated in Watchtower.

RabbitMQ: Wrapped interface

Each exchange is just a string and the returned message is just a blob of data. It would be nice to wrap the exchange with the messages to be able to type the interaction with rabbit during the ingestion pipeline.

AC:

  • Wrap/abstract rabbit functionality to ensure typing for each exchange (input data) and queue (output data) payloads

Template: Chain Addition Checklist

How to add a new chain. Note - this template is only a guide. Each chain is different so make changes to the plan as neccesary

Daemon

  • Spike: Select a blockchain daemon.
  • Update the Pulumi infra code, add init.sh and readiness.sh scripts
  • Deploy

Indexer
The Indexer maintains an index of transaction history by address. Most nodes don't do this so a separate database is needed.

  • Spike: Select an indexer. For UTXO and EVM chains, use Blockbook. For Cosmos chains (Cosmos, Binance, Thorchain) use the node
  • Update the Pulumi infra code
  • Deploy

API
The API is an adapter layer to the Indexer that provides a consistent set of endpoints for the ShapeShift client. Implement these endpoints using Bitcoin & Ethereum as a reference

  • /account{pubkey}
  • /account/{pubkey}/txs
  • /account/{pubkey}/utxos
  • /send

Ingester
The Ingester filters new transactions and sends only the relevant ones to each client

  • Get new blocks (ws)
  • Get transactions from mempool (ws)
  • Get transactions from confirmed blocks
  • Filter for transactions for addresses in the registry
  • Handle reorgs
  • Delta sync on register
  • Delta sync on new transaction
  • Client web sockets

Tests - Ingester

  • newBlock worker: Block Reorg
  • Tx worker: Delta sync
  • Tx worker: parseTx
    (TODO: add more tests)

Code Generation: Cleanup

We don't need to be checking in all of the generated code, but we do want to ensure the most recent generated code in a few circumstances.

  • coinstacks/api/src/routes.ts does not need to be tracked. this is automatically generated on yarn build and kept up to date during development. We run yarn build and persist the workspace in CircleCI, so we will have the routes available for deployed image.
  • coinstacks/api/src/swagger.json should be tracked. There is currently a pre-push hook that runs generate, but it is easy to miss the update and merge without actually committing the most recent swagger. It would be ideal to pull this out so that on merge, we run generate on the project and commit any swagger changes before merge to ensure they are up to date in the repository.
  • packages/client/src/generated does not need to be tracked. We should set up a way to handle hot regeneration of the client for development. Right now publishing is manual, we will want to generate and publish this package after deployment of coinstacks.

Cluster Autoscaling

AC:

  • Support cluster autoscaling so we don't have to manually scale as we continue to add new chains

Websocket: Data integrity/consistency

  • Due to the concurrent nature of the ingestion pipeline, transactions history can propagate to the client out of order.
  • This coincides with the need for a client to be able to pick back up sync at a specific block number as determined by their database state

AC:

  • Ensure a client can pick up syncing from where it last left off and not be worried about any missing transaction history

Deploy Blockbook for Bitcoin

We need a Blockbook instance in production. Use Pulumi to deploy to the open-source/public production cluster.

estimateGas: support from address

From address is an optional argument that can be sent to the estimateGas call and may have implications on the estimated gas cost returned.

AC:

  • Support a from query paramter for estimateGas endpoint

Websocket: Abstract server class

AC:

  • Export necessary types used in server class from ingester
  • Abstract server class out into common/api that can be used across stacks

Thorchain/Gaia: REST Client

Add thorchain client to unchained using swagger definition if we can find one

or use one from npm if cant find a good swagger

or write custom client class is none of those exist

Log Aggregation & Storage

We don't have the ability to view logs of a pod that is no longer running. We need a way to collect and store a rolling window of logs for analysis.

Spike: Adding Cosmos

Spike: Adding Cosmos

  1. Scope the work needed and document an implementation plan in the comments on this issue
  2. Who will do the work
  3. Estimate how long it will take to complete
  4. Challenges or other considerations that are unique to this chain
  5. Create Github issues to track the work

Use the following checklist as a guide:


Chain Addition Checklist

Daemon

  • Spike: Select a blockchain daemon.
  • Update the Pulumi infra code, add init.sh and readiness.sh scripts
  • Merge and deploy to public endpoints

Indexer
The Indexer maintains an index of transaction history by address. Most nodes don't do this so a separate database is needed.

  • Spike: Select an indexer. For UTXO and EVM chains, use Blockbook. For Cosmos chains (Cosmos, Binance, Thorchain) use the node
  • Update the Pulumi infra code
  • Merge and deploy to public endpoints

API
The API is an adapter layer that provides a consistent set of endpoints for the ShapeShift client. Implement these endpoints using Bitcoin & Ethereum as a reference

  • /account{pubkey}
  • /account/{pubkey}/txs
  • /account/{pubkey}/utxos
  • /send

Ingester
The Ingester filters new transactions and sends only the relevant ones to each client

  • Get new blocks (ws)
  • Get transactions from mempool (ws)
  • Get transactions from confirmed blocks
  • Filter for transactions for addresses in the registry
  • Handle reorgs
  • Delta sync on register
  • Delta sync on new transaction
  • Client web sockets

**Tests **
Ingester:

  • newBlock worker: Block Reorg
  • Tx worker: Delta sync
  • Tx worker: parseTx

Examine Rate Limiting of Public Dev Instance

Examine traffic levels since the launch of the public api.ethereum.shapeshift.com endpoint, determine if it would be prudent to implement ingress throttling, and implement if so.

Ensure correct ingester_meta handling on register

The ingester_meta object is not being sanitized or passed through completely on registration which results in always syncing from block 0.

AC:

  • Sanitize addresses in ingester_meta object in the same way as the address array
  • Allow sync to start from a block determined by client

Common Ingester: Pass in all configuration upon class construction

Both the Socket and Worker classes were abstracted into the common ingester package but left process.env artifacts.

These were recently moved into the constructor to allow publishing of the package without failing on import without env vars set as a quick fix.

This should really be updated to pass in the values in the constructor to be configurable more correctly.

Bitcoin API

Follow the Ethereum spec and deploy an API to production. Add tests with chain-adapters.

Bitcoin ingester: delta sync

Acceptance Criteria:

  1. When the ingester detects a new transaction on a watched address, it performs a delta sync (since the last known transaction) and sends to the address exchange for parsing. The reason for the delta sync is to fill in the gaps for any missed transactions that might have occurred

RabbitMQ Cluster/Replicas

There is currently only a single rabbitmq sts deployed for each coinstack which will result in down time whenever kube nodes roll. It would be best if we could update to use a rabbitmq cluster or replica set deployment, similar to mongodb

Unchained API: More restful design

Instead of lots of flat endpoints like /balance, /utxos, etc., use a more resource driven restful design pattern like:

/account/{pubkey}
/account/{pubkey}/txs
/account/{pubkey}/utxos
/gas/estimate
/gas/price

Websocket server class

AC:

  • Single websocket per client_id
  • Handle exchange/queue management
  • Support subscribe/unsubscribe/update methods
  • Support txs topic

Unchained: change favicon and page title of swagger api page

Change the favicon and page title so the browser tab shows as a ShapeShift page, rather than "Swagger UI".

See screenshot and arrow for more clarity about what needs to change.

Ideally the favicon and css would live in the coinstacks/common/api so that it can be referenced by each coinstack moving forward. We are using https://github.com/scottie1984/swagger-ui-express to generate the swagger doc ui which allows for custom styling options to be passed in.

Screen Shot 2021-09-07 at 8 36 09 PM

Ideally the favicon and css would live in the coinstacks/common/api so that it can be referenced by each coinstack moving forward. We are using https://github.com/scottie1984/swagger-ui-express to generate the swagger doc ui which allows for custom styling options to be passed in.

Add unchained BTC support

Does what it says on the box.

Please involve community members and have them shadow you when completing this ticket, such that they are able to add more arbitrary chains in future.

Spike: Adding more UTXOs

Spike: Adding more UTXOs

  1. Scope the work needed and document an implementation plan in the comments on this issue
  2. Who will do the work
  3. Estimate how long it will take to complete
  4. Challenges or other considerations that are unique to this chain
  5. Create Github issues to track the work

API Controller type check errors

Currently all errors are being treated as axios errors, but this is an incorrect assumption and we should ultimately use proper type checking on errors (treating err as unknown) so we handle all error types correctly

Thorchain API: add /account and /send endpoints

The API is an adapter layer that provides a consistent set of endpoints for the ShapeShift client. Implement these endpoints using Bitcoin & Ethereum as a reference

/account/{pubkey}
/send

Ethereum: Ropsten Support

AC:

Veryify working coinstack locally (init.sh, readiness.sh)
Deploy to personal aws account
Update .circleci/config.yml to deploy develop and production public coinstacks
Steps:

Verify indexer.daemon.chain (specified in your copy of coinstacks/ethereum/pulumi/Pulumi.sample.yaml) parameter works correctly to deploy a local kubernetes instance of an ethereum ropsten coinstack
There will be pulumi resource naming conflicts that need to be handled. It would make the most sense to update the asset name in coinstack/ethereum/pulumi/index.ts to append the chain type if it is not mainnet.
Ensure signal catching works correctly still as defined in coinstacks/ethereum/daemon/init.sh (should work the same as mainnet node)
Ensure readiness check works as defined in coinstacks/ethereum/daemon/readiness.sh (should work the same as mainnet node)
Deploy and sync ethereum ropsten coinstack to personal aws account
Update .circleci/config.yml with jobs to deploy ethereum ropsten coinstacks to the develop and production environments, specifying the correct daemon-chain paramter

Coinstack network support

Currently the only notion of network is in the pulumi config under the daemon resource. This needs to be a more overarching idea for a coinstack that can be used in the pulumi iac as well as reference and returned from the app as an env var.

AC:

  • Don't attach chain network type to the daemon configuration, but instead configure it at the top level (important also if using a hosted node instead of own dedicated node)
  • Support chain network in .env that can be reference within the app (both docker-desktop or kube)
  • Add getNetwork() endpoint to the BaseAPI and support in current coinstacks

Spike: Adding Thorchain

Spike: Adding Thorchain

  1. Scope the work needed and document an implementation plan in the comments on this issue

  2. Identify challenges or other considerations that are unique to this chain

  3. Task breakdown & create Github issues to track the work

    1. Who will do the work
  4. Estimate how long it will take to complete

Thorchain specific:

  • start with balance, rune sends and receives before adding chain-specific features like swaps, etc

Thorchain Addition Checklist

Daemon

  • Update the Pulumi infra code, add init.sh and readiness.sh scripts
  • Thornode - both REST & WebSocket ports open
  • Midgard API
  • Merge and deploy to public cluster
  • more steps tbd

Indexer
The Indexer maintains an index of transaction history by address.

  • For Thorchain, use the node (daemon)

API
The API is an adapter layer that provides a consistent set of endpoints for the ShapeShift client. Implement these endpoints using Bitcoin & Ethereum as a reference

  • /account/{pubkey}
  • /account/{pubkey}/txs (deferred for Thorchain, get tx history from WebSocket during account sync)
  • /send
  • fees endpt

Ingester
The Ingester filters new transactions and sends only the relevant ones to each client

  • Get new blocks (WebSocket)
  • Get transactions from mempool (WebSocket)
  • Get transactions from confirmed blocks
  • Filter for transactions for addresses in the registry
  • Handle reorgs
  • Delta sync on register
  • Delta sync on new transaction
  • Client web sockets
  • Thorchain specific - parse trade details

**Tests **
Ingester:

  • newBlock worker: Block Reorg
  • Tx worker: Delta sync
  • Tx worker: parseTx

Bitcoin Ingester: register an address

Acceptance Criteria:

  1. The ingester registers an address from the client, scans all new mempool and confirmed transactions and puts them in the output message queue for client to consume (via websocket eventually)

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.