aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/test/abi/calldata.ts
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils/test/abi/calldata.ts')
-rw-r--r--packages/order-utils/test/abi/calldata.ts140
1 files changed, 100 insertions, 40 deletions
diff --git a/packages/order-utils/test/abi/calldata.ts b/packages/order-utils/test/abi/calldata.ts
index dc0fcfb2b..725bdce62 100644
--- a/packages/order-utils/test/abi/calldata.ts
+++ b/packages/order-utils/test/abi/calldata.ts
@@ -9,15 +9,23 @@ export abstract class CalldataBlock {
private bodySizeInBytes: number;
private relocatable: boolean;
- constructor(name: string, signature: string, offsetInBytes: number, headerSizeInBytes: number, bodySizeInBytes: number, relocatable: boolean) {
+ constructor(name: string, signature: string, /*offsetInBytes: number,*/ headerSizeInBytes: number, bodySizeInBytes: number, relocatable: boolean) {
this.name = name;
this.signature = signature;
- this.offsetInBytes = offsetInBytes;
+ this.offsetInBytes = 0;
this.headerSizeInBytes = headerSizeInBytes;
this.bodySizeInBytes = bodySizeInBytes;
this.relocatable = relocatable;
}
+ protected setHeaderSize(headerSizeInBytes: number) {
+ this.headerSizeInBytes = headerSizeInBytes;
+ }
+
+ protected setBodySize(bodySizeInBytes: number) {
+ this.bodySizeInBytes = bodySizeInBytes;
+ }
+
public getName(): string {
return this.name;
}
@@ -46,22 +54,25 @@ export abstract class CalldataBlock {
return this.offsetInBytes;
}
- public abstract toHexString(): string;
+ public setOffset(offsetInBytes: number) {
+ this.offsetInBytes = offsetInBytes;
+ }
+
+ public abstract toBuffer(): Buffer;
}
export class PayloadCalldataBlock extends CalldataBlock {
private payload: Buffer;
- constructor(name: string, signature: string, offsetInBytes: number, relocatable: boolean, payload: Buffer) {
+ constructor(name: string, signature: string, /*offsetInBytes: number,*/ relocatable: boolean, payload: Buffer) {
const headerSizeInBytes = 0;
const bodySizeInBytes = payload.byteLength;
- super(name, signature, offsetInBytes, headerSizeInBytes, bodySizeInBytes, relocatable);
+ super(name, signature, /*offsetInBytes,*/ headerSizeInBytes, bodySizeInBytes, relocatable);
this.payload = payload;
}
- public toHexString(): string {
- const payloadHex = ethUtil.bufferToHex(this.payload);
- return payloadHex;
+ public toBuffer(): Buffer {
+ return this.payload;
}
}
@@ -70,15 +81,15 @@ export class DependentCalldataBlock extends CalldataBlock {
private parent: CalldataBlock;
private dependency: CalldataBlock;
- constructor(name: string, signature: string, offsetInBytes: number, relocatable: boolean, parent: CalldataBlock, dependency: CalldataBlock) {
+ constructor(name: string, signature: string, /*offsetInBytes: number,*/ relocatable: boolean, parent: CalldataBlock, dependency: CalldataBlock) {
const headerSizeInBytes = 0;
const bodySizeInBytes = DependentCalldataBlock.DEPENDENT_PAYLOAD_SIZE_IN_BYTES;
- super(name, signature, offsetInBytes, headerSizeInBytes, bodySizeInBytes, relocatable);
+ super(name, signature, /*offsetInBytes,*/ headerSizeInBytes, bodySizeInBytes, relocatable);
this.parent = parent;
this.dependency = dependency;
}
- public toHexString(): string {
+ public toBuffer(): Buffer {
const dependencyOffset = this.dependency.getOffsetInBytes();
const parentOffset = this.parent.getOffsetInBytes();
const parentHeaderSize = this.parent.getHeaderSizeInBytes();
@@ -86,8 +97,11 @@ export class DependentCalldataBlock extends CalldataBlock {
const pointerBuf = new Buffer(`0x${pointer.toString(16)}`);
const evmWordWidthInBytes = 32;
const pointerBufPadded = ethUtil.setLengthLeft(pointerBuf, evmWordWidthInBytes);
- const pointerHex = ethUtil.bufferToHex(pointerBufPadded);
- return pointerHex;
+ return pointerBufPadded;
+ }
+
+ public getDependency(): CalldataBlock {
+ return this.dependency;
}
}
@@ -96,51 +110,97 @@ export class MemberCalldataBlock extends CalldataBlock {
private header: Buffer | undefined;
private members: CalldataBlock[];
- constructor(name: string, signature: string, offsetInBytes: number, relocatable: boolean, members: CalldataBlock[], header?: Buffer) {
- const headerSizeInBytes = (header === undefined) ? 0 : header.byteLength;
+ constructor(name: string, signature: string, /*offsetInBytes: number,*/ relocatable: boolean) {
+ super(name, signature, /*offsetInBytes,*/ 0, 0, relocatable);
+ this.members = [];
+ this.header = undefined;
+ }
+
+ public setMembers(members: CalldataBlock[]) {
let bodySizeInBytes = 0;
- _.each(members, (member: Memblock) => {
+ _.each(members, (member: CalldataBlock) => {
bodySizeInBytes += member.getSizeInBytes();
});
-
- super(name, signature, offsetInBytes, headerSizeInBytes, bodySizeInBytes, relocatable);
this.members = members;
+ this.setBodySize(bodySizeInBytes);
+ }
+
+ public setHeader(header: Buffer) {
+ this.setHeaderSize(header.byteLength);
this.header = header;
}
- public toHexString(): string {
- let valueBuffers: Buffer[] = [];
- if (this.header !== undefined) valueBuffers.push(this.header);
- _.each(this.members, (member: CalldataBlock) => {
- const memberHexString = member.toHexString();
- const memberBuf = ethUtil.toBuffer(memberHexString);
- valueBuffers.push(memberBuf);
- });
- const combinedValueBufs = Buffer.concat(valueBuffers);
- const combinedValuesAsHex = ethUtil.bufferToHex(combinedValueBufs);
- return combinedValuesAsHex;
+ public toBuffer(): Buffer {
+ if (this.header !== undefined) return this.header;
+ return new Buffer('');
+ }
+
+ public getMembers(): CalldataBlock[] {
+ return this.members;
+ }
+}
+
+class Queue<T> {
+ private store: T[] = [];
+ push(val: T) {
+ this.store.push(val);
+ }
+ pop(): T | undefined {
+ return this.store.shift();
}
}
export class Calldata {
private selector: string;
private sizeInBytes: number;
- private blocks: CalldataBlock[];
+ private root: CalldataBlock | undefined;
constructor() {
this.selector = '0x';
this.sizeInBytes = 0;
- this.blocks = [];
+ this.root = undefined;
}
public toHexString(): string {
- let calldataString = `${this.selector}`;
- _.each(this.blocks, (block: CalldataBlock) => {
- const blockAsHexString = block.toHexString();
- const blockAsHexWithoutPrefix = ethUtil.stripHexPrefix(blockAsHexString);
- calldataString += blockAsHexWithoutPrefix;
- });
- return calldataString;
+ let selectorBuffer = ethUtil.toBuffer(this.selector);
+ if (this.root === undefined) {
+ throw new Error('expected root');
+ }
+
+ const blockQueue = new Queue<CalldataBlock>();
+ blockQueue.push(this.root);
+
+ // Assign locations in breadth-first manner
+ let block: CalldataBlock | undefined;
+ let offset = 0;
+ while ((block = blockQueue.pop()) !== undefined) {
+ block.setOffset(offset);
+ if (block instanceof DependentCalldataBlock) {
+ blockQueue.push(block.getDependency());
+ } else if (block instanceof MemberCalldataBlock) {
+ _.each(block.getMembers(), (member: CalldataBlock) => {
+ blockQueue.push(member);
+ });
+ }
+ }
+
+ // Fetch values using same technique
+ const valueBufs: Buffer[] = [selectorBuffer];
+ while ((block = blockQueue.pop()) !== undefined) {
+ valueBufs.push(block.toBuffer());
+
+ if (block instanceof DependentCalldataBlock) {
+ blockQueue.push(block.getDependency());
+ } else if (block instanceof MemberCalldataBlock) {
+ _.each(block.getMembers(), (member: CalldataBlock) => {
+ blockQueue.push(member);
+ });
+ }
+ }
+
+ const combinedBuffers = Buffer.concat(valueBufs);
+ const hexValue = ethUtil.bufferToHex(combinedBuffers);
+ return hexValue;
}
public getSelectorHex(): string {
@@ -155,8 +215,8 @@ export class Calldata {
return "";
}
- public pushBlock(block: CalldataBlock) {
- this.blocks.push(block);
+ public setRoot(block: CalldataBlock) {
+ this.root = block;
this.sizeInBytes += block.getSizeInBytes();
}