@@ -5,10 +5,11 @@ use flate2::read::GzDecoder;
5
5
use key_utils:: { Secp256k1PublicKey , Secp256k1SecretKey } ;
6
6
use once_cell:: sync:: Lazy ;
7
7
use pool_sv2:: PoolSv2 ;
8
+ use rand:: { thread_rng, Rng } ;
8
9
use sniffer:: Sniffer ;
9
10
use std:: {
10
11
collections:: HashSet ,
11
- convert:: TryFrom ,
12
+ convert:: { TryFrom , TryInto } ,
12
13
env,
13
14
fs:: { create_dir_all, File } ,
14
15
io:: { BufReader , Read } ,
@@ -380,3 +381,88 @@ pub async fn start_jds(tp_address: SocketAddr) -> SocketAddr {
380
381
tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 2 ) ) . await ;
381
382
listen_jd_address
382
383
}
384
+
385
+ pub async fn start_sv2_translator ( upstream : SocketAddr ) -> SocketAddr {
386
+ let upstream_address = upstream. ip ( ) . to_string ( ) ;
387
+ let upstream_port = upstream. port ( ) ;
388
+ let upstream_authority_pubkey = Secp256k1PublicKey :: try_from (
389
+ "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" . to_string ( ) ,
390
+ )
391
+ . expect ( "failed" ) ;
392
+ let listening_address = get_available_address ( ) ;
393
+ let listening_port = listening_address. port ( ) ;
394
+ let hashrate = measure_hashrate ( 3 ) as f32 / 100.0 ;
395
+ let min_individual_miner_hashrate = hashrate;
396
+ let shares_per_minute = 60.0 ;
397
+ let channel_diff_update_interval = 60 ;
398
+ let channel_nominal_hashrate = hashrate;
399
+ let downstream_difficulty_config =
400
+ translator_sv2:: proxy_config:: DownstreamDifficultyConfig :: new (
401
+ min_individual_miner_hashrate,
402
+ shares_per_minute,
403
+ 0 ,
404
+ 0 ,
405
+ ) ;
406
+ let upstream_difficulty_config = translator_sv2:: proxy_config:: UpstreamDifficultyConfig :: new (
407
+ channel_diff_update_interval,
408
+ channel_nominal_hashrate,
409
+ 0 ,
410
+ false ,
411
+ ) ;
412
+ let upstream_conf = translator_sv2:: proxy_config:: UpstreamConfig :: new (
413
+ upstream_address,
414
+ upstream_port,
415
+ upstream_authority_pubkey,
416
+ upstream_difficulty_config,
417
+ ) ;
418
+ let downstream_conf = translator_sv2:: proxy_config:: DownstreamConfig :: new (
419
+ listening_address. ip ( ) . to_string ( ) ,
420
+ listening_port,
421
+ downstream_difficulty_config,
422
+ ) ;
423
+
424
+ let config =
425
+ translator_sv2:: proxy_config:: ProxyConfig :: new ( upstream_conf, downstream_conf, 2 , 2 , 8 ) ;
426
+ let translator_v2 = translator_sv2:: TranslatorSv2 :: new ( config) ;
427
+ tokio:: spawn ( async move {
428
+ translator_v2. start ( ) . await ;
429
+ } ) ;
430
+ tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 1 ) ) . await ;
431
+ listening_address
432
+ }
433
+
434
+ fn measure_hashrate ( duration_secs : u64 ) -> f64 {
435
+ use stratum_common:: bitcoin:: hashes:: { sha256d, Hash , HashEngine } ;
436
+
437
+ let mut share = {
438
+ let mut rng = thread_rng ( ) ;
439
+ let mut arr = [ 0u8 ; 80 ] ;
440
+ rng. fill ( & mut arr[ ..] ) ;
441
+ arr
442
+ } ;
443
+ let start_time = std:: time:: Instant :: now ( ) ;
444
+ let mut hashes: u64 = 0 ;
445
+ let duration = std:: time:: Duration :: from_secs ( duration_secs) ;
446
+
447
+ let hash = |share : & mut [ u8 ; 80 ] | {
448
+ let nonce: [ u8 ; 8 ] = share[ 0 ..8 ] . try_into ( ) . unwrap ( ) ;
449
+ let mut nonce = u64:: from_le_bytes ( nonce) ;
450
+ nonce += 1 ;
451
+ share[ 0 ..8 ] . copy_from_slice ( & nonce. to_le_bytes ( ) ) ;
452
+ let mut engine = sha256d:: Hash :: engine ( ) ;
453
+ engine. input ( share) ;
454
+ sha256d:: Hash :: from_engine ( engine) . into_inner ( ) ;
455
+ } ;
456
+
457
+ loop {
458
+ if start_time. elapsed ( ) >= duration {
459
+ break ;
460
+ }
461
+ hash ( & mut share) ;
462
+ hashes += 1 ;
463
+ }
464
+
465
+ let elapsed_secs = start_time. elapsed ( ) . as_secs_f64 ( ) ;
466
+
467
+ hashes as f64 / elapsed_secs
468
+ }
0 commit comments