FuelError: Invalid u16, too many bytes

I’m able to compile a very large contract of mine (824.216 Kb compiled bytecode; ~2k+ lines) with Beta-5 and latest toolchain, BUT I’m not able to deploy said contracts with either the generated types (AbiFactory, and AbiHex), or the ContractFactory method. This is the error I get: FuelError: Invalid u16, too many bytes.

The traceback:

     FuelError: Invalid u16, too many bytes.
      at NumberCoder.encode (node_modules/@fuel-ts/abi-coder/src/coders/number.ts:55:13)
      at TransactionCreateCoder.encode (node_modules/@fuel-ts/transactions/src/coders/transaction.ts:206:39)
      at TransactionCoder.encode (node_modules/@fuel-ts/transactions/src/coders/transaction.ts:372:40)
      at CreateTransactionRequest.toTransactionBytes (node_modules/@fuel-ts/providers/src/transaction-request/transaction-request.ts:189:35)
      at CreateTransactionRequest.byteSize (node_modules/@fuel-ts/providers/src/transaction-request/transaction-request.ts:518:17)
      at CreateTransactionRequest.calculateMinGas (node_modules/@fuel-ts/providers/src/transaction-request/transaction-request.ts:538:25)
      at _Provider.getTransactionCost (node_modules/@fuel-ts/providers/src/provider.ts:810:39)
      at ContractFactory.deployContract (node_modules/@fuel-ts/contract/src/contract-factory.ts:149:35)
      at /Users/sluzhba/Documents/Dev/Burra Labs/ruscet-contracts/tests/core/Tester.test.ts:87:22
      at step (tests/core/Tester.test.ts:33:23)

My guess is that there’s something in my contract that is causing this error, but can’t debug effectively because this contract file is ~2500 lines of code; but it appears that the error (too many bytes is loosely related to unable to offest [...] more than 2^12 bits. Maybe the contract is too big?

I’m using fuels v0.73.0 (fails with v0.74.0 too)

[For more context, please see: Compiler error: Unable to offset into the data section more than 2^12 bits. Unsupported data section length]

1 Like

Hi @theAusicist,

Are you building your contract using forc like this below?

forc build

If yes, you can try adding the --release flag:

forc build --release

You should get a much smaller output in release mode.

Please try it out and let me know how it goes.

yes!

tried this too with forc build --release --build-target fuel, got a smaller output, but the issue still remains :confused:

1 Like

OK, thanks for the quick response.

Have you also re-generated types using the release output? This is necessary since you are using the generated Contract/Typescript for deploying your contract.

You must also update paths when using typegen and point to the release/* directory instead of the debug/* one.

yup, have done so, but it’s the same error unfortunately. I tried commenting out certain functions in an attempt to diagnose the specific piece of code in my contract that may be causing this issue, but in vain. I however did notice that, while there’s no single piece of code that is erroring out, the AbiEncoder appears to have a size limit for encoding. That’s the only plausible explanation imo.

delved deeper into what might be causing the error, and I think I’ve got it. In the encode method, some value is being encoded. Turns out, one of the values being encoded is the size of the compiled bytecode. When this bytecode size exceeds 65535 (max value of u16), the byte length size of the value is 3 and the invariant fails.

Now somewhere when encoding this value, the baseType has been set to u16, so the max size of a contract (at least according to the encoder) is max(u16). Is this a bug, or expected?

@anderson @david

Update:
this is the error line. A fix for this error is by changing the u16 to u32 to allow for encoding of contracts (and consequently, bytecode sizes). Submitted a PR here – please have a look at lmk what you think

3 Likes

@theAusicist Thanks for your contributions! The fix will be in the 0.75.0 release.

Just to clarify something for us, did you ever successfully deploy this contract before reporting this issue or was this your first time trying to deploy it?

1 Like

super!

not my first time deploying a contract, but certainly wasn’t able to deploy this contract in particular because of its large size. I wasn’t able to deploy the contract even after successful encoding (with the fix above) because of the block gas limit being set to 30000000. I updated my own chainspec for my local node and increased this gas limit by several magnitudes and I could deploy successfully. I suppose deploying such a large contract on Beta-5 (or later) testnets would prove to be an issue given the gas limit.

this contract with bytecode size 506884 bytes (~0.5mb) requires 32845844 gas (vs the block gas limit of 30000000).

do you suppose it would be worth looking into raising the block gas limit in general? I mean, if Fuel can theoretically support contract deployments of up to 16.7mb, the gas limit is a limiting factor for contracts of sizes even smaller than this (0.5mb in my case)

@nedsalk

just bumping this @nedsalk!

@theAusicist I looked into what you reported around block gas limit with the core team and they say that this is expected. Later we will charge the user for storage in a separate way and it will be not mixed with the gas so you won’t be having these issues. Plus, we won’t be allowing 17MB contracts later on, it is too much.

1 Like

understood, but my contract is ~0.5mb, and just about crosses the block gas limit. Imo there should be a line in the documentation saying "while max contract size is 17Mb, the actual max size for a deployable contract is ~0.5mb

@nedsalk bumping this!