Skip to content

Commit

Permalink
feature: display the revert reason when calls or gas estimations fail (
Browse files Browse the repository at this point in the history
  • Loading branch information
MexicanAce authored Sep 6, 2023
1 parent 74727c8 commit cbac9a1
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 13 deletions.
5 changes: 3 additions & 2 deletions e2e-tests/contracts/Greeter.sol
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "hardhat/console.sol";

contract Greeter {
contract Greeter is Ownable {
string private greeting;

constructor(string memory _greeting) {
Expand All @@ -14,7 +15,7 @@ contract Greeter {
return greeting;
}

function setGreeting(string memory _greeting) public {
function setGreeting(string memory _greeting) public onlyOwner {
console.log("setGreeting called");
console.log(_greeting);
require(
Expand Down
1 change: 1 addition & 0 deletions e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@matterlabs/hardhat-zksync-deploy": "^0.6.3",
"@matterlabs/hardhat-zksync-solc": "^0.4.0",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"@openzeppelin/contracts": "^4.9.3",
"@types/chai": "^4.3.4",
"@types/mocha": "^10.0.1",
"chai": "^4.3.7",
Expand Down
42 changes: 41 additions & 1 deletion e2e-tests/test/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { expect } from 'chai';
import { Wallet, Contract } from 'zksync-web3';
import { Wallet, Contract, Provider } from 'zksync-web3';
import * as hre from 'hardhat';
import { Deployer } from '@matterlabs/hardhat-zksync-deploy';
import { ethers } from 'ethers';

const RICH_WALLET_PK =
'0x7726827caac94a7f9e1b160f7ea819f172f7b6f9d2a97f992c38edeab82d4110';
Expand All @@ -11,6 +12,19 @@ async function deployGreeter(deployer: Deployer): Promise<Contract> {
return await deployer.deploy(artifact, ['Hi']);
}

async function fundAccount(
wallet: ethers.Wallet,
address: string,
amount: string,
) {
await (
await wallet.sendTransaction({
to: address,
value: ethers.utils.parseEther(amount),
})
).wait();
}

describe('Greeter', function () {
it("Should return the new greeting once it's changed", async function () {
const wallet = new Wallet(RICH_WALLET_PK);
Expand All @@ -26,4 +40,30 @@ describe('Greeter', function () {

expect(await greeter.greet()).to.equal('Hola, mundo!');
});

it("should prevent non-owners from setting greeting", async function () {
let errorThrown = false;
try {
const provider = new Provider("http://127.0.0.1:8011");
const wallet = new Wallet(RICH_WALLET_PK, provider);
const deployer = new Deployer(hre, wallet);

// setup user wallet
const userWallet = Wallet.createRandom().connect(provider);
await fundAccount(wallet, userWallet.address, "3");

// deploy Greeter contract
const artifact = await deployer.loadArtifact('Greeter');
const greeter = await deployer.deploy(artifact, ["Hello, world!"]);

// should revert
const tx = await greeter.connect(userWallet).setGreeting("Hola, mundo!");
await tx.wait();
} catch (e) {
expect(e.message).to.include("Ownable: caller is not the owner");
errorThrown = true;
}

expect(errorThrown).to.be.true;
});
});
5 changes: 5 additions & 0 deletions e2e-tests/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,11 @@
table "^6.8.0"
undici "^5.14.0"

"@openzeppelin/contracts@^4.9.3":
version "4.9.3"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364"
integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==

"@scure/base@~1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
Expand Down
24 changes: 14 additions & 10 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,17 +430,19 @@ impl<S: std::fmt::Debug + ForkSource> InMemoryNodeInner<S> {
);
println!("{}", format!("\tOverhead: {}", overhead).red());
let message = tx_revert_reason.to_string();
let pretty_message = format!(
"execution reverted{}{}",
if message.is_empty() { "" } else { ": " },
message
);
let data = match tx_revert_reason {
TxRevertReason::EthCall(vm_revert_reason) => vm_revert_reason.encoded_data(),
TxRevertReason::TxReverted(vm_revert_reason) => vm_revert_reason.encoded_data(),
_ => vec![],
};
println!("{}", pretty_message.on_red());
Err(into_jsrpc_error(Web3Error::SubmitTransactionError(
format!(
"execution reverted{}{}",
if message.is_empty() { "" } else { ": " },
message
),
pretty_message,
data,
)))
}
Expand Down Expand Up @@ -1199,6 +1201,11 @@ impl<S: Send + Sync + 'static + ForkSource + std::fmt::Debug> EthNamespaceT for
Ok(vm_block_result) => match vm_block_result.full_result.revert_reason {
Some(revert) => {
let message = revert.revert_reason.to_string();
let pretty_message = format!(
"execution reverted{}{}",
if message.is_empty() { "" } else { ": " },
message
);
let data = match revert.revert_reason {
TxRevertReason::EthCall(vm_revert_reason) => {
vm_revert_reason.encoded_data()
Expand All @@ -1208,12 +1215,9 @@ impl<S: Send + Sync + 'static + ForkSource + std::fmt::Debug> EthNamespaceT for
}
_ => vec![],
};
println!("{}", pretty_message.on_red());
Err(into_jsrpc_error(Web3Error::SubmitTransactionError(
format!(
"execution reverted{}{}",
if message.is_empty() { "" } else { ": " },
message
),
pretty_message,
data,
)))
.into_boxed_future()
Expand Down

0 comments on commit cbac9a1

Please sign in to comment.