From 5c5da461690684e90ecc12565d674fbca06b5f53 Mon Sep 17 00:00:00 2001 From: Hansie Odendaal <39146854+hansieodendaal@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:48:10 +0200 Subject: [PATCH 1/4] fix: fixed make-it-rain delay (#6165) Description --- Fixed make-it-rain delay Motivation and Context --- The delay did not work properly How Has This Been Tested? --- System-level testing (`make-it-rain --stealth --duration 7200 --transactions-per-second 1 --start-amount 0.039000T --increase-amount 0T --start-time now --message Brian_01_(stealth) d035876f990517ff2629d7acbba9c86a760412f12c029119e545ec2f1bda1f1ec1`) What process can a PR reviewer use to test or verify this change? --- Code walk-through System-level testing Breaking Changes --- - [x] None - [ ] Requires data directory on base node to be deleted - [ ] Requires hard fork - [ ] Other - Please specify --- .../src/automation/commands.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/applications/minotari_console_wallet/src/automation/commands.rs b/applications/minotari_console_wallet/src/automation/commands.rs index 8208168bad..e09e019ef1 100644 --- a/applications/minotari_console_wallet/src/automation/commands.rs +++ b/applications/minotari_console_wallet/src/automation/commands.rs @@ -409,10 +409,19 @@ pub async fn make_it_rain( // Manage transaction submission rate let actual_ms = (Utc::now() - started_at).num_milliseconds(); - let target_ms = (i as f64 / f64::from(transactions_per_second) / 1000.0) as i64; + let target_ms = (i as f64 * (1000.0 / f64::from(transactions_per_second))) as i64; + trace!( + target: LOG_TARGET, + "make-it-rain {}: target {:?} ms vs. actual {:?} ms", i, target_ms, actual_ms + ); if target_ms - actual_ms > 0 { // Maximum delay between Txs set to 120 s - sleep(Duration::from_millis((target_ms - actual_ms).min(120_000i64) as u64)).await; + let delay_ms = Duration::from_millis((target_ms - actual_ms).min(120_000i64) as u64); + trace!( + target: LOG_TARGET, + "make-it-rain {}: delaying for {:?} ms", i, delay_ms + ); + sleep(delay_ms).await; } let delayed_for = Instant::now(); let sender_clone = sender.clone(); From 8990b575cd4df01c1a3e5e9385e13a9ce3b9ddd4 Mon Sep 17 00:00:00 2001 From: Cayle Sharrock Date: Mon, 26 Feb 2024 08:49:18 +0000 Subject: [PATCH 2/4] feat: multi-network ci (#6162) When formally implementing compiler features, the setting of the `TARI_NETWORK` and (from now) `TARI_TARGET_NETWORK` envar and the related compiler flags matter. These changes require that when tests run, the correct network flags are set. For example, `blocks::genesis_block::test::stagenet_genesis_sanity_check` should only run when `TARI_NETWORK=stagenet`. The current setup reveals a problem: There is not a 1:1 mapping between the build _target_ and the actual network the binary may run on. E.g. the mainnet build can run on either stagenet or mainnet. Unfortunately the `TARI_NETWORK` envar was used to set both of these variables. Since these are 2 different things, this commit introduced `TARI_TARGET_NETWORK` which sets the **build target**. In most contexts, this then decouples the configured network, which is specified by the `TARI_NETWORK` envar as usual. The other changes in this commit revolve around updating merkle roots and the correct faucet sets to make the target/network/faucet combination consistent. The CI is configured to run tests for each of `{target} ({network})` * Testnet (Esme) * Nextnet (Nextnet) * Mainnet (Stagenet) Description --- This replaces part of #6131 Breaking Changes --- - [x] None - [ ] Requires data directory on base node to be deleted - [ ] Requires hard fork - [ ] Other - Please specify --- .config/nextest.toml | 12 ++ .github/workflows/base_node_binaries.yml | 2 + .github/workflows/build_dockers_workflow.yml | 3 + .github/workflows/build_libffis.yml | 2 + .github/workflows/ci.yml | 18 ++- Cargo.lock | 3 + applications/minotari_app_grpc/Cargo.toml | 1 + applications/minotari_app_grpc/build.rs | 3 + .../minotari_app_utilities/Cargo.toml | 4 +- .../src/network_check.rs | 6 +- .../minotari_console_wallet/Cargo.toml | 2 +- .../minotari_merge_mining_proxy/Cargo.toml | 2 +- applications/minotari_node/Cargo.toml | 2 +- base_layer/core/Cargo.toml | 1 + base_layer/core/build.rs | 3 + base_layer/core/src/blocks/genesis_block.rs | 36 +++--- .../core/src/proof_of_work/sha3x_pow.rs | 1 + .../core/src/transactions/coinbase_builder.rs | 2 +- .../transaction_components/test.rs | 34 ++++++ base_layer/tari_mining_helper_ffi/Cargo.toml | 4 +- base_layer/tari_mining_helper_ffi/build.rs | 27 +++++ base_layer/tari_mining_helper_ffi/src/lib.rs | 16 ++- buildtools/multinet_envs.sh | 4 + common/src/configuration/network.rs | 16 ++- common/tari_features/Cargo.toml | 2 +- common/tari_features/README.md | 108 +++++++++++++++++- common/tari_features/src/resolver.rs | 24 ++-- 27 files changed, 287 insertions(+), 51 deletions(-) create mode 100644 base_layer/tari_mining_helper_ffi/build.rs diff --git a/.config/nextest.toml b/.config/nextest.toml index b305587ac3..01af9351fd 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -3,3 +3,15 @@ slow-timeout = { period = "60s", terminate-after=2} [profile.ci.junit] # this can be some other profile, too path = "junit.xml" + +[profile.intellij] +retries = 0 +slow-timeout = { period = "30s" } +failure-output = "immediate-final" +fail-fast = false + +[profile.intellij.junit] # this can be some other profile, too +path = "junit.xml" + + + diff --git a/.github/workflows/base_node_binaries.yml b/.github/workflows/base_node_binaries.yml index cbc87b55f3..7e766cdef0 100644 --- a/.github/workflows/base_node_binaries.yml +++ b/.github/workflows/base_node_binaries.yml @@ -109,8 +109,10 @@ jobs: run: | source buildtools/multinet_envs.sh ${{ env.GHA_NETWORK }} echo ${TARI_NETWORK} + echo ${TARI_TARGET_NETWORK} echo ${TARI_NETWORK_DIR} echo "TARI_NETWORK=${TARI_NETWORK}" >> $GITHUB_ENV + echo "TARI_TARGET_NETWORK=${TARI_TARGET_NETWORK}" >> $GITHUB_ENV echo "TARI_NETWORK_DIR=${TARI_NETWORK_DIR}" >> $GITHUB_ENV echo "TARI_NETWORK_DIR=${TARI_NETWORK_DIR}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build_dockers_workflow.yml b/.github/workflows/build_dockers_workflow.yml index f656b24b66..e0e07ea4cf 100644 --- a/.github/workflows/build_dockers_workflow.yml +++ b/.github/workflows/build_dockers_workflow.yml @@ -119,6 +119,8 @@ jobs: source tari/buildtools/multinet_envs.sh ${{github.ref_name}} echo ${TARI_NETWORK} echo "TARI_NETWORK=${TARI_NETWORK}" >> $GITHUB_ENV + echo ${TARI_TARGET_NETWORK} + echo "TARI_TARGET_NETWORK=${TARI_TARGET_NETWORK}" >> $GITHUB_ENV - name: environment setup shell: bash @@ -225,6 +227,7 @@ jobs: APP_NAME=${{ matrix.builds.app_name }} APP_EXEC=${{ matrix.builds.app_exec }} TARI_NETWORK=${{ env.TARI_NETWORK }} + TARI_TARGET_NETWORK=${{ env.TARI_TARGET_NETWORK }} ${{ env.DOCKER_SUBTAG }} tags: | ${{ steps.meta.outputs.tags }} diff --git a/.github/workflows/build_libffis.yml b/.github/workflows/build_libffis.yml index e2bdef9cb8..ecd208c3eb 100644 --- a/.github/workflows/build_libffis.yml +++ b/.github/workflows/build_libffis.yml @@ -102,8 +102,10 @@ jobs: run: | source buildtools/multinet_envs.sh ${{ github.ref_name }} echo ${TARI_NETWORK} + echo ${TARI_TARGET_NETWORK} echo ${TARI_NETWORK_CHANGELOG} echo "TARI_NETWORK=${TARI_NETWORK}" >> $GITHUB_ENV + echo "TARI_TARGET_NETWORK=${TARI_TARGET_NETWORK}" >> $GITHUB_ENV echo "TARI_NETWORK_CHANGELOG=${TARI_NETWORK_CHANGELOG}" >> $GITHUB_ENV - name: Declare Android/iOS envs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8e8e38785..de1e78db33 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -167,6 +167,17 @@ jobs: permissions: checks: write pull-requests: write + strategy: + matrix: + tari_target_network: [ + { target: "testnet", network: "esmeralda" }, + { target: "nextnet", network: "nextnet" }, + { target: "mainnet", network: "stagenet" }, + ] + env: + TARI_TARGET_NETWORK: ${{ matrix.tari_target_network.target }} + TARI_NETWORK: ${{ matrix.tari_target_network.network }} + RUST_LOG: debug steps: - name: checkout uses: actions/checkout@v4 @@ -192,21 +203,22 @@ jobs: ~/.cargo/registry/CACHEDIR.TAG ~/.cargo/git target - key: tari-${{ runner.os }}-${{ runner.cpu-model }}-${{ env.toolchain }}-nightly-${{ hashFiles('**/Cargo.lock') }} + key: tari-${{ runner.os }}-${{ runner.cpu-model }}-${{ env.toolchain }}-nightly-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.tari_target_network.target }} restore-keys: | + tari-${{ runner.os }}-${{ runner.cpu-model }}-${{ env.toolchain }}-nightly-${{ hashFiles('**/Cargo.lock') }}-${{ matrix.tari_target_network.network }} tari-${{ runner.os }}-${{ runner.cpu-model }}-${{ env.toolchain }}-nightly-${{ hashFiles('**/Cargo.lock') }} tari-${{ runner.os }}-${{ runner.cpu-model }}-${{ env.toolchain }}-nightly - name: Install cargo-nextest run: cargo install cargo-nextest --locked --force - name: cargo test compile - run: cargo test --no-run --locked --all-features --release + run: cargo test -vv --no-run --locked --all-features --release - name: cargo test run: cargo nextest run --all-features --release -E "not package(tari_integration_tests)" --profile ci - name: upload artifact uses: actions/upload-artifact@v4 # upload test results as artifact if: always() with: - name: test-results + name: test-results-${{ matrix.tari_target_network.target }}.${{ matrix.tari_target_network.network }} path: ${{ github.workspace }}/target/nextest/ci/junit.xml # Allows other workflows to know the PR number diff --git a/Cargo.lock b/Cargo.lock index d04c7b04f5..b3292185bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3046,6 +3046,7 @@ dependencies = [ "tari_comms", "tari_core", "tari_crypto", + "tari_features", "tari_script", "tari_utilities", "thiserror", @@ -3243,6 +3244,7 @@ dependencies = [ "tari_comms", "tari_core", "tari_crypto", + "tari_features", "tari_utilities", "thiserror", ] @@ -5841,6 +5843,7 @@ dependencies = [ "tari_comms_dht", "tari_comms_rpc_macros", "tari_crypto", + "tari_features", "tari_hash_domains", "tari_key_manager", "tari_metrics", diff --git a/applications/minotari_app_grpc/Cargo.toml b/applications/minotari_app_grpc/Cargo.toml index d23cefceb5..7ddbd9e720 100644 --- a/applications/minotari_app_grpc/Cargo.toml +++ b/applications/minotari_app_grpc/Cargo.toml @@ -31,6 +31,7 @@ tonic = { version = "0.8.3", features = ["tls"]} zeroize = "1" [build-dependencies] +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } tonic-build = "0.8.4" [package.metadata.cargo-machete] diff --git a/applications/minotari_app_grpc/build.rs b/applications/minotari_app_grpc/build.rs index c059857769..f8084fb744 100644 --- a/applications/minotari_app_grpc/build.rs +++ b/applications/minotari_app_grpc/build.rs @@ -1,7 +1,10 @@ // Copyright 2022 The Tari Project // SPDX-License-Identifier: BSD-3-Clause +use tari_features::resolver::build_features; + fn main() -> Result<(), Box> { + build_features(); tonic_build::configure().build_client(true).build_server(true).compile( &[ "proto/base_node.proto", diff --git a/applications/minotari_app_utilities/Cargo.toml b/applications/minotari_app_utilities/Cargo.toml index b13da63ac9..682e361849 100644 --- a/applications/minotari_app_utilities/Cargo.toml +++ b/applications/minotari_app_utilities/Cargo.toml @@ -9,7 +9,7 @@ license = "BSD-3-Clause" tari_common = { path = "../../common" } tari_common_types = { path = "../../base_layer/common_types" } tari_comms = { path = "../../comms/core" } -tari_features = { path = "../../common/tari_features" } +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } tari_utilities = { version = "0.7" } minotari_app_grpc = { path = "../minotari_app_grpc", optional = true } @@ -27,7 +27,7 @@ tonic = "0.8.3" [build-dependencies] tari_common = { path = "../../common", features = ["build", "static-application-info"] } -tari_features = { path = "../../common/tari_features" } +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } [features] miner_input = ["minotari_app_grpc"] diff --git a/applications/minotari_app_utilities/src/network_check.rs b/applications/minotari_app_utilities/src/network_check.rs index ab742bb7cd..02e798cb0d 100644 --- a/applications/minotari_app_utilities/src/network_check.rs +++ b/applications/minotari_app_utilities/src/network_check.rs @@ -48,13 +48,13 @@ impl From for ExitError { } } -#[cfg(tari_network_mainnet)] +#[cfg(tari_target_network_mainnet)] pub const TARGET_NETWORK: Target = Target::MainNet; -#[cfg(tari_network_nextnet)] +#[cfg(tari_target_network_nextnet)] pub const TARGET_NETWORK: Target = Target::NextNet; -#[cfg(all(not(tari_network_mainnet), not(tari_network_nextnet)))] +#[cfg(all(not(tari_target_network_mainnet), not(tari_target_network_nextnet)))] pub const TARGET_NETWORK: Target = Target::TestNet; pub fn is_network_choice_valid(network: Network) -> Result { diff --git a/applications/minotari_console_wallet/Cargo.toml b/applications/minotari_console_wallet/Cargo.toml index 7e212f5fea..db8babd489 100644 --- a/applications/minotari_console_wallet/Cargo.toml +++ b/applications/minotari_console_wallet/Cargo.toml @@ -82,7 +82,7 @@ default-features = false features = ["crossterm"] [build-dependencies] -tari_features = { path = "../../common/tari_features" } +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } [features] default = ["libtor"] diff --git a/applications/minotari_merge_mining_proxy/Cargo.toml b/applications/minotari_merge_mining_proxy/Cargo.toml index d36666bb48..0bf57d7419 100644 --- a/applications/minotari_merge_mining_proxy/Cargo.toml +++ b/applications/minotari_merge_mining_proxy/Cargo.toml @@ -46,4 +46,4 @@ tracing = "0.1" url = "2.1.1" [build-dependencies] -tari_features = { path = "../../common/tari_features"} +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9"} diff --git a/applications/minotari_node/Cargo.toml b/applications/minotari_node/Cargo.toml index 7ef8bda9d7..f4ba09f257 100644 --- a/applications/minotari_node/Cargo.toml +++ b/applications/minotari_node/Cargo.toml @@ -58,7 +58,7 @@ safe = [] libtor = ["tari_libtor"] [build-dependencies] -tari_features = { path = "../../common/tari_features"} +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9"} [package.metadata.cargo-machete] ignored = [ diff --git a/base_layer/core/Cargo.toml b/base_layer/core/Cargo.toml index 9659fbf0ea..04ecddb278 100644 --- a/base_layer/core/Cargo.toml +++ b/base_layer/core/Cargo.toml @@ -105,6 +105,7 @@ quickcheck = "1.0" [build-dependencies] tari_common = { path = "../../common", features = ["build"], version = "1.0.0-pre.9" } +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } [[bench]] name = "mempool" diff --git a/base_layer/core/build.rs b/base_layer/core/build.rs index ca7f1901fc..02802ec35d 100644 --- a/base_layer/core/build.rs +++ b/base_layer/core/build.rs @@ -20,7 +20,10 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +use tari_features::resolver::build_features; + fn main() { + build_features(); tari_common::build::ProtobufCompiler::new() .include_paths(&["src/proto"]) .proto_paths(&[ diff --git a/base_layer/core/src/blocks/genesis_block.rs b/base_layer/core/src/blocks/genesis_block.rs index af798f9ec3..47821ea1d5 100644 --- a/base_layer/core/src/blocks/genesis_block.rs +++ b/base_layer/core/src/blocks/genesis_block.rs @@ -111,7 +111,7 @@ pub fn get_stagenet_genesis_block() -> ChainBlock { if add_faucet_utxos { // NB! Update 'consensus_constants.rs/pub fn igor()/ConsensusConstants {faucet_value: ?}' with total value // NB: `stagenet_genesis_sanity_check` must pass - let file_contents = include_str!("faucets/esmeralda_faucet.json"); + let file_contents = include_str!("faucets/stagenet_faucet.json"); add_faucet_utxos_to_genesis_block(file_contents, &mut block); // Enable print only if you need to generate new Merkle roots, then disable it again let print_values = false; @@ -119,9 +119,9 @@ pub fn get_stagenet_genesis_block() -> ChainBlock { // Hardcode the Merkle roots once they've been computed above block.header.kernel_mr = - FixedHash::from_hex("3f4011ec1e8ddfbd66fb7331c5623b38f529a66e81233d924df85f2070b2aacb").unwrap(); + FixedHash::from_hex("a08ff15219beea81d4131465290443fb3bd99d28b8af85975dbb2c77cb4cb5a0").unwrap(); block.header.output_mr = - FixedHash::from_hex("3e40efda288a57d3319c63388dd47ffe4b682baaf6a3b58622ec94d77ad712a2").unwrap(); + FixedHash::from_hex("435f13e21be06b0d0ae9ad3869ac7c723edd933983fa2e26df843c82594b3245").unwrap(); block.header.validator_node_mr = FixedHash::from_hex("277da65c40b2cf99db86baedb903a3f0a38540f3a94d40c826eecac7e27d5dfc").unwrap(); } @@ -163,7 +163,7 @@ pub fn get_nextnet_genesis_block() -> ChainBlock { if add_faucet_utxos { // NB! Update 'consensus_constants.rs/pub fn igor()/ConsensusConstants {faucet_value: ?}' with total value // NB: `nextnet_genesis_sanity_check` must pass - let file_contents = include_str!("faucets/esmeralda_faucet.json"); + let file_contents = include_str!("faucets/nextnet_faucet.json"); add_faucet_utxos_to_genesis_block(file_contents, &mut block); // Enable print only if you need to generate new Merkle roots, then disable it again let print_values = false; @@ -171,9 +171,9 @@ pub fn get_nextnet_genesis_block() -> ChainBlock { // Hardcode the Merkle roots once they've been computed above block.header.kernel_mr = - FixedHash::from_hex("3f4011ec1e8ddfbd66fb7331c5623b38f529a66e81233d924df85f2070b2aacb").unwrap(); + FixedHash::from_hex("36881d87e25183f5189d2dca5f7da450c399e7006dafd9bd9240f73a5fb3f0ad").unwrap(); block.header.output_mr = - FixedHash::from_hex("3e40efda288a57d3319c63388dd47ffe4b682baaf6a3b58622ec94d77ad712a2").unwrap(); + FixedHash::from_hex("7b65d5140485b44e33eef3690d46c41e4dc5c4520ad7464d7740f376f4f0a728").unwrap(); block.header.validator_node_mr = FixedHash::from_hex("277da65c40b2cf99db86baedb903a3f0a38540f3a94d40c826eecac7e27d5dfc").unwrap(); } @@ -368,6 +368,7 @@ mod test { use tari_common_types::{epoch::VnEpoch, types::Commitment}; use tari_utilities::ByteArray; + use Network; use super::*; use crate::{ @@ -383,14 +384,16 @@ mod test { }; #[test] - fn stagenet_genesis_sanity_check() { - // Note: Generate new data for `pub fn get_stagenet_genesis_block()` and `fn get_stagenet_genesis_block_raw()` + #[cfg(tari_target_network_testnet)] + fn esme_genesis_sanity_check() { + // Note: Generate new data for `pub fn get_esmeralda_genesis_block()` and `fn get_esmeralda_genesis_block_raw()` // if consensus values change, e.g. new faucet or other - let block = get_stagenet_genesis_block(); - check_block(Network::StageNet, &block, 100, 1); + let block = get_esmeralda_genesis_block(); + check_block(Network::Esmeralda, &block, 100, 1); } #[test] + #[cfg(tari_target_network_nextnet)] fn nextnet_genesis_sanity_check() { // Note: Generate new data for `pub fn get_nextnet_genesis_block()` and `fn get_stagenet_genesis_block_raw()` // if consensus values change, e.g. new faucet or other @@ -399,17 +402,18 @@ mod test { } #[test] - fn esmeralda_genesis_sanity_check() { - // Note: Generate new data for `pub fn get_esmeralda_genesis_block()` and `fn get_esmeralda_genesis_block_raw()` + #[cfg(tari_target_network_mainnet)] + fn stagenet_genesis_sanity_check() { + Network::set_current(Network::StageNet).unwrap(); + // Note: Generate new data for `pub fn get_stagenet_genesis_block()` and `fn get_stagenet_genesis_block_raw()` // if consensus values change, e.g. new faucet or other - let block = get_esmeralda_genesis_block(); - check_block(Network::Esmeralda, &block, 100, 1); + let block = get_stagenet_genesis_block(); + check_block(Network::StageNet, &block, 100, 1); } #[test] fn igor_genesis_sanity_check() { - // Note: Generate new data for `pub fn get_igor_genesis_block()` and `fn get_igor_genesis_block_raw()` - // if consensus values change, e.g. new faucet or other + // Note: If outputs and kernels are added, this test will fail unless you explicitly check that network == Igor let block = get_igor_genesis_block(); check_block(Network::Igor, &block, 0, 0); } diff --git a/base_layer/core/src/proof_of_work/sha3x_pow.rs b/base_layer/core/src/proof_of_work/sha3x_pow.rs index 783e642c41..c1953826b2 100644 --- a/base_layer/core/src/proof_of_work/sha3x_pow.rs +++ b/base_layer/core/src/proof_of_work/sha3x_pow.rs @@ -96,6 +96,7 @@ pub mod test { } #[test] + #[cfg(tari_target_network_testnet)] fn validate_max_target() { let mut header = get_header(); header.nonce = 631; diff --git a/base_layer/core/src/transactions/coinbase_builder.rs b/base_layer/core/src/transactions/coinbase_builder.rs index c8ae1811ab..cb2f27087f 100644 --- a/base_layer/core/src/transactions/coinbase_builder.rs +++ b/base_layer/core/src/transactions/coinbase_builder.rs @@ -662,7 +662,7 @@ mod test { let block_reward = rules.emission_schedule().block_reward(42) + missing_fee; let builder = CoinbaseBuilder::new(key_manager.clone()); let builder = builder - .with_block_height(4200000) + .with_block_height(4_200_000) .with_fees(1 * uT) .with_spend_key_id(p.spend_key_id.clone()) .with_encryption_key_id(TariKeyId::default()) diff --git a/base_layer/core/src/transactions/transaction_components/test.rs b/base_layer/core/src/transactions/transaction_components/test.rs index d68ca986a7..66328e9dc0 100644 --- a/base_layer/core/src/transactions/transaction_components/test.rs +++ b/base_layer/core/src/transactions/transaction_components/test.rs @@ -280,6 +280,11 @@ async fn sender_signature_verification() { #[test] fn kernel_hash() { + #[cfg(tari_target_network_mainnet)] + if let Network::MainNet = Network::get_current_or_default() { + eprintln!("This test is configured for stagenet only"); + return; + } let s = PrivateKey::from_hex("6c6eebc5a9c02e1f3c16a69ba4331f9f63d0718401dea10adc4f9d3b879a2c09").unwrap(); let r = PublicKey::from_hex("28e8efe4e5576aac931d358d0f6ace43c55fa9d4186d1d259d1436caa876d43b").unwrap(); let sig = Signature::new(r, s); @@ -291,6 +296,17 @@ fn kernel_hash() { .with_lock_height(500) .build() .unwrap(); + #[cfg(tari_target_network_nextnet)] + assert_eq!( + &k.hash().to_hex(), + "c1f6174935d08358809fcf244a9a1edb078b74a1ae18ab4c7dd501b0294a2a94" + ); + #[cfg(tari_target_network_mainnet)] + assert_eq!( + &k.hash().to_hex(), + "b94992cb59695ebad3786e9f51a220e91c627f8b38f51bcf6c87297325d1b410" + ); + #[cfg(tari_target_network_testnet)] assert_eq!( &k.hash().to_hex(), "38b03d013f941e86c027969fbbc190ca2a28fa2d7ac075d50dbfb6232deee646" @@ -310,6 +326,24 @@ fn kernel_metadata() { .with_lock_height(500) .build() .unwrap(); + #[cfg(tari_target_network_mainnet)] + match Network::get_current_or_default() { + Network::MainNet => { + eprintln!("This test is configured for stagenet only"); + }, + Network::StageNet => assert_eq!( + &k.hash().to_hex(), + "75a357c2769098b19a6aedc7e46f6be305f4f1a1831556cd380b0b0f20bfdf12" + ), + n => panic!("Only mainnet networks should target mainnet. Network was {}", n), + } + + #[cfg(tari_target_network_nextnet)] + assert_eq!( + &k.hash().to_hex(), + "22e39392dfeae9653c73437880be71e99f4b8a2b23289d54f57b8931deebfeed" + ); + #[cfg(tari_target_network_testnet)] assert_eq!( &k.hash().to_hex(), "ebc852fbac798c25ce497b416f69ec11a97e186aacaa10e2bb4ca5f5a0f197f2" diff --git a/base_layer/tari_mining_helper_ffi/Cargo.toml b/base_layer/tari_mining_helper_ffi/Cargo.toml index a9d3d34e5b..48557bd807 100644 --- a/base_layer/tari_mining_helper_ffi/Cargo.toml +++ b/base_layer/tari_mining_helper_ffi/Cargo.toml @@ -19,8 +19,10 @@ hex = "0.4.2" [dev-dependencies] tari_core = { path = "../core", features = ["transactions", "base_node"]} - rand = "0.8" +[build-dependencies] +tari_features = { path = "../../common/tari_features", version = "1.0.0-pre.9" } + [lib] crate-type = ["staticlib","cdylib"] diff --git a/base_layer/tari_mining_helper_ffi/build.rs b/base_layer/tari_mining_helper_ffi/build.rs new file mode 100644 index 0000000000..9e319750db --- /dev/null +++ b/base_layer/tari_mining_helper_ffi/build.rs @@ -0,0 +1,27 @@ +// Copyright 2019, The Tari Project +// +// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the +// following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following +// disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the +// following disclaimer in the documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote +// products derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +use tari_features::resolver::build_features; + +fn main() { + build_features(); +} diff --git a/base_layer/tari_mining_helper_ffi/src/lib.rs b/base_layer/tari_mining_helper_ffi/src/lib.rs index 0cbc4bb970..5aebef1f0e 100644 --- a/base_layer/tari_mining_helper_ffi/src/lib.rs +++ b/base_layer/tari_mining_helper_ffi/src/lib.rs @@ -386,8 +386,16 @@ mod tests { #[test] fn detect_change_in_consensus_encoding() { - const NONCE: u64 = 3926968094459426389; - let difficulty = Difficulty::from_u64(1817).expect("Failed to create difficulty"); + #[cfg(tari_target_network_mainnet)] + let (nonce, difficulty) = match Network::get_current_or_default() { + Network::MainNet => (9205754023158580549, Difficulty::from_u64(1015).unwrap()), + Network::StageNet => (12022341430563186162, Difficulty::from_u64(1011).unwrap()), + _ => panic!("Invalid network for mainnet target"), + }; + #[cfg(tari_target_network_nextnet)] + let (nonce, difficulty) = (8721374869059089110, Difficulty::from_u64(3037).unwrap()); + #[cfg(not(any(tari_target_network_mainnet, tari_target_network_nextnet)))] + let (nonce, difficulty) = (9860518124890236943, Difficulty::from_u64(2724).unwrap()); unsafe { let mut error = -1; let error_ptr = &mut error as *mut c_int; @@ -396,13 +404,15 @@ mod tests { #[allow(clippy::cast_possible_truncation)] let len = header_bytes.len() as u32; let byte_vec = byte_vector_create(header_bytes.as_ptr(), len, error_ptr); - inject_nonce(byte_vec, NONCE, error_ptr); + inject_nonce(byte_vec, nonce, error_ptr); assert_eq!(error, 0); let result = share_difficulty(byte_vec, error_ptr); if result != difficulty.as_u64() { // Use this to generate new NONCE and DIFFICULTY // Use ONLY if you know encoding has changed let (difficulty, nonce) = generate_nonce_with_min_difficulty(min_difficulty()).unwrap(); + let network = Network::get_current_or_default(); + eprintln!("network = {network:?}"); eprintln!("nonce = {:?}", nonce); eprintln!("difficulty = {:?}", difficulty); panic!( diff --git a/buildtools/multinet_envs.sh b/buildtools/multinet_envs.sh index 10e2bd488c..54d0424dcd 100644 --- a/buildtools/multinet_envs.sh +++ b/buildtools/multinet_envs.sh @@ -7,21 +7,25 @@ case "$tagnet" in v*-pre.*) echo "esme" export TARI_NETWORK=esme + export TARI_TARGET_NETWORK=testnet export TARI_NETWORK_DIR=testnet ;; v*-rc.*) echo "nextnet" export TARI_NETWORK=nextnet + export TARI_TARGET_NETWORK=nextnet export TARI_NETWORK_DIR=nextnet ;; v*-dan.*) echo "dan" export TARI_NETWORK=igor + export TARI_TARGET_NETWORK=testnet export TARI_NETWORK_DIR=testnetdan ;; *) echo "mainnet" export TARI_NETWORK=mainnet + export TARI_TARGET_NETWORK=mainnet export TARI_NETWORK_DIR=mainnet ;; esac diff --git a/common/src/configuration/network.rs b/common/src/configuration/network.rs index a78aa7d4a1..c754a913c6 100644 --- a/common/src/configuration/network.rs +++ b/common/src/configuration/network.rs @@ -80,17 +80,20 @@ impl Network { /// The default network for all applications impl Default for Network { - #[cfg(tari_network_mainnet)] + #[cfg(tari_target_network_mainnet)] fn default() -> Self { - Network::StageNet + match std::env::var("TARI_NETWORK") { + Ok(network) => Network::from_str(network.as_str()).unwrap_or(Network::MainNet), + Err(_) => Network::MainNet, + } } - #[cfg(tari_network_nextnet)] + #[cfg(tari_target_network_nextnet)] fn default() -> Self { Network::NextNet } - #[cfg(all(not(tari_network_mainnet), not(tari_network_nextnet)))] + #[cfg(not(any(tari_target_network_mainnet, tari_target_network_nextnet)))] fn default() -> Self { Network::Esmeralda } @@ -191,6 +194,11 @@ mod test { #[test] fn network_default() { let network = Network::default(); + #[cfg(tari_target_network_mainnet)] + assert!(matches!(network, Network::MainNet | Network::StageNet)); + #[cfg(tari_target_network_nextnet)] + assert_eq!(network, Network::NextNet); + #[cfg(not(any(tari_target_network_mainnet, tari_target_network_nextnet)))] assert_eq!(network, Network::Esmeralda); } diff --git a/common/tari_features/Cargo.toml b/common/tari_features/Cargo.toml index 45debb6fbb..83c32f42d3 100644 --- a/common/tari_features/Cargo.toml +++ b/common/tari_features/Cargo.toml @@ -13,4 +13,4 @@ edition = "2018" # So you're thinking about adding a dependency here? # This crate is utilized in the compilation of _most_ of our other crates. You're probably about -# to create a cyclic depedency. Please think hard whether this change is actually required. \ No newline at end of file +# to create a cyclic dependency. Please think hard whether this change is actually required. diff --git a/common/tari_features/README.md b/common/tari_features/README.md index e670b4ee93..3b0c92dd3d 100644 --- a/common/tari_features/README.md +++ b/common/tari_features/README.md @@ -1,5 +1,107 @@ -# tari_features +# Feature gating -Implementation of `tari features` for Tari. +## Step 1: define features -This crate is part of the [Tari Cryptocurrency](https://tari.com) project. +In build.rs, we define our features. + +Features have a +* name - will also be the attribute name you use in code +* description - a short description of the features +* issue tracking number on Github +* The current status. + +#### Status + +* New: New feature, may not even be working or compiling. Will be present on `testnet` +* Testing: Feature is undergoing testing on `nextnet`. Does not exist on `mainnet` or `stagenet`. +* Active: Feature is live and gate has been removed. Will be running on all networks. +* Removed: Feature has been cancelled. Can not be invoked anywhere. + +In `build.rs`, we maintain the list of feature flags. For example: + +```rust +const FEATURE_LIST: [Feature; 4] = [ + Feature::new("add_pair", "Allows you to add two numbers together", Some(123), Status::New), + Feature::new("about_to_launch", "Live in NextNet. If we stabilise, will go to mainnet", Some(123), Status::Testing), + Feature::new("live_feature", "This feature has been stabilised and is live!", Some(150), Status::Active), + Feature::new("old_feature", "We decided not to go with this featuree", Some(145), Status::Removed), +]; +``` + +## Step 2: Demarcate feature flag code + +In your code, you can now use any of the flags as attributes to mark code belonging to a feature. + +Example + +```rust +#[cfg(tari_feature_add_pair)] +use add_pair::add_pair; + +fn main() { + println!("Hello world!"); + #[cfg(tari_feature_add_pair)] + println!("40 + 2 = {}", add_pair(40, 2)); + println!("foo={}", foo()); + println!("Bye, world!"); +} + +#[cfg(tari_feature_add_pair)] +fn foo() -> usize { + 1 +} + +#[cfg(not(tari_feature_add_pair))] +fn foo() -> usize { + 2 +} +``` + +## Step 3: Specify the target network when building + +This PoC uses the `TARI_NETWORK` envar to specify the target network, but in principle, we can also read the `Cargo.toml` +file, or compiler flags. + +`$ TARI_NETWORK=dibbler cargo run -vv` + +Filtered output: + +```text +Building for Dibbler +These features are ACTIVE on mainnet (no special code handling is done) +live_feature. This feature has been stabilised and is live!. Tracking issue: https://github.com/tari-project/tari/issues/150 + +These features are DEPRECATED and will never be compiled +old_feature. We decided not to go with this featuree. Tracking issue: https://github.com/tari-project/tari/issues/145 + +** Activating add_pair. Allows you to add two numbers together. Tracking issue: https://github.com/tari-project/tari/issues/123 ** +** Activating about_to_launch. Live in NextNet. If we stabilise, will go to mainnet. Tracking issue: https://github.com/tari-project/tari/issues/123 ** + +Finished dev [unoptimized + debuginfo] target(s) in 7.44s + Running `target/debug/feature_gates` +Hello world! +40 + 2 = 42 +foo=1 +Bye, world! +``` + +Or compiling for MainNet: + +`$ TARI_NETWORK=mainnet cargo run -vv` + +Filtered output: + +```text +Building for MainNet + +These features are ACTIVE on mainnet (no special code handling is done) +live_feature. This feature has been stabilised and is live!. Tracking issue: https://github.com/tari-project/tari/issues/150 + +These features are DEPRECATED and will never be compiled +old_feature. We decided not to go with this featuree. Tracking issue: https://github.com/tari-project/tari/issues/145 + Finished dev [unoptimized + debuginfo] target(s) in 6.15s + Running `target/debug/feature_gates` +Hello world! +foo=2 +Bye, world! +``` diff --git a/common/tari_features/src/resolver.rs b/common/tari_features/src/resolver.rs index 3edb0edfc7..ba48fc916c 100644 --- a/common/tari_features/src/resolver.rs +++ b/common/tari_features/src/resolver.rs @@ -64,10 +64,10 @@ impl Display for Target { // Identify the target network by // 1. Checking whether --config tari-network=xxx was passed in as a config flag to cargo (or from Cargo.toml) // 2. Checking the environment variable TARI_NETWORK is set -// 3. default to mainnet +// 3. default to testnet (should be mainnet after launch) pub fn identify_target() -> Target { - check_envar("CARGO_CFG_TARI_NETWORK") - .or_else(|| check_envar("TARI_NETWORK")) + check_envar("CARGO_CFG_TARI_TARGET_NETWORK") + .or_else(|| check_envar("TARI_TARGET_NETWORK")) .unwrap_or(Target::TestNet) } @@ -79,19 +79,21 @@ pub fn check_envar(envar: &str) -> Option { } pub fn list_active_features() { - println!("These features are ACTIVE on mainnet (no special code handling is done)"); + println!("tari_feature:These features are ACTIVE on mainnet (no special code handling is done)"); FEATURE_LIST .iter() .filter(|f| f.is_active()) - .for_each(|f| println!("{}", f)); + .for_each(|f| println!("tari_feature:{f}")); + println!("tari_feature:End of ACTIVE feature list"); } pub fn list_removed_features() { - println!("These features are DEPRECATED and will never be compiled"); + println!("tari_feature:These features are DEPRECATED and will never be compiled"); FEATURE_LIST .iter() .filter(|f| f.was_removed()) - .for_each(|f| println!("{}", f)); + .for_each(|f| println!("tari_feature:{f}")); + println!("tari_feature:End of DEPRECATED feature list"); } pub fn resolve_features(target: Target) -> Result<(), String> { @@ -110,17 +112,17 @@ pub fn resolve_features(target: Target) -> Result<(), String> { } pub fn activate_feature(feature: &Feature) { - println!("** Activating {} **", feature); + println!("tari_feature:** Activating {feature} **"); println!("cargo:rustc-cfg={}", feature.attr_name()); } pub fn build_features() { // Make sure to rebuild when the network changes - println!("cargo:rerun-if-env-changed=TARI_NETWORK"); + println!("cargo:rerun-if-env-changed=TARI_TARGET_NETWORK"); let target = identify_target(); - println!("cargo:rustc-cfg=tari_network_{}", target.as_key_str()); - println!("Building for {}", target); + println!("cargo:rustc-cfg=tari_target_network_{}", target.as_key_str()); + println!("tari_feature:Building for {target}"); list_active_features(); list_removed_features(); if let Err(e) = resolve_features(target) { From f3d12196530f9bf7c266cba9eff014cba04cecbb Mon Sep 17 00:00:00 2001 From: SW van Heerden Date: Mon, 26 Feb 2024 10:49:33 +0200 Subject: [PATCH 3/4] fix: oms validation (#6161) Description --- Fixes the OMS validation to invalidate unmined utxos and not keep them pending Motivation and Context --- Although these utxo would never reach spending, the wallet sees them as pending incoming or pending outgoing. We need to ensure their status is correctly set. --- .../tasks/txo_validation_task.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/base_layer/wallet/src/output_manager_service/tasks/txo_validation_task.rs b/base_layer/wallet/src/output_manager_service/tasks/txo_validation_task.rs index f5aaeadb8b..2f7c37475a 100644 --- a/base_layer/wallet/src/output_manager_service/tasks/txo_validation_task.rs +++ b/base_layer/wallet/src/output_manager_service/tasks/txo_validation_task.rs @@ -46,6 +46,7 @@ use crate::{ storage::{ database::{OutputManagerBackend, OutputManagerDatabase}, models::DbWalletOutput, + OutputStatus, }, }, }; @@ -318,6 +319,20 @@ where ) .await?; } + for unmined_output in unmined { + if unmined_output.status == OutputStatus::UnspentMinedUnconfirmed { + info!( + target: LOG_TARGET, + "Updating output comm:{}: hash {} as unmined(Operation ID: {})", + unmined_output.commitment.to_hex(), + unmined_output.hash.to_hex(), + self.operation_id + ); + self.db + .set_output_to_unmined_and_invalid(unmined_output.hash) + .for_protocol(self.operation_id)?; + } + } } Ok(()) From 19a824dea8971f15a7b263122b20e46286f89857 Mon Sep 17 00:00:00 2001 From: Aaron Feickert <66188213+AaronFeickert@users.noreply.github.com> Date: Mon, 26 Feb 2024 02:53:01 -0600 Subject: [PATCH 4/4] fix: avoid cloning range proofs during verification (#6166) Description --- Removes unnecessary cloning of range proofs during batch verification. Motivation and Context --- Currently, range proofs exist in transaction outputs as byte vectors. When parsing outputs to collect these proofs for batch verification, the byte vectors are cloned. This is done because the verification API requires that the vector of proofs contain a vector reference to each proof, but the `BulletRangeProof` type wrapper provides a slice instead as part of its `ByteArray` implementation. Because proofs are several hundred bytes and batches can be large, this cloning is wasteful. This PR adds `BulletRangeProof::as_vec`, which returns the underlying range proof as a vector reference. Doing so lets us avoid the clone while collecting the range proofs. How Has This Been Tested? --- Existing tests pass. What process can a PR reviewer use to test or verify this change? --- Confirm that the change removes the cloning. --- base_layer/common_types/src/types/bullet_rangeproofs.rs | 5 +++++ .../transaction_components/transaction_output.rs | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/base_layer/common_types/src/types/bullet_rangeproofs.rs b/base_layer/common_types/src/types/bullet_rangeproofs.rs index 178e8dd6f7..52b5b27769 100644 --- a/base_layer/common_types/src/types/bullet_rangeproofs.rs +++ b/base_layer/common_types/src/types/bullet_rangeproofs.rs @@ -48,6 +48,11 @@ impl BulletRangeProof { .expect("This should be 32 bytes for a Blake 256 hash") .into() } + + /// Get the range proof as a vector reference, which is useful to satisfy the verification API without cloning + pub fn as_vec(&self) -> &Vec { + &self.0 + } } impl ByteArray for BulletRangeProof { diff --git a/base_layer/core/src/transactions/transaction_components/transaction_output.rs b/base_layer/core/src/transactions/transaction_components/transaction_output.rs index 9211af456a..5b8331e187 100644 --- a/base_layer/core/src/transactions/transaction_components/transaction_output.rs +++ b/base_layer/core/src/transactions/transaction_components/transaction_output.rs @@ -49,7 +49,7 @@ use tari_crypto::{ extended_range_proof::{ExtendedRangeProofService, Statement}, keys::SecretKey, ristretto::bulletproofs_plus::RistrettoAggregatedPublicStatement, - tari_utilities::{hex::Hex, ByteArray}, + tari_utilities::hex::Hex, }; use tari_script::TariScript; @@ -545,9 +545,9 @@ pub fn batch_verify_range_proofs( minimum_value_promise: output.minimum_value_promise.into(), }], }); - proofs.push(output.proof_result()?.to_vec().clone()); + proofs.push(output.proof_result()?.as_vec()); } - if let Err(err_1) = prover.verify_batch(proofs.iter().collect(), statements.iter().collect()) { + if let Err(err_1) = prover.verify_batch(proofs, statements.iter().collect()) { for output in &bulletproof_plus_proofs { if let Err(err_2) = output.verify_range_proof(prover) { return Err(RangeProofError::InvalidRangeProof {