Skip to content
This repository was archived by the owner on Dec 11, 2019. It is now read-only.

Commit 84b416b

Browse files
mrose17ryanml
authored andcommitted
Merge pull request #15029 from brave/geth-sanity-updates
Harden use of geth
1 parent c209fbd commit 84b416b

File tree

1 file changed

+83
-41
lines changed

1 file changed

+83
-41
lines changed

app/ethWallet-geth.js

+83-41
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const pwPath = path.join(gethDataDir, 'wallets.pw')
3030
const gethProcessPath = path.join(getExtensionsPath('bin'), gethProcessKey)
3131

3232
const configurePeers = async (dataDir) => {
33+
const staticNodePath = path.join(dataDir, 'geth', 'static-nodes.json')
3334
try {
3435
const discoveryDomain = `_enode._tcp.${envNet}.${envSubDomain}.brave.com`
3536
let newNodes = await dns.resolveSrv(discoveryDomain)
@@ -47,9 +48,10 @@ const configurePeers = async (dataDir) => {
4748

4849
const enodes = newNodes.map(({name, port}, i) => `enode://${newNodesPublicKeys[i]}@${newNodesIps[i]}:${port}`)
4950

50-
await fs.writeFile(path.join(dataDir, 'geth', 'static-nodes.json'), JSON.stringify(enodes))
51-
} catch (e) {
52-
console.error('Failed to configure static nodes peers ' + e.message)
51+
await fs.writeFile(staticNodePath, JSON.stringify(enodes))
52+
} catch (ex) {
53+
console.error('unable to configure ' + staticNodePath + ': ' + ex.message)
54+
throw ex
5355
}
5456
}
5557

@@ -106,29 +108,34 @@ const spawnGeth = async () => {
106108
}
107109

108110
const gethOptions = {
109-
stdio: process.env.GETH_LOG ? 'inherit' : 'ignore'
111+
stdio: ((envNet === 'ropsten') || process.env.GETH_LOG) ? 'inherit' : 'ignore'
110112
}
111113

112-
ensureGethDataDir()
113-
114114
// If the process from the previous browswer session still lingers, it should be killed
115115
if (await fs.pathExists(pidPath)) {
116116
try {
117117
const pid = await fs.readFile(pidPath)
118118
cleanupGeth(pid)
119119
} catch (ex) {
120-
console.error('Could not read from geth.pid')
120+
console.error('unable to read ' + pidPath + ': ' + ex.message)
121121
}
122122
}
123123

124-
geth = spawn(gethProcessPath, gethArgs, gethOptions)
124+
ensureGethDataDir()
125+
126+
try {
127+
geth = spawn(gethProcessPath, gethArgs, gethOptions)
125128

126-
geth.on('exit', handleGethStop.bind(null, 'exit'))
127-
geth.on('close', handleGethStop.bind(null, 'close'))
129+
geth.on('exit', handleGethStop.bind(null, 'exit'))
130+
geth.on('close', handleGethStop.bind(null, 'close'))
128131

129-
await writeGethPid(geth.pid)
132+
await writeGethPid(geth.pid)
130133

131-
console.warn('GETH: spawned')
134+
console.warn('GETH: spawned')
135+
} catch (ex) {
136+
console.error('unable to spawn ' + gethProcessPath + ': ' + ex.message)
137+
cleanupGeth(geth && geth.pid)
138+
}
132139
}
133140

134141
const ensureGethDataDir = () => {
@@ -159,44 +166,64 @@ const handleGethStop = (event, code, signal) => {
159166

160167
const writeGethPid = async (pid) => {
161168
if (!pid) {
162-
return
169+
throw new Error('no pid returned by spawn')
163170
}
164171

165172
gethProcessId = pid
166173

167174
try {
168175
await fs.writeFile(pidPath, gethProcessId)
169176
} catch (ex) {
170-
console.error('Could not write geth.pid')
177+
console.error('unable to write ' + pidPath + ': ' + ex.message)
178+
throw ex
171179
}
172180
}
173181

182+
const cleanupGethAndExit = (exitCode) => {
183+
cleanupGeth()
184+
process.exit(exitCode || 2)
185+
}
186+
174187
const cleanupGeth = (processId) => {
175188
processId = processId || gethProcessId
176189

177-
if (processId) {
178-
// Set geth to null to remove bound listeners
179-
// Otherwise, geth will attempt to restart itself
180-
// when killed.
181-
geth = null
190+
if (!processId) return console.warn('GET: nothing to cleanup')
191+
192+
// Set geth to null to remove bound listeners
193+
// Otherwise, geth will attempt to restart itself
194+
// when killed.
195+
geth = null
182196

183-
// Kill process
197+
// Kill process
198+
try {
184199
process.kill(processId)
200+
} catch (ex) {
201+
console.error('unable to kill ' + processId + ': ' + ex.message)
202+
}
203+
try {
204+
process.kill(processId, 0)
205+
console.log('GETH: unable to kill ' + processId)
206+
} catch (ex) {
207+
if (ex.code === 'ESRCH') {
208+
console.log('GETH: process killed')
209+
} else {
210+
console.error('unable to kill ' + processId + ': ' + ex.message)
211+
}
212+
}
185213

186-
// Remove in memory process id
187-
gethProcessId = null
214+
// Remove in memory process id
215+
gethProcessId = null
188216

189-
// Named pipes on Windows will get deleted
190-
// automatically once no processes are using them.
191-
if (!isWindows) {
192-
try {
193-
fs.unlinkSync(pidPath)
194-
} catch (ex) {
195-
console.error('Could not delete geth.pid')
196-
}
217+
// Named pipes on Windows will get deleted
218+
// automatically once no processes are using them.
219+
if (!isWindows) {
220+
try {
221+
fs.unlinkSync(pidPath)
222+
} catch (ex) {
223+
console.error('unable to delete ' + pidPath + ': ' + ex.message)
197224
}
198-
console.warn('GETH: cleanup done')
199225
}
226+
console.warn('GETH: cleanup done')
200227
}
201228

202229
// Attempts to restart geth up to 3 times
@@ -218,16 +245,19 @@ const restartGeth = async (tries = 3) => {
218245

219246
// Geth should be killed on normal process, exit, SIGINT,
220247
// and application crashing exceptions.
221-
process.on('exit', () => {
222-
cleanupGeth(gethProcessId)
223-
})
224-
process.on('SIGINT', () => {
225-
cleanupGeth(gethProcessId)
226-
process.exit(2)
227-
})
248+
process.on('exit', cleanupGeth)
249+
process.on('SIGHUP', cleanupGethAndExit)
250+
process.on('SIGTERM', cleanupGethAndExit)
251+
process.on('SIGINT', cleanupGethAndExit)
228252

229253
ipcMain.on('eth-wallet-create-wallet', (e, pwd) => {
230-
const client = net.createConnection(ipcPath)
254+
let client
255+
256+
try {
257+
client = net.createConnection(ipcPath)
258+
} catch (ex) {
259+
return console.error('unable to connect to ' + ipcPath + ' (1): ' + ex.message)
260+
}
231261

232262
client.on('connect', () => {
233263
client.write(JSON.stringify({ 'method': 'personal_newAccount', 'params': [pwd], 'id': 1, 'jsonrpc': '2.0' }))
@@ -243,7 +273,13 @@ ipcMain.on('eth-wallet-create-wallet', (e, pwd) => {
243273
})
244274

245275
ipcMain.on('eth-wallet-wallets', (e, data) => {
246-
const client = net.createConnection(ipcPath)
276+
let client
277+
278+
try {
279+
client = net.createConnection(ipcPath)
280+
} catch (ex) {
281+
console.error('unable to connect to ' + ipcPath + ' (2): ' + ex.message)
282+
}
247283

248284
client.on('connect', () => {
249285
client.write(JSON.stringify({ 'method': 'db_putString', 'params': ['braveEthWallet', 'wallets', data], 'id': 1, 'jsonrpc': '2.0' }))
@@ -255,7 +291,13 @@ ipcMain.on('eth-wallet-wallets', (e, data) => {
255291
})
256292

257293
ipcMain.on('eth-wallet-unlock-account', (e, address, pw) => {
258-
const client = net.createConnection(ipcPath)
294+
let client
295+
296+
try {
297+
client = net.createConnection(ipcPath)
298+
} catch (ex) {
299+
console.error('unable to connect to ' + ipcPath + ' (3): ' + ex.message)
300+
}
259301

260302
client.on('connect', () => {
261303
client.write(JSON.stringify({ 'method': 'personal_unlockAccount', 'params': [address, pw], 'id': 1, 'jsonrpc': '2.0' }))

0 commit comments

Comments
 (0)