diff --git a/.github/strict-checks.json b/.github/strict-checks.json index 34d372436..16ac99b7b 100644 --- a/.github/strict-checks.json +++ b/.github/strict-checks.json @@ -2,13 +2,13 @@ "strict_check_crates": [ "key-wallet", "key-wallet-manager", - "key-wallet-ffi" + "key-wallet-ffi", + "dash", + "hashes" ], "excluded_crates": [ - "dash", "dash-network", "dash-network-ffi", - "hashes", "internals", "fuzz", "rpc-client", diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e6c8c6ecd..a4720aa7e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,4 +1,9 @@ -on: [push, pull_request] +on: + push: + branches: + - master + - 'v**-dev' + pull_request: name: Continuous integration @@ -10,65 +15,58 @@ concurrency: cancel-in-progress: true jobs: - Tests: - name: Tests + spv_tests: + name: SPV Components Tests runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - include: - - rust: stable - env: - DO_COV: true - AS_DEPENDENCY: true - DO_NO_STD: false - - rust: beta - env: - AS_DEPENDENCY: true - DO_NO_STD: false - - rust: nightly - env: - # TODO: running with DO_BENCH: true causes the test to fail - # DO_BENCH: true - AS_DEPENDENCY: true - DO_NO_STD: false - DO_DOCS: true - - rust: 1.89.0 - env: - AS_DEPENDENCY: true steps: - name: Checkout Crate uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ matrix.rust }} - - name: Running test script - env: ${{ matrix.env }} - run: ./contrib/test.sh + - name: Cache cargo dependencies + uses: Swatinem/rust-cache@v2 + - name: Test dash-spv crate + run: cargo test -p dash-spv --all-features + - name: Test dash-spv-ffi crate + run: cargo test -p dash-spv-ffi --all-features - workspace-tests: - name: Workspace Tests + key_wallet_tests: + name: Key Wallet Components Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Crate + uses: actions/checkout@v4 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Cache cargo dependencies + uses: Swatinem/rust-cache@v2 + - name: Test key-wallet crate + run: cargo test -p key-wallet --all-features + - name: Test key-wallet-manager crate + run: cargo test -p key-wallet-manager --all-features + - name: Test key-wallet-ffi crate + run: cargo test -p key-wallet-ffi --all-features + + core_components_tests: + name: Core Components Tests runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - rust: [stable, beta, nightly, 1.89.0] steps: - name: Checkout Crate uses: actions/checkout@v4 - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ matrix.rust }} - name: Cache cargo dependencies uses: Swatinem/rust-cache@v2 - - name: Run workspace tests - run: cargo test --workspace --all-features - - name: Run workspace tests (no default features) - run: cargo test --workspace --no-default-features - - name: Build workspace (release mode) - run: cargo build --workspace --release + - name: Test dashcore crate + run: cargo test -p dashcore --all-features + - name: Test dashcore_hashes crate + run: cargo test -p dashcore_hashes --all-features + - name: Test dash-network crate + run: cargo test -p dash-network --all-features + - name: Test internals crate + run: cargo test -p dashcore-private --all-features + - name: Run script-based tests + run: ./contrib/test.sh clippy: name: Clippy (Non-strict) @@ -79,19 +77,18 @@ jobs: - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: - toolchain: stable components: clippy - name: Run clippy (excluding strict-checked crates) run: | # Auto-discover all workspace crates and exclude strict-checked ones - STRICT_CRATES=("key-wallet" "key-wallet-manager" "key-wallet-ffi") + STRICT_CRATES=("key-wallet" "key-wallet-manager" "key-wallet-ffi" "dashcore_hashes" "dashcore") mapfile -t ALL_CRATES < <(cargo metadata --no-deps --format-version=1 | jq -r '.packages[].name' | sort -u) for crate in "${ALL_CRATES[@]}"; do if printf '%s\n' "${STRICT_CRATES[@]}" | grep -qx "$crate"; then continue fi - echo "Checking $crate (warnings allowed)..." - cargo clippy -p "$crate" --all-features --all-targets || true + echo "Checking $crate (warnings allowed, errors will fail)..." + cargo clippy -p "$crate" --all-features --all-targets -- -W warnings done strict-checks: @@ -103,7 +100,6 @@ jobs: - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: - toolchain: stable components: clippy - name: Cache cargo dependencies uses: Swatinem/rust-cache@v2 @@ -143,6 +139,30 @@ jobs: - name: Clippy key-wallet-ffi (deny all warnings) run: cargo clippy -p key-wallet-ffi --all-features --lib --bins --tests -- -D warnings + + # Check dashcore with strict warnings + - name: Check dashcore (deny warnings) + env: + RUSTFLAGS: "-D warnings" + run: | + cargo check -p dashcore --all-features --lib --bins --tests + cargo build -p dashcore --all-features --lib --bins + cargo test -p dashcore --all-features --lib --bins + + - name: Clippy dashcore (deny all warnings) + run: cargo clippy -p dashcore --all-features --lib --bins --tests -- -D warnings + + # Check dashcore_hashes with strict warnings + - name: Check dashcore_hashes (deny warnings) + env: + RUSTFLAGS: "-D warnings" + run: | + cargo check -p dashcore_hashes --all-features --lib --bins --tests + cargo build -p dashcore_hashes --all-features --lib --bins + cargo test -p dashcore_hashes --all-features --lib --bins + + - name: Clippy dashcore_hashes (deny all warnings) + run: cargo clippy -p dashcore_hashes --all-features --lib --bins --tests -- -D warnings fmt: name: Format @@ -153,106 +173,41 @@ jobs: - name: Setup Rust toolchain uses: dtolnay/rust-toolchain@stable with: - toolchain: stable components: rustfmt - name: Check formatting run: cargo fmt --all -- --check -# TODO: need to support compiling rust-x11-hash under s390x -# Cross: -# name: Cross testing -# if: ${{ !github.event.act }} -# runs-on: ubuntu-latest -# steps: -# - name: Checkout Crate -# uses: actions/checkout@v4 -# - name: Checkout Toolchain -# uses: dtolnay/rust-toolchain@stable -# with: -# profile: minimal -# toolchain: stable -# override: true -# - name: Install target -# run: rustup target add s390x-unknown-linux-gnu -# - name: install cross -# run: cargo install cross -# - name: run cross test -# run: cross test --target s390x-unknown-linux-gnu - -# TODO: need to fix the ability to run the embedded tests -# Embedded: -# runs-on: ubuntu-latest -# env: -# RUSTFLAGS: "-C link-arg=-Tlink.x" -# CARGO_TARGET_THUMBV7M_NONE_EABI_RUNNER: "qemu-system-arm -cpu cortex-m3 -machine mps2-an385 -nographic -semihosting-config enable=on,target=native -kernel" -# steps: -# - name: Checkout -# uses: actions/checkout@v3 -# - name: Set up QEMU -# run: sudo apt update && sudo apt install -y qemu-system-arm gcc-arm-none-eabi -# - name: Checkout Toolchain -# uses: dtolnay/rust-toolchain@nightly -# with: -# targets: thumbv7m-none-eabi -# - name: Install src -# run: rustup component add rust-src -# - name: Run dash/embedded -# run: cd dash/embedded && cargo run --target thumbv7m-none-eabi -# - name: Run hashes/embedded no alloc -# run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi -# - name: Run hashes/embedded with alloc -# run: cd hashes/embedded && cargo run --target thumbv7m-none-eabi --features=alloc - - rpc-tests: - name: RPC Tests - runs-on: ubuntu-latest - strategy: - matrix: - include: - - rust: stable - env: - RUSTFMTCHK: true - - rust: nightly - env: - RUSTFMTCHK: false - - rust: 1.89.0 - env: - PIN_VERSIONS: true - steps: - - name: Checkout Crate - uses: actions/checkout@v4 - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ matrix.rust }} - - name: Running test script - env: ${{ matrix.env }} - run: ./contrib/test.sh + rpc_tests: + name: RPC Tests + runs-on: ubuntu-latest + strategy: + matrix: + include: + - rust: stable + env: + PIN_VERSIONS: true + steps: + - name: Checkout Crate + uses: actions/checkout@v4 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Running test script + env: ${{ matrix.env }} + run: ./contrib/test.sh - integrations-tests: - name: Integration Tests - runs-on: ubuntu-latest - strategy: - matrix: - rust: [stable] - bitcoinversion: - [ - "0.18.0", - "0.18.1", - "0.19.0.1", - "0.19.1", - "0.20.0", - "0.20.1", - "0.21.0", - ] - steps: - - name: Checkout Crate - uses: actions/checkout@v4 - - name: Setup Rust toolchain - uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ matrix.rust }} - - name: Running test script - env: - BITCOINVERSION: ${{ matrix.bitcoinversion }} - run: ./contrib/test-rpc.sh + integrations_tests: + name: Integration Tests + runs-on: ubuntu-latest + strategy: + matrix: + rust: [stable] + dashversion: ["22.0.0", "22.1.3"] + steps: + - name: Checkout Crate + uses: actions/checkout@v4 + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + - name: Running test script + env: + DASHVERSION: ${{ matrix.dashversion }} + run: ./contrib/test-rpc.sh diff --git a/Cargo.toml b/Cargo.toml index 1031c6a54..e6ab98d93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,14 @@ resolver = "2" [workspace.package] version = "0.39.6" -[patch.crates-io.dashcore_hashes] -path = "hashes" +[patch.crates-io] +dashcore_hashes = { path = "hashes" } +# Use fixed version of elliptic-curve-tools with DefaultIsZeroes trait bound +elliptic-curve-tools = { git = "https://github.com/QuantumExplorer/elliptic-curve-tools", branch = "fix/DefaultIsZeroesToSumOfProducts" } + +[profile.release] +# Default to unwinding for most crates + +[profile.dev] +# Default to unwinding for most crates diff --git a/contrib/test-rpc.sh b/contrib/test-rpc.sh index de6b24b1c..2c6190e0d 100755 --- a/contrib/test-rpc.sh +++ b/contrib/test-rpc.sh @@ -1,14 +1,14 @@ set -xe +set -o pipefail -# Just echo all the relevant env vars to help debug Travis. -echo "RUSTFMTCHECK: \"$RUSTFMTCHECK\"" -echo "BITCOINVERSION: \"$BITCOINVERSION\"" +# Just echo all the relevant env vars to help debug. +echo "DASHVERSION: \"$DASHVERSION\"" echo "PATH: \"$PATH\"" # Pin dependencies for Rust v1.29 -if [ -n $"$PIN_VERSIONS" ]; then +if [ -n "$PIN_VERSIONS" ]; then cargo generate-lockfile --verbose cargo update --verbose --package "log" --precise "0.4.13" @@ -20,18 +20,60 @@ if [ -n $"$PIN_VERSIONS" ]; then cargo update --verbose --package "byteorder" --precise "1.3.4" fi -if [ -n "$RUSTFMTCHECK" ]; then - rustup component add rustfmt - cargo fmt --all -- --check -fi - # Integration test. -if [ -n "$BITCOINVERSION" ]; then - wget https://bitcoincore.org/bin/bitcoin-core-$BITCOINVERSION/bitcoin-$BITCOINVERSION-x86_64-linux-gnu.tar.gz - tar -xzvf bitcoin-$BITCOINVERSION-x86_64-linux-gnu.tar.gz - export PATH=$PATH:$(pwd)/bitcoin-$BITCOINVERSION/bin - cd integration_test - ./run.sh +if [ -n "$DASHVERSION" ]; then + ASSET="dashcore-$DASHVERSION-x86_64-linux-gnu.tar.gz" + + # Download the Dash binary + echo "Downloading $ASSET..." + if ! wget "https://github.com/dashpay/dash/releases/download/v$DASHVERSION/$ASSET"; then + echo "Error: Failed to download $ASSET" >&2 + exit 1 + fi + + # Verify the downloaded file exists + if [ ! -f "$ASSET" ]; then + echo "Error: Downloaded file $ASSET not found" >&2 + exit 1 + fi + + # Extract and determine the actual extracted directory + echo "Extracting $ASSET..." + if ! tar -xzvf "$ASSET"; then + echo "Error: Failed to extract $ASSET" >&2 + exit 1 + fi + + # Find the extracted directory (should be dashcore-$DASHVERSION) + EXTRACT_DIR="dashcore-$DASHVERSION" + if [ ! -d "$EXTRACT_DIR" ]; then + echo "Error: Expected directory $EXTRACT_DIR not found after extraction" >&2 + exit 1 + fi + + # Add the bin directory to PATH (avoid SC2155) + DASH_BIN_PATH="$(pwd)/$EXTRACT_DIR/bin" + PATH="$PATH:$DASH_BIN_PATH" + export PATH + + echo "Added $DASH_BIN_PATH to PATH" + + # Change to the correct integration test directory + if [ -d "rpc-integration-test" ]; then + cd rpc-integration-test + else + echo "Error: rpc-integration-test directory not found" >&2 + exit 1 + fi + + # Run the integration tests + if [ -f "./run.sh" ]; then + ./run.sh + else + echo "Error: run.sh script not found in rpc-integration-test" >&2 + exit 1 + fi + exit 0 else # Regular build/unit test. diff --git a/dash-spv-ffi/Cargo.toml b/dash-spv-ffi/Cargo.toml index 06a38b39b..3405c9506 100644 --- a/dash-spv-ffi/Cargo.toml +++ b/dash-spv-ffi/Cargo.toml @@ -31,10 +31,4 @@ env_logger = "0.10" dashcore-test-utils = { path = "../test-utils" } [build-dependencies] -cbindgen = "0.26" - -[profile.release] -panic = "abort" - -[profile.dev] -panic = "abort" \ No newline at end of file +cbindgen = "0.26" \ No newline at end of file diff --git a/dash/Cargo.toml b/dash/Cargo.toml index d45f5e808..dd1e358c9 100644 --- a/dash/Cargo.toml +++ b/dash/Cargo.toml @@ -63,14 +63,12 @@ anyhow = { version= "1.0" } hex = { version= "0.4" } bincode = { version= "=2.0.0-rc.3", optional = true } bincode_derive = { version= "=2.0.0-rc.3", optional = true } -bitflags = "2.9.0" blsful = { git = "https://github.com/dashpay/agora-blsful", rev = "be108b2cf6ac64eedbe04f91c63731533c8956bc", optional = true } ed25519-dalek = { version = "2.1", features = ["rand_core"], optional = true } blake3 = "1.8.1" thiserror = "2" bitvec = "1.0" log = "0.4" -# bls-signatures removed during migration to agora-blsful [dev-dependencies] serde_json = "1.0.140" @@ -80,6 +78,8 @@ secp256k1 = { features = [ "recovery", "rand", "hashes" ], version="0.30.0" } bincode = { version= "=2.0.0-rc.3" } assert_matches = "1.5.0" dashcore = { path = ".", features = ["core-block-hash-use-x11", "message_verification", "quorum_validation", "signer"] } +criterion = "0.5" + [[example]] name = "handshake" @@ -92,3 +92,10 @@ required-features = ["std", "bitcoinconsensus"] [[example]] name = "taproot-psbt" required-features = ["std", "rand-std", "bitcoinconsensus"] + +[[bench]] +name = "transaction" +harness = false + +[lints.rust] +unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(fuzzing)', 'cfg(kani)'] } diff --git a/dash/benches/transaction.rs b/dash/benches/transaction.rs new file mode 100644 index 000000000..101cfddbf --- /dev/null +++ b/dash/benches/transaction.rs @@ -0,0 +1,77 @@ +use criterion::{Criterion, black_box, criterion_group, criterion_main}; +use dashcore::blockdata::transaction::Transaction; +use dashcore::consensus::{Encodable, deserialize}; +use dashcore::hashes::hex::FromHex; +use std::io::Write; + +const SOME_TX: &str = "0100000001a15d57094aa7a21a28cb20b59aab8fc7d1149a3bdbcddba9c622e4f5f6a99ece010000006c493046022100f93bb0e7d8db7bd46e40132d1f8242026e045f03a0efe71bbb8e3f475e970d790221009337cd7f1f929f00cc6ff01f03729b069a7c21b59b1736ddfee5db5946c5da8c0121033b9b137ee87d5a812d6f506efdd37f0affa7ffc310711c06c7f3e097c9447c52ffffffff0100e1f505000000001976a9140389035a9225b3839e2bbf32d826a1e222031fd888ac00000000"; + +/// A writer that discards all data written to it. +struct EmptyWrite; + +impl Write for EmptyWrite { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +fn bench_transaction_size(c: &mut Criterion) { + let raw_tx = Vec::from_hex(SOME_TX).unwrap(); + let mut tx: Transaction = deserialize(&raw_tx).unwrap(); + + c.bench_function("transaction_size", |b| { + b.iter(|| { + black_box(black_box(&mut tx).size()); + }); + }); +} + +fn bench_transaction_serialize(c: &mut Criterion) { + let raw_tx = Vec::from_hex(SOME_TX).unwrap(); + let tx: Transaction = deserialize(&raw_tx).unwrap(); + + c.bench_function("transaction_serialize", |b| { + let mut data = Vec::with_capacity(raw_tx.len()); + b.iter(|| { + let result = tx.consensus_encode(&mut data); + black_box(&result); + data.clear(); + }); + }); +} + +fn bench_transaction_serialize_logic(c: &mut Criterion) { + let raw_tx = Vec::from_hex(SOME_TX).unwrap(); + let tx: Transaction = deserialize(&raw_tx).unwrap(); + + c.bench_function("transaction_serialize_logic", |b| { + b.iter(|| { + let size = tx.consensus_encode(&mut EmptyWrite); + black_box(&size); + }); + }); +} + +fn bench_transaction_deserialize(c: &mut Criterion) { + let raw_tx = Vec::from_hex(SOME_TX).unwrap(); + + c.bench_function("transaction_deserialize", |b| { + b.iter(|| { + let tx: Transaction = deserialize(&raw_tx).unwrap(); + black_box(&tx); + }); + }); +} + +criterion_group!( + benches, + bench_transaction_size, + bench_transaction_serialize, + bench_transaction_serialize_logic, + bench_transaction_deserialize +); +criterion_main!(benches); diff --git a/dash/src/address.rs b/dash/src/address.rs index 01521c772..eec1126bd 100644 --- a/dash/src/address.rs +++ b/dash/src/address.rs @@ -760,8 +760,8 @@ struct AddressInner { /// ``` /// /// 2. `Debug` on `Address` does not produce clean address but address wrapped by -/// an indicator that its network has not been checked. This is to encourage programmer to properly -/// check the network and use `Display` in user-facing context. +/// an indicator that its network has not been checked. This is to encourage programmer to properly +/// check the network and use `Display` in user-facing context. /// /// ``` /// # use std::str::FromStr; @@ -885,7 +885,6 @@ impl bincode::Encode for AddressType { &self, encoder: &mut E, ) -> Result<(), bincode::error::EncodeError> { - use bincode::Encode; (*self as u8).encode(encoder) } } diff --git a/dash/src/amount.rs b/dash/src/amount.rs index 7b75a5034..9d41c79de 100644 --- a/dash/src/amount.rs +++ b/dash/src/amount.rs @@ -242,10 +242,10 @@ fn parse_signed_to_satoshi( // many as the difference in precision. let last_n = unsigned_abs(precision_diff).into(); if is_too_precise(s, last_n) { - match s.parse::() { - Ok(v) if v == 0_i64 => return Ok((is_negative, 0)), - _ => return Err(ParseAmountError::TooPrecise), - } + return match s.parse::() { + Ok(0_i64) => Ok((is_negative, 0)), + _ => Err(ParseAmountError::TooPrecise), + }; } s = &s[0..s.len() - last_n]; 0 @@ -438,7 +438,7 @@ fn fmt_satoshi_in( (true, false, fmt::Alignment::Left) => (0, width - num_width), // If the required padding is odd it needs to be skewed to the left (true, false, fmt::Alignment::Center) => { - ((width - num_width) / 2, (width - num_width + 1) / 2) + ((width - num_width) / 2, (width - num_width).div_ceil(2)) } }; diff --git a/dash/src/base58.rs b/dash/src/base58.rs index 30a2cb132..26ebb7cd4 100644 --- a/dash/src/base58.rs +++ b/dash/src/base58.rs @@ -52,6 +52,10 @@ pub enum Error { // TODO: Remove this as part of crate-smashing, there should not be any key related errors in this module Hex(hex::Error), + /// blsful related error + #[cfg(feature = "blsful")] + BLSError(String), + /// edwards 25519 related error #[cfg(feature = "ed25519-dalek")] Ed25519Dalek(String), @@ -77,6 +81,8 @@ impl fmt::Display for Error { Error::TooShort(_) => write!(f, "base58ck data not even long enough for a checksum"), Error::Secp256k1(ref e) => fmt::Display::fmt(&e, f), Error::Hex(ref e) => write!(f, "Hexadecimal decoding error: {}", e), + #[cfg(feature = "blsful")] + Error::BLSError(ref e) => write!(f, "BLS error: {}", e), #[cfg(feature = "ed25519-dalek")] Error::Ed25519Dalek(ref e) => write!(f, "Ed25519-Dalek error: {}", e), Error::NotSupported(ref e) => write!(f, "Not supported: {}", e), @@ -85,7 +91,7 @@ impl fmt::Display for Error { } #[cfg(feature = "std")] -impl ::std::error::Error for Error {} +impl std::error::Error for Error {} /// Vector-like object that holds the first 100 elements on the stack. If more space is needed it /// will be allocated on the heap. @@ -417,7 +423,7 @@ impl From for Error { key::Error::InvalidKeyPrefix(_) => Error::Secp256k1(secp256k1::Error::InvalidPublicKey), key::Error::Hex(e) => Error::Hex(e), key::Error::InvalidHexLength(size) => Error::InvalidLength(size), - #[cfg(feature = "bls-signatures")] + #[cfg(feature = "blsful")] key::Error::BLSError(e) => Error::BLSError(e), #[cfg(feature = "ed25519-dalek")] key::Error::Ed25519Dalek(e) => Error::Ed25519Dalek(e), diff --git a/dash/src/bip158.rs b/dash/src/bip158.rs index 7377f4735..e88c9a8a4 100644 --- a/dash/src/bip158.rs +++ b/dash/src/bip158.rs @@ -522,6 +522,9 @@ impl<'a, R: io::Read> BitStreamReader<'a, R> { /// ``` pub fn read(&mut self, mut nbits: u8) -> Result { if nbits > 64 { + #[cfg(feature = "std")] + return Err(io::Error::other("can not read more than 64 bits at once")); + #[cfg(not(feature = "std"))] return Err(io::Error::new( io::ErrorKind::Other, "can not read more than 64 bits at once", @@ -563,6 +566,9 @@ impl<'a, W: io::Write> BitStreamWriter<'a, W> { /// Writes nbits bits from data. pub fn write(&mut self, data: u64, mut nbits: u8) -> Result { if nbits > 64 { + #[cfg(feature = "std")] + return Err(io::Error::other("can not write more than 64 bits at once")); + #[cfg(not(feature = "std"))] return Err(io::Error::new( io::ErrorKind::Other, "can not write more than 64 bits at once", diff --git a/dash/src/blockdata/block.rs b/dash/src/blockdata/block.rs index fe818c221..f4a38cdae 100644 --- a/dash/src/blockdata/block.rs +++ b/dash/src/blockdata/block.rs @@ -37,7 +37,6 @@ use crate::{VarInt, io, merkle_tree}; /// * [CBlockHeader definition](https://github.com/bitcoin/bitcoin/blob/345457b542b6a980ccfbc868af0970a6f91d1b82/src/primitives/block.h#L20) #[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Header { /// Block version, now repurposed for soft fork signalling. pub version: Version, @@ -113,7 +112,6 @@ impl Header { /// * [BIP34 - Block v2, Height in Coinbase](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki) #[derive(Copy, PartialEq, Eq, Clone, Debug, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Version(i32); impl Version { @@ -199,7 +197,6 @@ impl Decodable for Version { /// * [CBlock definition](https://github.com/bitcoin/bitcoin/blob/345457b542b6a980ccfbc868af0970a6f91d1b82/src/primitives/block.h#L62) #[derive(PartialEq, Eq, Clone, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Block { /// The block header pub header: Header, @@ -252,11 +249,12 @@ impl Block { .unwrap(); // Witness reserved value is in coinbase input witness. let witness_vec: Vec<_> = coinbase.input[0].witness.iter().collect(); - if witness_vec.len() == 1 && witness_vec[0].len() == 32 { - if let Some(witness_root) = self.witness_root() { - return commitment - == Self::compute_witness_commitment(&witness_root, witness_vec[0]); - } + if witness_vec.len() == 1 + && witness_vec[0].len() == 32 + && let Some(witness_root) = self.witness_root() + { + return commitment + == Self::compute_witness_commitment(&witness_root, witness_vec[0]); } } diff --git a/dash/src/blockdata/fee_rate.rs b/dash/src/blockdata/fee_rate.rs index 67c0d39d9..c781fdeb0 100644 --- a/dash/src/blockdata/fee_rate.rs +++ b/dash/src/blockdata/fee_rate.rs @@ -74,7 +74,7 @@ impl FeeRate { /// Converts to sat/vB rounding up. pub const fn to_sat_per_vb_ceil(self) -> u64 { - (self.0 + (1000 / 4 - 1)) / (1000 / 4) + self.0.div_ceil(1000 / 4) } /// Checked multiplication. @@ -114,7 +114,7 @@ impl Mul for Weight { type Output = Amount; fn mul(self, rhs: FeeRate) -> Self::Output { - Amount::from_sat((rhs.to_sat_per_kwu() * self.to_wu() + 999) / 1000) + Amount::from_sat((rhs.to_sat_per_kwu() * self.to_wu()).div_ceil(1000)) } } diff --git a/dash/src/blockdata/locktime/absolute.rs b/dash/src/blockdata/locktime/absolute.rs index 76dd90ebf..f4a8df872 100644 --- a/dash/src/blockdata/locktime/absolute.rs +++ b/dash/src/blockdata/locktime/absolute.rs @@ -11,8 +11,6 @@ use core::cmp::{Ordering, PartialOrd}; use core::{fmt, mem}; use internals::write_err; -#[cfg(all(test, mutate))] -use mutagen::mutate; #[cfg(doc)] use crate::absolute; @@ -197,7 +195,6 @@ impl LockTime { /// } /// ```` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_satisfied_by(&self, height: Height, time: Time) -> bool { use LockTime::*; @@ -227,7 +224,6 @@ impl LockTime { /// assert!(lock_time.is_implied_by(check)); /// ``` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_implied_by(&self, other: LockTime) -> bool { use LockTime::*; @@ -388,7 +384,6 @@ impl<'de> serde::Deserialize<'de> for LockTime { /// An absolute block height, guaranteed to always contain a valid height value. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Height(u32); impl Height { @@ -479,7 +474,6 @@ impl FromHexStr for Height { /// threshold) seconds since epoch'. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Time(u32); impl Time { diff --git a/dash/src/blockdata/locktime/relative.rs b/dash/src/blockdata/locktime/relative.rs index 6d00dc191..7de8861c0 100644 --- a/dash/src/blockdata/locktime/relative.rs +++ b/dash/src/blockdata/locktime/relative.rs @@ -10,9 +10,6 @@ use core::convert::TryFrom; use core::fmt; -#[cfg(all(test, mutate))] -use mutagen::mutate; - use crate::parse::impl_parse_str_from_int_infallible; use crate::prelude::*; #[cfg(doc)] @@ -30,7 +27,6 @@ use crate::relative; #[allow(clippy::derive_ord_xor_partial_ord)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub enum LockTime { /// A block height lock time value. Blocks(Height), @@ -58,7 +54,6 @@ impl LockTime { /// assert!(lock.is_satisfied_by(current_height(), current_time())); /// ``` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_satisfied_by(&self, h: Height, t: Time) -> bool { if let Ok(true) = self.is_satisfied_by_height(h) { true @@ -93,7 +88,6 @@ impl LockTime { /// assert!(lock.is_implied_by(test_lock)); /// ``` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_implied_by(&self, other: LockTime) -> bool { use LockTime::*; @@ -120,7 +114,6 @@ impl LockTime { /// assert!(lock.is_satisfied_by_height(Height::from(height+1)).expect("a height")); /// ``` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_satisfied_by_height(&self, h: Height) -> Result { use LockTime::*; @@ -146,7 +139,6 @@ impl LockTime { /// assert!(lock.is_satisfied_by_time(Time::from_512_second_intervals(intervals + 10)).expect("a time")); /// ``` #[inline] - #[cfg_attr(all(test, mutate), mutate)] pub fn is_satisfied_by_time(&self, t: Time) -> Result { use LockTime::*; @@ -192,7 +184,6 @@ impl fmt::Display for LockTime { /// A relative lock time lock-by-blockheight value. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Height(u16); impl Height { @@ -246,7 +237,6 @@ impl fmt::Display for Height { /// For BIP 68 relative lock-by-blocktime locks, time is measure in 512 second intervals. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] - pub struct Time(u16); impl Time { @@ -289,7 +279,7 @@ impl Time { /// Will return an error if the input cannot be encoded in 16 bits. #[inline] pub fn from_seconds_ceil(seconds: u32) -> Result { - if let Ok(interval) = u16::try_from((seconds + 511) / 512) { + if let Ok(interval) = u16::try_from(seconds.div_ceil(512)) { Ok(Time::from_512_second_intervals(interval)) } else { Err(Error::IntegerOverflow(seconds)) diff --git a/dash/src/blockdata/script/borrowed.rs b/dash/src/blockdata/script/borrowed.rs index 1cf0c652c..d1b0a50b0 100644 --- a/dash/src/blockdata/script/borrowed.rs +++ b/dash/src/blockdata/script/borrowed.rs @@ -3,8 +3,6 @@ use core::convert::{TryFrom, TryInto}; use core::fmt; -#[cfg(rust_v_1_53)] -use core::ops::Bound; use core::ops::{Index, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive}; use hashes::Hash; @@ -556,5 +554,3 @@ delegate_index!( RangeInclusive, RangeToInclusive ); -#[cfg(rust_v_1_53)] -delegate_index!((Bound, Bound)); diff --git a/dash/src/blockdata/script/mod.rs b/dash/src/blockdata/script/mod.rs index e01c8c91d..6cfeb40ba 100644 --- a/dash/src/blockdata/script/mod.rs +++ b/dash/src/blockdata/script/mod.rs @@ -49,12 +49,14 @@ //! is minimal but we may extend it in the future if needed. use alloc::rc::Rc; -#[cfg(any(not(rust_v_1_60), target_has_atomic = "ptr"))] +#[cfg(all(not(feature = "std"), not(test), target_has_atomic = "ptr"))] use alloc::sync::Arc; use core::borrow::{Borrow, BorrowMut}; use core::cmp::Ordering; use core::fmt; use core::ops::{Deref, DerefMut}; +#[cfg(feature = "std")] +use std::sync::Arc; #[cfg(feature = "serde")] use serde; @@ -293,8 +295,6 @@ impl<'a> From<&'a Script> for Cow<'a, Script> { } } -/// Note: This will fail to compile on old Rust for targets that don't support atomics -#[cfg(any(not(rust_v_1_60), target_has_atomic = "ptr"))] impl<'a> From<&'a Script> for Arc