Skip to content

Commit d4baa88

Browse files
jewei1997udpatil
authored andcommitted
EVM Hardhat gas test (#1254)
* balances around 1usei - test currently failing * remove unused imports * cleanup * cleanup * cleanup * eip1559 gas seems to not work * both eip1559 tests work * added test for sending many eip1559 tests, base fee should be positive, table tests for eip1559 * cleanup prints * small fix * remove it.only * fix test * remove base fee test * add back some prints * move min gas price from 1 wei to 1 gwei * fix gas unit test
1 parent a7c713a commit d4baa88

File tree

8 files changed

+180
-28
lines changed

8 files changed

+180
-28
lines changed

contracts/hardhat.config.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ module.exports = {
2121
address: ["0xF87A299e6bC7bEba58dbBe5a5Aa21d49bCD16D52"],
2222
accounts: ["0x57acb95d82739866a5c29e40b0aa2590742ae50425b7dd5b5d279a986370189e"], // Replace with your private key
2323
},
24-
// sei: {
25-
// url: "https://evm-warroom-test.seinetwork.io:18545", // Replace with your JSON-RPC URL
26-
// address: ["0x07dc55085b721947d5c1645a07929eac9f1cc750"],
27-
// accounts: [process.env.TEST_PRIVATE_KEY], // Replace with your private key
28-
// },
24+
sei: {
25+
url: "https://evm-devnet.seinetwork.io", // Replace with your JSON-RPC URL
26+
address: ["0x07dc55085b721947d5c1645a07929eac9f1cc750"],
27+
accounts: ["0x57acb95d82739866a5c29e40b0aa2590742ae50425b7dd5b5d279a986370189e"], // Replace with your private key
28+
},
2929
seilocal: {
3030
url: "http://127.0.0.1:8545",
3131
address: ["0xF87A299e6bC7bEba58dbBe5a5Aa21d49bCD16D52", "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"],

contracts/package-lock.json

+7-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/test/EVMCompatabilityTester.js

+160-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const { expect } = require("chai");
22
const {isBigNumber} = require("hardhat/common");
3+
const { ethers } = require("hardhat");
34
const {uniq, shuffle} = require("lodash");
5+
46
function sleep(ms) {
57
return new Promise(resolve => setTimeout(resolve, ms));
68
}
@@ -14,6 +16,31 @@ function debug(msg) {
1416
//console.log(msg)
1517
}
1618

19+
async function sendTransactionAndCheckGas(sender, recipient, amount) {
20+
// Get the balance of the sender before the transaction
21+
const balanceBefore = await ethers.provider.getBalance(sender.address);
22+
23+
// Send the transaction
24+
const tx = await sender.sendTransaction({
25+
to: recipient.address,
26+
value: amount
27+
});
28+
29+
// Wait for the transaction to be mined and get the receipt
30+
const receipt = await tx.wait();
31+
32+
// Get the balance of the sender after the transaction
33+
const balanceAfter = await ethers.provider.getBalance(sender.address);
34+
35+
// Calculate the total cost of the transaction (amount + gas fees)
36+
const gasPrice = receipt.gasPrice;
37+
const gasUsed = receipt.gasUsed;
38+
const totalCost = gasPrice * gasUsed + BigInt(amount);
39+
40+
// Check that the sender's balance decreased by the total cost
41+
return balanceBefore - balanceAfter === totalCost
42+
}
43+
1744
function generateWallet() {
1845
const wallet = ethers.Wallet.createRandom();
1946
return wallet.connect(ethers.provider);
@@ -103,7 +130,7 @@ describe("EVM Test", function () {
103130
return
104131
}
105132
let signers = await ethers.getSigners();
106-
owner = signers[0]
133+
owner = signers[0];
107134
debug(`OWNER = ${owner.address}`)
108135

109136
const TestToken = await ethers.getContractFactory("TestToken")
@@ -311,8 +338,139 @@ describe("EVM Test", function () {
311338
});
312339
})
313340

314-
describe("JSON-RPC", function() {
341+
describe("Gas tests", function() {
342+
it("Should deduct correct amount of gas on transfer", async function () {
343+
const balanceBefore = await ethers.provider.getBalance(owner);
315344

345+
const feeData = await ethers.provider.getFeeData();
346+
const gasPrice = Number(feeData.gasPrice);
347+
348+
const zero = ethers.parseUnits('0', 'ether')
349+
const txResponse = await owner.sendTransaction({
350+
to: owner.address,
351+
gasPrice: gasPrice,
352+
value: zero,
353+
type: 1,
354+
});
355+
await txResponse.wait();
356+
357+
const balanceAfter = await ethers.provider.getBalance(owner);
358+
359+
const diff = balanceBefore - balanceAfter;
360+
expect(diff).to.equal(21000 * gasPrice);
361+
362+
const success = await sendTransactionAndCheckGas(owner, owner, 0)
363+
expect(success).to.be.true
364+
});
365+
366+
it("Should fail if insufficient gas is provided", async function () {
367+
const feeData = await ethers.provider.getFeeData();
368+
const gasPrice = Number(feeData.gasPrice);
369+
const zero = ethers.parseUnits('0', 'ether')
370+
expect(owner.sendTransaction({
371+
to: owner.address,
372+
gasPrice: gasPrice - 1,
373+
value: zero,
374+
type: 1,
375+
})).to.be.reverted;
376+
});
377+
378+
it("Should deduct correct amount even if higher gas price is used", async function () {
379+
const balanceBefore = await ethers.provider.getBalance(owner);
380+
381+
const feeData = await ethers.provider.getFeeData();
382+
const gasPrice = Number(feeData.gasPrice);
383+
const higherGasPrice = Number(gasPrice + 9)
384+
console.log(`gasPrice = ${gasPrice}`)
385+
386+
const zero = ethers.parseUnits('0', 'ether')
387+
const txResponse = await owner.sendTransaction({
388+
to: owner.address,
389+
value: zero,
390+
gasPrice: higherGasPrice,
391+
type: 1,
392+
});
393+
const receipt = await txResponse.wait();
394+
395+
const balanceAfter = await ethers.provider.getBalance(owner);
396+
397+
const diff = balanceBefore - balanceAfter;
398+
expect(diff).to.equal(21000 * higherGasPrice);
399+
400+
const success = await sendTransactionAndCheckGas(owner, owner, 0)
401+
expect(success).to.be.true
402+
});
403+
404+
describe("EIP-1559", async function() {
405+
const zero = ethers.parseUnits('0', 'ether')
406+
const twoGwei = ethers.parseUnits("2", "gwei");
407+
const oneGwei = ethers.parseUnits("1", "gwei");
408+
409+
const testCases = [
410+
["No truncation from max priority fee", oneGwei, oneGwei],
411+
["With truncation from max priority fee", oneGwei, twoGwei],
412+
["With complete truncation from max priority fee", zero, twoGwei]
413+
];
414+
415+
it("Should be able to send many EIP-1559 txs", async function () {
416+
const oneGwei = ethers.parseUnits("1", "gwei");
417+
const zero = ethers.parseUnits('0', 'ether')
418+
for (let i = 0; i < 10; i++) {
419+
const txResponse = await owner.sendTransaction({
420+
to: owner.address,
421+
value: zero,
422+
maxPriorityFeePerGas: oneGwei,
423+
maxFeePerGas: oneGwei,
424+
type: 2
425+
});
426+
await txResponse.wait();
427+
}
428+
});
429+
430+
describe("Differing maxPriorityFeePerGas and maxFeePerGas", async function() {
431+
testCases.forEach(async ([name, maxPriorityFeePerGas, maxFeePerGas]) => {
432+
it(`EIP-1559 test: ${name}`, async function() {
433+
console.log(`maxPriorityFeePerGas = ${maxPriorityFeePerGas}`)
434+
console.log(`maxFeePerGas = ${maxFeePerGas}`)
435+
const balanceBefore = await ethers.provider.getBalance(owner);
436+
const feeData = await ethers.provider.getFeeData();
437+
const gasPrice = Number(feeData.gasPrice);
438+
439+
console.log(`gasPrice = ${gasPrice}`)
440+
441+
const zero = ethers.parseUnits('0', 'ether')
442+
const txResponse = await owner.sendTransaction({
443+
to: owner.address,
444+
value: zero,
445+
maxPriorityFeePerGas: maxPriorityFeePerGas,
446+
maxFeePerGas: maxFeePerGas,
447+
type: 2
448+
});
449+
const receipt = await txResponse.wait();
450+
451+
expect(receipt).to.not.be.null;
452+
expect(receipt.status).to.equal(1);
453+
454+
const balanceAfter = await ethers.provider.getBalance(owner);
455+
456+
const tip = Math.min(
457+
Number(maxFeePerGas) - gasPrice,
458+
Number(maxPriorityFeePerGas)
459+
);
460+
console.log(`tip = ${tip}`)
461+
const effectiveGasPrice = tip + gasPrice;
462+
console.log(`effectiveGasPrice = ${effectiveGasPrice}`)
463+
464+
const diff = balanceBefore - balanceAfter;
465+
console.log(`diff = ${diff}`)
466+
expect(diff).to.equal(21000 * effectiveGasPrice);
467+
});
468+
});
469+
});
470+
});
471+
});
472+
473+
describe("JSON-RPC", function() {
316474
it("Should retrieve a transaction by its hash", async function () {
317475
// Send a transaction to get its hash
318476
const txResponse = await evmTester.setBoolVar(true);
@@ -481,11 +639,6 @@ describe("EVM Test", function () {
481639
const isContract = code !== '0x';
482640
expect(isContract).to.be.true;
483641
});
484-
485642
});
486-
487-
488-
489643
});
490-
491644
});

evmrpc/block_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ func verifyBlockResult(t *testing.T, resObj map[string]interface{}) {
8282
require.Equal(t, "0x0", tx["type"])
8383
require.Equal(t, []interface{}{}, tx["accessList"])
8484
require.Equal(t, "0xae3f3", tx["chainId"])
85-
require.Equal(t, "0x1b", tx["v"])
85+
require.Equal(t, "0x0", tx["v"])
8686
require.Equal(t, "0xa1ac0e5b8202742e54ae7af350ed855313cc4f9861c2d75a0e541b4aff7c981e", tx["r"])
8787
require.Equal(t, "0x288b16881aed9640cd360403b9db1ce3961b29af0b00158311856d1446670996", tx["s"])
88-
require.Equal(t, "0x1", tx["yParity"])
88+
require.Equal(t, "0x0", tx["yParity"])
8989
require.Equal(t, "0x0000000000000000000000000000000000000000000000000000000000000002", resObj["transactionsRoot"])
9090
require.Equal(t, []interface{}{}, resObj["uncles"])
9191
require.Equal(t, "0x0", resObj["baseFeePerGas"])

evmrpc/tx_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,10 +125,10 @@ func TestGetTransaction(t *testing.T) {
125125
require.Equal(t, "0x0", resObj["type"].(string))
126126
require.Equal(t, 0, len(resObj["accessList"].([]interface{})))
127127
require.Equal(t, "0xae3f3", resObj["chainId"].(string))
128-
require.Equal(t, "0x1b", resObj["v"].(string))
128+
require.Equal(t, "0x0", resObj["v"].(string))
129129
require.Equal(t, "0xa1ac0e5b8202742e54ae7af350ed855313cc4f9861c2d75a0e541b4aff7c981e", resObj["r"].(string))
130130
require.Equal(t, "0x288b16881aed9640cd360403b9db1ce3961b29af0b00158311856d1446670996", resObj["s"].(string))
131-
require.Equal(t, "0x1", resObj["yParity"].(string))
131+
require.Equal(t, "0x0", resObj["yParity"].(string))
132132
}
133133

134134
for _, body := range []string{bodyByBlockNumberAndIndex, bodyByBlockHashAndIndex, bodyByHash} {

evmrpc/utils.go

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func hydrateTransaction(
6969
idx := hexutil.Uint64(receipt.TransactionIndex)
7070
al := tx.AccessList()
7171
v, r, s := tx.RawSignatureValues()
72-
v = ante.AdjustV(v, tx.Type(), tx.ChainId())
7372
var yparity *hexutil.Uint64
7473
if tx.Type() != ethtypes.LegacyTxType {
7574
yp := hexutil.Uint64(v.Sign())

precompiles/wasmd/wasmd_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func TestInstantiate(t *testing.T) {
6868
require.Equal(t, 2, len(outputs))
6969
require.Equal(t, "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", outputs[0].(string))
7070
require.Empty(t, outputs[1].([]byte))
71-
require.Equal(t, uint64(899594), g)
71+
require.Equal(t, uint64(899567), g)
7272

7373
// non-existent code ID
7474
args, _ = instantiateMethod.Inputs.Pack(
@@ -128,7 +128,7 @@ func TestExecute(t *testing.T) {
128128
require.Nil(t, err)
129129
require.Equal(t, 1, len(outputs))
130130
require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(outputs[0].([]byte)))
131-
require.Equal(t, uint64(912476), g)
131+
require.Equal(t, uint64(912449), g)
132132

133133
// allowed delegatecall
134134
fmt.Println(testApp.BankKeeper.GetBalance(ctx, mockAddr, "usei"))
@@ -189,7 +189,7 @@ func TestQuery(t *testing.T) {
189189
require.Nil(t, err)
190190
require.Equal(t, 1, len(outputs))
191191
require.Equal(t, "{\"message\":\"query test\"}", string(outputs[0].([]byte)))
192-
require.Equal(t, uint64(927062), g)
192+
require.Equal(t, uint64(927035), g)
193193

194194
// bad contract address
195195
args, _ = queryMethod.Inputs.Pack(mockAddr.String(), []byte("{\"info\":{}}"))

x/evm/types/params.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var DefaultPriorityNormalizer = sdk.NewDec(1)
3232
// burnt rather than go to validators (similar to base fee on
3333
// Ethereum).
3434
var DefaultBaseFeePerGas = sdk.NewDec(0)
35-
var DefaultMinFeePerGas = sdk.NewDec(1)
35+
var DefaultMinFeePerGas = sdk.NewDec(1000000000)
3636
var DefaultChainID = sdk.NewInt(713715)
3737
var DefaultWhitelistedCodeHashesBankSend = generateDefaultWhitelistedCodeHashesBankSend()
3838
var DefaultWhitelistedCwCodeHashesForDelegateCall = [][]byte{}

0 commit comments

Comments
 (0)