@@ -9,7 +9,7 @@ using namespace pc;
9
9
#define PC_RPC_HTTP_PORT 8899
10
10
#define PC_RECONNECT_TIMEOUT (120L *1000000000L )
11
11
#define PC_BLOCKHASH_TIMEOUT 3
12
- #define PC_PUB_INTERVAL (227L *PC_NSECS_IN_MSEC)
12
+ #define PC_PUB_INTERVAL (400L *PC_NSECS_IN_MSEC)
13
13
#define PC_RPC_HOST " localhost"
14
14
#define PC_MAX_BATCH 8
15
15
// Flush partial batches if not completed within 400 ms.
@@ -76,7 +76,9 @@ manager::manager()
76
76
is_pub_( false ),
77
77
cmt_( commitment::e_confirmed ),
78
78
max_batch_( PC_MAX_BATCH ),
79
- sreq_{ { commitment::e_processed } }
79
+ sreq_{ { commitment::e_processed } },
80
+ secondary_{ nullptr },
81
+ is_secondary_ ( false )
80
82
{
81
83
tconn_.set_sub ( this );
82
84
breq_->set_sub ( this );
@@ -98,6 +100,9 @@ manager::~manager()
98
100
delete ptr;
99
101
}
100
102
svec_.clear ();
103
+ if ( has_secondary () ) {
104
+ delete secondary_;
105
+ }
101
106
}
102
107
103
108
bool manager::tx_parser::parse ( const char *, size_t len, size_t & res )
@@ -116,7 +121,7 @@ void manager::del_map_sub()
116
121
{
117
122
if ( --num_sub_ <= 0 && !has_status ( PC_PYTH_HAS_MAPPING ) ) {
118
123
set_status ( PC_PYTH_HAS_MAPPING );
119
- PC_LOG_INF ( " completed_mapping_init" ).end ();
124
+ PC_LOG_INF ( " completed_mapping_init" ).add ( " secondary " , get_is_secondary () ). end ();
120
125
// notify user that initialization is complete
121
126
if ( sub_ ) {
122
127
sub_->on_init ( this );
@@ -266,7 +271,7 @@ uint64_t manager::get_slot() const
266
271
267
272
void manager::teardown ()
268
273
{
269
- PC_LOG_INF ( " pythd_teardown" ).end ();
274
+ PC_LOG_INF ( " pythd_teardown" ).add ( " secondary " , get_is_secondary () ). end ();
270
275
271
276
// shutdown listener
272
277
lsvr_.close ();
@@ -287,6 +292,11 @@ void manager::teardown()
287
292
wconn_ = nullptr ;
288
293
clnt_.set_ws_conn ( nullptr );
289
294
}
295
+
296
+ // Shutdown secondary messenger
297
+ if ( has_secondary () ) {
298
+ get_secondary ()->teardown ();
299
+ }
290
300
}
291
301
292
302
bool manager::init ()
@@ -299,15 +309,15 @@ bool manager::init()
299
309
// log import key names
300
310
key_pair *kp = get_publish_key_pair ();
301
311
if ( kp ) {
302
- PC_LOG_INF ( " publish_key" ).add ( " key_name" , *kp ).end ();
312
+ PC_LOG_INF ( " publish_key" ).add ( " key_name" , *kp ).add ( " secondary " , get_is_secondary () ). end ();
303
313
}
304
314
pub_key *mpub = get_mapping_pub_key ();
305
315
if ( mpub ) {
306
- PC_LOG_INF ( " mapping_key" ).add ( " key_name" , *mpub ).end ();
316
+ PC_LOG_INF ( " mapping_key" ).add ( " key_name" , *mpub ).add ( " secondary " , get_is_secondary () ). end ();
307
317
}
308
318
pub_key *gpub = get_program_pub_key ();
309
319
if ( gpub ) {
310
- PC_LOG_INF ( " program_key" ).add ( " key_name" , *gpub ).end ();
320
+ PC_LOG_INF ( " program_key" ).add ( " key_name" , *gpub ).add ( " secondary " , get_is_secondary () ). end ();
311
321
}
312
322
313
323
// initialize capture
@@ -365,10 +375,12 @@ bool manager::init()
365
375
return set_err_msg ( lsvr_.get_err_msg () );
366
376
}
367
377
PC_LOG_INF (" listening" ).add (" port" ,lsvr_.get_port ())
378
+ .add ( " secondary" , get_is_secondary () )
368
379
.add ( " content_dir" , get_content_dir () )
369
380
.end ();
370
381
}
371
382
PC_LOG_INF ( " initialized" )
383
+ .add ( " secondary" , get_is_secondary () )
372
384
.add ( " version" , PC_VERSION )
373
385
.add ( " rpc_host" , get_rpc_host () )
374
386
.add ( " tx_host" , get_tx_host () )
@@ -377,9 +389,48 @@ bool manager::init()
377
389
.add ( " publish_interval(ms)" , get_publish_interval () )
378
390
.end ();
379
391
392
+ // Initialize secondary network manager
393
+ if ( has_secondary () ) {
394
+ PC_LOG_INF (" initializing secondary manager" ).end ();
395
+ secondary_->init ();
396
+ PC_LOG_INF (" initialized secondary manager" ).end ();
397
+ }
398
+
380
399
return true ;
381
400
}
382
401
402
+ void manager::add_secondary ( const std::string& rpc_host, const std::string& key_dir )
403
+ {
404
+
405
+ manager *mgr = new manager;
406
+ mgr->set_dir ( key_dir );
407
+ mgr->set_rpc_host ( rpc_host );
408
+ mgr->set_tx_host ( thost_ );
409
+ mgr->set_do_tx ( do_tx_ );
410
+ mgr->set_do_ws ( do_ws_ );
411
+ mgr->set_commitment ( cmt_ );
412
+ mgr->set_is_secondary ( true );
413
+
414
+ secondary_ = mgr;
415
+
416
+ }
417
+
418
+ bool manager::has_secondary () const {
419
+ return secondary_ != nullptr ;
420
+ }
421
+
422
+ void manager::set_is_secondary (bool is_secondary) {
423
+ is_secondary_ = is_secondary;
424
+ }
425
+
426
+ bool manager::get_is_secondary () const {
427
+ return is_secondary_;
428
+ }
429
+
430
+ manager *manager::get_secondary () {
431
+ return secondary_;
432
+ }
433
+
383
434
bool manager::get_is_tx_send () const
384
435
{
385
436
return tconn_.get_is_send ();
@@ -527,6 +578,9 @@ void manager::poll( bool do_wait )
527
578
}
528
579
}
529
580
581
+ // request quotes from the publishers
582
+ poll_schedule ();
583
+
530
584
// try to (re)connect to tx proxy
531
585
if ( do_tx_ && ( !tconn_.get_is_connect () || tconn_.get_is_err () ) ) {
532
586
tconn_.reconnect ();
@@ -535,17 +589,28 @@ void manager::poll( bool do_wait )
535
589
if ( has_status ( PC_PYTH_RPC_CONNECTED ) &&
536
590
!hconn_.get_is_err () &&
537
591
( !wconn_ || !wconn_->get_is_err () ) ) {
538
- // request product quotes from pythd's clients while connected
539
- poll_schedule ();
540
-
541
592
send_pending_ups ();
542
593
} else {
543
594
reconnect_rpc ();
544
595
}
596
+
597
+ // Call the secondary manager's poll loop if necessary
598
+ if ( has_secondary () ) {
599
+ secondary_->poll ();
600
+ }
545
601
}
546
602
547
603
void manager::poll_schedule ()
548
604
{
605
+ // Enable publishing mode if enough time has elapsed since last time.
606
+ int64_t time_since_last_stagger = curr_ts_ - pub_ts_;
607
+ if ( !is_pub_ && ( time_since_last_stagger > pub_int_ ) ) {
608
+ is_pub_ = true ;
609
+ kidx_ = 0 ;
610
+ pub_ts_ = curr_ts_;
611
+ }
612
+
613
+ // Schedule the price_sched requests in a staggered fashion.
549
614
while ( is_pub_ && kidx_ < kvec_.size () ) {
550
615
price_sched *kptr = kvec_[kidx_];
551
616
int64_t pub_ts = pub_ts_ + static_cast < int64_t >(
@@ -578,15 +643,12 @@ void manager::reconnect_rpc()
578
643
579
644
// check for successful (re)connect
580
645
if ( !hconn_.get_is_err () && ( !wconn_ || !wconn_->get_is_err () ) ) {
581
- PC_LOG_INF ( " rpc_connected" ).end ();
646
+ PC_LOG_INF ( " rpc_connected" ).add ( " secondary " , get_is_secondary () ). end ();
582
647
set_status ( PC_PYTH_RPC_CONNECTED );
583
648
584
649
// reset state
585
650
wait_conn_ = false ;
586
- is_pub_ = false ;
587
- kidx_ = 0 ;
588
651
ctimeout_ = PC_NSECS_IN_SEC;
589
- pub_ts_ = 0L ;
590
652
slot_ = 0L ;
591
653
slot_cnt_ = 0UL ;
592
654
slot_ts_ = 0L ;
@@ -685,6 +747,7 @@ void manager::log_disconnect()
685
747
{
686
748
if ( hconn_.get_is_err () ) {
687
749
PC_LOG_ERR ( " rpc_http_reset" )
750
+ .add ( " secondary" , get_is_secondary () )
688
751
.add ( " error" , hconn_.get_err_msg () )
689
752
.add ( " host" , rhost_ )
690
753
.add ( " port" , hconn_.get_port () )
@@ -693,6 +756,7 @@ void manager::log_disconnect()
693
756
}
694
757
if ( wconn_ && wconn_->get_is_err () ) {
695
758
PC_LOG_ERR ( " rpc_websocket_reset" )
759
+ .add ( " secondary" , get_is_secondary () )
696
760
.add ( " error" , wconn_->get_err_msg () )
697
761
.add ( " host" , rhost_ )
698
762
.add ( " port" , wconn_->get_port () )
@@ -770,20 +834,14 @@ void manager::on_response( rpc::get_slot *res )
770
834
PC_LOG_DBG ( " received get_slot" )
771
835
.add ( " slot" , slot_ )
772
836
.add ( " round_trip_time(ms)" , 1e-6 *ack_ts )
837
+ .add ( " secondary" , get_is_secondary () )
773
838
.end ();
774
839
775
840
// submit block hash every N slots
776
841
if ( slot_cnt_++ % PC_BLOCKHASH_TIMEOUT == 0 ) {
777
842
clnt_.send ( breq_ );
778
843
}
779
844
780
- // reset submit
781
- if ( !is_pub_ ) {
782
- kidx_ = 0 ;
783
- pub_ts_ = ts;
784
- is_pub_ = true ;
785
- }
786
-
787
845
// flush capture
788
846
if ( do_cap_ ) {
789
847
cap_.flush ();
@@ -812,6 +870,7 @@ void manager::on_response( rpc::get_recent_block_hash *m )
812
870
// set initialized status for block hash
813
871
set_status ( PC_PYTH_HAS_BLOCK_HASH );
814
872
PC_LOG_INF ( " received_recent_block_hash" )
873
+ .add ( " secondary" , get_is_secondary () )
815
874
.add ( " curr_slot" , slot_ )
816
875
.add ( " hash_slot" , m->get_slot () )
817
876
.add ( " round_trip_time(ms)" , 1e-6 *ack_ts )
@@ -830,13 +889,15 @@ void manager::on_response( rpc::account_update *m )
830
889
if ( m->get_is_http () ) {
831
890
int64_t ack_ts = m->get_recv_time () - m->get_sent_time ();
832
891
PC_LOG_DBG ( " received account_update" )
892
+ .add ( " secondary" , get_is_secondary () )
833
893
.add ( " account" , *m->get_account () )
834
894
.add ( " slot" , slot_ )
835
895
.add ( " round_trip_time(ms)" , 1e-6 *ack_ts )
836
896
.end ();
837
897
}
838
898
else {
839
899
PC_LOG_DBG ( " received account_update" )
900
+ .add ( " secondary" , get_is_secondary () )
840
901
.add ( " account" , *m->get_account () )
841
902
.add ( " slot" , slot_ )
842
903
.end ();
@@ -883,12 +944,14 @@ bool manager::submit_poll( request *req )
883
944
}
884
945
if ( req->get_is_err () ) {
885
946
PC_LOG_ERR ( " request error" )
947
+ .add ( " secondary" , get_is_secondary () )
886
948
.add ( " error" , req->get_err_msg () )
887
949
.end ();
888
950
return false ;
889
951
}
890
952
if ( get_is_err () ) {
891
953
PC_LOG_ERR ( " request error" )
954
+ .add ( " secondary" , get_is_secondary () )
892
955
.add ( " error" , get_err_msg () )
893
956
.end ();
894
957
return false ;
@@ -908,7 +971,7 @@ void manager::on_connect()
908
971
void manager::on_disconnect ()
909
972
{
910
973
// callback user with connection status
911
- PC_LOG_INF ( " pyth_tx_reset" ).end ();
974
+ PC_LOG_INF ( " pyth_tx_reset" ).add ( " secondary " , get_is_secondary () ). end ();
912
975
if ( sub_ ) {
913
976
sub_->on_tx_disconnect ( this );
914
977
}
0 commit comments