solidity-gas-optimization icon indicating copy to clipboard operation
solidity-gas-optimization copied to clipboard

Higher Gas Consumption for enum value 1 vs. enum value 2 and Reduced Gas Cost Discrepancy at Larger Batch Sizes in Solidity Smart Contract

Open farhanajaved opened this issue 8 months ago • 0 comments

I am developing a Solidity smart contract where users can either register as "Consumers" or "Providers". Despite having identical logic for both roles, there is a consistent difference in the gas consumption observed. The registration of "Providers" uses more gas than that of "Consumers".

Smart contract:

`contract Registration { enum Role { Consumer, Provider }

struct User {
    address userAddress;
    uint256 registrationTime;
    Role role;
}

mapping(address => User) public users;
uint256 public userCount;

function register(Role role) public {
    bool isNewUser = users[msg.sender].userAddress == address(0);
    users[msg.sender] = User({
        userAddress: msg.sender,
        registrationTime: block.timestamp,
        role: role
    });

    if (isNewUser) {
        userCount++;
    }
}

`

Details Observed Gas Usage

  • Consumers: Approximately 73,827 gas units on average.
  • Providers: Approximately 93,739 gas units on average.

Test Environment Tests were conducted on the Remix IDE, hardhat on sepolia network to ensure consistency.

Example Logs

  • Consumer Registrations:

  • Consumer 1: Address: 0xAddress1, Transaction Hash: 0xTxHash1, Gas Used: 90,927, Latency: 12.149 seconds.

  • Consumer 2: Address: 0xAddress2, Transaction Hash: 0xTxHash2, Gas Used: 73,827, Latency: 14.874 seconds.

  • Provider Registrations:

  • Provider 3: Address: 0xAddress3, Transaction Hash: 0xTxHash3, Gas Used: 93,739, Latency: 10.915 seconds.

  • Provider 4: Address: 0xAddress4, Transaction Hash: 0xTxHash4, Gas Used: 93,739, Latency: 11.316 seconds.

Batch Testing User roles were assigned as Consumer (enum 0) or Provider (enum 1) and tested in various concurrent transaction batch sizes each having 10 iterations (2, 16, 30, 44, 58, 72, 86, 100). Interestingly, the differences in gas consumption between the roles start to level out after batch of 44, the provider's gas cost is same as consumer meaning it levels out after batch of 44 user as batch sizes increase.

Observations Smaller Batches: Significant differences in gas costs between roles. Larger Batches: Convergence of gas costs for Providers and Consumers. Questions

  1. Why does registering "Providers" consume more gas than "Consumers" despite identical logic? (I understand this could be sue to enum 0 for consumer and 1 for provider. )

  2. Could the leveling out of gas costs in larger batches be due to EVM optimizations related to how storage is accessed during high transaction volumes?

  3. How might the reuse of addresses in each batch impact the state trie and potentially minimize gas costs over time?

farhanajaved avatar Jun 07 '24 19:06 farhanajaved