Merge rust-bitcoin/rust-bitcoin#1955: Rename `opcodes::All` to `Opcode`

63d0fa0164 Rename All to Opcode (Tobin C. Harding)
881d1b1a9d Move opcode aliases to the all module (Tobin C. Harding)
f3e8dbc392 Remove floating code comment (Tobin C. Harding)
dfd9384d14 opcodes: Fix whitespace (Tobin C. Harding)

Pull request description:

  I may be missing something about the `All` type but it seems it can be re-named to `Opcode` with no loss of clarity.

  The first few patches do some other clean ups, the last patch is the meat and potatoes.

ACKs for top commit:
  apoelstra:
    ACK 63d0fa0164

Tree-SHA512: c1b8be9e0c090d015c2bbfcb7ed6abe998ccada5a1eb0f6966c2a7dc462f8bbc45e6b99bf1387c736d2fca21a993a2c7fd5844c18b97a2e37ec43da517566ab1
This commit is contained in:
Andrew Poelstra 2023-08-11 18:54:37 +00:00
commit f1b3e69f20
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
7 changed files with 60 additions and 63 deletions

View File

@ -22,7 +22,7 @@ use crate::prelude::*;
/// ///
/// We do not implement Ord on this type because there is no natural ordering on opcodes, but there /// We do not implement Ord on this type because there is no natural ordering on opcodes, but there
/// may appear to be one (e.g. because all the push opcodes appear in a consecutive block) and we /// may appear to be one (e.g. because all the push opcodes appear in a consecutive block) and we
/// don't want to encourage subtly buggy code. Please use [`All::classify`] to distinguish different /// don't want to encourage subtly buggy code. Please use [`Opcode::classify`] to distinguish different
/// types of opcodes. /// types of opcodes.
/// ///
/// <details> /// <details>
@ -32,7 +32,7 @@ use crate::prelude::*;
/// in contexts where only pushes are supposed to be allowed. /// in contexts where only pushes are supposed to be allowed.
/// </details> /// </details>
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
pub struct All { pub struct Opcode {
code: u8, code: u8,
} }
@ -40,24 +40,33 @@ use self::all::*;
macro_rules! all_opcodes { macro_rules! all_opcodes {
($($op:ident => $val:expr, $doc:expr);*) => { ($($op:ident => $val:expr, $doc:expr);*) => {
// private import so we don't have to use `all::OP_FOO` in this file.
/// Enables wildcard imports to bring into scope all opcodes and nothing else. /// Enables wildcard imports to bring into scope all opcodes and nothing else.
/// ///
/// The `all` module is provided so one can use a wildcard import `use bitcoin::opcodes::all::*` to /// The `all` module is provided so one can use a wildcard import `use bitcoin::opcodes::all::*` to
/// get all the `OP_FOO` opcodes without getting other types defined in `opcodes` (e.g. `All`, `Class`). /// get all the `OP_FOO` opcodes without getting other types defined in `opcodes` (e.g. `Opcode`, `Class`).
/// ///
/// This module is guaranteed to never contain anything except opcode constants and all opcode /// This module is guaranteed to never contain anything except opcode constants and all opcode
/// constants are guaranteed to begin with OP_. /// constants are guaranteed to begin with OP_.
pub mod all { pub mod all {
use super::All; use super::Opcode;
$( $(
#[doc = $doc] #[doc = $doc]
pub const $op: All = All { code: $val}; pub const $op: Opcode = Opcode { code: $val};
)* )*
} }
impl fmt::Display for All { /// Push an empty array onto the stack.
pub static OP_0: Opcode = OP_PUSHBYTES_0;
/// Empty stack is also FALSE.
pub static OP_FALSE: Opcode = OP_PUSHBYTES_0;
/// Number 1 is also TRUE.
pub static OP_TRUE: Opcode = OP_PUSHNUM_1;
/// Previously called OP_NOP2.
pub static OP_NOP2: Opcode = OP_CLTV;
/// Previously called OP_NOP3.
pub static OP_NOP3: Opcode = OP_CSV;
impl fmt::Display for Opcode {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
$( $(
@ -66,7 +75,6 @@ macro_rules! all_opcodes {
} }
} }
} }
} }
} }
@ -344,7 +352,7 @@ pub enum ClassifyContext {
Legacy, Legacy,
} }
impl All { impl Opcode {
/// Classifies an Opcode into a broad class. /// Classifies an Opcode into a broad class.
#[inline] #[inline]
pub fn classify(self, ctx: ClassifyContext) -> Class { pub fn classify(self, ctx: ClassifyContext) -> Class {
@ -408,11 +416,11 @@ impl All {
} }
} }
/// Encodes [`All`] as a byte. /// Encodes [`Opcode`] as a byte.
#[inline] #[inline]
pub const fn to_u8(self) -> u8 { self.code } pub const fn to_u8(self) -> u8 { self.code }
/// Encodes PUSHNUM [`All`] as a `u8` representing its number (1-16). /// Encodes PUSHNUM [`Opcode`] as a `u8` representing its number (1-16).
/// ///
/// Does not convert `OP_FALSE` to 0. Only `1` to `OP_PUSHNUM_16` are covered. /// Does not convert `OP_FALSE` to 0. Only `1` to `OP_PUSHNUM_16` are covered.
/// ///
@ -430,15 +438,15 @@ impl All {
} }
} }
impl From<u8> for All { impl From<u8> for Opcode {
#[inline] #[inline]
fn from(b: u8) -> All { All { code: b } } fn from(b: u8) -> Opcode { Opcode { code: b } }
} }
debug_from_display!(All); debug_from_display!(Opcode);
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
impl serde::Serialize for All { impl serde::Serialize for Opcode {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: serde::Serializer, S: serde::Serializer,
@ -447,17 +455,6 @@ impl serde::Serialize for All {
} }
} }
/// Push an empty array onto the stack.
pub static OP_0: All = OP_PUSHBYTES_0;
/// Empty stack is also FALSE.
pub static OP_FALSE: All = OP_PUSHBYTES_0;
/// Number 1 is also TRUE.
pub static OP_TRUE: All = OP_PUSHNUM_1;
/// Previously called OP_NOP2.
pub static OP_NOP2: All = OP_CLTV;
/// Previously called OP_NOP3.
pub static OP_NOP3: All = OP_CSV;
/// Broad categories of opcodes with similar behavior. /// Broad categories of opcodes with similar behavior.
#[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum Class { pub enum Class {
@ -495,15 +492,15 @@ macro_rules! ordinary_opcode {
} }
impl Ordinary { impl Ordinary {
fn with(b: All) -> Self { fn with(b: Opcode) -> Self {
match b { match b {
$( $op => { Ordinary::$op } ),* $( $op => { Ordinary::$op } ),*
_ => unreachable!("construction of `Ordinary` type from non-ordinary opcode {}", b), _ => unreachable!("construction of `Ordinary` type from non-ordinary opcode {}", b),
} }
} }
/// Try to create from an All /// Try to create a [`Ordinary`] from an [`Opcode`].
pub fn try_from_all(b: All) -> Option<Self> { pub fn from_opcode(b: Opcode) -> Option<Self> {
match b { match b {
$( $op => { Some(Ordinary::$op) } ),* $( $op => { Some(Ordinary::$op) } ),*
_ => None, _ => None,
@ -540,7 +537,7 @@ ordinary_opcode! {
} }
impl Ordinary { impl Ordinary {
/// Encodes [`All`] as a byte. /// Encodes [`Opcode`] as a byte.
#[inline] #[inline]
pub fn to_u8(self) -> u8 { self as u8 } pub fn to_u8(self) -> u8 { self as u8 }
} }
@ -553,7 +550,7 @@ mod tests {
macro_rules! roundtrip { macro_rules! roundtrip {
($unique:expr, $op:ident) => { ($unique:expr, $op:ident) => {
assert_eq!($op, All::from($op.to_u8())); assert_eq!($op, Opcode::from($op.to_u8()));
let s1 = format!("{}", $op); let s1 = format!("{}", $op);
let s2 = format!("{:?}", $op); let s2 = format!("{:?}", $op);
@ -582,7 +579,7 @@ mod tests {
0x51..=0x60 => Some(i - 0x50), 0x51..=0x60 => Some(i - 0x50),
_ => None, _ => None,
}; };
assert_eq!(All::from(i).decode_pushnum(), expected); assert_eq!(Opcode::from(i).decode_pushnum(), expected);
} }
// Test the named opcode constants // Test the named opcode constants

View File

@ -10,7 +10,7 @@ use hashes::Hash;
use secp256k1::{Secp256k1, Verification}; use secp256k1::{Secp256k1, Verification};
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self}; use crate::blockdata::opcodes::{self, Opcode};
use crate::blockdata::script::witness_version::WitnessVersion; use crate::blockdata::script::witness_version::WitnessVersion;
use crate::blockdata::script::{ use crate::blockdata::script::{
bytes_to_asm_fmt, Builder, Instruction, InstructionIndices, Instructions, ScriptBuf, bytes_to_asm_fmt, Builder, Instruction, InstructionIndices, Instructions, ScriptBuf,
@ -166,7 +166,7 @@ impl Script {
/// Returns witness version of the script, if any, assuming the script is a `scriptPubkey`. /// Returns witness version of the script, if any, assuming the script is a `scriptPubkey`.
#[inline] #[inline]
pub fn witness_version(&self) -> Option<WitnessVersion> { pub fn witness_version(&self) -> Option<WitnessVersion> {
self.0.first().and_then(|opcode| WitnessVersion::try_from(opcodes::All::from(*opcode)).ok()) self.0.first().and_then(|opcode| WitnessVersion::try_from(Opcode::from(*opcode)).ok())
} }
/// Checks whether a script pubkey is a P2SH output. /// Checks whether a script pubkey is a P2SH output.
@ -229,7 +229,7 @@ impl Script {
if !(4..=42).contains(&script_len) { if !(4..=42).contains(&script_len) {
return false; return false;
} }
let ver_opcode = opcodes::All::from(self.0[0]); // Version 0 or PUSHNUM_1-PUSHNUM_16 let ver_opcode = Opcode::from(self.0[0]); // Version 0 or PUSHNUM_1-PUSHNUM_16
let push_opbyte = self.0[1]; // Second byte push opcode 2-40 bytes let push_opbyte = self.0[1]; // Second byte push opcode 2-40 bytes
WitnessVersion::try_from(ver_opcode).is_ok() WitnessVersion::try_from(ver_opcode).is_ok()
&& push_opbyte >= OP_PUSHBYTES_2.to_u8() && push_opbyte >= OP_PUSHBYTES_2.to_u8()
@ -286,7 +286,7 @@ impl Script {
match self.0.first() { match self.0.first() {
Some(b) => { Some(b) => {
let first = opcodes::All::from(*b); let first = Opcode::from(*b);
let class = first.classify(opcodes::ClassifyContext::Legacy); let class = first.classify(opcodes::ClassifyContext::Legacy);
class == ReturnOp || class == IllegalOp class == ReturnOp || class == IllegalOp
@ -475,14 +475,14 @@ impl Script {
pub fn to_hex_string(&self) -> String { self.as_bytes().to_lower_hex_string() } pub fn to_hex_string(&self) -> String { self.as_bytes().to_lower_hex_string() }
/// Returns the first opcode of the script (if there is any). /// Returns the first opcode of the script (if there is any).
pub fn first_opcode(&self) -> Option<opcodes::All> { pub fn first_opcode(&self) -> Option<Opcode> {
self.as_bytes().first().copied().map(From::from) self.as_bytes().first().copied().map(From::from)
} }
/// Iterates the script to find the last opcode. /// Iterates the script to find the last opcode.
/// ///
/// Returns `None` is the instruction is data push or if the script is empty. /// Returns `None` is the instruction is data push or if the script is empty.
pub(in crate::blockdata::script) fn last_opcode(&self) -> Option<opcodes::All> { pub(in crate::blockdata::script) fn last_opcode(&self) -> Option<Opcode> {
match self.instructions().last() { match self.instructions().last() {
Some(Ok(Instruction::Op(op))) => Some(op), Some(Ok(Instruction::Op(op))) => Some(op),
_ => None, _ => None,

View File

@ -7,7 +7,7 @@ use secp256k1::XOnlyPublicKey;
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self}; use crate::blockdata::opcodes::{self, Opcode};
use crate::blockdata::script::{opcode_to_verify, write_scriptint, PushBytes, Script, ScriptBuf}; use crate::blockdata::script::{opcode_to_verify, write_scriptint, PushBytes, Script, ScriptBuf};
use crate::blockdata::transaction::Sequence; use crate::blockdata::transaction::Sequence;
use crate::key::PublicKey; use crate::key::PublicKey;
@ -15,7 +15,7 @@ use crate::prelude::*;
/// An Object which can be used to construct a script piece by piece. /// An Object which can be used to construct a script piece by piece.
#[derive(PartialEq, Eq, Clone)] #[derive(PartialEq, Eq, Clone)]
pub struct Builder(ScriptBuf, Option<opcodes::All>); pub struct Builder(ScriptBuf, Option<Opcode>);
impl Builder { impl Builder {
/// Creates a new empty script. /// Creates a new empty script.
@ -34,7 +34,7 @@ impl Builder {
pub fn push_int(self, data: i64) -> Builder { pub fn push_int(self, data: i64) -> Builder {
// We can special-case -1, 1-16 // We can special-case -1, 1-16
if data == -1 || (1..=16).contains(&data) { if data == -1 || (1..=16).contains(&data) {
let opcode = opcodes::All::from((data - 1 + opcodes::OP_TRUE.to_u8() as i64) as u8); let opcode = Opcode::from((data - 1 + opcodes::OP_TRUE.to_u8() as i64) as u8);
self.push_opcode(opcode) self.push_opcode(opcode)
} }
// We can also special-case zero // We can also special-case zero
@ -78,7 +78,7 @@ impl Builder {
} }
/// Adds a single opcode to the script. /// Adds a single opcode to the script.
pub fn push_opcode(mut self, data: opcodes::All) -> Builder { pub fn push_opcode(mut self, data: Opcode) -> Builder {
self.0.push_opcode(data); self.0.push_opcode(data);
self.1 = Some(data); self.1 = Some(data);
self self

View File

@ -2,7 +2,7 @@
use core::convert::TryInto; use core::convert::TryInto;
use crate::blockdata::opcodes; use crate::blockdata::opcodes::{self, Opcode};
use crate::blockdata::script::{read_uint_iter, Error, PushBytes, Script, ScriptBuf, UintError}; use crate::blockdata::script::{read_uint_iter, Error, PushBytes, Script, ScriptBuf, UintError};
/// A "parsed opcode" which allows iterating over a [`Script`] in a more sensible way. /// A "parsed opcode" which allows iterating over a [`Script`] in a more sensible way.
@ -11,12 +11,12 @@ pub enum Instruction<'a> {
/// Push a bunch of data. /// Push a bunch of data.
PushBytes(&'a PushBytes), PushBytes(&'a PushBytes),
/// Some non-push opcode. /// Some non-push opcode.
Op(opcodes::All), Op(Opcode),
} }
impl<'a> Instruction<'a> { impl<'a> Instruction<'a> {
/// Returns the opcode if the instruction is not a data push. /// Returns the opcode if the instruction is not a data push.
pub fn opcode(&self) -> Option<opcodes::All> { pub fn opcode(&self) -> Option<Opcode> {
match self { match self {
Instruction::Op(op) => Some(*op), Instruction::Op(op) => Some(*op),
Instruction::PushBytes(_) => None, Instruction::PushBytes(_) => None,
@ -124,7 +124,7 @@ impl<'a> Iterator for Instructions<'a> {
// classify parameter does not really matter here since we are only using // classify parameter does not really matter here since we are only using
// it for pushes and nums // it for pushes and nums
match opcodes::All::from(byte).classify(opcodes::ClassifyContext::Legacy) { match Opcode::from(byte).classify(opcodes::ClassifyContext::Legacy) {
opcodes::Class::PushBytes(n) => { opcodes::Class::PushBytes(n) => {
// make sure safety argument holds across refactorings // make sure safety argument holds across refactorings
let n: u32 = n; let n: u32 = n;
@ -152,7 +152,7 @@ impl<'a> Iterator for Instructions<'a> {
opcodes::Class::Ordinary(opcodes::Ordinary::OP_PUSHDATA4) => opcodes::Class::Ordinary(opcodes::Ordinary::OP_PUSHDATA4) =>
self.next_push_data_len(PushDataLenLen::Four, 0x10000), self.next_push_data_len(PushDataLenLen::Four, 0x10000),
// Everything else we can push right through // Everything else we can push right through
_ => Some(Ok(Instruction::Op(opcodes::All::from(byte)))), _ => Some(Ok(Instruction::Op(Opcode::from(byte)))),
} }
} }

View File

@ -60,7 +60,7 @@ use hashes::{hash160, sha256};
use serde; use serde;
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self}; use crate::blockdata::opcodes::{self, Opcode};
use crate::consensus::{encode, Decodable, Encodable}; use crate::consensus::{encode, Decodable, Encodable};
use crate::prelude::*; use crate::prelude::*;
use crate::{io, OutPoint}; use crate::{io, OutPoint};
@ -236,7 +236,7 @@ fn read_uint_iter(data: &mut core::slice::Iter<'_, u8>, size: usize) -> Result<u
} }
} }
fn opcode_to_verify(opcode: Option<opcodes::All>) -> Option<opcodes::All> { fn opcode_to_verify(opcode: Option<Opcode>) -> Option<Opcode> {
opcode.and_then(|opcode| match opcode { opcode.and_then(|opcode| match opcode {
OP_EQUAL => Some(OP_EQUALVERIFY), OP_EQUAL => Some(OP_EQUALVERIFY),
OP_NUMEQUAL => Some(OP_NUMEQUALVERIFY), OP_NUMEQUAL => Some(OP_NUMEQUALVERIFY),
@ -606,7 +606,7 @@ pub(super) fn bytes_to_asm_fmt(script: &[u8], f: &mut dyn fmt::Write) -> fmt::Re
// `iter` needs to be borrowed in `read_push_data_len`, so we have to use `while let` instead // `iter` needs to be borrowed in `read_push_data_len`, so we have to use `while let` instead
// of `for`. // of `for`.
while let Some(byte) = iter.next() { while let Some(byte) = iter.next() {
let opcode = opcodes::All::from(*byte); let opcode = Opcode::from(*byte);
let data_len = if let opcodes::Class::PushBytes(n) = let data_len = if let opcodes::Class::PushBytes(n) =
opcode.classify(opcodes::ClassifyContext::Legacy) opcode.classify(opcodes::ClassifyContext::Legacy)

View File

@ -6,7 +6,7 @@ use core::ops::Deref;
use secp256k1::{Secp256k1, Verification}; use secp256k1::{Secp256k1, Verification};
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::{self}; use crate::blockdata::opcodes::{self, Opcode};
use crate::blockdata::script::witness_program::WitnessProgram; use crate::blockdata::script::witness_program::WitnessProgram;
use crate::blockdata::script::witness_version::WitnessVersion; use crate::blockdata::script::witness_version::WitnessVersion;
use crate::blockdata::script::{ use crate::blockdata::script::{
@ -176,7 +176,7 @@ impl ScriptBuf {
pub fn into_bytes(self) -> Vec<u8> { self.0 } pub fn into_bytes(self) -> Vec<u8> { self.0 }
/// Adds a single opcode to the script. /// Adds a single opcode to the script.
pub fn push_opcode(&mut self, data: opcodes::All) { self.0.push(data.to_u8()); } pub fn push_opcode(&mut self, data: Opcode) { self.0.push(data.to_u8()); }
/// Adds instructions to push some arbitrary data onto the stack. /// Adds instructions to push some arbitrary data onto the stack.
pub fn push_slice<T: AsRef<PushBytes>>(&mut self, data: T) { pub fn push_slice<T: AsRef<PushBytes>>(&mut self, data: T) {
@ -266,7 +266,7 @@ impl ScriptBuf {
/// alternative. /// alternative.
/// ///
/// See the public fn [`Self::scan_and_push_verify`] to learn more. /// See the public fn [`Self::scan_and_push_verify`] to learn more.
pub(in crate::blockdata::script) fn push_verify(&mut self, last_opcode: Option<opcodes::All>) { pub(in crate::blockdata::script) fn push_verify(&mut self, last_opcode: Option<Opcode>) {
match opcode_to_verify(last_opcode) { match opcode_to_verify(last_opcode) {
Some(opcode) => { Some(opcode) => {
self.0.pop(); self.0.pop();

View File

@ -13,8 +13,8 @@ use core::str::FromStr;
use internals::write_err; use internals::write_err;
use crate::blockdata::opcodes;
use crate::blockdata::opcodes::all::*; use crate::blockdata::opcodes::all::*;
use crate::blockdata::opcodes::Opcode;
use crate::blockdata::script::Instruction; use crate::blockdata::script::Instruction;
use crate::error::ParseIntError; use crate::error::ParseIntError;
@ -149,7 +149,7 @@ impl TryFrom<u8> for WitnessVersion {
} }
} }
impl TryFrom<opcodes::All> for WitnessVersion { impl TryFrom<Opcode> for WitnessVersion {
type Error = Error; type Error = Error;
/// Converts bitcoin script opcode into [`WitnessVersion`] variant. /// Converts bitcoin script opcode into [`WitnessVersion`] variant.
@ -162,7 +162,7 @@ impl TryFrom<opcodes::All> for WitnessVersion {
/// ///
/// If the opcode does not correspond to any witness version, errors with /// If the opcode does not correspond to any witness version, errors with
/// [`Error::Malformed`]. /// [`Error::Malformed`].
fn try_from(opcode: opcodes::All) -> Result<Self, Self::Error> { fn try_from(opcode: Opcode) -> Result<Self, Self::Error> {
match opcode.to_u8() { match opcode.to_u8() {
0 => Ok(WitnessVersion::V0), 0 => Ok(WitnessVersion::V0),
version if version >= OP_PUSHNUM_1.to_u8() && version <= OP_PUSHNUM_16.to_u8() => version if version >= OP_PUSHNUM_1.to_u8() && version <= OP_PUSHNUM_16.to_u8() =>
@ -202,12 +202,12 @@ impl From<WitnessVersion> for bech32::u5 {
} }
} }
impl From<WitnessVersion> for opcodes::All { impl From<WitnessVersion> for Opcode {
/// Converts [`WitnessVersion`] instance into corresponding Bitcoin scriptopcode (`OP_0`..`OP_16`). /// Converts [`WitnessVersion`] instance into corresponding Bitcoin scriptopcode (`OP_0`..`OP_16`).
fn from(version: WitnessVersion) -> opcodes::All { fn from(version: WitnessVersion) -> Opcode {
match version { match version {
WitnessVersion::V0 => OP_PUSHBYTES_0, WitnessVersion::V0 => OP_PUSHBYTES_0,
no => opcodes::All::from(OP_PUSHNUM_1.to_u8() + no.to_num() - 1), no => Opcode::from(OP_PUSHNUM_1.to_u8() + no.to_num() - 1),
} }
} }
} }