diff --git a/stratum-v1/src/client/job.rs b/stratum-v1/src/client/job.rs index ffe41bd..f21f166 100644 --- a/stratum-v1/src/client/job.rs +++ b/stratum-v1/src/client/job.rs @@ -10,13 +10,12 @@ use bitcoin::{ hashes::{sha256d::Hash as DHash, Hash}, CompactTarget, }; -use heapless::Vec; +use heapless::{String, Vec}; -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub struct Job { - pub job_id: u64, + pub job_id: String<32>, pub extranonce2: Vec, - pub version_bits: i32, pub header: Header, } @@ -25,7 +24,7 @@ impl defmt::Format for Job { fn format(&self, fmt: defmt::Formatter) { defmt::write!( fmt, - "Job {{ job_id: {}, extranonce2: {:?}, version_bits: {}, header: {{ version: {:x}, prev_block_hash: {:x}, merkle_root: {:x}, time: {:x}, bits: {:x}, nonce: {:x} }} }}", + "Job {{ job_id: {}, extranonce2: {:?}, header: {{ version: {:x}, prev_block_hash: {:x}, merkle_root: {:x}, ntime: {:x}, nbits: {:x}, nonce: {:x} }} }}", self.job_id, self.extranonce2, self.version_bits, @@ -42,7 +41,6 @@ impl defmt::Format for Job { #[derive(Debug, Default)] #[cfg_attr(feature = "defmt-03", derive(defmt::Format))] pub(crate) struct JobCreator { - job_id: u64, last_work: Option, version_mask: i32, pub(crate) version_rolling: bool, @@ -79,6 +77,7 @@ impl JobCreator { .resize_default(self.extranonce2_size) .map_err(|_| Error::VecFull)?; self.extranonce2.fill(0); + self.ntime_bits = 0; Ok(()) } @@ -134,11 +133,9 @@ impl JobCreator { } else { work.ntime }; - self.job_id += self.job_id.wrapping_add(1); Ok(Job { - job_id: self.job_id, + job_id: work.job_id.clone(), extranonce2: self.extranonce2.clone(), - version_bits: rolled_version, header: Header { version: Version::from_consensus(rolled_version), prev_blockhash: BlockHash::from_byte_array(work.prev_hash), @@ -153,128 +150,257 @@ impl JobCreator { #[cfg(test)] mod tests { + use core::str::FromStr; + use super::*; #[test] - fn test_merkle_root() { - // example from https://github.com/stratum-mining/stratum/pull/305/files - let mut coinb1 = Vec::new(); - coinb1 - .extend_from_slice(&[ - 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 75, 3, 63, 146, 11, 250, 190, 109, - 109, 86, 6, 110, 64, 228, 218, 247, 203, 127, 75, 141, 53, 51, 197, 180, 38, 117, - 115, 221, 103, 2, 11, 85, 213, 65, 221, 74, 90, 97, 128, 91, 182, 1, 0, 0, 0, 0, 0, - 0, 0, 49, 101, 7, 7, 139, 168, 76, 0, 1, 0, 0, 0, 0, 0, 0, 70, 84, 183, 110, 24, - 47, 115, 108, 117, 115, 104, 47, 0, 0, 0, 0, 3, - ]) - .unwrap(); - let mut coinb2 = Vec::new(); - coinb2 - .extend_from_slice(&[ - 25, 118, 169, 20, 124, 21, 78, 209, 220, 89, 96, 158, 61, 38, 171, 178, 223, 46, - 163, 213, 135, 205, 140, 65, 136, 172, 0, 0, 0, 0, 0, 0, 0, 0, 44, 106, 76, 41, 82, - 83, 75, 66, 76, 79, 67, 75, 58, 216, 82, 49, 182, 148, 133, 228, 178, 20, 248, 55, - 219, 145, 83, 227, 86, 32, 97, 240, 182, 3, 175, 116, 196, 69, 114, 83, 46, 0, 71, - 230, 205, 0, 0, 0, 0, 0, 0, 0, 0, 38, 106, 36, 170, 33, 169, 237, 179, 75, 32, 206, - 223, 111, 113, 150, 112, 248, 21, 36, 163, 123, 107, 168, 153, 76, 233, 86, 77, - 218, 162, 59, 48, 26, 180, 38, 62, 34, 3, 185, 0, 0, 0, 0, - ]) - .unwrap(); - let mut merkle_branch = Vec::new(); - merkle_branch - .push([ - 122, 97, 64, 124, 164, 158, 164, 14, 87, 119, 226, 169, 34, 196, 251, 51, 31, 131, - 109, 250, 13, 54, 94, 6, 177, 27, 156, 154, 101, 30, 123, 159, - ]) - .unwrap(); - merkle_branch - .push([ - 180, 113, 121, 253, 215, 85, 129, 38, 108, 2, 86, 66, 46, 12, 131, 139, 130, 87, - 29, 92, 59, 164, 247, 114, 251, 140, 129, 88, 127, 196, 125, 116, - ]) - .unwrap(); - merkle_branch - .push([ - 171, 77, 225, 148, 80, 32, 41, 157, 246, 77, 161, 49, 87, 139, 214, 236, 149, 164, - 192, 128, 195, 9, 5, 168, 131, 27, 250, 9, 60, 179, 206, 94, - ]) - .unwrap(); - merkle_branch - .push([ - 6, 187, 202, 75, 155, 220, 255, 166, 199, 35, 182, 220, 20, 96, 123, 41, 109, 40, - 186, 142, 13, 139, 230, 164, 116, 177, 217, 23, 16, 123, 135, 202, - ]) - .unwrap(); - merkle_branch - .push([ - 109, 45, 171, 89, 223, 39, 132, 14, 150, 128, 241, 113, 136, 227, 105, 123, 224, - 48, 66, 240, 189, 186, 222, 49, 173, 143, 80, 90, 110, 219, 192, 235, - ]) - .unwrap(); - merkle_branch - .push([ - 196, 7, 21, 180, 228, 161, 182, 132, 28, 153, 242, 12, 210, 127, 157, 86, 62, 123, - 181, 33, 84, 3, 105, 129, 148, 162, 5, 152, 64, 7, 196, 156, - ]) - .unwrap(); - merkle_branch - .push([ - 22, 16, 18, 180, 109, 237, 68, 167, 197, 10, 195, 134, 11, 119, 219, 184, 49, 140, - 239, 45, 27, 210, 212, 120, 186, 60, 155, 105, 106, 219, 218, 32, - ]) - .unwrap(); - merkle_branch - .push([ - 83, 228, 21, 241, 42, 240, 8, 254, 109, 156, 59, 171, 167, 46, 183, 60, 27, 63, - 241, 211, 235, 179, 147, 99, 46, 3, 22, 166, 159, 169, 183, 159, - ]) - .unwrap(); - merkle_branch - .push([ - 230, 81, 3, 190, 66, 73, 200, 55, 94, 135, 209, 50, 92, 193, 114, 202, 141, 170, - 124, 142, 206, 29, 88, 9, 22, 110, 203, 145, 238, 66, 166, 35, - ]) - .unwrap(); - merkle_branch - .push([ - 43, 106, 86, 239, 237, 74, 208, 202, 247, 133, 88, 42, 15, 77, 163, 186, 85, 26, - 89, 151, 5, 19, 30, 122, 108, 220, 215, 104, 152, 226, 113, 55, - ]) - .unwrap(); - merkle_branch - .push([ - 148, 76, 200, 221, 206, 54, 56, 45, 252, 60, 123, 202, 195, 73, 144, 65, 168, 184, - 59, 130, 145, 229, 250, 44, 213, 70, 175, 128, 34, 31, 102, 80, - ]) + fn test_roll() { + let mut job_creator = JobCreator::default(); + assert_eq!(job_creator.roll(), Err(Error::NoWork)); + let job_id = hstring!(32, "1234"); + job_creator + .set_work(Work { + job_id: job_id.clone(), + prev_hash: [0; 32], + coinb1: Vec::new(), + coinb2: Vec::new(), + merkle_branch: Vec::new(), + version: 0x2000_0000, + nbits: 0x1234_5678, + ntime: 0, + clean_jobs: false, + }) .unwrap(); - merkle_branch - .push([ - 203, 112, 102, 31, 49, 147, 24, 25, 245, 61, 179, 146, 205, 127, 126, 100, 78, 204, - 228, 146, 209, 154, 89, 194, 209, 81, 57, 167, 88, 251, 44, 76, - ]) + job_creator.set_version_mask(0x1fff_e000); + job_creator.set_extranonces(Vec::new(), 1).unwrap(); + assert_eq!( + job_creator.roll(), + Ok(Job { + job_id: job_id.clone(), + extranonce2: hvec!(u8, 8, &[0]), + header: Header { + version: Version::from_consensus(0x2000_0000), + prev_blockhash: BlockHash::from_byte_array([0; 32]), + merkle_root: TxMerkleNode::from_byte_array([ + 0x14, 0x06, 0xe0, 0x58, 0x81, 0xe2, 0x99, 0x36, 0x77, 0x66, 0xd3, 0x13, + 0xe2, 0x6c, 0x05, 0x56, 0x4e, 0xc9, 0x1b, 0xf7, 0x21, 0xd3, 0x17, 0x26, + 0xbd, 0x6e, 0x46, 0xe6, 0x06, 0x89, 0x53, 0x9a, + ]), + time: 0, + bits: CompactTarget::from_consensus(0x1234_5678), + nonce: 0, + } + }) + ); + job_creator.version_rolling = true; + assert_eq!( + job_creator.roll(), + Ok(Job { + job_id: job_id.clone(), + extranonce2: hvec!(u8, 8, &[0]), + header: Header { + version: Version::from_consensus(0x2000_2000), + prev_blockhash: BlockHash::from_byte_array([0; 32]), + merkle_root: TxMerkleNode::from_byte_array([ + 0x14, 0x06, 0xe0, 0x58, 0x81, 0xe2, 0x99, 0x36, 0x77, 0x66, 0xd3, 0x13, + 0xe2, 0x6c, 0x05, 0x56, 0x4e, 0xc9, 0x1b, 0xf7, 0x21, 0xd3, 0x17, 0x26, + 0xbd, 0x6e, 0x46, 0xe6, 0x06, 0x89, 0x53, 0x9a, + ]), + time: 0, + bits: CompactTarget::from_consensus(0x1234_5678), + nonce: 0, + } + }) + ); + job_creator.ntime_rolling = true; + assert_eq!( + job_creator.roll(), + Ok(Job { + job_id: job_id.clone(), + extranonce2: hvec!(u8, 8, &[0]), + header: Header { + version: Version::from_consensus(0x2000_4000), + prev_blockhash: BlockHash::from_byte_array([0; 32]), + merkle_root: TxMerkleNode::from_byte_array([ + 0x14, 0x06, 0xe0, 0x58, 0x81, 0xe2, 0x99, 0x36, 0x77, 0x66, 0xd3, 0x13, + 0xe2, 0x6c, 0x05, 0x56, 0x4e, 0xc9, 0x1b, 0xf7, 0x21, 0xd3, 0x17, 0x26, + 0xbd, 0x6e, 0x46, 0xe6, 0x06, 0x89, 0x53, 0x9a, + ]), + time: 1, + bits: CompactTarget::from_consensus(0x1234_5678), + nonce: 0, + } + }) + ); + job_creator.extranonce2_rolling = true; + assert_eq!( + job_creator.roll(), + Ok(Job { + job_id: job_id.clone(), + extranonce2: hvec!(u8, 8, &[1]), + header: Header { + version: Version::from_consensus(0x2000_6000), + prev_blockhash: BlockHash::from_byte_array([0; 32]), + merkle_root: TxMerkleNode::from_byte_array([ + 0x9c, 0x12, 0xcf, 0xdc, 0x04, 0xc7, 0x45, 0x84, 0xd7, 0x87, 0xac, 0x3d, + 0x23, 0x77, 0x21, 0x32, 0xc1, 0x85, 0x24, 0xbc, 0x7a, 0xb2, 0x8d, 0xec, + 0x42, 0x19, 0xb8, 0xfc, 0x5b, 0x42, 0x5f, 0x70, + ]), + time: 2, + bits: CompactTarget::from_consensus(0x1234_5678), + nonce: 0, + } + }) + ); + job_creator + .set_work(Work { + job_id: job_id.clone(), + prev_hash: [0; 32], + coinb1: Vec::new(), + coinb2: Vec::new(), + merkle_branch: Vec::new(), + version: 0x2000_0000, + nbits: 0x1234_5678, + ntime: 0, + clean_jobs: false, + }) .unwrap(); - let work = Work { - job_id: "662ede".try_into().unwrap(), - prev_hash: [ - 0xa8, 0x0f, 0x3e, 0x7f, 0xb2, 0xfa, 0xe8, 0x23, 0x68, 0x12, 0xba, 0xa7, 0x66, 0xc2, - 0xc6, 0x14, 0x1b, 0x91, 0x18, 0x53, 0x00, 0x01, 0xc1, 0xce, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - ], - coinb1, - coinb2, - merkle_branch, - version: 0x2000_0000, - nbits: 0x1703_1abe, - ntime: 0x66aa_d286, - clean_jobs: false, - }; + assert_eq!( + job_creator.roll(), + Ok(Job { + job_id: job_id.clone(), + extranonce2: hvec!(u8, 8, &[1]), + header: Header { + version: Version::from_consensus(0x2000_2000), + prev_blockhash: BlockHash::from_byte_array([0; 32]), + merkle_root: TxMerkleNode::from_byte_array([ + 0x9c, 0x12, 0xcf, 0xdc, 0x04, 0xc7, 0x45, 0x84, 0xd7, 0x87, 0xac, 0x3d, + 0x23, 0x77, 0x21, 0x32, 0xc1, 0x85, 0x24, 0xbc, 0x7a, 0xb2, 0x8d, 0xec, + 0x42, 0x19, 0xb8, 0xfc, 0x5b, 0x42, 0x5f, 0x70, + ]), + time: 1, + bits: CompactTarget::from_consensus(0x1234_5678), + nonce: 0, + } + }) + ); + } + + #[test] + fn test_merkle_root() { + // example from https://github.com/stratum-mining/stratum/pull/305/files let mut job_creator = JobCreator::default(); - let mut extranonce1 = Vec::new(); - extranonce1.extend_from_slice(&[120, 55, 179, 37]).unwrap(); - job_creator.set_extranonces(extranonce1, 4).unwrap(); + job_creator + .set_extranonces(hvec!(u8, 8, &[120, 55, 179, 37]), 4) + .unwrap(); assert_eq!( - job_creator.merkle_root(&work), + job_creator.merkle_root(&Work { + job_id: hstring!(32, "662ede"), + prev_hash: [ + 0xa8, 0x0f, 0x3e, 0x7f, 0xb2, 0xfa, 0xe8, 0x23, 0x68, 0x12, 0xba, 0xa7, 0x66, + 0xc2, 0xc6, 0x14, 0x1b, 0x91, 0x18, 0x53, 0x00, 0x01, 0xc1, 0xce, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ], + coinb1: hvec!( + u8, + 128, + &[ + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 75, 3, 63, 146, 11, + 250, 190, 109, 109, 86, 6, 110, 64, 228, 218, 247, 203, 127, 75, 141, 53, + 51, 197, 180, 38, 117, 115, 221, 103, 2, 11, 85, 213, 65, 221, 74, 90, 97, + 128, 91, 182, 1, 0, 0, 0, 0, 0, 0, 0, 49, 101, 7, 7, 139, 168, 76, 0, 1, 0, + 0, 0, 0, 0, 0, 70, 84, 183, 110, 24, 47, 115, 108, 117, 115, 104, 47, 0, 0, + 0, 0, 3, + ] + ), + coinb2: hvec!( + u8, + 130, + &[ + 25, 118, 169, 20, 124, 21, 78, 209, 220, 89, 96, 158, 61, 38, 171, 178, + 223, 46, 163, 213, 135, 205, 140, 65, 136, 172, 0, 0, 0, 0, 0, 0, 0, 0, 44, + 106, 76, 41, 82, 83, 75, 66, 76, 79, 67, 75, 58, 216, 82, 49, 182, 148, + 133, 228, 178, 20, 248, 55, 219, 145, 83, 227, 86, 32, 97, 240, 182, 3, + 175, 116, 196, 69, 114, 83, 46, 0, 71, 230, 205, 0, 0, 0, 0, 0, 0, 0, 0, + 38, 106, 36, 170, 33, 169, 237, 179, 75, 32, 206, 223, 111, 113, 150, 112, + 248, 21, 36, 163, 123, 107, 168, 153, 76, 233, 86, 77, 218, 162, 59, 48, + 26, 180, 38, 62, 34, 3, 185, 0, 0, 0, 0, + ] + ), + merkle_branch: hveca!( + u8, + 32, + 16, + &[ + [ + 122, 97, 64, 124, 164, 158, 164, 14, 87, 119, 226, 169, 34, 196, 251, + 51, 31, 131, 109, 250, 13, 54, 94, 6, 177, 27, 156, 154, 101, 30, 123, + 159, + ], + [ + 180, 113, 121, 253, 215, 85, 129, 38, 108, 2, 86, 66, 46, 12, 131, 139, + 130, 87, 29, 92, 59, 164, 247, 114, 251, 140, 129, 88, 127, 196, 125, + 116, + ], + [ + 171, 77, 225, 148, 80, 32, 41, 157, 246, 77, 161, 49, 87, 139, 214, + 236, 149, 164, 192, 128, 195, 9, 5, 168, 131, 27, 250, 9, 60, 179, 206, + 94, + ], + [ + 6, 187, 202, 75, 155, 220, 255, 166, 199, 35, 182, 220, 20, 96, 123, + 41, 109, 40, 186, 142, 13, 139, 230, 164, 116, 177, 217, 23, 16, 123, + 135, 202, + ], + [ + 109, 45, 171, 89, 223, 39, 132, 14, 150, 128, 241, 113, 136, 227, 105, + 123, 224, 48, 66, 240, 189, 186, 222, 49, 173, 143, 80, 90, 110, 219, + 192, 235, + ], + [ + 196, 7, 21, 180, 228, 161, 182, 132, 28, 153, 242, 12, 210, 127, 157, + 86, 62, 123, 181, 33, 84, 3, 105, 129, 148, 162, 5, 152, 64, 7, 196, + 156, + ], + [ + 22, 16, 18, 180, 109, 237, 68, 167, 197, 10, 195, 134, 11, 119, 219, + 184, 49, 140, 239, 45, 27, 210, 212, 120, 186, 60, 155, 105, 106, 219, + 218, 32, + ], + [ + 83, 228, 21, 241, 42, 240, 8, 254, 109, 156, 59, 171, 167, 46, 183, 60, + 27, 63, 241, 211, 235, 179, 147, 99, 46, 3, 22, 166, 159, 169, 183, + 159, + ], + [ + 230, 81, 3, 190, 66, 73, 200, 55, 94, 135, 209, 50, 92, 193, 114, 202, + 141, 170, 124, 142, 206, 29, 88, 9, 22, 110, 203, 145, 238, 66, 166, + 35, + ], + [ + 43, 106, 86, 239, 237, 74, 208, 202, 247, 133, 88, 42, 15, 77, 163, + 186, 85, 26, 89, 151, 5, 19, 30, 122, 108, 220, 215, 104, 152, 226, + 113, 55, + ], + [ + 148, 76, 200, 221, 206, 54, 56, 45, 252, 60, 123, 202, 195, 73, 144, + 65, 168, 184, 59, 130, 145, 229, 250, 44, 213, 70, 175, 128, 34, 31, + 102, 80, + ], + [ + 203, 112, 102, 31, 49, 147, 24, 25, 245, 61, 179, 146, 205, 127, 126, + 100, 78, 204, 228, 146, 209, 154, 89, 194, 209, 81, 57, 167, 88, 251, + 44, 76, + ] + ] + ), + version: 0x2000_0000, + nbits: 0x1703_1abe, + ntime: 0x66aa_d286, + clean_jobs: false, + }), Ok([ 73, 100, 41, 247, 106, 44, 1, 242, 3, 64, 100, 1, 98, 155, 40, 91, 170, 255, 170, 29, 193, 255, 244, 71, 236, 29, 134, 218, 94, 45, 78, 77, diff --git a/stratum-v1/src/client/notification.rs b/stratum-v1/src/client/notification.rs index 27d26c8..cac2778 100644 --- a/stratum-v1/src/client/notification.rs +++ b/stratum-v1/src/client/notification.rs @@ -182,12 +182,10 @@ mod tests { assert_eq!( parse_set_version_mask(resp), Err(Error::JsonError( - serde_json_core::de::Error::CustomErrorWithMessage( - String::<64>::from_str( - "invalid length 9, expected a string no more than 8 bytes long" - ) - .unwrap() - ) + serde_json_core::de::Error::CustomErrorWithMessage(hstring!( + 64, + "invalid length 9, expected a string no more than 8 bytes long" + )) )) ); @@ -201,29 +199,8 @@ mod tests { #[test] fn test_notify() { // example from https://bitcointalk.org/index.php?topic=557866.5 - let resp = br#"{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008","072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],"00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"#; - let mut coinb1 = Vec::new(); - coinb1 - .extend_from_slice(&[ - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x20, - 0x02, 0x08, 0x62, 0x06, 0x2f, 0x50, 0x32, 0x53, 0x48, 0x2f, 0x04, 0xb8, 0x86, 0x4e, - 0x50, 0x08, - ]) - .unwrap(); - let mut coinb2 = Vec::new(); - coinb2 - .extend_from_slice(&[ - 0x07, 0x2f, 0x73, 0x6c, 0x75, 0x73, 0x68, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, 0x14, 0xd2, 0x3f, 0xcd, - 0xf8, 0x6f, 0x7e, 0x75, 0x6a, 0x64, 0xa7, 0xa9, 0x68, 0x8e, 0xf9, 0x90, 0x33, 0x27, - 0x04, 0x8e, 0xd9, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, - ]) - .unwrap(); - let merkle_branch = Vec::new(); assert_eq!( - parse_notify(resp), + parse_notify(br#"{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008","072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],"00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"#), Ok(Work { job_id: "bf".try_into().unwrap(), prev_hash: [ @@ -231,9 +208,29 @@ mod tests { 0x7a, 0xe5, 0x61, 0x6d, 0xe6, 0x7f, 0x78, 0x8f, 0x44, 0xae, 0x2a, 0x5a, 0xf6, 0xe2, 0x19, 0x4d, 0x16, 0xb6, 0xf8, ], - coinb1, - coinb2, - merkle_branch, + coinb1: hvec!( + u8, + 128, + &[ + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x20, 0x02, 0x08, 0x62, 0x06, 0x2f, 0x50, + 0x32, 0x53, 0x48, 0x2f, 0x04, 0xb8, 0x86, 0x4e, 0x50, 0x08, + ] + ), + coinb2: hvec!( + u8, + 130, + &[ + 0x07, 0x2f, 0x73, 0x6c, 0x75, 0x73, 0x68, 0x2f, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x19, 0x76, 0xa9, + 0x14, 0xd2, 0x3f, 0xcd, 0xf8, 0x6f, 0x7e, 0x75, 0x6a, 0x64, 0xa7, 0xa9, + 0x68, 0x8e, 0xf9, 0x90, 0x33, 0x27, 0x04, 0x8e, 0xd9, 0x88, 0xac, 0x00, + 0x00, 0x00, 0x00, + ] + ), + merkle_branch: Vec::new(), version: 0x0000_00002, nbits: 0x1c2a_c4af, ntime: 0x504e_86b9, @@ -242,32 +239,8 @@ mod tests { ); // example from actual mining job - let resp = br#"{"params": ["278", "9c16805af67958e9c183d0fa47e4b8245fea76e26cfe874b0000000e00000000","02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3b03219200005374726174756d207632204e6562756c6120506f6f6c","ffffffff0200f2052a01000000160014d4989f3137807deab9a76e549eef5c5a03448ca40000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",[],"20000000","19609307","66ab8012",true], "id": null, "method": "mining.notify"}"#; - let mut coinb1 = Vec::new(); - coinb1 - .extend_from_slice(&[ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x3b, - 0x03, 0x21, 0x92, 0x00, 0x00, 0x53, 0x74, 0x72, 0x61, 0x74, 0x75, 0x6d, 0x20, 0x76, - 0x32, 0x20, 0x4e, 0x65, 0x62, 0x75, 0x6c, 0x61, 0x20, 0x50, 0x6f, 0x6f, 0x6c, - ]) - .unwrap(); - let mut coinb2 = Vec::new(); - coinb2 - .extend_from_slice(&[ - 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, 0x16, - 0x00, 0x14, 0xd4, 0x98, 0x9f, 0x31, 0x37, 0x80, 0x7d, 0xea, 0xb9, 0xa7, 0x6e, 0x54, - 0x9e, 0xef, 0x5c, 0x5a, 0x03, 0x44, 0x8c, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x26, 0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed, 0xe2, 0xf6, 0x1c, 0x3f, 0x71, - 0xd1, 0xde, 0xfd, 0x3f, 0xa9, 0x99, 0xdf, 0xa3, 0x69, 0x53, 0x75, 0x5c, 0x69, 0x06, - 0x89, 0x79, 0x99, 0x62, 0xb4, 0x8b, 0xeb, 0xd8, 0x36, 0x97, 0x4e, 0x8c, 0xf9, 0x00, - 0x00, 0x00, 0x00, - ]) - .unwrap(); - let merkle_branch = Vec::new(); assert_eq!( - parse_notify(resp), + parse_notify(br#"{"params": ["278", "9c16805af67958e9c183d0fa47e4b8245fea76e26cfe874b0000000e00000000","02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3b03219200005374726174756d207632204e6562756c6120506f6f6c","ffffffff0200f2052a01000000160014d4989f3137807deab9a76e549eef5c5a03448ca40000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",[],"20000000","19609307","66ab8012",true], "id": null, "method": "mining.notify"}"#), Ok(Work { job_id: "278".try_into().unwrap(), prev_hash: [ @@ -275,9 +248,33 @@ mod tests { 0xea, 0x76, 0xe2, 0x47, 0xe4, 0xb8, 0x24, 0xc1, 0x83, 0xd0, 0xfa, 0xf6, 0x79, 0x58, 0xe9, 0x9c, 0x16, 0x80, 0x5a, ], - coinb1, - coinb2, - merkle_branch, + coinb1: hvec!( + u8, + 128, + &[ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x3b, 0x03, 0x21, 0x92, 0x00, 0x00, 0x53, + 0x74, 0x72, 0x61, 0x74, 0x75, 0x6d, 0x20, 0x76, 0x32, 0x20, 0x4e, 0x65, + 0x62, 0x75, 0x6c, 0x61, 0x20, 0x50, 0x6f, 0x6f, 0x6c, + ] + ), + coinb2: hvec!( + u8, + 130, + &[ + 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x14, 0xd4, 0x98, 0x9f, 0x31, 0x37, 0x80, 0x7d, 0xea, + 0xb9, 0xa7, 0x6e, 0x54, 0x9e, 0xef, 0x5c, 0x5a, 0x03, 0x44, 0x8c, 0xa4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x6a, 0x24, 0xaa, + 0x21, 0xa9, 0xed, 0xe2, 0xf6, 0x1c, 0x3f, 0x71, 0xd1, 0xde, 0xfd, 0x3f, + 0xa9, 0x99, 0xdf, 0xa3, 0x69, 0x53, 0x75, 0x5c, 0x69, 0x06, 0x89, 0x79, + 0x99, 0x62, 0xb4, 0x8b, 0xeb, 0xd8, 0x36, 0x97, 0x4e, 0x8c, 0xf9, 0x00, + 0x00, 0x00, 0x00, + ] + ), + merkle_branch: Vec::new(), version: 0x2000_0000, nbits: 0x1960_9307, ntime: 0x66ab_8012, @@ -286,133 +283,109 @@ mod tests { ); // example from actual mining job - let resp = br#"{"id":null,"method":"mining.notify","params":["662ede","a80f3e7fb2fae8236812baa766c2c6141b9118530001c1ce0000000000000000","02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff17035a0b0d5075626c69632d506f6f6c","ffffffff0294b1f512000000001976a91495e381440a0faf41a7206b86b0d770bcabfef2cf88ac0000000000000000266a24aa21a9edee8a2981199af032120e8bc567edb3d3f3335278b508ced184bcbff13137364d00000000",["48133ccb9355395e02960124db8bf4f98f3cb05908f5c27abc77f020fe13feee","bb4120b2bd74d2204588eed34911b311f1e9ec1561c0fe7730b795a3b5d28fa6","53e7786db850a2bb49a88c003f278aa48866ccdadc5bc7b27e77af1bf3ca2669","ce8944028b7360405f2929922e00e08276af6cab0f119aa8ca3bceb29e2306d2","b2debecba153be2fe9da0f193e33a9d1fe888779dfd855770f0f7020c4047f26","548b2b9331cc40b9d68fd142b1ae2322e33ddb1b65cdf94cfd089ec967362118","8af1d2d31f86c0a240a11f55320335560642f3633ba481929fc431a9996fc874","62e671ae9d5d20aa7fc7f45856367f3dedb96b1736ec559292c8b9e0134672b1","10d017262b9152c47aa4e261c84fb6e8fb07f0b760a4da172b09f548f42d1db4","f1b01197d16a068329d39cdcbe0040029b51095635f332ca91e426e5da8bbe7d","ef342a7b654060a5048aaf1d6b0ac18f51a0cee6d58856f21a9cbec799ee6e9e","f6bb407984e000a2a619e26a46e91e113001aebd563407ea6202d8b042cf9294","5d60ed1a9ee3bbfac2b0f24abf0c72fe7c39c4b51b046903a4dfe21ca5312c25"],"20000000","17031abe","66aad286",false]}"#; - let mut coinb1 = Vec::new(); - coinb1 - .extend_from_slice(&[ - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x17, - 0x03, 0x5a, 0x0b, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x50, 0x6f, 0x6f, - 0x6c, - ]) - .unwrap(); - let mut coinb2 = Vec::new(); - coinb2 - .extend_from_slice(&[ - 0xff, 0xff, 0xff, 0xff, 0x02, 0x94, 0xb1, 0xf5, 0x12, 0x00, 0x00, 0x00, 0x00, 0x19, - 0x76, 0xa9, 0x14, 0x95, 0xe3, 0x81, 0x44, 0x0a, 0x0f, 0xaf, 0x41, 0xa7, 0x20, 0x6b, - 0x86, 0xb0, 0xd7, 0x70, 0xbc, 0xab, 0xfe, 0xf2, 0xcf, 0x88, 0xac, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed, 0xee, 0x8a, - 0x29, 0x81, 0x19, 0x9a, 0xf0, 0x32, 0x12, 0x0e, 0x8b, 0xc5, 0x67, 0xed, 0xb3, 0xd3, - 0xf3, 0x33, 0x52, 0x78, 0xb5, 0x08, 0xce, 0xd1, 0x84, 0xbc, 0xbf, 0xf1, 0x31, 0x37, - 0x36, 0x4d, 0x00, 0x00, 0x00, 0x00, - ]) - .unwrap(); - let mut merkle_branch = Vec::new(); - merkle_branch - .push([ - 0x48, 0x13, 0x3c, 0xcb, 0x93, 0x55, 0x39, 0x5e, 0x02, 0x96, 0x01, 0x24, 0xdb, 0x8b, - 0xf4, 0xf9, 0x8f, 0x3c, 0xb0, 0x59, 0x08, 0xf5, 0xc2, 0x7a, 0xbc, 0x77, 0xf0, 0x20, - 0xfe, 0x13, 0xfe, 0xee, - ]) - .unwrap(); - merkle_branch - .push([ - 0xbb, 0x41, 0x20, 0xb2, 0xbd, 0x74, 0xd2, 0x20, 0x45, 0x88, 0xee, 0xd3, 0x49, 0x11, - 0xb3, 0x11, 0xf1, 0xe9, 0xec, 0x15, 0x61, 0xc0, 0xfe, 0x77, 0x30, 0xb7, 0x95, 0xa3, - 0xb5, 0xd2, 0x8f, 0xa6, - ]) - .unwrap(); - merkle_branch - .push([ - 0x53, 0xe7, 0x78, 0x6d, 0xb8, 0x50, 0xa2, 0xbb, 0x49, 0xa8, 0x8c, 0x00, 0x3f, 0x27, - 0x8a, 0xa4, 0x88, 0x66, 0xcc, 0xda, 0xdc, 0x5b, 0xc7, 0xb2, 0x7e, 0x77, 0xaf, 0x1b, - 0xf3, 0xca, 0x26, 0x69, - ]) - .unwrap(); - merkle_branch - .push([ - 0xce, 0x89, 0x44, 0x02, 0x8b, 0x73, 0x60, 0x40, 0x5f, 0x29, 0x29, 0x92, 0x2e, 0x00, - 0xe0, 0x82, 0x76, 0xaf, 0x6c, 0xab, 0x0f, 0x11, 0x9a, 0xa8, 0xca, 0x3b, 0xce, 0xb2, - 0x9e, 0x23, 0x06, 0xd2, - ]) - .unwrap(); - merkle_branch - .push([ - 0xb2, 0xde, 0xbe, 0xcb, 0xa1, 0x53, 0xbe, 0x2f, 0xe9, 0xda, 0x0f, 0x19, 0x3e, 0x33, - 0xa9, 0xd1, 0xfe, 0x88, 0x87, 0x79, 0xdf, 0xd8, 0x55, 0x77, 0x0f, 0x0f, 0x70, 0x20, - 0xc4, 0x04, 0x7f, 0x26, - ]) - .unwrap(); - merkle_branch - .push([ - 0x54, 0x8b, 0x2b, 0x93, 0x31, 0xcc, 0x40, 0xb9, 0xd6, 0x8f, 0xd1, 0x42, 0xb1, 0xae, - 0x23, 0x22, 0xe3, 0x3d, 0xdb, 0x1b, 0x65, 0xcd, 0xf9, 0x4c, 0xfd, 0x08, 0x9e, 0xc9, - 0x67, 0x36, 0x21, 0x18, - ]) - .unwrap(); - merkle_branch - .push([ - 0x8a, 0xf1, 0xd2, 0xd3, 0x1f, 0x86, 0xc0, 0xa2, 0x40, 0xa1, 0x1f, 0x55, 0x32, 0x03, - 0x35, 0x56, 0x06, 0x42, 0xf3, 0x63, 0x3b, 0xa4, 0x81, 0x92, 0x9f, 0xc4, 0x31, 0xa9, - 0x99, 0x6f, 0xc8, 0x74, - ]) - .unwrap(); - merkle_branch - .push([ - 0x62, 0xe6, 0x71, 0xae, 0x9d, 0x5d, 0x20, 0xaa, 0x7f, 0xc7, 0xf4, 0x58, 0x56, 0x36, - 0x7f, 0x3d, 0xed, 0xb9, 0x6b, 0x17, 0x36, 0xec, 0x55, 0x92, 0x92, 0xc8, 0xb9, 0xe0, - 0x13, 0x46, 0x72, 0xb1, - ]) - .unwrap(); - merkle_branch - .push([ - 0x10, 0xd0, 0x17, 0x26, 0x2b, 0x91, 0x52, 0xc4, 0x7a, 0xa4, 0xe2, 0x61, 0xc8, 0x4f, - 0xb6, 0xe8, 0xfb, 0x07, 0xf0, 0xb7, 0x60, 0xa4, 0xda, 0x17, 0x2b, 0x09, 0xf5, 0x48, - 0xf4, 0x2d, 0x1d, 0xb4, - ]) - .unwrap(); - merkle_branch - .push([ - 0xf1, 0xb0, 0x11, 0x97, 0xd1, 0x6a, 0x06, 0x83, 0x29, 0xd3, 0x9c, 0xdc, 0xbe, 0x00, - 0x40, 0x02, 0x9b, 0x51, 0x09, 0x56, 0x35, 0xf3, 0x32, 0xca, 0x91, 0xe4, 0x26, 0xe5, - 0xda, 0x8b, 0xbe, 0x7d, - ]) - .unwrap(); - merkle_branch - .push([ - 0xef, 0x34, 0x2a, 0x7b, 0x65, 0x40, 0x60, 0xa5, 0x04, 0x8a, 0xaf, 0x1d, 0x6b, 0x0a, - 0xc1, 0x8f, 0x51, 0xa0, 0xce, 0xe6, 0xd5, 0x88, 0x56, 0xf2, 0x1a, 0x9c, 0xbe, 0xc7, - 0x99, 0xee, 0x6e, 0x9e, - ]) - .unwrap(); - merkle_branch - .push([ - 0xf6, 0xbb, 0x40, 0x79, 0x84, 0xe0, 0x00, 0xa2, 0xa6, 0x19, 0xe2, 0x6a, 0x46, 0xe9, - 0x1e, 0x11, 0x30, 0x01, 0xae, 0xbd, 0x56, 0x34, 0x07, 0xea, 0x62, 0x02, 0xd8, 0xb0, - 0x42, 0xcf, 0x92, 0x94, - ]) - .unwrap(); - merkle_branch - .push([ - 0x5d, 0x60, 0xed, 0x1a, 0x9e, 0xe3, 0xbb, 0xfa, 0xc2, 0xb0, 0xf2, 0x4a, 0xbf, 0x0c, - 0x72, 0xfe, 0x7c, 0x39, 0xc4, 0xb5, 0x1b, 0x04, 0x69, 0x03, 0xa4, 0xdf, 0xe2, 0x1c, - 0xa5, 0x31, 0x2c, 0x25, - ]) - .unwrap(); assert_eq!( - parse_notify(resp), + parse_notify( + br#"{"id":null,"method":"mining.notify","params":["662ede","a80f3e7fb2fae8236812baa766c2c6141b9118530001c1ce0000000000000000","02000000010000000000000000000000000000000000000000000000000000000000000000ffffffff17035a0b0d5075626c69632d506f6f6c","ffffffff0294b1f512000000001976a91495e381440a0faf41a7206b86b0d770bcabfef2cf88ac0000000000000000266a24aa21a9edee8a2981199af032120e8bc567edb3d3f3335278b508ced184bcbff13137364d00000000",["48133ccb9355395e02960124db8bf4f98f3cb05908f5c27abc77f020fe13feee","bb4120b2bd74d2204588eed34911b311f1e9ec1561c0fe7730b795a3b5d28fa6","53e7786db850a2bb49a88c003f278aa48866ccdadc5bc7b27e77af1bf3ca2669","ce8944028b7360405f2929922e00e08276af6cab0f119aa8ca3bceb29e2306d2","b2debecba153be2fe9da0f193e33a9d1fe888779dfd855770f0f7020c4047f26","548b2b9331cc40b9d68fd142b1ae2322e33ddb1b65cdf94cfd089ec967362118","8af1d2d31f86c0a240a11f55320335560642f3633ba481929fc431a9996fc874","62e671ae9d5d20aa7fc7f45856367f3dedb96b1736ec559292c8b9e0134672b1","10d017262b9152c47aa4e261c84fb6e8fb07f0b760a4da172b09f548f42d1db4","f1b01197d16a068329d39cdcbe0040029b51095635f332ca91e426e5da8bbe7d","ef342a7b654060a5048aaf1d6b0ac18f51a0cee6d58856f21a9cbec799ee6e9e","f6bb407984e000a2a619e26a46e91e113001aebd563407ea6202d8b042cf9294","5d60ed1a9ee3bbfac2b0f24abf0c72fe7c39c4b51b046903a4dfe21ca5312c25"],"20000000","17031abe","66aad286",false]}"# + ), Ok(Work { - job_id: "662ede".try_into().unwrap(), + job_id: hstring!(32, "662ede"), prev_hash: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc1, 0xce, 0x1b, 0x91, 0x18, 0x53, 0x66, 0xc2, 0xc6, 0x14, 0x68, 0x12, 0xba, 0xa7, 0xb2, 0xfa, 0xe8, 0x23, 0xa8, 0x0f, 0x3e, 0x7f, ], - coinb1, - coinb2, - merkle_branch, + coinb1: hvec!( + u8, + 128, + &[ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0xff, 0xff, 0x17, 0x03, 0x5a, 0x0b, 0x0d, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x2d, 0x50, 0x6f, 0x6f, 0x6c, + ] + ), + coinb2: hvec!( + u8, + 130, + &[ + 0xff, 0xff, 0xff, 0xff, 0x02, 0x94, 0xb1, 0xf5, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x19, 0x76, 0xa9, 0x14, 0x95, 0xe3, 0x81, 0x44, 0x0a, 0x0f, 0xaf, + 0x41, 0xa7, 0x20, 0x6b, 0x86, 0xb0, 0xd7, 0x70, 0xbc, 0xab, 0xfe, 0xf2, + 0xcf, 0x88, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, + 0x6a, 0x24, 0xaa, 0x21, 0xa9, 0xed, 0xee, 0x8a, 0x29, 0x81, 0x19, 0x9a, + 0xf0, 0x32, 0x12, 0x0e, 0x8b, 0xc5, 0x67, 0xed, 0xb3, 0xd3, 0xf3, 0x33, + 0x52, 0x78, 0xb5, 0x08, 0xce, 0xd1, 0x84, 0xbc, 0xbf, 0xf1, 0x31, 0x37, + 0x36, 0x4d, 0x00, 0x00, 0x00, 0x00, + ] + ), + merkle_branch: hveca!(u8, 32, 16, &[ + [ + 0x48, 0x13, 0x3c, 0xcb, 0x93, 0x55, 0x39, 0x5e, 0x02, 0x96, 0x01, 0x24, 0xdb, 0x8b, + 0xf4, 0xf9, 0x8f, 0x3c, 0xb0, 0x59, 0x08, 0xf5, 0xc2, 0x7a, 0xbc, 0x77, 0xf0, 0x20, + 0xfe, 0x13, 0xfe, 0xee, + ], + [ + 0xbb, 0x41, 0x20, 0xb2, 0xbd, 0x74, 0xd2, 0x20, 0x45, 0x88, 0xee, 0xd3, 0x49, 0x11, + 0xb3, 0x11, 0xf1, 0xe9, 0xec, 0x15, 0x61, 0xc0, 0xfe, 0x77, 0x30, 0xb7, 0x95, 0xa3, + 0xb5, 0xd2, 0x8f, 0xa6, + ], + [ + 0x53, 0xe7, 0x78, 0x6d, 0xb8, 0x50, 0xa2, 0xbb, 0x49, 0xa8, 0x8c, 0x00, 0x3f, 0x27, + 0x8a, 0xa4, 0x88, 0x66, 0xcc, 0xda, 0xdc, 0x5b, 0xc7, 0xb2, 0x7e, 0x77, 0xaf, 0x1b, + 0xf3, 0xca, 0x26, 0x69, + ], + [ + 0xce, 0x89, 0x44, 0x02, 0x8b, 0x73, 0x60, 0x40, 0x5f, 0x29, 0x29, 0x92, 0x2e, 0x00, + 0xe0, 0x82, 0x76, 0xaf, 0x6c, 0xab, 0x0f, 0x11, 0x9a, 0xa8, 0xca, 0x3b, 0xce, 0xb2, + 0x9e, 0x23, 0x06, 0xd2, + ], + [ + 0xb2, 0xde, 0xbe, 0xcb, 0xa1, 0x53, 0xbe, 0x2f, 0xe9, 0xda, 0x0f, 0x19, 0x3e, 0x33, + 0xa9, 0xd1, 0xfe, 0x88, 0x87, 0x79, 0xdf, 0xd8, 0x55, 0x77, 0x0f, 0x0f, 0x70, 0x20, + 0xc4, 0x04, 0x7f, 0x26, + ], + [ + 0x54, 0x8b, 0x2b, 0x93, 0x31, 0xcc, 0x40, 0xb9, 0xd6, 0x8f, 0xd1, 0x42, 0xb1, 0xae, + 0x23, 0x22, 0xe3, 0x3d, 0xdb, 0x1b, 0x65, 0xcd, 0xf9, 0x4c, 0xfd, 0x08, 0x9e, 0xc9, + 0x67, 0x36, 0x21, 0x18, + ], + [ + 0x8a, 0xf1, 0xd2, 0xd3, 0x1f, 0x86, 0xc0, 0xa2, 0x40, 0xa1, 0x1f, 0x55, 0x32, 0x03, + 0x35, 0x56, 0x06, 0x42, 0xf3, 0x63, 0x3b, 0xa4, 0x81, 0x92, 0x9f, 0xc4, 0x31, 0xa9, + 0x99, 0x6f, 0xc8, 0x74, + ], + [ + 0x62, 0xe6, 0x71, 0xae, 0x9d, 0x5d, 0x20, 0xaa, 0x7f, 0xc7, 0xf4, 0x58, 0x56, 0x36, + 0x7f, 0x3d, 0xed, 0xb9, 0x6b, 0x17, 0x36, 0xec, 0x55, 0x92, 0x92, 0xc8, 0xb9, 0xe0, + 0x13, 0x46, 0x72, 0xb1, + ], + [ + 0x10, 0xd0, 0x17, 0x26, 0x2b, 0x91, 0x52, 0xc4, 0x7a, 0xa4, 0xe2, 0x61, 0xc8, 0x4f, + 0xb6, 0xe8, 0xfb, 0x07, 0xf0, 0xb7, 0x60, 0xa4, 0xda, 0x17, 0x2b, 0x09, 0xf5, 0x48, + 0xf4, 0x2d, 0x1d, 0xb4, + ], + [ + 0xf1, 0xb0, 0x11, 0x97, 0xd1, 0x6a, 0x06, 0x83, 0x29, 0xd3, 0x9c, 0xdc, 0xbe, 0x00, + 0x40, 0x02, 0x9b, 0x51, 0x09, 0x56, 0x35, 0xf3, 0x32, 0xca, 0x91, 0xe4, 0x26, 0xe5, + 0xda, 0x8b, 0xbe, 0x7d, + ], + [ + 0xef, 0x34, 0x2a, 0x7b, 0x65, 0x40, 0x60, 0xa5, 0x04, 0x8a, 0xaf, 0x1d, 0x6b, 0x0a, + 0xc1, 0x8f, 0x51, 0xa0, 0xce, 0xe6, 0xd5, 0x88, 0x56, 0xf2, 0x1a, 0x9c, 0xbe, 0xc7, + 0x99, 0xee, 0x6e, 0x9e, + ], + [ + 0xf6, 0xbb, 0x40, 0x79, 0x84, 0xe0, 0x00, 0xa2, 0xa6, 0x19, 0xe2, 0x6a, 0x46, 0xe9, + 0x1e, 0x11, 0x30, 0x01, 0xae, 0xbd, 0x56, 0x34, 0x07, 0xea, 0x62, 0x02, 0xd8, 0xb0, + 0x42, 0xcf, 0x92, 0x94, + ], + [ + 0x5d, 0x60, 0xed, 0x1a, 0x9e, 0xe3, 0xbb, 0xfa, 0xc2, 0xb0, 0xf2, 0x4a, 0xbf, 0x0c, + 0x72, 0xfe, 0x7c, 0x39, 0xc4, 0xb5, 0x1b, 0x04, 0x69, 0x03, 0xa4, 0xdf, 0xe2, 0x1c, + 0xa5, 0x31, 0x2c, 0x25, + ] + ]), version: 0x2000_0000, nbits: 0x1703_1abe, ntime: 0x66aa_d286, @@ -423,12 +396,17 @@ mod tests { #[test] fn test_parse_set_difficulty() { - let resp = br#"{"params": [2.5], "id": null, "method": "mining.set_difficulty"}"#; - assert_eq!(parse_set_difficulty(resp), Ok(2.5)); + assert_eq!( + parse_set_difficulty( + br#"{"params": [2.5], "id": null, "method": "mining.set_difficulty"}"# + ), + Ok(2.5) + ); - let resp = br#"{"params": [2.5a], "id": null, "method": "mining.set_difficulty"}"#; assert_eq!( - parse_set_difficulty(resp), + parse_set_difficulty( + br#"{"params": [2.5a], "id": null, "method": "mining.set_difficulty"}"# + ), Err(Error::JsonError( serde_json_core::de::Error::ExpectedListCommaOrEnd )) @@ -437,16 +415,28 @@ mod tests { #[test] fn test_parse_method() { - let resp = br#"{"params":["1fffe000"], "id":null, "method": "mining.set_version_mask"}"#; - assert_eq!(parse_method(resp), Ok(Notification::SetVersionMask)); + assert_eq!( + parse_method( + br#"{"params":["1fffe000"], "id":null, "method": "mining.set_version_mask"}"# + ), + Ok(Notification::SetVersionMask) + ); - let resp = br#"{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008","072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],"00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"#; - assert_eq!(parse_method(resp), Ok(Notification::Notify)); + assert_eq!( + parse_method( + br#"{"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008","072f736c7573682f000000000100f2052a010000001976a914d23fcdf86f7e756a64a7a9688ef9903327048ed988ac00000000", [],"00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"}"# + ), + Ok(Notification::Notify) + ); - let resp = br#"{"params": [2.5], "id": null, "method": "mining.set_difficulty"}"#; - assert_eq!(parse_method(resp), Ok(Notification::SetDifficulty)); + assert_eq!( + parse_method(br#"{"params": [2.5], "id": null, "method": "mining.set_difficulty"}"#), + Ok(Notification::SetDifficulty) + ); - let resp = br#"{"params": [], "id": null, "method": "mining.broken"}"#; - assert_eq!(parse_method(resp), Err(Error::UnknownNotification)); + assert_eq!( + parse_method(br#"{"params": [], "id": null, "method": "mining.broken"}"#), + Err(Error::UnknownNotification) + ); } } diff --git a/stratum-v1/src/client/request.rs b/stratum-v1/src/client/request.rs index b4104ba..f409887 100644 --- a/stratum-v1/src/client/request.rs +++ b/stratum-v1/src/client/request.rs @@ -349,12 +349,9 @@ mod tests { #[test] fn test_submit() { let mut buf = [0u8; 1024]; - let mut extranonce2 = Vec::new(); - extranonce2.resize(4, 0).unwrap(); - extranonce2[3] = 0x01; let share = Share { job_id: "bf".try_into().unwrap(), - extranonce2, + extranonce2: hvec!(u8, 8, &[0, 0, 0, 1]), ntime: 1347323629, nonce: 0xb295_7c02, version_bits: None, diff --git a/stratum-v1/src/client/response.rs b/stratum-v1/src/client/response.rs index 136e3dd..c6a105f 100644 --- a/stratum-v1/src/client/response.rs +++ b/stratum-v1/src/client/response.rs @@ -339,6 +339,7 @@ pub(crate) fn parse_submit(resp: &[u8]) -> Result { #[cfg(test)] mod tests { + use core::str::FromStr; use heapless::Vec; use super::*; @@ -384,14 +385,13 @@ mod tests { let resp = br#"{"id": 1, "result": [ [ ["mining.set_difficulty", "b4b6693b72a50c7116db18d6497cac52"], ["mining.notify", "ae6812eb4cd7735a302a8a9dd95cf71f"]], "08000002", 4], "error": null}"#; let mut subs = Vec::new(); let mut sub = Vec::new(); - sub.push("mining.set_difficulty".try_into().unwrap()) - .unwrap(); - sub.push("b4b6693b72a50c7116db18d6497cac52".try_into().unwrap()) + sub.push(hstring!(32, "mining.set_difficulty")).unwrap(); + sub.push(hstring!(32, "b4b6693b72a50c7116db18d6497cac52")) .unwrap(); subs.push(sub).unwrap(); let mut sub = Vec::new(); - sub.push("mining.notify".try_into().unwrap()).unwrap(); - sub.push("ae6812eb4cd7735a302a8a9dd95cf71f".try_into().unwrap()) + sub.push(hstring!(32, "mining.notify")).unwrap(); + sub.push(hstring!(32, "ae6812eb4cd7735a302a8a9dd95cf71f")) .unwrap(); subs.push(sub).unwrap(); let mut extranonce1 = Vec::new(); @@ -410,21 +410,18 @@ mod tests { let resp = br#"{"id":2,"result":[[["mining.set_difficulty","1"],["mining.notify","1"]],"00",6],"error":null}"#; let mut subs = Vec::new(); let mut sub = Vec::new(); - sub.push("mining.set_difficulty".try_into().unwrap()) - .unwrap(); - sub.push("1".try_into().unwrap()).unwrap(); + sub.push(hstring!(32, "mining.set_difficulty")).unwrap(); + sub.push(hstring!(32, "1")).unwrap(); subs.push(sub).unwrap(); let mut sub = Vec::new(); - sub.push("mining.notify".try_into().unwrap()).unwrap(); - sub.push("1".try_into().unwrap()).unwrap(); + sub.push(hstring!(32, "mining.notify")).unwrap(); + sub.push(hstring!(32, "1")).unwrap(); subs.push(sub).unwrap(); - let mut extranonce1 = Vec::new(); - extranonce1.extend_from_slice(&[0x00]).unwrap(); assert_eq!( parse_connect(resp), Ok(ConnectResp { subscriptions: subs, - extranonce1, + extranonce1: hvec!(u8, 8, &[0x00]), extranonce2_size: 6, }) ); @@ -433,18 +430,14 @@ mod tests { br#"{"id":2,"error":null,"result":[[["mining.notify","e26e1928"]],"e26e1928",4]}"#; let mut subs = Vec::new(); let mut sub = Vec::new(); - sub.push("mining.notify".try_into().unwrap()).unwrap(); - sub.push("e26e1928".try_into().unwrap()).unwrap(); + sub.push(hstring!(32, "mining.notify")).unwrap(); + sub.push(hstring!(32, "e26e1928")).unwrap(); subs.push(sub).unwrap(); - let mut extranonce1 = Vec::new(); - extranonce1 - .extend_from_slice(&[0xe2, 0x6e, 0x19, 0x28]) - .unwrap(); assert_eq!( parse_connect(resp), Ok(ConnectResp { subscriptions: subs, - extranonce1, + extranonce1: hvec!(u8, 8, &[0xe2, 0x6e, 0x19, 0x28]), extranonce2_size: 4, }) ); @@ -454,7 +447,7 @@ mod tests { parse_connect(resp), Err(Error::Pool { code: 20, - message: "Other/Unknown".try_into().unwrap(), + message: hstring!(32, "Other/Unknown"), detail: None }) ); @@ -473,7 +466,7 @@ mod tests { parse_authorize(resp), Err(Error::Pool { code: 25, - message: "Not subscribed".try_into().unwrap(), + message: hstring!(32, "Not subscribed"), detail: None }) ); @@ -485,8 +478,8 @@ mod tests { parse_authorize(resp), Err(Error::Pool { code: 20, - message: "Authorization validation error".try_into().unwrap(), - detail: Some(", slush".try_into().unwrap()), + message: hstring!(32, "Authorization validation error"), + detail: Some(hstring!(32, ", slush")), }) ); @@ -506,8 +499,8 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 23, - message: "Difficulty too low".try_into().unwrap(), - detail: Some("".try_into().unwrap()) + message: hstring!(32, "Difficulty too low"), + detail: Some(hstring!(32, "")) }) ); let resp = br#"{"id":84,"result":null,"error":[21,"Job not found",""]}"#; @@ -515,8 +508,8 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 21, - message: "Job not found".try_into().unwrap(), - detail: Some("".try_into().unwrap()) + message: hstring!(32, "Job not found"), + detail: Some(hstring!(32, "")) }) ); // Philon Proxy @@ -525,7 +518,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 23, - message: "Low difficulty share".try_into().unwrap(), + message: hstring!(32, "Low difficulty share"), detail: None }) ); @@ -534,7 +527,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: -32601, - message: "Method not found".try_into().unwrap(), + message: hstring!(32, "Method not found"), detail: None }) ); @@ -544,7 +537,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 30, - message: "SInvalidJobId".try_into().unwrap(), + message: hstring!(32, "SInvalidJobId"), detail: None }) ); @@ -553,7 +546,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 33, - message: "SInvalidVersion".try_into().unwrap(), + message: hstring!(32, "SInvalidVersion"), detail: None }) ); @@ -562,7 +555,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 34, - message: "SInvalidTime".try_into().unwrap(), + message: hstring!(32, "SInvalidTime"), detail: None }) ); @@ -571,7 +564,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 35, - message: "SInvalidExnSize".try_into().unwrap(), + message: hstring!(32, "SInvalidExnSize"), detail: None }) ); @@ -580,7 +573,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 38, - message: "STooLowDiff".try_into().unwrap(), + message: hstring!(32, "STooLowDiff"), detail: None }) ); @@ -589,7 +582,7 @@ mod tests { parse_submit(resp), Err(Error::Pool { code: 39, - message: "SStaleJobNoSub".try_into().unwrap(), + message: hstring!(32, "SStaleJobNoSub"), detail: None }) ); diff --git a/stratum-v1/src/fmt.rs b/stratum-v1/src/fmt.rs index e98dae2..35ade47 100644 --- a/stratum-v1/src/fmt.rs +++ b/stratum-v1/src/fmt.rs @@ -227,3 +227,21 @@ impl Try for Result { self } } + +macro_rules! hstring { + ($l:expr, $s:expr) => { + heapless::String::<$l>::from_str($s).unwrap() + }; +} + +macro_rules! hvec { + ($t:ident, $l:expr, $s:expr) => { + heapless::Vec::<$t, $l>::from_slice($s).unwrap() + }; +} + +macro_rules! hveca { + ($t:ident, $la:expr, $l:expr, $s:expr) => { + heapless::Vec::<[$t; $la], $l>::from_slice($s).unwrap() + }; +}