Skip to content

Commit

Permalink
Allow events to use compact bytes ABI coded data for Solidity 0.4 ext…
Browse files Browse the repository at this point in the history
…ernal events (#891, #992).
  • Loading branch information
ricmoo committed Sep 7, 2020
1 parent 97acaa1 commit 4e394fc
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 23 deletions.
8 changes: 4 additions & 4 deletions packages/abi/src.ts/abi-coder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export class AbiCoder {

_getWordSize(): number { return 32; }

_getReader(data: Uint8Array): Reader {
return new Reader(data, this._getWordSize(), this.coerceFunc);
_getReader(data: Uint8Array, allowLoose?: boolean): Reader {
return new Reader(data, this._getWordSize(), this.coerceFunc, allowLoose);
}

_getWriter(): Writer {
Expand All @@ -107,10 +107,10 @@ export class AbiCoder {
return writer.data;
}

decode(types: Array<string | ParamType>, data: BytesLike): Result {
decode(types: Array<string | ParamType>, data: BytesLike, loose?: boolean): Result {
const coders: Array<Coder> = types.map((type) => this._getCoder(ParamType.from(type)));
const coder = new TupleCoder(coders, "_");
return coder.decode(this._getReader(arrayify(data)));
return coder.decode(this._getReader(arrayify(data), loose));
}
}

Expand Down
24 changes: 15 additions & 9 deletions packages/abi/src.ts/coders/abstract-coder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,16 +131,18 @@ export class Writer {

export class Reader {
readonly wordSize: number;
readonly allowLoose: boolean;

readonly _data: Uint8Array;
readonly _coerceFunc: CoerceFunc;

_offset: number;

constructor(data: BytesLike, wordSize?: number, coerceFunc?: CoerceFunc) {
constructor(data: BytesLike, wordSize?: number, coerceFunc?: CoerceFunc, allowLoose?: boolean) {
defineReadOnly(this, "_data", arrayify(data));
defineReadOnly(this, "wordSize", wordSize || 32);
defineReadOnly(this, "_coerceFunc", coerceFunc);
defineReadOnly(this, "allowLoose", allowLoose);

this._offset = 0;
}
Expand All @@ -160,23 +162,27 @@ export class Reader {
return Reader.coerce(name, value);
}

_peekBytes(offset: number, length: number): Uint8Array {
_peekBytes(offset: number, length: number, loose?: boolean): Uint8Array {
let alignedLength = Math.ceil(length / this.wordSize) * this.wordSize;
if (this._offset + alignedLength > this._data.length) {
logger.throwError("data out-of-bounds", Logger.errors.BUFFER_OVERRUN, {
length: this._data.length,
offset: this._offset + alignedLength
});
if (this.allowLoose && loose && this._offset + length <= this._data.length) {
alignedLength = length;
} else {
logger.throwError("data out-of-bounds", Logger.errors.BUFFER_OVERRUN, {
length: this._data.length,
offset: this._offset + alignedLength
});
}
}
return this._data.slice(this._offset, this._offset + alignedLength)
}

subReader(offset: number): Reader {
return new Reader(this._data.slice(this._offset + offset), this.wordSize, this._coerceFunc);
return new Reader(this._data.slice(this._offset + offset), this.wordSize, this._coerceFunc, this.allowLoose);
}

readBytes(length: number): Uint8Array {
let bytes = this._peekBytes(0, length);
readBytes(length: number, loose?: boolean): Uint8Array {
let bytes = this._peekBytes(0, length, !!loose);
this._offset += bytes.length;
// @TODO: Make sure the length..end bytes are all 0?
return bytes.slice(0, length);
Expand Down
8 changes: 0 additions & 8 deletions packages/abi/src.ts/coders/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
// A reader anchored to this base
let baseReader = reader.subReader(0);

// The amount of dynamic data read; to consume later to synchronize
let dynamicLength = 0;

coders.forEach((coder) => {
let value: any = null;

Expand All @@ -105,7 +102,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
value.name = coder.localName;
value.type = coder.type;
}
dynamicLength += offsetReader.consumed;

} else {
try {
Expand All @@ -125,10 +121,6 @@ export function unpack(reader: Reader, coders: Array<Coder>): Result {
}
});

// @TODO: get rid of this an see if it still works?
// Consume the dynamic components in the main reader
reader.readBytes(dynamicLength);

// We only output named properties for uniquely named coders
const uniqueNames = coders.reduce((accum, coder) => {
const name = coder.localName;
Expand Down
2 changes: 1 addition & 1 deletion packages/abi/src.ts/coders/bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class DynamicBytesCoder extends Coder {
}

decode(reader: Reader): any {
return reader.readBytes(reader.readValue().toNumber());
return reader.readBytes(reader.readValue().toNumber(), true);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/abi/src.ts/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ export class Interface {
});

let resultIndexed = (topics != null) ? this._abiCoder.decode(indexed, concat(topics)): null;
let resultNonIndexed = this._abiCoder.decode(nonIndexed, data);
let resultNonIndexed = this._abiCoder.decode(nonIndexed, data, true);

let result: (Array<any> & { [ key: string ]: any }) = [ ];
let nonIndexedIndex = 0, indexedIndex = 0;
Expand Down

0 comments on commit 4e394fc

Please sign in to comment.