integration_tests_sv2 0.1.1

Sv2 Integration Tests Framework
docs.rs failed to build integration_tests_sv2-0.1.1
Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.

SV2 Integration Tests

This library provides tools for building integration tests for Stratum V2 roles.

Additionally, the library includes pre-defined integration tests for various Stratum V2 roles/scenarios, which can be found in the tests folder.

Each role has a start_[role_name] function that can be called to run the respective role.

To assert the behavior of a role or the messages it exchanges with other roles, you can use the Sniffer module to listen to the messages between roles.

For examples on how to use the Sniffer helper, check out the sniffer_integration.rs module or other tests in the tests folder.

All tests run in either regtest or signet network.

Bitcoin Core v30.2 binaries are downloaded from https://bitcoincore.org/bin/bitcoin-core-30.2/ and the Template provider (sv2-tp) binaries from https://github.com/stratum-mining/sv2-tp/releases.

Bitcoin Core runs via IPC, and sv2-tp provides Stratum V2 template distribution. These are the only external dependencies in our tests.

Running Tests Instructions

To run pre defined integration tests, use the following command:

$ git clone git@github.com:stratum-mining/stratum.git
$ cargo test --manifest-path=integration-tests/Cargo.toml --verbose --test '*' -- --nocapture

Note: during the execution of the tests, the template-provider directory holds the downloaded binaries (Bitcoin Core and sv2-tp), while test data directories are created in the system temp directory.

Standalone mining_device Binary

The embedded integration_tests_sv2::mining_device module also exposes a standalone executable binary again.

To build it:

cargo build --manifest-path=integration-tests/Cargo.toml --release --bin mining_device

The executable will be available at integration-tests/target/release/mining_device.

To run it directly through Cargo:

cargo run --manifest-path=integration-tests/Cargo.toml --release --bin mining_device -- \
  --address-pool 127.0.0.1:3333 \
  --id-device test

Writing Custom Integration Tests

  • To write your own integration tests using this library, you can install the library as follows:
$ cargo add sv2-integration-tests --git

Then, create your own test by using the library as shown below:

use sv2_integration_tests::{Sniffer, template_provider, interceptor::MessageDirection};
use stratum_apps::stratum_core::{
    common_messages_sv2::{Protocol, SetupConnection, *},
    mining_sv2::*,
    parsers_sv2::{AnyMessage, CommonMessages, Mining, TemplateDistribution},
    template_distribution_sv2::*,
};

struct MyCustomPool;

#[tokio::test]
async fn success_pool_template_provider_connection() {
    let (_tp, tp_addr) = template_provider::start_template_provider(None, template_provider::DifficultyLevel::Low);
    let (sniffer, sniffer_addr) = start_sniffer("", tp_addr, true, vec![], None);
    // From the Pool perspective, `sniffer_addr` is the address of the Template Provider
    // The Sniffer will sit between the Pool and the Template Provider
    let _ = MyCustomPool::start(sniffer_addr).await;
    // here we assert that the downstream(pool in this case) have sent `SetupConnection` message
    // with the correct parameters, protocol, flags, min_version and max_version.  Note that the
    // macro can take any number of arguments after the message argument, but the order is
    // important where a property should be followed by its value.
    sniffer
        .wait_for_message_type(MessageDirection::ToUpstream, MESSAGE_TYPE_SETUP_CONNECTION)
        .await;
    assert_common_message!(
        &sniffer.next_message_from_downstream(),
        SetupConnection,
        protocol,
        Protocol::TemplateDistributionProtocol,
        flags,
        0,
        min_version,
        2,
        max_version,
        2
    );
    sniffer
        .wait_for_message_type(
            MessageDirection::ToDownstream,
            MESSAGE_TYPE_SETUP_CONNECTION_SUCCESS,
        )
        .await;
    assert_common_message!(
        &sniffer.next_message_from_upstream(),
        SetupConnectionSuccess
    );
    sniffer
        .wait_for_message_type(
            MessageDirection::ToUpstream,
            MESSAGE_TYPE_COINBASE_OUTPUT_CONSTRAINTS,
        )
        .await;
    assert_tp_message!(
        &sniffer.next_message_from_downstream(),
        CoinbaseOutputConstraints
    );
    sniffer
        .wait_for_message_type(MessageDirection::ToDownstream, MESSAGE_TYPE_NEW_TEMPLATE)
        .await;
    assert_tp_message!(&sniffer.next_message_from_upstream(), NewTemplate);
    sniffer
        .wait_for_message_type(
            MessageDirection::ToDownstream,
            MESSAGE_TYPE_SET_NEW_PREV_HASH,
        )
        .await;
    assert_tp_message!(sniffer.next_message_from_upstream(), SetNewPrevHash);
}

License

MIT OR Apache-2.0