Skip to content
This repository was archived by the owner on Feb 17, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ local.properties
*.iml
gradlew
gradlew.bat
android/.settings
android/.project

# node.js
#
Expand Down
33 changes: 21 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ A smart contract is a computer protocol intended to digitally facilitate, verify
## Supported platforms

- Android
- iOS (Need PR)
- iOS

## Initial Setup

Expand Down Expand Up @@ -75,18 +75,23 @@ const PrivateEth = async () => {
}`

const config = {
"bootnodeEnodes": [ // --bootnodesv5 / Enodes of v5 bootnodes for p2p discovery
"enode://XXXX@X[::]:XXXX",
"enode://YYYY@Y[::]:YYYY"
bootnodeEnodes: [ // --bootnodesv5 / Enodes of v5 bootnodes for p2p discovery
'enode://XXXX@X[::]:XXXX',
'enode://YYYY@Y[::]:YYYY'
],
"networkID": networkID, // --networkid / Network identifier (integer, 0=Olympic (disused), 1=Frontier, 2=Morden (disused), 3=Ropsten) (default: 1)
"maxPeers": 0, // --maxpeers / Maximum number of network peers (network disabled if set to 0) (default: 25)
"genesis": genesis, // genesis.json file
"nodeDir": ".private-ethereum", // --datadir / Data directory for the databases and keystore
"keyStoreDir": "keystore", // --keystore / Directory for the keystore (default = inside the datadir)
"enodes": "enode://XXXX@X[::]:XXXX" // static_nodes.json file. Comma separated enode URLs
"noDiscovery": false, // --nodiscover / determines if the node will not participate in p2p discovery (v5)
"syncMode": 5 // the number associated with a sync mode in `celo-blockchain/mobile/geth.go`
networkID: networkID, // --networkid / Network identifier (integer, 0=Olympic (disused), 1=Frontier, 2=Morden (disused), 3=Ropsten) (default: 1)
Comment thread
tkporter marked this conversation as resolved.
Outdated
maxPeers: 0, // --maxpeers / Maximum number of network peers (network disabled if set to 0) (default: 25)
genesis: genesis, // genesis.json file
nodeDir: '.private-ethereum', // --datadir / Data directory for the databases and keystore

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a new change but at some point can update to celo

keyStoreDir: 'keystore', // --keystore / Directory for the keystore (default = inside the datadir)
enodes: 'enode://XXXX@X[::]:XXXX', // static_nodes.json file. Comma separated enode URLs
noDiscovery: false, // --nodiscover / determines if the node will not participate in p2p discovery (v5)
syncMode: 5, // the number associated with a sync mode in `celo-blockchain/mobile/geth.go`
// HTTP RPC server - only intended for development & debugging
httpHost: '0.0.0.0', // host of the server

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should suggest opening RPC on 0.0.0.0:8545 because that could allow anyone on the local network to access the node and completely compromise the node, possible also attacking the device through the javascript execution features allowed by the debug API. Opening on 127.0.0.1:8545 is better. With this, we should definitely add a stronger warning here about only using this in debug mode because opening the network socket allows any app on the device to access the node with full permissions.

httpPort: 8545, // port the server will be created for
httpVirtualHosts: '*', // comma separated string of allowed virtual hostnames for requests
httpModules: ['rpc,txpool,admin,istanbul,les,net,web3,debug,eth'], // comma separated string of RPC API modules to expose
}

const geth = new Geth(config)
Expand Down Expand Up @@ -140,6 +145,10 @@ Geth object
- `config.enodes` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Comma separated enode URLs of static nodes
- `config.noDiscovery` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** Determines if the node will not participate in p2p discovery (v5)
- `config.syncMode` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The number associated with a sync mode in `celo-blockchain/mobile/geth.go`
- `config.httpHost` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** The host of the HTTP RPC server. If not specified, no server is created.
- `config.httpPort` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** The port of the HTTP RPC server if present. If 0, a random port is chosen.
- `config.httpVirtualHosts` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Comma separated virtual hostnames whose requests to the HTTP RPC server are allowed.
- `config.httpModules` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Comma separated RPC API modules to expose.

### start

Expand Down
32 changes: 19 additions & 13 deletions android/src/main/java/com/reactnativegeth/RNGethModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
import org.ethereum.geth.Address;
import org.ethereum.geth.BigInt;
import org.ethereum.geth.Context;
// import org.ethereum.geth.Enode;
// import org.ethereum.geth.Enodes;
import org.ethereum.geth.Enode;
import org.ethereum.geth.Enodes;
import org.ethereum.geth.EthereumClient;
import org.ethereum.geth.Geth;
import org.ethereum.geth.Header;
Expand Down Expand Up @@ -102,17 +102,23 @@ public void nodeConfig(ReadableMap config, Promise promise) {
if (config.hasKey("keyStoreDir")) keyStoreDir = config.getString("keyStoreDir");
if (config.hasKey("syncMode")) nc.setSyncMode(config.getInt("syncMode"));
if (config.hasKey("useLightweightKDF")) nc.setUseLightweightKDF(config.getBoolean("useLightweightKDF"));
// if (config.hasKey("noDiscovery")) nc.setNoDiscovery(config.getBoolean("noDiscovery"));
// if (config.hasKey("bootnodeEnodes")) {
// ReadableArray bootnodeEnodes = config.getArray("bootnodeEnodes");
// int enodesSize = bootnodeEnodes.size();
// Enodes enodes = new Enodes(enodesSize);
// for (int i = 0; i < enodesSize; i++) {
// Enode enode = new Enode(bootnodeEnodes.getString(i));
// enodes.set(i, enode);
// }
// nc.setBootstrapNodes(enodes);
// }
if (config.hasKey("noDiscovery")) nc.setNoDiscovery(config.getBoolean("noDiscovery"));
if (config.hasKey("bootnodeEnodes")) {
ReadableArray bootnodeEnodes = config.getArray("bootnodeEnodes");
int enodesSize = bootnodeEnodes.size();
Enodes enodes = new Enodes(enodesSize);
for (int i = 0; i < enodesSize; i++) {
Enode enode = new Enode(bootnodeEnodes.getString(i));
enodes.set(i, enode);
}
nc.setBootstrapNodes(enodes);
}
// HTTP RPC configurations, which should only be used for development & debugging
if (config.hasKey("httpHost")) nc.setHTTPHost(config.getString("httpHost"));
if (config.hasKey("httpPort")) nc.setHTTPPort(config.getInt("httpPort"));
if (config.hasKey("httpVirtualHosts")) nc.setHTTPVirtualHosts(config.getString("httpVirtualHosts"));
if (config.hasKey("httpModules")) nc.setHTTPModules(config.getString("httpModules"));

if (config.hasKey("ipcPath")) nc.setIPCPath(config.getString("ipcPath"));
if (config.hasKey("logFile")) {
String logFileName = config.getString("logFile");
Expand Down
63 changes: 50 additions & 13 deletions ios/RNGeth.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
func onError(_ failure: String?) {
NSLog("@", failure!)
}

private let ETH_DIR: String = ".ethereum"
private let KEY_STORE_DIR: String = "keystore"
private let DATA_DIR_PREFIX = NSHomeDirectory() + "/Documents"
Expand All @@ -52,18 +52,18 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
NSLog("Failed stopping geth node: \(error)")
}
}

@objc(supportedEvents)
override func supportedEvents() -> [String]! {
return ["GethNewHead"]
}

func convertToDictionary(from text: String) throws -> [String: String] {
guard let data = text.data(using: .utf8) else { return [:] }
let anyResult: Any = try JSONSerialization.jsonObject(with: data, options: [])
return anyResult as? [String: String] ?? [:]
}

func onNewHead(_ header: GethHeader?) {
guard bridge != nil else {
// Don't call sendEvent when the bridge is not set
Expand All @@ -82,7 +82,7 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
NSLog("@", NSErr)
}
}

/**
* Creates and configures a new Geth node.
*
Expand All @@ -97,13 +97,13 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
resolve([true] as NSObject)
return;
}

do {
let nodeconfig: GethNodeConfig = geth_node.getNodeConfig()!
let nodeDir: String = (config?["nodeDir"] as? String) ?? ETH_DIR
let keyStoreDir: String = (config?["keyStoreDir"] as? String) ?? KEY_STORE_DIR
var error: NSError?

if let enodes = config?["enodes"] as? String {
geth_node.writeStaticNodesFile(enodes: enodes)
}
Expand All @@ -122,14 +122,51 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
if let useLightweightKDF = config?["useLightweightKDF"] as? Bool {
nodeconfig.useLightweightKDF = useLightweightKDF
}
if let ipcPath = config?["ipcPath"] as? String {
if let noDiscovery = config?["noDiscovery"] as? Bool {
nodeconfig.noDiscovery = noDiscovery
}
if let bootnodeEnodes = config?["bootnodeEnodes"] as? [String] {
guard let enodes = GethEnodes(bootnodeEnodes.count) else {
throw error ?? RuntimeError("Unable to create GethEnodes")
}
for i in 0..<bootnodeEnodes.count {
try enodes.set(i, enode: GethEnode(bootnodeEnodes[i]))
}
nodeconfig.bootstrapNodes = enodes
}
// HTTP RPC configurations, which should only be used for development & debugging
if let httpHost = config?["httpHost"] as? String {
// Workaround gomobile objc binding bug for properties starting with a capital letter in the go source
// See https://github.com/golang/go/issues/32008
// Once that bug is fixed the assertion will fail and we can switch back to:
// nodeconfig.ipcPath = ipcPath
// nodeconfig.httpHost = httpHost
nodeconfig.setValue(httpHost, forKey: "HTTPHost")
}
if let httpPort = config?["httpPort"] as? Int {
// See comment for httpHost
nodeconfig.setValue(httpPort, forKey: "HTTPPort")
}
if let httpVirtualHosts = config?["httpVirtualHosts"] as? String {
// See comment for httpHost
nodeconfig.setValue(httpVirtualHosts, forKey: "HTTPVirtualHosts")
}
if let httpModules = config?["httpModules"] as? String {
// See comment for httpHost
nodeconfig.setValue(httpModules, forKey: "HTTPModules")
}

if let ipcPath = config?["ipcPath"] as? String {
// See comment for httpHost
nodeconfig.setValue(ipcPath, forKey: "IPCPath")
assert(nodeconfig.ipcPath == ipcPath)
}
if let logFile = config?["logFile"] as? String {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I actually wanted to bring this up, I noticed it was happening only on android.

var logLevel = 3 // Info
if let logFileLogLevel = config?["logFileLogLevel"] as? Int {
logLevel = logFileLogLevel
}
GethSendLogsToFile(logFile, logLevel, "term")
}

let dataDir = DATA_DIR_PREFIX + "/" + nodeDir

Expand All @@ -155,7 +192,7 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
reject(nil, nil, NCErr)
}
}

/**
* Start creates a live P2P node and starts running it.
*
Expand All @@ -171,14 +208,14 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
result = true
geth_node.setNodeStarted(started: true)
}

resolve([result] as NSObject)
} catch let NSErr as NSError {
NSLog("@", NSErr)
reject(nil, nil, NSErr)
}
}

@objc(subscribeNewHead:rejecter:)
func subscribeNewHead(resolver resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) -> Void {
do {
Expand All @@ -191,7 +228,7 @@ class RNGeth: RCTEventEmitter, GethNewHeadHandlerProtocol {
reject(nil, nil, NSErr)
}
}

/**
* Terminates a running node along with all it's services.
*
Expand Down
2 changes: 1 addition & 1 deletion src/geth.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

import { Platform, NativeModules } from 'react-native'
import { NativeModules } from 'react-native'
import type { NodeConfig, Account, ListAccounts, SyncProgress, GethNativeModule } from './types'

/**
Expand Down