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

Document the Blobstream contract gas usage #223

Closed
rach-id opened this issue Oct 11, 2023 · 1 comment
Closed

Document the Blobstream contract gas usage #223

rach-id opened this issue Oct 11, 2023 · 1 comment
Assignees
Labels
documentation Improvements or additions to documentation

Comments

@rach-id
Copy link
Member

rach-id commented Oct 11, 2023

No description provided.

@rach-id rach-id self-assigned this Oct 11, 2023
@rach-id rach-id added the documentation Improvements or additions to documentation label Oct 11, 2023
@rach-id
Copy link
Member Author

rach-id commented Oct 11, 2023

Gas Cost Benchmark

This document will contain a gas cost benchmark for BlobStream contract.

Real deployment to Sepolia

For a real deployment, where we have 100 validators, and 30 of them have 2/3rds of the network, the cost is 328,852 gas.

Contract link:

https://sepolia.etherscan.io/address/0xbefe11e2a35cefcb3552ff8ae56baaa14952331b

Code:

celestiaorg/orchestrator-relayer#524

if we profile the Sepolia transaction, we find the results in picture:

image

  • calldata and account access: 135736 gas
countNonZeroBytesInCalldata * 16 + countZeroBytesInCalldata * 4 + countAccountAccessList * 240
  • UUPS cost: 8371 gas

Foundry gas report

For foundry the cost of the same setup is: 201819 gas

Code:

#218

And if we dig deeper using foundry, we find the following:

|------------------------------------------------------------|-----------------|--------|--------|--------|---------|
| Deployment Cost                                            | Deployment Size |        |        |        |         |
| 1201301                                                    | 6048            |        |        |        |         |
| Function Name                                              | min             | avg    | median | max    | # calls |
| checkValidatorSignatures                                   | 130350          | 130350 | 130350 | 130350 | 1       |
| computeValidatorSetHash                                    | 21445           | 21445  | 21445  | 21445  | 1       |
| domainSeparateValidatorSetHash                             | 636             | 636    | 636    | 636    | 1       |
| initialize                                                 | 96320           | 96320  | 96320  | 96320  | 1       |
| submitDataRootTupleRoot                                    | 201869          | 201869 | 201869 | 201869 | 1       |
  • Checking the validator signatures: 130350 gas
checkValidatorSignatures(...)
  • loading the current contract state: 843 gas
uint256 currentNonce = state_eventNonce;
uint256 currentPowerThreshold = state_powerThreshold;
bytes32 lastValidatorSetCheckpoint = state_lastValidatorSetCheckpoint;
  • persisting the new commitment: 45127 gas
state_eventNonce = _newNonce;
state_dataRootTupleRoots[_newNonce] = _dataRootTupleRoot;
  • Emitting the event at the end: 2266 gas
emit DataRootTupleRootEvent(_newNonce, _dataRootTupleRoot);
  • calculating the validator set hash: 21445 gas
computeValidatorSetHash(...)
  • calculating the domain separate validator set hash: 636 gas
domainSeparateValidatorSetHash(...)
  • calculating the domain separate data root tuple root: 1018 gas
domainSeparateDataRootTupleRoot(...)

The remaining costs are just for necessary checks:

        if (_newNonce != currentNonce + 1) {
            revert InvalidDataRootTupleRootNonce();
        }

        // Check that current validators and signatures are well-formed.
        if (_currentValidatorSet.length != _sigs.length) {
            revert MalformedCurrentValidatorSet();
        }

        // Check that the supplied current validator set matches the saved checkpoint.
        bytes32 currentValidatorSetHash = computeValidatorSetHash(_currentValidatorSet);
        if (
            domainSeparateValidatorSetHash(_validatorSetNonce, currentPowerThreshold, currentValidatorSetHash)
                != lastValidatorSetCheckpoint
        ) {
            revert SuppliedValidatorSetInvalid();
        }

@rach-id rach-id closed this as completed Oct 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant