Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
068c3f2
Fix `is_invalid_use_of_sighash_single()` incompatibility with Bitcoin…
liuchengxu Feb 24, 2025
18c2cad
Add test for sighash_single_bug incompatility fix
liuchengxu Feb 24, 2025
2c97c79
Merge rust-bitcoin/rust-bitcoin#4122: backport: Fix `is_invalid_use_o…
apoelstra Feb 28, 2025
39e280a
Fix key/script spend detection in `Witness`
Kixunil Feb 21, 2025
74138d5
Add a test case checking `taproot_control_block`
Kixunil Feb 21, 2025
730baeb
Add `taproot_leaf_script` methood to `Witness`
Kixunil Feb 21, 2025
9e87bc5
Deprecate the `Witness::tapscript` method
Kixunil Feb 21, 2025
30fbc0f
Merge rust-bitcoin/rust-bitcoin#4101: Backport witness fixes
apoelstra Mar 9, 2025
315750d
bip32: return error when attempting to derive past maximum depth
apoelstra May 3, 2025
b75b2e3
Fix GetKey for sets to properly compare the fingerprint
shesek Sep 13, 2024
d005ddd
Refactor GetKey for sets to internally use Xpriv::get_key()
shesek Sep 13, 2024
d8a6b9f
Merge rust-bitcoin/rust-bitcoin#4434: [backport 0.32.x] bip32: return…
apoelstra May 5, 2025
2858b6c
Support GetKey where the Xpriv is a direct child of the looked up Key…
shesek Sep 13, 2024
95eb255
Add XOnlyPublicKey support for PSBT key retrieval and improve Taproot…
erickcestari Mar 14, 2025
c67adcd
backport: Add methods to retrieve inner types
shinghim Apr 20, 2025
f4fac15
Merge rust-bitcoin/rust-bitcoin#4450: backport: Add methods to retrie…
apoelstra May 7, 2025
2044697
Merge rust-bitcoin/rust-bitcoin#4443: backport: Add XOnlyPublicKey su…
apoelstra May 8, 2025
916982a
bitcoin: Bump version to 0.32.6
tcharding May 5, 2025
7ff26ac
Merge rust-bitcoin/rust-bitcoin#4453: Release tracking PR: `bitcoin 0…
apoelstra May 13, 2025
c7b20f4
backport: Use _u32 in FeeRate constructor instead of _unchecked
tcharding May 24, 2025
944feb9
Merge rust-bitcoin/rust-bitcoin#4552: backport: Use _u32 in FeeRate c…
apoelstra May 24, 2025
c2481e4
backport: Add support for pay to anchor outputs
tcharding Jul 8, 2025
d31d17e
Merge rust-bitcoin/rust-bitcoin#4691: backport: Add support for pay t…
apoelstra Jul 16, 2025
3cf4a91
Remove non_exhausive from Network
tcharding Jul 1, 2025
db7a238
Merge rust-bitcoin/rust-bitcoin#4658: backport to `v0.32`: Remove `no…
apoelstra Jul 28, 2025
571cd7f
bitcoin: Bump version to 0.32.7
tcharding Jul 30, 2025
8aec240
Merge rust-bitcoin/rust-bitcoin#4740: Release tracking PR: `bitcoin 0…
apoelstra Aug 4, 2025
17a4241
chore(workflow): update labeler workflow to use doge-master instead o…
mducroux May 26, 2025
2c3f453
chore(workflow): update labeler permissions to allow writing issues
mducroux May 26, 2025
22dc185
chore(dogecoin): set up crate
mducroux May 23, 2025
d812d42
feat(dogecoin): add dogecoin AuxPow and Block
mducroux May 23, 2025
c463c5b
feat(dogecoin): add module documentation and update AuxPow struct
mducroux May 23, 2025
9a1c94f
add prelude import
mducroux May 23, 2025
91b5c2b
update lock file
mducroux May 23, 2025
e44902c
Revert "update lock file"
mducroux May 23, 2025
790dcf0
run formatter in nightly mode
mducroux May 26, 2025
8f6dcdb
update lock files
mducroux May 26, 2025
8af5eaf
update doc
mducroux May 26, 2025
0549e83
Revert "add write permission to labeller for issues"
mducroux May 26, 2025
6d91df4
Revert "run formatter in nightly mode"
mducroux May 26, 2025
081989f
update workflows to include doge-master branch
mducroux May 26, 2025
a6163fb
update labeler configuration to include base-branch for doge-master
mducroux May 26, 2025
8b2e592
Revert "update labeler configuration to include base-branch for doge-…
mducroux May 26, 2025
96dd33a
Reapply "add write permission to labeller for issues"
mducroux May 26, 2025
28571b3
feature(dogecoin): add scrypt PoW validation
mducroux May 28, 2025
8190978
remove leftover test
mducroux May 28, 2025
33cf462
update lock files
mducroux May 28, 2025
9cf9d93
chore(license): add Apache-2.0 license (#4)
mducroux Jun 10, 2025
afd98dc
feat(dogecoin): add dogecoin consensus and genesis parameters (#3)
mducroux Jun 11, 2025
0b182fb
feat: Add more methods to the dogecoin network type (#7)
ninegua Jun 11, 2025
762f8af
feat(dogecoin): add difficulty adjustment algorithm for blocks 0-5,00…
mducroux Jun 12, 2025
ee2493a
feat: Dogecoin specific address type (#5)
ninegua Jun 12, 2025
8cd380f
feat: Support dogecoin in p2p messages (#6)
ninegua Jun 13, 2025
90ac9b9
feat(pow): add difficulty calculation for pre-digishield blocks (5,00…
mducroux Jul 15, 2025
6849413
refactor(params): simpler and more consistent Dogecoin params (#12)
mducroux Jul 21, 2025
5d203f9
feat(pow): add digishield difficulty adjustment algorithm (#13)
mducroux Aug 4, 2025
363471f
feat: pass p2p protocol version explicitly (#10)
ninegua Aug 4, 2025
ae548e7
feat: add auxpow validation (#14)
mducroux Aug 27, 2025
a47e2d2
feat: make Header a parameter of NetworkMessage (#16)
ninegua Sep 4, 2025
d275ae7
test: add additional tests adapted from core's dogecoin_tests.cpp (#15)
mducroux Sep 5, 2025
556c95e
chore: update README.md (#17)
mducroux Nov 3, 2025
df5bb2c
chore: add changelog v0.32.5-doge.0 and rust dogecoin logo (#18)
mducroux Nov 7, 2025
cf61b2b
docs: fix docs.rs build (#19)
mducroux Nov 18, 2025
6cd908d
Merge branch 'doge-master' into mducroux/doge-0.32.7
mducroux Dec 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 30 additions & 21 deletions bitcoin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
All notable changes to this project will be documented in this file.
# 0.32.7 - 2025-07-30

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- Backport - Use `_u32` in `FeeRate` constructor instead of `_unchecked` [#4552](https://github.com/rust-bitcoin/rust-bitcoin/pull/4552)
- Backport - Add support for pay to anchor outputs [#4691](https://github.com/rust-bitcoin/rust-bitcoin/pull/4691)
- Backport - Remove `non_exhaustive` from `Network` [#4658](https://github.com/rust-bitcoin/rust-bitcoin/pull/4658)

# 0.32.6 - 2025-05-06

- Backport - Fix `is_invalid_use_of_sighash_single()` incompatibility with Bitcoin Core [#4122](https://github.com/rust-bitcoin/rust-bitcoin/pull/4122)
- Backport - Backport witness fixes [#4101](https://github.com/rust-bitcoin/rust-bitcoin/pull/4101)
- Backport - bip32: Return error when attempting to derive past maximum depth [#4434](https://github.com/rust-bitcoin/rust-bitcoin/pull/4434)
- Backport - Add `XOnlyPublicKey` support for PSBT key retrieval and improve Taproot signing [#4443](https://github.com/rust-bitcoin/rust-bitcoin/pull/4443)
- Backport - Add methods to retrieve inner types [#4450](https://github.com/rust-bitcoin/rust-bitcoin/pull/4450)

# 0.32.5-doge.1 - 2025-11-10

Expand All @@ -16,38 +25,38 @@ Initial release of the rust-dogecoin crate, a fork of rust-bitcoin adapted for D

- **Scrypt Proof-of-Work**: Add scrypt-based PoW validation (`block_hash_with_scrypt()` and `validate_pow_with_scrypt()`) to support Dogecoin's PoW algorithm.
- **Difficulty Adjustment Algorithms**:
- Pre-Digishield algorithm (blocks 0-144,999) with variable transition thresholds based on block height ranges
- Digishield algorithm (blocks 145,000+)
- Methods `min_transition_threshold_dogecoin()` and `max_transition_threshold_dogecoin()`
- Pre-Digishield algorithm (blocks 0-144,999) with variable transition thresholds based on block height ranges
- Digishield algorithm (blocks 145,000+)
- Methods `min_transition_threshold_dogecoin()` and `max_transition_threshold_dogecoin()`
- **Generic Network Messages**: Make `RawNetworkMessage` and `NetworkMessage` generic over `Header` and `Block` types to support AuxPoW blocks
- Updated license to Apache-2.0 for new Dogecoin-specific code

### New Dogecoin module (`bitcoin/src/dogecoin/`)

- **Core Types** (`mod.rs`):
- `Header`: Dogecoin block header with optional AuxPoW data
- `Block`: Block structure supporting both legacy and AuxPoW blocks
- `Network`: Dogecoin mainnet, Testnet, Regtest
- Helper methods for AuxPoW bit detection, chain ID extraction, and legacy block identification
- `Header`: Dogecoin block header with optional AuxPoW data
- `Block`: Block structure supporting both legacy and AuxPoW blocks
- `Network`: Dogecoin mainnet, Testnet, Regtest
- Helper methods for AuxPoW bit detection, chain ID extraction, and legacy block identification

- **AuxPoW Support** (`auxpow.rs`):
- AuxPow validation (coinbase script validation, merkle branch verification, chain ID checks)
- Error types for AuxPow validation failures
- AuxPow validation (coinbase script validation, merkle branch verification, chain ID checks)
- Error types for AuxPow validation failures

- **Consensus Parameters** (`params.rs`):
- Dogecoin PoW parameters and methods: target spacing, max attainable target, pow target timespan
- Digishield and AuxPoW activation height
- Chain ID for merged mining
- BIP activation heights
- Dogecoin PoW parameters and methods: target spacing, max attainable target, pow target timespan
- Digishield and AuxPoW activation height
- Chain ID for merged mining
- BIP activation heights

- **Constants** (`constants.rs`):
- Genesis block definitions for mainnet, testnet, and regtest
- Prefixes for P2PKH and P2SH addresses
- Genesis block definitions for mainnet, testnet, and regtest
- Prefixes for P2PKH and P2SH addresses

- **Address Handling** (`address/`):
- Base58 address encoding/decoding with Dogecoin-specific prefixes
- Support for P2PKH and P2SH address types
- Network validation and address parsing
- Base58 address encoding/decoding with Dogecoin-specific prefixes
- Support for P2PKH and P2SH address types
- Network validation and address parsing

# 0.32.5 - 2024-11-27

Expand Down
2 changes: 1 addition & 1 deletion bitcoin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ required-features = ["std", "rand-std", "bitcoinconsensus"]
name = "sighash"

[lints.rust]
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(fuzzing)', 'cfg(kani)', 'cfg(mutate)', 'cfg(rust_v_1_60)'] }
unexpected_cfgs = { level = "deny", check-cfg = ['cfg(bench)', 'cfg(fuzzing)', 'cfg(kani)', 'cfg(mutate)', 'cfg(rust_v_1_60)', 'cfg(rust_v_1_61)'] }
2 changes: 1 addition & 1 deletion bitcoin/examples/sign-tx-taproot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn main() {
// Sign the sighash using the secp256k1 library (exported by rust-bitcoin).
let tweaked: TweakedKeypair = keypair.tap_tweak(&secp, None);
let msg = Message::from(sighash);
let signature = secp.sign_schnorr(&msg, &tweaked.to_inner());
let signature = secp.sign_schnorr(&msg, tweaked.as_keypair());

// Update the witness stack.
let signature = bitcoin::taproot::Signature { signature, sighash_type };
Expand Down
2 changes: 1 addition & 1 deletion bitcoin/examples/taproot-psbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ fn sign_psbt_taproot(
) {
let keypair = secp256k1::Keypair::from_seckey_slice(secp, secret_key.as_ref()).unwrap();
let keypair = match leaf_hash {
None => keypair.tap_tweak(secp, psbt_input.tap_merkle_root).to_inner(),
None => keypair.tap_tweak(secp, psbt_input.tap_merkle_root).to_keypair(),
Some(_) => keypair, // no tweak for script spend
};

Expand Down
24 changes: 24 additions & 0 deletions bitcoin/src/address/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ pub enum AddressType {
P2wsh,
/// Pay to taproot.
P2tr,
/// Pay to anchor.
P2a
}

impl fmt::Display for AddressType {
Expand All @@ -84,6 +86,7 @@ impl fmt::Display for AddressType {
AddressType::P2wpkh => "p2wpkh",
AddressType::P2wsh => "p2wsh",
AddressType::P2tr => "p2tr",
AddressType::P2a => "p2a",
})
}
}
Expand All @@ -97,6 +100,7 @@ impl FromStr for AddressType {
"p2wpkh" => Ok(AddressType::P2wpkh),
"p2wsh" => Ok(AddressType::P2wsh),
"p2tr" => Ok(AddressType::P2tr),
"p2a" => Ok(AddressType::P2a),
_ => Err(UnknownAddressTypeError(s.to_owned())),
}
}
Expand Down Expand Up @@ -496,6 +500,8 @@ impl Address {
Some(AddressType::P2wsh)
} else if program.is_p2tr() {
Some(AddressType::P2tr)
} else if program.is_p2a() {
Some(AddressType::P2a)
} else {
None
},
Expand Down Expand Up @@ -1367,4 +1373,22 @@ mod tests {
}
}
}

#[test]
fn pay_to_anchor_address_regtest() {
// Verify that p2a uses the expected address for regtest.
// This test-vector is borrowed from the bitcoin source code.
let address_str = "bcrt1pfeesnyr2tx";

let script = ScriptBuf::new_p2a();
let address_unchecked = address_str.parse().unwrap();
let address = Address::from_script(&script, Network::Regtest).unwrap();
assert_eq!(address.as_unchecked(), &address_unchecked);
assert_eq!(address.to_string(), address_str);

// Verify that the address is considered standard
// and that the output type is P2a
assert!(address.is_spend_standard());
assert_eq!(address.address_type(), Some(AddressType::P2a));
}
}
13 changes: 11 additions & 2 deletions bitcoin/src/bip32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ impl ChildNumber {

/// Returns the child number that is a single increment from this one.
pub fn increment(self) -> Result<ChildNumber, Error> {
// Bare addition in this function is okay, because we have an invariant that
// `index` is always within [0, 2^31 - 1]. FIXME this is not actually an
// invariant because the fields are public.
match self {
ChildNumber::Normal { index: idx } => ChildNumber::from_normal_idx(idx + 1),
ChildNumber::Hardened { index: idx } => ChildNumber::from_hardened_idx(idx + 1),
Expand Down Expand Up @@ -481,6 +484,10 @@ pub type KeySource = (Fingerprint, DerivationPath);
pub enum Error {
/// A pk->pk derivation was attempted on a hardened key
CannotDeriveFromHardenedKey,
/// Attempted to derive a child of depth 256 or higher.
///
/// There is no way to encode such xkeys.
MaximumDepthExceeded,
/// A secp256k1 error occurred
Secp256k1(secp256k1::Error),
/// A child number was provided that was out of range
Expand Down Expand Up @@ -512,6 +519,7 @@ impl fmt::Display for Error {
match *self {
CannotDeriveFromHardenedKey =>
f.write_str("cannot derive hardened key from public key"),
MaximumDepthExceeded => f.write_str("cannot derive child of depth 256 or higher"),
Secp256k1(ref e) => write_err!(f, "secp256k1 error"; e),
InvalidChildNumber(ref n) =>
write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n),
Expand Down Expand Up @@ -540,6 +548,7 @@ impl std::error::Error for Error {
Hex(ref e) => Some(e),
InvalidBase58PayloadLength(ref e) => Some(e),
CannotDeriveFromHardenedKey
| MaximumDepthExceeded
| InvalidChildNumber(_)
| InvalidChildNumberFormat
| InvalidDerivationPathFormat
Expand Down Expand Up @@ -636,7 +645,7 @@ impl Xpriv {

Ok(Xpriv {
network: self.network,
depth: self.depth + 1,
depth: self.depth.checked_add(1).ok_or(Error::MaximumDepthExceeded)?,
parent_fingerprint: self.fingerprint(secp),
child_number: i,
private_key: tweaked,
Expand Down Expand Up @@ -768,7 +777,7 @@ impl Xpub {

Ok(Xpub {
network: self.network,
depth: self.depth + 1,
depth: self.depth.checked_add(1).ok_or(Error::MaximumDepthExceeded)?,
parent_fingerprint: self.fingerprint(),
child_number: i,
public_key: tweaked,
Expand Down
12 changes: 9 additions & 3 deletions bitcoin/src/blockdata/script/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use secp256k1::{Secp256k1, Verification};

use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self, Opcode};
use crate::blockdata::script::witness_program::WitnessProgram;
use crate::blockdata::script::witness_program::{WitnessProgram, P2A_PROGRAM};
use crate::blockdata::script::witness_version::WitnessVersion;
use crate::blockdata::script::{
opcode_to_verify, Builder, Instruction, PushBytes, Script, ScriptHash, WScriptHash,
Expand Down Expand Up @@ -130,6 +130,11 @@ impl ScriptBuf {
ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, output_key.serialize())
}

/// Generates pay to anchor output.
pub fn new_p2a() -> Self {
ScriptBuf::new_witness_program_unchecked(WitnessVersion::V1, P2A_PROGRAM)
}

/// Generates P2WSH-type of scriptPubkey with a given [`WitnessProgram`].
pub fn new_witness_program(witness_program: &WitnessProgram) -> Self {
Builder::new()
Expand All @@ -141,14 +146,15 @@ impl ScriptBuf {
/// Generates P2WSH-type of scriptPubkey with a given [`WitnessVersion`] and the program bytes.
/// Does not do any checks on version or program length.
///
/// Convenience method used by `new_p2wpkh`, `new_p2wsh`, `new_p2tr`, and `new_p2tr_tweaked`.
/// Convenience method used by `new_p2wpkh`, `new_p2wsh`, `new_p2tr`, and `new_p2tr_tweaked`,
/// and `new_p2a`.
pub(crate) fn new_witness_program_unchecked<T: AsRef<PushBytes>>(
version: WitnessVersion,
program: T,
) -> Self {
let program = program.as_ref();
debug_assert!(program.len() >= 2 && program.len() <= 40);
// In segwit v0, the program must be 20 or 32 bytes long.
// In SegWit v0, the program must be either 20 (P2WPKH) bytes or 32 (P2WSH) bytes long
debug_assert!(version != WitnessVersion::V0 || program.len() == 20 || program.len() == 32);
Builder::new().push_opcode(version.into()).push_slice(program).into_script()
}
Expand Down
19 changes: 17 additions & 2 deletions bitcoin/src/blockdata/script/witness_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ pub const MIN_SIZE: usize = 2;
/// The maximum byte size of a segregated witness program.
pub const MAX_SIZE: usize = 40;

/// The P2A program which is given by 0x4e73.
pub(crate) const P2A_PROGRAM: [u8;2] = [78, 115];

/// The segregated witness program.
///
/// The segregated witness program is technically only the program bytes _excluding_ the witness
Expand Down Expand Up @@ -90,16 +93,23 @@ impl WitnessProgram {
merkle_root: Option<TapNodeHash>,
) -> Self {
let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
let pubkey = output_key.to_inner().serialize();
let pubkey = output_key.as_x_only_public_key().serialize();
WitnessProgram::new_p2tr(pubkey)
}

/// Creates a pay to taproot address from a pre-tweaked output key.
pub fn p2tr_tweaked(output_key: TweakedPublicKey) -> Self {
let pubkey = output_key.to_inner().serialize();
let pubkey = output_key.as_x_only_public_key().serialize();
WitnessProgram::new_p2tr(pubkey)
}

internals::const_tools::cond_const! {
/// Constructs a new pay to anchor address
pub const(in rust_v_1_61 = "1.61") fn p2a() -> Self {
WitnessProgram { version: WitnessVersion::V1, program: ArrayVec::from_slice(&P2A_PROGRAM)}
}
}

/// Returns the witness program version.
pub fn version(&self) -> WitnessVersion { self.version }

Expand All @@ -123,6 +133,11 @@ impl WitnessProgram {

/// Returns true if this witness program is for a P2TR output.
pub fn is_p2tr(&self) -> bool { self.version == WitnessVersion::V1 && self.program.len() == 32 }

/// Returns true if this is a pay to anchor output.
pub fn is_p2a(&self) -> bool {
self.version == WitnessVersion::V1 && self.program == P2A_PROGRAM
}
}

/// Witness program error.
Expand Down
Loading