@@ -30,6 +30,9 @@ var _require3 = require('./peer'),
30
30
var _require4 = require ( './iri' ) ,
31
31
DEFAULT_IRI_OPTIONS = _require4 . DEFAULT_OPTIONS ;
32
32
33
+ var _require5 = require ( './utils' ) ,
34
+ getSecondsPassed = _require5 . getSecondsPassed ;
35
+
33
36
var DEFAULT_OPTIONS = {
34
37
dataPath : path . join ( process . cwd ( ) , 'data/neighbors.db' ) ,
35
38
multiPort : false ,
@@ -146,6 +149,17 @@ var PeerList = function (_Base) {
146
149
} ;
147
150
return refreshPeer ? peer . update ( newData , false ) . then ( updater ) : updater ( ) ;
148
151
}
152
+ } , {
153
+ key : 'markConnected' ,
154
+ value : function markConnected ( peer ) {
155
+ var increaseWeight = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : false ;
156
+
157
+ return this . update ( peer , {
158
+ connected : peer . data . connected + 1 ,
159
+ weight : peer . data . weight * ( increaseWeight ? 1.01 : 1 ) ,
160
+ dateLastConnected : new Date ( )
161
+ } ) ;
162
+ }
149
163
150
164
/**
151
165
* Returns currently loaded peers.
@@ -230,6 +244,42 @@ var PeerList = function (_Base) {
230
244
} ) ;
231
245
}
232
246
247
+ /**
248
+ * Returns average age of all known peers.
249
+ * @returns {number }
250
+ * @private
251
+ */
252
+
253
+ } , {
254
+ key : '_getAverageAge' ,
255
+ value : function _getAverageAge ( ) {
256
+ if ( ! this . peers . length ) {
257
+ return 1 ;
258
+ }
259
+ var ages = this . peers . map ( function ( p ) {
260
+ return getSecondsPassed ( p . data . dateCreated ) ;
261
+ } ) ;
262
+ return ages . reduce ( function ( sum , x ) {
263
+ return sum + x ;
264
+ } ) / this . peers . length ;
265
+ }
266
+
267
+ /**
268
+ * Calculates the weight of a peer
269
+ * @param {Peer } peer
270
+ * @param {number } averageAge
271
+ * @returns {number }
272
+ */
273
+
274
+ } , {
275
+ key : 'getPeerWeight' ,
276
+ value : function getPeerWeight ( peer , averageAge ) {
277
+ averageAge = averageAge || this . _getAverageAge ( ) ;
278
+ var normalizedAge = Math . max ( getSecondsPassed ( peer . data . dateCreated ) - averageAge , 1 ) ;
279
+ var weightedAgeMinutes = normalizedAge / 60.0 * peer . data . weight ;
280
+ return Math . max ( Math . pow ( weightedAgeMinutes , 2 ) , 0.00001 ) ;
281
+ }
282
+
233
283
/**
234
284
* Get a certain amount of weighted random peers.
235
285
* The weight depends on relationship age (connections) and trust (weight).
@@ -240,9 +290,12 @@ var PeerList = function (_Base) {
240
290
} , {
241
291
key : 'getWeighted' ,
242
292
value : function getWeighted ( ) {
293
+ var _this7 = this ;
294
+
243
295
var amount = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : 0 ;
244
296
245
297
amount = amount || this . peers . length ;
298
+ var averageAge = this . _getAverageAge ( ) ;
246
299
var peers = Array . from ( this . peers ) ;
247
300
if ( ! peers . length ) {
248
301
return [ ] ;
@@ -251,7 +304,7 @@ var PeerList = function (_Base) {
251
304
var choices = [ ] ;
252
305
var getChoice = function getChoice ( ) {
253
306
var peer = weighted ( peers , peers . map ( function ( p ) {
254
- return Math . max ( p . data . connected * p . data . weight , 1 ) ;
307
+ return _this7 . getPeerWeight ( p , averageAge ) ;
255
308
} ) ) ;
256
309
peers . splice ( peers . indexOf ( peer ) , 1 ) ;
257
310
choices . push ( peer ) ;
@@ -287,7 +340,7 @@ var PeerList = function (_Base) {
287
340
var TCPPort = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : DEFAULT_IRI_OPTIONS . TCPPort ;
288
341
var UDPPort = arguments . length > 3 && arguments [ 3 ] !== undefined ? arguments [ 3 ] : DEFAULT_IRI_OPTIONS . UDPPort ;
289
342
290
- var _this7 = this ;
343
+ var _this8 = this ;
291
344
292
345
var isTrusted = arguments . length > 4 && arguments [ 4 ] !== undefined ? arguments [ 4 ] : false ;
293
346
var weight = arguments . length > 5 && arguments [ 5 ] !== undefined ? arguments [ 5 ] : 0 ;
@@ -302,21 +355,21 @@ var PeerList = function (_Base) {
302
355
// If the hostname already exists and no multiple ports from same hostname are allowed,
303
356
// update existing with port. Otherwise just return the existing peer.
304
357
if ( existing ) {
305
- if ( ! _this7 . opts . multiPort && ( port !== existing . data . port || TCPPort !== existing . data . TCPPort || UDPPort !== existing . data . UDPPort ) ) {
306
- return _this7 . update ( existing , { port : port , TCPPort : TCPPort , UDPPort : UDPPort } ) ;
358
+ if ( ! _this8 . opts . multiPort && ( port !== existing . data . port || TCPPort !== existing . data . TCPPort || UDPPort !== existing . data . UDPPort ) ) {
359
+ return _this8 . update ( existing , { port : port , TCPPort : TCPPort , UDPPort : UDPPort } ) ;
307
360
} else if ( existing . data . weight < weight ) {
308
- return _this7 . update ( existing , { weight : weight } ) ;
361
+ return _this8 . update ( existing , { weight : weight } ) ;
309
362
} else {
310
363
return existing ;
311
364
}
312
365
} else {
313
- _this7 . log ( 'adding' , hostname , port ) ;
366
+ _this8 . log ( 'adding' , hostname , port ) ;
314
367
var peerIP = ip . isV4Format ( addr ) || ip . isV6Format ( addr ) ? addr : null ;
315
- var peer = new Peer ( { port : port , hostname : addr , ip : peerIP , TCPPort : TCPPort , UDPPort : UDPPort , isTrusted : isTrusted , weight : weight } , { onDataUpdate : _this7 . onPeerUpdate } ) ;
316
- _this7 . peers . push ( peer ) ;
317
- _this7 . log ( 'added' , hostname , port , _this7 . peers . length ) ;
368
+ var peer = new Peer ( { port : port , hostname : addr , ip : peerIP , TCPPort : TCPPort , UDPPort : UDPPort , isTrusted : isTrusted , weight : weight , dateCreated : new Date ( ) } , { onDataUpdate : _this8 . onPeerUpdate } ) ;
369
+ _this8 . peers . push ( peer ) ;
370
+ _this8 . log ( 'added' , hostname , port , _this8 . peers . length ) ;
318
371
return new Promise ( function ( resolve , reject ) {
319
- _this7 . db . insert ( peer . data , function ( err , doc ) {
372
+ _this8 . db . insert ( peer . data , function ( err , doc ) {
320
373
if ( err ) {
321
374
reject ( err ) ;
322
375
}
0 commit comments