From 3bc45395cc0e1c5c483e7319967b6308122123bf Mon Sep 17 00:00:00 2001
From: Greg Hysen <greg.hysen@gmail.com>
Date: Thu, 8 Nov 2018 11:14:44 -0800
Subject: static vs dynamic tuple differentatiion

---
 packages/order-utils/test/abi_encoder.ts      | 30 +++++++++++++++------
 packages/order-utils/test/abi_encoder_test.ts | 34 ++++++++++++++++-------
 packages/order-utils/test/abi_samples.ts      | 39 ++++++++++++++++++++++++---
 3 files changed, 83 insertions(+), 20 deletions(-)

diff --git a/packages/order-utils/test/abi_encoder.ts b/packages/order-utils/test/abi_encoder.ts
index 77cb89056..853aac627 100644
--- a/packages/order-utils/test/abi_encoder.ts
+++ b/packages/order-utils/test/abi_encoder.ts
@@ -770,12 +770,14 @@ export class SolArray extends DynamicDataType {
 export class Tuple extends DynamicDataType {
     private length: BigNumber;
     private childMap: { [key: string]: number };
+    private members: DataType[];
 
     constructor(dataItem: DataItem) {
         super(dataItem);
         expect(Tuple.matchGrammar(dataItem.type)).to.be.true();
         this.length = new BigNumber(0);
         this.childMap = {};
+        this.members = [];
         if (dataItem.components !== undefined) {
             this.constructChildren(dataItem.components);
             this.length = new BigNumber(dataItem.components.length);
@@ -792,7 +794,11 @@ export class Tuple extends DynamicDataType {
             } as DataItem;
             const child = DataTypeFactory.create(childDataItem, this);
             this.childMap[dataItem.name] = this.children.length;
-            this.children.push(child);
+
+            if (child instanceof Pointer) {
+                this.children.push(child.getChildren()[0]);
+            }
+            this.members.push(child);
         });
     }
 
@@ -810,7 +816,7 @@ export class Tuple extends DynamicDataType {
         // Assign values to children
         for (let idx = new BigNumber(0); idx.lessThan(this.length); idx = idx.plus(1)) {
             const idxNumber = idx.toNumber();
-            this.children[idxNumber].assignValue(value[idxNumber]);
+            this.members[idxNumber].assignValue(value[idxNumber]);
         }
     }
 
@@ -820,7 +826,7 @@ export class Tuple extends DynamicDataType {
             if (key in childMap === false) {
                 throw new Error(`Could not assign tuple to object: unrecognized key '${key}'`);
             }
-            this.children[this.childMap[key]].assignValue(value);
+            this.members[this.childMap[key]].assignValue(value);
             delete childMap[key];
         });
 
