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

Commit

Permalink
Merge branch 'master' into add-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
ArjunBhuptani committed Oct 5, 2020
2 parents 648b7bd + 754e7e1 commit 28af2e5
Show file tree
Hide file tree
Showing 118 changed files with 2,820 additions and 1,396 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*.docker-compose.yml
docker-compose.yml
modules/*/package-lock.json
config-prod.json

# Cache
**/.bot-store
Expand Down
43 changes: 31 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ commit=$(shell git rev-parse HEAD | head -c 8)
id=$(shell if [[ "`uname`" == "Darwin" ]]; then echo 0:0; else echo "`id -u`:`id -g`"; fi)

# Pool of images to pull cached layers from during docker build steps
image_cache=$(shell if [[ -n "${GITHUB_WORKFLOW}" ]]; then echo "--cache-from=$(project)_builder:latest,$(project)_database:latest,$(project)_ethprovider:latest,$(project)_server-node:latest,$(project)_router:latest,$(project)_proxy:latest"; else echo ""; fi)
image_cache=$(shell if [[ -n "${GITHUB_WORKFLOW}" ]]; then echo "--cache-from=$(project)_builder:latest,$(project)_database:latest,$(project)_ethprovider:latest,$(project)_server-node:latest,$(project)_router:latest,$(project)_global_proxy:latest,$(project)_node_proxy:latest,$(project)_router_proxy:latest"; else echo ""; fi)

interactive=$(shell if [[ -t 0 && -t 2 ]]; then echo "--interactive"; else echo ""; fi)

Expand All @@ -33,15 +33,16 @@ log_finish=@echo $$((`date "+%s"` - `cat $(startTime)`)) > $(totalTime); rm $(st
########################################
# Build Shortcuts

default: node router
default: router

global: auth ethprovider
node: global database proxy server-node
duet: global database server-node
trio: global database server-node router
global: auth ethprovider global-proxy
node: global database node-proxy server-node
router: node router-img router-proxy
duet: global node
trio: global node router
extras: test-runner

all: global node duet trio extras
all: global node router duet trio extras

########################################
# Command & Control Shortcuts
Expand Down Expand Up @@ -116,6 +117,7 @@ reset: stop-all
docker volume rm $(project)_database_dev 2> /dev/null || true
docker volume rm `docker volume ls -q -f name=$(project)_database_test_*` 2> /dev/null || true
rm -rf .chaindata/*
rm -rf *.docker-compose.yml

reset-images:
rm -f .flags/auth .flags/database .flags/ethprovider .flags/*proxy .flags/server-node
Expand Down Expand Up @@ -258,9 +260,14 @@ auth: auth-bundle $(shell find modules/auth/ops $(find_options))
docker tag $(project)_auth $(project)_auth:$(commit)
$(log_finish) && mv -f $(totalTime) .flags/$@

browser-node-bundle: engine $(shell find modules/browser-node $(find_options))
$(log_start)
$(docker_run) "cd modules/browser-node && npm run build && touch src/index.ts"
$(log_finish) && mv -f $(totalTime) .flags/$@

server-node-bundle: engine $(shell find modules/server-node $(find_options))
$(log_start)
$(docker_run) "cd modules/server-node && npm run build"
$(docker_run) "cd modules/server-node && npm run build && touch src/index.ts"
$(log_finish) && mv -f $(totalTime) .flags/$@

server-node: server-node-bundle $(shell find modules/server-node/ops $(find_options))
Expand All @@ -274,7 +281,7 @@ router-bundle: engine $(shell find modules/router $(find_options))
$(docker_run) "cd modules/router && npm run build"
$(log_finish) && mv -f $(totalTime) .flags/$@

router: router-bundle $(shell find modules/router/ops $(find_options))
router-img: router-bundle $(shell find modules/router/ops $(find_options))
$(log_start)
docker build --file modules/router/ops/Dockerfile $(image_cache) --tag $(project)_router modules/router
docker tag $(project)_router $(project)_router:$(commit)
Expand Down Expand Up @@ -306,8 +313,20 @@ ethprovider: contracts $(shell find modules/contracts/ops $(find_options))
docker tag $(project)_ethprovider $(project)_ethprovider:$(commit)
$(log_finish) && mv -f $(totalTime) .flags/$@

proxy: $(shell find ops/proxy $(find_options))
global-proxy: $(shell find ops/proxy $(find_options))
$(log_start)
docker build $(image_cache) --tag $(project)_global_proxy ops/proxy/global
docker tag $(project)_global_proxy $(project)_global_proxy:$(commit)
$(log_finish) && mv -f $(totalTime) .flags/$@

node-proxy: $(shell find ops/proxy $(find_options))
$(log_start)
docker build $(image_cache) --tag $(project)_node_proxy ops/proxy/node
docker tag $(project)_node_proxy $(project)_node_proxy:$(commit)
$(log_finish) && mv -f $(totalTime) .flags/$@

router-proxy: $(shell find ops/proxy $(find_options))
$(log_start)
docker build $(image_cache) --tag $(project)_proxy ops/proxy
docker tag $(project)_proxy $(project)_proxy:$(commit)
docker build $(image_cache) --tag $(project)_router_proxy ops/proxy/router
docker tag $(project)_router_proxy $(project)_router_proxy:$(commit)
$(log_finish) && mv -f $(totalTime) .flags/$@
139 changes: 126 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,96 @@ This monorepo contains a number of packages hoisted using lerna. Documentation f

Contents:

- [Architecture and Module Breakdown](#architecture-and-module-breakdown)
- [Quick Start](#quick-start)
- [Configuration API](#configuration-api)
- [Architecture and Module Breakdown](#architecture-and-module-breakdown)
- [Interacting with a vector node](#interacting-with-a-vector-node)
- [Development and Running Tests](#development-and-running-tests)
- Configuring Vector // TODO
- Deploying Vector to Production // TODO

## Quick start

**Prerequisites:**

- `make`: Probably already installed, otherwise install w `brew install make` or `apt install make` or similar.
- `jq`: Probably not installed yet, install w `brew install jq` or `apt install jq` or similar.
- `docker`: See the [Docker website](https://www.docker.com/) for installation instructions.

To start, clone & enter the Vector repo:

```bash
git clone https://github.com/connext/vector.git
cd vector
```

To build everything and deploy a Vector node in dev-mode, run the following:

```bash
make start

# view the node's logs
bash ops/logs.sh node
```

That's all! But beware: the first time `make start` is run, it will take a very long time (maybe 10 minutes, depends on your internet speed) but have no fear: downloads will be cached & most build steps won't ever need to be repeated again so subsequent `make start` runs will go much more quickly. Get this started asap & browse the rest of the README while the first `make start` runs.

By default, Vector will launch using two local chains (ganache with chain id `1337` and `1338`) but you can also run a local Vector stack against a public chain (or multiple chains!) such as Rinkeby. To do so, edit the `chainProviders` and `chainAddresses` fields of `config.json` according to the chain you want to support.

Note: this will start a local Connext node pointed at a remote chain, so make sure the mnemonic used to start your node is funded in the appropriate native currencies and supported chain assets. By default, the node starts with the account:

```node
mnemonic: "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat";
privateKey: "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3";
address: "0x627306090abaB3A6e1400e9345bC60c78a8BEf57";
```

To apply updates to `config.json`, you'll need to restart your vector node with `make restart`.

(`make start`/`make restart` are aliases for `make start-node`/`make restart-node`)

Four different Vector stacks are supported:

- `global`: standalone messaging service (+ EVMs in dev-mode)
- `node`: vector node + database
- `router`: vector node + router + database
- `duet`: 2x node/db pairs, used to test one-on-one node interactions
- `trio`: 2x node/db pairs + 1x node/router/db , used to test node interactions via a routing node.

For any of these stacks, you can manage them with:

- `make ${stack}` eg `make duet` builds everything required by the given stack
- `make start-${stack}` eg `make start-router` will start up the router stack.
- `make stop-${stack}` stops the stack
- `make restart-${stack}` stops the stack if it's running & starts it again
- `make test-${stack}` runs unit tests against some stack. It will build & start the stack if that hasn't been done already.

## Configuration API

The `node` and `router` stacks are configurable via the `config-node.json` and `config-router.json` files respectively. Note that the `duet` and `trio` stacks are designed exclusively for development/testing so these are not configurable.

There is an additional `config-prod.json` file that can apply to either the node or router but not both. The `config-prod.json` file contains your domain name and, because it's _not_ tracked by git, it's a good place to put overrides for secret values like API keys. A prod-mode deployment using a domain name w https must be exposed on port 443, therefore only a single prod-mode stack can run on a given machine at a time.

The formats of `config-node.json` and `config-router.json` overlap almost entirely because the router stack also contains a `node` internally. They are separated to allow you to run & separately configure both a node & a router on the same machine.

### Configuration API

- `adminToken` (type: `string`): Currently, this is only used during development to protect a few admin endpoints eg to reset the database between tests. If/when we add admin-only features in prod, they will only be accessible to those who provide the correct adminToken.
- `allowedSwaps` (type: `object`): Specifies which swaps are allowed & how swap rates are determined.
- `authUrl` (type: `string`): The url used to authenticate with the messaging service (TODO: merge this with the nats url?)
- `awsAccessId` (type: `string`): An API KEY id that specifies credentials for a remote AWS S3 bucket for storing db backups
- `awsAccessKey` (type: `string`): An API KEY secret that to authenticate on a remote AWS S3 bucket for storing db backups.
- `production` (type: `boolean`): Enables prod-mode if true.
- Dev-mode ops are designed to automatically build anything that isn't available locally before starting up a given stack.
- Prod-mode ops are designed to build nothing. Any required docker images will be pulled from docker-hub. Prod-mode is optimized for keeping your machine's disk clean & free from unnecessary build artifacts.
- `logLevel` (type: `string`): one of `"debug"`, `"info"`, `"warn"`, `"error"` to specify the maximum log level that will be printed.
- `chainAddresses` (type: `object`): Specifies the addresses of all relevant contracts, keyed by `chainId`.
- `chainProviders` (type: `object`): Specifies the URL to use to connect to each chain's provider, keyed by `chainId`
- `domainName` (type: `string`): If provided, https will be auto-configured & the stack will be exposed on port 443.
- `natsUrl` (type: `string`): The URL of the messaging service (TODO: merge with auth url?)
- `port` (type: `number`): The port number on which the stack should be exposed to the outside world.
- `redisUrl` (type: `string`): The URL of the redis instance used to negotiate channel-locks.
- `rebalanceProfiles` (type: `object`): Specifies the thresholds & target while collateralizing some `assetId` on some `chainId`.

## Architecture and Module Breakdown

Vector uses a layered-approach to compartmentalize risk and delegate tasks throughout protocol usage. In general, lower layers are not context-aware of higher level actions. Information flows downwards through call params and upwards through events. The only exception to this are services, which are set up at the services layer and passed down to the protocol directly.
Expand All @@ -40,7 +124,7 @@ You can find documentation on each layer in its respective readme:

Note that the engine and protocol are isomorphic. Immediately after the core implementation is done, we plan to build a `browser-node` implementation which sets up services in a browser-compatible way and exposes a direct JS interface to be consumed by a dApp developer.

## Quick Start
## Interacting with a vector node

This quick start will guide you through getting to a simple e2e transfer flow between two peers running [server-nodes](https://github.com/connext/vector/tree/master/modules/server-node) (Alice, Bob) that is routed through one intermediary routing node (Roger).

Expand Down Expand Up @@ -77,7 +161,8 @@ Content-Type: application/json
{
"counterpartyIdentifier": "{{alicePublicIdentifier}}",
"chainId": "{{chainId}}",
"timeout": "36000"
"timeout": "36000",
"publicIdentifier": "{{nodePublicIdentifier}}"
}
### Node -> Bob
Expand All @@ -87,7 +172,8 @@ Content-Type: application/json
{
"counterpartyIdentifier": "{{bobPublicIdentifier}}",
"chainId": "{{chainId}}",
"timeout": "36000"
"timeout": "36000",
"publicIdentifier": "{{nodePublicIdentifier}}"
}
```

Expand All @@ -100,7 +186,8 @@ Content-Type: application/json
{
"channelAddress": "{{aliceNodeChannel}}",
"amount": "{{ethAmount}}",
"assetId": "0x0000000000000000000000000000000000000000"
"assetId": "0x0000000000000000000000000000000000000000",
"publicIdentifier": "{{alicePublicIdentifier}}"
}
```

Expand All @@ -112,42 +199,45 @@ Content-Type: application/json
{
"channelAddress": "{{aliceNodeChannel}}",
"assetId": "0x0000000000000000000000000000000000000000"
"assetId": "0x0000000000000000000000000000000000000000",
"publicIdentifier": "{{alicePublicIdentifier}}"
}
```

Then, create a transfer between Alice and Bob through Roger (in [3_transfer](https://github.com/connext/vector/blob/master/modules/server-node/examples/3-transfer.http)):

```
POST {{aliceUrl}}/linked-transfer/create
POST {{aliceUrl}}/hashlock-transfer/create
Content-Type: application/json
{
"conditionType": "LinkedTransfer",
"conditionType": "HashlockTransfer",
"channelAddress": "{{aliceNodeChannel}}",
"amount": "{{ethAmount}}",
"assetId": "0x0000000000000000000000000000000000000000",
"details": {
"linkedHash": "{{linkedHash}}"
"lockHash": "{{lockHash}}"
},
"routingId": "{{routingId}}",
"recipient": "{{bobPublicIdentifier}}",
"meta": {
"hello": "world"
}
},
"publicIdentifier": "{{alicePublicIdentifier}}"
}
```

Lastly, unlock the transfer for Bob to get his funds:

```
POST {{bobUrl}}/linked-transfer/resolve
POST {{bobUrl}}/hashlock-transfer/resolve
Content-Type: application/json
{
"channelAddress": "{{aliceBobChannel}}",
"routingId": "{{routingId}}",
"preImage": "{{preImage}}"
"preImage": "{{preImage}}",
"publicIdentifier": "{{bobPublicIdentifier}}"
}
```

Expand Down Expand Up @@ -232,6 +322,29 @@ await node.on(
);
```

#### Indexed Engines

To enable the SDK to work with an indexed engine, you can specify an `index` param in the `connect` method.

### Managing Multiple Private Keys

In most cases, the `server-node` manages a single private key and signs all channel operations with this key. In some cases, users will want the ability to manage multiple private keys and multiple instances of `engine`s`.

This functionality is possible in the `server-node` by deriving private keys from the mnemonic in the `server-node`'s config ([more info](https://medium.com/@wolovim/ethereum-201-hd-wallets-11d0c93c87f7)). By default, the `server-node` creates an engine at the index path "0" for convenience.

Below is an example of creating a new Engine instance. The `index` param is an integer between 0 and 2147483647 (2\*\*32):

```
POST {{aliceUrl}}/node
Content-Type: application/json
{
"index": 1234
}
```

The response to this request contains a `signerAddress` and `publicIdentifier`. Additional calls to the server node must include the `publicIdentifier` to specify which `engine` to use.

## Development and Running Tests

You can build the whole stack by running `make`.
Expand Down
28 changes: 28 additions & 0 deletions config-node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"adminToken": "cxt1234",
"authUrl": "http://auth:5040",
"logLevel": "info",
"chainAddresses": {
"1337": {
"channelFactoryAddress": "0xF12b5dd4EAD5F743C6BaA640B0216200e89B60Da",
"channelMastercopyAddress": "0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0",
"hashlockTransferAddress": "0x345cA3e014Aaf5dcA488057592ee47305D9B3e10",
"withdrawAddress": "0xf25186B5081Ff5cE73482AD761DB0eB0d25abfBF",
"TestToken": "0x8f0483125FCb9aaAEFA9209D8E9d7b9C8B9Fb90F"
},
"1338": {
"channelFactoryAddress": "0xF12b5dd4EAD5F743C6BaA640B0216200e89B60Da",
"channelMastercopyAddress": "0x8CdaF0CD259887258Bc13a92C0a6dA92698644C0",
"hashlockTransferAddress": "0x345cA3e014Aaf5dcA488057592ee47305D9B3e10",
"withdrawAddress": "0xf25186B5081Ff5cE73482AD761DB0eB0d25abfBF",
"TestToken": "0x8f0483125FCb9aaAEFA9209D8E9d7b9C8B9Fb90F"
}
},
"chainProviders": {
"1337": "http://evm_1337:8545",
"1338": "http://evm_1338:8545"
},
"natsUrl": "nats://nats:4222",
"port": 3000,
"redisUrl": "redis://redis:6379"
}
6 changes: 6 additions & 0 deletions config-prod.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"awsAccessId": "",
"awsAccessKey": "",
"domainName": "",
"production": false
}
Loading

0 comments on commit 28af2e5

Please sign in to comment.