Skip to content

Commit

Permalink
POC refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
kaladinlight committed Dec 17, 2021
1 parent 5878646 commit 11996c0
Show file tree
Hide file tree
Showing 173 changed files with 35,468 additions and 2,445 deletions.
19 changes: 18 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,18 @@
.vscode/launch.json
# Project specific
config.json

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2021 ShapeShift

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
108 changes: 96 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,100 @@
# Cosmos SDK chain support in Unchained
Add support for cosmos and cosmos-sdk chains
# Introduction

## Tech
- golang v1.17
[![ShapeShift](https://img.shields.io/badge/ShapeShift%20DAO-Unchained-386ff9?logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNTdweCIgaGVpZ2h0PSI2MnB4IiB2aWV3Qm94PSIwIDAgNTcgNjIiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDU1LjEgKDc4MTM2KSAtIGh0dHBzOi8vc2tldGNoYXBwLmNvbSAtLT4KICAgIDx0aXRsZT5NYXJrPC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGcgaWQ9Ik1vY2stVXBzIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4KICAgICAgICA8ZyBpZD0iTGFuZGluZy1QYWdlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNzY5LjAwMDAwMCwgLTc2LjAwMDAwMCkiIGZpbGw9IiNGRkZGRkUiPgogICAgICAgICAgICA8ZyBpZD0iTmF2IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3OS4wMDAwMDAsIDY5LjAwMDAwMCkiPgogICAgICAgICAgICAgICAgPGcgaWQ9IlNTX2hvcml6b250YWxfV2hpdGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDY5MC4wNTY4MDAsIDcuNTgxNDUxKSI+CiAgICAgICAgICAgICAgICAgICAgPGcgaWQ9Ik1hcmsiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuNDM0Mzk1LCAwLjM1NjgwOCkiPgogICAgICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNTEuNjY5Njg1Myw1LjEwMzg0NDE5IEw0OC45Njk3MzM5LDIxLjI5OTQ3NzkgTDM5LjM3MDY4MjcsOS45OTYyMTIxMiBMNTEuNjY5Njg1Myw1LjEwMzg0NDE5IFogTTQ5LjAyNzkzMjYsMjguMjY1MTUxNSBMNTEuNDMwODM4MSwzNy4xNDE1NjQzIEwzMy4wNTcyOTQxLDQyLjIwNDQxNzUgTDQ5LjAyNzkzMjYsMjguMjY1MTUxNSBaIE05LjAzMTAzMjQzLDIzLjgwNDEyMDYgTDE4Ljg4MTk2NzMsMTAuOTI3ODI1NiBMMzUuOTg5MTA4OSwxMC45Mjc4MjU2IEw0Ni45MjM0Njk3LDIzLjgwNDEyMDYgTDkuMDMxMDMyNDMsMjMuODA0MTIwNiBaIE00NS42NTcwNjcyLDI2Ljk4NTU4MDUgTDI3Ljg0NTAyMzcsNDIuNTMwOTQ4IEw5LjcwMjg3NzU1LDI2Ljk4NTU4MDUgTDQ1LjY1NzA2NzIsMjYuOTg1NTgwNSBaIE0xNS41ODMyNjgzLDEwLjAwNTUyODMgTDYuNzgwODQwMTUsMjEuNTEwOTU0MSBMNC4wNzc2Mjk2Myw1LjE2NjI2MjI5IEwxNS41ODMyNjgzLDEwLjAwNTUyODMgWiBNMjIuNTY5NDMzMyw0Mi4xOTkyOTM2IEw0LjAyMDgyNzc2LDM3LjE0NTc1NjYgTDYuNTYyNDc4ODQsMjguNDg0MDgwNyBMMjIuNTY5NDMzMyw0Mi4xOTkyOTM2IFogTTI1Ljk5NDMwNjksNDYuNDI5NzUwMiBMMjIuNDkyNjExMSw1MC4yODQzMDA4IEMxOS41MjU0MTE1LDQ3LjQ2NDc3MjcgMTYuMjYzMDI4NCw0NC45NjEwNjE2IDEyLjc4MDQyMTcsNDIuODI5NTMwMSBMMjUuOTk0MzA2OSw0Ni40Mjk3NTAyIFogTTQyLjk3ODA2NzQsNDIuNzcwODM4NSBDMzkuNDk1NDYwNiw0NC45MzY4Mzk3IDM2LjI0MDk5MjYsNDcuNDczMTU3MiAzMy4yOTI0MTY2LDUwLjMxOTcwMjEgTDI5LjcxNjY5MjEsNDYuNDI0NjI2MyBMNDIuOTc4MDY3NCw0Mi43NzA4Mzg1IFogTTU1LjczNDI3ODQsMC4wNjI4ODM5MDY2IEwzNi40MTk3Nzg4LDcuNzQ2MzY1NjggTDE4LjQxNzc3NSw3Ljc0NjM2NTY4IEw5Ljk0NzU5ODNlLTE0LC04LjE3MTI0MTQ2ZS0xNCBMNC4xODM3ODM5NiwyNS4yOTU2MzM3IEwwLjE2NjIxNTMyMSwzOC45ODgwMjIxIEwxMC42NDgwMjM1LDQ1LjI1NzMxNDcgQzE1LjYxMDczODEsNDguMjI1OTAwOSAyMC4wNTYxODMxLDUxLjk0MDI0MzcgMjMuODYwNTExOSw1Ni4yOTY0NjgxIEwyNy45NDE4NjYzLDYwLjk2OTkwNjggTDMyLjIyNTI4NjMsNTYuMDU1MTgwMiBDMzUuOTAwNjQ2OSw1MS44Mzc3NjYyIDQwLjE4MDgwNzgsNDguMjE3NTE2NCA0NC45NDY1NzgyLDQ1LjI5NDU3OTIgTDU1LjIyNTg1NTEsMzguOTg4MDIyMSBMNTEuNTIzOTU1OSwyNS4zMTQyNjYgTDU1LjczNDI3ODQsMC4wNjI4ODM5MDY2IEw1NS43MzQyNzg0LDAuMDYyODgzOTA2NiBaIiBpZD0iRmlsbC0xNiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+)](https://github.com/shapeshift/go-unchained) [![ShapeShift](https://img.shields.io/badge/License-MIT-brightgreen)](https://github.com/shapeshift/go-unchained/blob/main/LICENSE) [![ShapeShift](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://github.com/shapeshift/go-unchained/pulls)

## Running
- Install golang
- Copy sample.launch.json to .vscode and update with any keys etc
- cmd/cosmos is main for Cosmos
- cmd/osmosis is main for Osmosis
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)

## Design
- The core functionality of chains like Osmosis and Thorchain is identical to Cosmos
- We can write the Cosmos SDK implementation once, and provide mechanisms to inject chain specific behavior (additional protos, support for custom messages and event logs, custom API routes etc)
## Table Of Contents

- [Helpful Docs](#helpful-docs)
- [Project Structure](#project-structure)
- [Coin Stack Components](#coin-stack-components)
- [Dependencies](#dependencies)
- [Notes](#notes)
- [Initial Setup](#initial-setup)
- [Ports](#ports)
- [Docker-Compose Local Dev Instructions](#docker-compose-local-dev-instructions)
- [Prerequisites](#prerequisites)
- [Running](#running)
- [Kubernetes Local Dev Instructions](#kubernetes-local-dev-instructions)
- [Docker Desktop (macOS)](docs/docker-desktop.md)
- [Minikube (Linux)](docs/minikube.md)

## Helpful Docs

- [Pulumi](https://www.pulumi.com/docs/)
- [Kubernetes](https://kubernetes.io/docs/home/)
- [OpenAPI](https://github.com/OAI/OpenAPI-Specification)

## Project Structure

- `internal` - internal utility packages
- `pkg` - shared common packages across coinstacks
- `coinstacks/{coin}` - coin specific logic

## Coin Stack Components

- **Blockchain Full Node** - coin specific daemon providing historical blockchain data (ie. bitcoind, geth, etc)
- **Indexer** - indexes transaction and balance history by address (if not provided by the node directly)
- **Common API** - a [REST API](https://api.cosmos.shapeshift.com/docs/) that provides necessary data to a client in a common format across all blockchains

![Coin Stack Architecture](docs/coinstack.png)

## Dependencies

- [Golang](https://go.dev/doc/install)
- [Docker](https://docs.docker.com/get-docker/)

## Notes

- The cosmos coinstack is used in all examples. If you wish to run a different coinstack, just replace `cosmos` with the coinstack name you wish to run
- All paths are relative to the root unchained directory (ex. `go-unchained/{path}`)

## Initial Setup

- Install [Node.js LTS](https://nodejs.org/en/)
- (Optional) use nvm to automatically install the node version specified in `.nvmrc`
```sh
nvm use
```

## 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.bitcoin.localhost`
- `mongo.bitcoin.localhost`
- `rabbit-admin.bitcoin.localhost`

## Docker-Compose Local Dev Instructions

#### _Lightweight local development environment_

#### **Prerequisites**

- Install [docker-compose](https://docs.docker.com/compose/install/)
- Copy sample config file:
```sh
cp cmd/cosmos/sample.config.json cmd/cosmos/config.json
```
- Fill out any missing config variables

#### **Running**

- To start up the reverse proxy and hot reloading for files run from the root of the project
```sh
docker-compose up
```

- To spin up a coinstack:
```sh
cd coinstacks/cosmos && docker-compose up
```
- To completely tear down the coinstack (including docker volumes):
```sh
cd coinstacks/cosmos && docker-compose down -v
```
5 changes: 5 additions & 0 deletions build/Dockerfile.local
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM golang:1.17.5

RUN go install github.com/cespare/reflex@latest

ENTRYPOINT ["reflex", "-s"]
83 changes: 52 additions & 31 deletions cmd/cosmos/main.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,71 @@
package main

import (
// "net/http"
// _ "net/http/pprof"
"flag"
"os"
"os/signal"
"syscall"

codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/shapeshift/unchained-cosmos/server/rest"
"github.com/shapeshift/unchained-cosmos/service"
log "github.com/sirupsen/logrus"
"github.com/shapeshift/go-unchained/coinstacks/cosmos/api"
"github.com/shapeshift/go-unchained/internal/config"
"github.com/shapeshift/go-unchained/internal/log"
"github.com/shapeshift/go-unchained/pkg/cosmos"
)

func main() {
log.Debug("")
start()
var logger = log.WithoutFields()

var confPath = flag.String("config", "cmd/cosmos/config.json", "path to configuration file")

// Config for running application
type Config struct {
APIKey string `mapstructure:"apiKey"`
GRPCURL string `mapstructure:"grpcUrl"`
LCDURL string `mapstructure:"lcdUrl"`
RPCURL string `mapstructure:"rpcUrl"`
}

func start() {
// where to listen
restListenAddr := os.Getenv("REST_LISTEN_ADDR")
if restListenAddr == "" {
restListenAddr = "localhost:1660"
func main() {
flag.Parse()

errChan := make(chan error, 1)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

conf := &Config{}
if err := config.Load(*confPath, conf); err != nil {
logger.Panic(err)
}

config := service.ChainConfig{
CosmosBase: os.Getenv("COSMOS_BASE"),
TendermintBase: os.Getenv("TENDERMINT_BASE"),
ApiKey: os.Getenv("DATAHUB_API_KEY"),
GRPCBase: os.Getenv("GRPC_BASE"),
RestListenAddr: restListenAddr,
Bech32PrefixAccAddr: "cosmos",
Bech32PrefixAccPub: "cosmospub",
RegisterTypes: func(registry codectypes.InterfaceRegistry) {
// cosmos so all stock protos
},
encoding := cosmos.NewEncoding()

cfg := cosmos.Config{
APIKey: conf.APIKey,
Bech32AddrPrefix: "cosmos",
Bech32PkPrefix: "cosmospub",
Encoding: encoding,
GRPCURL: conf.GRPCURL,
LCDURL: conf.LCDURL,
RPCURL: conf.RPCURL,
}

service, err := service.NewCosmosService(config)
httpClient, err := cosmos.NewHTTPClient(cfg)
if err != nil {
log.Errorf("dumping config: %#v", config)
log.Fatalf("error creating CosmosService: %s", err)
logger.Panic(err)
}

srv, err := rest.New(service, config)
grpcClient, err := cosmos.NewGRPCClient(cfg)
if err != nil {
log.Fatal("error starting http server: %s", err)
logger.Panic(err)
}
defer grpcClient.Shutdown()

go api.Start(httpClient, grpcClient, errChan)

select {
case err := <-errChan:
logger.Panic(err)
case <-sigChan:
grpcClient.Shutdown()
os.Exit(0)
}
log.Infof("got srv: %#v", srv)
}
6 changes: 6 additions & 0 deletions cmd/cosmos/sample.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"lcdUrl": "https://cosmoshub-4--lcd--archive.datahub.figment.io",
"grpcUrl": "cosmoshub-4--grpc--archive.grpc.datahub.figment.io:443",
"rpcUrl": "https://cosmoshub-4--rpc--archive.datahub.figment.io",
"apiKey": ""
}
87 changes: 59 additions & 28 deletions cmd/osmosis/main.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,75 @@
package main

import (
// "net/http"
// _ "net/http/pprof"
"flag"
"os"
"os/signal"
"syscall"

"github.com/shapeshift/unchained-cosmos/osmosis"
"github.com/shapeshift/unchained-cosmos/server/rest"
"github.com/shapeshift/unchained-cosmos/service"
log "github.com/sirupsen/logrus"
gammtypes "github.com/osmosis-labs/osmosis/x/gamm/types"
lockuptypes "github.com/osmosis-labs/osmosis/x/lockup/types"
"github.com/shapeshift/go-unchained/coinstacks/osmosis/api"
"github.com/shapeshift/go-unchained/internal/config"
"github.com/shapeshift/go-unchained/internal/log"
"github.com/shapeshift/go-unchained/pkg/cosmos"
)

func main() {
start()
var logger = log.WithoutFields()

var confPath = flag.String("config", "cmd/osmosis/config.json", "path to configuration file")

type Config struct {
APIKey string `mapstructure:"apiKey"`
GRPCURL string `mapstructure:"grpcUrl"`
LCDURL string `mapstructure:"lcdUrl"`
RPCURL string `mapstructure:"rpcUrl"`
}

func start() {
// where to listen
restListenAddr := os.Getenv("REST_LISTEN_ADDR")

config := service.ChainConfig{
CosmosBase: os.Getenv("COSMOS_BASE"),
TendermintBase: os.Getenv("TENDERMINT_BASE"),
ApiKey: os.Getenv("DATAHUB_OSMO_API_KEY"),
GRPCBase: os.Getenv("GRPC_BASE"),
RestListenAddr: restListenAddr,
Bech32PrefixAccAddr: "osmo",
Bech32PrefixAccPub: "osmopub",
RegisterTypes: osmosis.RegisterTypes,
EventHandler: osmosis.OsmosisEventHandler,
func main() {
flag.Parse()

errChan := make(chan error, 1)
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)

conf := &Config{}
if err := config.Load(*confPath, conf); err != nil {
logger.Panic(err)
}

service, err := service.NewCosmosService(config)
encoding := cosmos.NewEncoding(
gammtypes.RegisterInterfaces,
lockuptypes.RegisterInterfaces,
)

cfg := cosmos.Config{
APIKey: conf.APIKey,
Bech32AddrPrefix: "osmo",
Bech32PkPrefix: "osmopub",
Encoding: encoding,
GRPCURL: conf.GRPCURL,
LCDURL: conf.LCDURL,
RPCURL: conf.RPCURL,
}

httpClient, err := cosmos.NewHTTPClient(cfg)
if err != nil {
log.Errorf("dumping config: %#v", config)
log.Fatalf("error creating CosmosService: %s", err)
logger.Panic(err)
}
srv, err := rest.New(service, config)

grpcClient, err := cosmos.NewGRPCClient(cfg)
if err != nil {
log.Fatal("error starting http server: %s", err)
logger.Panic(err)
}
defer grpcClient.Shutdown()

go api.Start(httpClient, grpcClient, errChan)

select {
case err := <-errChan:
logger.Panic(err)
case <-sigChan:
grpcClient.Shutdown()
os.Exit(0)
}
log.Infof("got srv: %#v", srv)
}
6 changes: 6 additions & 0 deletions cmd/osmosis/sample.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"lcdUrl": "https://osmosis-1--lcd--archive.datahub.figment.io",
"grpcUrl": "osmosis-1--grpc--archive.grpc.datahub.figment.io:443",
"rpcUrl": "https://osmosis-1--rpc--archive.datahub.figment.io",
"apiKey": ""
}
Loading

0 comments on commit 11996c0

Please sign in to comment.