Skip to content

TP hangs up too quickly (before fully sending SetupConnection.Error) #84

Closed

Description

@plebhash

Is there an existing issue for this?

  • I have searched the existing issues

Current behaviour

the following Integration Test made me realize that TP doesn't respond with a SetupConnection.Error

#[tokio::test]
async fn debug_test() {
    start_tracing();
    use roles_logic_sv2::common_messages_sv2::{SetupConnection, Protocol};
    use roles_logic_sv2::parsers::{AnyMessage, CommonMessages};
    use integration_tests_sv2::start_sniffer;
    use integration_tests_sv2::start_tracing;
    use integration_tests_sv2::sniffer::{MessageDirection, ReplaceMessage};
    use const_sv2::MESSAGE_TYPE_SETUP_CONNECTION;
    use const_sv2::MESSAGE_TYPE_SETUP_CONNECTION_ERROR;
    use std::convert::TryInto;

    // start TemplateProvider
    let (_tp, tp_addr) = integration_tests_sv2::start_template_provider(None);

    // message we are going to replace on the request from Pool
    let setup_connection = SetupConnection {
        protocol: Protocol::MiningProtocol, // not supported by a TP
        min_version: 2,
        max_version: 2,
        flags: 0,
        endpoint_host: "0.0.0.0".to_string().into_bytes().try_into().unwrap(),
        endpoint_port: 8081,
        vendor: "".to_string().into_bytes().try_into().unwrap(),
        hardware_version: "".to_string().into_bytes().try_into().unwrap(),
        firmware: "".to_string().into_bytes().try_into().unwrap(),
        device_id: "".to_string().into_bytes().try_into().unwrap(),
    };

    let message_replacement = AnyMessage::Common(CommonMessages::SetupConnection(setup_connection));
    let intercept = ReplaceMessage::new(
        MessageDirection::ToUpstream,
        MESSAGE_TYPE_SETUP_CONNECTION,
        message_replacement,
    );

    // sniffer that will be used to intercept the Pool's request and replace it with one that contains an unsupported protocol
    let (sniffer_a, sniffer_a_addr) =
        start_sniffer("A".to_string(), tp_addr, false, Some(intercept.into())).await;

    // start pool
    let _ = integration_tests_sv2::start_pool(Some(sniffer_a_addr)).await;

    // prints None
    println!("response from TP {:?}", sniffer_a.next_message_from_upstream());

    // hangs until timeout
    sniffer_a.wait_for_message_type(MessageDirection::ToDownstream, MESSAGE_TYPE_SETUP_CONNECTION_ERROR).await;
}

According to the spec, I would expect it to return a SetupConnection.Error with error_code = unsupported-protocol

Expected behaviour

#[tokio::test]
async fn debug_test() {
    start_tracing();
    use roles_logic_sv2::common_messages_sv2::{SetupConnection, Protocol};
    use roles_logic_sv2::parsers::{AnyMessage, CommonMessages};
    use integration_tests_sv2::start_sniffer;
    use integration_tests_sv2::start_tracing;
    use integration_tests_sv2::sniffer::{MessageDirection, ReplaceMessage};
    use const_sv2::MESSAGE_TYPE_SETUP_CONNECTION;
    use const_sv2::MESSAGE_TYPE_SETUP_CONNECTION_ERROR;
    use std::convert::TryInto;

    // start TemplateProvider
    let (_tp, tp_addr) = integration_tests_sv2::start_template_provider(None);

    // message we are going to replace on the request from Pool
    let setup_connection = SetupConnection {
        protocol: Protocol::MiningProtocol, // not supported by a TP
        min_version: 2,
        max_version: 2,
        flags: 0,
        endpoint_host: "0.0.0.0".to_string().into_bytes().try_into().unwrap(),
        endpoint_port: 8081,
        vendor: "".to_string().into_bytes().try_into().unwrap(),
        hardware_version: "".to_string().into_bytes().try_into().unwrap(),
        firmware: "".to_string().into_bytes().try_into().unwrap(),
        device_id: "".to_string().into_bytes().try_into().unwrap(),
    };

    let message_replacement = AnyMessage::Common(CommonMessages::SetupConnection(setup_connection));
    let intercept = ReplaceMessage::new(
        MessageDirection::ToUpstream,
        MESSAGE_TYPE_SETUP_CONNECTION,
        message_replacement,
    );

    // sniffer that will be used to intercept the Pool's request and replace it with one that contains an unsupported protocol
    let (sniffer_a, sniffer_a_addr) =
        start_sniffer("A".to_string(), tp_addr, false, Some(intercept.into())).await;

    // start pool
    let _ = integration_tests_sv2::start_pool(Some(sniffer_a_addr)).await;

    // prints Some(SetupConnectionError)
    println!("response from TP {:?}", sniffer_a.next_message_from_upstream());

    // returns without error
    sniffer_a.wait_for_message_type(MessageDirection::ToDownstream, MESSAGE_TYPE_SETUP_CONNECTION_ERROR).await;
}

Steps to reproduce

Integration Tests described above

Relevant log output

No response

How did you obtain Bitcoin Core

Other

What version of Bitcoin Core are you using?

0.1.13

Operating system and version

MacOS Sonoma Version 14.4.1 (23E224)

Machine specifications

No response

