Skip to content

Conversation

@sanket1729
Copy link
Contributor

Error messages in clean stack is misleading as it lets the user believe that there are extra
elements on the stack which is incorrect if the stack is empty.

Let me know if this requires additional test.

Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK c2f00b7e2f6c17083b7c72555f5a366c9ff8c673

Agree that this is misleading.

Copy link
Member

@glozow glozow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK c2f00b7
An empty stack is a SCRIPT_ERR_EVAL_FALSE, yes?

@darosior
Copy link
Member

darosior commented Sep 24, 2020

An empty stack is a SCRIPT_ERR_EVAL_FALSE, yes?

No, it's SCRIPT_ERR_CLEANSTACK.

That's actually the point of this change :)
Relevant line:

// Scripts inside witness implicitly require cleanstack behaviour
if (stack.size() != 1) return set_error(serror, SCRIPT_ERR_CLEANSTACK);
if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
return true;

@glozow
Copy link
Member

glozow commented Sep 24, 2020

@darosior
I meant to clarify that, if we want a clean stack (i.e. script flag SCRIPT_VERIFY_CLEANSTACK), we want to end up with 1 item exactly.
We never want 0 items, as that would be a SCRIPT_ERR_EVAL_FALSE.
I wouldn't ACK without thinking there's a point :)

Copy link
Member

@instagibbs instagibbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK c2f00b7

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is trivial change anyways, maybe "must be exactly one", somehow reads better to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This sounds better.

@theStack
Copy link
Contributor

theStack commented Sep 24, 2020

ACK c2f00b7

An empty stack is a SCRIPT_ERR_EVAL_FALSE, yes?

That was also my initial thought. After digging deeper into the VerifyScript() function though I think this is only true for native txs (w/o SegWit). With SegWit involved, in the following part, in the function ExecuteWitnessScript() it could happen that after running the witness script the stack is empty, but still SCRIPT_ERR_CLEANSTACK is thrown:

// Run the script interpreter.
if (!EvalScript(stack, scriptPubKey, flags, checker, sigversion, serror)) return false;
// Scripts inside witness implicitly require cleanstack behaviour
if (stack.size() != 1) return set_error(serror, SCRIPT_ERR_CLEANSTACK);
if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE);
return true;

Don't know though if that is intended or it was just forgotten to implicitely check for empty and return SCRIPT_ERR_EVAL_FALSE in this place. (For practical matters it shouldn't make a difference, in any case the script fails).

Error messages in cleanstack is misleading as
it lets the user believe that there are extra
elements on stack which is incorrect if the
stack is empty.
@sipa
Copy link
Member

sipa commented Sep 24, 2020

For context, I believe the current behavior is:

  • For non-segwit spends, SCRIPT_ERR_CLEANSTACK is only returned when SCRIPT_VERIFY_CLEANSTACK is enabled, and refers strictly to stacks larger than 1 (because if the size was 0, SCRIPT_ERR_EVAL_FALSE would have been triggered already).
  • For segwit spends, SCRIPT_ERR_CLEANSTACK is returned for any script size different from exactly 1, and doesn't need the SCRIPT_VERIFY_CLEANSTACK flag.

I'm ok with this PR as is, but perhaps it's more insightful to split up the two cases entirely, and give them separate error codes?

@instagibbs
Copy link
Member

@sipa if we do that might as well do minimalif too and any others similar

@sipa
Copy link
Member

sipa commented Sep 24, 2020

@instagibbs I don't think there are any others like that currently. Splitting out the consensus-defined MINIMALIF behavior in #19953 into a separate error code does make sense.

@instagibbs
Copy link
Member

filed an issue in case someone wants to do it later(or sanket now if he wants)

@sanket1729
Copy link
Contributor Author

@theStack, yup I faced when evaluating Segwit script.

I can take on #20009. I think still PR is conceptually independent, so I will keep this open.
Let me know if I should close this and address this issue along with the separation of Errors.

Copy link
Contributor

@theStack theStack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-ACK af57766

@instagibbs
Copy link
Member

re-ACK af57766

Copy link
Member

@darosior darosior left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re ACK af57766

@glozow
Copy link
Member

glozow commented Sep 26, 2020

reACK af57766

@laanwj laanwj merged commit 4f5ae52 into bitcoin:master Sep 30, 2020
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Sep 30, 2020
af57766 Fix misleading error message: Clean stack rule (sanket1729)

Pull request description:

  Error messages in clean stack is misleading as it lets the user believe that there are extra
  elements on the stack which is incorrect if the stack is empty.

  Let me know if this requires additional test.

ACKs for top commit:
  instagibbs:
    re-ACK bitcoin@af57766
  gzhao408:
    reACK bitcoin@af57766
  theStack:
    re-ACK af57766
  darosior:
    re ACK af57766

Tree-SHA512: 88e77416e220b080246fec368f5552a891d102d072b7bee62ac560d5e31c4a8c2ee9cbe569740b253e9df177d21dc788d10d856b2a542ab47761bb81698e4082
sanket1729 added a commit to sanket1729/bitcoin that referenced this pull request Jan 26, 2021
CleanStack rule is consensus enforced in Segwitv0.
See discussion in bitcoin#20006 for motivation
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Nov 3, 2021
Summary:
Error messages in cleanstack is misleading as
it lets the user believe that there are extra
elements on stack which is incorrect if the
stack is empty.

This is a backport of [[bitcoin/bitcoin#20006 | core#20006]]

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, majcosta

Reviewed By: #bitcoin_abc, majcosta

Differential Revision: https://reviews.bitcoinabc.org/D10411
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Feb 15, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants