Skip to content

Commit

Permalink
upd gas tests
Browse files Browse the repository at this point in the history
  • Loading branch information
galekseev committed Dec 23, 2023
1 parent 3b601d2 commit 69c5eaf
Show file tree
Hide file tree
Showing 4 changed files with 1,699 additions and 608 deletions.
54 changes: 37 additions & 17 deletions contracts/tests/StringUtilTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,60 @@ import "../libraries/StringUtil.sol";
import "./libraries/StringUtilNaive.sol";
import "../GasChecker.sol";

contract StringUtilTest is GasChecker {
function toHex(uint256 value, uint256 expectedGasCost)
contract StringUtilTest {
function toHex(uint256 value)
external
view
checkGasCost(expectedGasCost)
returns (string memory)
returns (string memory hexString, uint256 gasUsed)
{
return StringUtil.toHex(value);
gasUsed = gasleft();

hexString = StringUtil.toHex(value);

unchecked {
gasUsed -= gasleft();
}
}

function toHexBytes(bytes memory data, uint256 expectedGasCost)
function toHexBytes(bytes memory data)
external
view
checkGasCost(expectedGasCost)
returns (string memory)
returns (string memory hexString, uint256 gasUsed)
{
return StringUtil.toHex(data);
gasUsed = gasleft();

hexString = StringUtil.toHex(data);

unchecked {
gasUsed -= gasleft();
}
}

function toHexNaive(uint256 value, uint256 expectedGasCost)
function toHexNaive(uint256 value)
external
view
checkGasCost(expectedGasCost)
returns (string memory)
returns (string memory hexString, uint256 gasUsed)
{
return StringUtilNaive.toHex(value);
gasUsed = gasleft();

hexString = StringUtilNaive.toHex(value);

unchecked {
gasUsed -= gasleft();
}
}

function toHexNaiveBytes(bytes memory data, uint256 expectedGasCost)
function toHexNaiveBytes(bytes memory data)
external
view
checkGasCost(expectedGasCost)
returns (string memory)
returns (string memory hexString, uint256 gasUsed)
{
return StringUtilNaive.toHex(data);
gasUsed = gasleft();

hexString = StringUtilNaive.toHex(data);

unchecked {
gasUsed -= gasleft();
}
}
}
67 changes: 34 additions & 33 deletions test/contracts/StringUtil.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,81 +38,82 @@ describe('StringUtil', function () {

it('Same bytes long', () => testBytes(sameBytesLong));

it('Single byte naive', () => testIncorrectGas(singleByte, 2000));

async function test(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
const result = await stringUtilTest.toHex(value, 0);
const naiveResult = await stringUtilTest.toHexNaive(value, 0);
const [result] = await stringUtilTest.toHex(value);
const [naiveResult] = await stringUtilTest.toHexNaive(value);
expect(result.toLowerCase()).to.be.equal(value.toLowerCase());
expect(result.toLowerCase()).to.be.equal(naiveResult.toLowerCase());
}

async function testBytes(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
const result = await stringUtilTest.toHexBytes(value, 0);
const naiveResult = await stringUtilTest.toHexNaiveBytes(value, 0);
const [result] = await stringUtilTest.toHexBytes(value);
const [naiveResult] = await stringUtilTest.toHexNaiveBytes(value);
expect(result.toLowerCase()).to.be.equal(value.toLowerCase());
expect(result.toLowerCase()).to.be.equal(naiveResult.toLowerCase());
}

async function testIncorrectGas(value: string, expectedGas: number) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
await expect(stringUtilTest.toHexNaiveBytes(value, expectedGas)).to.be.reverted; // TODO: change to revertedWithCustomError(stringUtilTest, 'GasCostDiffers')
}
});