Activity

  1. Sjors commented on Mar 17, 2025

    @Sjors
    Owner

    There is a check that returns SetupConnection.Error with unsupported-protocol:

    bitcoin/src/sv2/connman.cpp

    Lines 279 to 285 in b4eb739

    // Disconnect a client that connects on the wrong subprotocol.
    if (setup_conn.m_protocol != m_subprotocol) {
    node::Sv2SetupConnectionErrorMsg setup_conn_err{setup_conn.m_flags, std::string{"unsupported-protocol"}};
    LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Send 0x02 SetupConnectionError to client id=%zu\n",
    client.m_id);
    client.m_send_messages.emplace_back(setup_conn_err);

    Perhaps it's checking for the wrong thing?

    Can you also post the TP logs with -debug=sv2 -loglevel=sv2:trace?

  2. plebhash commented on Mar 17, 2025

    @plebhash
    Author

    logs from Integration Test:

    2025-03-17T12:49:13.281593Z  INFO pool_sv2::template_receiver: Connected to template distribution server at 127.0.0.1:54504
    2025-03-17T12:49:13.296580Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:54498
    2025-03-17T12:49:13.296631Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:54506
    2025-03-17T12:49:13.296741Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:54498
    2025-03-17T12:49:13.296756Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:54504
    2025-03-17T12:49:13.297515Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:54504
    2025-03-17T12:49:13.297646Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:54506
    

    I added some extra log lines into the pool source that should be triggered whenever it receives a SetupConnection.Error, but I never see them being printed.

    this indicates that TP simply closes the connection before sending any response.


    logs from TP:

    2025-03-17T12:50:49.458032Z Bitcoin Core version v28.99.0-ga1c1bd932fc7cf016e44a96bd0b2c3b0c5294402 (release build)
    2025-03-17T12:50:49.458035Z parameter interaction: -listen=0 -> setting -natpmp=0
    2025-03-17T12:50:49.458036Z parameter interaction: -listen=0 -> setting -discover=0
    2025-03-17T12:50:49.458037Z parameter interaction: -listen=0 -> setting -listenonion=0
    2025-03-17T12:50:49.458038Z parameter interaction: -listen=0 -> setting -i2pacceptincoming=0
    2025-03-17T12:50:49.458126Z Using the 'arm_shani(1way,2way)' SHA256 implementation
    2025-03-17T12:50:49.560832Z Default data directory /Users/plebhash/Library/Application Support/Bitcoin
    2025-03-17T12:50:49.560838Z Using data directory /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest
    2025-03-17T12:50:49.560847Z Config file: /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/bitcoin.conf (not found, skipping)
    2025-03-17T12:50:49.560855Z Command-line arg: datadir="/Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570"
    2025-03-17T12:50:49.560861Z Command-line arg: debug="rpc"
    2025-03-17T12:50:49.560866Z Command-line arg: debug="sv2"
    2025-03-17T12:50:49.560871Z Command-line arg: fallbackfee="0.0001"
    2025-03-17T12:50:49.560875Z Command-line arg: listen="0"
    2025-03-17T12:50:49.560880Z Command-line arg: loglevel="sv2:trace"
    2025-03-17T12:50:49.560884Z Command-line arg: logtimemicros="1"
    2025-03-17T12:50:49.560889Z Command-line arg: regtest=""
    2025-03-17T12:50:49.560894Z Command-line arg: rpcport="54571"
    2025-03-17T12:50:49.560899Z Command-line arg: sv2=""
    2025-03-17T12:50:49.560904Z Command-line arg: sv2feedelta="0"
    2025-03-17T12:50:49.560908Z Command-line arg: sv2interval="20"
    2025-03-17T12:50:49.560913Z Command-line arg: sv2port="54570"
    2025-03-17T12:50:49.560917Z Command-line arg: txindex="1"
    2025-03-17T12:50:49.560923Z Using at most 125 automatic connections (1024 file descriptors available)
    2025-03-17T12:50:49.560959Z scheduler thread start
    2025-03-17T12:50:49.563655Z Binding RPC on address ::1 port 54571
    2025-03-17T12:50:49.564066Z Binding RPC on address 127.0.0.1 port 54571
    2025-03-17T12:50:49.564094Z [rpc] Starting RPC
    2025-03-17T12:50:49.564102Z [rpc] Starting HTTP RPC server
    2025-03-17T12:50:49.564254Z Generated RPC authentication cookie /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/.cookie
    2025-03-17T12:50:49.564264Z Permissions used for cookie: rw-------
    2025-03-17T12:50:49.564269Z Using random cookie authentication.
    2025-03-17T12:50:49.564280Z Starting HTTP server with 4 worker threads
    2025-03-17T12:50:49.564324Z Using wallet directory /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/wallets
    2025-03-17T12:50:49.564332Z init message: Verifying wallet(s)…
    2025-03-17T12:50:49.564358Z Using /16 prefix for IP bucketing
    2025-03-17T12:50:49.564364Z init message: Loading P2P addresses…
    2025-03-17T12:50:49.564513Z Creating peers.dat because the file was not found ("/Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/peers.dat")
    2025-03-17T12:50:49.572671Z init message: Loading banlist…
    2025-03-17T12:50:49.572694Z Recreating the banlist database
    2025-03-17T12:50:49.572888Z SetNetworkActive: true
    2025-03-17T12:50:49.573050Z /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/fee_estimates.dat is not found. Continue anyway.
    2025-03-17T12:50:49.573070Z Cache configuration:
    2025-03-17T12:50:49.573076Z * Using 2.0 MiB for block index database
    2025-03-17T12:50:49.573082Z * Using 56.0 MiB for transaction index database
    2025-03-17T12:50:49.573087Z * Using 8.0 MiB for chain state database
    2025-03-17T12:50:49.573104Z * Using 384.0 MiB for in-memory UTXO set (plus up to 286.1 MiB of unused mempool space)
    2025-03-17T12:50:49.573116Z Script verification uses 11 additional threads
    2025-03-17T12:50:49.573288Z Using obfuscation key for blocksdir *.dat files (/Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/blocks): 'b3624b0f9124422b'
    2025-03-17T12:50:49.574457Z Using 16 MiB out of 16 MiB requested for signature cache, able to store 524288 elements
    2025-03-17T12:50:49.575604Z Using 16 MiB out of 16 MiB requested for script execution cache, able to store 524288 elements
    2025-03-17T12:50:49.575613Z init message: Loading block index…
    2025-03-17T12:50:49.575618Z Validating signatures for all blocks.
    2025-03-17T12:50:49.575622Z Setting nMinimumChainWork=0000000000000000000000000000000000000000000000000000000000000000
    2025-03-17T12:50:49.575687Z Opening LevelDB in /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/blocks/index
    2025-03-17T12:50:49.594924Z Opened LevelDB successfully
    2025-03-17T12:50:49.594940Z Using obfuscation key for /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/blocks/index: 0000000000000000
    2025-03-17T12:50:49.594957Z LoadBlockIndexDB: last block file = 0
    2025-03-17T12:50:49.594967Z LoadBlockIndexDB: last block file info: CBlockFileInfo(blocks=0, size=0, heights=0...0, time=1970-01-01...1970-01-01)
    2025-03-17T12:50:49.594971Z Checking all blk files are present...
    2025-03-17T12:50:49.597176Z Initializing chainstate Chainstate [ibd] @ height -1 (null)
    2025-03-17T12:50:49.597229Z Opening LevelDB in /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/chainstate
    2025-03-17T12:50:49.616397Z Opened LevelDB successfully
    2025-03-17T12:50:49.616479Z Wrote new obfuscate key for /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/chainstate: a311115047f2cad4
    2025-03-17T12:50:49.616485Z Using obfuscation key for /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/chainstate: a311115047f2cad4
    2025-03-17T12:50:49.616502Z init message: Verifying blocks…
    2025-03-17T12:50:49.616508Z  block index              40ms
    2025-03-17T12:50:49.616596Z Opening LevelDB in /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/indexes/txindex
    2025-03-17T12:50:49.634533Z Opened LevelDB successfully
    2025-03-17T12:50:49.634545Z Using obfuscation key for /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/indexes/txindex: 0000000000000000
    2025-03-17T12:50:49.634556Z Setting NODE_NETWORK on non-prune mode
    2025-03-17T12:50:49.634586Z initload thread start
    2025-03-17T12:50:49.634656Z UpdateTip: new best=0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206 height=0 version=0x00000001 log2_work=1.000000 tx=1 date='2011-02-02T23:16:42Z' progress=1.000000 cache=0.3MiB(0txo)
    2025-03-17T12:50:49.634683Z block tree size = 1
    2025-03-17T12:50:49.634698Z nBestHeight = 0
    2025-03-17T12:50:49.634717Z txindex thread start
    2025-03-17T12:50:49.634724Z txindex is enabled
    2025-03-17T12:50:49.634729Z txindex thread exit
    2025-03-17T12:50:49.634738Z Failed to open mempool file. Continuing anyway.
    2025-03-17T12:50:49.634747Z initload thread exit
    2025-03-17T12:50:49.634755Z 0 block-relay-only anchors will be tried for connections.
    2025-03-17T12:50:49.634762Z init message: Starting network threads…
    2025-03-17T12:50:49.634785Z net thread start
    2025-03-17T12:50:49.634794Z dnsseed thread start
    2025-03-17T12:50:49.634804Z opencon thread start
    2025-03-17T12:50:49.634816Z msghand thread start
    2025-03-17T12:50:49.634826Z addcon thread start
    2025-03-17T12:50:49.634837Z Loading addresses from DNS seed dummySeed.invalid.
    2025-03-17T12:50:49.634956Z [sv2] Generated static key, saved to /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/sv2_static_key
    2025-03-17T12:50:49.634980Z [sv2:info] Static key: 024192555ef60bded27eb9f305f5cde776c815bf6b2598ff14784c0cfe786ebc2f
    2025-03-17T12:50:49.635061Z [sv2] Generated authority key, saved to /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/sv2_authority_key
    2025-03-17T12:50:49.635093Z Template Provider authority key: 9ajeb8DyAvdmp4ZbzYVjXz8cuKDGjwrttyaPkzttpGbtYy7zep1
    2025-03-17T12:50:49.635099Z [sv2:trace] Authority key: 0dcc0b11d7470afb58e7a7dfba097a8f8b4fc5fdb12eda2be4cc65b162ad52d0
    2025-03-17T12:50:49.635120Z [sv2:trace] Certificate hashed data: 0000990cd867ffffffff4192555ef60bded27eb9f305f5cde776c815bf6b2598ff14784c0cfe786ebc2f
    2025-03-17T12:50:49.635254Z [sv2:info] Template Provider listening on 127.0.0.1:54570
    2025-03-17T12:50:49.635277Z net thread start
    2025-03-17T12:50:49.635287Z init message: Done loading
    2025-03-17T12:50:49.635295Z sv2 thread start
    2025-03-17T12:50:49.635305Z [sv2:trace] Waiting to come out of IBD
    2025-03-17T12:50:49.637213Z 0 addresses found from DNS seeds
    2025-03-17T12:50:49.637221Z dnsseed thread exit
    2025-03-17T12:50:50.461315Z [rpc] ThreadRPCServer method=getblockchaininfo user=__cookie__
    2025-03-17T12:50:50.462246Z [rpc] ThreadRPCServer method=createwallet user=__cookie__
    2025-03-17T12:50:50.462373Z Using SQLite Version 3.46.1
    2025-03-17T12:50:50.462390Z Using wallet /Users/plebhash/develop/stratum/roles/tests-integration/template-provider/.bitcoin-54570/regtest/wallets/default
    2025-03-17T12:50:50.515600Z init message: Loading wallet…
    2025-03-17T12:50:50.515689Z [default] Wallet file version = 10500, last client version = 289900
    2025-03-17T12:50:50.515755Z [default] Legacy Wallet Keys: 0 plaintext, 0 encrypted, 0 w/ metadata, 0 total.
    2025-03-17T12:50:50.515773Z [default] Descriptors: 0, Descriptor Keys: 0 plaintext, 0 encrypted, 0 total.
    2025-03-17T12:50:50.533538Z [default] Setting minversion to 169900
    2025-03-17T12:50:50.603540Z [default] Setting spkMan to active: id = dc5b5c39547ff6df90e06fcd96ccc9576e25957f7a1a21355f4a95dffe648f34, type = legacy, internal = false
    2025-03-17T12:50:50.630990Z [default] Setting spkMan to active: id = 3a7a381b52ef96005855d4b8574314e204e86c21812553504b0c38ddddd97f66, type = p2sh-segwit, internal = false
    2025-03-17T12:50:50.640334Z [sv2:trace] Waiting to come out of IBD
    2025-03-17T12:50:50.654653Z [default] Setting spkMan to active: id = 3190a56a16017e468cfd666f3ecdb9844b30d6d9ce14134e0d28f5a212681203, type = bech32, internal = false
    2025-03-17T12:50:50.700681Z [default] Setting spkMan to active: id = e1d744a1dd1d2324973d4c7ee281d5a7414bc17523bdf358deb843033411b59f, type = bech32m, internal = false
    2025-03-17T12:50:50.724160Z [default] Setting spkMan to active: id = a9d6be76e5bccbb199491522e50a6736802e06d1ddb23ee78fa295ced7efaccf, type = legacy, internal = true
    2025-03-17T12:50:50.747829Z [default] Setting spkMan to active: id = abf04af99083277041c11041814d794a74f32ade0c8346b3d9c97d18fd5ced63, type = p2sh-segwit, internal = true
    2025-03-17T12:50:50.771519Z [default] Setting spkMan to active: id = d31641ed257bab9a4a100ae7d4b8eb91eb9087abb023678652d121e2bd1023fe, type = bech32, internal = true
    2025-03-17T12:50:50.816656Z [default] Setting spkMan to active: id = c45cffe7cb977b1e0822c551173d07ee80bc593d7ecbee711e2510f8a8cbd320, type = bech32m, internal = true
    2025-03-17T12:50:50.870130Z [default] Wallet completed loading in             354ms
    2025-03-17T12:50:51.006170Z [default] setKeyPool.size() = 8000
    2025-03-17T12:50:51.006195Z [default] mapWallet.size() = 0
    2025-03-17T12:50:51.006206Z [default] m_address_book.size() = 0
    2025-03-17T12:50:51.007174Z [rpc] ThreadRPCServer method=getnewaddress user=__cookie__
    2025-03-17T12:50:51.073864Z [rpc] ThreadRPCServer method=generatetoaddress user=__cookie__
    2025-03-17T12:50:51.073931Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.074749Z Leaving InitialBlockDownload (latching to false)
    2025-03-17T12:50:51.074792Z UpdateTip: new best=7e98f8366895915a4dd2ff416515c183f871c6fb21711b3120683c98870bf8f3 height=1 version=0x20000000 log2_work=2.000000 tx=2 date='2025-03-17T12:50:51Z' progress=1.000000 cache=0.3MiB(1txo)
    2025-03-17T12:50:51.075378Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.075419Z Saw new header hash=77b9bf56bf4132b4287a6a6c1a395fa6c4e8c61f8035c7918c14e3d56dc83132 height=2
    2025-03-17T12:50:51.075602Z UpdateTip: new best=77b9bf56bf4132b4287a6a6c1a395fa6c4e8c61f8035c7918c14e3d56dc83132 height=2 version=0x20000000 log2_work=2.584963 tx=3 date='2025-03-17T12:50:52Z' progress=1.000000 cache=0.3MiB(2txo)
    2025-03-17T12:50:51.075673Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.075696Z Saw new header hash=14cee2c1fba326698eb1663c6aedd94077f0bb59d5ab7c43fefd4eddd3802b7b height=3
    2025-03-17T12:50:51.075832Z UpdateTip: new best=14cee2c1fba326698eb1663c6aedd94077f0bb59d5ab7c43fefd4eddd3802b7b height=3 version=0x20000000 log2_work=3.000000 tx=4 date='2025-03-17T12:50:52Z' progress=1.000000 cache=0.3MiB(3txo)
    2025-03-17T12:50:51.075898Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.075919Z Saw new header hash=42b4bc9fee5a3810eb6799bae9c2fd588a73dbbe75f3bf64467ea13074e2d986 height=4
    2025-03-17T12:50:51.076044Z UpdateTip: new best=42b4bc9fee5a3810eb6799bae9c2fd588a73dbbe75f3bf64467ea13074e2d986 height=4 version=0x20000000 log2_work=3.321928 tx=5 date='2025-03-17T12:50:53Z' progress=1.000000 cache=0.3MiB(4txo)
    2025-03-17T12:50:51.076108Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.076579Z Saw new header hash=52cc32a781b16063fa5409f04db096566ea376f9c7c082c924b6ed94b0da21b4 height=5
    2025-03-17T12:50:51.076736Z UpdateTip: new best=52cc32a781b16063fa5409f04db096566ea376f9c7c082c924b6ed94b0da21b4 height=5 version=0x20000000 log2_work=3.584963 tx=6 date='2025-03-17T12:50:53Z' progress=1.000000 cache=0.3MiB(5txo)
    2025-03-17T12:50:51.076800Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.076822Z Saw new header hash=46ca5d09ddbf980eef866b9fa213081293acff1c963471d58cd7d005bf76f6c5 height=6
    2025-03-17T12:50:51.112184Z [default] AddToWallet bad5a4311834ab97c2c0d9a90a1d531fcd7a7b8f1458058d8caaa71111907399  new Confirmed (block=7e98f8366895915a4dd2ff416515c183f871c6fb21711b3120683c98870bf8f3, height=1, index=0)
    2025-03-17T12:50:51.165127Z [default] AddToWallet 92fa8698a89ff5bb8f2bab3fb576356e7df183ceaf4b2a0b7b19d29dd2b49b9c  new Confirmed (block=77b9bf56bf4132b4287a6a6c1a395fa6c4e8c61f8035c7918c14e3d56dc83132, height=2, index=0)
    2025-03-17T12:50:51.216098Z [default] AddToWallet a5faeab1cfd95c04de79d5980f653f0e56eef899e98181c04afc7b718be85893  new Confirmed (block=14cee2c1fba326698eb1663c6aedd94077f0bb59d5ab7c43fefd4eddd3802b7b, height=3, index=0)
    2025-03-17T12:50:51.275063Z [default] AddToWallet 2355cd5af695109522429d4a9f56f8c4f07b6204e50ef2158f91e8cd8cb13eb1  new Confirmed (block=42b4bc9fee5a3810eb6799bae9c2fd588a73dbbe75f3bf64467ea13074e2d986, height=4, index=0)
    2025-03-17T12:50:51.325020Z [default] AddToWallet 71cebebd2c8e1ce8a6873e02949e159fbcaf0903e8fd5c22ee4fbeb619b08e60  new Confirmed (block=52cc32a781b16063fa5409f04db096566ea376f9c7c082c924b6ed94b0da21b4, height=5, index=0)
    2025-03-17T12:50:51.341717Z UpdateTip: new best=46ca5d09ddbf980eef866b9fa213081293acff1c963471d58cd7d005bf76f6c5 height=6 version=0x20000000 log2_work=3.807355 tx=7 date='2025-03-17T12:50:53Z' progress=1.000000 cache=0.3MiB(6txo)
    2025-03-17T12:50:51.342073Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.342168Z Saw new header hash=53ef6259f79f67ff9865d186cafcfc52176677afc6a9bf294ab610a735c1a912 height=7
    2025-03-17T12:50:51.342874Z UpdateTip: new best=53ef6259f79f67ff9865d186cafcfc52176677afc6a9bf294ab610a735c1a912 height=7 version=0x20000000 log2_work=4.000000 tx=8 date='2025-03-17T12:50:53Z' progress=1.000000 cache=0.3MiB(7txo)
    2025-03-17T12:50:51.343056Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.343123Z Saw new header hash=3245bf33e0c24f1a1e73e8f07e91e0c24f25bfdc3f3cbf30492f2ec7137b4e17 height=8
    2025-03-17T12:50:51.352797Z UpdateTip: new best=3245bf33e0c24f1a1e73e8f07e91e0c24f25bfdc3f3cbf30492f2ec7137b4e17 height=8 version=0x20000000 log2_work=4.169925 tx=9 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(8txo)
    2025-03-17T12:50:51.352969Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.353045Z Saw new header hash=2876020de61e59541db5d55f0730cc340bf2c50441ae3dbf97e3a9b91ae04816 height=9
    2025-03-17T12:50:51.359414Z UpdateTip: new best=2876020de61e59541db5d55f0730cc340bf2c50441ae3dbf97e3a9b91ae04816 height=9 version=0x20000000 log2_work=4.321928 tx=10 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(9txo)
    2025-03-17T12:50:51.359622Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.363033Z Saw new header hash=5fb211807e3753efede9edb40e047a4f7a6685046619c5a202d96c22a264e3e8 height=10
    2025-03-17T12:50:51.363593Z UpdateTip: new best=5fb211807e3753efede9edb40e047a4f7a6685046619c5a202d96c22a264e3e8 height=10 version=0x20000000 log2_work=4.459432 tx=11 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(10txo)
    2025-03-17T12:50:51.363864Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.367305Z Saw new header hash=051fd8967ce98b4afe84523064c1f55608cab1a10b222a47370a69737b45bbde height=11
    2025-03-17T12:50:51.380135Z [default] AddToWallet 028221a441cbd1c6f76cfca941c2628a9490f7e4168b51c56e1581059407ea63  new Confirmed (block=46ca5d09ddbf980eef866b9fa213081293acff1c963471d58cd7d005bf76f6c5, height=6, index=0)
    2025-03-17T12:50:51.430105Z [default] AddToWallet 77f570a49330fa56f461c8e3e7343d85c794ad871c533b0f707479a0b214e61d  new Confirmed (block=53ef6259f79f67ff9865d186cafcfc52176677afc6a9bf294ab610a735c1a912, height=7, index=0)
    2025-03-17T12:50:51.487004Z [default] AddToWallet b896391e5575173ae5cc2f8c085f0419d0b5c8a2763fefb34e29b1e57f7b6e29  new Confirmed (block=3245bf33e0c24f1a1e73e8f07e91e0c24f25bfdc3f3cbf30492f2ec7137b4e17, height=8, index=0)
    2025-03-17T12:50:51.534986Z [default] AddToWallet 86daa5be63391bcb528a3ecb91474fe2583301d6ae3c3a01bafb26df374f240a  new Confirmed (block=2876020de61e59541db5d55f0730cc340bf2c50441ae3dbf97e3a9b91ae04816, height=9, index=0)
    2025-03-17T12:50:51.583012Z [default] AddToWallet 839e5f95a5aa8a657ffd2685ff8797b3225399302933e614cae388c97d2ec275  new Confirmed (block=5fb211807e3753efede9edb40e047a4f7a6685046619c5a202d96c22a264e3e8, height=10, index=0)
    2025-03-17T12:50:51.599570Z UpdateTip: new best=051fd8967ce98b4afe84523064c1f55608cab1a10b222a47370a69737b45bbde height=11 version=0x20000000 log2_work=4.584963 tx=12 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(11txo)
    2025-03-17T12:50:51.599893Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.599991Z Saw new header hash=3ee22cec69db0242f6dc90d162fe041251e6bf79ff0f2d65f1b043d53d30e578 height=12
    2025-03-17T12:50:51.600467Z UpdateTip: new best=3ee22cec69db0242f6dc90d162fe041251e6bf79ff0f2d65f1b043d53d30e578 height=12 version=0x20000000 log2_work=4.700440 tx=13 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(12txo)
    2025-03-17T12:50:51.600639Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.600703Z Saw new header hash=2f0e547b7e7fa4fcd0023c04176a5318a916188dd92244c717c16b305685f5af height=13
    2025-03-17T12:50:51.601302Z UpdateTip: new best=2f0e547b7e7fa4fcd0023c04176a5318a916188dd92244c717c16b305685f5af height=13 version=0x20000000 log2_work=4.807355 tx=14 date='2025-03-17T12:50:54Z' progress=1.000000 cache=0.3MiB(13txo)
    2025-03-17T12:50:51.601477Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.605293Z Saw new header hash=227f65f32e5ea60c6100b2966b53cb05ffa9d5dd927698fff52b3559a235c98e height=14
    2025-03-17T12:50:51.609174Z UpdateTip: new best=227f65f32e5ea60c6100b2966b53cb05ffa9d5dd927698fff52b3559a235c98e height=14 version=0x20000000 log2_work=4.906891 tx=15 date='2025-03-17T12:50:55Z' progress=1.000000 cache=0.3MiB(14txo)
    2025-03-17T12:50:51.609361Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.612935Z Saw new header hash=6e417edab32dff7b0d5352e260032642d7a866e3628112f75bdba54fe6dc3c67 height=15
    2025-03-17T12:50:51.613462Z UpdateTip: new best=6e417edab32dff7b0d5352e260032642d7a866e3628112f75bdba54fe6dc3c67 height=15 version=0x20000000 log2_work=5.000000 tx=16 date='2025-03-17T12:50:55Z' progress=1.000000 cache=0.3MiB(15txo)
    2025-03-17T12:50:51.617327Z CreateNewBlock(): block weight: 884 txs: 0 fees: 0 sigops 400
    2025-03-17T12:50:51.617424Z Saw new header hash=4d8e4ef5f8c74b992b3e41498d93eac37be89e41989c3dc21c33e4a670172286 height=16
    2025-03-17T12:50:51.633080Z [default] AddToWallet 6fd8658811ab879c6d5c15840c8262dad86c14167dd40d25a316056b1afb9af1  new Confirmed (block=051fd8967ce98b4afe84523064c1f55608cab1a10b222a47370a69737b45bbde, height=11, index=0)
    2025-03-17T12:50:51.682099Z [default] AddToWallet e9c759d3e822daee72af9cb277d616dd8ca6b628005b4419e3f68ddbbac69ae4  new Confirmed (block=3ee22cec69db0242f6dc90d162fe041251e6bf79ff0f2d65f1b043d53d30e578, height=12, index=0)
    2025-03-17T12:50:51.735020Z [default] AddToWallet 794b3fe691ea55e3cce9302cb93e6fc52260c2b32e59c6859468e77169c5cf95  new Confirmed (block=2f0e547b7e7fa4fcd0023c04176a5318a916188dd92244c717c16b305685f5af, height=13, index=0)
    2025-03-17T12:50:51.786039Z [default] AddToWallet ea17e2caffbf7da74ce3d7bda00eda4fdf456488bc09e0ed8b23cfb8d2b05c77  new Confirmed (block=227f65f32e5ea60c6100b2966b53cb05ffa9d5dd927698fff52b3559a235c98e, height=14, index=0)
    2025-03-17T12:50:51.837130Z [default] AddToWallet 527f665c414aa55eca1a0ae7cdd5ca96dd5871e73053a4cd80b4ceabb2cfe616  new Confirmed (block=6e417edab32dff7b0d5352e260032642d7a866e3628112f75bdba54fe6dc3c67, height=15, index=0)
    2025-03-17T12:50:51.854618Z UpdateTip: new best=4d8e4ef5f8c74b992b3e41498d93eac37be89e41989c3dc21c33e4a670172286 height=16 version=0x20000000 log2_work=5.087463 tx=17 date='2025-03-17T12:50:55Z' progress=1.000000 cache=0.3MiB(16txo)
    2025-03-17T12:50:51.859776Z [sv2:trace] Noise session receive state -> HANDSHAKE_STEP_1
    2025-03-17T12:50:51.862738Z [sv2:trace] New client id=0 connected
    2025-03-17T12:50:51.862786Z [sv2:trace] Read their ephemeral key
    2025-03-17T12:50:51.862803Z [sv2:trace] Mix hash: 6a627b7d33cd014b1fc5d6ff4f822c729d6483f89a87a8c471501f827edc3fb3
    2025-03-17T12:50:51.862820Z [sv2:trace] Noise session receive state -> HANDSHAKE_STEP_2
    2025-03-17T12:50:51.862833Z [sv2:trace] Generate ephemeral key
    2025-03-17T12:50:51.862941Z [sv2:trace] Write our ephemeral key
    2025-03-17T12:50:51.862970Z [sv2:trace] Mix hash: c484eb57a887b9407dedf4b5291251b7a5c78b9c01890eec6319db1ce0d7ce65
    2025-03-17T12:50:51.862983Z [sv2:trace] Perform ECDH with the remote ephemeral key
    2025-03-17T12:50:51.863143Z [sv2:trace] Mix key with ECDH result: ephemeral ours -- remote ephemeral
    2025-03-17T12:50:51.867002Z [sv2:trace] Chaining key: b0c718c18600537e8448083b5e83898f4ef4c900c7f79429e08f154cb94ed3cc
    2025-03-17T12:50:51.867153Z [sv2:trace] Encrypt and write our static key
    2025-03-17T12:50:51.867180Z [sv2:trace] Mix hash: 5fbdfd31cf02edf5c54d1082c37bb9e79f111b55c1ed4b7067b7f6cd79c76d96
    2025-03-17T12:50:51.867196Z [sv2:trace] Perform ECDH between our static and remote ephemeral key
    2025-03-17T12:50:51.867347Z [sv2:trace] ECDH result: 78ce2ffb82a525d1b495c7de968fbdfebd4c98747e66714631e0ab7037fc06bb
    2025-03-17T12:50:51.867626Z [sv2:trace] Mix key with ECDH result: static ours -- remote ephemeral
    2025-03-17T12:50:51.871080Z [sv2:trace] Chaining key: b29d497cee3d6f2be944e4c1d732f8ef291f449e2cefa8695074a02500660dbd
    2025-03-17T12:50:51.871133Z [sv2:trace] Encrypt certificate: 0000990cd867ffffffff1112c217b11a87a3c8c4915741220f19bf25e428b2e2d52166188459137da4fd6830b6108051a51447fc2795ec721c93d387241b9429ed7942e1882a0129b933
    2025-03-17T12:50:51.871159Z [sv2:trace] Mix hash: 524d799bbc047659432cb6922bd32c1c1dc349d05a3cbd09eb4b1ccfa29e9b54
    2025-03-17T12:50:51.871183Z [sv2:trace] Noise session send state -> READY
    2025-03-17T12:50:51.871198Z [sv2:trace] Noise session receive state -> APP
    2025-03-17T12:50:51.871230Z [sv2:trace] Send 234 bytes to client id=0
    2025-03-17T12:50:51.871815Z [sv2:trace] Header: 000000170000
    2025-03-17T12:50:51.871858Z [sv2:trace] Expecting 23 bytes payload (plain)
    2025-03-17T12:50:51.876249Z [sv2:trace] Payload: 00020002000000000007302e302e302e30911f00000000
    2025-03-17T12:50:51.876266Z [sv2:trace] Noise session receive state -> APP_READY
    2025-03-17T12:50:51.876314Z [sv2:trace] Noise session receive state -> APP
    2025-03-17T12:50:51.876376Z [sv2] Received 0x00 SetupConnection from client id=0
    2025-03-17T12:50:51.876530Z [sv2] Send 0x02 SetupConnectionError to client id=0
    2025-03-17T12:50:51.888154Z [default] AddToWallet d251a5640e0b25e8085be4b77f82c09dc16e35b4b73bbd0e24f709bbe4b17c51  new Confirmed (block=4d8e4ef5f8c74b992b3e41498d93eac37be89e41989c3dc21c33e4a670172286, height=16, index=0)
    2025-03-17T12:50:54.621626Z [rpc] Interrupting HTTP RPC server
    2025-03-17T12:50:54.621697Z [rpc] Interrupting RPC
    2025-03-17T12:50:54.621746Z addcon thread exit
    2025-03-17T12:50:54.621783Z opencon thread exit
    2025-03-17T12:50:54.621821Z net thread exit
    2025-03-17T12:50:54.621884Z Shutdown: In progress...
    2025-03-17T12:50:54.621911Z [rpc] Stopping HTTP RPC server
    2025-03-17T12:50:54.621924Z [rpc] Stopping RPC
    2025-03-17T12:50:54.622223Z [rpc] RPC stopped.
    2025-03-17T12:50:54.657464Z sv2 thread exit
    2025-03-17T12:50:54.717192Z msghand thread exit
    2025-03-17T12:50:54.723247Z DumpAnchors: Flush 0 outbound block-relay-only peer addresses to anchors.dat started
    2025-03-17T12:50:54.728015Z DumpAnchors: Flush 0 outbound block-relay-only peer addresses to anchors.dat completed (0.00s)
    2025-03-17T12:50:54.728044Z scheduler thread exit
    2025-03-17T12:50:54.744800Z net thread exit
    2025-03-17T12:50:54.744951Z Writing 0 mempool transactions to file...
    2025-03-17T12:50:54.744964Z Writing 0 unbroadcast transactions to file.
    2025-03-17T12:50:54.749120Z Dumped mempool: 0.000s to copy, 0.004s to dump, 27 bytes dumped to file
    2025-03-17T12:50:54.750367Z Flushed fee estimates to fee_estimates.dat.
    2025-03-17T12:50:54.800537Z [default] Releasing wallet default..
    2025-03-17T12:50:54.803267Z Shutdown: done
    
  3. Sjors commented on Mar 17, 2025

    @Sjors
    Owner

    Ah interesting, so we're hanging up too quickly:

    Send 0x02 SetupConnectionError to client id=0
    

    That message never makes it.

    @vasild any idea?

  4. changed the title [-]TP doesn't reply with `SetupConnection.Error` when presented with an unsupported protocol request[/-] [+]TP hangs up too quickly (before fully sending `SetupConnection.Error`)[/+] on Mar 17, 2025
  5. vasild commented on Mar 19, 2025

    @vasild

    The code is queuing the message for sending in Sv2Client::m_send_messages and then closes the socket immediately after that, before actually sending the queued message. What about closing the connection only if the send queue is empty? Untested:

    diff --git i/src/sv2/connman.cpp w/src/sv2/connman.cpp
    index 14abe763ed..f679348b05 100644
    --- i/src/sv2/connman.cpp
    +++ w/src/sv2/connman.cpp
    @@ -16,13 +16,12 @@ Sv2Connman::~Sv2Connman()
     
         {
             LOCK(m_clients_mutex);
             for (const auto& client : m_sv2_clients) {
                 LogTrace(BCLog::SV2, "Disconnecting client id=%zu\n",
                         client.first);
    -            CloseConnection(client.second->m_id);
                 client.second->m_disconnect_flag = true;
             }
             DisconnectFlagged();
         }
     
         Interrupt();
    @@ -61,13 +60,14 @@ void Sv2Connman::DisconnectFlagged()
     {
         AssertLockHeld(m_clients_mutex);
     
         // Remove clients that are flagged for disconnection.
         auto it = m_sv2_clients.begin();
         while(it != m_sv2_clients.end()) {
    -        if (it->second->m_disconnect_flag) {
    +        if (it->second->m_send_messages.empty() && it->second->m_disconnect_flag) {
    +            CloseConnection(it->second->m_id);
                 it = m_sv2_clients.erase(it);
             } else {
                 it++;
             }
         }
     }
    @@ -205,13 +205,12 @@ void Sv2Connman::EventGotData(Id id, std::span<const uint8_t> _data)
             while (data.size() > 0) {
                 // absorb network data
                 if (!client->m_transport->ReceivedBytes(data)) {
                     // Serious transport problem
                     LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Transport problem, disconnecting client id=%zu\n",
                                     client->m_id);
    -                CloseConnection(id);
                     // TODO: should we even bother with this?
                     client->m_disconnect_flag = true;
                     break;
                 }
     
                 if (client->m_transport->ReceivedMessageComplete()) {
    @@ -219,31 +218,28 @@ void Sv2Connman::EventGotData(Id id, std::span<const uint8_t> _data)
                     Sv2NetMsg msg = client->m_transport->GetReceivedMessage(std::chrono::milliseconds(0), dummy_reject_message);
                     ProcessSv2Message(msg, *client.get());
                 }
             }
         } catch (const std::exception& e) {
             LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received error when processing client id=%zu message: %s\n", client->m_id, e.what());
    -        CloseConnection(id);
             client->m_disconnect_flag = true;
         }
     
     }
     
     void Sv2Connman::EventGotEOF(NodeId node_id)
     {
         auto client{WITH_LOCK(m_clients_mutex, return GetClientById(node_id);)};
         if (client == nullptr) return;
    -    CloseConnection(node_id);
         client->m_disconnect_flag = true;
     }
     
     void Sv2Connman::EventGotPermanentReadError(NodeId node_id, const std::string& errmsg)
     {
         auto client{WITH_LOCK(m_clients_mutex, return GetClientById(node_id);)};
         if (client == nullptr) return;
    -    CloseConnection(node_id);
         client->m_disconnect_flag = true;
     }
     
     void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& client)
     {
         uint8_t msg_type[1] = {uint8_t(sv2_net_msg.m_msg_type)};
    @@ -252,12 +248,19 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
                        // std::format("{:x}", uint8_t(sv2_net_msg.m_msg_type)),
                        HexStr(msg_type),
                        node::SV2_MSG_NAMES.at(sv2_net_msg.m_msg_type), client.m_id);
     
         DataStream ss (sv2_net_msg.m_msg);
     
    +    if (client.m_disconnect_flag) {
    +        // Don't bother processing new messages if we are about to disconnect when the
    +        // send queue empties. This also prevents us from appending to the send queue
    +        // when m_disconnect_flag is set.
    +        return;
    +    }
    +
         switch (sv2_net_msg.m_msg_type)
         {
         case Sv2MsgType::SETUP_CONNECTION:
         {
             if (client.m_setup_connection_confirmed) {
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Client client id=%zu connection has already been confirmed\n",
    @@ -268,26 +271,24 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
             node::Sv2SetupConnectionMsg setup_conn;
             try {
                 ss >> setup_conn;
             } catch (const std::exception& e) {
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received invalid SetupConnection message from client id=%zu: %s\n",
                               client.m_id, e.what());
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             // Disconnect a client that connects on the wrong subprotocol.
             if (setup_conn.m_protocol != m_subprotocol) {
                 node::Sv2SetupConnectionErrorMsg setup_conn_err{setup_conn.m_flags, std::string{"unsupported-protocol"}};
     
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Send 0x02 SetupConnectionError to client id=%zu\n",
                               client.m_id);
                 client.m_send_messages.emplace_back(setup_conn_err);
     
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             // Disconnect a client if they are not running a compatible protocol version.
             if ((m_protocol_version < setup_conn.m_min_version) || (m_protocol_version > setup_conn.m_max_version)) {
    @@ -295,13 +296,12 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Send 0x02 SetupConnection.Error to client id=%zu\n",
                               client.m_id);
                 client.m_send_messages.emplace_back(setup_conn_err);
     
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received a connection from client id=%zu with incompatible protocol_versions: min_version: %d, max_version: %d\n",
                               client.m_id, setup_conn.m_min_version, setup_conn.m_max_version);
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Send 0x01 SetupConnection.Success to client id=%zu\n",
                           client.m_id);
    @@ -312,36 +312,33 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie
     
             break;
         }
         case Sv2MsgType::COINBASE_OUTPUT_CONSTRAINTS:
         {
             if (!client.m_setup_connection_confirmed) {
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             node::Sv2CoinbaseOutputConstraintsMsg coinbase_output_constraints;
             try {
                 ss >> coinbase_output_constraints;
                 client.m_coinbase_output_constraints_recv = true;
             } catch (const std::exception& e) {
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received invalid CoinbaseOutputConstraints message from client id=%zu: %s\n",
                               client.m_id, e.what());
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             uint32_t max_additional_size = coinbase_output_constraints.m_coinbase_output_max_additional_size;
             LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "coinbase_output_max_additional_size=%d bytes\n", max_additional_size);
     
             if (max_additional_size > MAX_BLOCK_WEIGHT) {
                 LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received impossible CoinbaseOutputConstraints from client id=%zu: %d\n",
                               client.m_id, max_additional_size);
    -            CloseConnection(client.m_id);
                 client.m_disconnect_flag = true;
                 return;
             }
     
             client.m_coinbase_tx_outputs_size = coinbase_output_constraints.m_coinbase_output_max_additional_size;
     
    diff --git i/src/sv2/connman.h w/src/sv2/connman.h
    index 842843bff3..a661cf5edc 100644
    --- i/src/sv2/connman.h
    +++ w/src/sv2/connman.h
    @@ -34,13 +34,14 @@ struct Sv2Client
         /**
          * Whether the client has confirmed the connection with a successful SetupConnection.
          */
         bool m_setup_connection_confirmed = false;
     
         /**
    -     * Whether the client is a candidate for disconnection.
    +     * Whether the client is a candidate for disconnection. The client's socket will be
    +     * closed after all queued messages have been sent.
          */
         bool m_disconnect_flag = false;
     
         /** Queue of messages to be sent */
         std::deque<Sv2NetMsg> m_send_messages;
     
  6. Sjors commented on Mar 19, 2025

    @Sjors
    Owner

    That seems reasonable, thanks! Will try.

  7. Sjors commented on Mar 20, 2025

    @Sjors
    Owner

    @plebhash I added the above potential fix to the sv2 branch, can you try it?

    If it doesn't help, please let me know how to reproduce the integration test.

  8. plebhash commented on Mar 20, 2025

    @plebhash
    Author

    @plebhash I added the above potential fix to the sv2 branch, can you try it?

    If it doesn't help, please let me know how to reproduce the integration test.

    same behavior

    in order to reproduce with integration tests, do the following:

    • clone a fresh https://github.com/stratum-mining/stratum
    • cd test/integration-tests
    • run whatever test to initialize the template-provider directory, e.g.: cargo t success_pool_template_provider_connection
    • replace template-provider/bitcoin-sv2-tp-0.1.13/bin/bitcoind with the binary you want to test
    • add a new file tests/debug.rs
    • paste the code from the original issue description into tests/debug.rs
    • run the test cargo t debug_test -- --nocapture

    the wait_for_message_type has a timeout of 1 minute, and here's what you will see in the logs:

    running 1 test
    2025-03-20T17:16:18.505998Z  INFO pool_sv2::mining_pool: PUB KEY: Ok([TxOut { value: 0 SAT, script_pubkey: Script(OP_0 OP_PUSHBYTES_20 ebe1b7dcc293ccaa0ee743a86f89df8258c208fc) }])
    2025-03-20T17:16:18.506059Z  INFO pool_sv2::mining_pool: Starting up Pool server
    2025-03-20T17:16:18.506094Z  INFO pool_sv2::mining_pool: Pool is running on: 127.0.0.1:56671
    2025-03-20T17:16:18.506269Z  INFO pool_sv2::template_receiver: Connected to template distribution server at 127.0.0.1:56670
    2025-03-20T17:16:18.513024Z  INFO integration_tests_sv2::sniffer: 🔍 Sniffer A | Replaced: SetupConnection with SetupConnection | Direction: ⬆
    2025-03-20T17:16:18.513150Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:56664
    2025-03-20T17:16:18.513178Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:56672
    2025-03-20T17:16:18.513187Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:56664
    2025-03-20T17:16:18.513199Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:56670
    2025-03-20T17:16:18.513240Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:56670
    2025-03-20T17:16:18.513271Z ERROR pool_sv2: SHUTDOWN from Downstream: Component shutdown: "Downstream no longer accepting new prevhash"
    Try to restart the downstream listener
    2025-03-20T17:16:18.513287Z  INFO pool_sv2::mining_pool: Pool is stopping the server after stop shutdown signal received
    2025-03-20T17:16:18.513319Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:56672
    response from TP None
    test debug_test has been running for over 60 seconds
    thread 'debug_test' panicked at /Users/plebhash/develop/stratum/test/integration-tests/lib/sniffer.rs:561:17:
    Timeout waiting for message type
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    test debug_test ... FAILED
    
    failures:
    
    failures:
        debug_test
    
    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 64.56s
    
    error: test failed, to rerun pass `--test debug`
    

    ideally, the test should exit gracefully without hitting the 60s timeout, and the println! should have Some and not None

  9. Sjors commented on Mar 20, 2025

    @Sjors
    Owner

    Where does cargo t get the TP from?

    Note that there was a recent build system change in Bitcoin Core, so the binary is going to be in build/bin/bitcoind, not in build/src/bitcoind. Make sure there's no dangling old version there.

  10. Sjors commented on Mar 20, 2025

    @Sjors
    Owner

    The test fails after a minute, but it did receive "SetupConnectionError with error code unsupported-protocol":

    running 1 test
    2025-03-20T18:13:05.007662Z  INFO pool_sv2::mining_pool: PUB KEY: Ok([TxOut { value: 0 SAT, script_pubkey: Script(OP_0 OP_PUSHBYTES_20 ebe1b7dcc293ccaa0ee743a86f89df8258c208fc) }])
    2025-03-20T18:13:05.007770Z  INFO pool_sv2::mining_pool: Starting up Pool server
    2025-03-20T18:13:05.007839Z  INFO pool_sv2::mining_pool: Pool is running on: 127.0.0.1:51264
    2025-03-20T18:13:05.009037Z  INFO pool_sv2::template_receiver: Connected to template distribution server at 127.0.0.1:51263
    2025-03-20T18:13:05.020550Z  INFO integration_tests_sv2::sniffer: 🔍 Sniffer A | Replaced: SetupConnection with SetupConnection | Direction: ⬆
    2025-03-20T18:13:05.020830Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:51257
    2025-03-20T18:13:05.020868Z  INFO integration_tests_sv2::sniffer: 🔍 Sniffer A | Forwarded: SetupConnectionError | Direction: ⬇
    2025-03-20T18:13:05.020913Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:51265
    2025-03-20T18:13:05.020922Z ERROR network_helpers_sv2::noise_connection: Disconnecting from client due to error receiving: receiving from an empty and closed channel - 127.0.0.1:51257
    2025-03-20T18:13:05.020959Z ERROR network_helpers_sv2::noise_connection: Disconnected from client while reading : early eof - 127.0.0.1:51263
    2025-03-20T18:13:05.020990Z ERROR roles_logic_sv2::handlers::common: Received SetupConnectionError with error code unsupported-protocol
    2025-03-20T18:13:05.021144Z ERROR pool_sv2: SHUTDOWN from Upstream: Channel recv failed: `RecvError`
    Try to reconnecting or connecting to a new upstream
    2025-03-20T18:13:05.021159Z  INFO pool_sv2::mining_pool: Pool is stopping the server after stop shutdown signal received
    2025-03-20T18:13:05.021206Z ERROR network_helpers_sv2::noise_connection: Shutting down noise stream reader!
    response from TP Some((2, Common(SetupConnectionError(SetupConnectionError { flags: 0, error_code: Owned([117, 110, 115, 117, 112, 112, 111, 114, 116, 101, 100, 45, 112, 114, 111, 116, 111, 99, 111, 108]) }))))
    
    test debug_test has been running for over 60 seconds
    thread 'debug_test' panicked at /Users/sjors/dev/stratum/test/integration-tests/lib/sniffer.rs:561:17:
    Timeout waiting for message type
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    test debug_test ... FAILED
    
    failures:
    
    failures:
        debug_test
    
    test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 63.83s
    
    error: test failed, to rerun pass `--test debug`
    
  11. plebhash commented on Mar 20, 2025

    @plebhash
    Author

    Where does cargo t get the TP from?

    It fetches it from https://github.com/Sjors/bitcoin/releases. Currently it's pointing to v0.1.13 but we're about to merge a PR that points to v0.1.15.

    Note that there was a recent build system change in Bitcoin Core, so the binary is going to be in build/bin/bitcoind, not in build/src/bitcoind. Make sure there's no dangling old version there.

    That was my mistake when testing your changes. Sorry for that. I was basically using an old build.

    The test fails after a minute, but it did receive "SetupConnectionError with error code unsupported-protocol":

    That's just because the test is poorly structured, that was my bad.

    Essentially next_message_from_upstream pops the message from the queue where it's stored, and then wait_for_message_type cannot find it. If we switch the order of these two lines the timeout goes away.

    Anyways, the problem has been solved. Thanks and apologies for the confusion!

  12. Sjors commented on Mar 20, 2025

    @Sjors
    Owner

    Nice! 🎉

    This doesn't seem like a big enough bug to warrant a fresh release, but I'll probably bake one next week - waiting for some more goodies to be merged into Bitcoin Core, so my rebase hell is lighter.

  13. added a commit that references this issue on Apr 8, 2025
    dc0f901
  14. added a commit that references this issue on Jul 29, 2025
  15. added a commit that references this issue on Dec 29, 2025
  16. added a commit that references this issue on May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions