Mise à jour effectuée, merci de nous signaler tout dysfonctionnement ! | Upgrade done, please let us know about any dysfunction!

Commit 9ff516e5 authored by Cédric Moreau's avatar Cédric Moreau
Browse files

[enh] do not require "currency" parameter for initial sync, even with WS2P

parent c6a2719d
......@@ -49,8 +49,8 @@ export const CrawlerDependency = {
return crawler.sandboxPull(server)
},
synchronize: (currency: string, server:Server, onHost:string, onPort:number, upTo:number, chunkLength:number) => {
const strategy = new RemoteSynchronizer(currency, onHost, onPort, server, chunkLength)
synchronize: (server:Server, onHost:string, onPort:number, upTo:number, chunkLength:number) => {
const strategy = new RemoteSynchronizer(onHost, onPort, server, chunkLength)
const remote = new Synchroniser(server, strategy)
const syncPromise = (async () => {
await server.dal.disableChangesAPI()
......@@ -70,8 +70,8 @@ export const CrawlerDependency = {
* @param {number} onPort
* @returns {Promise<any>}
*/
testForSync: (currency: string, server:Server, onHost:string, onPort:number) => {
return RemoteSynchronizer.test(currency, onHost, onPort, server.conf.pair)
testForSync: (server:Server, onHost:string, onPort:number) => {
return RemoteSynchronizer.test(onHost, onPort, server.conf.pair)
}
},
......@@ -86,7 +86,6 @@ export const CrawlerDependency = {
{ value: '--slow', desc: 'Download slowly the blokchcain (for low connnections).'},
{ value: '--readfilesystem',desc: 'Also read the filesystem to speed up block downloading.'},
{ value: '--minsig <minsig>', desc: 'Minimum pending signatures count for `crawl-lookup`. Default is 5.'},
{ value: '--up-to <block-number>', desc: 'Block number to reach.'},
],
cli: [{
......@@ -95,8 +94,7 @@ export const CrawlerDependency = {
preventIfRunning: true,
onDatabaseExecute: async (server:Server, conf:ConfDTO, program:any, params:any): Promise<any> => {
const source = params[0]
let currency = params[1]
const to = program.upTo
const to = params[1]
const HOST_PATTERN = /^[^:/]+(:[0-9]{1,5})?$/
const FILE_PATTERN = /^(\/.+)$/
if (!source || !(source.match(HOST_PATTERN) || source.match(FILE_PATTERN))) {
......@@ -129,10 +127,7 @@ export const CrawlerDependency = {
const sp = source.split(':')
const onHost = sp[0]
const onPort = parseInt(sp[1] ? sp[1] : '443') // Defaults to 443
if (!currency) {
throw 'currency parameter is required for network synchronization'
}
strategy = new RemoteSynchronizer(currency, onHost, onPort, server, CommonConstants.SYNC_BLOCKS_CHUNK, noShufflePeers === true, otherDAL)
strategy = new RemoteSynchronizer(onHost, onPort, server, CommonConstants.SYNC_BLOCKS_CHUNK, noShufflePeers === true, otherDAL)
} else {
strategy = new LocalPathSynchronizer(source, server, CommonConstants.SYNC_BLOCKS_CHUNK)
}
......
......@@ -11,6 +11,7 @@ import {Watcher} from "./Watcher"
import {cliprogram} from "../../../../lib/common-libs/programOptions"
import {Querable, querablep} from "../../../../lib/common-libs/querable"
import {AbstractSynchronizer} from "./AbstractSynchronizer"
import {Underscore} from "../../../../lib/common-libs/underscore"
const logger = NewLogger()
......@@ -48,7 +49,13 @@ export class ChunkGetter {
private downloadedChunks = 0
private writtenChunks = 0
private numberOfChunksToDownload:number
// --- Downloading slots and speed handling ---
private parallelDownloads = cliprogram.slow ? 1 : 5
private aSlotWasAdded = 0
private MAX_DELAY_PER_DOWNLOAD = cliprogram.slow ? 15000 : 5000
private lastAvgDelay = this.MAX_DELAY_PER_DOWNLOAD
private maxDownloadAdvance = 10 // 10 chunks can be downloaded even if 10th chunk above is not completed
private MAX_DOWNLOAD_TIMEOUT = 15000
private writeDAL: FileDAL
......@@ -139,12 +146,15 @@ export class ChunkGetter {
}
}
else if (handler.state === 'DOWNLOADED') {
// Chaining test: we must wait for upper chunk to be completed (= downloaded + chained)
const chunk = await handler.chunk
if (chunk.length === 0 && handler.downloader === this.fsDownloader) {
// Retry with P2P
handler.downloader = this.p2PDownloader
;(handler as any).state = 'WAITING'
remainingDownloads++
continue
}
if (isTopChunk || this.downloadHandlers[i + 1].state === 'COMPLETED') {
const fileName = this.syncStrategy.getChunkRelativePath(i)
......@@ -157,15 +167,19 @@ export class ChunkGetter {
if (!chainsWell) {
if (handler.downloader === this.p2PDownloader) {
if (chunk.length === 0) {
logger.error('No block was downloaded')
logger.error('No block was downloaded for chunk#%s', i)
}
logger.warn("Chunk #%s is DOES NOT CHAIN CORRECTLY. Retrying.", i)
logger.warn("Chunk #%s DOES NOT CHAIN CORRECTLY. Retrying.", i)
}
handler.downloader = this.p2PDownloader // If ever the first call does not chains well, we try using P2P
;(handler as any).state = 'WAITING'
i++
} else {
logger.info("Chunk #%s read from filesystem.", i)
if (handler.downloader === this.fsDownloader) {
logger.info("Chunk #%s read from filesystem.", i)
}
logger.info("Chunk #%s chains well.", i)
let doWrite = handler.downloader !== this.fsDownloader
|| !(await this.writeDAL.confDAL.coreFS.exists(fileName))
if (doWrite) {
......@@ -187,6 +201,40 @@ export class ChunkGetter {
(handler as any).chunk = undefined
}
this.downloadedChunks++
if (handler.downloader === this.p2PDownloader) {
// Speed resolution
const peers = await this.p2PDownloader.getTimesToAnswer()
const downloading = Underscore.filter(peers, (p) => p.ttas.length > 0)
const currentAvgDelay = downloading.length === 0 ? 0 : downloading.reduce((sum:number, c) => {
const tta = Math.round(c.ttas.reduce((sum:number, tta:number) => sum + tta, 0) / c.ttas.length)
return sum + tta;
}, 0) / downloading.length
if (!cliprogram.slow) {
// Check the impact of an added node (not first time)
if (!this.aSlotWasAdded) {
// We try to add a node
const newValue = Math.min(this.p2PDownloader.maxSlots, this.parallelDownloads + 1)
if (newValue !== this.parallelDownloads) {
this.parallelDownloads = newValue
this.aSlotWasAdded = i
logger.info('AUGMENTED DOWNLOAD SLOTS! Now has %s slots', this.parallelDownloads)
}
} else if (this.aSlotWasAdded && this.aSlotWasAdded - i > 5) { // We measure every 5 blocks
this.aSlotWasAdded = 0
const decelerationPercent = !this.lastAvgDelay ? 0 : currentAvgDelay / this.lastAvgDelay - 1
const addedNodePercent = 1 / downloading.length
logger.info('Deceleration = %s (%s/%s), AddedNodePercent = %s', decelerationPercent, currentAvgDelay, this.lastAvgDelay, addedNodePercent)
if (decelerationPercent > addedNodePercent) {
this.parallelDownloads = Math.max(1, this.parallelDownloads - 1); // We reduce the number of slots, but we keep at least 1 slot
logger.info('REDUCED DOWNLOAD SLOT! Now has %s slots', this.parallelDownloads)
}
}
}
this.lastAvgDelay = currentAvgDelay
}
this.watcher.downloadPercent(parseInt((this.downloadedChunks / this.numberOfChunksToDownload * 100).toFixed(0)))
// We pre-save blocks only for non-cautious sync
if (this.nocautious) {
......
......@@ -81,7 +81,7 @@ export class P2PSyncDownloader implements ISyncDownloader {
}
let syncApi: any = null
try {
syncApi = await RemoteSynchronizer.getSyncAPI(this.currency, apis, this.keypair)
syncApi = await RemoteSynchronizer.getSyncAPI(apis, this.keypair)
const manualp = newManualPromise<boolean>()
manualp.resolve(true)
const node: ProfiledNode = {
......
......@@ -16,7 +16,6 @@ import {BlockDTO} from "../../../../lib/dto/BlockDTO"
import {PeerDTO} from "../../../../lib/dto/PeerDTO"
import {connect} from "../connect"
import {NewLogger} from "../../../../lib/logger"
import {CrawlerConstants} from "../constants"
import {cliprogram} from "../../../../lib/common-libs/programOptions"
import {Watcher} from "./Watcher"
import {PeeringService} from "../../../../service/PeeringService"
......@@ -45,6 +44,7 @@ const logger = NewLogger()
export class RemoteSynchronizer extends AbstractSynchronizer {
private currency:string
private node:IRemoteContacter
private peer:PeerDTO
private shuffledPeers: JSONDBPeer[]
......@@ -53,12 +53,9 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
private to: number
private localNumber: number
private watcher: Watcher
private static contacterOptions = {
timeout: CrawlerConstants.SYNC_LONG_TIMEOUT
}
private endpoint: string = ""
constructor(
private readonly currency: string,
private host: string,
private port: number,
private server:Server,
......@@ -82,7 +79,7 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
}
getCurrency(): string {
return this.currency
return this.currency || 'unknown-currency'
}
getPeer(): PeerDTO {
......@@ -98,10 +95,12 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
}
async init(): Promise<void> {
const syncApi = await RemoteSynchronizer.getSyncAPI(this.currency, [{ host: this.host, port: this.port }], this.server.conf.pair)
const syncApi = await RemoteSynchronizer.getSyncAPI([{ host: this.host, port: this.port }], this.server.conf.pair)
if (!syncApi.api) {
throw Error(DataErrors[DataErrors.CANNOT_CONNECT_TO_REMOTE_FOR_SYNC])
}
this.currency = syncApi.currency
this.endpoint = syncApi.endpoint
this.node = syncApi.api
this.peer = PeerDTO.fromJSONObject(syncApi.peering)
logger.info("Try with %s %s", this.peer.getURL(), this.peer.pubkey.substr(0, 6))
......@@ -114,9 +113,10 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
;(this.node as any).pubkey = this.peer.pubkey
}
public static async getSyncAPI(currency: string, hosts: { isBMA?: boolean, isWS2P?: boolean, host: string, port: number, path?: string }[], keypair: Keypair) {
public static async getSyncAPI(hosts: { isBMA?: boolean, isWS2P?: boolean, host: string, port: number, path?: string }[], keypair: Keypair) {
let api: IRemoteContacter|undefined
let peering: any
let endpoint = ""
for (const access of hosts) {
const host = access.host
const port = access.port
......@@ -129,6 +129,7 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
const contacter = await connect(PeerDTO.fromJSONObject({ endpoints: [`BASIC_MERKLED_API ${host} ${port}${path && ' ' + path || ''}`]}), 3000)
peering = await contacter.getPeer()
api = new BMARemoteContacter(contacter)
endpoint = 'BASIC_MERKLED_API ' + host + ' ' + port + ((path && ' ' + path) || '')
} catch (e) {
logger.warn(`Node does not support BMA at address ${host} :${port}, trying WS2P...`)
}
......@@ -147,14 +148,15 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
logger.warn('Receiving push messages, which are not allowed during a SYNC.', json)
}
}),
new WS2PPubkeySyncLocalAuth(currency, pair, '00000000'),
new WS2PPubkeyRemoteAuth(currency, pair),
new WS2PPubkeySyncLocalAuth("", pair, '00000000'),
new WS2PPubkeyRemoteAuth("", pair), // The currency will be set by the remote node
undefined
)
try {
const requester = WS2PRequester.fromConnection(connection)
peering = await requester.getPeer()
api = new WS2PRemoteContacter(requester)
endpoint = 'WS2P 99999999 ' + host + ' ' + port + ((path && ' ' + path) || '')
} catch (e) {
logger.warn(`Node does not support WS2P at address ${host} :${port} either.`)
}
......@@ -170,12 +172,11 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
if (!peering) {
throw Error(DataErrors[DataErrors.NO_PEERING_AVAILABLE_FOR_SYNC])
}
if (peering.currency !== currency) {
throw Error(DataErrors[DataErrors.WRONG_CURRENCY_DETECTED])
}
return {
api,
peering
peering,
endpoint,
currency: peering.currency
}
}
......@@ -191,6 +192,19 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
peers = await this.node.getPeers()
}
// Add current peer if it is not returned (example of a local node)
peers.push({
version: 1,
currency: '',
status: 'UP',
first_down: null,
last_try: null,
pubkey: '',
block: '',
signature: '',
endpoints: [this.endpoint]
})
peers = peers.filter(p => {
if (!p) return false
let hasWS2P = false
......@@ -234,8 +248,8 @@ export class RemoteSynchronizer extends AbstractSynchronizer {
return this.node.getBlock(number)
}
static async test(currency: string, host: string, port: number, keypair: Keypair): Promise<BlockDTO> {
const syncApi = await RemoteSynchronizer.getSyncAPI(currency, [{ host, port }], keypair)
static async test(host: string, port: number, keypair: Keypair): Promise<BlockDTO> {
const syncApi = await RemoteSynchronizer.getSyncAPI([{ host, port }], keypair)
const current = await syncApi.api.getCurrent()
if (!current) {
throw Error(DataErrors[DataErrors.REMOTE_HAS_NO_CURRENT_BLOCK])
......
......@@ -21,6 +21,8 @@ import {TransactionDTO} from "../../../lib/dto/TransactionDTO"
import {PeerDTO} from "../../../lib/dto/PeerDTO"
import {WS2PConstants} from './constants';
import {WebSocket} from "../../../lib/common-libs/websocket"
import {ManualPromise, newManualPromise} from "../../../lib/common-libs/manual-promise"
import {DataErrors} from "../../../lib/common-libs/errors"
const SocksProxyAgent = require('socks-proxy-agent');
const nuuid = require('node-uuid');
......@@ -61,7 +63,8 @@ export interface WS2PAuth {
}
export interface WS2PRemoteAuth extends WS2PAuth {
registerCONNECT(type: 'CONNECT'|'SYNC', ws2pVersion:number, challenge:string, sig: string, pub: string, ws2pId:string): Promise<boolean>
givenCurrency: Promise<string>
registerCONNECT(type: 'CONNECT'|'SYNC', ws2pVersion:number, challenge:string, sig: string, pub: string, currency: string, ws2pId:string): Promise<boolean>
sendACK(ws:any): Promise<void>
registerOK(sig: string): Promise<boolean>
isAuthenticatedByRemote(): boolean
......@@ -75,6 +78,7 @@ export interface WS2PLocalAuth extends WS2PAuth {
registerACK(sig: string, pub: string): Promise<boolean>
sendOK(ws:any): Promise<void>
isRemoteAuthenticated(): boolean
currency: string
}
/**
......@@ -91,6 +95,7 @@ export class WS2PPubkeyRemoteAuth implements WS2PRemoteAuth {
protected serverAuthResolve:()=>void
protected serverAuthReject:(err:any)=>void
protected isSyncConnection = false
public givenCurrency: ManualPromise<string>
constructor(
protected currency:string,
......@@ -102,6 +107,11 @@ export class WS2PPubkeyRemoteAuth implements WS2PRemoteAuth {
this.serverAuthResolve = resolve
this.serverAuthReject = reject
})
this.givenCurrency = newManualPromise()
// If the currency is already provided, resolve the promise immediately
if (currency) {
this.givenCurrency.resolve(currency)
}
}
getVersion() {
......@@ -127,12 +137,20 @@ export class WS2PPubkeyRemoteAuth implements WS2PRemoteAuth {
}))
}
async registerCONNECT(type: 'CONNECT'|'SYNC', ws2pVersion:number, challenge:string, sig: string, pub: string, ws2pId:string = ""): Promise<boolean> {
async registerCONNECT(type: 'CONNECT'|'SYNC', ws2pVersion:number, challenge:string, sig: string, pub: string, currency: string, ws2pId:string = ""): Promise<boolean> {
this.isSyncConnection = type === 'SYNC'
const allow = await this.tellIsAuthorizedPubkey(pub, this.isSyncConnection)
if (!allow) {
return false
}
// If the connection was not aware of the currency beforehand, let's give the remote node's value
if (!this.currency && currency) {
this.currency = currency
}
else if (this.currency && this.currency !== currency && currency) {
throw Error(DataErrors[DataErrors.WRONG_CURRENCY_DETECTED])
}
this.givenCurrency.resolve(this.currency)
const challengeMessage = (ws2pVersion > 1) ? `WS2P:${type}:${this.currency}:${pub}:${ws2pId}:${challenge}`:`WS2P:${type}:${this.currency}:${pub}:${challenge}`
Logger.log('registerCONNECT >>> ' + challengeMessage)
const verified = verify(challengeMessage, sig, pub)
......@@ -179,7 +197,7 @@ export class WS2PPubkeyLocalAuth implements WS2PLocalAuth {
protected isSync: boolean
constructor(
protected currency:string,
public currency:string,
protected pair:Key,
protected ws2pId:string,
protected tellIsAuthorizedPubkey:(pub: string) => Promise<boolean> = () => Promise.resolve(true)
......@@ -204,7 +222,8 @@ export class WS2PPubkeyLocalAuth implements WS2PLocalAuth {
pub: this.pair.pub,
ws2pid: this.ws2pId,
challenge: this.challenge,
sig
sig,
currency: this.currency, // This is necessary for SYNC: because the currency is supposed not to be known by the remote
}))
return this.serverAuth
} else if (ws2pVersion == 1) {
......@@ -215,7 +234,8 @@ export class WS2PPubkeyLocalAuth implements WS2PLocalAuth {
auth: `${connectWord}`,
pub: this.pair.pub,
challenge: this.challenge,
sig
sig,
currency: this.currency, // This is necessary for SYNC: because the currency is supposed not to be known by the remote
}))
return this.serverAuth
}
......@@ -260,12 +280,12 @@ export class WS2PPubkeyLocalAuth implements WS2PLocalAuth {
export class WS2PPubkeySyncLocalAuth extends WS2PPubkeyLocalAuth {
constructor(
protected currency:string,
currency:string, // Only here for function signature purpose
protected pair:Key,
protected ws2pId:string,
protected tellIsAuthorizedPubkey:(pub: string) => Promise<boolean> = () => Promise.resolve(true)
) {
super(currency, pair, ws2pId, tellIsAuthorizedPubkey)
super("", pair, ws2pId, tellIsAuthorizedPubkey)
this.isSync = true
}
}
......@@ -450,6 +470,19 @@ export class WS2PConnection {
(async () => {
await this.onWsOpened
try {
// First: wait to know about the currency name. It can be given spontaneously by the remote node,
// or be already given if we know it before any exchange.
const currency = await this.remoteAuth.givenCurrency
// Then make some checks about its value
if (this.localAuth.currency && this.localAuth.currency !== currency) {
throw Error(DataErrors[DataErrors.WRONG_CURRENCY_DETECTED])
}
// Eventually give the information to localAuth, which will now be able to start the connection (currency is required for WS2P messages)
if (!this.localAuth.currency) {
this.localAuth.currency = currency
}
await this.localAuth.sendCONNECT(this.ws, this.ws2pVersion)
await Promise.all([
this.localAuth.authenticationIsDone(),
......@@ -497,7 +530,7 @@ export class WS2PConnection {
if (this.expectedPub && data.pub !== this.expectedPub) {
await this.errorDetected(WS2P_ERR.INCORRECT_PUBKEY_FOR_REMOTE)
} else {
const valid = await this.remoteAuth.registerCONNECT(data.auth, this.ws2pVersion, data.challenge, data.sig, data.pub, (this.ws2pVersion > 1) ? data.ws2pID:"")
const valid = await this.remoteAuth.registerCONNECT(data.auth, this.ws2pVersion, data.challenge, data.sig, data.pub, data.currency, (this.ws2pVersion > 1) ? data.ws2pID:"")
if (valid) {
await this.remoteAuth.sendACK(this.ws)
} else {
......
......@@ -126,14 +126,14 @@ describe("CLI", function() {
it('sync 7 blocks (fast)', async () => {
await execute(['reset', 'data']);
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), 'duniter_unit_test_currency', '--nocautious', '--nointeractive', '--noshuffle', '--up-to', '7']);
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), '--nocautious', '--nointeractive', '--noshuffle', '7']);
const res = await execute(['export-bc', '--nostdout']);
res[res.length - 1].should.have.property('number').equal(7);
res.should.have.length(7 + 1); // blocks #0..#7
})
it('sync 4 blocks (cautious)', async () => {
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), 'duniter_unit_test_currency', '--nointeractive', '--up-to', '11']);
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), '--nointeractive', '11']);
const res = await execute(['export-bc', '--nostdout']);
res[res.length - 1].should.have.property('number').equal(11);
res.should.have.length(11 + 1);
......@@ -146,7 +146,7 @@ describe("CLI", function() {
})
it('[spawn] sync 10 first blocks --memory', async () => {
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), 'duniter_unit_test_currency', '--memory', '--cautious', '--nointeractive', '--up-to', '10']);
await execute(['sync', fakeServer.host + ':' + String(fakeServer.port), '--memory', '--cautious', '--nointeractive', '10']);
})
});
......
......@@ -699,7 +699,7 @@ export class TestingServer {
const connection = WS2PConnection.newConnectionToAddress(1,
`ws://${HOST}:${port}`,
new WS2PServerMessageHandler(this._server, api.getCluster()),
new constructor(this.conf.currency, pair, ws2pId),
new constructor("", pair, ws2pId),
new WS2PPubkeyRemoteAuth(this.conf.currency, pair)
)
return WS2PRequester.fromConnection(connection)
......
......@@ -60,7 +60,7 @@ describe('WS2P', () => {
})
it('should be able to create a connection', async () => {
const ws2p = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:' + portA, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth())
const ws2p = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:' + portA, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth(gtest))
const res = await ws2p.request({ name: 'head' })
assert.deepEqual({ bla: 'aa' }, res)
})
......@@ -139,7 +139,7 @@ describe('WS2P', () => {
it('should accept the connection if the server answers with a good signature', async () => {
const keypair = new Key('HgTTJLAQ5sqfknMq7yLPZbehtuLSsKj9CxWN7k8QvYJd', '51w4fEShBk1jCMauWu4mLpmDVfHksKmWcygpxriqCEZizbtERA6de4STKRkQBpxmMUwsKXRjSzuQ8ECwmqN1u2DP')
const ws2p = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair, ""), new WS2PNoRemoteAuth(), undefined, {
const ws2p = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:20903', new WS2PMutedHandler(), new WS2PPubkeyLocalAuth(gtest, keypair, ""), new WS2PNoRemoteAuth(gtest), undefined, {
connectionTimeout: 1000,
requestTimeout: 1000
})
......@@ -171,7 +171,7 @@ describe('WS2P', () => {
async answerToRequest(json: any): Promise<WS2PResponse> {
return { answer: 'world' }
}
}), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth())
}), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth(gtest))
s1.connect().catch(e => logger.error('WS2P: newConnectionFromWebSocketServer connection error'))
break
case 1:
......@@ -182,7 +182,7 @@ describe('WS2P', () => {
async answerToRequest(json: any): Promise<WS2PResponse> {
return { answer: 'this is s2![j = ' + (j++) + ']' }
}
}), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth())
}), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth(gtest))
s2.connect().catch(e => logger.error('WS2P: newConnectionFromWebSocketServer connection error'))
break
}
......@@ -196,7 +196,7 @@ describe('WS2P', () => {
it('should be able to create connections and make several requests', async () => {
// connection 1
const c1 = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:' + portB, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth())
const c1 = WS2PConnection.newConnectionToAddress(1, 'ws://localhost:' + portB, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth(gtest))
assert.deepEqual({ answer: 'world' }, await c1.request({ name: 'hello!' }))
assert.deepEqual({ answer: 'world' }, await c1.request({ name: 'hello2!' }))
assert.equal(s1.nbRequests, 0)
......@@ -208,7 +208,7 @@ describe('WS2P', () => {
assert.equal(s1.nbPushsByRemote, 0)
assert.equal(c1.nbPushsByRemote, 0)
// connection 2
const c2 = WS2PConnection.newConnectionToAddress(1 ,'ws://localhost:' + portB, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth())
const c2 = WS2PConnection.newConnectionToAddress(1 ,'ws://localhost:' + portB, new WS2PMutedHandler(), new WS2PNoLocalAuth(), new WS2PNoRemoteAuth(gtest))
assert.deepEqual({ answer: 'this is s2![j = 0]' }, await c2.request({ name: 'test?' }))
assert.deepEqual({ answer: 'this is s2![j = 1]' }, await c2.request({ name: 'test!' }))
assert.deepEqual({ answer: 'this is s2![j = 2]' }, await c2.request({ name: 'test!!!' }))
......@@ -427,10 +427,18 @@ class WS2PNoLocalAuth implements WS2PLocalAuth {
async authenticationIsDone(): Promise<void> {
}
currency: string
}
class WS2PNoRemoteAuth implements WS2PRemoteAuth {
givenCurrency: Promise<string>
constructor(currency: string) {
this.givenCurrency = Promise.resolve(currency)
}
getVersion(): number {
return 1
}
......@@ -442,7 +450,8 @@ class WS2PNoRemoteAuth implements WS2PRemoteAuth {
async sendACK(ws: any): Promise<void> {
}
async registerCONNECT(type: 'CONNECT'|'SYNC', version:number, challenge:string, sig: string, pub: string, ws2pId:string): Promise<boolean> {
async registerCONNECT(type: 'CONNECT'|'SYNC', version:number, challenge:string, sig: string, pub: string, currency:string, ws2pId:string): Promise<boolean> {
this.givenCurrency = Promise.resolve(currency)
return true
}
......
......@@ -54,7 +54,7 @@ describe('WS2P sync', () => writeBasicTestWith2Users((test) => {
const s2 = NewTestingServer({ pair: cat.keypair })
await s2.initWithDAL()
// We sync on s1
await CrawlerDependency.duniter.methods.synchronize(s1.conf.currency, s2._server, ws2p.host, ws2p.port, 2, 2).syncPromise
await CrawlerDependency.duniter.methods.synchronize(s2._server, ws2p.host, ws2p.port, 2, 2).syncPromise
assertNotNull(await s2.dal.getCurrentBlockOrNull())
})
}))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment