-
Notifications
You must be signed in to change notification settings - Fork 136
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
OP_CHECKSIGADD got left behind! #151
base: master
Are you sure you want to change the base?
Conversation
Is this function ever used by something that invokes it in a tapscript context? If so, could you add a regression test? |
Hey, yeah so if you try the following transaction, btcdeb wont be able to decode the script itself even if the script lead to an invalid transaction (on purpose, the script itself will be reverted after stack execution):
After the change, the transaction can be executed without any problems. Here is a valid version of the transaction. This transaction includes empty witnesses (so it works with OP_CHECKSIGADD). There is an other bug in btcdeb code. You can reproduce it via the following command (I did not fix it yet.):
Currently this valid transaction error with the following: The error is due to an invalid opcode being decoded: 32765. I would have to debug the code futher to find the cause of that bug. As mentioned in BIP 342, this should be possible: https://en.bitcoin.it/wiki/BIP_0342 Potentially, we should add a check to verify that the transaction is taproot, if its not taproot, this opcode is not valid. This opcode is only usable for tapscript transactions. Here the transaction on my local testnet: |
thanks man, this works like a charm, so far so good when I am using OP_CHECKSIGADD with |
|
No. Try it in a tapscript like the example provided. Without this, it does NOT work inside tapscripts. Try it yourself. If this is not the intended behavior, you have a major issue somewhere. |
--- a/btcdeb.cpp
+++ b/btcdeb.cpp
@@ -242,9 +242,9 @@ int main(int argc, char* const* argv)
}
}
- CScript script;
if (script_str) {
- if (instance.parse_script(script_str)) {
+ int witprogver = ((flags & SCRIPT_VERIFY_TAPROOT) != 0 ? 1 : 0);
+ if (instance.parse_script(witprogver, script_str)) {
if (verbose) btc_logf("valid script\n");
} else {
fprintf(stderr, "invalid script\n");
--- a/instance.cpp
+++ b/instance.cpp
@@ -93,7 +93,7 @@ bool Instance::parse_input_transaction(const char* txdata, int select_index) {
return true;
}
-bool Instance::parse_script(const char* script_str) {
+bool Instance::parse_script(int witprogver, const char* script_str) {
std::vector<unsigned char> scriptData = Value(script_str).data_value();
script = CScript(scriptData.begin(), scriptData.end());
// for (const auto& keymap : COMPILER_CTX.keymap) {
@@ -110,12 +110,12 @@ bool Instance::parse_script(const char* script_str) {
// printf("miniscript failed to parse script; miniscript support disabled\n");
// msenv = nullptr;
// }
- return script.HasValidOps();
+ return witprogver != 0 || script.HasValidOps();
}
-bool Instance::parse_script(const std::vector<uint8_t>& script_data) {
+bool Instance::parse_script(int witprogver, const std::vector<uint8_t>& script_data) {
script = CScript(script_data.begin(), script_data.end());
- return script.HasValidOps();
+ return witprogver != 0 || script.HasValidOps();
}
bool Instance::parse_pretend_valid_expr(const char* expr) {
@@ -545,7 +545,7 @@ bool Instance::configure_tx_txin() {
}
} else assert(!"should never get here; was a new witprogver added?");
- if (parse_script(std::vector<uint8_t>(validation.begin(), validation.end()))) {
+ if (parse_script(witprogver, std::vector<uint8_t>(validation.begin(), validation.end()))) {
btc_logf("valid script\n");
} else {
fprintf(stderr, "invalid script (witness stack last element)\n");
--- a/instance.h
+++ b/instance.h
@@ -68,8 +68,8 @@ public:
bool parse_transaction(const char* txdata, bool parse_amounts = false);
bool parse_input_transaction(const char* txdata, int select_index = -1);
- bool parse_script(const char* script_str);
- bool parse_script(const std::vector<uint8_t>& script_data);
+ bool parse_script(int witprogver, const char* script_str);
+ bool parse_script(int witprogver, const std::vector<uint8_t>& script_data);
void parse_stack_args(size_t argc, char* const* argv, size_t starting_index);
void parse_stack_args(const std::vector<const char*> args);
diff --git a/tap.cpp b/tap.cpp
index 991571c..4e01d8b 100644
--- a/tap.cpp
+++ b/tap.cpp
@@ -265,7 +265,7 @@ int main(int argc, char* const* argv)
for (size_t i = 0; i < script_count; ++i) {
Item scriptData = Value(ca.l[2 + i]).data_value();
CScript script = CScript(scriptData.begin(), scriptData.end());
- if (!script.HasValidOps()) {
+ if (!is_tapscript && !script.HasValidOps()) {
abort("invalid script #%zu: %s", i, HEXC(scriptData));
}
if (!quiet) { (test/signing.cpp also needs to be See also bitcoin/bitcoin#22338 |
OP_CHECKSIGADD got left behind!
We can not parse a transaction containing OP_CHECKSIGADD opcodes due to the following check: