diff --git a/CHANGELOG.md b/CHANGELOG.md index 119e4df55f..8bc6f97071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Changelog ========= +[0.13.1](https://github.com/ordinals/ord/releases/tag/0.13.1) - 2023-12-16 +-------------------------------------------------------------------------- + +### Fixed +- Use pre-segwit transaction serialization for fundrawtransaction (#2865) + [0.13.0](https://github.com/ordinals/ord/releases/tag/0.13.0) - 2023-12-15 -------------------------------------------------------------------------- diff --git a/Cargo.lock b/Cargo.lock index 1039599ff1..4ef42cfb21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2095,7 +2095,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ord" -version = "0.13.0" +version = "0.13.1" dependencies = [ "anyhow", "async-trait", @@ -3144,18 +3144,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 910fa8d89a..4fa8a097ef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ord" description = "◉ Ordinal wallet and block explorer" -version = "0.13.0" +version = "0.13.1" license = "CC0-1.0" edition = "2021" autotests = false diff --git a/src/lib.rs b/src/lib.rs index 7b8921141f..c18bf58866 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -160,15 +160,27 @@ fn fund_raw_transaction( fee_rate: FeeRate, unfunded_transaction: &Transaction, ) -> Result> { + let mut buffer = Vec::new(); + + { + unfunded_transaction.version.consensus_encode(&mut buffer)?; + unfunded_transaction.input.consensus_encode(&mut buffer)?; + unfunded_transaction.output.consensus_encode(&mut buffer)?; + unfunded_transaction + .lock_time + .consensus_encode(&mut buffer)?; + } + Ok( client .fund_raw_transaction( - unfunded_transaction, + &buffer, Some(&bitcoincore_rpc::json::FundRawTransactionOptions { // NB. This is `fundrawtransaction`'s `feeRate`, which is fee per kvB // and *not* fee per vB. So, we multiply the fee rate given by the user // by 1000. fee_rate: Some(Amount::from_sat((fee_rate.n() * 1000.0).ceil() as u64)), + change_position: Some(unfunded_transaction.output.len().try_into()?), ..Default::default() }), Some(false), diff --git a/test-bitcoincore-rpc/src/lib.rs b/test-bitcoincore-rpc/src/lib.rs index 3a3a1560a2..b12cf61fbf 100644 --- a/test-bitcoincore-rpc/src/lib.rs +++ b/test-bitcoincore-rpc/src/lib.rs @@ -162,6 +162,8 @@ impl From for JsonOutPoint { struct FundRawTransactionOptions { #[serde(with = "bitcoin::amount::serde::as_btc::opt")] fee_rate: Option, + #[serde(skip_serializing_if = "Option::is_none")] + change_position: Option, } #[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)] diff --git a/test-bitcoincore-rpc/src/server.rs b/test-bitcoincore-rpc/src/server.rs index 4655939f92..3ec18b188d 100644 --- a/test-bitcoincore-rpc/src/server.rs +++ b/test-bitcoincore-rpc/src/server.rs @@ -1,9 +1,11 @@ use { super::*, bitcoin::{ + consensus::Decodable, secp256k1::{rand, KeyPair, Secp256k1, XOnlyPublicKey}, Witness, }, + std::io::Cursor, }; pub(crate) struct Server { @@ -243,7 +245,26 @@ impl Api for Server { options: Option, _is_witness: Option, ) -> Result { - let mut transaction: Transaction = deserialize(&hex::decode(tx).unwrap()).unwrap(); + let options = options.unwrap(); + + let mut cursor = Cursor::new(hex::decode(tx).unwrap()); + + let version = i32::consensus_decode_from_finite_reader(&mut cursor).unwrap(); + let input = Vec::::consensus_decode_from_finite_reader(&mut cursor).unwrap(); + let output = Decodable::consensus_decode_from_finite_reader(&mut cursor).unwrap(); + let lock_time = Decodable::consensus_decode_from_finite_reader(&mut cursor).unwrap(); + + let mut transaction = Transaction { + version, + input, + output, + lock_time, + }; + + assert_eq!( + options.change_position, + Some(transaction.output.len().try_into().unwrap()) + ); let state = self.state(); @@ -294,7 +315,7 @@ impl Api for Server { script_pubkey: ScriptBuf::new(), }); - let fee = if let Some(fee_rate) = options.and_then(|options| options.fee_rate) { + let fee = if let Some(fee_rate) = options.fee_rate { // increase vsize to account for the witness that `fundrawtransaction` will add let funded_vsize = transaction.vsize() as f64 + 68.0 / 4.0; let funded_kwu = funded_vsize / 1000.0;