@0x/utils
: Fix nested revert decoding
This commit is contained in:
parent
228246089e
commit
f9d02c9e27
@ -7,7 +7,7 @@ import { inspect } from 'util';
|
|||||||
import * as AbiEncoder from './abi_encoder';
|
import * as AbiEncoder from './abi_encoder';
|
||||||
import { BigNumber } from './configured_bignumber';
|
import { BigNumber } from './configured_bignumber';
|
||||||
|
|
||||||
// tslint:disable: max-classes-per-file
|
// tslint:disable: max-classes-per-file no-unnecessary-type-assertion
|
||||||
|
|
||||||
type ArgTypes =
|
type ArgTypes =
|
||||||
| string
|
| string
|
||||||
@ -109,7 +109,10 @@ export abstract class RevertError extends Error {
|
|||||||
* @param coerce Whether to coerce unknown selectors into a `RawRevertError` type.
|
* @param coerce Whether to coerce unknown selectors into a `RawRevertError` type.
|
||||||
* @return A RevertError object.
|
* @return A RevertError object.
|
||||||
*/
|
*/
|
||||||
public static decode(bytes: string | Buffer, coerce: boolean = false): RevertError {
|
public static decode(bytes: string | Buffer | RevertError, coerce: boolean = false): RevertError {
|
||||||
|
if (bytes instanceof RevertError) {
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
const _bytes = bytes instanceof Buffer ? ethUtil.bufferToHex(bytes) : ethUtil.addHexPrefix(bytes);
|
const _bytes = bytes instanceof Buffer ? ethUtil.bufferToHex(bytes) : ethUtil.addHexPrefix(bytes);
|
||||||
// tslint:disable-next-line: custom-no-magic-numbers
|
// tslint:disable-next-line: custom-no-magic-numbers
|
||||||
const selector = _bytes.slice(2, 10);
|
const selector = _bytes.slice(2, 10);
|
||||||
@ -122,21 +125,7 @@ export abstract class RevertError extends Error {
|
|||||||
const { type, decoder } = RevertError._typeRegistry[selector];
|
const { type, decoder } = RevertError._typeRegistry[selector];
|
||||||
const instance = new type();
|
const instance = new type();
|
||||||
try {
|
try {
|
||||||
const values = decoder(_bytes);
|
Object.assign(instance, { values: decoder(_bytes) });
|
||||||
_.transform(
|
|
||||||
values,
|
|
||||||
(result, value, key) => {
|
|
||||||
const { type: argType } = instance._getArgumentByName(key);
|
|
||||||
if (argType === 'bytes') {
|
|
||||||
try {
|
|
||||||
const nestedRevert = RevertError.decode(value as string, coerce);
|
|
||||||
result[key] = nestedRevert.toString();
|
|
||||||
} catch (err) {} // tslint:disable-line:no-empty
|
|
||||||
}
|
|
||||||
},
|
|
||||||
values,
|
|
||||||
);
|
|
||||||
_.assign(instance, { values });
|
|
||||||
instance.message = instance.toString();
|
instance.message = instance.toString();
|
||||||
return instance;
|
return instance;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -306,6 +295,16 @@ export abstract class RevertError extends Error {
|
|||||||
return `${this.constructor.name}(${this._raw})`;
|
return `${this.constructor.name}(${this._raw})`;
|
||||||
}
|
}
|
||||||
const values = _.omitBy(this.values, (v: any) => _.isNil(v));
|
const values = _.omitBy(this.values, (v: any) => _.isNil(v));
|
||||||
|
// tslint:disable-next-line: forin
|
||||||
|
for (const k in values) {
|
||||||
|
const { type: argType } = this._getArgumentByName(k);
|
||||||
|
if (argType === 'bytes') {
|
||||||
|
// Try to decode nested revert errors.
|
||||||
|
try {
|
||||||
|
values[k] = RevertError.decode(values[k] as any);
|
||||||
|
} catch (err) {} // tslint:disable-line:no-empty
|
||||||
|
}
|
||||||
|
}
|
||||||
const inner = _.isEmpty(values) ? '' : inspect(values);
|
const inner = _.isEmpty(values) ? '' : inspect(values);
|
||||||
return `${this.constructor.name}(${inner})`;
|
return `${this.constructor.name}(${inner})`;
|
||||||
}
|
}
|
||||||
@ -498,6 +497,12 @@ function declarationToAbi(declaration: string): RevertErrorAbi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkArgEquality(type: string, lhs: ArgTypes, rhs: ArgTypes): boolean {
|
function checkArgEquality(type: string, lhs: ArgTypes, rhs: ArgTypes): boolean {
|
||||||
|
// Try to compare as decoded revert errors first.
|
||||||
|
try {
|
||||||
|
return RevertError.decode(lhs as any).equals(RevertError.decode(rhs as any));
|
||||||
|
} catch (err) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
if (type === 'address') {
|
if (type === 'address') {
|
||||||
return normalizeAddress(lhs as string) === normalizeAddress(rhs as string);
|
return normalizeAddress(lhs as string) === normalizeAddress(rhs as string);
|
||||||
} else if (type === 'bytes' || /^bytes(\d+)$/.test(type)) {
|
} else if (type === 'bytes' || /^bytes(\d+)$/.test(type)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user