Skip to content

Translator panics on share submission when user_identity is a Bitcoin address #295

@warioishere

Description

@warioishere

Bug Report

Description

The translator (tproxy) panics with the following error as soon as a connected SV1 miner submits a share, when user_identity in the config is a Bitcoin address:

thread 'tokio-runtime-worker' panicked at miner-apps/translator/src/lib/sv1/sv1_server/sv1_server.rs:461:18:
called `Result::unwrap()` on an `Err` value: "UserIdentity exceeds 32 bytes"

Root Cause

When a SV1 miner connects, the translator constructs a per-miner identity string (sv1_server.rs:718):

let user_identity = format!("{}.miner{}", self.config.user_identity, miner_id);

On every share submission, the translator attempts to attach a UserIdentity TLV (Worker-Specific Hashrate Tracking extension 0x0002) to the SubmitSharesExtended message (sv1_server.rs:460-461):

UserIdentity::new(&user_identity_string)
    .unwrap()  // panics here

UserIdentity in extensions-sv2 has a hard limit of MAX_USER_IDENTITY_LENGTH = 32 bytes. Bitcoin addresses are up to 64 bytes (e.g. regtest taproot bcrt1p...), which immediately exceeds this limit.

Use Case / Motivation

We are running an SV2 server in solo mining mode where the server parses the user_identity field from OpenExtendedMiningChannel and substitutes the pool's coinbase Bitcoin address with the address provided in user_identity. This allows each miner/operator to receive block rewards directly to their own address.

This approach already works correctly for the JD-client: it passes the Bitcoin address via OpenExtendedMiningChannel.user_identity (typed as Str0255, 255-byte limit — no problem), and does not create a UserIdentity TLV on share submissions (there is even a TODO comment at jd-client/src/lib/channel_manager/downstream_message_handler.rs:1306 acknowledging this is not yet implemented).

The translator, however, unconditionally creates the TLV on every share, causing the crash.

Affected Versions

  • translator_sv2 — crashes on first share when user_identity length > 32 bytes
  • jd-client — works correctly today (no TLV on shares, address passed via Str0255)

Proposed Quick Fix

Make the UserIdentity TLV on share submissions opt-in via a config flag, defaulting to false (disabled), matching current JD-client behaviour:

# Attach worker identity TLV to share submissions for per-worker hashrate tracking.
# Requires upstream to support extension 0x0002.
# Note: user_identity must be <= 32 bytes when enabled.
enable_worker_identity_tlv = false

In sv1_server.rs, replace:

// Only add TLV fields with user identity in non-aggregated mode
let tlv_fields = if is_non_aggregated() {
    let user_identity_string = ...;
    UserIdentity::new(&user_identity_string)
        .unwrap()   // <-- panics
        .to_tlv()
        .ok()
        .map(|tlv| vec![tlv])
} else {
    None
};

With:

let tlv_fields = if self.config.enable_worker_identity_tlv {
    let user_identity_string = ...;
    UserIdentity::new(&user_identity_string)
        .ok()
        .and_then(|ui| ui.to_tlv().ok())
        .map(|tlv| vec![tlv])
} else {
    None
};

Longer-Term Issue

The 32-byte limit in extensions-sv2 (MAX_USER_IDENTITY_LENGTH) and parsers-sv2 (tlv_extensions/mod.rs) is incompatible with Bitcoin addresses being used as worker identities. Bitcoin addresses range up to 64 bytes (regtest bech32m taproot). This limit likely needs to be revisited at the spec level (EXTENSION_TYPE=0x0002) to support address-based identity for a possible solomining mode,, but that is a separate discussion.

Steps to Reproduce

  1. Set user_identity in the translator config to any Bitcoin address (e.g. bcrt1qqz93nn9k2r08mallruhgfy8f7xfkkkge93chf5)
  2. Connect a SV1 miner to the translator
  3. Wait for the miner to submit a share
  4. Translator panics

Expected Behaviour

The translator should not crash. If the UserIdentity TLV cannot be constructed (e.g. identity too long), it should either skip the TLV gracefully or be disabled via config.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions