Skip to content

Commit 44452bf

Browse files
committed
Merge rust-bitcoin/rust-bitcoin#939: fix: reject message (de)serialization
548725c test: reject message (de)serialization (0xb10c) fc572ab fix: use var_str in 'reject' msgs (0xb10c) Pull request description: [BIP-61 defines `response-to-msg`][bip61] (`Reject::message` in rust-bitcoin; the message that triggered the reject) to be a `var_str`. However, by using the `CommandString` it was (de)serialized as 12 byte string. A test is added that de- and serializes two reject messages received from an older Bitcoin Core peer. Reject message sending has been removed from Bitcoin Core, I'm still receiving them from older peers from time to time. [bip61]: https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki#common-payload gh-ref: rust-bitcoin/rust-bitcoin#323 ACKs for top commit: apoelstra: ACK 548725c Tree-SHA512: e5cbf215a471f113b4dd7f7fada162686fc6e8c7b1e2e9e641667208a36d3db610e57e8b549756ffe597656fee5444fe95466f1b88f45366595766f7c4640eea
2 parents a9b1063 + a7b7afb commit 44452bf

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/network/message.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ mod test {
472472
NetworkMessage::GetCFCheckpt(GetCFCheckpt{filter_type: 17, stop_hash: hash([25u8; 32]).into()}),
473473
NetworkMessage::CFCheckpt(CFCheckpt{filter_type: 27, stop_hash: hash([77u8; 32]).into(), filter_headers: vec![hash([3u8; 32]).into(), hash([99u8; 32]).into()]}),
474474
NetworkMessage::Alert(vec![45,66,3,2,6,8,9,12,3,130]),
475-
NetworkMessage::Reject(Reject{message: CommandString::try_from("Test reject").unwrap(), ccode: RejectReason::Duplicate, reason: "Cause".into(), hash: hash([255u8; 32])}),
475+
NetworkMessage::Reject(Reject{message: "Test reject".into(), ccode: RejectReason::Duplicate, reason: "Cause".into(), hash: hash([255u8; 32])}),
476476
NetworkMessage::FeeFilter(1000),
477477
NetworkMessage::WtxidRelay,
478478
NetworkMessage::AddrV2(vec![AddrV2Message{ addr: AddrV2::Ipv4(Ipv4Addr::new(127, 0, 0, 1)), port: 0, services: ServiceFlags::NONE, time: 0 }]),

src/network/message_network.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use network::address::Address;
2626
use network::constants::{self, ServiceFlags};
2727
use consensus::{Encodable, Decodable, ReadExt};
2828
use consensus::encode;
29-
use network::message::CommandString;
3029
use hashes::sha256d;
3130

3231
/// Some simple messages
@@ -133,7 +132,7 @@ impl Decodable for RejectReason {
133132
#[derive(PartialEq, Eq, Clone, Debug)]
134133
pub struct Reject {
135134
/// message type rejected
136-
pub message: CommandString,
135+
pub message: Cow<'static, str>,
137136
/// reason of rejection as code
138137
pub ccode: RejectReason,
139138
/// reason of rejectection
@@ -147,8 +146,11 @@ impl_consensus_encoding!(Reject, message, ccode, reason, hash);
147146
#[cfg(test)]
148147
mod tests {
149148
use super::VersionMessage;
149+
use super::Reject;
150+
use super::RejectReason;
150151

151152
use hashes::hex::FromHex;
153+
use hashes::sha256d::Hash;
152154
use network::constants::ServiceFlags;
153155

154156
use consensus::encode::{deserialize, serialize};
@@ -172,4 +174,37 @@ mod tests {
172174

173175
assert_eq!(serialize(&real_decode), from_sat);
174176
}
177+
178+
#[test]
179+
fn reject_message_test() {
180+
let reject_tx_conflict = Vec::from_hex("027478121474786e2d6d656d706f6f6c2d636f6e666c69637405df54d3860b3c41806a3546ab48279300affacf4b88591b229141dcf2f47004").unwrap();
181+
let reject_tx_nonfinal = Vec::from_hex("02747840096e6f6e2d66696e616c259bbe6c83db8bbdfca7ca303b19413dc245d9f2371b344ede5f8b1339a5460b").unwrap();
182+
183+
let decode_result_conflict: Result<Reject, _> = deserialize(&reject_tx_conflict);
184+
let decode_result_nonfinal: Result<Reject, _> = deserialize(&reject_tx_nonfinal);
185+
186+
assert!(decode_result_conflict.is_ok());
187+
assert!(decode_result_nonfinal.is_ok());
188+
189+
let conflict = decode_result_conflict.unwrap();
190+
assert_eq!("tx", conflict.message);
191+
assert_eq!(RejectReason::Duplicate, conflict.ccode);
192+
assert_eq!("txn-mempool-conflict", conflict.reason);
193+
assert_eq!(
194+
Hash::from_hex("0470f4f2dc4191221b59884bcffaaf00932748ab46356a80413c0b86d354df05").unwrap(),
195+
conflict.hash
196+
);
197+
198+
let nonfinal = decode_result_nonfinal.unwrap();
199+
assert_eq!("tx", nonfinal.message);
200+
assert_eq!(RejectReason::NonStandard, nonfinal.ccode);
201+
assert_eq!("non-final", nonfinal.reason);
202+
assert_eq!(
203+
Hash::from_hex("0b46a539138b5fde4e341b37f2d945c23d41193b30caa7fcbd8bdb836cbe9b25").unwrap(),
204+
nonfinal.hash
205+
);
206+
207+
assert_eq!(serialize(&conflict), reject_tx_conflict);
208+
assert_eq!(serialize(&nonfinal), reject_tx_nonfinal);
209+
}
175210
}

0 commit comments

Comments
 (0)