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

Expensive struct hashing. #14065

Closed
drortirosh opened this issue Mar 22, 2023 · 2 comments
Closed

Expensive struct hashing. #14065

drortirosh opened this issue Mar 22, 2023 · 2 comments
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. stale The issue/PR was marked as stale because it has been open for too long.

Comments

@drortirosh
Copy link

I need to create a unique hash for a Struct.
Using keccak256(abi.encode()) on all 10 fields costs 1210 gas
As a comparison, hashing directly msg.data (which contains all fields data but also includes lengths, abi offsets and methodsig) costs 143 gas

I understand the compiler has some overheads (like validating the address range, and multiple keccak calls), but I don't think it warrants 8 times the gas price.

Remix example (the given struct to encode is taken from erc4337

pragma solidity ^0.8.17;

// SPDX-License-Identifier: GPL-3.0
import 'hardhat/console.sol';

contract Test {

    struct UserOperation {
        address sender;
        uint256 nonce;
        bytes initCode;
        bytes callData;
        uint256 callGasLimit;
        uint256 verificationGasLimit;
        uint256 preVerificationGas;
        uint256 maxFeePerGas;
        uint256 maxPriorityFeePerGas;
        bytes paymasterAndData;
        bytes signature;
    }

    function testhash(UserOperation calldata u) external view {

        uint g = gasleft();
        calldata_keccak256(msg.data);
        uint g1 = gasleft();
        internalHash(u);
        uint g2 = gasleft();

        console.log("keccak msg.data", g-g1); // 143
        console.log("keccak fields", g1-g2); // 1210
    }

    function internalHash(UserOperation calldata u) internal pure returns (bytes32) {
        address sender = u.sender;
        uint nonce = u.nonce;
        uint callGasLimit = u.callGasLimit;
        uint verificationGasLimit = u.verificationGasLimit;
        uint preVerificationGas = u.preVerificationGas;
        uint maxFeePerGas = u.maxFeePerGas;
        uint maxPriorityFeePerGas = u.maxPriorityFeePerGas;

        return keccak256(abi.encode(
            sender, nonce, 
            calldata_keccak256(u.initCode),
            calldata_keccak256(u.callData),
            callGasLimit, verificationGasLimit, preVerificationGas,
            maxFeePerGas, maxPriorityFeePerGas,
            calldata_keccak256(u.paymasterAndData) 
        ));
    }

    function run() public view {
        UserOperation memory userOp = UserOperation(
            address(this),
            1,
            "initcode (if constructing a new account)",
            "calldata (methodsig and params)",
            4, 5, 6, 7, 8,
            "paymaster and data info",
            ""
        );
        this.testhash(userOp);
    }
    
    function calldata_keccak256(bytes calldata data) private pure returns (bytes32 ret) {
        assembly {
            let mem := mload(0x40)
            let len := data.length
            calldatacopy(mem, data.offset, len)
            ret := keccak256(mem, len)
        }
    }

}

contract Arun {
    constructor() {
        new Test().run();
    }
}

Partly-related issues:

@github-actions github-actions bot added this to Triage in Solidity Mar 22, 2023
@cameel cameel removed this from Triage in Solidity Apr 27, 2023
@github-actions
Copy link

This issue has been marked as stale due to inactivity for the last 90 days.
It will be automatically closed in 7 days.

@github-actions github-actions bot added the stale The issue/PR was marked as stale because it has been open for too long. label Jun 21, 2023
@github-actions
Copy link

Hi everyone! This issue has been automatically closed due to inactivity.
If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen.
However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.

@github-actions github-actions bot added the closed due inactivity The issue/PR was automatically closed due to inactivity. label Jun 28, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed due inactivity The issue/PR was automatically closed due to inactivity. stale The issue/PR was marked as stale because it has been open for too long.
Projects
None yet
Development

No branches or pull requests

1 participant