Skip to content

fix: add regtest hrp for segwit bitcoin address #6373

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

fdefelici
Copy link
Contributor

@fdefelici fdefelici commented Aug 12, 2025

Description

This PR allows BitcoinAddress to manage segwit addresses for regtest (hrp = "bcrt").

The following apis, now works nicely with regtest hrp:

  • SegwitBitcoinAddress::from_bech32(..)
  • BitcoinAddress::from_string(..)

Applicable issues

Additional info (benefits, drawbacks, caveats)

Convert from Option to Result?

LegacyBitcoinAddress::from_b58(str) already use Result.
Possibly, we could then propagate Result to Address::from_string()

pub fn from_bech32(s: &str) -> Option<SegwitBitcoinAddress> {
let (hrp, quintets, variant) = bech32::decode(s)
.inspect_err(|_e| {
test_debug!("Failed to decode '{s}': {_e:?}");
})
.ok()?;

PoxAddress related

Current patch is applying a fallback that convert back and forth: is_mainnet (bool) <=> NetworkType

pub fn to_b58(self) -> String {
match self {
PoxAddress::Standard(addr, _) => addr.to_b58(),
PoxAddress::Addr20(mainnet, addrtype, addrbytes) => match addrtype {
PoxAddressType20::P2WPKH => {
let btc_addr = SegwitBitcoinAddress::P2WPKH(mainnet, addrbytes);
btc_addr.to_bech32()
}
},
PoxAddress::Addr32(mainnet, addrtype, addrbytes) => match addrtype {
PoxAddressType32::P2WSH => {
let btc_addr = SegwitBitcoinAddress::P2WSH(mainnet, addrbytes);
btc_addr.to_bech32()
}
PoxAddressType32::P2TR => {
let btc_addr = SegwitBitcoinAddress::P2TR(mainnet, addrbytes);
btc_addr.to_bech32()
}
},
}
}

pub fn try_from_bitcoin_output(o: &BitcoinTxOutput) -> Option<PoxAddress> {
match &o.address {
BitcoinAddress::Legacy(ref legacy_addr) => {
let addr = StacksAddress::from_legacy_bitcoin_address(legacy_addr);
let pox_addr = PoxAddress::Standard(addr, None);
Some(pox_addr)
}
BitcoinAddress::Segwit(SegwitBitcoinAddress::P2WPKH(is_mainnet, bytes_20)) => Some(
PoxAddress::Addr20(*is_mainnet, PoxAddressType20::P2WPKH, *bytes_20),
),
BitcoinAddress::Segwit(SegwitBitcoinAddress::P2WSH(is_mainnet, bytes_32)) => Some(
PoxAddress::Addr32(*is_mainnet, PoxAddressType32::P2WSH, *bytes_32),
),
BitcoinAddress::Segwit(SegwitBitcoinAddress::P2TR(is_mainnet, bytes_32)) => Some(
PoxAddress::Addr32(*is_mainnet, PoxAddressType32::P2TR, *bytes_32),
),
}
}

Checklist

  • Test coverage for new or modified code paths
  • Changelog is updated
  • Required documentation changes (e.g., docs/rpc/openapi.yaml and rpc-endpoints.md for v2 endpoints, event-dispatcher.md for new events)
  • New clarity functions have corresponding PR in clarity-benchmarking repo
  • New integration test(s) added to bitcoin-tests.yml

@fdefelici fdefelici self-assigned this Aug 12, 2025
@fdefelici fdefelici changed the title fix: add regtest hrp for segwit bitcoin address, fix: add regtest hrp for segwit bitcoin address Aug 12, 2025
@jcnelson
Copy link
Member

I think this is fine for now.

LegacyBitcoinAddress::from_b58(str) already use Result.
Possibly, we could then propagate Result to Address::from_string()

The reason we don't is because there's not much the client can do based on the decoding error. A string either decodes to a LegacyBitcoinAddress, or it doesn't. If it doesn't, then the fundamental reason is that the string is incorrect.

In curreny patch applying a fallback that convert back and forth: is_mainnet (bool) <=> NetworkType

That's okay. For now, the focus is on getting regtest HRP support for BitcoinAddress in order to unblock progress on the new Bitcoin RPC client. Considerations for altering PoxAddress can wait until the bitcoin_regtest_controller.rs file is refactored, since there will need to be a way to convert PoxAddress (which the node uses internally to represent Bitcoin addresses that receive PoX payouts) to and from BitcoinAddress.

@fdefelici fdefelici force-pushed the fix/bitcoin-address-regtest-hrp branch from 457ec9e to 76bd51a Compare August 13, 2025 09:20
@fdefelici
Copy link
Contributor Author

LegacyBitcoinAddress::from_b58(str) already use Result.
Possibly, we could then propagate Result to Address::from_string()

The reason we don't is because there's not much the client can do based on the decoding error. A string either decodes to a LegacyBitcoinAddress, or it doesn't. If it doesn't, then the fundamental reason is that the string is incorrect.

Got it.

I was just asking because it could be useful to have an error message in case deserialization of addresses fails in the new RPC Client. Just In case, I have the patch ready for this (not pushed yet)

That said, I’m also fine with keeping the current implementation as-is.

@fdefelici fdefelici marked this pull request as ready for review August 13, 2025 10:33
@fdefelici fdefelici requested review from a team as code owners August 13, 2025 10:33
@aldur aldur added this to the 3.2.0.0.1 milestone Aug 13, 2025
@aldur aldur moved this to Status: In Review in Stacks Core Eng Aug 13, 2025
@aldur aldur requested a review from Jiloc August 13, 2025 14:54
@aldur aldur linked an issue Aug 13, 2025 that may be closed by this pull request
Copy link
Member

@jcnelson jcnelson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@Jiloc Jiloc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

@fdefelici fdefelici added this pull request to the merge queue Aug 14, 2025
Merged via the queue into stacks-network:develop with commit 495fe91 Aug 14, 2025
262 of 263 checks passed
@fdefelici fdefelici deleted the fix/bitcoin-address-regtest-hrp branch August 14, 2025 10:18
@github-project-automation github-project-automation bot moved this from Status: In Review to Status: ✅ Done in Stacks Core Eng Aug 14, 2025
Copy link

codecov bot commented Aug 14, 2025

Codecov Report

❌ Patch coverage is 89.26554% with 19 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.23%. Comparing base (a9e2828) to head (76bd51a).
⚠️ Report is 4 commits behind head on develop.

Files with missing lines Patch % Lines
stackslib/src/burnchains/bitcoin/address.rs 91.83% 12 Missing ⚠️
...ackslib/src/chainstate/burn/operations/test/mod.rs 0.00% 4 Missing ⚠️
stackslib/src/burnchains/bitcoin/bits.rs 25.00% 3 Missing ⚠️

❌ Your project status has failed because the head coverage (76.23%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff              @@
##           develop    #6373       +/-   ##
============================================
+ Coverage    62.44%   76.23%   +13.78%     
============================================
  Files          552      552               
  Lines       351797   351925      +128     
============================================
+ Hits        219676   268277    +48601     
+ Misses      132121    83648    -48473     
Files with missing lines Coverage Δ
stackslib/src/burnchains/bitcoin/mod.rs 38.55% <100.00%> (+7.78%) ⬆️
stackslib/src/chainstate/stacks/address.rs 95.06% <100.00%> (+46.13%) ⬆️
stackslib/src/burnchains/bitcoin/bits.rs 81.07% <25.00%> (+26.50%) ⬆️
...ackslib/src/chainstate/burn/operations/test/mod.rs 0.00% <0.00%> (-72.50%) ⬇️
stackslib/src/burnchains/bitcoin/address.rs 86.01% <91.83%> (+24.25%) ⬆️

... and 379 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a9e2828...76bd51a. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Allow BitcoinAddress to represent addresses with Regtest HRP prefix
4 participants