Skip to content

Commit

Permalink
[fix] #1256 PoW improved with a security file for stopping it
Browse files Browse the repository at this point in the history
  • Loading branch information
c-geek committed Jan 28, 2018
1 parent 4acfe36 commit 6c07624
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 23 deletions.
4 changes: 4 additions & 0 deletions app/lib/dal/fileDAL.ts
Expand Up @@ -16,6 +16,7 @@ import {DBMembership} from "./sqliteDAL/MembershipDAL"
import {MerkleDTO} from "../dto/MerkleDTO"
import {CommonConstants} from "../common-libs/constants"
import { ProxiesConf } from '../proxy';
import {PowDAL} from "./fileDALs/PowDAL";

const fs = require('fs')
const path = require('path')
Expand All @@ -40,6 +41,7 @@ export class FileDAL {
wotb:any
profile:string

powDAL:PowDAL
confDAL:any
metaDAL:any
peerDAL:any
Expand Down Expand Up @@ -68,6 +70,7 @@ export class FileDAL {
this.profile = 'DAL'

// DALs
this.powDAL = new PowDAL(this.rootPath, this.myFS)
this.confDAL = new ConfDAL(this.rootPath, this.myFS)
this.metaDAL = new (require('./sqliteDAL/MetaDAL').MetaDAL)(this.sqliteDriver);
this.peerDAL = new (require('./sqliteDAL/PeerDAL').PeerDAL)(this.sqliteDriver);
Expand All @@ -85,6 +88,7 @@ export class FileDAL {
this.cindexDAL = new (require('./sqliteDAL/index/CIndexDAL').CIndexDAL)(this.sqliteDriver);

this.newDals = {
'powDAL': this.powDAL,
'metaDAL': this.metaDAL,
'blockDAL': this.blockDAL,
'certDAL': this.certDAL,
Expand Down
22 changes: 22 additions & 0 deletions app/lib/dal/fileDALs/PowDAL.ts
@@ -0,0 +1,22 @@
import {AbstractCFS} from "./AbstractCFS"

export class PowDAL extends AbstractCFS {

private static POW_FILE = "pow.txt"

constructor(rootPath:string, qioFS:any) {
super(rootPath, qioFS)
}

init() {
return this.coreFS.remove(PowDAL.POW_FILE, false).catch(() => {})
}

async getCurrent() {
return await this.coreFS.read(PowDAL.POW_FILE);
}

async writeCurrent(current:string) {
await this.coreFS.write(PowDAL.POW_FILE, current, false);
}
}
9 changes: 7 additions & 2 deletions app/lib/dto/ConfDTO.ts
Expand Up @@ -8,6 +8,10 @@ export interface Keypair {
sec: string
}

export interface PowDTO {
powNoSecurity:boolean
}

export interface BranchingDTO {
switchOnHeadAdvance:number
avgGenTime:number
Expand Down Expand Up @@ -82,7 +86,7 @@ export interface WS2PConfDTO {
}
}

export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, BranchingDTO, WS2PConfDTO {
export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, BranchingDTO, WS2PConfDTO, PowDTO {

constructor(
public loglevel: string,
Expand Down Expand Up @@ -158,7 +162,8 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO,
privilegedOnly: boolean
maxPublic?:number
maxPrivate?:number
}
},
public powNoSecurity = false
) {}

static mock() {
Expand Down
6 changes: 4 additions & 2 deletions app/lib/system/directory.ts
Expand Up @@ -28,7 +28,7 @@ const dir = module.exports = {

getHome: (profile:string|null = null, directory:string|null = null) => getHomePath(profile, directory),

getHomeFS: async (isMemory:boolean, theHome:string) => {
getHomeFS: async (isMemory:boolean, theHome:string, makeTree = true) => {
const home = theHome || dir.getHome();
const params:any = {
home: home
Expand All @@ -38,7 +38,9 @@ const dir = module.exports = {
} else {
params.fs = qfs;
}
await params.fs.makeTree(home);
if (makeTree) {
await params.fs.makeTree(home)
}
return params;
},

Expand Down
2 changes: 1 addition & 1 deletion app/modules/prover/lib/PowWorker.ts
Expand Up @@ -79,7 +79,7 @@ export class PowWorker {
return this.proofPromise
}

sendConf(confMessage:{ command:string, value:any }) {
sendConf(confMessage:{ rootPath: string, command:string, value:any }) {
this.nodejsWorker.send(confMessage)
}

Expand Down
10 changes: 3 additions & 7 deletions app/modules/prover/lib/blockProver.ts
Expand Up @@ -22,7 +22,7 @@ export class WorkerFarm {

constructor(private server:Server, private logger:any) {

this.theEngine = new PowEngine(server.conf, server.logger)
this.theEngine = new PowEngine(server.conf, server.logger, server.dal)

// An utility method to filter the pow notifications
this.checkPoWandNotify = (hash:string, block:DBBlock, found:boolean) => {
Expand Down Expand Up @@ -132,12 +132,7 @@ export class BlockProver {
// If no farm was instanciated, there is nothing to do yet
if (this.workerFarmPromise) {
let farm = await this.getWorker();
if (farm.isComputing() && !farm.isStopping()) {
await farm.stopPoW()
} else {
// We force the stop anyway, just to be sure
await farm.stopPoW()
}
await farm.stopPoW()
if (this.waitResolve) {
this.waitResolve();
this.waitResolve = null;
Expand Down Expand Up @@ -179,6 +174,7 @@ export class BlockProver {
let result = await powFarm.askNewProof({
newPoW: {
conf: {
powNoSecurity: this.conf.powNoSecurity,
cpu: this.conf.cpu,
prefix: this.conf.prefix,
avgGenTime: this.conf.avgGenTime,
Expand Down
7 changes: 4 additions & 3 deletions app/modules/prover/lib/engine.ts
@@ -1,5 +1,6 @@
import {Master as PowCluster} from "./powCluster"
import {ConfDTO} from "../../../lib/dto/ConfDTO"
import {FileDAL} from "../../../lib/dal/fileDAL";

const os = require('os')

Expand All @@ -16,11 +17,11 @@ export class PowEngine {
private cluster:PowCluster
readonly id:number

constructor(private conf:ConfDTO, logger:any) {
constructor(private conf:ConfDTO, logger:any, private dal?:FileDAL) {

// We use as much cores as available, but not more than CORES_MAXIMUM_USE_IN_PARALLEL
this.nbWorkers = conf.nbCores
this.cluster = new PowCluster(this.nbWorkers, logger)
this.cluster = new PowCluster(this.nbWorkers, logger, dal)
this.id = this.cluster.clusterId
}

Expand All @@ -33,7 +34,7 @@ export class PowEngine {
}

async prove(stuff:any) {
this.cluster.cancelWork()
await this.cluster.cancelWork()
return await this.cluster.proveByWorkers(stuff)
}

Expand Down
23 changes: 19 additions & 4 deletions app/modules/prover/lib/powCluster.ts
Expand Up @@ -2,6 +2,7 @@ import {ConfDTO} from "../../../lib/dto/ConfDTO"
import {ProverConstants} from "./constants"
import {createPowWorker} from "./proof"
import {PowWorker} from "./PowWorker"
import {FileDAL} from "../../../lib/dal/fileDAL";

const _ = require('underscore')
const nuuid = require('node-uuid');
Expand Down Expand Up @@ -36,7 +37,7 @@ export class Master {
onInfoCallback:any
workersOnline:Promise<any>[]

constructor(private nbCores:number, logger:any) {
constructor(private nbCores:number, logger:any, private dal?:FileDAL) {
this.clusterId = clusterId++
this.logger = logger || Master.defaultLogger()
this.onInfoMessage = (message:any) => {
Expand Down Expand Up @@ -83,6 +84,7 @@ export class Master {
}, () => {
this.logger.info(`[online] worker c#${this.clusterId}#w#${index}`)
worker.sendConf({
rootPath: this.dal ? this.dal.rootPath : '',
command: 'conf',
value: this.conf
})
Expand Down Expand Up @@ -119,6 +121,7 @@ export class Master {
this.conf.prefix = this.conf.prefix || conf.prefix
this.slaves.forEach(s => {
s.worker.sendConf({
rootPath: '',
command: 'conf',
value: this.conf
})
Expand All @@ -130,11 +133,15 @@ export class Master {
this.slaves.forEach(s => {
s.worker.sendCancel()
})
if (this.dal) {
this.dal.powDAL.writeCurrent("")
}
}

async cancelWork() {
this.cancelWorkersWork()
const workEnded = this.currentPromise
// Don't await the cancellation!
this.cancelWorkersWork()
// Current promise is done
this.currentPromise = null
return await workEnded
Expand All @@ -150,13 +157,17 @@ export class Master {
this.slaves = []
}

proveByWorkers(stuff:any) {
async proveByWorkers(stuff:any) {

// Eventually spawn the workers
if (this.slaves.length === 0) {
this.initCluster()
}

if (this.dal) {
await this.dal.powDAL.writeCurrent([stuff.newPoW.block.number - 1, stuff.newPoW.block.previousHash].join('-'))
}

// Register the new proof uuid
const uuid = nuuid.v4()
this.currentPromise = querablep((async () => {
Expand All @@ -173,14 +184,17 @@ export class Master {
uuid,
command: 'newPoW',
value: {
rootPath: this.dal ? this.dal.rootPath : '',
initialTestsPerRound: stuff.initialTestsPerRound,
maxDuration: stuff.maxDuration,block: stuff.newPoW.block,
maxDuration: stuff.maxDuration,
block: stuff.newPoW.block,
nonceBeginning: s.nonceBeginning,
zeros: stuff.newPoW.zeros,
highMark: stuff.newPoW.highMark,
pair: _.clone(stuff.newPoW.pair),
forcedTime: stuff.newPoW.forcedTime,
conf: {
powNoSecurity: stuff.newPoW.conf.powNoSecurity,
medianTimeBlocks: stuff.newPoW.conf.medianTimeBlocks,
avgGenTime: stuff.newPoW.conf.avgGenTime,
cpu: stuff.newPoW.conf.cpu,
Expand All @@ -197,6 +211,7 @@ export class Master {

// Find a proof
const result = await Promise.race(asks)
// Don't await the cancellation!
this.cancelWorkersWork()
// Wait for all workers to have stopped looking for a proof
await Promise.all(asks)
Expand Down
24 changes: 24 additions & 0 deletions app/modules/prover/lib/proof.ts
Expand Up @@ -7,12 +7,15 @@ import {KeyGen} from "../../../lib/common-libs/crypto/keyring"
import {dos2unix} from "../../../lib/common-libs/dos2unix"
import {rawer} from "../../../lib/common-libs/index"
import {ProcessCpuProfiler} from "../../../ProcessCpuProfiler"
import {PowDAL} from "../../../lib/dal/fileDALs/PowDAL";

const moment = require('moment');
const querablep = require('querablep');
const directory = require('../../../lib/system/directory');

export function createPowWorker() {

let powDAL:PowDAL|null = null
let computing = querablep(Promise.resolve(null));
let askedStop = false;

Expand Down Expand Up @@ -47,6 +50,11 @@ export function createPowWorker() {
await computing;
}

if (message.value.rootPath) {
const params = await directory.getHomeFS(false, message.value.rootPath, false)
powDAL = new PowDAL(message.value.rootPath, params.fs)
}

const res = await beginNewProofOfWork(message.value);
answer(message, res);
})()
Expand Down Expand Up @@ -226,6 +234,22 @@ export function createPowWorker() {
})()
]);

// console.log('W#%s.powDAL = ', process.pid, powDAL)

if (powDAL && !conf.powNoSecurity) {
const currentProofCheck = await powDAL.getCurrent()
if (currentProofCheck !== null) {
if (currentProofCheck === "") {
askedStop = true
} else {
const [currentNumber, currentHash] = currentProofCheck.split('-')
if (block.number !== parseInt(currentNumber) + 1 || block.previousHash !== currentHash) {
askedStop = true
}
}
}
}

// Next turn
turn++

Expand Down
6 changes: 2 additions & 4 deletions test/integration/server-import-export.js
Expand Up @@ -21,10 +21,10 @@ let s0, s1;
describe('Import/Export', () => {

before(() => co(function *() {
s0 = toolbox.server(_.extend({ homename: 'dev_unit_tests1' }, serverConfig));
s0 = toolbox.server(_.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig));
yield s0.resetHome();

s1 = toolbox.server(_.extend({ homename: 'dev_unit_tests1' }, serverConfig));
s1 = toolbox.server(_.extend({ homename: 'dev_unit_tests1', powNoSecurity: true }, serverConfig));

const cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 });
const tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 });
Expand Down Expand Up @@ -53,8 +53,6 @@ describe('Import/Export', () => {
return new Promise((resolve, reject) => {
archive.on('error', reject);
output.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
resolve();
});
});
Expand Down

0 comments on commit 6c07624

Please sign in to comment.