mirror of https://github.com/embarklabs/embark.git
Attempting to fix tests
Tests are not working currently, however given the current changes, the non-test functionality of the proxy is still working correctly.
This commit is contained in:
parent
b5aa508992
commit
9239c91492
|
@ -52,6 +52,7 @@ export interface Config {
|
|||
rpcCorsDomain: string;
|
||||
wsRPC: boolean;
|
||||
isDev: boolean;
|
||||
client: string;
|
||||
};
|
||||
webServerConfig: {
|
||||
certOptions: {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class Ganache {
|
||||
constructor(embark) {
|
||||
embark.events.request('proxy:vm:register', () => {
|
||||
embark.events.request('blockchain:vm:register', () => {
|
||||
const ganache = require('ganache-cli');
|
||||
return ganache.provider();
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@ export default class EthSubscribe extends RpcModifier {
|
|||
|
||||
private async ethSubscribeRequest(params: any, callback: Callback<any>) {
|
||||
// check for eth_subscribe and websockets
|
||||
if (params.isWs && params.request.method.includes("eth_subscribe")) {
|
||||
if (params.isWs && params.request.method === "eth_subscribe") {
|
||||
// indicate that we do not want this call to go to the node
|
||||
params.sendToNode = false;
|
||||
return callback(null, params);
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
import { Callback, Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
|
||||
import Web3RequestManager from "web3-core-requestmanager";
|
||||
import { __ } from "embark-i18n";
|
||||
import Web3 from "web3";
|
||||
import RpcModifier from "./rpcModifier";
|
||||
|
||||
export default class EthUnsubscribe extends RpcModifier {
|
||||
|
||||
private nodeSubscriptions: object = {};
|
||||
constructor(embark: Embark, rpcModifierEvents: Events) {
|
||||
super(embark, rpcModifierEvents);
|
||||
|
||||
|
@ -16,7 +13,7 @@ export default class EthUnsubscribe extends RpcModifier {
|
|||
|
||||
private async ethUnsubscribeRequest(params: any, callback: Callback<any>) {
|
||||
// check for eth_subscribe and websockets
|
||||
if (params.isWs && params.request.method.includes("eth_unsubscribe")) {
|
||||
if (params.isWs && params.request.method === "eth_unsubscribe") {
|
||||
// indicate that we do not want this call to go to the node
|
||||
params.sendToNode = false;
|
||||
return callback(null, params);
|
||||
|
|
|
@ -9,30 +9,42 @@ class BlockchainClient {
|
|||
|
||||
this.blockchainClients = {};
|
||||
this.client = null;
|
||||
this.vms = [];
|
||||
this.events.setCommandHandler("blockchain:client:register", (clientName, blockchainClient) => {
|
||||
this.blockchainClients[clientName] = blockchainClient;
|
||||
this.client = blockchainClient;
|
||||
});
|
||||
this.events.setCommandHandler("blockchain:vm:register", (handler) => {
|
||||
this.vms.push(handler);
|
||||
});
|
||||
|
||||
// TODO: unclear currently if this belongs here so it's a bit hardcoded for now
|
||||
this.events.setCommandHandler("blockchain:client:provider", (clientName, cb) => {
|
||||
this.events.request("proxy:endpoint:get", (err, endpoint) => {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
if (endpoint.startsWith('ws')) {
|
||||
return cb(null, new Web3.providers.WebsocketProvider(endpoint, {
|
||||
headers: {Origin: constants.embarkResourceOrigin},
|
||||
// TODO remove this when Geth fixes this: https://github.com/ethereum/go-ethereum/issues/16846
|
||||
// Edit: This has been fixed in Geth 1.9, but we don't support 1.9 yet and still support 1.8
|
||||
clientConfig: {
|
||||
fragmentationThreshold: 81920
|
||||
}
|
||||
}));
|
||||
}
|
||||
const web3 = new Web3(endpoint);
|
||||
cb(null, web3.currentProvider);
|
||||
});
|
||||
this.events.setCommandHandler("blockchain:client:nodeProvider", async (clientName, endpoint, cb) => {
|
||||
if (!cb) {
|
||||
cb = endpoint;
|
||||
endpoint = null;
|
||||
}
|
||||
if (clientName === constants.blockchain.vm) {
|
||||
return cb(null, this.vms[this.vms.length - 1]());
|
||||
}
|
||||
let provider;
|
||||
try {
|
||||
provider = await this._getProvider(clientName, endpoint);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(`Error getting provider: ${err.message || err}`);
|
||||
}
|
||||
cb(null, provider);
|
||||
});
|
||||
this.events.setCommandHandler("blockchain:client:provider", async (clientName, cb) => {
|
||||
let provider;
|
||||
try {
|
||||
provider = await this._getProvider(clientName);
|
||||
}
|
||||
catch (err) {
|
||||
return cb(`Error getting provider: ${err.message || err}`);
|
||||
}
|
||||
cb(null, provider);
|
||||
});
|
||||
|
||||
// TODO: maybe not the ideal event to listen to?
|
||||
|
@ -46,7 +58,28 @@ class BlockchainClient {
|
|||
// set default account
|
||||
});
|
||||
}
|
||||
|
||||
async _getProvider(clientName, endpoint) {
|
||||
// Passing in an endpoint allows us to customise which URL the provider connects to.
|
||||
// If no endpoint is providing, the provider will connect to the proxy.
|
||||
// Explicity setting an endpoint is useful for cases where we want to connect directly
|
||||
// to the node (ie in the proxy).
|
||||
if (!endpoint) {
|
||||
// will return the proxy URL
|
||||
endpoint = await this.events.request2("proxy:endpoint:get");
|
||||
}
|
||||
if (endpoint.startsWith('ws')) {
|
||||
return new Web3.providers.WebsocketProvider(endpoint, {
|
||||
headers: { Origin: constants.embarkResourceOrigin },
|
||||
// TODO remove this when Geth fixes this: https://github.com/ethereum/go-ethereum/issues/16846
|
||||
// Edit: This has been fixed in Geth 1.9, but we don't support 1.9 yet and still support 1.8
|
||||
clientConfig: {
|
||||
fragmentationThreshold: 81920
|
||||
}
|
||||
});
|
||||
}
|
||||
const web3 = new Web3(endpoint);
|
||||
return web3.currentProvider;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BlockchainClient;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
|
||||
import {__} from "embark-i18n";
|
||||
import { Embark, Events } /* supplied by @types/embark in packages/embark-typings */ from "embark";
|
||||
import { __ } from "embark-i18n";
|
||||
import { buildUrl, findNextPort } from "embark-utils";
|
||||
import { Logger } from 'embark-logger';
|
||||
import { Proxy } from "./proxy";
|
||||
|
@ -18,6 +18,8 @@ export default class ProxyManager {
|
|||
private ready = false;
|
||||
private isWs = false;
|
||||
private vms: any[];
|
||||
private _endpoint: string = "";
|
||||
private portsSetup: boolean = false;
|
||||
|
||||
constructor(private embark: Embark, options: any) {
|
||||
this.logger = embark.logger;
|
||||
|
@ -50,19 +52,28 @@ export default class ProxyManager {
|
|||
|
||||
this.events.setCommandHandler("proxy:endpoint:get", async (cb) => {
|
||||
await this.onReady();
|
||||
if (!this.embark.config.blockchainConfig.proxy) {
|
||||
return cb(null, this.embark.config.blockchainConfig.endpoint);
|
||||
cb(null, (await this.endpoint));
|
||||
});
|
||||
}
|
||||
|
||||
private get endpoint() {
|
||||
return (async () => {
|
||||
if (this._endpoint) {
|
||||
return this._endpoint;
|
||||
}
|
||||
if (!this.embark.config.blockchainConfig.proxy) {
|
||||
this._endpoint = this.embark.config.blockchainConfig.endpoint;
|
||||
return this._endpoint;
|
||||
}
|
||||
await this.setupPorts();
|
||||
// TODO Check if the proxy can support HTTPS, though it probably doesn't matter since it's local
|
||||
if (this.isWs) {
|
||||
return cb(null, buildUrl("ws", this.host, this.wsPort, "ws"));
|
||||
this._endpoint = buildUrl("ws", this.host, this.wsPort, "ws");
|
||||
return this._endpoint;
|
||||
}
|
||||
cb(null, buildUrl("http", this.host, this.rpcPort, "rpc"));
|
||||
});
|
||||
|
||||
this.events.setCommandHandler("proxy:vm:register", (handler: any) => {
|
||||
this.vms.push(handler);
|
||||
});
|
||||
this._endpoint = buildUrl("http", this.host, this.rpcPort, "rpc");
|
||||
return this._endpoint;
|
||||
})();
|
||||
}
|
||||
|
||||
public onReady() {
|
||||
|
@ -76,50 +87,65 @@ export default class ProxyManager {
|
|||
});
|
||||
}
|
||||
|
||||
private async setupPorts() {
|
||||
if (this.portsSetup) {
|
||||
return;
|
||||
}
|
||||
const port = await findNextPort(this.embark.config.blockchainConfig.rpcPort + constants.blockchain.servicePortOnProxy);
|
||||
this.portsSetup = true;
|
||||
|
||||
this.rpcPort = port;
|
||||
this.wsPort = port + 1;
|
||||
this.isWs = this.embark.config.blockchainConfig.client === constants.blockchain.vm || (/wss?/).test(this.embark.config.blockchainConfig.endpoint);
|
||||
}
|
||||
|
||||
private async setupProxy(clientName: string) {
|
||||
await this.setupPorts();
|
||||
if (!this.embark.config.blockchainConfig.proxy) {
|
||||
return;
|
||||
}
|
||||
if (this.httpProxy || this.wsProxy) {
|
||||
throw new Error("Proxy is already started");
|
||||
}
|
||||
const port = await findNextPort(this.embark.config.blockchainConfig.rpcPort + constants.blockchain.servicePortOnProxy);
|
||||
|
||||
this.rpcPort = port;
|
||||
this.wsPort = port + 1;
|
||||
this.isWs = clientName === constants.blockchain.vm || (/wss?/).test(this.embark.config.blockchainConfig.endpoint);
|
||||
const endpoint = this.embark.config.blockchainConfig.endpoint;
|
||||
let isVm = false;
|
||||
|
||||
// using simulator, ie tests
|
||||
if (clientName === constants.blockchain.vm) {
|
||||
this.isWs = true;
|
||||
isVm = true;
|
||||
}
|
||||
|
||||
// HTTP
|
||||
if (clientName !== constants.blockchain.vm) {
|
||||
this.httpProxy = await new Proxy({
|
||||
endpoint: this.embark.config.blockchainConfig.endpoint,
|
||||
endpoint,
|
||||
events: this.events,
|
||||
isWs: false,
|
||||
logger: this.logger,
|
||||
plugins: this.plugins,
|
||||
vms: this.vms,
|
||||
plugins: this.plugins
|
||||
})
|
||||
.serve(
|
||||
this.host,
|
||||
this.rpcPort,
|
||||
);
|
||||
.serve(
|
||||
this.host,
|
||||
this.rpcPort,
|
||||
);
|
||||
this.logger.info(`HTTP Proxy for node endpoint ${this.embark.config.blockchainConfig.endpoint} listening on ${buildUrl("http", this.host, this.rpcPort, "rpc")}`);
|
||||
}
|
||||
if (this.isWs) {
|
||||
const endpoint = clientName === constants.blockchain.vm ? constants.blockchain.vm : this.embark.config.blockchainConfig.endpoint;
|
||||
this.wsProxy = await new Proxy({
|
||||
endpoint,
|
||||
events: this.events,
|
||||
isWs: true,
|
||||
logger: this.logger,
|
||||
plugins: this.plugins,
|
||||
vms: this.vms,
|
||||
clientName
|
||||
})
|
||||
.serve(
|
||||
this.host,
|
||||
this.wsPort,
|
||||
);
|
||||
this.logger.info(`WS Proxy for node endpoint ${endpoint} listening on ${buildUrl("ws", this.host, this.wsPort, "ws")}`);
|
||||
.serve(
|
||||
this.host,
|
||||
this.wsPort,
|
||||
);
|
||||
this.logger.info(`WS Proxy for node endpoint ${isVm ? 'vm' : endpoint} listening on ${buildUrl("ws", this.host, this.wsPort, "ws")}`);
|
||||
}
|
||||
}
|
||||
private stopProxy() {
|
||||
|
|
|
@ -17,41 +17,35 @@ export class Proxy {
|
|||
this.timeouts = {};
|
||||
this.plugins = options.plugins;
|
||||
this.logger = options.logger;
|
||||
this.vms = options.vms;
|
||||
this.app = null;
|
||||
this.endpoint = options.endpoint;
|
||||
this.events = options.events;
|
||||
|
||||
if (options.endpoint === constants.blockchain.vm) {
|
||||
this.endpoint = this.vms[this.vms.length - 1]();
|
||||
}
|
||||
|
||||
let provider = null;
|
||||
|
||||
if (typeof this.endpoint === 'string' && this.endpoint.startsWith('ws')) {
|
||||
provider = this._createWebSocketProvider();
|
||||
} else {
|
||||
provider = this.endpoint;
|
||||
}
|
||||
this.isWs = options.isWs;
|
||||
// used to service all non-long-living WS connections, including any
|
||||
// request that is not WS and any WS request that is not an `eth_subscribe`
|
||||
// RPC request
|
||||
this.requestManager = this._createWeb3RequestManager(provider);
|
||||
this.clientName = options.clientName;
|
||||
this.nodeSubscriptions = {};
|
||||
this._requestManager = null;
|
||||
|
||||
this.events.setCommandHandler("proxy:websocket:subscribe", this.handleSubscribe.bind(this));
|
||||
this.events.setCommandHandler("proxy:websocket:unsubscribe", this.handleUnsubscribe.bind(this));
|
||||
}
|
||||
|
||||
_createWebSocketProvider() {
|
||||
return new Web3WsProvider(this.endpoint, {
|
||||
headers: { Origin: constants.embarkResourceOrigin },
|
||||
// TODO remove this when Geth fixes this: https://github.com/ethereum/go-ethereum/issues/16846
|
||||
// Edit: This has been fixed in Geth 1.9, but we don't support 1.9 yet and still support 1.8
|
||||
clientConfig: {
|
||||
fragmentationThreshold: 81920
|
||||
// used to service all non-long-living WS connections, including any
|
||||
// request that is not WS and any WS request that is not an `eth_subscribe`
|
||||
// RPC request
|
||||
get requestManager() {
|
||||
return (async () => {
|
||||
if (!this._requestManager) {
|
||||
const provider = await this._createWebSocketProvider(this.endpoint);
|
||||
this._requestManager = this._createWeb3RequestManager(provider);
|
||||
}
|
||||
});
|
||||
return this._requestManager;
|
||||
})();
|
||||
}
|
||||
|
||||
async _createWebSocketProvider(endpoint) {
|
||||
// pass in endpoint to ensure we get a provider with a connection to the node
|
||||
// this may return a VM provider during tests, in which case endpoint will be ignored
|
||||
return this.events.request2("blockchain:client:nodeProvider", this.clientName /* TODO: test that this returns "vm" or "ethereum" */, endpoint);
|
||||
}
|
||||
|
||||
_createWeb3RequestManager(provider) {
|
||||
|
@ -60,7 +54,8 @@ export class Proxy {
|
|||
|
||||
async nodeReady() {
|
||||
try {
|
||||
await this.requestManager.send({ method: 'eth_accounts' });
|
||||
const reqMgr = await this.requestManager;
|
||||
await reqMgr.send({ method: 'eth_accounts' });
|
||||
} catch (e) {
|
||||
throw new Error(__(`Unable to connect to the blockchain endpoint on ${this.endpoint}`));
|
||||
}
|
||||
|
@ -169,8 +164,9 @@ export class Proxy {
|
|||
}
|
||||
|
||||
forwardRequestToNode(request) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.requestManager.send(request, (fwdReqErr, result) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const reqMgr = await this.requestManager;
|
||||
reqMgr.send(request, (fwdReqErr, result) => {
|
||||
if (fwdReqErr) {
|
||||
return reject(fwdReqErr);
|
||||
}
|
||||
|
@ -180,8 +176,9 @@ export class Proxy {
|
|||
}
|
||||
|
||||
async handleSubscribe(clientSocket, request, response, cb) {
|
||||
const provider = await this._createWebSocketProvider(this.endpoint);
|
||||
// creates a new long-living connection to the node
|
||||
const currentReqManager = this._createWeb3RequestManager(this._createWebSocketProvider());
|
||||
const currentReqManager = this._createWeb3RequestManager(provider);
|
||||
|
||||
// kill WS connetion to the node when the client connection closes
|
||||
clientSocket.on('close', () => currentReqManager.provider.disconnect());
|
||||
|
|
|
@ -224,9 +224,9 @@ class TestRunner {
|
|||
const ogAccounts = this.simOptions.accounts;
|
||||
Object.assign(this.simOptions, {host, port, type, protocol, accounts, client: config.blockchain && config.blockchain.client});
|
||||
|
||||
if (!resetServices && !deepEqual(accounts, ogAccounts)) {
|
||||
return this.plugins.emitAndRunActionsForEvent("accounts:reseted", {accounts}, cb);
|
||||
}
|
||||
// if (!resetServices && !deepEqual(accounts, ogAccounts)) {
|
||||
// return this.plugins.emitAndRunActionsForEvent("accounts:reseted", {accounts}, cb);
|
||||
// }
|
||||
|
||||
if (!resetServices) {
|
||||
return cb();
|
||||
|
|
Loading…
Reference in New Issue