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

Commit

Permalink
Merge pull request #466 from magmo/adjudicator-watcher-common-data
Browse files Browse the repository at this point in the history
Server adjudicator watcher
  • Loading branch information
tomclose authored May 9, 2019
2 parents d6137b9 + 6ecab82 commit be9aba4
Show file tree
Hide file tree
Showing 33 changed files with 388 additions and 88 deletions.
14 changes: 12 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
"license": "MIT",
"scripts": {
"test:ci": "test:ci",
"build": "build"
}
"build": "build",
"heroku-postbuild": "npx lerna bootstrap"
},
"cacheDirectories": [
"node_modules",
"packages/wallet/node_modules",
"packages/server/node_modules",
"packages/magmo-wallet-client/node_modules",
"packages/rps/node_modules",
"packages/tictactoe/node_modules",
"packages/wallet-common/node_modules"
]
}
24 changes: 24 additions & 0 deletions packages/server/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Jest Chain Current",
"type": "node",
"request": "launch",
"args": [
"node_modules/.bin/jest",
"--runInBand",
"--env=jsdom",
"--config=${workspaceRoot}/config/jest/jest.chain.config.js",
"${relativeFile}"
],
"cwd": "${workspaceRoot}",
"protocol": "inspector",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
2 changes: 2 additions & 0 deletions packages/server/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web: cd packages/server && yarn start
adjudicator-watcher: cd packages/server && yarn start:adjudicator-watcher
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ process.env.NODE_ENV = 'test';
import * as supertest from 'supertest';
import app from '../../src/app/app';
import { HUB_ADDRESS, NAME, STAKE } from '../../src/constants';
import * as rpsArtifact from 'magmo-wallet-common/prebuilt-contracts/RockPaperScissorsGame.json';
import * as contracts from '../../src/utilities/contracts';

const BASE_URL = '/api/v1/rps_games';

