From e17b44451e4c58bb7dbaebfd05b14021094241e8 Mon Sep 17 00:00:00 2001
From: cgeek <cem.moreau@gmail.com>
Date: Sun, 20 Aug 2017 17:35:40 +0200
Subject: [PATCH] [fix] #1076 HEAD change detection

---
 app/lib/other_constants.ts                |  8 ++++++-
 app/modules/prover/lib/permanentProver.ts |  3 +++
 app/modules/prover/lib/proof.ts           |  5 ++++-
 app/modules/prover/lib/prover.ts          | 27 +++++++++++++----------
 app/service/BlockchainService.ts          | 12 +++++++++-
 server.ts                                 |  5 +++++
 test/integration/continuous-proof.js      |  2 +-
 7 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/app/lib/other_constants.ts b/app/lib/other_constants.ts
index 5eeec3809..db1ff032c 100644
--- a/app/lib/other_constants.ts
+++ b/app/lib/other_constants.ts
@@ -1,4 +1,10 @@
 export const OtherConstants = {
 
-  MUTE_LOGS_DURING_UNIT_TESTS: true
+  MUTE_LOGS_DURING_UNIT_TESTS: true,
+
+  BC_EVENT: {
+    SWITCHED: 'switched',
+    HEAD_CHANGED: 'newHEAD',
+    RESOLUTION_DONE: 'resolution_done'
+  }
 }
\ No newline at end of file
diff --git a/app/modules/prover/lib/permanentProver.ts b/app/modules/prover/lib/permanentProver.ts
index 1903a86bd..033fdb4c7 100644
--- a/app/modules/prover/lib/permanentProver.ts
+++ b/app/modules/prover/lib/permanentProver.ts
@@ -164,6 +164,9 @@ export class PermanentProver {
                 try {
                   const obj = parsers.parseBlock.syncWrite(dos2unix(this.lastComputedBlock.getRawSigned()));
                   await this.server.writeBlock(obj)
+                  await new Promise(res => {
+                    this.server.once('bcEvent', () => res())
+                  })
                 } catch (err) {
                   this.logger.warn('Proof-of-work self-submission: %s', err.message || err);
                 }
diff --git a/app/modules/prover/lib/proof.ts b/app/modules/prover/lib/proof.ts
index e569f5a36..bfa4af967 100644
--- a/app/modules/prover/lib/proof.ts
+++ b/app/modules/prover/lib/proof.ts
@@ -85,7 +85,10 @@ function beginNewProofOfWork(stuff:any) {
     const pair = stuff.pair;
     const forcedTime = stuff.forcedTime;
     currentCPU = conf.cpu || Constants.DEFAULT_CPU;
-    prefix = parseInt(conf.prefix || prefix) * 10 * Constants.NONCE_RANGE
+    prefix = parseInt(conf.prefix || prefix)
+    if (prefix && prefix < Constants.NONCE_RANGE) {
+      prefix *= 10 * Constants.NONCE_RANGE
+    }
     const highMark = stuff.highMark;
     const turnDuration = stuff.turnDuration || TURN_DURATION_IN_MILLISEC
     let sigFunc = null;
diff --git a/app/modules/prover/lib/prover.ts b/app/modules/prover/lib/prover.ts
index deebb93e1..e37662e08 100644
--- a/app/modules/prover/lib/prover.ts
+++ b/app/modules/prover/lib/prover.ts
@@ -1,6 +1,7 @@
 "use strict";
 import {PermanentProver} from "./permanentProver"
 import * as stream from "stream"
+import {OtherConstants} from "../../../lib/other_constants"
 
 export class Prover extends stream.Transform {
 
@@ -13,18 +14,20 @@ export class Prover extends stream.Transform {
 
   _write(obj:any, enc:any, done:any) {
     // Never close the stream
-    if (obj && obj.membersCount) {
-      this.permaProver.blockchainChanged(obj);
-    } else if (obj.nodeIndexInPeers !== undefined) {
-      this.permaProver.prover.changePoWPrefix((obj.nodeIndexInPeers + 1) * 10); // We multiply by 10 to give room to computers with < 100 cores
-    } else if (obj.cpu !== undefined) {
-      this.permaProver.prover.changeCPU(obj.cpu); // We multiply by 10 to give room to computers with < 100 cores
-    } else if (obj.pulling !== undefined) {
-      if (obj.pulling === 'processing') {
-        this.permaProver.pullingDetected();
-      }
-      else if (obj.pulling === 'finished') {
-        this.permaProver.pullingFinished();
+    if (obj) {
+      if (obj.bcEvent && obj.bcEvent === OtherConstants.BC_EVENT.HEAD_CHANGED || obj.bcEvent === OtherConstants.BC_EVENT.SWITCHED) {
+        this.permaProver.blockchainChanged(obj.block);
+      } else if (obj.nodeIndexInPeers !== undefined) {
+        this.permaProver.prover.changePoWPrefix((obj.nodeIndexInPeers + 1) * 10); // We multiply by 10 to give room to computers with < 100 cores
+      } else if (obj.cpu !== undefined) {
+        this.permaProver.prover.changeCPU(obj.cpu); // We multiply by 10 to give room to computers with < 100 cores
+      } else if (obj.pulling !== undefined) {
+        if (obj.pulling === 'processing') {
+          this.permaProver.pullingDetected();
+        }
+        else if (obj.pulling === 'finished') {
+          this.permaProver.pullingFinished();
+        }
       }
     }
     done && done();
diff --git a/app/service/BlockchainService.ts b/app/service/BlockchainService.ts
index faf238fb0..0e2db2fab 100644
--- a/app/service/BlockchainService.ts
+++ b/app/service/BlockchainService.ts
@@ -14,6 +14,7 @@ import {FIFOService} from "./FIFOService"
 import {CommonConstants} from "../lib/common-libs/constants"
 import {LOCAL_RULES_FUNCTIONS} from "../lib/rules/local_rules"
 import {Switcher, SwitcherDao} from "../lib/blockchain/Switcher"
+import {OtherConstants} from "../lib/other_constants"
 
 const _               = require('underscore');
 const constants       = require('../lib/constants');
@@ -158,6 +159,11 @@ export class BlockchainService extends FIFOService {
               await this.blockResolution()
               // Resolve the potential forks
               await this.forkResolution()
+              const current = this.current()
+              this.push({
+                bcEvent: OtherConstants.BC_EVENT.RESOLUTION_DONE,
+                block: current
+              })
             })
           })()
         }
@@ -187,6 +193,10 @@ export class BlockchainService extends FIFOService {
         try {
           await this.mainContext.checkAndAddBlock(dto)
           added = true
+          this.push({
+            bcEvent: OtherConstants.BC_EVENT.HEAD_CHANGED,
+            block: dto
+          })
         } catch (e) {
           this.logger.error(e)
           added = false
@@ -204,7 +214,7 @@ export class BlockchainService extends FIFOService {
     const newCurrent = await switcher.tryToFork()
     if (newCurrent) {
       this.push({
-        bcEvent: 'switched',
+        bcEvent: OtherConstants.BC_EVENT.SWITCHED,
         block: newCurrent
       })
     }
diff --git a/server.ts b/server.ts
index 3a2f9ece8..f872e3327 100644
--- a/server.ts
+++ b/server.ts
@@ -21,6 +21,7 @@ import {MembershipDTO} from "./app/lib/dto/MembershipDTO"
 import {RevocationDTO} from "./app/lib/dto/RevocationDTO"
 import {TransactionDTO} from "./app/lib/dto/TransactionDTO"
 import {PeerDTO} from "./app/lib/dto/PeerDTO"
+import {OtherConstants} from "./app/lib/other_constants"
 
 export interface HookableServer {
   getMainEndpoint: (...args:any[]) => Promise<any>
@@ -181,6 +182,10 @@ export class Server extends stream.Duplex implements HookableServer {
     // Messages piping
     this.BlockchainService
       .pipe(es.mapSync((e:any) => {
+        if (e.bcEvent === OtherConstants.BC_EVENT.HEAD_CHANGED || e.bcEvent === OtherConstants.BC_EVENT.SWITCHED) {
+          this.emitDocument(e.block, DuniterDocument.ENTITY_BLOCK)
+          this.emit('bcEvent', e)
+        }
         this.streamPush(e)
       }))
 
diff --git a/test/integration/continuous-proof.js b/test/integration/continuous-proof.js
index c2481d7ab..d44f1d53d 100644
--- a/test/integration/continuous-proof.js
+++ b/test/integration/continuous-proof.js
@@ -93,7 +93,7 @@ describe("Continous proof-of-work", function() {
     yield s1.permaProver.blockchainChanged();
     yield new Promise((resolve) => setTimeout(resolve, 100));
     // * 1 loop for waiting for b#4 but being interrupted
-    s1.permaProver.should.have.property('loops').greaterThanOrEqual(7);
+    s1.permaProver.should.have.property('loops').greaterThanOrEqual(6);
     yield s1.stopBlockComputation();
 
     // If we wait a bit, the loop should be ended
-- 
GitLab