diff --git a/.github/workflows/release-libs.yaml b/.github/workflows/release-libs.yaml index c31cfdde0..9ab285ef4 100644 --- a/.github/workflows/release-libs.yaml +++ b/.github/workflows/release-libs.yaml @@ -10,14 +10,26 @@ name: Release Libs -on: - # Manually run by going to "Actions/Release" in Github and running the workflow - workflow_dispatch: +on: + pull_request: + branches: + - main jobs: libs_publish: runs-on: ubuntu-latest steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Run check-versioning-lib-release.sh + run: | + ./check-versioning-lib-release.sh + if [ $? -eq 1 ]; then + echo "Script returned exit code 1, halting the workflow" + exit 1 + fi + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: @@ -138,20 +150,25 @@ jobs: - name: Publish crate jd_client continue-on-error: true run: | - cargo publish --manifest-path=roles/jd-client/Cargo.toml + cd roles/jd-client + cargo publish - name: Publish crate jd_server continue-on-error: true run: | - cargo publish --manifest-path=roles/jd-server/Cargo.toml + cd roles/jd-server + cargo publish - name: Publish crate mining_proxy_sv2 continue-on-error: true run: | - cargo publish --manifest-path=roles/mining-proxy/Cargo.toml + cd roles/mining-proxy + cargo publish - name: Publish crate pool_sv2 continue-on-error: true run: | - cargo publish --manifest-path=roles/pool/Cargo.toml + cd roles/pool + cargo publish - name: Publish crate translator_sv2 continue-on-error: true run: | - cargo publish --manifest-path=roles/translator/Cargo.toml \ No newline at end of file + cd roles/translator + cargo publish \ No newline at end of file diff --git a/check-versioning-lib-release.sh b/check-versioning-lib-release.sh new file mode 100755 index 000000000..6d2bcc794 --- /dev/null +++ b/check-versioning-lib-release.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +git fetch origin main +git fetch origin dev + +crates=( +"utils/buffer" +"protocols/v2/binary-sv2/no-serde-sv2/derive_codec" +"protocols/v2/binary-sv2/no-serde-sv2/codec" +"protocols/v2/binary-sv2/serde-sv2" +"protocols/v2/binary-sv2/binary-sv2" +"protocols/v2/const-sv2" +"protocols/v2/framing-sv2" +"protocols/v2/noise-sv2" +"protocols/v2/codec-sv2" +"protocols/v2/subprotocols/common-messages" +"protocols/v2/subprotocols/job-declaration" +"protocols/v2/subprotocols/mining" +"protocols/v2/subprotocols/template-distribution" +"protocols/v2/sv2-ffi" +"protocols/v2/roles-logic-sv2" +"protocols/v1" +"utils/bip32-key-derivation" +"utils/error-handling" +"utils/key-utils" +"roles/roles-utils/network-helpers" +"roles/roles-utils/rpc" +"roles/jd-client" +"roles/jd-server" +"roles/mining-proxy" +"roles/pool" +"roles/translator" +) + +# Loop through each crate +for crate in "${crates[@]}"; do + cd "$crate" + + # Check if there were any changes between dev and main + git diff --quiet "origin/dev" "origin/main" -- . + if [ $? -ne 0 ]; then + + # Check if crate versions on dev and main are identical + version_dev=$(git show origin/dev:./Cargo.toml | awk -F' = ' '$1 == "version" {gsub(/[ "]+/, "", $2); print $2}') + version_main=$(git show origin/main:./Cargo.toml | awk -F' = ' '$1 == "version" {gsub(/[ "]+/, "", $2); print $2}') + if [ "$version_dev" = "$version_main" ]; then + echo "Changes detected in crate $crate between dev and main branches! Versions on dev and main branches are identical ($version_dev), so you should bump the crate version on dev before merging into main." + exit 1 + fi + fi + + cd - >/dev/null +done \ No newline at end of file diff --git a/protocols/Cargo.lock b/protocols/Cargo.lock index 9c408b52f..499a9096f 100644 --- a/protocols/Cargo.lock +++ b/protocols/Cargo.lock @@ -201,7 +201,7 @@ dependencies = [ [[package]] name = "codec_sv2" -version = "1.0.0" +version = "1.0.1" dependencies = [ "binary_sv2", "buffer_sv2", diff --git a/protocols/v2/binary-sv2/binary-sv2/src/lib.rs b/protocols/v2/binary-sv2/binary-sv2/src/lib.rs index ae13b38a6..03efb8601 100644 --- a/protocols/v2/binary-sv2/binary-sv2/src/lib.rs +++ b/protocols/v2/binary-sv2/binary-sv2/src/lib.rs @@ -14,9 +14,9 @@ pub use binary_codec_sv2::{self, Decodable as Deserialize, Encodable as Serializ #[cfg(not(feature = "with_serde"))] pub use derive_codec_sv2::{Decodable as Deserialize, Encodable as Serialize}; -pub fn clone_message(_: T) -> T { - todo!() -} +//pub fn clone_message(_: T) -> T { +// todo!() +//} pub fn u256_from_int>(value: V) -> U256<'static> { // initialize u256 as a bytes vec of len 24 diff --git a/protocols/v2/roles-logic-sv2/src/channel_logic/channel_factory.rs b/protocols/v2/roles-logic-sv2/src/channel_logic/channel_factory.rs index 8bf351a04..9237c0a70 100644 --- a/protocols/v2/roles-logic-sv2/src/channel_logic/channel_factory.rs +++ b/protocols/v2/roles-logic-sv2/src/channel_logic/channel_factory.rs @@ -74,11 +74,11 @@ pub enum OnNewShare { impl OnNewShare { /// convert standard share into extended share - pub fn into_extended(&mut self, extranonce: Vec, up_id: u32) { + pub fn into_extended(&mut self, extranonce: Vec, up_id: u32) -> Result<(), Error> { match self { - OnNewShare::SendErrorDownstream(_) => (), + OnNewShare::SendErrorDownstream(_) => Ok(()), OnNewShare::SendSubmitShareUpstream((share, template_id)) => match share { - Share::Extended(_) => (), + Share::Extended(_) => Ok(()), Share::Standard((share, _)) => { let share = SubmitSharesExtended { channel_id: up_id, @@ -90,11 +90,12 @@ impl OnNewShare { extranonce: extranonce.try_into().unwrap(), }; *self = Self::SendSubmitShareUpstream((Share::Extended(share), *template_id)); + Ok(()) } }, - OnNewShare::RelaySubmitShareUpstream => (), + OnNewShare::RelaySubmitShareUpstream => Ok(()), OnNewShare::ShareMeetBitcoinTarget((share, t_id, coinbase, ext)) => match share { - Share::Extended(_) => (), + Share::Extended(_) => Ok(()), Share::Standard((share, _)) => { let share = SubmitSharesExtended { channel_id: up_id, @@ -111,9 +112,10 @@ impl OnNewShare { coinbase.clone(), ext.to_vec(), )); + Ok(()) } }, - OnNewShare::ShareMeetDownstreamTarget => todo!(), + OnNewShare::ShareMeetDownstreamTarget => Err(Error::ShareDownstreamTargetNowAllowed), } } } @@ -859,8 +861,10 @@ impl ChannelFactory { coinbase, extranonce.to_vec(), )); - res.into_extended(extranonce_, up_id); - Ok(res) + match res.into_extended(extranonce_, up_id) { + Ok(()) => Ok(res), + Err(e) => Err(e), + } } ExtendedChannelKind::Pool => Ok(OnNewShare::ShareMeetBitcoinTarget(( m, @@ -875,8 +879,10 @@ impl ChannelFactory { let upstream_extranonce_space = self.extranonces.get_range0_len(); let extranonce = extranonce[upstream_extranonce_space..].to_vec(); let mut res = OnNewShare::SendSubmitShareUpstream((m, template_id)); - res.into_extended(extranonce, up_id); - Ok(res) + match res.into_extended(extranonce, up_id) { + Ok(()) => Ok(res), + Err(e) => Err(e), + } } ExtendedChannelKind::Pool => { Ok(OnNewShare::SendSubmitShareUpstream((m, template_id))) diff --git a/protocols/v2/roles-logic-sv2/src/errors.rs b/protocols/v2/roles-logic-sv2/src/errors.rs index 20c4bcd55..9e78cf7cb 100644 --- a/protocols/v2/roles-logic-sv2/src/errors.rs +++ b/protocols/v2/roles-logic-sv2/src/errors.rs @@ -61,6 +61,7 @@ pub enum Error { HashrateError(InputError), LogicErrorMessage(std::boxed::Box>), JDSMissingTransactions, + ShareDownstreamTargetNowAllowed, } impl From for Error { @@ -153,6 +154,7 @@ impl Display for Error { HashrateError(e) => write!(f, "Impossible to get Hashrate: {:?}", e), LogicErrorMessage(e) => write!(f, "Message is well formatted but can not be handled: {:?}", e), JDSMissingTransactions => write!(f, "JD server cannot propagate the block: missing transactions"), + ShareDownstreamTargetNowAllowed => write!(f, "Share that meets downstream target is not allowed"), } } } diff --git a/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs b/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs index 61044fa15..93e493e1a 100644 --- a/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs +++ b/protocols/v2/roles-logic-sv2/src/handlers/job_declaration.rs @@ -77,7 +77,12 @@ where .safe_lock(|x| x.handle_provide_missing_transactions(message)) .map_err(|e| crate::Error::PoisonLock(e.to_string()))? } - Ok(_) => todo!(), + // the following messsages are not supposed to be received from the server + Ok(JobDeclaration::AllocateMiningJobToken(_)) => panic!(), + Ok(JobDeclaration::DeclareMiningJob(_)) => panic!(), + Ok(JobDeclaration::IdentifyTransactionsSuccess(_)) => panic!(), + Ok(JobDeclaration::ProvideMissingTransactionsSuccess(_)) => panic!(), + Ok(JobDeclaration::SubmitSolution(_)) => panic!(), Err(e) => Err(e), } } @@ -176,8 +181,12 @@ where .safe_lock(|x| x.handle_submit_solution(message)) .map_err(|e| crate::Error::PoisonLock(e.to_string()))? } - - Ok(_) => todo!(), + // the following messsages are not supposed to be received from the client + Ok(JobDeclaration::DeclareMiningJobError(_)) => panic!(), + Ok(JobDeclaration::DeclareMiningJobSuccess(_)) => panic!(), + Ok(JobDeclaration::AllocateMiningJobTokenSuccess(_)) => panic!(), + Ok(JobDeclaration::IdentifyTransactions(_)) => panic!(), + Ok(JobDeclaration::ProvideMissingTransactions(_)) => panic!(), Err(e) => Err(e), } } diff --git a/protocols/v2/roles-logic-sv2/src/job_creator.rs b/protocols/v2/roles-logic-sv2/src/job_creator.rs index 67cfe9ad5..3056f305c 100644 --- a/protocols/v2/roles-logic-sv2/src/job_creator.rs +++ b/protocols/v2/roles-logic-sv2/src/job_creator.rs @@ -125,6 +125,8 @@ impl JobsCreators { .copied() } // TODO how many templates can we have at max + // reported as issue on github + // https://github.com/stratum-mining/stratum/issues/842 _ => todo!("{:#?}", template.len()), } } diff --git a/protocols/v2/subprotocols/common-messages/src/setup_connection.rs b/protocols/v2/subprotocols/common-messages/src/setup_connection.rs index f0f730aae..a7457ba77 100644 --- a/protocols/v2/subprotocols/common-messages/src/setup_connection.rs +++ b/protocols/v2/subprotocols/common-messages/src/setup_connection.rs @@ -85,6 +85,8 @@ impl<'decoder> SetupConnection<'decoder> { work_selection && version_rolling } // TODO + // this todo requires a bit of restructuring and it is reported as an issue + // https://github.com/stratum-mining/stratum/issues/853 _ => todo!(), } } diff --git a/roles/Cargo.lock b/roles/Cargo.lock index 26a464a72..ddd871240 100644 --- a/roles/Cargo.lock +++ b/roles/Cargo.lock @@ -78,6 +78,54 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -318,43 +366,21 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" -[[package]] -name = "binary_codec_sv2" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d2635651b7acd536bdf016919e5ce3d973cd53d7ac81c6f1d2523faf688a78" -dependencies = [ - "buffer_sv2 0.1.3", -] - [[package]] name = "binary_codec_sv2" version = "1.0.0" dependencies = [ - "buffer_sv2 1.0.0", -] - -[[package]] -name = "binary_sv2" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d073857c17f94784a1bf3477b7d000b4242766788bb67d83081828d966027cb" -dependencies = [ - "binary_codec_sv2 0.1.5", - "derive_codec_sv2 0.1.5", - "serde", - "serde_sv2 0.1.3", - "tracing", + "buffer_sv2", ] [[package]] name = "binary_sv2" version = "1.0.0" dependencies = [ - "binary_codec_sv2 1.0.0", - "derive_codec_sv2 1.0.0", + "binary_codec_sv2", + "derive_codec_sv2", "serde", - "serde_sv2 1.0.0", + "serde_sv2", "tracing", ] @@ -455,21 +481,12 @@ dependencies = [ "sha2 0.9.9", ] -[[package]] -name = "buffer_sv2" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14ad62c33affff6687aa53d2e8124ebf96fa8b92a38fdd0c46fa93f0175a5e94" -dependencies = [ - "aes-gcm", - "serde", -] - [[package]] name = "buffer_sv2" version = "1.0.0" dependencies = [ "aes-gcm", + "serde", ] [[package]] @@ -538,38 +555,70 @@ dependencies = [ ] [[package]] -name = "codec_sv2" -version = "1.0.0" +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "const_sv2 1.0.0", - "framing_sv2 1.0.0", - "noise_sv2 1.1.0", - "tracing", + "clap_builder", + "clap_derive", ] [[package]] -name = "codec_sv2" -version = "1.0.0" +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.55", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c306ce9b6e1a23cc2a8decadc6547b5b5240200a285ed826b15f1129c0bb9b5c" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "codec_sv2" +version = "1.0.1" dependencies = [ - "binary_sv2 0.1.7", - "buffer_sv2 0.1.3", - "const_sv2 0.1.3", - "framing_sv2 0.1.6", - "noise_sv2 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "binary_sv2", + "buffer_sv2", + "const_sv2", + "framing_sv2", + "noise_sv2", "serde", "tracing", ] +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "common_messages_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "const_sv2", ] [[package]] @@ -581,15 +630,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "const_sv2" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e86c77da33604c86f89f4ce7c7ae585f7cea0ee6e11388439ced40cd599c32" -dependencies = [ - "secp256k1 0.28.2", -] - [[package]] name = "const_sv2" version = "1.0.0" @@ -632,20 +672,11 @@ dependencies = [ "cipher", ] -[[package]] -name = "derive_codec_sv2" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ac6d35ced783f37b45a6315379aa81e01b444f64d90d49c7bb7f43f06dff356" -dependencies = [ - "binary_codec_sv2 0.1.5", -] - [[package]] name = "derive_codec_sv2" version = "1.0.0" dependencies = [ - "binary_codec_sv2 1.0.0", + "binary_codec_sv2", ] [[package]] @@ -769,25 +800,14 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "framing_sv2" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a545e927300897731132ade9109a4150f1b30680ed7b942bb22c36894103334" -dependencies = [ - "binary_sv2 0.1.7", - "buffer_sv2 0.1.3", - "const_sv2 0.1.3", - "serde", -] - [[package]] name = "framing_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "const_sv2", + "serde", ] [[package]] @@ -1001,6 +1021,12 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1175,11 +1201,11 @@ version = "0.1.0" dependencies = [ "async-channel 1.9.0", "async-recursion 0.3.2", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "codec_sv2", "error_handling", - "framing_sv2 1.0.0", + "framing_sv2", "futures", "key-utils", "network_helpers_sv2", @@ -1198,17 +1224,17 @@ name = "jd_server" version = "0.1.0" dependencies = [ "async-channel 1.9.0", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "codec_sv2", + "const_sv2", "error_handling", "hashbrown 0.11.2", "hex", "key-utils", "network_helpers_sv2", "nohash-hasher", - "noise_sv2 1.1.0", + "noise_sv2", "rand", "roles_logic_sv2", "rpc_sv2", @@ -1226,8 +1252,8 @@ dependencies = [ name = "job_declaration_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "const_sv2", ] [[package]] @@ -1313,15 +1339,20 @@ dependencies = [ "async-channel 1.9.0", "async-recursion 0.3.2", "async-std", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "clap", + "codec_sv2", + "const_sv2", "futures", + "key-utils", "network_helpers_sv2", "rand", "roles_logic_sv2", + "sha2 0.10.8", "stratum-common", + "tracing", + "tracing-subscriber", ] [[package]] @@ -1330,10 +1361,10 @@ version = "0.1.0" dependencies = [ "async-channel 1.9.0", "async-recursion 0.3.2", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "codec_sv2", + "const_sv2", "futures", "key-utils", "network_helpers_sv2", @@ -1352,8 +1383,8 @@ dependencies = [ name = "mining_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "const_sv2", ] [[package]] @@ -1378,13 +1409,13 @@ dependencies = [ [[package]] name = "network_helpers_sv2" -version = "1.0.0" +version = "1.0.1" dependencies = [ "async-channel 1.9.0", "async-std", - "binary_sv2 1.0.0", - "codec_sv2 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "const_sv2 1.0.0", + "binary_sv2", + "codec_sv2", + "const_sv2", "futures", "serde", "tokio", @@ -1403,21 +1434,7 @@ version = "1.1.0" dependencies = [ "aes-gcm", "chacha20poly1305", - "const_sv2 1.0.0", - "rand", - "rand_chacha", - "secp256k1 0.28.2", -] - -[[package]] -name = "noise_sv2" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be5decbcc8c7487c91277675df156c472a025c1a5d83d9a6a3da5ff458c4d3f" -dependencies = [ - "aes-gcm", - "chacha20poly1305", - "const_sv2 0.1.3", + "const_sv2", "rand", "rand_chacha", "secp256k1 0.28.2", @@ -1631,16 +1648,16 @@ version = "0.1.0" dependencies = [ "async-channel 1.9.0", "async-recursion 1.1.0", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "codec_sv2", + "const_sv2", "error_handling", "hex", "key-utils", "network_helpers_sv2", "nohash-hasher", - "noise_sv2 1.1.0", + "noise_sv2", "rand", "roles_logic_sv2", "secp256k1 0.28.2", @@ -1764,11 +1781,11 @@ checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" name = "roles_logic_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", + "binary_sv2", "chacha20poly1305", "common_messages_sv2", - "const_sv2 1.0.0", - "framing_sv2 1.0.0", + "const_sv2", + "framing_sv2", "job_declaration_sv2", "mining_sv2", "nohash-hasher", @@ -1907,21 +1924,11 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_sv2" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "149f67cef8328b644f1e48d3d420f07dc57505424f6c399d66b3b10a658cc0d4" -dependencies = [ - "buffer_sv2 0.1.3", - "serde", -] - [[package]] name = "serde_sv2" version = "1.0.0" dependencies = [ - "buffer_sv2 1.0.0", + "buffer_sv2", "serde", ] @@ -2015,6 +2022,12 @@ dependencies = [ "bitcoin", ] +[[package]] +name = "strsim" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" + [[package]] name = "subtle" version = "2.5.0" @@ -2040,7 +2053,7 @@ dependencies = [ name = "sv1_api" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", + "binary_sv2", "bitcoin_hashes 0.3.2", "byteorder", "hex", @@ -2077,8 +2090,8 @@ dependencies = [ name = "template_distribution_sv2" version = "1.0.0" dependencies = [ - "binary_sv2 1.0.0", - "const_sv2 1.0.0", + "binary_sv2", + "const_sv2", ] [[package]] @@ -2247,11 +2260,11 @@ dependencies = [ "async-compat", "async-recursion 0.3.2", "async-std", - "binary_sv2 1.0.0", - "buffer_sv2 1.0.0", - "codec_sv2 1.0.0", + "binary_sv2", + "buffer_sv2", + "codec_sv2", "error_handling", - "framing_sv2 1.0.0", + "framing_sv2", "futures", "key-utils", "network_helpers_sv2", @@ -2298,6 +2311,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "valuable" version = "0.1.0" diff --git a/roles/jd-client/README.md b/roles/jd-client/README.md index efc5d8d2a..18ab95197 100644 --- a/roles/jd-client/README.md +++ b/roles/jd-client/README.md @@ -1,38 +1,34 @@ # JD Client -The JD Client is a Sv2 proxy that support one extended channel upstream and one extended channel -dowstream, and do job declaration. On start it will: + * connect to the jd-server * connect to the template-provider -* listen for and `OpenExtendedChannel` from downstream +The JD Client receives custom block templates from a Template Provider and declares use of the template with the pool using the Job Declaration Protocol. Further distributes the jobs to Mining Proxy (or Proxies) using the Job Distribution Protocol. ``` * transparently relay the `OpenExtendedChannel` to upstream -After the setup phase it will start to negotiate jobs with upstream and send the negotiated job -downstream, so that everything that is dowstream do not need to know that job is negotiated. ## Setup + ### Configuration File -The `proxy-config-example.toml` is a configuration example. The configuration file contains the following information: -1. The Upstream connection information which includes the SV2 Pool authority public key - (`upstream_authority_pubkey`) and the SV2 Pool connection address (`upstream_address`) and port - (`upstream_port`). -2. The maximum and minimum SV2 versions (`max_supported_version` and `min_supported_version`) -3. The Job Declarator information which includes the Pool JD connection address (`jd_address`) and the Template Provider connection address to which to connect (`tp_address`). -4. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example: -``` +1. The downstream socket information, which includes the listening IP address (`downstream_address`) and port (`downstream_port`). +2. The maximum and minimum SRI versions (`max_supported_version` and `min_supported_version`) with size as (`min_extranonce2_size`) +3. The authentication keys for the downstream connection (`authority_public_key`, `authority_secret_key`) +4. A `retry` parameter which tells JDC the number of times to reinitialize itself after a failure. +6. The Template Provider address (`tp_address`). +7. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example: + # 2024-02-13T14:59:24Z Template Provider authority key: EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd -``` ### Run -1. Copy the `jdc-config-example.toml` into `conf/` directory. -2. Edit it with custom desired configuration and rename it `jdc-config.toml` -3. Point the SV1 Downstream Mining Device(s) to the Translator Proxy IP address and port. -4. Run the Translator Proxy: - - ``` - cd roles/translator - ``` - ``` - cargo run -p translator_sv2 -- -c conf/jdc-config.toml - ``` + +Run the Job Declarator Client (JDC): +There are two files when you cd into roles/jd-client/config-examples/ + +1. `jdc-config-hosted-example.toml` connects to the community-hosted roles. +2. `jdc-config-local-example.toml` connects to self-hosted Job Declarator Client (JDC) and Translator Proxy + +``` bash +cd roles/jd-client/config-examples/ +cargo run -- -c jdc-config-hosted-example.toml +``` diff --git a/roles/mining-proxy/config-examples/proxy-config-example.toml b/roles/mining-proxy/config-examples/proxy-config-example.toml index 35d3917dd..6766f82d6 100644 --- a/roles/mining-proxy/config-examples/proxy-config-example.toml +++ b/roles/mining-proxy/config-examples/proxy-config-example.toml @@ -6,7 +6,6 @@ listen_mining_port = 34255 max_supported_version = 2 min_supported_version = 2 downstream_share_per_minute = 1 -coinbase_reward_sat = 5_000_000_000 # This value is used by the proxy to communicate to the pool the expected hash rate when we open an # extended channel, based on it the pool will set a target for the channel expected_total_downstream_hr = 10_000 diff --git a/roles/pool/README.md b/roles/pool/README.md index 5d7bd5b50..1e608b80d 100644 --- a/roles/pool/README.md +++ b/roles/pool/README.md @@ -1,4 +1,6 @@ + # SRI Pool + SRI Pool is designed to communicate with Downstream role (most typically a Translator Proxy or a Mining Proxy) running SV2 protocol to exploit features introduced by its sub-protocols. The most typical high level configuration is: @@ -18,47 +20,35 @@ The most typical high level configuration is: ``` ## Setup + ### Configuration File -The `pool-config-example.toml` is a configuration example which can be copy/paste into `/conf` directory by the party that is running the SV2 Pool (most -typically the pool service provider) to address the most preferred customization. + +`pool-config-hosted-tp-example.toml` and `pool-config-local-tp-example.toml` are examples of configuration files. The configuration file contains the following information: -1. The SRI Pool information which includes the SRI Pool authority public key - (`authority_pubkey`), the SRI Pool authority secret key (`authority_secret_key`), along with its certificate validity (`cert_validity_sec`). In addition to this, it contains the address which it will use to listen to new connection from downstream roles (`listen_address`) and the list of uncompressed pubkeys for coinbase payout (`coinbase_outputs`). -2. The SRI Pool Job Negatiator information which includes the Template Provider address (`tp_address`) and the address it uses to listen new request from the downstream JDs (`jd_address`). -3. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example: +1. The SRI Pool information which includes the SRI Pool authority public key + (`authority_public_key`), the SRI Pool authority secret key (`authority_secret_key`). +2. The address which it will use to listen to new connection from downstream roles (`listen_address`) +3. The list of uncompressed pubkeys for coinbase payout (`coinbase_outputs`) +4. A string that serves as signature on the coinbase tx (`pool_signature`). +5. The Template Provider address (`tp_address`). +6. Optionally, you may want to verify that your TP connection is authentic. You may get `tp_authority_public_key` from the logs of your TP, for example: + ``` # 2024-02-13T14:59:24Z Template Provider authority key: EguTM8URcZDQVeEBsM4B5vg9weqEUnufA8pm85fG4bZd ``` ### Run -1. Copy the `pool-config-example.toml` into `conf/` directory. -2. Edit it with custom desired configuration and rename it `pool-config.toml` - > **Warning**
- > If you want to mine spendable bitcoin on regtest, you can do it with bitcoin-cli: - > 1. Get a legacy Bitcoin address: - > ``` - > bitcoin-cli -regtest -rpcwallet="" getnewaddress "test" "legacy" - > ``` - > 2. Retrieve its corresponding public key: - > ``` - > bitcoin-cli -regtest getaddressinfo - > ``` - > 3. Copy the pubkey showed in the output - > 4. Paste it in the `coinbase_outputs` of `pool-config.toml`, after deleting the one which is already present - > 5. Mine a block - > 6. Generate 100 blocks - > ``` - > bitcoin-cli -regtest generatetoaddress 100 bcrt1qc5xss0cma0zldxfzzdpjxsayut7yy86e2lr6km - > ``` - > Now the mined bitcoin are spendable! - -3. Run the Pool: - - ``` - cd roles/v2/pool - ``` - ``` - cargo run -p pool_sv2 -- -c conf/pool-config.toml - ``` \ No newline at end of file + +There are two files found in `roles/pool/config-examples` + +1. `pool-config-hosted-tp-example.toml` runs on our community hosted server. +2. `pool-config-example-tp-example.toml` runs with your local config. + +Run the Pool: + +```bash +cd roles/pool/config-examples +cargo run -- -c pool-config-hosted-tp-example.toml +``` diff --git a/roles/pool/config-examples/pool-config-local-tp-example.toml b/roles/pool/config-examples/pool-config-local-tp-example.toml index 016c372f5..edc69b3c1 100644 --- a/roles/pool/config-examples/pool-config-local-tp-example.toml +++ b/roles/pool/config-examples/pool-config-local-tp-example.toml @@ -1,7 +1,6 @@ # SRI Pool config authority_public_key = "9auqWEzQDVyd2oe1JVGFLMLHZtCo2FFqZwtKA5gd9xbuEu7PH72" authority_secret_key = "mkDLTBBRxdBv998612qipDYoTK3YUrqLe8uWw7gu3iXbSrn2n" -#authority_secret_key = "7qbpUjScc865jyX2kiB4NVJANoC7GA7TAJupdzXWkc62" cert_validity_sec = 3600 test_only_listen_adress_plain = "0.0.0.0:34250" listen_address = "0.0.0.0:34254" diff --git a/roles/test-utils/mining-device/Cargo.toml b/roles/test-utils/mining-device/Cargo.toml index f308cb146..41429d6a1 100644 --- a/roles/test-utils/mining-device/Cargo.toml +++ b/roles/test-utils/mining-device/Cargo.toml @@ -19,3 +19,8 @@ buffer_sv2 = { version = "1.0.0", path = "../../../utils/buffer"} async-recursion = "0.3.2" rand = "0.8.4" futures = "0.3.5" +key-utils = { version = "^1.0.0", path = "../../../utils/key-utils" } +clap = { version = "^4.5.4", features = ["derive"] } +tracing = { version = "0.1" } +tracing-subscriber = "0.3" +sha2 = "0.10.6" diff --git a/roles/test-utils/mining-device/src/main.rs b/roles/test-utils/mining-device/src/main.rs index a0cc047a2..befd7edff 100644 --- a/roles/test-utils/mining-device/src/main.rs +++ b/roles/test-utils/mining-device/src/main.rs @@ -1,35 +1,117 @@ use async_std::net::TcpStream; -use network_helpers_sv2::PlainConnection; +use key_utils::Secp256k1PublicKey; +use network_helpers_sv2::Connection; use roles_logic_sv2::utils::Id; -use std::{ - net::{IpAddr, Ipv4Addr, SocketAddr}, - sync::Arc, -}; +use std::{net::SocketAddr, sync::Arc, thread::sleep, time::Duration}; +use async_std::net::ToSocketAddrs; +use clap::Parser; +use rand::{thread_rng, Rng}; +use sha2::{Digest, Sha256}; +use std::time::Instant; use stratum_common::bitcoin::{ blockdata::block::BlockHeader, hash_types::BlockHash, hashes::Hash, util::uint::Uint256, }; +use tracing::{error, info}; + +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +struct Args { + #[arg( + short, + long, + help = "Pool pub key, when left empty the pool certificate is not checked" + )] + pubkey_pool: Option, + #[arg( + short, + long, + help = "Sometimes used by the pool to identify the device" + )] + id_device: Option, + #[arg( + short, + long, + help = "Address of the pool in this format ip:port or domain:port" + )] + address_pool: String, + #[arg( + long, + help = "This value is used to slow down the cpu miner, it rapresents the number of micro-seconds that are awaited between hashes", + default_value = "0" + )] + handicap: u32, + #[arg( + long, + help = "User id, used when a new channel is opened, it can be used by the pool to identify the miner" + )] + id_user: Option, +} -async fn connect(address: SocketAddr, handicap: u32) { - let stream = TcpStream::connect(address).await.unwrap(); +async fn connect( + address: String, + pub_key: Option, + device_id: Option, + user_id: Option, + handicap: u32, +) { + let address = address + .clone() + .to_socket_addrs() + .await + .expect("Invalid pool address, use one of this formats: ip:port, domain:port") + .next() + .expect("Invalid pool address, use one of this formats: ip:port, domain:port"); + info!("Connecting to pool at {}", address); + let socket = loop { + let pool = + async_std::future::timeout(Duration::from_secs(5), TcpStream::connect(address)).await; + match pool { + Ok(result) => match result { + Ok(socket) => break socket, + Err(e) => { + error!( + "Failed to connect to Upstream role at {}, retrying in 5s: {}", + address, e + ); + sleep(Duration::from_secs(5)); + } + }, + Err(_) => { + error!("Pool is unresponsive, terminating"); + std::process::exit(1); + } + } + }; + info!("Pool tcp connection established at {}", address); + let address = socket.peer_addr().unwrap(); + let initiator = Initiator::new(pub_key.map(|e| e.0)); let (receiver, sender): (Receiver, Sender) = - PlainConnection::new(stream, 10).await; - Device::start(receiver, sender, address, handicap).await + Connection::new(socket, codec_sv2::HandshakeRole::Initiator(initiator), 10) + .await + .unwrap(); + info!("Pool noise connection established at {}", address); + Device::start(receiver, sender, address, device_id, user_id, handicap).await } #[async_std::main] async fn main() { - let socket = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 34255); - //task::spawn(async move { connect(socket, 10000).await }); - //task::spawn(async move { connect(socket, 11070).await }); - //task::spawn(async move { connect(socket, 7040).await }); - println!("start"); - connect(socket, 0).await + let args = Args::parse(); + tracing_subscriber::fmt::init(); + info!("start"); + connect( + args.address_pool, + args.pubkey_pool, + args.id_device, + args.id_user, + args.handicap, + ) + .await } use async_channel::{Receiver, Sender}; -use binary_sv2::u256_from_int; -use codec_sv2::{Frame, StandardEitherFrame, StandardSv2Frame}; +use binary_sv2::{u256_from_int, U256}; +use codec_sv2::{Frame, Initiator, StandardEitherFrame, StandardSv2Frame}; use roles_logic_sv2::{ common_messages_sv2::{Protocol, SetupConnection, SetupConnectionSuccess}, common_properties::{IsMiningUpstream, IsUpstream}, @@ -56,12 +138,19 @@ impl SetupConnectionHandler { pub fn new() -> Self { SetupConnectionHandler {} } - fn get_setup_connection_message(address: SocketAddr) -> SetupConnection<'static> { + fn get_setup_connection_message( + address: SocketAddr, + device_id: Option, + ) -> SetupConnection<'static> { let endpoint_host = address.ip().to_string().into_bytes().try_into().unwrap(); let vendor = String::new().try_into().unwrap(); let hardware_version = String::new().try_into().unwrap(); let firmware = String::new().try_into().unwrap(); - let device_id = String::new().try_into().unwrap(); + let device_id = device_id.unwrap_or_default(); + info!( + "Creating SetupConnection message with device id: {:?}", + device_id + ); SetupConnection { protocol: Protocol::MiningProtocol, min_version: 2, @@ -72,22 +161,24 @@ impl SetupConnectionHandler { vendor, hardware_version, firmware, - device_id, + device_id: device_id.try_into().unwrap(), } } pub async fn setup( self_: Arc>, receiver: &mut Receiver, sender: &mut Sender, + device_id: Option, address: SocketAddr, ) { - let setup_connection = Self::get_setup_connection_message(address); + let setup_connection = Self::get_setup_connection_message(address, device_id); let sv2_frame: StdFrame = MiningDeviceMessages::Common(setup_connection.into()) .try_into() .unwrap(); let sv2_frame = sv2_frame.into(); sender.send(sv2_frame).await.unwrap(); + info!("Setup connection sent to {}", address); let mut incoming: StdFrame = receiver.recv().await.unwrap().try_into().unwrap(); let message_type = incoming.get_header().unwrap().msg_type(); @@ -108,6 +199,7 @@ impl ParseUpstreamCommonMessages for SetupConnectionHandler { _: SetupConnectionSuccess, ) -> Result { use roles_logic_sv2::handlers::common::SendTo; + info!("Setup connection success"); Ok(SendTo::None(None)) } @@ -115,6 +207,7 @@ impl ParseUpstreamCommonMessages for SetupConnectionHandler { &mut self, _: roles_logic_sv2::common_messages_sv2::SetupConnectionError, ) -> Result { + error!("Setup connection error"); todo!() } @@ -140,14 +233,17 @@ pub struct Device { sequence_numbers: Id, } -fn open_channel() -> OpenStandardMiningChannel<'static> { - let user_identity = "ABC".to_string().try_into().unwrap(); +fn open_channel(device_id: Option) -> OpenStandardMiningChannel<'static> { + let user_identity = device_id.unwrap_or_default().try_into().unwrap(); let id: u32 = 10; - println!("MINING DEVICE: send open channel with request id {}", id); + info!("Measuring pc hashrate"); + let nominal_hash_rate = measure_hashrate(5) as f32; + info!("Pc hashrate is {}", nominal_hash_rate); + info!("MINING DEVICE: send open channel with request id {}", id); OpenStandardMiningChannel { request_id: id.into(), user_identity, - nominal_hash_rate: 1000.0, // use 1000 or 10000 to test group channels + nominal_hash_rate, max_target: u256_from_int(567_u64), } } @@ -157,11 +253,20 @@ impl Device { mut receiver: Receiver, mut sender: Sender, addr: SocketAddr, + device_id: Option, + user_id: Option, handicap: u32, ) { let setup_connection_handler = Arc::new(Mutex::new(SetupConnectionHandler::new())); - SetupConnectionHandler::setup(setup_connection_handler, &mut receiver, &mut sender, addr) - .await; + SetupConnectionHandler::setup( + setup_connection_handler, + &mut receiver, + &mut sender, + device_id, + addr, + ) + .await; + info!("Pool sv2 connection established at {}", addr); let miner = Arc::new(Mutex::new(Miner::new(handicap))); let self_ = Self { channel_opened: false, @@ -174,7 +279,7 @@ impl Device { sequence_numbers: Id::new(), }; let open_channel = - MiningDeviceMessages::Mining(Mining::OpenStandardMiningChannel(open_channel())); + MiningDeviceMessages::Mining(Mining::OpenStandardMiningChannel(open_channel(user_id))); let frame: StdFrame = open_channel.try_into().unwrap(); self_.sender.send(frame.into()).await.unwrap(); let self_mutex = std::sync::Arc::new(Mutex::new(self_)); @@ -314,7 +419,7 @@ impl ParseUpstreamMiningMessages<(), NullDownstreamMiningSelector, NoRouting> fo self.channel_opened = true; self.channel_id = Some(m.channel_id); let req_id = m.get_request_id_as_u32(); - println!( + info!( "MINING DEVICE: channel opened with: group id {}, channel id {}, request id {}", m.group_channel_id, m.channel_id, req_id ); @@ -357,12 +462,12 @@ impl ParseUpstreamMiningMessages<(), NullDownstreamMiningSelector, NoRouting> fo &mut self, m: SubmitSharesSuccess, ) -> Result, Error> { - println!("SUCCESS {:?}", m); + info!("SUCCESS {:?}", m); Ok(SendTo::None(None)) } fn handle_submit_shares_error(&mut self, _: SubmitSharesError) -> Result, Error> { - println!("Submit shares error"); + info!("Submit shares error"); Ok(SendTo::None(None)) } @@ -425,8 +530,11 @@ impl ParseUpstreamMiningMessages<(), NullDownstreamMiningSelector, NoRouting> fo todo!() } - fn handle_set_target(&mut self, _: SetTarget) -> Result, Error> { - todo!() + fn handle_set_target(&mut self, m: SetTarget) -> Result, Error> { + self.miner + .safe_lock(|miner| miner.new_target(m.maximum_target.to_vec())) + .unwrap(); + Ok(SendTo::None(None)) } fn handle_reconnect(&mut self, _: Reconnect) -> Result, Error> { @@ -457,6 +565,10 @@ impl Miner { fn new_target(&mut self, mut target: Vec) { // target is sent in LE and comparisons in this file are done in BE target.reverse(); + let hex_string = target + .iter() + .fold("".to_string(), |acc, b| acc + format!("{:02x}", b).as_str()); + info!("Set target to {}", hex_string); self.target = Some(Uint256::from_be_bytes(target.try_into().unwrap())); } @@ -489,7 +601,7 @@ impl Miner { hash.reverse(); let hash = Uint256::from_be_bytes(hash); if hash < *self.target.as_ref().ok_or(())? { - println!( + info!( "Found share with nonce: {}, for target: {:?}, with hash: {:?}", header.nonce, self.target, hash, ); @@ -499,3 +611,36 @@ impl Miner { } } } + +// returns hashrate based on how fast the device hashes over the given duration +fn measure_hashrate(duration_secs: u64) -> f64 { + let mut share = generate_random_80_byte_array(); + let start_time = Instant::now(); + let mut hashes: u64 = 0; + let duration = Duration::from_secs(duration_secs); + + while start_time.elapsed() < duration { + for _ in 0..10000 { + hash(&mut share); + hashes += 1; + } + } + + let elapsed_secs = start_time.elapsed().as_secs_f64(); + hashes as f64 / elapsed_secs +} +fn generate_random_80_byte_array() -> [u8; 80] { + let mut rng = thread_rng(); + let mut arr = [0u8; 80]; + rng.fill(&mut arr[..]); + arr +} +fn hash(share: &mut [u8; 80]) -> Target { + let nonce: [u8; 8] = share[0..8].try_into().unwrap(); + let mut nonce = u64::from_le_bytes(nonce); + nonce += 1; + share[0..8].copy_from_slice(&nonce.to_le_bytes()); + let hash = Sha256::digest(&share).to_vec(); + let hash: U256<'static> = hash.try_into().unwrap(); + hash.into() +} diff --git a/roles/translator/README.md b/roles/translator/README.md index ce8a07582..e09e4fd30 100644 --- a/roles/translator/README.md +++ b/roles/translator/README.md @@ -1,4 +1,6 @@ + # SV1 to SV2 Translator Proxy + This proxy is designed to sit in between a SV1 Downstream role (most typically Mining Device(s) running SV1 firmware) and a SV2 Upstream role (most typically a SV2 Pool Server with Extended Channel support). @@ -20,36 +22,37 @@ The most typical high level configuration is: ``` ## Setup + ### Configuration File -The `proxy-config-example.toml` is a configuration example which can be copy/paste into `/conf` directory by the party that is running the Translator Proxy (most -typically the mining farm/miner hobbyist) to address the most preferred customization. + +`tproxy-config-local-jdc-example.toml` and `tproxy-config-local-pool-example.toml` are examples of configuration files for the Translator Proxy. The configuration file contains the following information: 1. The SV2 Upstream connection information which includes the SV2 Pool authority public key (`upstream_authority_pubkey`) and the SV2 Pool connection address (`upstream_address`) and port (`upstream_port`). -1. The SV1 Downstream connection information which includes the SV1 Mining Device address +2. The SV1 Downstream socket information which includes the listening IP address (`downstream_address`) and port (`downstream_port`). -1. The maximum and minimum SV2 versions (`max_supported_version` and `min_supported_version`) that +3. The maximum and minimum SRI versions (`max_supported_version` and `min_supported_version`) that the Translator Proxy implementer wants to support. Currently the only available version is `2`. -1. The desired minimum `extranonce2` size that the Translator Proxy implementer wants to use +4. The desired minimum `extranonce2` size that the Translator Proxy implementer wants to use (`min_extranonce2_size`). The `extranonce2` size is ultimately decided by the SV2 Upstream role, but if the specified size meets the SV2 Upstream role's requirements, the size specified in this configuration file should be favored. -1. The Job Declarator information which includes the Pool JD connection address (`jd_address`) and the Template Provider connection address to which to connect (`tp_address`). -1. The difficulty params such as the hashrate (hashes/s) of the weakest Mining Device that will be connecting to the Translator Proxy (`min_individual_miner_hashrate`), the number of shares needed before a mining.set_difficulty update (`miner_num_submits_before_update`) and the number of shares per minute that Mining Devices should be sending to the Translator Proxy (`shares_per_minute`). Ultimately, the estimated aggregate hashrate of all SV1 Downstream roles (Mining - Devices) (`channel_nominal_hashrate`), which is communicated to the SV2 Upstream to help it decide a proper difficulty target. +5. The downstream difficulty params such as: +- the hashrate (hashes/s) of the weakest Mining Device that will be connecting to the Translator Proxy (`min_individual_miner_hashrate`) +- the number of shares per minute that Mining Devices should be sending to the Translator Proxy (`shares_per_minute`). +6. The upstream difficulty params such as: +- the interval in seconds to elapse before updating channel hashrate with the pool (`channel_diff_update_interval`) +- the estimated aggregate hashrate of all SV1 Downstream roles (`channel_nominal_hashrate`) ### Run -1. Copy the `proxy-config-example.toml` into `conf/` directory. -2. Edit it with custom desired configuration and rename it `proxy-config.toml` -3. Point the SV1 Downstream Mining Device(s) to the Translator Proxy IP address and port. -4. Run the Translator Proxy: - - ``` - cd roles/translator - ``` - ``` - cargo run -p translator_sv2 -- -c conf/proxy-config.toml - ``` + +There are two files in `roles/translator/config-examples`: +- `tproxy-config-local-jdc-example.toml` which assumes the Job Declaration protocol is used and a JD Client is deployed locally +- `tproxy-config-local-pool-example.toml` which assumes Job Declaration protocol is NOT used, and a Pool is deployed locally + +```bash +cd roles/translator/config-examples/ +cargo run -- -c tproxy-config-local-jdc-example.toml \ No newline at end of file diff --git a/roles/translator/config-examples/tproxy-config-local-jdc-example.toml b/roles/translator/config-examples/tproxy-config-local-jdc-example.toml index a8bc389aa..5fe4a8eeb 100644 --- a/roles/translator/config-examples/tproxy-config-local-jdc-example.toml +++ b/roles/translator/config-examples/tproxy-config-local-jdc-example.toml @@ -21,7 +21,6 @@ min_supported_version = 2 # Max value for CGminer: 8 # Min value: 2 min_extranonce2_size = 8 -coinbase_reward_sat = 5_000_000_000 # Difficulty params [downstream_difficulty_config] diff --git a/roles/translator/config-examples/tproxy-config-local-pool-example.toml b/roles/translator/config-examples/tproxy-config-local-pool-example.toml index d963ec945..b4359d5ab 100644 --- a/roles/translator/config-examples/tproxy-config-local-pool-example.toml +++ b/roles/translator/config-examples/tproxy-config-local-pool-example.toml @@ -21,7 +21,6 @@ min_supported_version = 2 # Max value for CGminer: 8 # Min value: 2 min_extranonce2_size = 8 -coinbase_reward_sat = 5_000_000_000 # Difficulty params [downstream_difficulty_config] diff --git a/utils/key-utils/src/lib.rs b/utils/key-utils/src/lib.rs index fdfc0c7de..4cde25083 100644 --- a/utils/key-utils/src/lib.rs +++ b/utils/key-utils/src/lib.rs @@ -27,6 +27,8 @@ impl Display for Error { } } +impl std::error::Error for Error {} + impl From for Error { fn from(e: Bs58DecodeError) -> Self { Error::Bs58Decode(e)