Skip to content

Commit

Permalink
Merge pull request #3 from harpagon210/resources-managment
Browse files Browse the repository at this point in the history
adding replay from blocks.log file
  • Loading branch information
harpagon210 authored Sep 29, 2018
2 parents 296e6a0 + cbcd5c5 commit c62aab1
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 74 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ examples
data
test/data
*.key
*.cert
*.cert
blocks.log
207 changes: 138 additions & 69 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const nodeCleanup = require('node-cleanup');
const fs = require('fs-extra');
const program = require('commander');
const packagejson = require('./package.json');
const { JsonRPCServer } = require('./libs/JsonRPCServer');
const {
chainId,
Expand All @@ -12,79 +14,146 @@ const {
const { SteemStreamer } = require('./libs/SteemStreamer');
const { Blockchain } = require('./libs/Blockchain');
const { Transaction } = require('./libs/Transaction');
const { Replay } = require('./libs/Replay');

// instantiate the blockchain
const steemContracts = new Blockchain(chainId, autosaveInterval, javascriptVMTimeout);

console.log('Loading Blockchain...'); // eslint-disable-line
steemContracts.loadBlockchain(dataDirectory, databaseFilePath, (error) => {
if (error) {
console.error(error); // eslint-disable-line
} else {
console.log('Blockchain loaded'); // eslint-disable-line

// start reading the Steem blockchain to get incoming transactions
const steemStreamer = new SteemStreamer(chainId, startSteemBlock);
steemStreamer.stream((result) => {
// the stream parsed transactions from the Steem blockchain
const { timestamp, transactions } = result;
// we create the transactions that will be processed by the sidechain
transactions.forEach((transaction) => {
steemContracts.createTransaction(
new Transaction(
transaction.refBlockNumber,
transaction.transactionId,
transaction.sender,
transaction.contractName,
transaction.contractAction,
transaction.contractPayload,
),
);
});
program
.version(packagejson.version)
.option('-r, --replay [type]', 'replay the blockchain from [file|steemd]', /^(file|steemd)$/i)
.parse(process.argv);

// if there are transactions pending we produce a block
if (transactions.length > 0) {
steemContracts.producePendingTransactions(timestamp);
}
});

// JSON RPC Server instantiation
const jsonRPCServer = new JsonRPCServer(steemContracts);
jsonRPCServer.StartServer();

// execute actions before the app closes
nodeCleanup((exitCode, signal) => {
if (signal) {
console.log('Closing App... ', exitCode, signal); // eslint-disable-line

let currentSteemBlock = steemStreamer.GetCurrentBlock();
steemStreamer.StopStream();

steemContracts.saveBlockchain((err) => {
if (err) {
console.error(err); // eslint-disable-line
} else {
console.log('Blockchain saved'); // eslint-disable-line
}
if (program.replay !== undefined) {
// instantiate the blockchain
const steemContracts = new Blockchain(chainId, 0, javascriptVMTimeout);

console.log('Loading Blockchain...'); // eslint-disable-line
steemContracts.loadBlockchain(dataDirectory, databaseFilePath, (error) => {
if (error) {
console.error(error); // eslint-disable-line
} else {
let nbBlocksReplayed = 0;
console.log('Blockchain loaded'); // eslint-disable-line

// check if the last streamed Steem block is not lower than the latest block processed
const latestBlock = steemContracts.getLatestBlock();
if (currentSteemBlock < latestBlock.refSteemBlockNumber) {
currentSteemBlock = latestBlock.refSteemBlockNumber;
// instantiate the replay tool
const replay = new Replay(program.replay);
console.log(`Sarting replay from ${program.replay}`); // eslint-disable-line
replay.start((result) => {
if (result) {
const { timestamp, transactions, blockNumber } = result;
console.log(`Replaying block ${blockNumber}`); // eslint-disable-line
nbBlocksReplayed += 1;
// we create the transactions that will be processed by the sidechain
transactions.forEach((transaction) => {
steemContracts.createTransaction(
new Transaction(
transaction.refBlockNumber,
transaction.transactionId,
transaction.sender,
transaction.contract,
transaction.action,
transaction.payload,
),
);
});
// if there are transactions pending we produce a block
if (transactions.length > 0) {
steemContracts.producePendingTransactions(timestamp);
}
} else {
console.log(`Done replaying ${nbBlocksReplayed} blocks`); // eslint-disable-line
steemContracts.saveBlockchain((err) => {
if (err) {
console.error(err); // eslint-disable-line
} else {
console.log('Blockchain saved'); // eslint-disable-line
}

const config = fs.readJSONSync('./config.json');
config.startSteemBlock = currentSteemBlock;
fs.writeJSONSync('./config.json', config);
const latestBlock = steemContracts.getLatestBlock();

// calling process.exit() won't inform parent process of signal
process.kill(process.pid, signal);
const config = fs.readJSONSync('./config.json');
config.startSteemBlock = latestBlock.refSteemBlockNumber;
fs.writeJSONSync('./config.json', config);

// calling process.exit() won't inform parent process of signal
process.kill(process.pid);
});
}
});
}
});
} else {
// instantiate the blockchain
const steemContracts = new Blockchain(chainId, autosaveInterval, javascriptVMTimeout);

console.log('Loading Blockchain...'); // eslint-disable-line
steemContracts.loadBlockchain(dataDirectory, databaseFilePath, (error) => {
if (error) {
console.error(error); // eslint-disable-line
} else {
console.log('Blockchain loaded'); // eslint-disable-line

// start reading the Steem blockchain to get incoming transactions
const steemStreamer = new SteemStreamer(chainId, startSteemBlock);
steemStreamer.stream((result) => {
// the stream parsed transactions from the Steem blockchain
const { timestamp, transactions } = result;
// we create the transactions that will be processed by the sidechain
transactions.forEach((transaction) => {
steemContracts.createTransaction(
new Transaction(
transaction.refBlockNumber,
transaction.transactionId,
transaction.sender,
transaction.contractName,
transaction.contractAction,
transaction.contractPayload,
),
);
});
nodeCleanup.uninstall(); // don't call cleanup handler again
return false;
}

return true;
});
}
});

// if there are transactions pending we produce a block
if (transactions.length > 0) {
steemContracts.producePendingTransactions(timestamp);
}
});

// JSON RPC Server instantiation
const jsonRPCServer = new JsonRPCServer(steemContracts);
jsonRPCServer.StartServer();

// execute actions before the app closes
nodeCleanup((exitCode, signal) => {
if (signal) {
console.log('Closing App... ', exitCode, signal); // eslint-disable-line

let currentSteemBlock = steemStreamer.GetCurrentBlock();
steemStreamer.StopStream();

steemContracts.saveBlockchain((err) => {
if (err) {
console.error(err); // eslint-disable-line
} else {
console.log('Blockchain saved'); // eslint-disable-line
}

// check if the last streamed Steem block is not lower than the latest block processed
const latestBlock = steemContracts.getLatestBlock();
if (currentSteemBlock < latestBlock.refSteemBlockNumber) {
currentSteemBlock = latestBlock.refSteemBlockNumber;
}

const config = fs.readJSONSync('./config.json');
config.startSteemBlock = currentSteemBlock;
fs.writeJSONSync('./config.json', config);

// calling process.exit() won't inform parent process of signal
process.kill(process.pid, signal);
});
nodeCleanup.uninstall(); // don't call cleanup handler again
return false;
}

return true;
});
}
});
}
59 changes: 59 additions & 0 deletions libs/Replay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const fs = require('fs');
const readline = require('readline');
const stream = require('stream');

class Replay {
constructor(type) {
this.type = type;
this.stop = false;
}

start(callback) {
if (this.type === 'file') {
Replay.replayFile(callback);
}
}

stop() {
this.stop = true;
}

static replayFile(callback) {
let instream;
let outstream;
let rl;

// make sure file exists
const fileName = './blocks.log';
fs.stat(fileName, (err, stats) => {
if (!err && stats.isFile()) {
instream = fs.createReadStream(fileName);
outstream = new stream(); // eslint-disable-line new-cap
rl = readline.createInterface(instream, outstream);

rl.on('line', (line) => {
if (line !== '') {
const block = JSON.parse(line);
if (block.blockNumber !== 0) {
callback({
blockNumber: block.blockNumber,
// we timestamp the block with the Steem block timestamp
timestamp: block.timestamp,
transactions: block.transactions,
});
}
}
});

rl.on('close', () => {
callback(null);
});
} else {
// file does not exist, so callback with null
callback(null);
}
});
}
}

module.exports.Replay = Replay;
12 changes: 9 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "steemsmartcontracts",
"version": "1.0.0",
"version": "0.0.1",
"description": "",
"main": "app.js",
"scripts": {
Expand All @@ -11,6 +11,7 @@
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.3",
"commander": "^2.18.0",
"cors": "^2.8.4",
"crypto-js": "^3.1.9-1",
"currency.js": "^1.1.4",
Expand Down

0 comments on commit c62aab1

Please sign in to comment.