What changed, and why it matters
This commit is a routine performance improvement, not a security fix. It adds a new way to get an opcode's name as a static string slice without allocating memory, and uses that new method during JSON/serde serialization. There is no change to behavior, no bug fix, and no security relevance in the code itself.
No security action required. Treat as a normal performance/refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces Opcode::as_str(), returning &’static str via the existing macro-generated match over all opcodes. It refactors fmt::Display to delegate to as_str() and changes serde::Serialize for Opcode from serializer.serialize_str(&self.to_string()) to serializer.serialize_str(self.as_str()). This removes a per-serialization String allocation when the serde feature is enabled. The behavior of serialization and Display output is unchanged.
Changed components
bitcoin/src/blockdata/opcodes.rsOpcode serde serializationOpcode Display formattingInspect captured patch +26 / −9
diff --git a/bitcoin/src/blockdata/opcodes.rs b/bitcoin/src/blockdata/opcodes.rs
index 552e1603..8445f2e4 100644
--- a/bitcoin/src/blockdata/opcodes.rs
+++ b/bitcoin/src/blockdata/opcodes.rs
@@ -9,9 +9,6 @@
use core::fmt;
-#[cfg(feature = "serde")]
-use crate::prelude::ToString;
-
/// A script Opcode.
///
/// We do not implement Ord on this type because there is no natural ordering on opcodes, but there
@@ -48,6 +45,30 @@ macro_rules! all_opcodes {
pub const $op: Opcode = Opcode { code: $val};
)*
+ impl Opcode {
+ /// Returns the string representation of the opcode.
+ ///
+ /// This function maps the `Opcode`'s `code` value (a `u8`) to its corresponding
+ /// Bitcoin Script opcode name.
+ ///
+ /// # Example
+ /// ```
+ /// use bitcoin::opcodes::all::*;
+ ///
+ /// assert_eq!(OP_1.as_str(), "OP_1");
+ /// assert_eq!(OP_1NEGATE.as_str(), "OP_1NEGATE");
+ /// assert_eq!(OP_CHECKMULTISIG.as_str(), "OP_CHECKMULTISIG");
+ /// ```
+ #[inline]
+ pub fn as_str(&self) -> &'static str {
+ match *self {
+ $(
+ $op => stringify!($op),
+ )+
+ }
+ }
+ }
+
/// Push an empty array onto the stack.
pub const OP_0: Opcode = OP_PUSHBYTES_0;
/// Empty stack is also FALSE.
@@ -114,11 +135,7 @@ macro_rules! all_opcodes {
impl fmt::Display for Opcode {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
- match *self {
- $(
- $op => core::fmt::Display::fmt(stringify!($op), f),
- )+
- }
+ core::fmt::Display::fmt(self.as_str(), f)
}
}
}
@@ -501,7 +518,7 @@ impl serde::Serialize for Opcode {
where
S: serde::Serializer,
{
- serializer.serialize_str(&self.to_string())
+ serializer.serialize_str(self.as_str())
}
}
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.