describe('Gas usage', function () {
before(function () {
if (hre.__SOLIDITY_COVERAGE_RUNNING) { this.skip(); }
});

it('Uint 256', () => testGasUint256(uint256TestValue, 834));
it('Uint 256', () => testGasUint256(uint256TestValue));

it('Uint 256 naive', () => testGasNaiveUint256(uint256TestValue, 16369));
it('Uint 256 naive', () => testGasNaiveUint256(uint256TestValue));

it('Uint 256 as bytes', () => testGasBytes(uint256TestValue, 716));
it('Uint 256 as bytes', () => testGasBytes(uint256TestValue));

it('Uint 256 as bytes naive', () => testGasNaiveBytes(uint256TestValue, 16251));
it('Uint 256 as bytes naive', () => testGasNaiveBytes(uint256TestValue));

it('Uint 128', () => testGasUint256(uint128TestValue, 834));
it('Uint 128', () => testGasUint256(uint128TestValue));

it('Uint 128 naive', () => testGasNaiveUint256(uint128TestValue, 16369));
it('Uint 128 naive', () => testGasNaiveUint256(uint128TestValue));

it('Very long byte array gas', () => testGasBytes(veryLongArray, 1766));
it('Very long byte array gas', () => testGasBytes(veryLongArray));

it('Very long byte array gas naive', () => testGasNaiveBytes(veryLongArray, 33483));
it('Very long byte array gas naive', () => testGasNaiveBytes(veryLongArray));

it('Extremely long byte array gas', () => testGasBytes(extremelyLongArray, 17009));
it('Extremely long byte array gas', () => testGasBytes(extremelyLongArray));

it('Extremely long byte array gas naive', () => testGasNaiveBytes(extremelyLongArray, 492884));
it('Extremely long byte array gas naive', () => testGasNaiveBytes(extremelyLongArray));

it('Empty bytes', () => testGasBytes(emptyBytes, 191));
it('Empty bytes', () => testGasBytes(emptyBytes));

it('Empty bytes naive', () => testGasNaiveBytes(emptyBytes, 495));
it('Empty bytes naive', () => testGasNaiveBytes(emptyBytes));

it('Single byte', () => testGasBytes(singleByte, 716));
it('Single byte', () => testGasBytes(singleByte));

it('Single byte naive', () => testGasNaiveBytes(singleByte, 987));
it('Single byte naive', () => testGasNaiveBytes(singleByte));

async function testGasUint256(value: string, expectedGas: number) {
async function testGasUint256(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
await stringUtilTest.toHex(value, expectedGas);
const { gasUsed } = await stringUtilTest.toHex(value);

expect(gasUsed).toMatchSnapshot();
}

async function testGasBytes(value: string, expectedGas: number) {
async function testGasBytes(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
await stringUtilTest.toHexBytes(value, expectedGas);
const { gasUsed } = await stringUtilTest.toHexBytes(value);

expect(gasUsed).toMatchSnapshot();
}

async function testGasNaiveUint256(value: string, expectedGas: number) {
async function testGasNaiveUint256(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
await stringUtilTest.toHexNaive(value, expectedGas);
const { gasUsed } = await stringUtilTest.toHexNaive(value);

expect(gasUsed).toMatchSnapshot();
}

async function testGasNaiveBytes(value: string, expectedGas: number) {
async function testGasNaiveBytes(value: string) {
const { stringUtilTest } = await loadFixture(deployStringUtilTest);
await stringUtilTest.toHexNaiveBytes(value, expectedGas);
const { gasUsed } = await stringUtilTest.toHexNaiveBytes(value);

expect(gasUsed).toMatchSnapshot();
}
});
});
29 changes: 29 additions & 0 deletions test/contracts/__snapshots__/StringUtil.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`StringUtil Gas usage Empty bytes 1`] = `191n`;

exports[`StringUtil Gas usage Empty bytes naive 1`] = `495n`;

exports[`StringUtil Gas usage Extremely long byte array gas 1`] = `17009n`;

exports[`StringUtil Gas usage Extremely long byte array gas naive 1`] = `492884n`;

exports[`StringUtil Gas usage Single byte 1`] = `716n`;

exports[`StringUtil Gas usage Single byte naive 1`] = `987n`;

exports[`StringUtil Gas usage Uint 128 1`] = `840n`;

exports[`StringUtil Gas usage Uint 128 naive 1`] = `16366n`;

exports[`StringUtil Gas usage Uint 256 1`] = `840n`;

exports[`StringUtil Gas usage Uint 256 as bytes 1`] = `716n`;

exports[`StringUtil Gas usage Uint 256 as bytes naive 1`] = `16251n`;

exports[`StringUtil Gas usage Uint 256 naive 1`] = `16366n`;

exports[`StringUtil Gas usage Very long byte array gas 1`] = `1766n`;

exports[`StringUtil Gas usage Very long byte array gas naive 1`] = `33483n`;
Loading

0 comments on commit 69c5eaf

Please sign in to comment.