Initial Commit

Changelog:
Setup & Foundation
- bcoin
- express
- mongo
- eslint
- logging

Status: Bcoin syncs over network, uses a local leveldb to store blocks and checkpoints. Block event saves data to mongo. Express endpoint for block hashes, stubbed to reply with blockhashes until mongo models are finalized.

ToDo:
Move config out of code
This commit is contained in:
tenthirtyone 2017-08-02 14:51:06 -04:00
parent 09804961c7
commit b028dead40
9 changed files with 2037 additions and 0 deletions

7
.eslintrc.json Normal file
View File

@ -0,0 +1,7 @@
{
"extends": "airbnb-base",
"env": {
"node": true,
"es6": true
}
}

5
.gitignore vendored
View File

@ -1,3 +1,8 @@
# Config
config/config.js
## Default gitignore below this line
# Logs
logs
*.log

View File

@ -0,0 +1,5 @@
const config = {
mongodb: 'mongodb://localhost/bitcore',
};
module.exports = config;

73
index.js Normal file
View File

@ -0,0 +1,73 @@
const FullNode = require('bcoin/lib/node/fullnode');
const mongoose = require('mongoose');
const config = require('./config/config.js');
const logger = require('./lib/logger');
const Block = require('./models/block');
const Server = require('./lib/server');
mongoose.connect(config.mongodb, {
useMongoClient: true
});
logger.log('debug',
'Debug mode started');
const node = new FullNode({
network: 'main',
db: 'leveldb',
checkpoints: true,
workers: true,
//logLevel: 'info',
});
(async () => {
await node.open();
await node.connect();
node.on('connect', (entry, block) => {
block.height = entry.height;
processBlock(block);
});
node.on('tx', (tx) => {
console.log('%s added to mempool.', tx.txid());
});
node.startSync();
})();
function processBlock(block) {
block.hash = revHex(block.hash().toString('hex'));
logger.log('debug',
`New Block Height: ${block.height}, Hash: ${block.hash}`);
let b = new Block({
mainChain: true,
height: block.height,
hash: block.hash,
version: block.version,
merkleRoot: block.merkleRoot,
time: block.ts,
timeNormalized: block.ts,
nonce: block.nonce,
previousBlockHash: block.prevBlock,
transactionCount: block.txs.length,
});
b.save((err) => {
if (err) {
console.log(err);
}
})
}
function revHex(hexString) {
let out = '';
for (let i = 0; i < hexString.length; i += 2) {
out = hexString.slice(i, i + 2) + out;
}
return out;
}
Server.listen(3000, function() {
console.log('listening on port 3000');
})

17
lib/logger/index.js Normal file
View File

@ -0,0 +1,17 @@
const winston = require('winston');
const logfile = new Date().toISOString();
const logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({
timestamp: true,
}),
new (winston.transports.File)({
filename: `logs/${logfile}.log`,
}),
],
});
logger.level = process.env.LOG || 'debug';
module.exports = logger;

15
lib/server/index.js Normal file
View File

@ -0,0 +1,15 @@
const express = require('express');
const app = express();
const mongoose = require('mongoose');
const config = require('../../config/config.js');
const Block = require('../../models/block.js');
mongoose.connect(config.mongodb, {
useMongoClient: true
});
app.get('/block/:blockhash', (req, res) => {
res.send(req.params.blockhash);
});
module.exports = app;

33
models/block.js Normal file
View File

@ -0,0 +1,33 @@
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const BlockSchema = new Schema({
hash: String,
size: Number,
height: Number,
version: Number,
merkleRoot: String,
tx: Array,
time: Date,
nonce: Number,
bits: Number,
difficulty: Number,
chainwork: Number,
confirmations: Number,
previousBlockHash: String,
nextBlockHash: String,
reward: Number,
timeNormalized: Date,
isMainChain: Boolean,
poolInfo: Object,
transactionCount: Number,
});
BlockSchema.index({ hash: 1 }, { unique: true });
BlockSchema.index({ height: 1 });
BlockSchema.index({ time: 1 });
BlockSchema.index({ timeNormalized: 1 });
const Block = mongoose.model('Block', BlockSchema);
module.exports = Block;

1861
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

21
package.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "bitcore-bcoin-insight",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "",
"dependencies": {
"bcoin": "^1.0.0-beta.14",
"express": "^4.15.3",
"mongoose": "^4.11.5",
"winston": "^2.3.1"
},
"devDependencies": {
"eslint-config-airbnb-base": "^11.3.1",
"eslint-plugin-import": "^2.7.0"
}
}