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

[TASK] Investigate gas optimization: instantiate Attestation with {} notation #918

Open
alainncls opened this issue Feb 14, 2025 · 1 comment

Comments

@alainncls
Copy link
Collaborator

Summary

It has been suggested that instantiating an Attestation struct using {} notation could save gas. This ticket aims to validate this claim and, if confirmed, apply the optimization across the codebase.

Objectives

  1. Research & benchmark

    • Compare gas costs of instantiating an Attestation using {} notation vs. standard assignment.
    • Provide concrete gas measurements to determine if the optimization is significant.
  2. Apply optimization (if confirmed)

    • Update all instances where Attestation is instantiated to use {} notation if it proves beneficial.
    • Ensure no unintended side effects in contract behaviour.

Impact

  • Potential gas savings across Verax contracts.
  • Improved efficiency for attestation-related transactions.
@evgeniytar
Copy link
Contributor

Conducted some benchmarks on this and seems like { } annotation is indeed slightly more gas efficient.

As a comparison base I took this method that initiates Attestation.

function _buildAttestation(
AttestationPayload calldata attestationPayload,
address attester,
address portal
) internal view returns (Attestation memory) {
return
Attestation(
attestationRegistry.getNextAttestationId(),
attestationPayload.schemaId,
bytes32(0),
attester,
portal,
uint64(block.timestamp),
attestationPayload.expirationDate,
0,
attestationRegistry.getVersionNumber(),
false,
attestationPayload.subject,
attestationPayload.attestationData
);
}

Here is a contract that I built for measuring gas usage

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract AttestationGasTest {
    struct Attestation {
        bytes32 uid;
        bytes32 schema;
        uint64 time;
        uint64 expirationTime;
        uint64 revocationTime;
        bytes32 refUID;
        address recipient;
        address attester;
        bool revocable;
        bytes data;
    }

    function _buildAttestationPositional(
        bytes32 uid,
        bytes32 schema,
        uint64 time,
        uint64 expirationTime,
        uint64 revocationTime,
        bytes32 refUID,
        address recipient,
        address attester,
        bool revocable,
        bytes memory data
    ) public pure returns (Attestation memory) {
        return Attestation(
            uid,
            schema,
            time,
            expirationTime,
            revocationTime,
            refUID,
            recipient,
            attester,
            revocable,
            data
        );
    }

    function _buildAttestationNamed(
        bytes32 uid,
        bytes32 schema,
        uint64 time,
        uint64 expirationTime,
        uint64 revocationTime,
        bytes32 refUID,
        address recipient,
        address attester,
        bool revocable,
        bytes memory data
    ) public pure returns (Attestation memory) {
        return Attestation({
            uid: uid,
            schema: schema,
            time: time,
            expirationTime: expirationTime,
            revocationTime: revocationTime,
            refUID: refUID,
            recipient: recipient,
            attester: attester,
            revocable: revocable,
            data: data
        });
    }

    uint256 constant N = 100;

    function testGas_Positional() public pure {
        bytes memory emptyData = "";
        bytes32 dummyBytes = keccak256("test");
        address dummyAddr = address(0x123);

        for (uint256 i = 0; i < N; i++) {
            _buildAttestationPositional(dummyBytes, dummyBytes, 1, 2, 3, dummyBytes, dummyAddr, dummyAddr, true, emptyData);
        }
    }

    function testGas_Named() public pure {
        bytes memory emptyData = "";
        bytes32 dummyBytes = keccak256("test");
        address dummyAddr = address(0x123);

        for (uint256 i = 0; i < N; i++) {
            _buildAttestationNamed(dummyBytes, dummyBytes, 1, 2, 3, dummyBytes, dummyAddr, dummyAddr, true, emptyData);
        }
    }
}

As result positional argument approach took 71449 gas per 100 initiations,

Image

meantime {} annotation used 71383.

Image

@alainncls does this research make sense for you?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Ready for development
Development

No branches or pull requests

2 participants