add blockchain install scripts

This commit is contained in:
Josh Harvey 2017-07-01 16:02:46 +03:00
parent 0e9e27b97b
commit 178f576cfb
39 changed files with 3938 additions and 750 deletions

33
lib/blockchain/bitcoin.js Normal file
View file

@ -0,0 +1,33 @@
const fs = require('fs')
const path = require('path')
const coinUtils = require('../coin-utils')
const common = require('./common')
module.exports = {setup}
const es = common.es
function setup (dataDir) {
const coinRec = coinUtils.getCryptoCurrency('BTC')
common.firewall([coinRec.defaultPort])
const config = buildConfig()
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
setupPm2(dataDir)
}
function buildConfig () {
return `rpcuser=lamassuserver
rpcpassword=${common.randomPass()}
dbcache=500
server=1
connections=40
keypool=10000
prune=4000
daemon=0`
}
function setupPm2 (dataDir) {
es(`pm2 start /usr/local/bin/bitcoind -- -datadir=${dataDir}`)
}

61
lib/blockchain/common.js Normal file
View file

@ -0,0 +1,61 @@
const crypto = require('crypto')
const os = require('os')
const path = require('path')
const cp = require('child_process')
const logger = require('console-log-level')({level: 'info'})
module.exports = {es, firewall, randomPass, fetchAndInstall, logger}
const BINARIES = {
BTC: {
url: 'https://bitcoin.org/bin/bitcoin-core-0.14.2/bitcoin-0.14.2-x86_64-linux-gnu.tar.gz',
dir: 'bitcoin-0.14.2/bin'
},
ETH: {
url: 'https://gethstore.blob.core.windows.net/builds/geth-linux-amd64-1.6.6-10a45cb5.tar.gz',
dir: 'geth-linux-amd64-1.6.6-10a45cb5'
},
ZEC: {
url: 'https://z.cash/downloads/zcash-1.0.10-1-linux64.tar.gz',
dir: 'zcash-1.0.10-1/bin'
},
DASH: {
url: 'https://www.dash.org/binaries/dashcore-0.12.1.5-linux64.tar.gz',
dir: 'dashcore-0.12.1/bin'
},
LTC: {
url: 'https://download.litecoin.org/litecoin-0.13.2/linux/litecoin-0.13.2-x86_64-linux-gnu.tar.gz',
dir: 'litecoin-0.13.2/bin'
}
}
function firewall (ports) {
if (!ports || ports.length === 0) throw new Error('No ports supplied')
const portsString = ports.join(',')
es(`sudo ufw allow ${portsString}`)
}
function randomPass () {
return crypto.randomBytes(32).toString('hex')
}
function es (cmd) {
const env = {HOME: os.userInfo().homedir}
const options = {encoding: 'utf8', env}
const res = cp.execSync(cmd, options)
logger.debug(res)
return res.toString()
}
function fetchAndInstall (crypto) {
const binaries = BINARIES[crypto.cryptoCode]
if (!binaries) throw new Error(`No such coin: ${crypto.code}`)
const url = binaries.url
const downloadFile = path.basename(url)
const binDir = binaries.dir
es(`wget -q ${url}`)
es(`tar -xzf ${downloadFile}`)
es(`sudo cp ${binDir}/* /usr/local/bin`)
}

28
lib/blockchain/dash.js Normal file
View file

@ -0,0 +1,28 @@
const fs = require('fs')
const path = require('path')
const coinUtils = require('../coin-utils')
const common = require('./common')
module.exports = {setup}
const es = common.es
function setup (dataDir) {
const coinRec = coinUtils.getCryptoCurrency('DASH')
common.firewall([coinRec.defaultPort])
const config = buildConfig()
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
setupPm2(dataDir)
}
function buildConfig () {
return `rpcuser=lamassuserver
rpcpassword=${common.randomPass()}
dbcache=500`
}
function setupPm2 (dataDir) {
es(`pm2 start /usr/local/bin/dashd -- -datadir=${dataDir}`)
}

0
lib/blockchain/dashd.js Normal file
View file

View file

@ -0,0 +1,67 @@
const fs = require('fs')
const common = require('./common')
const MOUNT_POINT = '/mnt/blockchains'
module.exports = {prepareVolume}
const logger = common.logger
function isMounted () {
return fs.existsSync(MOUNT_POINT)
}
function isFormatted (volumePath) {
const res = common.es(`file --dereference -s ${volumePath}`)
return res !== `${volumePath}: data`
}
function formatVolume (volumePath) {
if (isFormatted(volumePath)) {
logger.info('Volume is already formatted.')
return
}
logger.info('Formatting...')
common.es(`sudo mkfs.ext4 ${volumePath}`)
}
function mountVolume (volumePath) {
if (isMounted()) {
logger.info('Volume is already mounted.')
return
}
logger.info('Mounting...')
common.es(`sudo mkdir -p ${MOUNT_POINT}`)
common.es(`sudo mount -o discard,defaults ${volumePath} ${MOUNT_POINT}`)
common.es(`echo ${volumePath} ${MOUNT_POINT} ext4 defaults,nofail,discard 0 0 | sudo tee -a /etc/fstab`)
}
function locateVolume () {
const res = common.es('ls /dev/disk/by-id/*')
const lines = res.trim().split('\n')
if (lines.length > 1) {
logger.error('More than one volume present, cannot prepare.')
return null
}
if (lines.length === 0) {
logger.error('No available volumes. You might need to attach one.')
return null
}
return lines[0].trim()
}
function prepareVolume () {
const volumePath = locateVolume()
if (!volumePath) return false
formatVolume(volumePath)
mountVolume(volumePath)
return true
}

View file

@ -0,0 +1,17 @@
const coinUtils = require('../coin-utils')
const common = require('./common')
module.exports = {setup}
const es = common.es
function setup (dataDir) {
const coinRec = coinUtils.getCryptoCurrency('ETH')
common.firewall([coinRec.defaultPort])
setupPm2(dataDir)
}
function setupPm2 (dataDir) {
es(`pm2 start /usr/local/bin/geth -- --datadir "${dataDir}" --cache 500`)
}

95
lib/blockchain/install.js Normal file
View file

@ -0,0 +1,95 @@
const fs = require('fs')
const path = require('path')
const process = require('process')
const makeDir = require('make-dir')
const inquirer = require('inquirer')
const _ = require('lodash/fp')
const options = require('../options')
const coinUtils = require('../coin-utils')
const common = require('./common')
const doVolume = require('./do-volume')
const cryptos = coinUtils.cryptoCurrencies()
const logger = common.logger
const PLUGINS = {
BTC: require('./bitcoin.js'),
LTC: require('./litecoin.js'),
ETH: require('./ethereum.js'),
DASH: require('./dash.js'),
ZEC: require('./zcash.js')
}
function installedFilePath (crypto) {
return path.resolve(options.blockchainDir, crypto.code, '.installed')
}
function isInstalled (crypto) {
return fs.existsSync(installedFilePath(crypto))
}
const choices = _.map(c => {
const checked = isInstalled(c)
return {
name: c.display,
value: c.code,
checked,
disabled: checked && 'Installed'
}
}, cryptos)
const questions = []
questions.push({
type: 'checkbox',
name: 'crypto',
message: 'Which cryptocurrencies would you like to install?',
choices
})
function processCryptos (codes) {
if (_.isEmpty(codes)) {
logger.info('No cryptos selected. Exiting.')
process.exit(0)
}
doVolume.prepareVolume()
logger.info('Thanks! Installing: %s. Will take a while...', _.join(', ', codes))
const selectedCryptos = _.map(code => _.find(['code', code], cryptos), codes)
_.forEach(setupCrypto, selectedCryptos)
common.es('pm2 save')
logger.info('Installation complete.')
}
inquirer.prompt(questions)
.then(answers => processCryptos(answers.crypto))
function plugin (crypto) {
const plugin = PLUGINS[crypto.cryptoCode]
if (!plugin) throw new Error(`No such plugin: ${crypto.cryptoCode}`)
return plugin
}
function setupCrypto (crypto) {
logger.info(`Installing ${crypto.display}...`)
const cryptoDir = path.resolve(options.blockchainDir, crypto.code)
makeDir.sync(cryptoDir)
const cryptoPlugin = plugin(crypto)
const oldDir = process.cwd()
const tmpDir = '/tmp/blockchain-install'
makeDir.sync(tmpDir)
process.chdir(tmpDir)
common.es('rm -rf *')
common.fetchAndInstall(crypto)
cryptoPlugin.setup(cryptoDir)
fs.writeFileSync(installedFilePath(crypto), '')
process.chdir(oldDir)
}

View file

@ -0,0 +1,33 @@
const fs = require('fs')
const path = require('path')
const coinUtils = require('../coin-utils')
const common = require('./common')
module.exports = {setup}
const es = common.es
function setup (dataDir) {
const coinRec = coinUtils.getCryptoCurrency('LTC')
common.firewall([coinRec.defaultPort])
const config = buildConfig()
fs.writeFileSync(path.resolve(dataDir, coinRec.configFile), config)
setupPm2(dataDir)
}
function buildConfig () {
return `rpcuser=lamassuserver
rpcpassword=${common.randomPass()}
dbcache=500
server=1
connections=40
keypool=10000
prune=4000
daemon=0`
}
function setupPm2 (dataDir) {
es(`pm2 start /usr/local/bin/litecoind -- -datadir=${dataDir}`)
}

37
lib/blockchain/zcash.js Normal file
View file

@ -0,0 +1,37 @@
const fs = require('fs')
const path = require('path')
const coinUtils = require('../coin-utils')
const common = require('./common')
module.exports = {setup}
const es = common.es
const logger = common.logger
function setup (dataDir) {
es('sudo apt-get update')
es('sudo apt-get install libgomp1 -y')
const coinRec = coinUtils.getCryptoCurrency('ZEC')
common.firewall([coinRec.defaultPort])
logger.info('Fetching Zcash proofs, will take a while...')
es('zcash-fetch-params 2>&1')
logger.info('Finished fetching proofs.')
const config = buildConfig()
fs.writeFileSync(path.resolve(dataDir, 'zcash.conf'), config)
setupPm2(dataDir)
}
function buildConfig () {
return `mainnet=1
addnode=mainnet.z.cash
rpcuser=lamassuserver
rpcpassword=${common.randomPass()}
dbcache=500`
}
function setupPm2 (dataDir) {
es(`pm2 start /usr/local/bin/zcashd -- -datadir=${dataDir}`)
}

0
lib/blockchain/zcashd.js Normal file
View file