Skip to content
Snippets Groups Projects
Commit 4fd9397f authored by Éloïs's avatar Éloïs
Browse files

Merge branch...

Merge branch '1256-the-1-6-15-and-1-6-16-versions-never-starts-the-calculation-of-blocks' into '1.6'

Resolve "the 1.6.15 and 1.6.16 versions never starts the calculation of blocks"

Closes #1256

See merge request nodes/typescript/duniter!1238
parents b2942376 0c99bcab
Branches
Tags
1 merge request!1238Resolve "the 1.6.15 and 1.6.16 versions never starts the calculation of blocks"
...@@ -16,6 +16,7 @@ import {DBMembership} from "./sqliteDAL/MembershipDAL" ...@@ -16,6 +16,7 @@ import {DBMembership} from "./sqliteDAL/MembershipDAL"
import {MerkleDTO} from "../dto/MerkleDTO" import {MerkleDTO} from "../dto/MerkleDTO"
import {CommonConstants} from "../common-libs/constants" import {CommonConstants} from "../common-libs/constants"
import { ProxiesConf } from '../proxy'; import { ProxiesConf } from '../proxy';
import {PowDAL} from "./fileDALs/PowDAL";
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
...@@ -40,6 +41,7 @@ export class FileDAL { ...@@ -40,6 +41,7 @@ export class FileDAL {
wotb:any wotb:any
profile:string profile:string
powDAL:PowDAL
confDAL:any confDAL:any
metaDAL:any metaDAL:any
peerDAL:any peerDAL:any
...@@ -68,6 +70,7 @@ export class FileDAL { ...@@ -68,6 +70,7 @@ export class FileDAL {
this.profile = 'DAL' this.profile = 'DAL'
// DALs // DALs
this.powDAL = new PowDAL(this.rootPath, this.myFS)
this.confDAL = new ConfDAL(this.rootPath, this.myFS) this.confDAL = new ConfDAL(this.rootPath, this.myFS)
this.metaDAL = new (require('./sqliteDAL/MetaDAL').MetaDAL)(this.sqliteDriver); this.metaDAL = new (require('./sqliteDAL/MetaDAL').MetaDAL)(this.sqliteDriver);
this.peerDAL = new (require('./sqliteDAL/PeerDAL').PeerDAL)(this.sqliteDriver); this.peerDAL = new (require('./sqliteDAL/PeerDAL').PeerDAL)(this.sqliteDriver);
...@@ -85,6 +88,7 @@ export class FileDAL { ...@@ -85,6 +88,7 @@ export class FileDAL {
this.cindexDAL = new (require('./sqliteDAL/index/CIndexDAL').CIndexDAL)(this.sqliteDriver); this.cindexDAL = new (require('./sqliteDAL/index/CIndexDAL').CIndexDAL)(this.sqliteDriver);
this.newDals = { this.newDals = {
'powDAL': this.powDAL,
'metaDAL': this.metaDAL, 'metaDAL': this.metaDAL,
'blockDAL': this.blockDAL, 'blockDAL': this.blockDAL,
'certDAL': this.certDAL, 'certDAL': this.certDAL,
......
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);
}
}
...@@ -8,6 +8,10 @@ export interface Keypair { ...@@ -8,6 +8,10 @@ export interface Keypair {
sec: string sec: string
} }
export interface PowDTO {
powNoSecurity:boolean
}
export interface BranchingDTO { export interface BranchingDTO {
switchOnHeadAdvance:number switchOnHeadAdvance:number
avgGenTime:number avgGenTime:number
...@@ -82,7 +86,7 @@ export interface WS2PConfDTO { ...@@ -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( constructor(
public loglevel: string, public loglevel: string,
...@@ -158,7 +162,8 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO, ...@@ -158,7 +162,8 @@ export class ConfDTO implements CurrencyConfDTO, KeypairConfDTO, NetworkConfDTO,
privilegedOnly: boolean privilegedOnly: boolean
maxPublic?:number maxPublic?:number
maxPrivate?:number maxPrivate?:number
} },
public powNoSecurity = false
) {} ) {}
static mock() { static mock() {
......
...@@ -28,7 +28,7 @@ const dir = module.exports = { ...@@ -28,7 +28,7 @@ const dir = module.exports = {
getHome: (profile:string|null = null, directory:string|null = null) => getHomePath(profile, directory), 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 home = theHome || dir.getHome();
const params:any = { const params:any = {
home: home home: home
...@@ -38,7 +38,9 @@ const dir = module.exports = { ...@@ -38,7 +38,9 @@ const dir = module.exports = {
} else { } else {
params.fs = qfs; params.fs = qfs;
} }
await params.fs.makeTree(home); if (makeTree) {
await params.fs.makeTree(home)
}
return params; return params;
}, },
......
...@@ -79,7 +79,7 @@ export class PowWorker { ...@@ -79,7 +79,7 @@ export class PowWorker {
return this.proofPromise return this.proofPromise
} }
sendConf(confMessage:{ command:string, value:any }) { sendConf(confMessage:{ rootPath: string, command:string, value:any }) {
this.nodejsWorker.send(confMessage) this.nodejsWorker.send(confMessage)
} }
......
...@@ -22,7 +22,7 @@ export class WorkerFarm { ...@@ -22,7 +22,7 @@ export class WorkerFarm {
constructor(private server:Server, private logger:any) { 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 // An utility method to filter the pow notifications
this.checkPoWandNotify = (hash:string, block:DBBlock, found:boolean) => { this.checkPoWandNotify = (hash:string, block:DBBlock, found:boolean) => {
...@@ -132,12 +132,7 @@ export class BlockProver { ...@@ -132,12 +132,7 @@ export class BlockProver {
// If no farm was instanciated, there is nothing to do yet // If no farm was instanciated, there is nothing to do yet
if (this.workerFarmPromise) { if (this.workerFarmPromise) {
let farm = await this.getWorker(); let farm = await this.getWorker();
if (farm.isComputing() && !farm.isStopping()) {
await farm.stopPoW() await farm.stopPoW()
} else {
// We force the stop anyway, just to be sure
await farm.stopPoW()
}
if (this.waitResolve) { if (this.waitResolve) {
this.waitResolve(); this.waitResolve();
this.waitResolve = null; this.waitResolve = null;
...@@ -179,6 +174,7 @@ export class BlockProver { ...@@ -179,6 +174,7 @@ export class BlockProver {
let result = await powFarm.askNewProof({ let result = await powFarm.askNewProof({
newPoW: { newPoW: {
conf: { conf: {
powNoSecurity: this.conf.powNoSecurity,
cpu: this.conf.cpu, cpu: this.conf.cpu,
prefix: this.conf.prefix, prefix: this.conf.prefix,
avgGenTime: this.conf.avgGenTime, avgGenTime: this.conf.avgGenTime,
......
import {Master as PowCluster} from "./powCluster" import {Master as PowCluster} from "./powCluster"
import {ConfDTO} from "../../../lib/dto/ConfDTO" import {ConfDTO} from "../../../lib/dto/ConfDTO"
import {FileDAL} from "../../../lib/dal/fileDAL";
const os = require('os') const os = require('os')
...@@ -16,11 +17,11 @@ export class PowEngine { ...@@ -16,11 +17,11 @@ export class PowEngine {
private cluster:PowCluster private cluster:PowCluster
readonly id:number 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 // We use as much cores as available, but not more than CORES_MAXIMUM_USE_IN_PARALLEL
this.nbWorkers = conf.nbCores this.nbWorkers = conf.nbCores
this.cluster = new PowCluster(this.nbWorkers, logger) this.cluster = new PowCluster(this.nbWorkers, logger, dal)
this.id = this.cluster.clusterId this.id = this.cluster.clusterId
} }
......
...@@ -2,6 +2,7 @@ import {ConfDTO} from "../../../lib/dto/ConfDTO" ...@@ -2,6 +2,7 @@ import {ConfDTO} from "../../../lib/dto/ConfDTO"
import {ProverConstants} from "./constants" import {ProverConstants} from "./constants"
import {createPowWorker} from "./proof" import {createPowWorker} from "./proof"
import {PowWorker} from "./PowWorker" import {PowWorker} from "./PowWorker"
import {FileDAL} from "../../../lib/dal/fileDAL";
const _ = require('underscore') const _ = require('underscore')
const nuuid = require('node-uuid'); const nuuid = require('node-uuid');
...@@ -36,7 +37,7 @@ export class Master { ...@@ -36,7 +37,7 @@ export class Master {
onInfoCallback:any onInfoCallback:any
workersOnline:Promise<any>[] workersOnline:Promise<any>[]
constructor(private nbCores:number, logger:any) { constructor(private nbCores:number, logger:any, private dal?:FileDAL) {
this.clusterId = clusterId++ this.clusterId = clusterId++
this.logger = logger || Master.defaultLogger() this.logger = logger || Master.defaultLogger()
this.onInfoMessage = (message:any) => { this.onInfoMessage = (message:any) => {
...@@ -83,6 +84,7 @@ export class Master { ...@@ -83,6 +84,7 @@ export class Master {
}, () => { }, () => {
this.logger.info(`[online] worker c#${this.clusterId}#w#${index}`) this.logger.info(`[online] worker c#${this.clusterId}#w#${index}`)
worker.sendConf({ worker.sendConf({
rootPath: this.dal ? this.dal.rootPath : '',
command: 'conf', command: 'conf',
value: this.conf value: this.conf
}) })
...@@ -119,6 +121,7 @@ export class Master { ...@@ -119,6 +121,7 @@ export class Master {
this.conf.prefix = this.conf.prefix || conf.prefix this.conf.prefix = this.conf.prefix || conf.prefix
this.slaves.forEach(s => { this.slaves.forEach(s => {
s.worker.sendConf({ s.worker.sendConf({
rootPath: '',
command: 'conf', command: 'conf',
value: this.conf value: this.conf
}) })
...@@ -130,11 +133,15 @@ export class Master { ...@@ -130,11 +133,15 @@ export class Master {
this.slaves.forEach(s => { this.slaves.forEach(s => {
s.worker.sendCancel() s.worker.sendCancel()
}) })
if (this.dal) {
this.dal.powDAL.writeCurrent("")
}
} }
async cancelWork() { async cancelWork() {
this.cancelWorkersWork()
const workEnded = this.currentPromise const workEnded = this.currentPromise
// Don't await the cancellation!
this.cancelWorkersWork()
// Current promise is done // Current promise is done
this.currentPromise = null this.currentPromise = null
return await workEnded return await workEnded
...@@ -150,13 +157,17 @@ export class Master { ...@@ -150,13 +157,17 @@ export class Master {
this.slaves = [] this.slaves = []
} }
proveByWorkers(stuff:any) { async proveByWorkers(stuff:any) {
// Eventually spawn the workers // Eventually spawn the workers
if (this.slaves.length === 0) { if (this.slaves.length === 0) {
this.initCluster() 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 // Register the new proof uuid
const uuid = nuuid.v4() const uuid = nuuid.v4()
this.currentPromise = querablep((async () => { this.currentPromise = querablep((async () => {
...@@ -173,14 +184,17 @@ export class Master { ...@@ -173,14 +184,17 @@ export class Master {
uuid, uuid,
command: 'newPoW', command: 'newPoW',
value: { value: {
rootPath: this.dal ? this.dal.rootPath : '',
initialTestsPerRound: stuff.initialTestsPerRound, initialTestsPerRound: stuff.initialTestsPerRound,
maxDuration: stuff.maxDuration,block: stuff.newPoW.block, maxDuration: stuff.maxDuration,
block: stuff.newPoW.block,
nonceBeginning: s.nonceBeginning, nonceBeginning: s.nonceBeginning,
zeros: stuff.newPoW.zeros, zeros: stuff.newPoW.zeros,
highMark: stuff.newPoW.highMark, highMark: stuff.newPoW.highMark,
pair: _.clone(stuff.newPoW.pair), pair: _.clone(stuff.newPoW.pair),
forcedTime: stuff.newPoW.forcedTime, forcedTime: stuff.newPoW.forcedTime,
conf: { conf: {
powNoSecurity: stuff.newPoW.conf.powNoSecurity,
medianTimeBlocks: stuff.newPoW.conf.medianTimeBlocks, medianTimeBlocks: stuff.newPoW.conf.medianTimeBlocks,
avgGenTime: stuff.newPoW.conf.avgGenTime, avgGenTime: stuff.newPoW.conf.avgGenTime,
cpu: stuff.newPoW.conf.cpu, cpu: stuff.newPoW.conf.cpu,
...@@ -197,6 +211,7 @@ export class Master { ...@@ -197,6 +211,7 @@ export class Master {
// Find a proof // Find a proof
const result = await Promise.race(asks) const result = await Promise.race(asks)
// Don't await the cancellation!
this.cancelWorkersWork() this.cancelWorkersWork()
// Wait for all workers to have stopped looking for a proof // Wait for all workers to have stopped looking for a proof
await Promise.all(asks) await Promise.all(asks)
......
...@@ -7,12 +7,15 @@ import {KeyGen} from "../../../lib/common-libs/crypto/keyring" ...@@ -7,12 +7,15 @@ import {KeyGen} from "../../../lib/common-libs/crypto/keyring"
import {dos2unix} from "../../../lib/common-libs/dos2unix" import {dos2unix} from "../../../lib/common-libs/dos2unix"
import {rawer} from "../../../lib/common-libs/index" import {rawer} from "../../../lib/common-libs/index"
import {ProcessCpuProfiler} from "../../../ProcessCpuProfiler" import {ProcessCpuProfiler} from "../../../ProcessCpuProfiler"
import {PowDAL} from "../../../lib/dal/fileDALs/PowDAL";
const moment = require('moment'); const moment = require('moment');
const querablep = require('querablep'); const querablep = require('querablep');
const directory = require('../../../lib/system/directory');
export function createPowWorker() { export function createPowWorker() {
let powDAL:PowDAL|null = null
let computing = querablep(Promise.resolve(null)); let computing = querablep(Promise.resolve(null));
let askedStop = false; let askedStop = false;
...@@ -47,6 +50,11 @@ export function createPowWorker() { ...@@ -47,6 +50,11 @@ export function createPowWorker() {
await computing; 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); const res = await beginNewProofOfWork(message.value);
answer(message, res); answer(message, res);
})() })()
...@@ -226,6 +234,22 @@ export function createPowWorker() { ...@@ -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 // Next turn
turn++ turn++
......
...@@ -21,10 +21,10 @@ let s0, s1; ...@@ -21,10 +21,10 @@ let s0, s1;
describe('Import/Export', () => { describe('Import/Export', () => {
before(() => co(function *() { 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(); 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 cat = new TestUser('cat', { pub: 'HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', sec: '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP'}, { server: s1 });
const tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 }); const tac = new TestUser('tac', { pub: '2LvDg21dVXvetTD9GdkPLURavLYEqP3whauvPWX4c2qc', sec: '2HuRLWgKgED1bVio1tdpeXrf7zuUszv1yPHDsDj7kcMC4rVSN9RC58ogjtKNfTbH1eFz7rn38U1PywNs3m6Q7UxE'}, { server: s1 });
...@@ -53,8 +53,6 @@ describe('Import/Export', () => { ...@@ -53,8 +53,6 @@ describe('Import/Export', () => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
archive.on('error', reject); archive.on('error', reject);
output.on('close', function() { output.on('close', function() {
console.log(archive.pointer() + ' total bytes');
console.log('archiver has been finalized and the output file descriptor has closed.');
resolve(); resolve();
}); });
}); });
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment