dgpv / bsst

B'SST: Bitcoin-like Script Symbolic Tracer
Other
34 stars 5 forks source link

Handle OP_SUCCESS-like behavior for opcodes like CHECKCONTRACTVERIFY #10

Open dgpv opened 1 year ago

dgpv commented 1 year ago

When we know that the upgradable opcode will definitely behave like OP_SUCCESS - when there's no possibility that it will behave as normal, we can stop the execution with a special "SUCCESS" code, rather than simply adding a warning.

This execution path need to be clearly marked in the report as "unconditional success because of SUCCESS-like behavior of upgradable opcode".

(edit) An example of such opcode is CHECKCONTRACTVERIFY: https://github.com/Merkleize/bitcoin/blob/705dc9e41450edca86413710fc137906f6e5c949/src/script/interpreter.cpp#L1177 -- this is a proposed opcode that is currently not available in bitcoin. Still, if we would like to analyze scripts with opcode that might directly call set_success(), we need to consider how to handle this correctly

ajtowns commented 1 year ago

Note that OP_SUCCESS behaviour occurs at initial parsing time, before any actual execution. 1 OP_IF OP_RETURN OP_ELSE OP_SUCCESS OP_ENDIF always succeeds, for example. (So there's not really an "execution path" if this is relevant)

dgpv commented 1 year ago

I was thinking not about OP_SUCCESS itself, but about a cases where other opcodes can behave like OP_SUCCESS depending on their arguments. ~For example, upgradable pubkeys in tapscript. Right now, for upgradable pubkeys, there will be a warning, even when it is certain that the pubkey will not have length 32. For these cases, the report needs to show more than just a warning~. Correction: upgradeable pubkeys do not entail OP_SUCCESS-like behavior, they just make signature check be successful.

It seems that the title and the first message did not clearly convey the intended meaning. I will edit them.

dgpv commented 1 year ago

Regarding OP_SUCCESS itself, bsst do not recognize this opcode: there's no utility in analyzing scripts that contain explicit OP_SUCCESS, for exactly the reason that you have stated.

ajtowns commented 1 year ago

I was thinking not about OP_SUCCESS itself, but about a cases where other opcodes can behave like OP_SUCCESS depending on their arguments. For example, upgradable pubkeys in tapscript.

Upgradable pubkeys isn't much different to setting your pubkey to G -- it's trivial to create a signature that satisfies the pubkey, but it doesn't change the behaviour of the rest of the script.

dgpv commented 1 year ago

You're correct, I has mixed up the case of upgradable pubkeys (which only cause their sig check operation to succeed) with the behavior defined for CHECKCONTRACTVERIFY: https://github.com/Merkleize/bitcoin/blob/705dc9e41450edca86413710fc137906f6e5c949/src/script/interpreter.cpp#L1177

That was my mistake, the cases of "upgradable pubkeys" and "undefined values for flags in CCV" are different. For CCV, it actually does set_success(), which should mean the script terminates immediately with success.

There are no currently enabled opcodes which call set_success directly. Maybe doing it for CCV was also not the best decision by the authors, although I don't have enough knowledge to say with certainty what is problematic with such approach of calling set_success from the opcode implementation. It complicates bsst analysis for sure though, by having us to consider this issue :-)

I will edit the title to explicitly mention CCV