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

Optimize calldata requirements for static contracts #115

Closed
adlerjohn opened this issue Feb 25, 2021 · 14 comments · Fixed by #125
Closed

Optimize calldata requirements for static contracts #115

adlerjohn opened this issue Feb 25, 2021 · 14 comments · Fixed by #125
Assignees
Labels
comp:FVM Component: FuelVM comp:VAL Component: Transaction Validity outside the Fuel VM enhancement New feature or request

Comments

@adlerjohn
Copy link
Contributor

adlerjohn commented Feb 25, 2021

Currently, loading code from a contract requires declaring that contract as an input (and as an output). Explorer if we can reduce the data that needs to be declared in order to support this functionality.

Consideration: we want to guarantee that transactions across blocks can also be validated in parallel (modulo UTXO existence, which requires a sequential pass).

One possibility is for contracts to declare once, on contract creation, a static list of contract IDs that can be loaded. Then, LOADCODE would panic if the contract to load code from is not in both the input list and static list.

Pros: easy.
Cons: not very flexible.

@adlerjohn adlerjohn added the question Further information is requested label Feb 25, 2021
@SilentCicero
Copy link
Member

SilentCicero commented Feb 25, 2021

One option is to make a simple access list in the transaction format, and then have an opcode which simply references this in execution.

Proposed:

TransactionCreate

name type description
gasPrice uint64 Gas price for transaction.
gasLimit uint64 Gas limit for transaction.
maturity uint64 Block until which tx cannot be included.
bytecodeLength uint16 Contract bytecode length, in instructions.
bytecodeWitnessIndex uint8 Witness index of contract bytecode to create.
inputsCount uint8 Number of inputs.
outputsCount uint8 Number of outputs.
witnessesCount uint8 Number of witnesses.
contractsCount uint16. Number of static contacts.
salt byte[32] Salt.
inputs Input[] List of inputs.
outputs Output[] List of outputs.
witnesses Witness[] List of witnesses.
contracts Contracts byte[][32] List of contract ID's.

Opcode: Static Load Code

SLOADCODE( staticContractIndex ) loads contract code into runtime.

Parallelism

This way, we can statically analyse what contract call is depending on which blocks and have a pathway to parallelism for cross-block parallel processing.

Notes

  • This would not replace LOADCODE and would simply be an akin code to it for static loading of contract data.

@adlerjohn
Copy link
Contributor Author

There's definitely value in a different opcode instead of repurposing an existing opcode.

@SilentCicero
Copy link
Member

@adlerjohn you can keep the existing LOADCODE opcode, this is a new opcode SLOADCODE.

@adlerjohn
Copy link
Contributor Author

you can keep the existing LOADCODE opcode, this is a new opcode SLOADCODE

Right. I'm saying that that's not a bad idea.

@SilentCicero
Copy link
Member

Alright, sounds about right.

@adlerjohn
Copy link
Contributor Author

Correction: " contracts | Contracts byte[6] | List of contract ID's."

This should be a list of contract IDs, not pointers. The user needs to sign over the actual contract IDs to prevent re-orgs from being unsafe.

@SilentCicero
Copy link
Member

Sorry, do you mean contract addresses and ID's? Are you looking for a hash here?

@adlerjohn
Copy link
Contributor Author

Contract ID on Fuel is equivalent to contract address on Ethereum. It's a 32-byte hash computed here https:/FuelLabs/fuel-specs/blob/f1e49fb2c050618373c5f8b494b33057f5a7215e/specs/protocol/tx_format.md#transactioncreate

@SilentCicero
Copy link
Member

@SilentCicero would it not be nicer to do contract ID + the block number referenced? I'd assume that would be easier to manage for parallelism.

It's a one time cost, so I don't mind.

@SilentCicero
Copy link
Member

Also, Contract ID should be added to the ID's document, I didn't see it there and thought we didn't formally state it. Organizational thought.

@adlerjohn
Copy link
Contributor Author

would it not be nicer to do contract ID + the block number referenced? I'd assume that would be easier to manage for parallelism.

It wouldn't gain you anything because when posted to Ethereum, the contract ID will be replaced with a pointer, which includes the block number.

@SilentCicero
Copy link
Member

SilentCicero commented Feb 25, 2021

Ah, I see now.

Is there any reason why we can't just use inputs for this instead of contractsCount and contracts? I.e. the opcode would just reference that input.

It might be nice as we can really release limits on contractsCount vs inputs (which have a slightly different meaning in state).

Thoughts?

So the SLOADBYTES would just select from the inputs list here, would that even work? That way it's all still UTXOish, and inline with access thinking, but without a new property/concept.

I.e. just static access inputs particularly.

@adlerjohn
Copy link
Contributor Author

adlerjohn commented Feb 25, 2021

I'm not sure what the benefit of repurposing inputs would be. There doesn't seem to be one. If anything it would increase costs because it would require you to add an output for each contract at the input. While if you just listed the contracts, then you save on the outputs.

without a new property/concept

A distinct way of doing things is better than a special case of an existing thing. Much easier to reason about. Hence

There's definitely value in a different opcode instead of repurposing an existing opcode.

@SilentCicero
Copy link
Member

Sounds good, well I'm fine with the methods sited above for this. Seems very straight forward and reasonable.

I.e. seperate opcode, the tx format change.

@adlerjohn adlerjohn added comp:FVM Component: FuelVM comp:VAL Component: Transaction Validity outside the Fuel VM enhancement New feature or request and removed question Further information is requested labels Feb 27, 2021
@adlerjohn adlerjohn self-assigned this Feb 27, 2021
@adlerjohn adlerjohn changed the title Consider optimizing data required for static contracts Optimizing calldata requirements for static contracts Feb 27, 2021
@adlerjohn adlerjohn changed the title Optimizing calldata requirements for static contracts Optimize calldata requirements for static contracts Feb 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:FVM Component: FuelVM comp:VAL Component: Transaction Validity outside the Fuel VM enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants