@@ -467,12 +467,19 @@ impl Neighbor {
467
467
Ok ( ( ) )
468
468
}
469
469
470
- pub fn from_handshake (
470
+ /// Instantiate a Neighbor from HandshakeData, merging the information we have on-disk in the
471
+ /// PeerDB with information in the handshake.
472
+ /// * If we already know about this neighbor, then all previously-calculated state and local
473
+ /// configuration state will be loaded as well. This includes things like the calculated
474
+ /// in/out-degree and last-contact time, as well as the allow/deny time limits.
475
+ /// * If we do not know about this neighbor, then the above state will not be loaded.
476
+ /// Returns (the neighbor, whether or not the neighbor was known)
477
+ pub fn load_and_update (
471
478
conn : & DBConn ,
472
479
peer_version : u32 ,
473
480
network_id : u32 ,
474
481
handshake_data : & HandshakeData ,
475
- ) -> Result < Neighbor , net_error > {
482
+ ) -> Result < ( Neighbor , bool ) , net_error > {
476
483
let addr = NeighborKey :: from_handshake ( peer_version, network_id, handshake_data) ;
477
484
let pubk = handshake_data
478
485
. node_public_key
@@ -482,15 +489,15 @@ impl Neighbor {
482
489
let peer_opt = PeerDB :: get_peer ( conn, network_id, & addr. addrbytes , addr. port )
483
490
. map_err ( net_error:: DBError ) ?;
484
491
485
- let mut neighbor = match peer_opt {
492
+ let ( mut neighbor, present ) = match peer_opt {
486
493
Some ( neighbor) => {
487
494
let mut ret = neighbor;
488
495
ret. addr = addr. clone ( ) ;
489
- ret
496
+ ( ret, true )
490
497
}
491
498
None => {
492
499
let ret = Neighbor :: empty ( & addr, & pubk, handshake_data. expire_block_height ) ;
493
- ret
500
+ ( ret, false )
494
501
}
495
502
} ;
496
503
@@ -510,7 +517,7 @@ impl Neighbor {
510
517
}
511
518
512
519
neighbor. handshake_update ( conn, & handshake_data) ?;
513
- Ok ( neighbor)
520
+ Ok ( ( neighbor, present ) )
514
521
}
515
522
516
523
pub fn from_conversation (
@@ -1250,13 +1257,13 @@ impl ConversationP2P {
1250
1257
if updated {
1251
1258
// save the new key
1252
1259
let mut tx = peerdb. tx_begin ( ) . map_err ( net_error:: DBError ) ?;
1253
- let mut neighbor = Neighbor :: from_handshake (
1260
+ let ( mut neighbor, _ ) = Neighbor :: load_and_update (
1254
1261
& mut tx,
1255
1262
message. preamble . peer_version ,
1256
1263
message. preamble . network_id ,
1257
1264
& handshake_data,
1258
1265
) ?;
1259
- neighbor. save_update ( & mut tx) ?;
1266
+ neighbor. save_update ( & mut tx, None ) ?;
1260
1267
tx. commit ( )
1261
1268
. map_err ( |e| net_error:: DBError ( db_error:: SqliteError ( e) ) ) ?;
1262
1269
@@ -1277,10 +1284,7 @@ impl ConversationP2P {
1277
1284
accept_data,
1278
1285
StackerDBHandshakeData {
1279
1286
rc_consensus_hash : chain_view. rc_consensus_hash . clone ( ) ,
1280
- // placeholder sbtc address for now
1281
- smart_contracts : vec ! [
1282
- ContractId :: parse( "SP000000000000000000002Q6VF78.sbtc" ) . unwrap( )
1283
- ] ,
1287
+ smart_contracts : local_peer. stacker_dbs . clone ( ) ,
1284
1288
} ,
1285
1289
)
1286
1290
} else {
@@ -1401,11 +1405,12 @@ impl ConversationP2P {
1401
1405
let epoch = self . get_current_epoch ( chain_view. burn_block_height ) ;
1402
1406
1403
1407
// get neighbors at random as long as they're fresh, and as long as they're compatible with
1404
- // the current system epoch
1405
- let mut neighbors = PeerDB :: get_random_neighbors (
1408
+ // the current system epoch.
1409
+ let mut neighbors = PeerDB :: get_fresh_random_neighbors (
1406
1410
peer_dbconn,
1407
1411
self . network_id ,
1408
1412
epoch. network_epoch ,
1413
+ ( get_epoch_time_secs ( ) as u64 ) . saturating_sub ( self . connection . options . max_neighbor_age ) ,
1409
1414
MAX_NEIGHBORS_DATA_LEN ,
1410
1415
chain_view. burn_block_height ,
1411
1416
false ,
@@ -2664,6 +2669,7 @@ mod test {
2664
2669
data_url. clone ( ) ,
2665
2670
& asn4_entries,
2666
2671
Some ( & initial_neighbors) ,
2672
+ & vec ! [ ContractId :: parse( "SP000000000000000000002Q6VF78.sbtc" ) . unwrap( ) ] ,
2667
2673
)
2668
2674
. unwrap ( ) ;
2669
2675
let sortdb = SortitionDB :: connect (
@@ -3188,15 +3194,16 @@ mod test {
3188
3194
assert_eq ! ( data. handshake. data_url, "http://peer2.com" . into( ) ) ;
3189
3195
assert_eq ! ( data. heartbeat_interval, conn_opts. heartbeat) ;
3190
3196
3191
- // remote peer always replies with its supported smart contracts
3192
- assert_eq ! (
3193
- db_data. smart_contracts,
3194
- vec![ ContractId :: parse( "SP000000000000000000002Q6VF78.sbtc" ) . unwrap( ) ]
3195
- ) ;
3196
-
3197
3197
if peer_1_rc_consensus_hash == peer_2_rc_consensus_hash {
3198
3198
assert_eq ! ( db_data. rc_consensus_hash, chain_view_1. rc_consensus_hash) ;
3199
3199
3200
+ // remote peer always replies with its supported smart contracts
3201
+ assert_eq ! (
3202
+ db_data. smart_contracts,
3203
+ vec![ ContractId :: parse( "SP000000000000000000002Q6VF78.sbtc" )
3204
+ . unwrap( ) ]
3205
+ ) ;
3206
+
3200
3207
// peers learn each others' smart contract DBs
3201
3208
eprintln ! (
3202
3209
"{:?}, {:?}" ,
@@ -5519,6 +5526,7 @@ mod test {
5519
5526
None ,
5520
5527
get_epoch_time_secs ( ) + 123456 ,
5521
5528
UrlString :: try_from ( "http://foo.com" ) . unwrap ( ) ,
5529
+ vec ! [ ] ,
5522
5530
) ;
5523
5531
let mut convo = ConversationP2P :: new (
5524
5532
123 ,
0 commit comments