Skip to content

Commit 6db8d87

Browse files
jrainvilleiurimatias
authored andcommitted
feat(@embark/nethermind): add Nethermind blockchain client plugin
1 parent 4190d5e commit 6db8d87

File tree

23 files changed

+1022
-14
lines changed

23 files changed

+1022
-14
lines changed

packages/core/core/src/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export class Config {
7777

7878
version: string;
7979

80+
locale: string;
81+
8082
shownNoAccountConfigMsg = false; // flag to ensure "no account config" message is only displayed once to the user
8183

8284
corsParts: string[] = [];
@@ -95,6 +97,7 @@ export class Config {
9597
this.configDir = options.configDir || DEFAULT_CONFIG_PATH;
9698
this.chainsFile = options.chainsFile;
9799
this.plugins = options.plugins;
100+
this.locale = options.locale || 'en';
98101
this.logger = options.logger;
99102
this.package = options.package;
100103
this.events = options.events;

packages/core/core/src/plugin.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,6 @@ export class Plugin {
138138
this._loggerObject[type](this.name + ':', ...[].slice.call(arguments, 1));
139139
}
140140

141-
setUpLogger() {
142-
this.logger = new Logger({});
143-
}
144-
145141
isContextValid() {
146142
if (this.currentContext.includes(constants.contexts.any) || this.acceptedContext.includes(constants.contexts.any)) {
147143
return true;
@@ -161,9 +157,6 @@ export class Plugin {
161157
return false;
162158
}
163159
this.loaded = true;
164-
if (this.shouldInterceptLogs) {
165-
this.setUpLogger();
166-
}
167160
if (isEs6Module(this.pluginModule)) {
168161
if (this.pluginModule.default) {
169162
this.pluginModule = this.pluginModule.default;

packages/core/engine/src/index.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,16 @@ export class Engine {
8585
const options = _options || {};
8686
this.events = options.events || this.events || new Events();
8787
this.logger = this.logger || new Logger({context: this.context, logLevel: options.logLevel || this.logLevel || 'info', events: this.events, logFile: this.logFile});
88-
this.config = new Config({env: this.env, logger: this.logger, events: this.events, context: this.context, webServerConfig: this.webServerConfig, version: this.version, package: this.package});
88+
this.config = new Config({
89+
env: this.env,
90+
logger: this.logger,
91+
events: this.events,
92+
context: this.context,
93+
webServerConfig: this.webServerConfig,
94+
version: this.version,
95+
package: this.package,
96+
locale: this.locale
97+
});
8998
this.config.loadConfigFiles({embarkConfig: this.embarkConfig, interceptLogs: this.interceptLogs});
9099
this.plugins = this.config.plugins;
91100
this.isDev = this.config && this.config.blockchainConfig && (this.config.blockchainConfig.isDev || this.config.blockchainConfig.default);

packages/core/utils/src/check.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const WebSocket = require("ws");
2+
const http = require("http");
3+
const https = require("https");
4+
5+
const LIVENESS_CHECK=`{"jsonrpc":"2.0","method":"web3_clientVersion","params":[],"id":42}`;
6+
7+
const parseAndRespond = (data, cb) => {
8+
let resp;
9+
try {
10+
resp = JSON.parse(data);
11+
if (resp.error) {
12+
return cb(resp.error);
13+
}
14+
} catch (e) {
15+
return cb('Version data is not valid JSON');
16+
}
17+
if (!resp || !resp.result) {
18+
return cb('No version returned');
19+
}
20+
const [_, version, __] = resp.result.split('/');
21+
cb(null, version);
22+
};
23+
24+
const testRpcWithEndpoint = (endpoint, cb) => {
25+
const options = {
26+
method: "POST",
27+
timeout: 1000,
28+
headers: {
29+
"Content-Type": "application/json",
30+
"Content-Length": Buffer.byteLength(LIVENESS_CHECK)
31+
}
32+
};
33+
34+
let obj = http;
35+
if (endpoint.startsWith('https')) {
36+
obj = https;
37+
}
38+
39+
const req = obj.request(endpoint, options, (res) => {
40+
let data = "";
41+
res.on("data", chunk => { data += chunk; });
42+
res.on("end", () => parseAndRespond(data, cb));
43+
});
44+
req.on("error", (e) => cb(e));
45+
req.write(LIVENESS_CHECK);
46+
req.end();
47+
};
48+
49+
const testWsEndpoint = (endpoint, cb) => {
50+
const conn = new WebSocket(endpoint);
51+
conn.on("message", (data) => {
52+
parseAndRespond(data, cb);
53+
conn.close();
54+
});
55+
conn.on("open", () => conn.send(LIVENESS_CHECK));
56+
conn.on("error", (e) => cb(e));
57+
};
58+
59+
module.exports = {
60+
testWsEndpoint,
61+
testRpcWithEndpoint
62+
};

packages/core/utils/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const clipboardy = require('clipboardy');
66
import { canonicalHost } from './host';
77
export { canonicalHost, defaultCorsHost, defaultHost, dockerHostSwap, isDocker } from './host';
88
export { downloadFile, findNextPort, getJson, httpGet, httpsGet, httpGetJson, httpsGetJson, pingEndpoint } from './network';
9+
export { testRpcWithEndpoint, testWsEndpoint } from './check';
910
const logUtils = require('./log-utils');
1011
export const escapeHtml = logUtils.escapeHtml;
1112
export const normalizeInput = logUtils.normalizeInput;

packages/embark/src/cmd/cmd_controller.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,22 @@ class EmbarkController {
5858
});
5959

6060
engine.init({}, () => {
61+
Object.assign(engine.config.blockchainConfig, { isStandalone: true });
62+
6163
engine.registerModuleGroup("coreComponents");
6264
engine.registerModuleGroup("blockchainStackComponents");
6365
engine.registerModuleGroup("blockchain");
6466

67+
// load custom plugins
68+
engine.loadDappPlugins();
69+
let pluginList = engine.plugins.listPlugins();
70+
if (pluginList.length > 0) {
71+
engine.logger.info(__("loaded plugins") + ": " + pluginList.join(", "));
72+
}
73+
6574
engine.startEngine(async () => {
6675
try {
67-
const alreadyStarted = await engine.events.request2("blockchain:node:start", Object.assign(engine.config.blockchainConfig, { isStandalone: true }));
76+
const alreadyStarted = await engine.events.request2("blockchain:node:start", engine.config.blockchainConfig);
6877
if (alreadyStarted) {
6978
engine.logger.warn(__('Blockchain process already started. No need to run `embark blockchain`'));
7079
process.exit(0);

packages/embark/src/test/config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ describe('embark.Config', function () {
167167
},
168168
"datadir": ".embark/extNetwork/datadir",
169169
"rpcHost": "mynetwork.com",
170-
"rpcPort": undefined,
170+
"rpcPort": false,
171171
"rpcCorsDomain": {
172172
"auto": true,
173173
"additionalCors": []

packages/plugins/ethereum-blockchain-client/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class EthereumBlockchainClient {
6464
const code = contract.code.substring(0, 2) === '0x' ? contract.code : "0x" + contract.code;
6565
const contractObject = contractObj.deploy({arguments: (contract.args || []), data: code});
6666
if (contract.gas === 'auto' || !contract.gas) {
67-
const gasValue = await contractObject.estimateGas();
67+
const gasValue = await contractObject.estimateGas({value: 0, from: account});
6868
const increase_per = 1 + (Math.random() / 10.0);
6969
contract.gas = Math.floor(gasValue * increase_per);
7070
}

packages/plugins/geth/src/blockchain.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Blockchain {
3535
this.config = {
3636
silent: this.userConfig.silent,
3737
client: this.userConfig.client,
38-
ethereumClientBin: this.userConfig.ethereumClientBin || this.userConfig.client,
38+
ethereumClientBin: this.userConfig.ethereumClientBin,
3939
networkType: this.userConfig.networkType || clientClass.DEFAULTS.NETWORK_TYPE,
4040
networkId: this.userConfig.networkId || clientClass.DEFAULTS.NETWORK_ID,
4141
genesisBlock: this.userConfig.genesisBlock || false,

packages/plugins/geth/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Geth {
1212
this.embarkConfig = embark.config.embarkConfig;
1313
this.blockchainConfig = embark.config.blockchainConfig;
1414
this.communicationConfig = embark.config.communicationConfig;
15+
// TODO get options from config instead of options
1516
this.locale = options.locale;
1617
this.logger = embark.logger;
1718
this.client = options.client;

packages/plugins/nethermind/.npmrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
engine-strict = true
2+
package-lock = false
3+
save-exact = true
4+
scripts-prepend-node-path = true

packages/plugins/nethermind/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# `embark-nethermind`
2+
3+
> Nethermind blockchain client plugin for Embark
4+
5+
6+
## Quick docs
7+
8+
To configure the Netherminds client, you can use the Embark configs as always, or for more control, use the Nethermind config files.
9+
To change them, go in your Netherminds directory, then in `configs/`. There, you will see all the configuration files for the different networks.
10+
If you ever need to run a different network than dev, testnet or mainnet, you can change it in the Embark blockchain configuration by changing the `networkType` to the name of the config file, without the `.cfg`.
11+
Eg: For the Goerli network, just put `networkType: 'goerli`
12+
Note: The dev mode of Netherminds is called `ndm` and the config file is `ndm_consumer_local.cfg`. Using `miningMode: 'dev'` automatically translates to using that config file.
13+
14+
## Websocket support
15+
16+
Even though Nethermind supports Websocket connections, it does not support `eth_subscribe`, so you will not be able to use contract events.
17+
Also, please note that you will need to change the `endpoint` in the blockchain configuration to `ws://localhost:8545/ws/json-rpc` when working in local. Do change the port or the host to whatever you need.
18+
19+
Visit [embark.status.im](https://embark.status.im/) to get started with
20+
[Embark](https://github.com/embark-framework/embark).
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"name": "embark-nethermind",
3+
"version": "5.0.0-alpha.9",
4+
"author": "Iuri Matias <iuri.matias@gmail.com>",
5+
"contributors": [],
6+
"description": "Nethermind blockchain client plugin for Embark",
7+
"homepage": "https://github.com/embark-framework/embark/tree/master/packages/plugins/nethermind#readme",
8+
"bugs": "https://github.com/embark-framework/embark/issues",
9+
"keywords": [
10+
"blockchain",
11+
"dapps",
12+
"ethereum",
13+
"serverless",
14+
"nethermind"
15+
],
16+
"files": [
17+
"dist"
18+
],
19+
"license": "MIT",
20+
"repository": {
21+
"directory": "packages/plugins/nethermind",
22+
"type": "git",
23+
"url": "https://github.com/embark-framework/embark.git"
24+
},
25+
"main": "./dist/index.js",
26+
"types": "./dist/index.d.ts",
27+
"embark-collective": {
28+
"build:node": true,
29+
"typecheck": true
30+
},
31+
"scripts": {
32+
"_build": "npm run solo -- build",
33+
"_typecheck": "npm run solo -- typecheck",
34+
"ci": "npm run qa",
35+
"clean": "npm run reset",
36+
"lint": "eslint src/",
37+
"qa": "npm-run-all lint _typecheck _build",
38+
"reset": "npx rimraf dist embark-*.tgz package",
39+
"solo": "embark-solo"
40+
},
41+
"eslintConfig": {
42+
"extends": "../../../.eslintrc.json"
43+
},
44+
"dependencies": {
45+
"@babel/runtime-corejs3": "7.7.4",
46+
"async": "2.6.1",
47+
"core-js": "3.4.3",
48+
"embark-core": "^5.0.0-alpha.9",
49+
"embark-i18n": "^5.0.0-alpha.5",
50+
"embark-utils": "^5.0.0-alpha.9",
51+
"fs-extra": "8.1.0",
52+
"netcat": "1.3.5",
53+
"semver": "5.6.0",
54+
"ws": "7.1.2"
55+
},
56+
"devDependencies": {
57+
"embark-solo": "^5.0.0-alpha.5",
58+
"eslint": "5.7.0",
59+
"npm-run-all": "4.1.5",
60+
"rimraf": "3.0.0"
61+
},
62+
"engines": {
63+
"node": ">=10.17.0 <12.0.0",
64+
"npm": ">=6.11.3",
65+
"yarn": ">=1.19.1"
66+
}
67+
}

0 commit comments

Comments
 (0)