Skip to content
This repository has been archived by the owner on Mar 8, 2022. It is now read-only.

Commit

Permalink
refactor rpc.controller will match whale rpc.controller (#10)
Browse files Browse the repository at this point in the history
* refactor rpc.controller will match whale rpc.controller
added docker router for whale and playground

* test stub.client.ts

* fixed unit test

* refactor playground setup to be state-aware

* added code docs

* fixed playground test

* updated with traefik health check

* added logging

* individual wait for
  • Loading branch information
fuxingloh authored May 26, 2021
1 parent 0ebecb0 commit 4252905
Show file tree
Hide file tree
Showing 17 changed files with 436 additions and 266 deletions.
10 changes: 8 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,14 @@ jobs:
- name: Setup docker containers
run: docker-compose -f __sanity__/docker-compose.yml up -d

- name: Wait for
run: ./__sanity__/wait-for http://localhost:3000/_health/probes/liveness -t 120
- name: Wait for :3001/_health/probes/liveness
run: ./__sanity__/wait-for http://localhost:3001/_health/probes/liveness -t 120

- name: Wait for :3002/_health/probes/liveness
run: ./__sanity__/wait-for http://localhost:3002/_health/probes/liveness -t 120

- name: Wait for :8082/ping
run: ./__sanity__/wait-for http://localhost:8082/ping -t 120

- name: Sanity testing
uses: matt-ball/newman-action@0659e9b8d056c0d03d94e1dbfce380512088b566
Expand Down
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,76 @@

DeFi playground for DeFi Blockchain engineers to build DeFi applications without running your own node.

## Running DeFi Playground

`docker-compose.yml`

```yaml
version: '3.7'

services:
traefik:
image: traefik:v2.4
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:3000"
ports:
- "3000:3000"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"

defi-blockchain:
image: defi/defichain:1.7.0
command: >
defid
-printtoconsole
-rpcallowip=0.0.0.0/0
-rpcbind=0.0.0.0
-rpcuser=playground-rpcuser
-rpcpassword=playground-rpcpassword
-masternode_operator=mswsMVsyGMj1FzDMbbxw2QW3KvQAv2FKiy
-regtest=1
-txnotokens=0
-logtimemicros
-txindex=1
-acindex=1
-amkheight=0
-bayfrontheight=1
-bayfrontgardensheight=2
-clarkequayheight=3
-dakotaheight=4
-dakotacrescentheight=5
-eunosheight=6
defi-whale:
image: ghcr.io/defich/whale:latest
depends_on:
- defi-blockchain
environment:
WHALE_DEFID_URL: http://playground-rpcuser:playground-rpcpassword@defi-blockchain:19554
WHALE_DATABASE_PROVIDER: memory
WHALE_NETWORK: playground
labels:
- "traefik.http.routers.whale.priority=1"
- "traefik.http.routers.whale.rule=PathPrefix(`/{version:v[1-9]}/playground/`)"
- "traefik.http.routers.whale.entrypoints=web"
- "traefik.http.services.whale.loadbalancer.server.port=3000"

defi-playground:
image: ghcr.io/defich/playground:latest
depends_on:
- defi-blockchain
environment:
PLAYGROUND_DEFID_URL: http://playground-rpcuser:playground-rpcpassword@defi-blockchain:19554
labels:
- "traefik.http.routers.playground.priority=0"
- "traefik.http.routers.playground.rule=PathPrefix(`/{version:v[1-9]}/playground/rpc/`)"
- "traefik.http.routers.playground.entrypoints=web"
- "traefik.http.services.playground.loadbalancer.server.port=3000"
```
## Developing & Contributing
Thanks for contributing, appreciate all the help we can get. Feel free to make a pull-request, we will guide you along
Expand Down
38 changes: 32 additions & 6 deletions __sanity__/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
version: '3.7'

services:
defi-blockchain:
image: defi/defichain:1.6.4
traefik:
image: traefik:v2.4
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:3000"
- "--entrypoints.ping.address=:8082"
- "--ping.entryPoint=ping"
ports:
- "19554:19554"
- "3000:3000"
- "8080:8080"
- "8082:8082"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"

defi-blockchain:
image: defi/defichain:1.7.0
command: >
defid
-printtoconsole
Expand All @@ -24,22 +37,35 @@ services:
-clarkequayheight=3
-dakotaheight=4
-dakotacrescentheight=5
-eunosheight=6
defi-whale:
image: ghcr.io/defich/whale:latest
depends_on:
- defi-blockchain
ports:
- "3001:3000"
environment:
WHALE_DEFID_URL: http://playground-rpcuser:playground-rpcpassword@defi-blockchain:19554
WHALE_NETWORK: regtest
WHALE_DATABASE_PROVIDER: memory
WHALE_NETWORK: playground
labels:
- "traefik.http.routers.whale.priority=1"
- "traefik.http.routers.whale.rule=PathPrefix(`/{version:v[1-9]}/playground/`)"
- "traefik.http.routers.whale.entrypoints=web"
- "traefik.http.services.whale.loadbalancer.server.port=3000"

defi-playground:
build: ..
image: ghcr.io/defich/playground:latest
ports:
- "3000:3000"
depends_on:
- defi-blockchain
ports:
- "3002:3000"
environment:
PLAYGROUND_DEFID_URL: http://playground-rpcuser:playground-rpcpassword@defi-blockchain:19554
labels:
- "traefik.http.routers.playground.priority=0"
- "traefik.http.routers.playground.rule=PathPrefix(`/{version:v[1-9]}/playground/rpc/`)"
- "traefik.http.routers.playground.entrypoints=web"
- "traefik.http.services.playground.loadbalancer.server.port=3000"
49 changes: 6 additions & 43 deletions __sanity__/postman_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,7 @@
},
"item": [
{
"name": "/_health/probes/liveness",
"event": [
{
"listen": "test",
"script": {
"exec": [
"pm.test(\"Status code is 200\", function () {",
" pm.response.to.have.status(200);",
"});",
"",
"pm.test(\"Status in JSON body is ok\", function () {",
" var jsonData = pm.response.json();",
" pm.expect(jsonData.status).to.eql(\"ok\");",
"});"
],
"type": "text/javascript"
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:3000/_health/probes/liveness",
"protocol": "http",
"host": [
"localhost"
],
"port": "3000",
"path": [
"_health",
"probes",
"liveness"
]
}
},
"response": []
},
{
"name": "/v1/rpc/getblockchaininfo",
"name": "/v1/playground/rpc/getblockchaininfo",
"event": [
{
"listen": "test",
Expand All @@ -68,14 +29,15 @@
"method": "POST",
"header": [],
"url": {
"raw": "http://localhost:3000/v1/rpc/getblockchaininfo",
"raw": "http://localhost:3000/v1/playground/rpc/getblockchaininfo",
"protocol": "http",
"host": [
"localhost"
],
"port": "3000",
"path": [
"v1",
"playground",
"rpc",
"getblockchaininfo"
]
Expand All @@ -84,7 +46,7 @@
"response": []
},
{
"name": "/v1/rpc/getblockhash",
"name": "/v1/playground/rpc/getblockhash",
"event": [
{
"listen": "test",
Expand Down Expand Up @@ -116,14 +78,15 @@
}
},
"url": {
"raw": "http://localhost:3000/v1/rpc/getblockhash",
"raw": "http://localhost:3000/v1/playground/rpc/getblockhash",
"protocol": "http",
"host": [
"localhost"
],
"port": "3000",
"path": [
"v1",
"playground",
"rpc",
"getblockhash"
]
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"test": "jest",
"test:ci": "jest --ci --coverage --maxWorkers=3",
"test:ci": "jest --ci --coverage --maxWorkers=4",
"packages:build": "lerna run build",
"packages:version": "lerna version $1 --yes --no-push --no-git-tag-version",
"packages:publish:next": "lerna exec -- npm publish --tag next --access public",
Expand Down
2 changes: 1 addition & 1 deletion packages/playground-api-client/__tests__/api/rpc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ afterAll(async () => {
it('should throw error on invalid params', async () => {
await expect(
client.rpc.call('getblock', [{ block: 1 }], 'number')
).rejects.toThrow('400 - BadRequest (/v1/rpc/getblock): RpcApiError: \'JSON value is not a string as expected\', code: -1, method: getblock')
).rejects.toThrow('400 - BadRequest (/v1/playground/rpc/getblock): RpcApiError: \'JSON value is not a string as expected\', code: -1, method: getblock')
})

describe('whitelisted rpc methods', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/playground-api-client/__tests__/stub.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class StubPlaygroundApiClient extends PlaygroundApiClient {

const res = await this.service.app.inject({
method: method,
url: `/v1/${path}`,
url: `/v1/playground/${path}`,
payload: body,
headers: method !== 'GET' ? { 'Content-Type': 'application/json' } : {}
})
Expand Down
4 changes: 2 additions & 2 deletions packages/playground-api-client/src/playground.api.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface PlaygroundApiClientOptions {
* PlaygroundApiClient default options
*/
export const DefaultOptions: PlaygroundApiClientOptions = {
url: 'https://playground.ocean.defichain.com',
url: 'https://ocean.defichain.com',
timeout: 60000,
version: 'v1'
}
Expand Down Expand Up @@ -128,7 +128,7 @@ export class PlaygroundApiClient {
*/
async requestAsString (method: Method, path: string, body?: string): Promise<ResponseAsString> {
const { url: urlString, version, timeout } = this.options
const url = `${urlString}/${version as string}/${path}`
const url = `${urlString}/${version as string}/playground/${path}`

const controller = new AbortController()
const id = setTimeout(() => controller.abort(), timeout)
Expand Down
2 changes: 1 addition & 1 deletion src/module.api/rpc.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class CallRequest {
params?: any[]
}

@Controller('/v1/rpc')
@Controller('/v1/playground/rpc')
export class RpcController {
constructor (private readonly client: JsonRpcClient) {
}
Expand Down
38 changes: 25 additions & 13 deletions src/module.playground/_module.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { Global, Module, OnApplicationBootstrap } from '@nestjs/common'
import { PlaygroundToken } from '@src/module.playground/playground.token'
import { PlaygroundDex } from '@src/module.playground/playground.dex'
import { Global, Logger, Module, OnApplicationBootstrap } from '@nestjs/common'
import { SetupToken } from '@src/module.playground/setup/setup.token'
import { SetupDex } from '@src/module.playground/setup/setup.dex'
import { PlaygroundProbeIndicator } from '@src/module.playground/playground.indicator'
import { JsonRpcClient } from '@defichain/jellyfish-api-jsonrpc'
import { PlaygroundBlock } from '@src/module.playground/playground.block'
import { Playground } from '@src/module.playground/playground'
import { PlaygroundSetup } from '@src/module.playground/setup/setup'

@Global()
@Module({
providers: [
PlaygroundToken,
PlaygroundDex,
SetupToken,
SetupDex,
PlaygroundBlock,
PlaygroundProbeIndicator
],
Expand All @@ -19,21 +19,33 @@ import { Playground } from '@src/module.playground/playground'
]
})
export class PlaygroundModule implements OnApplicationBootstrap {
private readonly logger = new Logger(PlaygroundModule.name)

private readonly setups: Array<PlaygroundSetup<any>>

constructor (
private readonly token: PlaygroundToken,
private readonly dex: PlaygroundDex,
private readonly client: JsonRpcClient,
private readonly indicator: PlaygroundProbeIndicator
private readonly indicator: PlaygroundProbeIndicator,
token: SetupToken, dex: SetupDex
) {
this.setups = [
token,
dex
]
}

async onApplicationBootstrap (): Promise<void> {
await this.waitForDeFiD()
await this.client.call('importprivkey', [Playground.MN_KEY.owner.privKey, 'coinbase'], 'number')
await this.client.call('importprivkey', [Playground.MN_KEY.operator.privKey, 'coinbase'], 'number')

await this.token.init()
await this.dex.init()
this.logger.log('setup started')
await this.client.call('importprivkey', [PlaygroundSetup.MN_KEY.owner.privKey, 'coinbase'], 'number')
await this.client.call('importprivkey', [PlaygroundSetup.MN_KEY.operator.privKey, 'coinbase'], 'number')

for (const setup of this.setups) {
await setup.setup()
}

this.logger.log('setup completed')
this.indicator.ready = true
}

Expand Down
9 changes: 6 additions & 3 deletions src/module.playground/playground.block.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Interval } from '@nestjs/schedule'
import { Injectable } from '@nestjs/common'
import { Injectable, Logger } from '@nestjs/common'
import { JsonRpcClient } from '@defichain/jellyfish-api-jsonrpc'
import { Playground } from '@src/module.playground/playground'
import { PlaygroundSetup } from '@src/module.playground/setup/setup'

@Injectable()
export class PlaygroundBlock {
private readonly logger = new Logger(PlaygroundBlock.name)

constructor (private readonly client: JsonRpcClient) {
}

@Interval(3000)
async generate (): Promise<void> {
await this.client.call('generatetoaddress', [1, Playground.address, 1], 'number')
await this.client.call('generatetoaddress', [1, PlaygroundSetup.address, 1], 'number')
this.logger.log('generated new block')
}
}
Loading

0 comments on commit 4252905

Please sign in to comment.