@@ -840,7 +846,14 @@ export class Tuple extends DynamicDataType {
     }
 
     public getHexValue(): string {
-        return '0x';
+        let paramBufs: Buffer[] = [];
+        _.each(this.members, (member: DataType) => {
+            paramBufs.push(ethUtil.toBuffer(member.getHexValue()));
+        });
+
+        const value = Buffer.concat(paramBufs);
+        const hexValue = ethUtil.bufferToHex(value);
+        return hexValue;
     }
 
     public getHeaderSize(): BigNumber {
@@ -856,9 +869,9 @@ export class Tuple extends DynamicDataType {
     public getSignature(): string {
         // Compute signature
         let signature = `(`;
-        _.each(this.children, (child: DataType, i: number) => {
-            signature += child.getSignature();
-            if (i < this.children.length - 1) {
+        _.each(this.members, (member: DataType, i: number) => {
+            signature += member.getSignature();
+            if (i < this.members.length - 1) {
                 signature += ',';
             }
         });
@@ -867,7 +880,8 @@ export class Tuple extends DynamicDataType {
     }
 
     public isStatic(): boolean {
-        return false; // @TODO: True in every case or only when dynamic data?
+        const isStaticTuple = this.children.length === 0;
+        return isStaticTuple; // @TODO: True in every case or only when dynamic data?
     }
 
     public static matchGrammar(type: string): boolean {
diff --git a/packages/order-utils/test/abi_encoder_test.ts b/packages/order-utils/test/abi_encoder_test.ts
index 91a32bfbf..070bfe7f6 100644
--- a/packages/order-utils/test/abi_encoder_test.ts
+++ b/packages/order-utils/test/abi_encoder_test.ts
@@ -36,7 +36,7 @@ describe.only('ABI Encoder', () => {
                 '0x7283472398237423984723984729847248927498748974284728947239487498749847874329423743492347329847239842374892374892374892347238947289478947489374289472894738942749823743298742389472389473289472389437249823749823742893472398',
                 '0x283473298473248923749238742398742398472894729843278942374982374892374892743982',
             ], // m
-            [
+            /*[
                 [
                     'some string',
                     'some another string',
@@ -49,7 +49,7 @@ describe.only('ABI Encoder', () => {
                     'the kid knows how to write poems, what can I say -- I guess theres a lot I could say to try to fill this line with a lot of text.',
                 ],
                 [],
-            ], // n
+            ],*/ // n
             [
                 new BigNumber(4037824789),
                 'the kid knows how to write poems, what can I say -- I guess theres a lot I could say to try to fill this line with a lot of text.',
@@ -114,7 +114,9 @@ describe.only('ABI Encoder', () => {
             console.log(JSON.stringify(args));
             console.log(method.getSignature());
 
-            const expectedCalldata = '0x30e1f844000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e72834723982374239847239847298472489274987489742847289472394874987498478743294237434923473298472398423748923748923748923472389472894789474893742894728947389427498237432987423894723894732894723894372498237498237428934723980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027283473298473248923749238742398742398472894729843278942374982374892374892743982000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000b736f6d6520737472696e670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013736f6d6520616e6f7468657220737472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024746865726520617265206a75737420746f6f206d616e7920737472696e6773757020696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002079616c6c2067686f6e6e61206d616b65206d65206c6f7365206d79206d696e640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf5763d5ec63d500600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f7484848484848484848484848484848484848384757687980943399445858584893209100000000000000000000000000000000000000000000000000000000';
+            const expectedCalldata = '0x76c14e63000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e728347239823742398472398472984724892749874897428472894723948749874984787432942374349234732984723984237489237489237489234723894728947894748937428947289473894274982374329874238947238947328947238943724982374982374289347239800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000272834732984732489237492387423987423984728947298432789423749823748923748927439820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf5763d5ec63d500600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f7484848484848484848484848484848484848384757687980943399445858584893209100000000000000000000000000000000000000000000000000000000';
+
+            //const expectedCalldata = '0x30e1f844000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000008600000000000000000000000000000000000000000000000000000000000000960000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000163874563783498732482743928742389723894723984700000000000000000000000000000000000000000000000000000000000000000000000000000000006e72834723982374239847239847298472489274987489742847289472394874987498478743294237434923473298472398423748923748923748923472389472894789474893742894728947389427498237432987423894723894732894723894372498237498237428934723980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027283473298473248923749238742398742398472894729843278942374982374892374892743982000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000b736f6d6520737472696e670000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013736f6d6520616e6f7468657220737472696e67000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024746865726520617265206a75737420746f6f206d616e7920737472696e6773757020696e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002079616c6c2067686f6e6e61206d616b65206d65206c6f7365206d79206d696e640000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000034746865206c6974746c6520706970696e67207069706572207069706564206120706970696e6720706970706572207061707065720000000000000000000000000000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0ac511500000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000081746865206b6964206b6e6f777320686f7720746f20777269746520706f656d732c20776861742063616e204920736179202d2d2049206775657373207468657265732061206c6f74204920636f756c642073617920746f2074727920746f2066696c6c2074686973206c696e6520776974682061206c6f74206f6620746578742e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cf5763d5ec63d500600000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498000000000000000000000000000000000000000000000000000000000000004e616b64686a61736a6b646861736a6b6c647368646a6168646b6a73616864616a6b73646873616a6b646873616a6b646861646a6b617368646a6b73616468616a6b646873616a6b64687361646a6b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f7484848484848484848484848484848484848384757687980943399445858584893209100000000000000000000000000000000000000000000000000000000';
             expect(calldata).to.be.equal(expectedCalldata);
 
             /*
@@ -209,8 +211,21 @@ describe.only('ABI Encoder', () => {
             expect(calldata).to.be.equal(expectedCalldata);
         });
 
-        it('Object ABI (Array input)', async () => {
-            const method = new AbiEncoder.Method(AbiSamples.tupleAbi);
+        it.only('Static Tuple', async () => {
+            // This is dynamic because it has dynamic members
+            const method = new AbiEncoder.Method(AbiSamples.staticTupleAbi);
+            const calldata = method.encode([[new BigNumber(5), new BigNumber(10), new BigNumber(15), false]]);
+            console.log(method.getSignature());
+            console.log(method.selector);
+
+            console.log(calldata);
+            const expectedCalldata = '0xa9125e150000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000';
+            expect(calldata).to.be.equal(expectedCalldata);
+        });
+
+        it('Dynamic Tuple (Array input)', async () => {
+            // This is dynamic because it has dynamic members
+            const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi);
             const calldata = method.encode([[new BigNumber(5), 'five']]);
             console.log(method.getSignature());
             console.log(method.selector);
@@ -221,8 +236,9 @@ describe.only('ABI Encoder', () => {
             expect(calldata).to.be.equal(expectedCalldata);
         });
 
-        it('Object ABI (Object input)', async () => {
-            const method = new AbiEncoder.Method(AbiSamples.tupleAbi);
+        it('Dynamic Tuple (Object input)', async () => {
+            // This is dynamic because it has dynamic members
+            const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi);
             const calldata = method.encode([{ someUint: new BigNumber(5), someStr: 'five' }]);
             console.log(method.getSignature());
             console.log(method.selector);
@@ -234,7 +250,7 @@ describe.only('ABI Encoder', () => {
         });
 
         it.skip('Object ABI (Object input - Missing Key)', async () => {
-            const method = new AbiEncoder.Method(AbiSamples.tupleAbi);
+            const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi);
             const calldata = method.encode([{ someUint: new BigNumber(5) }]);
             console.log(method.getSignature());
             console.log(method.selector);
@@ -248,7 +264,7 @@ describe.only('ABI Encoder', () => {
         });
 
         it.skip('Object ABI (Object input - Too Many Keys)', async () => {
-            const method = new AbiEncoder.Method(AbiSamples.tupleAbi);
+            const method = new AbiEncoder.Method(AbiSamples.dynamicTupleAbi);
             const calldata = method.encode([{ someUint: new BigNumber(5), someStr: 'five', unwantedKey: 14 }]);
             console.log(method.getSignature());
             console.log(method.selector);
diff --git a/packages/order-utils/test/abi_samples.ts b/packages/order-utils/test/abi_samples.ts
index 2e7111504..fb5cfbeb7 100644
--- a/packages/order-utils/test/abi_samples.ts
+++ b/packages/order-utils/test/abi_samples.ts
@@ -34,7 +34,7 @@ export const stringAbi = {
     type: 'function',
 } as MethodAbi;
 
-export const tupleAbi = {
+export const dynamicTupleAbi = {
     constant: false,
     inputs: [
         {
@@ -59,6 +59,39 @@ export const tupleAbi = {
     type: 'function',
 } as MethodAbi;
 
+export const staticTupleAbi = {
+    constant: false,
+    inputs: [
+        {
+            components: [
+                {
+                    name: 'someUint1',
+                    type: 'uint256',
+                },
+                {
+                    name: 'someUint2',
+                    type: 'uint256',
+                },
+                {
+                    name: 'someUint3',
+                    type: 'uint256',
+                },
+                {
+                    name: 'someBool',
+                    type: 'bool',
+                },
+            ],
+            name: 'order',
+            type: 'tuple',
+        },
+    ],
+    name: 'simpleFunction',
+    outputs: [],
+    payable: false,
+    stateMutability: 'nonpayable',
+    type: 'function',
+} as MethodAbi;
+
 export const staticArrayAbi = {
     constant: false,
     inputs: [
@@ -171,10 +204,10 @@ export const crazyAbi = {
             name: 'someDynamicArrayWithDynamicMembers',
             type: 'bytes[]',
         },
-        {
+        /* {
             name: 'some2DArray',
             type: 'string[][]',
-        },
+        }, */
         {
             name: 'someTuple',
             type: 'tuple',
-- 
cgit v1.2.3