Expand All @@ -17,7 +17,7 @@ describe('routes : rps_channels', () => {
address: HUB_ADDRESS,
games: [
{
rules_address: rpsArtifact.networks['3'].address,
rules_address: contracts.rpsGameArtifact.networks['3'].address,
stake: STAKE,
name: NAME,
},
Expand Down
5 changes: 5 additions & 0 deletions packages/server/bin/copy-client-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
parentPath=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )

cd "${parentPath}/.."
cp ../wallet/build/contracts/* build/contracts/
8 changes: 0 additions & 8 deletions packages/server/bin/splice-networks.sh

This file was deleted.

3 changes: 3 additions & 0 deletions packages/server/config/jest/jest.chain.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
var config = require('./jest.config');
config.testMatch = ['<rootDir>/src/**/__chain-test__/?(*.)test.ts?(x)'];
module.exports = config;
34 changes: 34 additions & 0 deletions packages/server/config/jest/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const { resolve } = require('path');
const root = resolve(__dirname, '../../');

module.exports = {
rootDir: root,
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}'],
setupFiles: [],
setupFilesAfterEnv: ['./src/config/knexSetupTeardown.ts'],
testMatch: ['<rootDir>/**/__test__/**/?(*.)(spec|test).ts'],
testEnvironment: 'node',
testURL: 'http://localhost',
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
transformIgnorePatterns: ['[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|ts|tsx)$'],
moduleFileExtensions: [
'web.ts',
'ts',
'web.tsx',
'tsx',
'web.js',
'js',
'web.jsx',
'jsx',
'json',
'node',
'mjs',
],
globals: {
'ts-jest': {
tsConfig: './tsconfig.json',
},
},
};
23 changes: 23 additions & 0 deletions packages/server/contracts/Migrations.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.5.0;

contract Migrations {
address public owner;
uint public last_completed_migration;

constructor() public {
owner = msg.sender;
}

modifier restricted() {
if (msg.sender == owner) _;
}

function setCompleted(uint completed) public restricted {
last_completed_migration = completed;
}

function upgrade(address new_address) public restricted {
Migrations upgraded = Migrations(new_address);
upgraded.setCompleted(last_completed_migration);
}
}
7 changes: 7 additions & 0 deletions packages/server/contracts/TestContract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pragma solidity ^0.5.0;
pragma experimental ABIEncoderV2;

import "fmg-core/contracts/Commitment.sol";
import "fmg-nitro-adjudicator/contracts/ConsensusCommitment.sol";
import "fmg-nitro-adjudicator/contracts/NitroAdjudicator.sol";
import "fmg-nitro-adjudicator/contracts/ConsensusApp.sol";
55 changes: 11 additions & 44 deletions packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,26 @@
"description": "nitro hub prototype",
"main": "lib/index.js",
"scripts": {
"splice-networks": "bin/splice-networks.sh",
"copy-client-contracts": "bin/copy-client-contracts.sh",
"db:drop": "dropdb server_wallet_${NODE_ENV}",
"db:create": "createdb server_wallet_${NODE_ENV}",
"db:migrate": "npx knex migrate:latest",
"db:rollback": "npx knex migrate:rollback",
"db:seed": "npx knex seed:run",
"test": "npx jest --runInBand",
"test:ci": "run-s prettier:check test",
"test:server": "npx jest --runInBand -c ./config/jest/jest.config.js",
"test:chain": "npx ganache-then-jest --runInBand -c ./config/jest/jest.chain.config.js",
"test:ci": "run-s contracts:clear prettier:check 'test:chain --all --ci' test:server",
"watch-server": "nodemon --watch 'src/**/*' -e ts,tsx --exec ts-node ./src/app/server.ts",
"build": "npx tsc && npx tsc knexfile.ts",
"start": "node ./lib/app/server.js",
"build": "tsc && npx tsc knexfile.ts",
"start": "run-s start:server",
"start:server": "node ./lib/app/server.js",
"start:adjudicator-watcher": "node lib/wallet/adjudicator-watcher/index.js",
"prestart": "npm run db:rollback && npm run db:migrate && npm run db:seed",
"prettier:check": "npx prettier --check 'src/**/*.{ts,tsx}'",
"prettier:write": "npx prettier --write 'src/**/*.{ts,tsx}'",
"postinstall": "npm run build"
"postinstall": "npm run build",
"contracts:clear": "rm -rf ./build/contracts",
"contracts:deploy": "npx deploy-contracts"
},
"author": "",
"license": "MIT",
Expand Down Expand Up @@ -64,43 +69,5 @@
"tslint-config": "^0.0.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.3.3"
},
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}"
],
"setupFiles": [],
"setupFilesAfterEnv": [
"./src/config/knexSetupTeardown.ts"
],
"testMatch": [
"<rootDir>/**/?(*.)(spec|test).ts"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.tsx?$": "ts-jest"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|ts|tsx)$"
],
"moduleFileExtensions": [
"web.ts",
"ts",
"web.tsx",
"tsx",
"web.js",
"js",
"web.jsx",
"jsx",
"json",
"node",
"mjs"
],
"globals": {
"ts-jest": {
"tsConfig": "./tsconfig.json"
}
}
}
}
14 changes: 8 additions & 6 deletions packages/server/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ $ curl -X POST -H "Content-Type: application/json" -H "Accept:application/json"
$ curl -X POST -H "Content-Type: application/json" -H "Accept:application/json" -d "$(cat samples/update_channel.rps.json)" http://localhost:3002/api/v1/rps_channels
```

### Playing against the server
### Interacting with the server from a browser

To play against the server from the client, the server's prebuilt contracts will need
to know the addresses of the deployed contracts on the local ganache network shared between this app and the client app.
To play against the server from the browser client, the server and the browser need to:

In addition to the above development setup, after deploying wallet contracts to your local ganache server, add the wallet artifact's network data to this project's prebuilt contracts:
- Point to the same local Ganache server.
- Point to the same contract addresses on Ganache.

In addition to the above development setup, after deploying wallet contracts to your local ganache server, copy the browser wallet built artifacts to this project:

```
chmod +x bin/splice-networks.sh
PATH_TO_WALLET_CONTRACTS=${PATH_TO_WALLET_PROJECT}/build/contracts yarn splice-networks
chmod +x bin/copy-client-contracts.sh
./bin/copy-client-contracts.sh
```

You will also need to make sure that the server's address has funds. You can find the server address in [constants.ts](https://github.com/magmo/node-bot/blob/master/src/constants.ts)
Expand Down
10 changes: 5 additions & 5 deletions packages/server/src/app/routes/rps_games.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Address, Uint256 } from 'fmg-core';
import * as koaBody from 'koa-body';
import * as Router from 'koa-router';

import { HUB_ADDRESS, NAME, STAKE } from '../../constants';
import * as contracts from '../../utilities/contracts';
import Wallet from '../../wallet';

export const BASE_URL = `/api/v1/rps_games`;
import { Address, Uint256 } from 'fmg-core';
import { HUB_ADDRESS, NAME, STAKE } from '../../constants';
import * as artifact from 'magmo-wallet-common/prebuilt-contracts/RockPaperScissorsGame.json';

const router = new Router();

Expand All @@ -18,7 +18,7 @@ interface Game {
router.get(`${BASE_URL}`, koaBody(), async ctx => {
try {
const applications = await new Wallet('').getApplications();
const { address } = applications.find(a => a.name === artifact.contractName);
const { address } = applications.find(a => a.name === contracts.rpsGameArtifact.contractName);

const games: Game[] = [
{
Expand Down
12 changes: 11 additions & 1 deletion packages/server/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const UNKNOWN_RULES_ADDRESS = '0x92b5b042047731FF882423cB555554F11F632Bd6

// TODO: These should be in the seed file, but they got exported as undefined for some reason
export const FUNDED_CHANNEL_NONCE = 3;
export const FUNDED_CHANNEL_HOLDINGS = '0x03';
export const FUNDED_CHANNEL_HOLDINGS = '0x00';

export const FUNDED_RPS_CHANNEL_NONCE = 33;
export const FUNDED_RPS_CHANNEL_HOLDINGS = '0x03';
Expand All @@ -46,6 +46,16 @@ export const SEEDED_PARTICIPANTS = SEEDED_CHANNELS * 2;
export const NONCE = 1000;
export const RPS_NONCE = 22222;

export const DUMMY_RULES_FUNDED_NONCE_CHANNEL_ID = '0xA401D66E18BD3918dAC8FAdc6F744219432eB150';
export const DUMMY_RULES_BEGINNING_APP_CHANNEL_NONCE_CHANNEL_ID =
'0xAB3085EF30eb526C3388D886c066714DF16Fd79D';
export const DUMMY_RULES_ONGOING_APP_CHANNEL_NONCE_CHANNEL_ID =
'0x04935CE33a179bF43125C9C23ee64F3b749E6246';
export const DUMMY_RULES_FUNDED_RPS_CHANNEL_NONCE_CHANNEL_ID =
'0xe18f12dF62979893E7B5a7914dFb3d8694258ae0';
export const DUMMY_RULES_BEGINNING_RPS_APP_CHANNEL_NONCE_CHANNEL_ID =
'0x52F42dE3f25051e31DF70199182A622f59a2072c';

export const STAKE: Uint256 = ethers.utils.parseEther('0.01').toHexString();
export const ALLOCATION: Uint256[] = ['0x05', '0x05'];
export const DESTINATION: Address[] = [PARTICIPANT_ADDRESS, HUB_ADDRESS];
Expand Down
28 changes: 28 additions & 0 deletions packages/server/src/utilities/contracts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as path from 'path';

const commonDataPrefix = 'magmo-wallet-common/prebuilt-contracts';
const devPathPrefix = '../../build/contracts';

const commitmentJson = 'Commitment.json';
const rulesJson = 'Rules.json';
const nitroAdjudicatorJson = 'NitroAdjudicator.json';
const rpsGameJson = 'RockPaperScissorsGame.json';

interface Artifact {
abi: any;
contractName: string;
networks: { [key: string]: { address: string } };
}

let commitmentArtifact: Artifact = require(path.join(commonDataPrefix, commitmentJson));
let rulesArtifact: Artifact = require(path.join(commonDataPrefix, rulesJson));
let nitroAdjudicatorArtifact: Artifact = require(path.join(commonDataPrefix, nitroAdjudicatorJson));
let rpsGameArtifact: Artifact = require(path.join(commonDataPrefix, rpsGameJson));

if (process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'development') {
commitmentArtifact = require(path.join(devPathPrefix, commitmentJson));
rulesArtifact = require(path.join(devPathPrefix, rulesJson));
nitroAdjudicatorArtifact = require(path.join(devPathPrefix, nitroAdjudicatorJson));
}

export { commitmentArtifact, rulesArtifact, nitroAdjudicatorArtifact, rpsGameArtifact };
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ethers } from 'ethers';
import { bigNumberify } from 'ethers/utils';
import { channelID } from 'fmg-core/lib/channel';
import { listen } from '..';
import AllocatorChannel from '../../models/allocatorChannel';
import { channel, depositContract } from './utils';

jest.setTimeout(60000);
const channelId = channelID(channel);
let removeListeners = null;

async function getHoldings() {
return (await AllocatorChannel.query()
.where('channel_id', channelId)
.first()
.select('holdings')).holdings;
}

describe('adjudicator listener', () => {
const provider: ethers.providers.JsonRpcProvider = new ethers.providers.JsonRpcProvider(
`http://localhost:${process.env.DEV_GANACHE_PORT}`,
);

it('should handle a funds received event when channel is in the database', async done => {
const preEventHoldings = await getHoldings();

const eventCallback = async eventType => {
const postEventHoldings = await getHoldings();

const eventDeposit = bigNumberify(postEventHoldings).sub(bigNumberify(preEventHoldings));
expect(eventDeposit.toNumber()).toBeGreaterThanOrEqual(5);
done();
};

removeListeners = await listen(eventCallback);
await depositContract(provider, channelId);
});
});

afterEach(() => {
removeListeners();
});
Loading

0 comments on commit be9aba4

Please sign in to comment.