Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upFix displaying of invalid and non-minimal small pushes as numbers #8598
Conversation
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
jonasschnelli
Aug 26, 2016
Member
Would you mind adding some unit tests for this? There are already some ScriptToAsmStr() in script_tests.cpp?
|
Would you mind adding some unit tests for this? There are already some |
jonasschnelli
added
the
RPC/REST/ZMQ
label
Aug 26, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Sure, I'll give it a go. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
luke-jr
Aug 27, 2016
Member
hex script: 0181 hex script: 0181
"asm": "[error]", "asm": "-1",
hex script: 0101 hex script: 0101
"asm": "[error]", "asm": "1",
Am I missing something? Why are these errors? Shouldn't they be valid non-minimally-encoded numbers to display as hex?
Also, it seems this creates ambiguity between number and hex literals in asm? "10" asm could be either "5a" or "0110" now, right?
Am I missing something? Why are these errors? Shouldn't they be valid non-minimally-encoded numbers to display as hex? Also, it seems this creates ambiguity between number and hex literals in asm? "10" asm could be either "5a" or "0110" now, right? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
fivepiece
Aug 27, 2016
Contributor
Thanks for the feedback!
As I understand it, "wasteful" data pushes are themselves invalid. It's fine to push a non-minimally encoded number and then not do math operations on it, but pushing a value with an a "larger" opcode would fail. So in the case of 0x81 and [0x01,0x10], not using 1NEGATE or OP_1-OP_16 would cause the script to fail :
$ bitcoin-cli decodescript 51A8204BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A87 | grep asm
"asm": "1 OP_SHA256 4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a OP_EQUAL",
$ bitcoin-cli signrawtransaction \
0100000001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa00000000252451a8204bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a87ffffffff0100000000000000001976a914bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb88ac00000000 \
'[{"txid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","vout":0,"scriptPubKey":"A91405FCBC74F0D5EAE9229CDED69AF137CAD27834F587","redeemScript":"51A8204BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A87","amount":0}]'
...
"complete": true
vs
$ bitcoin-cli decodescript 0101A8204BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A87 | grep asm
"asm": "1 OP_SHA256 4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a OP_EQUAL",
$ bitcoin-cli signrawtransaction \
0100000001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000026250101a8204bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a87ffffffff0100000000000000001976a914bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb88ac00000000 \
'[{"txid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","vout":0,"scriptPubKey":"A914120FD81D49579E40E968EEDD5215E92644BBD48A87","redeemScript":"0101A8204BF5122F344554C53BDE2EBB8CD2B7E3D1600AD631C385A5D7CCE23C7785459A87","amount":0}]'
{
"hex": "0100000001aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0000000026250101a8204bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a87ffffffff0100000000000000001976a914bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb88ac00000000",
"complete": false,
"errors": [
{
"txid": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"vout": 0,
"scriptSig": "250101a8204bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a87",
"sequence": 4294967295,
"error": "Data push larger than necessary"
}
]
}
As for the ambiguity, specifically wrt 10 in asm, after this change, the only case where you'd see a 10 is if you executed 5a. Currently you will see 10 either by using 5a or 010a (though this is not a valid push). To actually push the byte 0x10 you would have to use OP_16, 60.
I do agree that numbers in base 10 and short hex are ambigous in asm (like the example in OP with 52), but that is already the case. This change only helps in the sense that values that would not pass as numbers, are not displayed as such.
You have given me more food for thought, what about larger invalid push operations? Those still do not appear as errors after this change.
For example this script would also fail;
4C0175A8200BFE935E70C321C7CA3AFC75CE0D0CA2F98B5422E008BB31C00C6D7F1F1C0AD687
If I'm wrong and these "larger than necessary" are not invalid, then you are correct that the '[error]'s should be removed and the original functionality restored.
|
Thanks for the feedback! As I understand it, "wasteful" data pushes are themselves invalid. It's fine to push a non-minimally encoded number and then not do math operations on it, but pushing a value with an a "larger" opcode would fail. So in the case of
vs
As for the ambiguity, specifically wrt I do agree that numbers in base 10 and short hex are ambigous in asm (like the example in OP with You have given me more food for thought, what about larger invalid push operations? Those still do not appear as errors after this change. If I'm wrong and these "larger than necessary" are not invalid, then you are correct that the '[error]'s should be removed and the original functionality restored. |
fivepiece
added some commits
Aug 28, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
fivepiece
Aug 28, 2016
Contributor
I've added a check that happens if the push opcode is PUSHDATA1 - PUSHDATA4.
A temporary script is created that only pushes the data, then we compare our own push op with the one the script has.
I'm guessing this does cost some to execute, but I think it's better to eventually return an "[error]" instead of some wasteful push that will produce errors on actual script evaluation.
Thoughts?
|
I've added a check that happens if the push opcode is Thoughts? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sipa
Sep 4, 2016
Member
MINIMALDATA is not a consensus rule, and transactions that use non-minimal pushes or non-minimally encoded numbers are perfectly valid in blocks. I don't think we should fail to decode them. I don't really have good advice here, as I'm fine with somehow marking these as different, but they shouldn't fail to decode.
|
MINIMALDATA is not a consensus rule, and transactions that use non-minimal pushes or non-minimally encoded numbers are perfectly valid in blocks. I don't think we should fail to decode them. I don't really have good advice here, as I'm fine with somehow marking these as different, but they shouldn't fail to decode. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
fivepiece
Sep 4, 2016
Contributor
Seems like I was fixing a problem that did not exist in the first place. I will be closing this PR for the sake of resubmitting another one which should reflect non-standard use of Script in a warning fasion rather than error and terminate.
Both non-minimally encoded numbers /and/ wasteful pushes are valid in blocks. Thanks @sipa for clarifying.
|
Seems like I was fixing a problem that did not exist in the first place. I will be closing this PR for the sake of resubmitting another one which should reflect non-standard use of Script in a warning fasion rather than error and terminate. Both non-minimally encoded numbers /and/ wasteful pushes are valid in blocks. Thanks @sipa for clarifying. |
fivepiece commentedAug 26, 2016
•
edited
Currently, commands like
decodescriptthat return an assembly representation of the script will show seemingly valid integers for a number of incorrectly pushed int values of sizes 0 to 4. The purpose of this change is to allowScriptToAsmStrto return a more accurate representation of the assembly.In addition,
ScriptToAsmStrwill not fail on what are considered invalid pushes altogether. This change will makeScriptToAsmStrreturn an '[error]' string, much like other invalid pushes.I believe this makes more sense when displaying decoded script.
As opposed to showing the valid representation of an int for an incorrectly pushed value, the value is returned either as a number if both the push is minimal and the encoding is correct, or as hex if the push is not minimal. Invalid pushes are shown as '[error]' and end the decoding.
Examples:
Here the first two pushes are valid numbers. The rest are shown as hex data.
Pushing -1,[1,16] incorrectly, after and before the patch.
Actual example of how '0' and '0x00' are different. Both pushes are currently shown as '0'. After the patch, the first will be shown as '0' and the second as '00', making the distinction more obvious.
vs