-
Notifications
You must be signed in to change notification settings - Fork 95
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
mandatory-script-verify-flag-failed (Push value size limit exceeded) error occurs when sending raw tx with Taproot inscriptions exceeding ~500KB #69
Comments
The issue wasn't confirmed. I verified the script with bitcoin core decodescript JSON RPC API and it returned correctly parsed synthetic data I referenced above. This means serialization, padding and endianness are correct.
I'm investigating further why my specific data is not processed properly though. My script: content = '<!DOCTYPE html><html><body><img width=100 height=100 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAGlQTFRF////39/f9vb2UVFR7Ozsi4uL4uLi3d3dODg4eXl58PDwZGRk2dnZp6en+vr66OjoHBwcmJiYXV1dLCwsbm5u5eXlkZGRPT09hISE/f39SEhIfn5+s7OzcHBwxsbG0NDQoKCgu7u7Tk5OFhbxHAAAAHFJREFUeJy9j0kKgDAMRWPbVDvY2jrPw/0PaRQX7gUfhIRH8iEAf+ETglEJYKvsJU0SciwV2hJxt+3WLaErsKFdnoLg1HN1XbLsDrhkwfmkYzuztzyc6ym/Gd9yqGuRpJoSHokedDQm2MpUGpz67fHPnDHBBHGtTb5yAAAAAElFTkSuQmCC"></body></html>'.encode("utf-8")
taproot_script_p2pk = Script(
[
priv_key.get_public_key().to_x_only_hex(),
"OP_CHECKSIG",
"OP_0",
"OP_IF",
"ord".encode("utf-8").hex(),
"01",
MIME_TYPE.encode("utf-8").hex(),
"OP_0",
content.hex(),
"OP_ENDIF",
]
)
Decoded tx:
Decoded script:
I successfully recovered my data in reverse direction: Noticeably that the shorter data that fits OP_PUSHDATA_1 below gets processed correctly:
successful rawtx:
decoded:
witness script decoded:
All other code and datapath are absolutely same, plus I've isolated #68 using pickle library for serdes and additional assertions that guarantee consistency of taproot script hex. |
I've figured out the root cause of the If you encounter this error, you'll need to break down long data into smaller tokens (I used 512 bytes for better kilobyte-alignment), and then use these minimized tokens in the script. Here’s a function and an example of how to use it, shown below. # To avoid `mandatory-script-verify-flag-failed (Push value size limit exceeded)` in bitcoin-core
# See https://github.com/bitcoin/bitcoin/blob/0de63b8b46eff5cda85b4950062703324ba65a80/src/script/script.h#L27
# and https://github.com/karask/python-bitcoin-utils/issues/69
def chunk_script_element(data: bytes):
BTC_CORE_MAX_SCRIPT_ELEMENT_SIZE = 512
for i in range(0, len(data), BTC_CORE_MAX_SCRIPT_ELEMENT_SIZE):
yield data[i:i+BTC_CORE_MAX_SCRIPT_ELEMENT_SIZE] Example use for ordinals case taproot_script_p2pk = Script(
[
priv_key.get_public_key().to_x_only_hex(),
"OP_CHECKSIG",
"OP_0",
"OP_IF",
"ord".encode("utf-8").hex(),
"01",
MIME_TYPE.encode("utf-8").hex(),
"OP_0",
*[chunk.hex() for chunk in chunk_script_element(content)],
"OP_ENDIF",
]
) |
@karask maybe incorporate this chunking approach in Script class by default? |
Hi @ongrid and thanks for the feedback The tx size block weight limit for a user (not miner) is 400kBs, not 500. I went through the issues quite quickly just to get an idea of the problem. Indeed, data pushes need to be in chunks of 520 bytes, so for inscriptions you would need sth like this: OP_FALSE I have not tested this limit myself and I will when I find some time. I was away in an event and I will soon be away again so not sure when I will spent some time on this. Meanwhile make sure you try <400kBs txs when testing. |
Hi @ongrid , For now, the library rarely does execution validation; it leaves this to the node. Validating txs in the library would involve a ton of work (and maintenance to keep it in sync with Bitcoin core). Maybe a check could be added to see if the size is >520 but definitely not a priority. |
Update: The root cause of the
mandatory-script-verify-flag-failed (Push value size limit exceeded)
error when processing thesendrawtransaction
command by Bitcoin Core, is the script tokensize limit defined in bitcoindMAX_SCRIPT_ELEMENT_SIZE = 520
constant https://github.com/bitcoin/bitcoin/blob/0de63b8b46eff5cda85b4950062703324ba65a80/src/script/script.h#L27If you encounter this error, you'll need to break down long data into smaller tokens (I used 512 bytes for better kilobyte-alignment), and then use these minimized tokens in the script. Here’s a function and an example of how to use it, shown below.
Example use for ordinals case
My suspicions that the problem was with the functions in the Script class were not confirmed.
The text was updated successfully, but these errors were encountered: