@@ -8,14 +8,16 @@ use tokio::net::TcpStream;
88use tokio:: io:: { AsyncWriteExt , AsyncReadExt } ;
99use tokio:: fs:: File ;
1010
11+ use log:: { info, warn, error} ;
12+
1113use sha1:: { Sha1 , Digest } ;
1214use rand:: Rng ;
1315
1416use clap:: { AppSettings , Clap , Subcommand } ;
1517
1618#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
1719pub struct Config {
18- pub devices : Vec < Device >
20+ pub devices : Vec < Device > ,
1921}
2022
2123#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
@@ -58,26 +60,26 @@ struct Generate {
5860 username : String ,
5961 #[ clap( long, default_value = "16" ) ]
6062 device_count : u32 ,
61- #[ clap( long, default_value = "esp -" ) ]
63+ #[ clap( long, default_value = "avr -" ) ]
6264 device_name_prefix : String ,
63- #[ clap( long, default_value = "ESP8266 " ) ]
65+ #[ clap( long, default_value = "AVR " ) ]
6466 device_type : String ,
65- #[ clap( long, default_value = "ESP8266 Miner v2.55 " ) ]
67+ #[ clap( long, default_value = "Official AVR Miner v2.6 " ) ]
6668 firmware : String ,
67- #[ clap( long, default_value = "9200 " ) ]
69+ #[ clap( long, default_value = "190 " ) ]
6870 target_rate : u32 ,
6971}
7072
7173#[ derive( Clap ) ]
7274struct Run { }
7375
7476
75- fn generate_5hex ( ) -> String {
77+ fn generate_8hex ( ) -> String {
7678 const HEX_ARRAY : [ char ; 16 ] = [ '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'a' , 'b' , 'c' , 'd' , 'e' , 'f' ] ;
7779
7880 let mut result = String :: new ( ) ;
7981
80- for _ in 0 ..5 {
82+ for _ in 0 ..8 {
8183 let n: usize = rand:: thread_rng ( ) . gen_range ( 0 ..16 ) ;
8284 result. push ( HEX_ARRAY [ n] ) ;
8385 }
@@ -95,7 +97,7 @@ async fn generate_config(file_path: String, gen: &Generate) -> Result<(), Box<dy
9597 username : gen. username . clone ( ) ,
9698 device_name : format ! ( "{}{}" , gen . device_name_prefix, i + 1 ) ,
9799 device_type : gen. device_type . clone ( ) ,
98- chip_id : generate_5hex ( ) ,
100+ chip_id : format ! ( "DUCOID{}" , generate_8hex ( ) ) ,
99101 firmware : gen. firmware . clone ( ) ,
100102 target_rate : gen. target_rate ,
101103 } ;
@@ -127,11 +129,11 @@ async fn start_miner(device: Device) -> Result<(), MinerError> {
127129 let mut stream = TcpStream :: connect (
128130 format ! ( "{}:{}" , device. host, device. port) ) . await . map_err ( |_| MinerError :: Connection ) ?;
129131
130- // println !("{} connected to pool {}:{}", device.device_name, device.host, device.port);
132+ info ! ( "{} connected to pool {}:{}" , device. device_name, device. host, device. port) ;
131133
132134 let mut cmd_in: [ u8 ; 200 ] = [ 0 ; 200 ] ;
133135 let n = stream. read ( & mut cmd_in) . await . map_err ( |_| MinerError :: RecvCommand ) ?;
134- // println !("version: {}", std::str::from_utf8(&cmd_in[..n])?);
136+ info ! ( "version: {}" , std:: str :: from_utf8( & cmd_in[ ..n] ) . map_err ( |_| MinerError :: InvalidUTF8 ) ?) ;
135137
136138 let expected_interval = 1000000u128 / device. target_rate as u128 ;
137139
@@ -151,7 +153,7 @@ async fn start_miner(device: Device) -> Result<(), MinerError> {
151153 let expected_hash = args[ 1 ] ;
152154 let diff = args[ 2 ] . parse :: < u32 > ( ) . map_err ( |_| MinerError :: MalformedJob ( job. to_string ( ) ) ) ? * 100 + 1 ;
153155
154- // println !("last: {}, expected: {}, diff: {}", last_block_hash, expected_hash, diff);
156+ info ! ( "last: {}, expected: {}, diff: {}" , last_block_hash, expected_hash, diff) ;
155157
156158 let start = SystemTime :: now ( ) ;
157159
@@ -167,27 +169,34 @@ async fn start_miner(device: Device) -> Result<(), MinerError> {
167169 let expected_duration = expected_interval * duco_numeric_result as u128 ;
168170
169171 if duration < expected_duration {
170- tokio:: time:: sleep ( Duration :: from_micros (
171- ( expected_duration - duration) as u64 ) ) . await ;
172- // println!("Waited {} micro sec", expected_duration - duration);
172+ let wait_multiplier: u64 = rand:: thread_rng ( ) . gen_range ( 95 ..105 ) ;
173+ let wait_duration = ( expected_duration - duration) as u64 * wait_multiplier / 100 ;
174+ tokio:: time:: sleep ( Duration :: from_micros ( wait_duration) ) . await ;
175+ info ! ( "Waited {} micro sec" , wait_duration) ;
176+ } else {
177+ warn ! ( "system too slow, lag {} micro sec" , duration - expected_duration) ;
173178 }
174179
175180 let end = SystemTime :: now ( ) ;
176181 let duration = end. duration_since ( start) . unwrap ( ) . as_micros ( ) ;
177182 let emu_rate = duco_numeric_result as f64 / duration as f64 * 1000000f64 ;
178183
184+ let lag_duration: u64 = rand:: thread_rng ( ) . gen_range ( 0 ..100 ) ;
185+ tokio:: time:: sleep ( Duration :: from_millis ( lag_duration) ) . await ;
186+
179187 let cmd_out = format ! ( "{},{:.2},{},{},{}\n " ,
180188 duco_numeric_result, emu_rate, device. firmware, device. device_name, device. chip_id) ;
181189 stream. write ( cmd_out. as_bytes ( ) ) . await . map_err ( |_| MinerError :: SendCommand ) ?;
182190
183191 let n = stream. read ( & mut cmd_in) . await . map_err ( |_| MinerError :: RecvCommand ) ?;
184192 let resp = std:: str:: from_utf8 ( & cmd_in[ ..n] ) . map_err ( |_| MinerError :: InvalidUTF8 ) ?. trim ( ) ;
185193
186- // println!("resp: {}, result: {}, rate: {:.2}, real: {:.2}",
187- // resp, duco_numeric_result, emu_rate, real_rate);
188194 if resp != "GOOD" {
189- println ! ( "resp: {}, result: {}, rate: {:.2}, real: {:.2}" ,
195+ warn ! ( "resp: {}, result: {}, rate: {:.2}, real: {:.2}" ,
190196 resp, duco_numeric_result, emu_rate, real_rate) ;
197+ } else {
198+ info ! ( "resp: {}, result: {}, rate: {:.2}, real: {:.2}" ,
199+ resp, duco_numeric_result, emu_rate, real_rate) ;
191200 }
192201
193202 break ;
@@ -211,6 +220,8 @@ async fn start_miners(devices: Vec<Device>) -> Result<(), MinerError> {
211220
212221#[ tokio:: main]
213222async fn main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
223+ pretty_env_logger:: init ( ) ;
224+
214225 let opts: Opts = Opts :: parse ( ) ;
215226
216227 match opts. sub_command {
@@ -221,13 +232,13 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
221232 let c_serial = tokio:: fs:: read_to_string ( opts. config_file ) . await ?;
222233 let c: Config = serde_yaml:: from_str ( c_serial. as_str ( ) ) ?;
223234
224- println ! ( "Running with {} miners" , c. devices. len( ) ) ;
235+ info ! ( "Running with {} miners" , c. devices. len( ) ) ;
225236
226237 loop {
227238 match start_miners ( c. devices . clone ( ) ) . await {
228239 Ok ( _) => break ,
229240 Err ( e) => {
230- println ! ( "Exited with error: {:?}" , e) ;
241+ error ! ( "Exited with error: {:?}" , e) ;
231242 tokio:: time:: sleep ( Duration :: from_secs ( 300u64 ) ) . await ;
232243 }
233244 }
0 commit comments