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

Reverts: Do not run out of stack and extract string revert reason #3308

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions packages/providers/src.ts/json-rpc-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ import { BaseProvider, Event } from "./base-provider";

const errorGas = [ "call", "estimateGas" ];

const revertReasonStringRe = /^[^:]*: reverted with reason string '(.*)'$/;

function spelunk(value: any, requireData: boolean): null | { message: string, data: null | string } {
if (value == null) { return null; }

const message = value.message;
// These *are* the droids we're looking for.
if (typeof(value.message) === "string" && value.message.match("reverted")) {
const data = isHexString(value.data) ? value.data: null;
if (typeof(message) === "string" && message.match("reverted")) {
let data = isHexString(value.data) ? value.data: null;
let m;
if (data === null && (m = message.match(revertReasonStringRe))) {
data = toUtf8Bytes(m[1]);
}
if (!requireData || data) {
return { message: value.message, data };
}
Expand All @@ -36,6 +43,21 @@ function spelunk(value: any, requireData: boolean): null | { message: string, da
// Spelunk further...
if (typeof(value) === "object") {
for (const key in value) {
if (value instanceof Error && key === "stackTrace") {
/*
* When an Error object is precessed, `stackTrace` property will
* contain references to objects that represent files and
* functions and is an internally cyclical data structure.
* `spelunk` will loop though it until it will exceed all the
* stack space.
*
* In any case, `stackTrace` does not contain an explanation as
* to why the transaction was reverted, so it does not make
* sense to look in there regardless of if it is cyclical or
* not.
*/
continue;
}
const result = spelunk(value[key], requireData);
if (result) { return result; }
}
Expand Down