From 01396910afe65f7610cead81b586ea218476625c Mon Sep 17 00:00:00 2001 From: Richard Bertok Date: Tue, 24 Sep 2024 15:52:45 +0200 Subject: [PATCH] feat(coinbase-extra): add coinbase extra field (#67) Description --- Coinbase extra field is cached now (locally) and use other miners' coinbase extra when possible from share chain for their shares. Motivation and Context --- Coinbase extra field was not supported to be passed to p2pool before, so in order to let miners pass any extra data they want, we need to be able to do that. Specs for the format of p2pool coinbase extra field: https://github.com/tari-project/sha-p2pool/issues/56 How Has This Been Tested? --- What process can a PR reviewer use to test or verify this change? --- Breaking Changes --- - [ ] None - [ ] Requires data directory on base node to be deleted - [ ] Requires hard fork - [x] Other - Please specify - P2pool should be updated at all clients --- Cargo.lock | 279 +++++++++--------- Cargo.toml | 3 +- src/cli/args.rs | 30 +- .../{list_tribes.rs => list_squads.rs} | 22 +- src/cli/commands/mod.rs | 4 +- src/cli/commands/util.rs | 29 +- src/cli/util.rs | 8 +- src/server/config.rs | 6 +- src/server/grpc/p2pool.rs | 41 ++- src/server/grpc/util.rs | 25 +- src/server/http/server.rs | 12 +- src/server/http/stats/handlers.rs | 39 ++- src/server/http/stats/models.rs | 6 +- src/server/p2p/messages.rs | 8 +- src/server/p2p/network.rs | 152 +++++----- src/server/p2p/peer_store.rs | 8 +- src/server/server.rs | 15 +- src/sharechain/block.rs | 7 + src/sharechain/in_memory.rs | 101 +++++-- src/sharechain/mod.rs | 13 +- 20 files changed, 492 insertions(+), 316 deletions(-) rename src/cli/commands/{list_tribes.rs => list_squads.rs} (77%) diff --git a/Cargo.lock b/Cargo.lock index dc8fa43..2ada03c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,7 +286,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-sink", "futures-util", "memchr", @@ -299,7 +299,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-sink", "futures-util", "memchr", @@ -332,7 +332,7 @@ dependencies = [ "async-trait", "axum-core 0.3.4", "bitflags 1.3.2", - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 0.2.12", "http-body 0.4.6", @@ -346,20 +346,20 @@ dependencies = [ "rustversion", "serde", "sync_wrapper 0.1.2", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", ] [[package]] name = "axum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +checksum = "8f43644eed690f5374f1af436ecd6aea01cd201f6fbdf0178adaf6907afb2cec" dependencies = [ "async-trait", - "axum-core 0.4.3", - "bytes 1.7.1", + "axum-core 0.4.4", + "bytes 1.7.2", "futures-util", "http 1.1.0", "http-body 1.0.1", @@ -379,7 +379,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower", + "tower 0.5.1", "tower-layer", "tower-service", "tracing", @@ -392,7 +392,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 0.2.12", "http-body 0.4.6", @@ -404,12 +404,12 @@ dependencies = [ [[package]] name = "axum-core" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +checksum = "5e6b8ba012a258d63c9adfa28b9ddcf66149da6f986c5b5452e629d5ee64bf00" dependencies = [ "async-trait", - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 1.1.0", "http-body 1.0.1", @@ -417,7 +417,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper 0.1.2", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", "tracing", @@ -630,9 +630,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -648,9 +648,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.19" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "shlex", ] @@ -758,9 +758,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -768,9 +768,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -780,9 +780,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -1602,7 +1602,7 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "futures-core", "futures-sink", @@ -1793,7 +1793,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "itoa", ] @@ -1804,7 +1804,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "itoa", ] @@ -1815,7 +1815,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "http 0.2.12", "pin-project-lite", ] @@ -1826,7 +1826,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "http 1.1.0", ] @@ -1836,7 +1836,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 1.1.0", "http-body 1.0.1", @@ -1867,7 +1867,7 @@ version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-channel", "futures-core", "futures-util", @@ -1891,7 +1891,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-channel", "futures-util", "http 1.1.0", @@ -1922,20 +1922,22 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 1.1.0", "http-body 1.0.1", "hyper 1.4.1", "pin-project-lite", "tokio", + "tower 0.4.13", + "tower-service", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2028,7 +2030,7 @@ checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ "async-trait", "attohttpc", - "bytes 1.7.1", + "bytes 1.7.2", "futures 0.3.30", "http 0.2.12", "hyper 0.14.30", @@ -2221,7 +2223,7 @@ version = "0.53.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681fb3f183edfbedd7a57d32ebe5dcdc0b9f94061185acf3c30249349cc6fc99" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "either", "futures 0.3.30", "futures-timer", @@ -2247,7 +2249,7 @@ dependencies = [ "libp2p-tcp", "libp2p-upnp", "libp2p-yamux", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "pin-project 1.1.5", "rw-stream-sink", "thiserror", @@ -2309,7 +2311,7 @@ dependencies = [ "futures 0.3.30", "futures-timer", "libp2p-identity", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "multistream-select", "once_cell", @@ -2375,7 +2377,7 @@ dependencies = [ "asynchronous-codec 0.7.0", "base64 0.21.7", "byteorder", - "bytes 1.7.1", + "bytes 1.7.2", "either", "fnv", "futures 0.3.30", @@ -2448,7 +2450,7 @@ checksum = "5cc5767727d062c4eac74dd812c998f0e488008e82cce9c33b463d38423f9ad2" dependencies = [ "arrayvec", "asynchronous-codec 0.7.0", - "bytes 1.7.1", + "bytes 1.7.2", "either", "fnv", "futures 0.3.30", @@ -2518,12 +2520,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecd0545ce077f6ea5434bcb76e8d0fe942693b4380aaad0d34a358c2bd05793" dependencies = [ "asynchronous-codec 0.7.0", - "bytes 1.7.1", + "bytes 1.7.2", "curve25519-dalek", "futures 0.3.30", "libp2p-core", "libp2p-identity", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "once_cell", "quick-protobuf", @@ -2543,7 +2545,7 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c67296ad4e092e23f92aea3d2bdb6f24eab79c0929ed816dfb460ea2f4567d2b" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures 0.3.30", "futures-timer", "if-watch", @@ -2568,7 +2570,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d1c667cfabf3dd675c8e3cea63b7b98434ecf51721b7894cbb01d29983a6a9b" dependencies = [ "asynchronous-codec 0.7.0", - "bytes 1.7.1", + "bytes 1.7.2", "either", "futures 0.3.30", "futures-bounded", @@ -2916,8 +2918,8 @@ dependencies = [ [[package]] name = "minotari_app_grpc" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "argon2", "base64 0.13.1", @@ -2946,8 +2948,8 @@ dependencies = [ [[package]] name = "minotari_ledger_wallet_common" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "bs58 0.5.1", ] @@ -2955,7 +2957,7 @@ dependencies = [ [[package]] name = "minotari_node_grpc_client" version = "0.1.0" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "minotari_app_grpc", ] @@ -3033,9 +3035,9 @@ dependencies = [ [[package]] name = "multiaddr" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" dependencies = [ "arrayref", "byteorder", @@ -3046,7 +3048,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", "url", ] @@ -3109,7 +3111,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea0df8e5eec2298a62b326ee4f0d7fe1a6b90a09dfcf9df37b38f947a8c42f19" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures 0.3.30", "log", "pin-project 1.1.5", @@ -3161,7 +3163,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures 0.3.30", "log", "netlink-packet-core", @@ -3176,7 +3178,7 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures 0.3.30", "libc", "log", @@ -3358,9 +3360,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ea5043e58958ee56f3e15a90aee535795cd7dfd319846288d93c5b57d85cbe" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" dependencies = [ "critical-section", "portable-atomic", @@ -3555,9 +3557,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polling" @@ -3599,12 +3601,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" -dependencies = [ - "critical-section", -] +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" [[package]] name = "powerfmt" @@ -3724,7 +3723,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "prost-derive", ] @@ -3734,7 +3733,7 @@ version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "heck 0.4.1", "itertools 0.10.5", "lazy_static", @@ -3809,7 +3808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ededb1cd78531627244d51dd0c7139fbe736c7d57af0092a76f0ffb2f56e98" dependencies = [ "asynchronous-codec 0.6.2", - "bytes 1.7.1", + "bytes 1.7.2", "quick-protobuf", "thiserror", "unsigned-varint 0.7.2", @@ -3822,7 +3821,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15a0580ab32b169745d7a39db2ba969226ca16738931be152a3209b409de2474" dependencies = [ "asynchronous-codec 0.7.0", - "bytes 1.7.1", + "bytes 1.7.2", "quick-protobuf", "thiserror", "unsigned-varint 0.8.0", @@ -3834,7 +3833,7 @@ version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-io", "pin-project-lite", "quinn-proto", @@ -3853,7 +3852,7 @@ version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "rand", "ring 0.17.8", "rustc-hash", @@ -4407,13 +4406,13 @@ dependencies = [ [[package]] name = "sha_p2pool" -version = "0.1.8" +version = "0.1.9" dependencies = [ "anyhow", "async-trait", - "axum 0.7.5", + "axum 0.7.6", "blake2", - "clap 4.5.17", + "clap 4.5.18", "convert_case", "digest", "dirs", @@ -4764,8 +4763,8 @@ dependencies = [ [[package]] name = "tari_common" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "anyhow", "config", @@ -4788,8 +4787,8 @@ dependencies = [ [[package]] name = "tari_common_sqlite" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "diesel", "diesel_migrations", @@ -4802,8 +4801,8 @@ dependencies = [ [[package]] name = "tari_common_types" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "base64 0.21.7", "bitflags 2.6.0", @@ -4828,14 +4827,14 @@ dependencies = [ [[package]] name = "tari_comms" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "anyhow", "async-trait", "bitflags 2.6.0", "blake2", - "bytes 1.7.1", + "bytes 1.7.2", "chrono", "cidr", "data-encoding", @@ -4864,7 +4863,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util 0.6.10", - "tower", + "tower 0.4.13", "tracing", "yamux 0.13.3", "zeroize", @@ -4872,8 +4871,8 @@ dependencies = [ [[package]] name = "tari_comms_dht" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "anyhow", "bitflags 2.6.0", @@ -4901,14 +4900,14 @@ dependencies = [ "tari_utilities", "thiserror", "tokio", - "tower", + "tower 0.4.13", "zeroize", ] [[package]] name = "tari_comms_rpc_macros" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "proc-macro2", "quote", @@ -4917,8 +4916,8 @@ dependencies = [ [[package]] name = "tari_core" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "async-trait", "bincode", @@ -5008,13 +5007,13 @@ dependencies = [ [[package]] name = "tari_features" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" [[package]] name = "tari_hashing" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "borsh", "digest", @@ -5023,8 +5022,8 @@ dependencies = [ [[package]] name = "tari_key_manager" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "argon2", "async-trait", @@ -5056,8 +5055,8 @@ dependencies = [ [[package]] name = "tari_max_size" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "borsh", "serde", @@ -5067,8 +5066,8 @@ dependencies = [ [[package]] name = "tari_mmr" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "borsh", "digest", @@ -5081,8 +5080,8 @@ dependencies = [ [[package]] name = "tari_p2p" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "anyhow", "fs2", @@ -5104,15 +5103,15 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "trust-dns-client", "webpki", ] [[package]] name = "tari_script" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "blake2", "borsh", @@ -5129,8 +5128,8 @@ dependencies = [ [[package]] name = "tari_service_framework" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "anyhow", "async-trait", @@ -5144,16 +5143,16 @@ dependencies = [ [[package]] name = "tari_shutdown" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "futures 0.3.30", ] [[package]] name = "tari_storage" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "bincode", "lmdb-zero", @@ -5164,8 +5163,8 @@ dependencies = [ [[package]] name = "tari_test_utils" -version = "1.4.2-pre.2" -source = "git+https://github.com/tari-project/tari.git#8728c4e468525e07efaf5ab03a06da2584e5727e" +version = "1.5.1-pre.0" +source = "git+https://github.com/tari-project/tari.git#fd41ba490470ff43fb3dc7e31fc6fc77266f264e" dependencies = [ "futures 0.3.30", "rand", @@ -5218,18 +5217,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", @@ -5328,7 +5327,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", - "bytes 1.7.1", + "bytes 1.7.2", "libc", "mio", "parking_lot", @@ -5399,7 +5398,7 @@ version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-core", "futures-io", "futures-sink", @@ -5414,7 +5413,7 @@ version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-core", "futures-sink", "pin-project-lite", @@ -5453,9 +5452,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "serde", @@ -5474,7 +5473,7 @@ dependencies = [ "async-trait", "axum 0.6.20", "base64 0.13.1", - "bytes 1.7.1", + "bytes 1.7.2", "futures-core", "futures-util", "h2", @@ -5491,7 +5490,7 @@ dependencies = [ "tokio-rustls 0.23.4", "tokio-stream", "tokio-util 0.7.12", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -5532,6 +5531,22 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -5692,9 +5707,9 @@ checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -5707,15 +5722,15 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" @@ -5749,7 +5764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" dependencies = [ "asynchronous-codec 0.6.2", - "bytes 1.7.1", + "bytes 1.7.2", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be3a6da..794e2c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sha_p2pool" -version = "0.1.8" +version = "0.1.9" edition = "2021" [dependencies] @@ -10,7 +10,6 @@ tari_common_types = { git = "https://github.com/tari-project/tari.git" } tari_common = { git = "https://github.com/tari-project/tari.git" } tari_core = { git = "https://github.com/tari-project/tari.git" } tari_shutdown = { git = "https://github.com/tari-project/tari.git" } - tari_crypto = "0.20.1" tari_utilities = { version = "0.7", features = ["borsh"] } diff --git a/src/cli/args.rs b/src/cli/args.rs index dd02197..9b252e1 100644 --- a/src/cli/args.rs +++ b/src/cli/args.rs @@ -8,7 +8,7 @@ use tari_shutdown::ShutdownSignal; use crate::cli::{ commands, - util::{cli_styles, validate_tribe}, + util::{cli_styles, validate_squad}, }; #[allow(clippy::struct_excessive_bools)] @@ -63,12 +63,12 @@ pub struct StartArgs { #[arg(long, value_name = "stable-peer", default_value_t = false)] pub stable_peer: bool, - /// Tribe to enter (a team of miners). - /// A tribe can have any name. + /// Squad to enter (a team of miners). + /// A squad can have any name. #[arg( - long, value_name = "tribe", default_value = "default", value_parser = validate_tribe + long, alias = "tribe", value_name = "squad", default_value = "default", value_parser = validate_squad )] - pub tribe: String, + pub squad: String, /// Private key folder. /// @@ -110,10 +110,10 @@ pub struct StartArgs { } #[derive(Clone, Parser, Debug)] -pub struct ListTribeArgs { - /// List tribe command timeout in seconds. +pub struct ListSquadArgs { + /// List squad command timeout in seconds. /// - /// The list-tribes commands tries to look for all the currently available tribes + /// The list-squads commands tries to look for all the currently available squads /// for this amount of time maximum. #[arg(long, value_name = "timeout", default_value_t = 15)] pub timeout: u64, @@ -130,13 +130,13 @@ pub enum Commands { /// Generating new identity. GenerateIdentity, - /// Listing all tribes that are present on the network. - ListTribes { + /// Listing all squads that are present on the network. + ListSquads { #[clap(flatten)] args: StartArgs, #[clap(flatten)] - list_tribe_args: ListTribeArgs, + list_squad_args: ListSquadArgs, }, } @@ -157,9 +157,9 @@ impl Cli { .clone() .unwrap_or_else(|| dirs::home_dir().unwrap().join(".tari/p2pool")), Commands::GenerateIdentity => dirs::home_dir().unwrap().join(".tari/p2pool"), - Commands::ListTribes { + Commands::ListSquads { args, - list_tribe_args: _list_tribe_args, + list_squad_args: _list_squad_args, } => args .base_dir .clone() @@ -180,8 +180,8 @@ impl Cli { Commands::GenerateIdentity => { commands::handle_generate_identity().await?; }, - Commands::ListTribes { args, list_tribe_args } => { - commands::handle_list_tribes(cli_ref.clone(), args, list_tribe_args, cli_shutdown.clone()).await?; + Commands::ListSquads { args, list_squad_args } => { + commands::handle_list_squads(cli_ref.clone(), args, list_squad_args, cli_shutdown.clone()).await?; }, } diff --git a/src/cli/commands/list_tribes.rs b/src/cli/commands/list_squads.rs similarity index 77% rename from src/cli/commands/list_tribes.rs rename to src/cli/commands/list_squads.rs index 6f05a0e..ffc3c43 100644 --- a/src/cli/commands/list_tribes.rs +++ b/src/cli/commands/list_squads.rs @@ -10,16 +10,16 @@ use tokio::{select, sync::oneshot, task::JoinHandle, time}; use crate::{ cli::{ - args::{Cli, ListTribeArgs, StartArgs}, + args::{Cli, ListSquadArgs, StartArgs}, commands::util, }, server::p2p::peer_store::PeerStore, }; -pub async fn handle_list_tribes( +pub async fn handle_list_squads( cli: Arc, args: &StartArgs, - list_tribe_args: &ListTribeArgs, + list_squad_args: &ListSquadArgs, cli_shutdown_signal: ShutdownSignal, ) -> anyhow::Result<()> { // start server asynchronously @@ -43,9 +43,9 @@ pub async fn handle_list_tribes( // wait for peer store from started server let peer_store = peer_store_channel_rx.await?; - // collect tribes for the given timeout - let mut tribes = vec![]; - let timeout = time::sleep(Duration::from_secs(list_tribe_args.timeout)); + // collect squads for the given timeout + let mut squads = vec![]; + let timeout = time::sleep(Duration::from_secs(list_squad_args.timeout)); tokio::pin!(timeout); tokio::pin!(cli_shutdown_signal); loop { @@ -56,9 +56,9 @@ pub async fn handle_list_tribes( () = &mut timeout => { break; } - current_tribes = peer_store.tribes() => { - tribes = current_tribes; - if tribes.len() > 1 { + current_squads = peer_store.squads() => { + squads = current_squads; + if squads.len() > 1 { break; } } @@ -67,8 +67,8 @@ pub async fn handle_list_tribes( shutdown.trigger(); handle.await??; - let tribes = tribes.iter().map(|tribe| tribe.to_string()).collect_vec(); - print!("{}", serde_json::to_value(tribes)?); + let squads = squads.iter().map(|squad| squad.to_string()).collect_vec(); + print!("{}", serde_json::to_value(squads)?); Ok(()) } diff --git a/src/cli/commands/mod.rs b/src/cli/commands/mod.rs index d7b1960..7da8e69 100644 --- a/src/cli/commands/mod.rs +++ b/src/cli/commands/mod.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: BSD-3-Clause pub use generate_identity::*; -pub use list_tribes::*; +pub use list_squads::*; pub use start::*; mod generate_identity; -mod list_tribes; +mod list_squads; mod start; mod util; diff --git a/src/cli/commands/util.rs b/src/cli/commands/util.rs index a0c7ef6..458e934 100644 --- a/src/cli/commands/util.rs +++ b/src/cli/commands/util.rs @@ -1,7 +1,7 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::{env, sync::Arc}; +use std::{collections::HashMap, env, sync::Arc}; use libp2p::identity::Keypair; use log::info; @@ -12,11 +12,12 @@ use tari_core::{ }; use tari_shutdown::ShutdownSignal; use tari_utilities::hex::Hex; +use tokio::sync::RwLock; use crate::{ cli::args::{Cli, StartArgs}, server as main_server, - server::{p2p::Tribe, Server}, + server::{p2p::Squad, Server}, sharechain::{in_memory::InMemoryShareChain, BlockValidationParams, MAX_BLOCKS_COUNT}, }; @@ -46,7 +47,7 @@ pub async fn server( config_builder.with_p2p_port(p2p_port); } - config_builder.with_tribe(Tribe::from(args.tribe.clone())); + config_builder.with_squad(Squad::from(args.squad.clone())); // set default tari network specific seed peer address let mut seed_peers = vec![]; @@ -99,14 +100,30 @@ genesis_block_hash.to_hex()); consensus_manager.clone(), genesis_block_hash, )); - let share_chain_sha3x = - InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager.clone())?; + let coinbase_extras_sha3x = Arc::new(RwLock::new(HashMap::>::new())); + let share_chain_sha3x = InMemoryShareChain::new( + MAX_BLOCKS_COUNT, + PowAlgorithm::Sha3x, + None, + consensus_manager.clone(), + coinbase_extras_sha3x.clone(), + )?; + let coinbase_extras_random_x = Arc::new(RwLock::new(HashMap::>::new())); let share_chain_random_x = InMemoryShareChain::new( MAX_BLOCKS_COUNT, PowAlgorithm::RandomX, Some(block_validation_params.clone()), consensus_manager, + coinbase_extras_random_x.clone(), )?; - Ok(Server::new(config, share_chain_sha3x, share_chain_random_x, shutdown_signal).await?) + Ok(Server::new( + config, + share_chain_sha3x, + share_chain_random_x, + coinbase_extras_sha3x.clone(), + coinbase_extras_random_x.clone(), + shutdown_signal, + ) + .await?) } diff --git a/src/cli/util.rs b/src/cli/util.rs index 3fc6b10..838384a 100644 --- a/src/cli/util.rs +++ b/src/cli/util.rs @@ -14,10 +14,10 @@ pub fn cli_styles() -> Styles { .valid(AnsiColor::BrightGreen.on_default()) } -pub fn validate_tribe(tribe: &str) -> Result { - if tribe.trim().is_empty() { - return Err(String::from("tribe must be set")); +pub fn validate_squad(squad: &str) -> Result { + if squad.trim().is_empty() { + return Err(String::from("squad must be set")); } - Ok(String::from(tribe)) + Ok(String::from(squad)) } diff --git a/src/server/config.rs b/src/server/config.rs index 0c02722..1451a8e 100644 --- a/src/server/config.rs +++ b/src/server/config.rs @@ -8,7 +8,7 @@ use libp2p::identity::Keypair; use crate::server::{ http, p2p, - p2p::{peer_store::PeerStoreConfig, Tribe}, + p2p::{peer_store::PeerStoreConfig, Squad}, }; /// Config is the server configuration struct. @@ -68,8 +68,8 @@ impl ConfigBuilder { self } - pub fn with_tribe(&mut self, tribe: Tribe) -> &mut Self { - self.config.p2p_service.tribe = tribe; + pub fn with_squad(&mut self, squad: Squad) -> &mut Self { + self.config.p2p_service.squad = squad; self } diff --git a/src/server/grpc/p2pool.rs b/src/server/grpc/p2pool.rs index 0b4b845..f778d54 100644 --- a/src/server/grpc/p2pool.rs +++ b/src/server/grpc/p2pool.rs @@ -1,7 +1,7 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::{collections::HashMap, sync::Arc, time::Instant}; +use std::{collections::HashMap, str::FromStr, sync::Arc, time::Instant}; use log::{debug, error, info, warn}; use minotari_app_grpc::tari_rpc::{ @@ -16,7 +16,7 @@ use minotari_app_grpc::tari_rpc::{ SubmitBlockResponse, }; use num_format::{Locale, ToFormattedString}; -use tari_common_types::types::FixedHash; +use tari_common_types::{tari_address::TariAddress, types::FixedHash}; use tari_core::{ consensus::ConsensusManager, proof_of_work::{randomx_difficulty, randomx_factory::RandomXFactory, sha3x_difficulty, Difficulty, PowAlgorithm}, @@ -37,6 +37,7 @@ use crate::{ P2POOL_STAT_REJECTED_BLOCKS_COUNT, }, p2p, + p2p::Squad, stats_store::StatsStore, }, sharechain::{block::Block, BlockValidationParams, ShareChain, SHARE_COUNT}, @@ -77,6 +78,9 @@ where S: ShareChain stats_max_difficulty_since_last_success: Arc>, consensus_manager: ConsensusManager, submit_block_semaphore: Arc, + squad: Squad, + coinbase_extras_sha3x: Arc>>>, + coinbase_extras_random_x: Arc>>>, } impl ShaP2PoolGrpc @@ -92,6 +96,9 @@ where S: ShareChain random_x_factory: RandomXFactory, consensus_manager: ConsensusManager, genesis_block_hash: FixedHash, + squad: Squad, + coinbase_extras_sha3x: Arc>>>, + coinbase_extras_random_x: Arc>>>, ) -> Result { Ok(Self { client: Arc::new(RwLock::new( @@ -111,6 +118,9 @@ where S: ShareChain stats_max_difficulty_since_last_success: Arc::new(RwLock::new(Difficulty::min())), consensus_manager, submit_block_semaphore: Arc::new(Semaphore::new(1)), + squad, + coinbase_extras_sha3x, + coinbase_extras_random_x, }) } @@ -153,16 +163,16 @@ where S: ShareChain { /// Returns a new block (that can be mined) which contains all the shares generated /// from the current share chain as coinbase transactions. + #[allow(clippy::too_many_lines)] async fn get_new_block( &self, request: Request, ) -> Result, Status> { let timer = Instant::now(); + let grpc_req = request.into_inner(); + // extract pow algo - let grpc_block_header_pow = request - .into_inner() - .pow - .ok_or(Status::invalid_argument("missing pow in request"))?; + let grpc_block_header_pow = grpc_req.pow.ok_or(Status::invalid_argument("missing pow in request"))?; let grpc_pow_algo = PowAlgos::from_i32(grpc_block_header_pow.pow_algo) .ok_or_else(|| Status::internal("invalid block header pow algo in request"))?; let pow_algo = match grpc_pow_algo { @@ -187,12 +197,26 @@ where S: ShareChain .ok_or_else(|| Status::internal("missing miner data"))?; // let reward = miner_data.reward; + // update coinbase extras cache + let wallet_payment_address = TariAddress::from_str(grpc_req.wallet_payment_address.as_str()) + .map_err(|error| Status::failed_precondition(format!("Invalid wallet payment address: {}", error)))?; + let mut coinbase_extras_lock = match pow_algo { + PowAlgorithm::RandomX => self.coinbase_extras_random_x.write().await, + PowAlgorithm::Sha3x => self.coinbase_extras_sha3x.write().await, + }; + coinbase_extras_lock.insert( + wallet_payment_address.to_base58(), + util::convert_coinbase_extra(self.squad.clone(), grpc_req.coinbase_extra) + .map_err(|error| Status::internal(format!("failed to convert coinbase extra {error:?}")))?, + ); + drop(coinbase_extras_lock); + // request new block template with shares as coinbases let share_chain = match pow_algo { PowAlgorithm::RandomX => self.share_chain_random_x.clone(), PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), }; - let shares = share_chain.generate_shares().await; + let shares = share_chain.generate_shares(self.squad.clone()).await; let mut response = self .client @@ -257,6 +281,7 @@ where S: ShareChain if timer.elapsed() > MAX_ACCEPTABLE_GRPC_TIMEOUT { warn!(target: LOG_TARGET, "get_new_block took {}ms", timer.elapsed().as_millis()); } + Ok(Response::new(GetNewBlockResponse { block: Some(response), target_difficulty: target_difficulty.as_u64(), @@ -307,7 +332,7 @@ where S: ShareChain PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), }; let mut block = share_chain - .new_block(grpc_block) + .new_block(grpc_block, self.squad.clone()) .await .map_err(|error| Status::internal(error.to_string()))?; diff --git a/src/server/grpc/util.rs b/src/server/grpc/util.rs index f69d8f4..f786fc7 100644 --- a/src/server/grpc/util.rs +++ b/src/server/grpc/util.rs @@ -1,7 +1,7 @@ // Copyright 2024 The Tari Project // SPDX-License-Identifier: BSD-3-Clause -use std::time::Duration; +use std::{num::TryFromIntError, time::Duration}; use log::error; use minotari_app_grpc::tari_rpc::base_node_client::BaseNodeClient; @@ -10,7 +10,10 @@ use tari_shutdown::ShutdownSignal; use tokio::select; use tonic::transport::Channel; -use crate::server::grpc::error::{Error, TonicError}; +use crate::server::{ + grpc::error::{Error, TonicError}, + p2p::Squad, +}; /// Utility function to connect to a Base node and try infinitely when it fails until gets connected. pub async fn connect_base_node( @@ -49,3 +52,21 @@ pub async fn connect_base_node( Ok(client) } + +pub fn convert_coinbase_extra(squad: Squad, custom_coinbase_extra: String) -> Result, TryFromIntError> { + let type_length_value_marker = 0xFFu8; + let squad_type_marker = 0x02u8; + let custom_message_type_marker = 0x01u8; + + let mut current_squad = squad.as_string().into_bytes(); + let current_squad_len = u8::try_from(current_squad.len())?; + let mut result = vec![type_length_value_marker, squad_type_marker, current_squad_len]; + result.append(&mut current_squad); + + let mut custom_coinbase_extra_bytes = custom_coinbase_extra.into_bytes(); + let custom_coinbase_extra_len = u8::try_from(custom_coinbase_extra_bytes.len())?; + result.append(&mut vec![custom_message_type_marker, custom_coinbase_extra_len]); + result.append(&mut custom_coinbase_extra_bytes); + + Ok(result) +} diff --git a/src/server/http/server.rs b/src/server/http/server.rs index ca04aa8..5b43b84 100644 --- a/src/server/http/server.rs +++ b/src/server/http/server.rs @@ -16,7 +16,7 @@ use crate::{ stats::{cache::StatsCache, handlers}, version, }, - p2p::{peer_store::PeerStore, Tribe}, + p2p::{peer_store::PeerStore, Squad}, stats_store::StatsStore, }, sharechain::ShareChain, @@ -53,7 +53,7 @@ where S: ShareChain peer_store: Arc, stats_store: Arc, port: u16, - tribe: Tribe, + squad: Squad, stats_cache: Arc, shutdown_signal: ShutdownSignal, } @@ -64,7 +64,7 @@ pub struct AppState { pub share_chain_random_x: Arc, pub peer_store: Arc, pub stats_store: Arc, - pub tribe: Tribe, + pub squad: Squad, pub stats_cache: Arc, } @@ -77,7 +77,7 @@ where S: ShareChain peer_store: Arc, stats_store: Arc, port: u16, - tribe: Tribe, + squad: Squad, stats_cache: Arc, shutdown_signal: ShutdownSignal, ) -> Self { @@ -87,7 +87,7 @@ where S: ShareChain peer_store, stats_store, port, - tribe, + squad, stats_cache, shutdown_signal, } @@ -106,7 +106,7 @@ where S: ShareChain share_chain_random_x: self.share_chain_random_x.clone(), peer_store: self.peer_store.clone(), stats_store: self.stats_store.clone(), - tribe: self.tribe.clone(), + squad: self.squad.clone(), stats_cache: self.stats_cache.clone(), }) } diff --git a/src/server/http/stats/handlers.rs b/src/server/http/stats/handlers.rs index a58ee92..50eb63e 100644 --- a/src/server/http/stats/handlers.rs +++ b/src/server/http/stats/handlers.rs @@ -15,7 +15,7 @@ use crate::server::{ server::AppState, stats::{ algo_stat_key, - models::{BlockStats, EstimatedEarnings, Stats, TribeDetails}, + models::{BlockStats, EstimatedEarnings, SquadDetails, Stats}, MINER_STAT_ACCEPTED_BLOCKS_COUNT, MINER_STAT_REJECTED_BLOCKS_COUNT, P2POOL_STAT_ACCEPTED_BLOCKS_COUNT, @@ -81,17 +81,25 @@ pub(crate) async fn handle_miners_with_shares( let mut result = HashMap::with_capacity(2); result.insert( PowAlgorithm::Sha3x.to_string().to_lowercase(), - state.share_chain_sha3x.miners_with_shares().await.map_err(|error| { - error!(target: LOG_TARGET, "Failed to get Sha3x miners with shares: {error:?}"); - StatusCode::INTERNAL_SERVER_ERROR - })?, + state + .share_chain_sha3x + .miners_with_shares(state.squad.clone()) + .await + .map_err(|error| { + error!(target: LOG_TARGET, "Failed to get Sha3x miners with shares: {error:?}"); + StatusCode::INTERNAL_SERVER_ERROR + })?, ); result.insert( PowAlgorithm::RandomX.to_string().to_lowercase(), - state.share_chain_random_x.miners_with_shares().await.map_err(|error| { - error!(target: LOG_TARGET, "Failed to get RandomX miners with shares: {error:?}"); - StatusCode::INTERNAL_SERVER_ERROR - })?, + state + .share_chain_random_x + .miners_with_shares(state.squad.clone()) + .await + .map_err(|error| { + error!(target: LOG_TARGET, "Failed to get RandomX miners with shares: {error:?}"); + StatusCode::INTERNAL_SERVER_ERROR + })?, ); if timer.elapsed() > MAX_ACCEPTABLE_HTTP_TIMEOUT { @@ -140,10 +148,13 @@ async fn get_stats(state: AppState, algo: PowAlgorithm) -> Result 0; - let shares = share_chain.miners_with_shares().await.map_err(|error| { - error!(target: LOG_TARGET, "Failed to get miners with shares: {error:?}"); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let shares = share_chain + .miners_with_shares(state.squad.clone()) + .await + .map_err(|error| { + error!(target: LOG_TARGET, "Failed to get miners with shares: {error:?}"); + StatusCode::INTERNAL_SERVER_ERROR + })?; // collect number of miners // let num_of_miners = chain // .iter() @@ -256,7 +267,7 @@ async fn get_stats(state: AppState, algo: PowAlgorithm) -> Result Self { Self { id, name } } @@ -86,7 +86,7 @@ impl TribeDetails { pub struct Stats { pub connected: bool, pub connected_since: Option, - pub tribe: TribeDetails, + pub squad: SquadDetails, pub num_of_miners: usize, pub last_block_won: Option, pub share_chain_height: u64, diff --git a/src/server/p2p/messages.rs b/src/server/p2p/messages.rs index e755bda..ed94324 100644 --- a/src/server/p2p/messages.rs +++ b/src/server/p2p/messages.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use tari_core::proof_of_work::PowAlgorithm; use crate::{ - server::p2p::{Error, Tribe}, + server::p2p::{Error, Squad}, sharechain::block::Block, }; @@ -48,20 +48,20 @@ pub struct PeerInfo { pub version: u64, pub current_sha3x_height: u64, pub current_random_x_height: u64, - pub tribe: Tribe, + pub squad: Squad, pub timestamp: u128, pub user_agent: Option, pub user_agent_version: Option, } impl_conversions!(PeerInfo); impl PeerInfo { - pub fn new(current_sha3x_height: u64, current_random_x_height: u64, tribe: Tribe) -> Self { + pub fn new(current_sha3x_height: u64, current_random_x_height: u64, squad: Squad) -> Self { let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_micros(); Self { version: 1, current_sha3x_height, current_random_x_height, - tribe, + squad, timestamp, user_agent: Some("tari-p2pool".to_string()), user_agent_version: Some(env!("CARGO_PKG_VERSION").to_string()), diff --git a/src/server/p2p/network.rs b/src/server/p2p/network.rs index 5e732dd..e3b8d56 100644 --- a/src/server/p2p/network.rs +++ b/src/server/p2p/network.rs @@ -103,23 +103,27 @@ pub const STABLE_PRIVATE_KEY_FILE: &str = "p2pool_private.key"; const MAX_ACCEPTABLE_P2P_MESSAGE_TIMEOUT: Duration = Duration::from_millis(500); #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct Tribe { +pub struct Squad { inner: String, } -impl Tribe { +impl Squad { pub fn formatted(&self) -> String { self.inner.to_case(Case::Lower).replace("_", " ").to_case(Case::Title) } + + pub fn as_string(&self) -> String { + self.inner.to_case(Case::Lower) + } } -impl ToValue for Tribe { +impl ToValue for Squad { fn to_value(&self) -> Value { Value::from(self.inner.as_str()) } } -impl From for Tribe { +impl From for Squad { fn from(value: String) -> Self { Self { inner: value.to_case(Case::Lower).to_case(Case::Snake), @@ -127,7 +131,7 @@ impl From for Tribe { } } -impl Display for Tribe { +impl Display for Squad { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.inner.clone()) } @@ -143,7 +147,7 @@ pub struct Config { pub private_key: Option, pub mdns_enabled: bool, pub relay_server_enabled: bool, - pub tribe: Tribe, + pub squad: Squad, } impl Default for Config { @@ -157,7 +161,7 @@ impl Default for Config { private_key: None, mdns_enabled: false, relay_server_enabled: false, - tribe: Tribe::from("default".to_string()), + squad: Squad::from("default".to_string()), } } } @@ -184,7 +188,7 @@ where S: ShareChain port: u16, share_chain_sha3x: Arc, share_chain_random_x: Arc, - tribe_peer_store: Arc, + squad_peer_store: Arc, network_peer_store: Arc, config: Config, sync_in_progress: Arc, @@ -209,7 +213,7 @@ where S: ShareChain config: &config::Config, share_chain_sha3x: Arc, share_chain_random_x: Arc, - tribe_peer_store: Arc, + squad_peer_store: Arc, network_peer_store: Arc, sync_in_progress: Arc, shutdown_signal: ShutdownSignal, @@ -225,7 +229,7 @@ where S: ShareChain port: config.p2p_port, share_chain_sha3x, share_chain_random_x, - tribe_peer_store, + squad_peer_store, network_peer_store, config: config.p2p_service.clone(), shutdown_signal, @@ -377,9 +381,9 @@ where S: ShareChain let current_height_sha3x = share_chain_sha3x.tip_height().await.map_err(Error::ShareChain)?; let current_height_random_x = share_chain_random_x.tip_height().await.map_err(Error::ShareChain)?; let peer_info_network_raw: Vec = - PeerInfo::new(current_height_sha3x, current_height_random_x, self.config.tribe.clone()).try_into()?; - let peer_info_tribe_raw: Vec = - PeerInfo::new(current_height_sha3x, current_height_random_x, self.config.tribe.clone()).try_into()?; + PeerInfo::new(current_height_sha3x, current_height_random_x, self.config.squad.clone()).try_into()?; + let peer_info_squad_raw: Vec = + PeerInfo::new(current_height_sha3x, current_height_random_x, self.config.squad.clone()).try_into()?; // broadcast peer info to network self.swarm @@ -391,13 +395,13 @@ where S: ShareChain ) .map_err(|error| Error::LibP2P(LibP2PError::Publish(error)))?; - // broadcast peer info to tribe + // broadcast peer info to squad self.swarm .behaviour_mut() .gossipsub .publish( - IdentTopic::new(Self::tribe_topic(&self.config.tribe, PEER_INFO_TOPIC)), - peer_info_tribe_raw, + IdentTopic::new(Self::squad_topic(&self.config.squad, PEER_INFO_TOPIC)), + peer_info_squad_raw, ) .map_err(|error| Error::LibP2P(LibP2PError::Publish(error)))?; @@ -420,7 +424,7 @@ where S: ShareChain .behaviour_mut() .gossipsub .publish( - IdentTopic::new(Self::tribe_topic(&self.config.tribe, NEW_BLOCK_TOPIC)), + IdentTopic::new(Self::squad_topic(&self.config.squad, NEW_BLOCK_TOPIC)), block_raw, ) // .map_err(|error| Error::LibP2P(LibP2PError::Publish(error))) @@ -428,20 +432,20 @@ where S: ShareChain Ok(_) => {}, Err(error) => { if matches!(error, PublishError::InsufficientPeers) { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "No peers to broadcast new block"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "No peers to broadcast new block"); } else { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to broadcast new block: {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to broadcast new block: {error:?}"); } }, } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to convert block to bytes: {error:?}") + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to convert block to bytes: {error:?}") }, } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to receive new block: {error:?}") + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to receive new block: {error:?}") }, } } @@ -455,17 +459,17 @@ where S: ShareChain } /// Generates a gossip sub topic name based on the current Tari network to avoid mixing up - /// blocks and peers with different Tari networks and the given tribe name. - fn tribe_topic(tribe: &Tribe, topic: &str) -> String { + /// blocks and peers with different Tari networks and the given squad name. + fn squad_topic(squad: &Squad, topic: &str) -> String { let network = Network::get_current_or_user_setting_or_default().as_key_str(); let chain_id = CURRENT_CHAIN_ID.clone(); - format!("{network}_{chain_id}_{tribe}_{topic}") + format!("{network}_{chain_id}_{squad}_{topic}") } /// Subscribing to a gossipsub topic. - fn subscribe(&mut self, topic: &str, tribe: bool) { - let topic = if tribe { - Self::tribe_topic(&self.config.tribe, topic) + fn subscribe(&mut self, topic: &str, squad: bool) { + let topic = if squad { + Self::squad_topic(&self.config.squad, topic) } else { Self::network_topic(topic) }; @@ -498,19 +502,19 @@ where S: ShareChain match topic { topic if topic == Self::network_topic(PEER_INFO_TOPIC) => match messages::PeerInfo::try_from(message) { Ok(payload) => { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "[NETWORK] New peer info: {peer:?} -> {payload:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "[NETWORK] New peer info: {peer:?} -> {payload:?}"); }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Can't deserialize peer info payload: {:?}", error); + error!(target: LOG_TARGET, squad = &self.config.squad; "Can't deserialize peer info payload: {:?}", error); }, }, - topic if topic == Self::tribe_topic(&self.config.tribe, PEER_INFO_TOPIC) => { + topic if topic == Self::squad_topic(&self.config.squad, PEER_INFO_TOPIC) => { match messages::PeerInfo::try_from(message) { Ok(payload) => { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "[TRIBE] New peer info: {peer:?} -> {payload:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "[squad] New peer info: {peer:?} -> {payload:?}"); let current_randomx_height = payload.current_random_x_height; let current_sha3x_height = payload.current_sha3x_height; - self.tribe_peer_store.add(peer, payload).await; + self.squad_peer_store.add(peer, payload).await; if self.sync_in_progress.load(Ordering::SeqCst) { return; @@ -539,21 +543,21 @@ where S: ShareChain } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Can't deserialize peer info payload: {:?}", error); + error!(target: LOG_TARGET, squad = &self.config.squad; "Can't deserialize peer info payload: {:?}", error); }, } }, // TODO: send a signature that proves that the actual block was coming from this peer // TODO: (sender peer's wallet address should be included always in the conibases with a fixed percent (like // 20%)) - topic if topic == Self::tribe_topic(&self.config.tribe, NEW_BLOCK_TOPIC) => { + topic if topic == Self::squad_topic(&self.config.squad, NEW_BLOCK_TOPIC) => { if self.sync_in_progress.load(Ordering::SeqCst) { return; } match Block::try_from(message) { Ok(payload) => { - info!(target: LOG_TARGET, tribe = &self.config.tribe; "🆕 New block from broadcast: {:?}", &payload.hash.to_hex()); + info!(target: LOG_TARGET, squad = &self.config.squad; "🆕 New block from broadcast: {:?}", &payload.hash.to_hex()); let share_chain = match payload.original_block_header.pow.pow_algo { PowAlgorithm::RandomX => self.share_chain_random_x.clone(), PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), @@ -561,20 +565,20 @@ where S: ShareChain // TODO: Treating this as a sync for now. match share_chain.add_synced_blocks(vec![payload.clone()]).await { Ok(_result) => { - info!(target: LOG_TARGET, tribe = &self.config.tribe; "New block added to local share chain via gossip: {}. Height: {}", &payload.hash.to_hex(), &payload.height); + info!(target: LOG_TARGET, squad = &self.config.squad; "New block added to local share chain via gossip: {}. Height: {}", &payload.hash.to_hex(), &payload.height); }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Could not add new block to local share chain: {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Could not add new block to local share chain: {error:?}"); }, } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Can't deserialize broadcast block payload: {:?}", error); + error!(target: LOG_TARGET, squad = &self.config.squad; "Can't deserialize broadcast block payload: {:?}", error); }, } }, _ => { - warn!(target: LOG_TARGET, tribe = &self.config.tribe; "Unknown topic {topic:?}!"); + warn!(target: LOG_TARGET, squad = &self.config.squad; "Unknown topic {topic:?}!"); }, } } @@ -585,7 +589,7 @@ where S: ShareChain channel: ResponseChannel, request: ShareChainSyncRequest, ) { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Incoming Share chain sync request: {request:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Incoming Share chain sync request: {request:?}"); let share_chain = match request.algo { PowAlgorithm::RandomX => self.share_chain_random_x.clone(), PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), @@ -599,11 +603,11 @@ where S: ShareChain .send_response(channel, ShareChainSyncResponse::new(request.algo, blocks.clone())) .is_err() { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to send block sync response"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to send block sync response"); } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to get blocks from height: {error:?}") + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to get blocks from height: {error:?}") }, } } @@ -615,23 +619,23 @@ where S: ShareChain if !self.sync_in_progress.load(Ordering::SeqCst) { return; } - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Share chain sync response: {response:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Share chain sync response: {response:?}"); let share_chain = match response.algo { PowAlgorithm::RandomX => self.share_chain_random_x.clone(), PowAlgorithm::Sha3x => self.share_chain_sha3x.clone(), }; match share_chain.add_synced_blocks(response.blocks).await { Ok(result) => { - info!(target: LOG_TARGET, tribe = &self.config.tribe; "Synced blocks added to share chain: {result:?}"); + info!(target: LOG_TARGET, squad = &self.config.squad; "Synced blocks added to share chain: {result:?}"); // Ok(()) }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to add synced blocks to share chain: {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to add synced blocks to share chain: {error:?}"); }, }; self.sync_in_progress.store(false, Ordering::SeqCst); if timer.elapsed() > MAX_ACCEPTABLE_P2P_MESSAGE_TIMEOUT { - warn!(target: LOG_TARGET, tribe = &self.config.tribe; "Share chain sync response took too long: {:?}", timer.elapsed()); + warn!(target: LOG_TARGET, squad = &self.config.squad; "Share chain sync response took too long: {:?}", timer.elapsed()); } } @@ -644,10 +648,10 @@ where S: ShareChain } self.sync_in_progress.store(true, Ordering::SeqCst); - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Syncing share chain..."); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Syncing share chain..."); if let Some(peer_id) = peer { - info!(target: LOG_TARGET, tribe = &self.config.tribe; "Send share chain sync request to specific peer: {peer_id:?}"); + info!(target: LOG_TARGET, squad = &self.config.squad; "Send share chain sync request to specific peer: {peer_id:?}"); self.swarm .behaviour_mut() .share_chain_sync @@ -655,10 +659,10 @@ where S: ShareChain return; } - match self.tribe_peer_store.tip_of_block_height(algo).await { + match self.squad_peer_store.tip_of_block_height(algo).await { Some(result) => { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Found highest known block height: {result:?}"); - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Send share chain sync request: {result:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Found highest known block height: {result:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Send share chain sync request: {result:?}"); // we always send from_height as zero now, to not miss any blocks info!(target: LOG_TARGET, "[{:?}] Syncing share chain...", algo); self.swarm @@ -668,7 +672,7 @@ where S: ShareChain }, None => { self.sync_in_progress.store(false, Ordering::SeqCst); - error!(target: LOG_TARGET, tribe = &self.config.tribe; "[{:?}] Failed to get peer with highest share chain height!", algo) + error!(target: LOG_TARGET, squad = &self.config.squad; "[{:?}] Failed to get peer with highest share chain height!", algo) }, } } @@ -683,10 +687,10 @@ where S: ShareChain share_chain_random_x: Arc, share_chain_sync_tx: broadcast::Sender, timeout: Duration, - tribe: Tribe, + squad: Squad, shutdown_signal: ShutdownSignal, ) { - info!(target: LOG_TARGET, tribe = &tribe; "Initially syncing share chain (timeout: {timeout:?})..."); + info!(target: LOG_TARGET, squad = &squad; "Initially syncing share chain (timeout: {timeout:?})..."); in_progress.store(true, Ordering::SeqCst); let sleep = time::sleep(timeout); tokio::pin!(sleep); @@ -697,7 +701,7 @@ where S: ShareChain break; } _ = &mut shutdown_signal => { - info!(target: LOG_TARGET, tribe = &tribe; "Stopped initial syncing..."); + info!(target: LOG_TARGET, squad = &squad; "Stopped initial syncing..."); return; } else => { @@ -733,7 +737,7 @@ where S: ShareChain for (algo, share_chain) in to_sync { match peer_store.tip_of_block_height(algo).await { Some(result) => { - debug!(target: LOG_TARGET, tribe = &tribe; "Found highest block height: {result:?}"); + debug!(target: LOG_TARGET, squad = &squad; "Found highest block height: {result:?}"); match share_chain.tip_height().await { Ok(tip) => { if tip < result.height { @@ -741,7 +745,7 @@ where S: ShareChain result.peer_id, ShareChainSyncRequest::new(algo, 0), )) { - error!(target: LOG_TARGET, tribe = &tribe; "Failed to send share chain sync request: {error:?}"); + error!(target: LOG_TARGET, squad = &squad; "Failed to send share chain sync request: {error:?}"); } } else { in_progress.store(false, Ordering::SeqCst); @@ -749,13 +753,13 @@ where S: ShareChain }, Err(error) => { in_progress.store(false, Ordering::SeqCst); - error!(target: LOG_TARGET, tribe = &tribe; "Failed to get latest height of share chain: {error:?}") + error!(target: LOG_TARGET, squad = &squad; "Failed to get latest height of share chain: {error:?}") }, } }, None => { in_progress.store(false, Ordering::SeqCst); - error!(target: LOG_TARGET, tribe = &tribe; "Failed to get peer with highest share chain height!") + error!(target: LOG_TARGET, squad = &squad; "Failed to get peer with highest share chain height!") }, } } @@ -766,7 +770,7 @@ where S: ShareChain async fn handle_event(&mut self, event: SwarmEvent) { match event { SwarmEvent::NewListenAddr { address, .. } => { - debug!(target: LOG_TARGET, tribe = &self.config.tribe; "Listening on {address:?}"); + debug!(target: LOG_TARGET, squad = &self.config.squad; "Listening on {address:?}"); }, SwarmEvent::Behaviour(event) => match event { ServerNetworkBehaviourEvent::Mdns(mdns_event) => match mdns_event { @@ -814,16 +818,16 @@ where S: ShareChain if self.sync_in_progress.load(Ordering::SeqCst) { self.sync_in_progress.store(false, Ordering::SeqCst); } - error!(target: LOG_TARGET, tribe = &self.config.tribe; "REQ-RES outbound failure: {peer:?} -> {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "REQ-RES outbound failure: {peer:?} -> {error:?}"); // Remove peer from peer store to try to sync from another peer, // if the peer goes online/accessible again, the peer store will have it again. - self.tribe_peer_store.remove(&peer).await; + self.squad_peer_store.remove(&peer).await; }, request_response::Event::InboundFailure { peer, error, .. } => { if self.sync_in_progress.load(Ordering::SeqCst) { self.sync_in_progress.store(false, Ordering::SeqCst); } - error!(target: LOG_TARGET, tribe = &self.config.tribe; "REQ-RES inbound failure: {peer:?} -> {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "REQ-RES inbound failure: {peer:?} -> {error:?}"); }, request_response::Event::ResponseSent { .. } => {}, }, @@ -842,7 +846,7 @@ where S: ShareChain self.swarm.behaviour_mut().gossipsub.remove_explicit_peer(&old_peer); } }, - _ => debug!(target: LOG_TARGET, tribe = &self.config.tribe; "[KADEMLIA] {event:?}"), + _ => debug!(target: LOG_TARGET, squad = &self.config.squad; "[KADEMLIA] {event:?}"), }, ServerNetworkBehaviourEvent::Identify(event) => match event { identify::Event::Received { peer_id, info } => self.handle_peer_identified(peer_id, info).await, @@ -974,22 +978,22 @@ where S: ShareChain } _ = publish_peer_info_interval.tick() => { // handle case when we have some peers removed - let expired_peers = self.tribe_peer_store.cleanup().await; + let expired_peers = self.squad_peer_store.cleanup().await; for exp_peer in expired_peers { self.swarm.behaviour_mut().kademlia.remove_peer(&exp_peer); self.swarm.behaviour_mut().gossipsub.remove_explicit_peer(&exp_peer); } // broadcast peer info - info!(target: LOG_TARGET, tribe = &self.config.tribe; "Peer count: {:?}", self.tribe_peer_store.peer_count().await); + info!(target: LOG_TARGET, squad = &self.config.squad; "Peer count: {:?}", self.squad_peer_store.peer_count().await); if let Err(error) = self.broadcast_peer_info().await { match error { Error::LibP2P(LibP2PError::Publish(PublishError::InsufficientPeers)) => { - warn!(target: LOG_TARGET, tribe = &self.config.tribe; "No peers to broadcast peer info!"); + warn!(target: LOG_TARGET, squad = &self.config.squad; "No peers to broadcast peer info!"); } Error::LibP2P(LibP2PError::Publish(PublishError::Duplicate)) => {} _ => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to publish node info: {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to publish node info: {error:?}"); } } } @@ -1007,7 +1011,7 @@ where S: ShareChain }, _ = kademlia_bootstrap_interval.tick() => { if let Err(error) = self.bootstrap_kademlia() { - warn!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to do kademlia bootstrap: {error:?}"); + warn!(target: LOG_TARGET, squad = &self.config.squad; "Failed to do kademlia bootstrap: {error:?}"); } } } @@ -1061,14 +1065,14 @@ where S: ShareChain } }, Err(error) => { - warn!(target: LOG_TARGET, tribe = &self.config.tribe; "Skipping invalid DNS entry: {:?}: {error:?}", chars); + warn!(target: LOG_TARGET, squad = &self.config.squad; "Skipping invalid DNS entry: {:?}: {error:?}", chars); }, } } } }, Err(error) => { - error!(target: LOG_TARGET, tribe = &self.config.tribe; "Failed to lookup domain records: {error:?}"); + error!(target: LOG_TARGET, squad = &self.config.squad; "Failed to lookup domain records: {error:?}"); }, } } @@ -1142,11 +1146,11 @@ where S: ShareChain // start initial share chain sync let in_progress = self.sync_in_progress.clone(); - let peer_store = self.tribe_peer_store.clone(); + let peer_store = self.squad_peer_store.clone(); let share_chain_sha3x = self.share_chain_sha3x.clone(); let share_chain_random_x = self.share_chain_random_x.clone(); let share_chain_sync_tx = self.share_chain_sync_tx.clone(); - let tribe = self.config.tribe.clone(); + let squad = self.config.squad.clone(); let shutdown_signal = self.shutdown_signal.clone(); tokio::spawn(async move { Self::initial_share_chain_sync( @@ -1156,7 +1160,7 @@ where S: ShareChain share_chain_random_x, share_chain_sync_tx, Duration::from_secs(30), - tribe, + squad, shutdown_signal, ) .await; diff --git a/src/server/p2p/peer_store.rs b/src/server/p2p/peer_store.rs index b3fca78..00ee05d 100644 --- a/src/server/p2p/peer_store.rs +++ b/src/server/p2p/peer_store.rs @@ -13,7 +13,7 @@ use moka::future::{Cache, CacheBuilder}; use tari_core::proof_of_work::PowAlgorithm; use tari_utilities::epoch_time::EpochTime; -use crate::server::p2p::{messages::PeerInfo, Tribe}; +use crate::server::p2p::{messages::PeerInfo, Squad}; const LOG_TARGET: &str = "tari::p2pool::server::p2p::peer_store"; const PEER_BAN_TIME: Duration = Duration::from_secs(60 * 5); @@ -143,11 +143,11 @@ impl PeerStore { self.set_last_connected().await; } - /// Collects all current tribes from all PeerInfo collected from broadcasts. - pub async fn tribes(&self) -> Vec { + /// Collects all current squads from all PeerInfo collected from broadcasts. + pub async fn squads(&self) -> Vec { self.peers .iter() - .map(|(_, record)| record.peer_info.tribe) + .map(|(_, record)| record.peer_info.squad) .unique() .collect_vec() } diff --git a/src/server/server.rs b/src/server/server.rs index 6e0d55e..88dd807 100644 --- a/src/server/server.rs +++ b/src/server/server.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: BSD-3-Clause use std::{ + collections::HashMap, net::{AddrParseError, SocketAddr}, str::FromStr, sync::{atomic::AtomicBool, Arc}, @@ -13,6 +14,7 @@ use tari_common::configuration::Network; use tari_core::{consensus::ConsensusManager, proof_of_work::randomx_factory::RandomXFactory}; use tari_shutdown::ShutdownSignal; use thiserror::Error; +use tokio::sync::RwLock; use crate::{ server::{ @@ -60,12 +62,14 @@ where S: ShareChain config: config::Config, share_chain_sha3x: S, share_chain_random_x: S, + coinbase_extras_sha3x: Arc>>>, + coinbase_extras_random_x: Arc>>>, shutdown_signal: ShutdownSignal, ) -> Result { let share_chain_sha3x = Arc::new(share_chain_sha3x); let share_chain_random_x = Arc::new(share_chain_random_x); let sync_in_progress = Arc::new(AtomicBool::new(true)); - let tribe_peer_store = Arc::new(PeerStore::new(&config.peer_store)); + let squad_peer_store = Arc::new(PeerStore::new(&config.peer_store)); let network_peer_store = Arc::new(PeerStore::new(&config.peer_store)); let stats_store = Arc::new(StatsStore::new()); @@ -73,7 +77,7 @@ where S: ShareChain &config, share_chain_sha3x.clone(), share_chain_random_x.clone(), - tribe_peer_store.clone(), + squad_peer_store.clone(), network_peer_store.clone(), sync_in_progress.clone(), shutdown_signal.clone(), @@ -103,6 +107,9 @@ where S: ShareChain randomx_factory, consensus_manager, genesis_block_hash, + config.p2p_service.squad.clone(), + coinbase_extras_sha3x.clone(), + coinbase_extras_random_x.clone(), ) .await .map_err(Error::Grpc)?; @@ -115,10 +122,10 @@ where S: ShareChain Some(Arc::new(HttpServer::new( share_chain_sha3x.clone(), share_chain_random_x.clone(), - tribe_peer_store.clone(), + squad_peer_store.clone(), stats_store.clone(), config.http_server.port, - config.p2p_service.tribe.clone(), + config.p2p_service.squad.clone(), http_stats_cache.clone(), shutdown_signal.clone(), ))) diff --git a/src/sharechain/block.rs b/src/sharechain/block.rs index 7bb113e..8cd4f76 100644 --- a/src/sharechain/block.rs +++ b/src/sharechain/block.rs @@ -36,6 +36,7 @@ pub(crate) struct Block { pub miner_wallet_address: Option, pub sent_to_main_chain: bool, pub achieved_difficulty: Difficulty, + pub miner_coinbase_extra: Vec, } impl_conversions!(Block); @@ -76,6 +77,7 @@ impl BlockBuilder { miner_wallet_address: Default::default(), sent_to_main_chain: false, achieved_difficulty: Difficulty::min(), + miner_coinbase_extra: vec![], }, } } @@ -100,6 +102,11 @@ impl BlockBuilder { self } + pub fn with_miner_coinbase_extra(&mut self, coinbase_extra: Vec) -> &mut Self { + self.block.miner_coinbase_extra = coinbase_extra; + self + } + pub fn with_miner_wallet_address(&mut self, miner_wallet_address: TariAddress) -> &mut Self { self.block.miner_wallet_address = Some(miner_wallet_address); self diff --git a/src/sharechain/in_memory.rs b/src/sharechain/in_memory.rs index aeafacd..908a645 100644 --- a/src/sharechain/in_memory.rs +++ b/src/sharechain/in_memory.rs @@ -23,7 +23,10 @@ use tokio::sync::{RwLock, RwLockWriteGuard}; use super::MAX_BLOCKS_COUNT; use crate::{ - server::grpc::p2pool::min_difficulty, + server::{ + grpc::{p2pool::min_difficulty, util::convert_coinbase_extra}, + p2p::Squad, + }, sharechain::{ error::{BlockConvertError, Error}, Block, @@ -63,6 +66,7 @@ pub(crate) struct InMemoryShareChain { pow_algo: PowAlgorithm, block_validation_params: Option>, consensus_manager: ConsensusManager, + coinbase_extras: Arc>>>, } /// A collection of blocks with the same height. @@ -117,6 +121,7 @@ impl InMemoryShareChain { pow_algo: PowAlgorithm, block_validation_params: Option>, consensus_manager: ConsensusManager, + coinbase_extras: Arc>>>, ) -> Result { if pow_algo == PowAlgorithm::RandomX && block_validation_params.is_none() { return Err(Error::MissingBlockValidationParams); @@ -133,6 +138,7 @@ impl InMemoryShareChain { pow_algo, block_validation_params, consensus_manager, + coinbase_extras, }) } @@ -451,8 +457,23 @@ impl InMemoryShareChain { .add_block(block.clone(), true)?; } + // update coinbase extra cache + let mut coinbase_extras_lock = self.coinbase_extras.write().await; + if let Some(miner_wallet_address) = &block.miner_wallet_address { + coinbase_extras_lock.insert(miner_wallet_address.to_base58(), block.miner_coinbase_extra.clone()); + } + Ok(()) } + + async fn find_coinbase_extra(&self, miner_wallet_address: TariAddress) -> Option> { + let coinbase_extras_lock = self.coinbase_extras.read().await; + if let Some(found_coinbase_extras) = coinbase_extras_lock.get(&miner_wallet_address.to_base58()) { + return Some(found_coinbase_extras.clone()); + } + + None + } } #[async_trait] @@ -493,7 +514,7 @@ impl ShareChain for InMemoryShareChain { Ok(tip_level) } - async fn generate_shares(&self) -> Vec { + async fn generate_shares(&self, squad: Squad) -> Vec { let bl = self.block_levels.read().await; if let Some(ref cached_shares) = bl.cached_shares { return cached_shares.clone(); @@ -563,12 +584,20 @@ impl ShareChain for InMemoryShareChain { } for (key, value) in miners_to_shares { + // find coinbase extra for wallet address + let mut coinbase_extra = convert_coinbase_extra(squad.clone(), String::new()).unwrap_or_default(); + if let Ok(miner_wallet_address) = TariAddress::from_str(key.as_str()) { + if let Some(coinbase_extra_found) = self.find_coinbase_extra(miner_wallet_address).await { + coinbase_extra = coinbase_extra_found; + } + } + res.push(NewBlockCoinbase { address: key, value, stealth_payment: false, revealed_value_proof: true, - coinbase_extra: vec![], + coinbase_extra, }); } @@ -577,7 +606,7 @@ impl ShareChain for InMemoryShareChain { res } - async fn new_block(&self, request: &SubmitBlockRequest) -> ShareChainResult { + async fn new_block(&self, request: &SubmitBlockRequest, squad: Squad) -> ShareChainResult { let origin_block_grpc = request .block .as_ref() @@ -595,14 +624,24 @@ impl ShareChain for InMemoryShareChain { .block_in_main_chain() .ok_or_else(|| Error::Empty)?; + let miner_wallet_address = + TariAddress::from_str(request.wallet_payment_address.as_str()).map_err(Error::TariAddress)?; + + // coinbase extra + let coinbase_extra = + if let Some(found_coinbase_extra) = self.find_coinbase_extra(miner_wallet_address.clone()).await { + found_coinbase_extra.clone() + } else { + convert_coinbase_extra(squad, String::new())? + }; + Ok(Block::builder() .with_timestamp(EpochTime::now()) .with_prev_hash(last_block.hash) .with_height(last_block.height + 1) + .with_miner_coinbase_extra(coinbase_extra) .with_original_block_header(origin_block.header.clone()) - .with_miner_wallet_address( - TariAddress::from_str(request.wallet_payment_address.as_str()).map_err(Error::TariAddress)?, - ) + .with_miner_wallet_address(miner_wallet_address) .build()) } @@ -682,14 +721,14 @@ impl ShareChain for InMemoryShareChain { // Ok(hash_rates_sum.div(hash_rates_count)) } - async fn miners_with_shares(&self) -> ShareChainResult> { + async fn miners_with_shares(&self, squad: Squad) -> ShareChainResult> { let bl = self.block_levels.read().await; if let Some(ref shares) = bl.cached_shares { return Ok(shares.iter().map(|s| (s.address.clone(), s.value)).collect()); } drop(bl); - let shares = self.generate_shares().await; + let shares = self.generate_shares(squad).await; Ok(shares.iter().map(|s| (s.address.clone(), s.value)).collect()) } } @@ -742,8 +781,15 @@ mod test { let consensus_manager = ConsensusManager::builder(Network::get_current_or_user_setting_or_default()) .build() .unwrap(); - let share_chain = - InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager).unwrap(); + let coinbase_extras = Arc::new(RwLock::new(HashMap::>::new())); + let share_chain = InMemoryShareChain::new( + MAX_BLOCKS_COUNT, + PowAlgorithm::Sha3x, + None, + consensus_manager, + coinbase_extras, + ) + .unwrap(); let shares = share_chain.miners_with_shares(blocks); // assert @@ -772,8 +818,15 @@ mod test { let consensus_manager = ConsensusManager::builder(Network::get_current_or_user_setting_or_default()) .build() .unwrap(); - let share_chain = - InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager).unwrap(); + let coinbase_extras = Arc::new(RwLock::new(HashMap::>::new())); + let share_chain = InMemoryShareChain::new( + MAX_BLOCKS_COUNT, + PowAlgorithm::Sha3x, + None, + consensus_manager, + coinbase_extras, + ) + .unwrap(); let shares = share_chain.miners_with_shares(blocks); // assert @@ -802,8 +855,15 @@ mod test { let consensus_manager = ConsensusManager::builder(Network::get_current_or_user_setting_or_default()) .build() .unwrap(); - let share_chain = - InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager).unwrap(); + let coinbase_extras = Arc::new(RwLock::new(HashMap::>::new())); + let share_chain = InMemoryShareChain::new( + MAX_BLOCKS_COUNT, + PowAlgorithm::Sha3x, + None, + consensus_manager, + coinbase_extras, + ) + .unwrap(); let shares = share_chain.miners_with_shares(blocks); // assert @@ -834,8 +894,15 @@ mod test { let consensus_manager = ConsensusManager::builder(Network::get_current_or_user_setting_or_default()) .build() .unwrap(); - let share_chain = - InMemoryShareChain::new(MAX_BLOCKS_COUNT, PowAlgorithm::Sha3x, None, consensus_manager).unwrap(); + let coinbase_extras = Arc::new(RwLock::new(HashMap::>::new())); + let share_chain = InMemoryShareChain::new( + MAX_BLOCKS_COUNT, + PowAlgorithm::Sha3x, + None, + consensus_manager, + coinbase_extras, + ) + .unwrap(); let shares = share_chain.miners_with_shares(blocks); // assert diff --git a/src/sharechain/mod.rs b/src/sharechain/mod.rs index 239aa33..8e0607c 100644 --- a/src/sharechain/mod.rs +++ b/src/sharechain/mod.rs @@ -9,11 +9,14 @@ use num::BigUint; use tari_common_types::types::FixedHash; use tari_core::{consensus::ConsensusManager, proof_of_work::randomx_factory::RandomXFactory}; -use crate::sharechain::{block::Block, error::Error}; +use crate::{ + server::p2p::Squad, + sharechain::{block::Block, error::Error}, +}; /// Chain ID is an identifier which makes sure we apply the same rules to blocks. /// Note: This must be updated when new logic applied to blocks handling. -pub const CHAIN_ID: usize = 1; +pub const CHAIN_ID: usize = 2; /// How many blocks to keep overall. pub const MAX_BLOCKS_COUNT: usize = 2001; @@ -83,10 +86,10 @@ pub(crate) trait ShareChain: Send + Sync + 'static { async fn tip_height(&self) -> ShareChainResult; /// Generate shares based on the previous blocks. - async fn generate_shares(&self) -> Vec; + async fn generate_shares(&self, squad: Squad) -> Vec; /// Return a new block that could be added via `submit_block`. - async fn new_block(&self, request: &SubmitBlockRequest) -> ShareChainResult; + async fn new_block(&self, request: &SubmitBlockRequest, squad: Squad) -> ShareChainResult; /// Returns blocks from the given height (`from_height`, exclusive). async fn blocks(&self, from_height: u64) -> ShareChainResult>; @@ -97,5 +100,5 @@ pub(crate) trait ShareChain: Send + Sync + 'static { async fn hash_rate(&self) -> ShareChainResult; /// Returns the current miners with all the current shares in the current blocks window. - async fn miners_with_shares(&self) -> ShareChainResult>; + async fn miners_with_shares(&self, squad: Squad) -> ShareChainResult>; }