-
Notifications
You must be signed in to change notification settings - Fork 831
Remove usage of opcodes::all
#1295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I think we should also drop the |
Perhaps rename module to |
Yeah, I like that. |
Drats, we can't do it because of things like |
19d2f4b
to
a31b9c9
Compare
I'm a little tempted to name @Kixunil what would you think about this? It would be similar to renaming |
|
4e2b944
to
e1eb641
Compare
We should probably add a commit that adds a deprecated module (If we want to be more careful I guess |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK e1eb641eacf2e1340b5f4b9135ff8550986aaf33
By "deprecated" you mean just deprecated to use Rust Bitcoin devs, right? Remembering that I don't currently know of a way to deprecated modules. |
Ah, damn, I forgot this. |
That's good English, right there :) |
Friendly bump, is this one good to go in? Needs a second ACK if so please. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is moving in the right direction but not sure if we should change this just to change it again if/when we change to enum.
I'm also considering this design to solve #1187:
/// Types that can be used as opcodes
pub trait Opcode: sealed::Opcode + Into<AnyOpcode> + Copy {
fn to_u8(self) -> u8;
}
macro_rules! all_opcodes {
($($name:ident = $val:expr (, $subclass:ident)*);+ $(;)?) => {
/// May contain any opcode of bitcoin script.
#[allow(non_camel_case_types)]
pub enum AnyOpcode {
$(
$name = $val,
)+
}
$(
/// The zero-sized opcode.
///
/// Zero-sized opcodes can statically guarantee some properties. e.g. (not) carrying bytes parameter. These are represented as conversion traits being implemented.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
pub struct $name;
impl From<$name> for AnyOpcode {
fn from(opcode: $name) -> Self {
AnyOpcode::from_u8(opcode.to_u8())
}
}
impl Opcode for $name {
fn to_u8(self) -> u8 {
$value
}
}
impl From<$name> for $subclass {
fn from(opcode: $name) -> Self {
$subclass(opcode.to_u8())
}
}
)+
}
}
/// Opcodes that don't take a byte array parameter
pub struct NonParametrised(u8);
Then the Instructions
iterator could use NonParametrised
instead of All
. Script::push_opcode
would become: fn push_opcode<Op: Opcode + Into<NonParametrised>(&mut self, op: Op)
bitcoin/src/address.rs
Outdated
WitnessVersion::try_from(version - opcodes::all::OP_PUSHNUM_1.to_u8() + 1), | ||
if version >= op::OP_PUSHNUM_1.to_u8() | ||
&& version <= op::OP_PUSHNUM_16.to_u8() => | ||
WitnessVersion::try_from(version - op::OP_PUSHNUM_1.to_u8() + 1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since all the opcodes begin with OP_
maybe just use op::*;
and drop op::
? The main reasons for not having ::*
is name conflicts and not being obvious where things come from but this situation seems like a good exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't do this because some opcodes start with 2
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm suggesting the other change - keep OP_
and drop op::
. Now we have op::OP_
which is kinda silly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. agreed.
@@ -26,632 +26,627 @@ pub struct All { | |||
code: u8, | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this isn't an enum? Maybe we should change it while we're at it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because conversion from a u8 to an enum requires either a 256-arm match or a transmute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neither of them sounds too bad to me.
@Kixunil I tend to agree "let's not change this just to change it again". But I remain unconvinced that we can find a much better API than the current messy one. Maybe if our only goal is to distinguish opcodes which are followed by other non-opcode data, from opcodes which are "zero sized", that would work since this is an unambiguous partition of all the opcodes. But "push vs non-push", "numeric vs non-numeric", cannot be so clearly separated. This also maybe mixes in with #1324 because we may want some opcodes It all seems like a big difficult problem. |
Is your idea to just merge it nd iterate on that? That's not too bad for something you doubt can be done (I think it can).
My design idea has no problem with that. The intention is mainly to verify an opcode is usable in certain context.
Yes, it does and my idea should work with it too. It'll be a bit more fiddly but not a huge issue, I think. |
Yes, that's my vote -- though I expect that whatever we release in 0.30 won't be the final form, and that we'll have more breakage in 0.31. If you want to avoid repeated breakage like that, we should hold off on merging this until we've come up with a more comprehensive design. I'd rather just move forward and iterate, though I don't feel super strongly. |
OK, no problem with merging and I will try to find some time to sketch up alternative before 0.30 is released. But even then I don't expect 0.30 to become stable. The whole stabilization project is an insane monstrosity and will take time. |
Lolz, the same thought had occurred to me of late. |
e1eb641
to
d5d34a2
Compare
Mentioned in PR description but double posting, now includes importing with wildcard and removing the |
Ok, weak concept ACK on this design. I agree it's annoying to write But for opcodes maybe it's okay to make an exception because there's so many of them and they're all easily identifiable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK d5d34a2a7611a6c3fe984df8397cde2b6567e386
hmmm, if you have any apprehension over wildcard imports then perhaps this PR is not good because it allows use of naked |
Oh, yes, accidental import of One thing about wildcard imports: if you have only one it's easy to conclude "there's one wildcard import so the item must coms from it". It's still harder than not having it but the tradeoff seems in favor of using it here. |
We have all of the opcodes defined in a submodule called `all`, this allows wildcard imports without bringing in the other types in the `opcodes` module. Use wildcard import `use crate::blockdata::opcodes::all::*` instead of fully qualifying the path to opcodes.
d5d34a2
to
c3e4399
Compare
opcodes::all
Huh, hilariously the wildcard usage is currently supported in a super clean way because we have the Excuse the noise, this was a very roundabout way to find a pretty basic improvement, amusingly no one else saw it either :) |
Do we want to keep the name |
Yeah I rekon this usage by users of the lib reads nicely
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK c3e4399
I'd also ACK a future commit/PR explicitly promising in the doc that the all
module will only ever contain opcodes prefixed with OP_
so it's OK to glob-import as long as the user doesn't have any other OP_
items in the module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK c3e4399
2157e69 Document the `all` module (Tobin C. Harding) Pull request description: Improve documentation on the `all` module by doing: - Document guarantee that `all` will only ever contain opcode constants - Fix stale/incorrect code comment Done as follow up to #1295 ACKs for top commit: apoelstra: ACK 2157e69 Kixunil: ACK 2157e69 Tree-SHA512: 4df091bbdce7b9ba73caabd74b80f9e8c0a30fa2f9a20ed9b75542e71a204e5cd82698a74bebbd6f0beab55ecd807154d1b7d27a787cc9dede7abbd20a0a4ad5
We have all of the opcodes defined in a submodule called
all
, this allows wildcard imports without bringing in the other types in theopcodes
module.Use wildcard import
use crate::blockdata::opcodes::all::*
instead of fully qualifying the path to opcodes.Original PR description (left here so the thread of discussion below makes sense)
The
all
module adds no value, we can remove it without loss of meaning or clarity, doing so makes the code less verbose.EDIT: After review, now includes importing with wildcard and removing the
opcodes::
path from any type starting withOP_
.Idea stolen from: #525 (patch 7)