Skip to content
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

Lower transaction size limit to 1.5MiB #11379

Closed
wants to merge 1 commit into from

Conversation

jancionear
Copy link
Contributor

@jancionear jancionear commented May 22, 2024

Lower transaction size limit to 1.5MiB

The size limit for a single transaction used to be 4MiB, this PR reduces it to 1.5MiB. Transactions larger than 1.5MiB will be rejected.

This is done to help with #11103. It's hard to limit the size of ChunkStateWitness when a single transaction can be as large as 4MiB. Having 1.5MiB transactions makes things much more manageable.

This will break some transactions.
On current mainnet there is approximately one transaction larger than 1.5MiB per day (~420 large txs per year).
We've decided that it's okay to break those transactions.
List of transactions larger than 1.5MiB from the last year of mainnet traffic: broken-transactions.txt

The new limit is introduced in protocol version 68.
This protocol version could be released before the full stateless validation launch, to see if anyone complains.

Note that this change doesn't limit the size of receipts, only transactions. It's still possible to create a receipt with a 4MiB contract or function call, but that's out of scope for the transaction size limit.

Zulip discussion about lowering the limit: https://near.zulipchat.com/#narrow/stream/295306-contract-runtime/topic/.E2.9C.94.20Lowering.20the.20limit.20for.20contract.20code.20size

The size limit for a single single transaction used to be 4MiB,
this PR reduces it to 1.5MiB. Transactions larger than 1.5MiB will be rejected.

This is done to help with near#11103.
It's hard to limit the size of `ChunkStateWitness` when a single transaction
can be as large as 4MiB. Having 1.5MiB transactions makes things much more manageable.

This will break some transactions.
On current mainnet there is approximately one transaction larger than 1.5MiB per day (~420 large txs per year).
We've decided that it's okay to break those transactions.

The new limit is introduced in protocol version `68`.
This protocol version could be released before the full stateless validation launch, to see if anyone complains.

Note that this change doesn't limit the size of receipts, only transactions.
It's still possible to create a receipt with a 4MiB contract or function call,
but that's out of scope for the transaction size limit.

Zulip discussion about lowering the limit: https://near.zulipchat.com/#narrow/stream/295306-contract-runtime/topic/.E2.9C.94.20Lowering.20the.20limit.20for.20contract.20code.20size
@jancionear jancionear requested a review from bowenwang1996 May 22, 2024 19:35
@jancionear jancionear requested a review from a team as a code owner May 22, 2024 19:35
@jancionear
Copy link
Contributor Author

jancionear commented May 22, 2024

tests/sanity/upgradable.py failed, difference between the current master protocol version (66) and the new one (68) is greater than one :/

[2024-05-22 19:46:43] INFO: Getting neard for 1.39.1@Linux (deploy=14334b9e4e2bff198537130324f2bb9702f54d6d)
[2024-05-22 19:46:43] INFO: Got protocol 66 in mainnet release 1.39.1.
[2024-05-22 19:46:43] INFO: Got protocol 66 in testnet release 1.39.1.
[2024-05-22 19:46:43] INFO: Got protocol 68 on master branch.

I guess #11368 would help with that...

Comment on lines 162 to -163
max_contract_size 4_194_304
max_transaction_size 4_194_304
Copy link
Contributor

Choose a reason for hiding this comment

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

Does setting lower max_transaction_size implicitly limit the contract size as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not necessarily, as the size limit for receipts is still 4MiB, so I think that a contract could potentially deploy another 4MiB contract.

Copy link
Contributor

Choose a reason for hiding this comment

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

But still it will make it impossible to deploy a large contract using the most common case of deploy action in a single transaction right? Just to be clear I'm not against it, just making sure that you considered this consequence.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

But still it will make it impossible to deploy a large contract using the most common case of deploy action in a single transaction right?

Yes, it's a breaking change :/

I'm currently focused on limiting transactions, so this PR only adds a limit for transactions, but in the future that might be extended to receipts as well. (possibly for #11295)

@jancionear
Copy link
Contributor Author

Closing in favor of #11406

@jancionear jancionear closed this May 28, 2024
github-merge-queue bot pushed a commit that referenced this pull request May 30, 2024
…1406)

Fixes: #11103

This PR adds 3 new limitations to control total size of transactions
included in ChunkStateWitness
1) Reduce `max_transaction_size` from 4MiB to 1.5MiB. Transactions
larger than 1.5MiB will be rejected.
2) Limit size of transactions included in the last two chunks to 2MiB.
`ChunkStateWitness` contains transactions from both the current and the
previous chunk, so we have to limit the sum of transactions from both of
those chunks.
3) Limit size of storage proof generated during transaction validation
to 500kiB (soft limit).

In total that limits the size transaction related fields to 2.5MiB.

About 1):
Having 4MiB transactions is troublesome, because it means that we have
to allow at least 4MiB of transactions to be included in
`ChunkStateWitness`. Having so much space taken up by the transactions
could cause problems with witness size. See
#11379 for more information.

About 2):
`ChunkStateWitness` contains both transactions from the previous chunk
(`transactions`) and the new chunk (`new_transactions`). This is
annoying because it halves the space that we can reserve for
transactions. To make sure that the size stays reasonable we limit the
sum of both those fields to 2MiB. On current mainnet traffic the sum of
these fields stays under 400kiB, so 2MiB should be more than enough.
This limit has to be slightly higher than the limit for a single
transaction, so we can't make it 1MiB, it has to be at least 1.5MiB.

About 3):
On mainnet traffic the size of transactions storage proof is under
500kiB on most chunks, so adding this limit shouldn't affect the
throughput. I assume that every transactions generates a limited amount
of storage proof during validation, so we can have a soft limit for the
total size of storage proof. Implementing a hard limit would be
difficult because it's hard to predict how much storage proof will be
generated by validating a transaction.

Transactions are validated by running `prepare_transactions` on the
validator, so there's no need for separate validation code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants