Skip to content

Commit

Permalink
ABI encoding performance additions (#1012).
Browse files Browse the repository at this point in the history
  • Loading branch information
ricmoo committed Oct 5, 2020
1 parent 3d051e4 commit f3e5b0d
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
33 changes: 22 additions & 11 deletions packages/abi/src.ts/coders/abstract-coder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";

import { arrayify, BytesLike, concat, hexlify } from "@ethersproject/bytes";
import { arrayify, BytesLike, concat, hexConcat, hexlify } from "@ethersproject/bytes";
import { BigNumber, BigNumberish } from "@ethersproject/bignumber";
import { defineReadOnly } from "@ethersproject/properties";

Expand Down Expand Up @@ -75,28 +75,38 @@ export abstract class Coder {
export class Writer {
readonly wordSize: number;

_data: Uint8Array;
_data: Array<Uint8Array>;
_dataLength: number;
_padding: Uint8Array;

constructor(wordSize?: number) {
defineReadOnly(this, "wordSize", wordSize || 32);
this._data = arrayify([ ]);
this._data = [ ];
this._dataLength = 0;
this._padding = new Uint8Array(wordSize);
}

get data(): string { return hexlify(this._data); }
get length(): number { return this._data.length; }
get data(): string {
return hexConcat(this._data);
}
get length(): number { return this._dataLength; }

_writeData(data: Uint8Array): number {
this._data = concat([ this._data, data ]);
this._data.push(data);
this._dataLength += data.length;
return data.length;
}

appendWriter(writer: Writer): number {
return this._writeData(concat(writer._data));
}

// Arrayish items; padded on the right to wordSize
writeBytes(value: BytesLike): number {
let bytes = arrayify(value);
if (bytes.length % this.wordSize) {
bytes = concat([ bytes, this._padding.slice(bytes.length % this.wordSize) ])
const paddingOffset = bytes.length % this.wordSize;
if (paddingOffset) {
bytes = concat([ bytes, this._padding.slice(paddingOffset) ])
}
return this._writeData(bytes);
}
Expand All @@ -121,10 +131,11 @@ export class Writer {
}

writeUpdatableValue(): (value: BigNumberish) => void {
let offset = this.length;
this.writeValue(0);
const offset = this._data.length;
this._data.push(this._padding);
this._dataLength += this.wordSize;
return (value: BigNumberish) => {
this._data.set(this._getValue(value), offset);
this._data[offset] = this._getValue(value);
};
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/abi/src.ts/coders/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export function pack(writer: Writer, coders: ReadonlyArray<Coder>, values: Array
// Backfill all the dynamic offsets, now that we know the static length
updateFuncs.forEach((func) => { func(staticWriter.length); });

let length = writer.writeBytes(staticWriter.data);
length += writer.writeBytes(dynamicWriter.data);
let length = writer.appendWriter(staticWriter);
length += writer.appendWriter(dynamicWriter);
return length;
}

Expand Down

0 comments on commit f3e5b0d

Please sign in to comment.