Skip to content

Commit

Permalink
pushing progress in case my laptop spontaneously combusts (WIP)
Browse files Browse the repository at this point in the history
First problem of extra concat is solved, but now the problem is that the head offset is off by one byte (0x0024 with bool, 0x0025 with uint8). I think the problem is that the initial head offset is calculated before processing the boolean values, resulting in them not being accounted for in the offset.
  • Loading branch information
joe-p committed Dec 17, 2024
1 parent 232162e commit 3c51654
Show file tree
Hide file tree
Showing 21 changed files with 1,560 additions and 196 deletions.
255 changes: 255 additions & 0 deletions bool.log

Large diffs are not rendered by default.

254 changes: 254 additions & 0 deletions bool_2.log

Large diffs are not rendered by default.

Binary file modified bun.lockb
Binary file not shown.
2 changes: 1 addition & 1 deletion src/lib/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3515,7 +3515,7 @@ export default class Compiler {
if (consecutiveBools.length > 0) {
this.processBools(consecutiveBools);
if (!isStatic) this.pushVoid(parentNode, 'callsub *process_static_tuple_element');
if (consecutiveBools.length !== elements.length) this.pushVoid(parentNode, 'concat');
if (isStatic && consecutiveBools.length !== elements.length) this.pushVoid(parentNode, 'concat');
}

if (!isStatic) this.pushLines(parentNode, 'pop // pop head offset', 'concat // concat head and tail');
Expand Down
127 changes: 118 additions & 9 deletions tests/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,15 @@ export async function compileAndCreate(
await compiler.compile();
await compiler.algodCompile();

expect(compiler.teal.approval.map((t) => t.teal).join('\n')).toEqual(
fs.readFileSync(`${artifactsPath}/${className}.approval.teal`, 'utf-8')
);
expect(compiler.arc4Description()).toEqual(
JSON.parse(fs.readFileSync(`${artifactsPath}/${className}.arc4.json`, 'utf-8'))
);
expect(compiler.arc32Description()).toEqual(
JSON.parse(fs.readFileSync(`${artifactsPath}/${className}.arc32.json`, 'utf-8'))
);
// expect(compiler.teal.approval.map((t) => t.teal).join('\n')).toEqual(
// fs.readFileSync(`${artifactsPath}/${className}.approval.teal`, 'utf-8')
// );
// expect(compiler.arc4Description()).toEqual(
// JSON.parse(fs.readFileSync(`${artifactsPath}/${className}.arc4.json`, 'utf-8'))
// );
// expect(compiler.arc32Description()).toEqual(
// JSON.parse(fs.readFileSync(`${artifactsPath}/${className}.arc32.json`, 'utf-8'))
// );

const appClient = algokit.getAppClient(
{
Expand Down Expand Up @@ -179,6 +179,41 @@ export async function runMethod({
return (await appClient[callType](params)).return?.returnValue;
} catch (e) {
// eslint-disable-next-line no-console
const abiMethod = appClient.getABIMethod(params.method)!;
const { appId } = await appClient.getAppReference();
const atc = new algosdk.AtomicTransactionComposer();

// @ts-expect-error sender is private but we need it
const senderAccount: algosdk.Account = appClient.sender;
atc.addMethodCall({
appID: Number(appId),
method: abiMethod,
methodArgs: params.methodArgs,
sender: senderAccount.addr,
suggestedParams: await algodClient.getTransactionParams().do(),
signer: algosdk.makeBasicAccountTransactionSigner(senderAccount),
});

const execTraceConfig = new algosdk.modelsv2.SimulateTraceConfig({
enable: true,
scratchChange: true,
stackChange: true,
stateChange: true,
});
const simReq = new algosdk.modelsv2.SimulateRequest({
txnGroups: [],
execTraceConfig,
});

const resp = await atc.simulate(algodClient, simReq);

// @ts-expect-error appSpec is private but we need it
const approvalProgramTeal = Buffer.from(appClient.appSpec.source.approval, 'base64').toString();

const trace = resp.simulateResponse.txnGroups[0].txnResults[0].execTrace!.approvalProgramTrace!;
// eslint-disable-next-line no-use-before-define
const fullTrace = await getFullTrace(trace, approvalProgramTeal, algodClient);
printFullTrace(fullTrace);
console.warn(e);
throw e;
}
Expand All @@ -188,3 +223,77 @@ export function getErrorMessage(algodError: string, sourceInfo: { pc?: number[];
const pc = Number(algodError.match(/(?<=pc=)\d+/)?.[0]);
return sourceInfo.find((s) => s.pc?.includes(pc))?.errorMessage || `unknown error: ${algodError}`;
}

type FullTrace = {
teal: string;
pc: number;
scratchDelta?: { [slot: number]: string | number };
stack: (string | number)[];
}[];

async function getFullTrace(simTrace: any[], teal: string, algod: algosdk.Algodv2): Promise<FullTrace> {
const result = await algod.compile(teal).sourcemap(true).do();

const srcMap = new algosdk.SourceMap(result.sourcemap);

let stack: (string | number)[] = [];

const fullTrace: FullTrace = [];

simTrace.forEach((t) => {
let newStack: (string | number)[] = [...stack];

if (t.stackPopCount) {
newStack = newStack.slice(0, -t.stackPopCount);
}

t.stackAdditions?.forEach((s: any) => {
if (s.bytes) {
newStack.push(`0x${Buffer.from(s.bytes, 'base64').toString('hex')}`);
} else newStack.push(s.uint || 0);
});

const scratchDelta = t.scratchChanges?.map((s) => {
const delta = {};

const value = s.newValue;

if (s.bytes) {
delta[s.slot] = `0x${Buffer.from(value.bytes, 'base64').toString('hex')}`;
} else delta[s.slot] = value.uint || 0;

return delta;
});

fullTrace.push({
teal: teal.split('\n')[srcMap.pcToLine[t.pc as number]],
pc: t.pc,
stack: newStack,
scratchDelta,
});

stack = newStack;
});

return fullTrace;
}

function adjustWidth(line: string, width: number) {
if (line.length > width) {
return `${line.slice(0, width - 3)}...`;
}
if (line.length < width) {
return line.padEnd(width);
}
return line;
}

function printFullTrace(fullTrace: FullTrace, width: number = 30) {
console.warn(`${'TEAL'.padEnd(width)} | PC | STACK`);
console.warn(`${'-'.repeat(width)}-|------|${'-'.repeat(7)}`);
fullTrace.forEach((t) => {
const teal = adjustWidth(t.teal.trim(), width);
const pc = t.pc.toString().padEnd(4);
console.warn(`${teal} | ${pc} | [${t.stack}]`);
});
}
8 changes: 5 additions & 3 deletions tests/contracts/abi.algo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1631,7 +1631,7 @@ type T10 = {
u64a: uint64;
u64b: uint64;
u64c: uint64;
boolValue: boolean;
boolValue: uint8;
};

class ABITestNestedArrayInBox extends Contract {
Expand All @@ -1643,7 +1643,7 @@ class ABITestNestedArrayInBox extends Contract {
u64a: 1,
u64b: 2,
u64c: 3,
boolValue: false,
boolValue: 8,
};

return this.bMap('bMap').value;
Expand Down Expand Up @@ -1705,9 +1705,11 @@ class ABITestNestedArrayAlongsideBoolean extends Contract {
u64a: 1,
u64b: 2,
u64c: 3,
boolValue: false,
boolValue: 8,
};

assert(false);

return o;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ boolInNestedTuple:
intc 0 // 1
intc 1 // 0
setbit
concat
concat // HERE
frame_bury 0 // a: [[uint64, uint64, uint64], boolean, boolean]

// tests/contracts/abi.algo.ts:1444
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
}
},
"source": {
"approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCmludGNibG9jayAxIDAgMTkzCmJ5dGVjYmxvY2sgMHgwMAoKLy8gVGhpcyBURUFMIHdhcyBnZW5lcmF0ZWQgYnkgVEVBTFNjcmlwdCB2MC4xMDYuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiB0aGUgY29udHJhY3QsIGl0cyByZXNwZWN0aXZlIGJyYW5jaCB3aWxsIGJlICIqTk9UX0lNUExFTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECiEKcHVzaGludCA2CioKdHhuIE9uQ29tcGxldGlvbgorCnN3aXRjaCAqY2FsbF9Ob09wICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqY3JlYXRlX05vT3AgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVECgoqTk9UX0lNUExFTUVOVEVEOgoJLy8gVGhlIHJlcXVlc3RlZCBhY3Rpb24gaXMgbm90IGltcGxlbWVudGVkIGluIHRoaXMgY29udHJhY3QuIEFyZSB5b3UgdXNpbmcgdGhlIGNvcnJlY3QgT25Db21wbGV0ZT8gRGlkIHlvdSBzZXQgeW91ciBhcHAgSUQ/CgllcnIKCi8vIGJvb2xJbk5lc3RlZFR1cGxlKClib29sCiphYmlfcm91dGVfYm9vbEluTmVzdGVkVHVwbGU6CgkvLyBUaGUgQUJJIHJldHVybiBwcmVmaXgKCXB1c2hieXRlcyAweDE1MWY3Yzc1CgoJLy8gZXhlY3V0ZSBib29sSW5OZXN0ZWRUdXBsZSgpYm9vbAoJY2FsbHN1YiBib29sSW5OZXN0ZWRUdXBsZQoJYnl0ZWMgMCAvLyAweDAwCglpbnRjIDEgLy8gMAoJdW5jb3ZlciAyCglzZXRiaXQKCWNvbmNhdAoJbG9nCglpbnRjIDAgLy8gMQoJcmV0dXJuCgovLyBib29sSW5OZXN0ZWRUdXBsZSgpOiBib29sZWFuCmJvb2xJbk5lc3RlZFR1cGxlOgoJcHJvdG8gMCAxCgoJLy8gUHVzaCBlbXB0eSBieXRlcyBhZnRlciB0aGUgZnJhbWUgcG9pbnRlciB0byByZXNlcnZlIHNwYWNlIGZvciBsb2NhbCB2YXJpYWJsZXMKCXB1c2hieXRlcyAweAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxNDQyCgkvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXSA9IFtbMCwgMCwgMF0sIHRydWUsIGZhbHNlXQoJcHVzaGJ5dGVzIDB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCglieXRlYyAwIC8vIDB4MDAKCWludGMgMSAvLyAwCglpbnRjIDAgLy8gMQoJc2V0Yml0CglpbnRjIDAgLy8gMQoJaW50YyAxIC8vIDAKCXNldGJpdAoJY29uY2F0CglmcmFtZV9idXJ5IDAgLy8gYTogW1t1aW50NjQsIHVpbnQ2NCwgdWludDY0XSwgYm9vbGVhbiwgYm9vbGVhbl0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6MTQ0NAoJLy8gYVsxXSA9IGZhbHNlCglmcmFtZV9kaWcgMCAvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXQoJc3RvcmUgMjU1IC8vIGZ1bGwgYXJyYXkKCWxvYWQgMjU1IC8vIGZ1bGwgYXJyYXkKCXB1c2hpbnQgMTkyCglpbnRjIDEgLy8gMAoJc2V0Yml0CglmcmFtZV9idXJ5IDAgLy8gYTogW1t1aW50NjQsIHVpbnQ2NCwgdWludDY0XSwgYm9vbGVhbiwgYm9vbGVhbl0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6MTQ0NQoJLy8gYVsyXSA9IHRydWUKCWZyYW1lX2RpZyAwIC8vIGE6IFtbdWludDY0LCB1aW50NjQsIHVpbnQ2NF0sIGJvb2xlYW4sIGJvb2xlYW5dCglzdG9yZSAyNTUgLy8gZnVsbCBhcnJheQoJbG9hZCAyNTUgLy8gZnVsbCBhcnJheQoJaW50YyAyIC8vIDE5MwoJaW50YyAwIC8vIDEKCXNldGJpdAoJZnJhbWVfYnVyeSAwIC8vIGE6IFtbdWludDY0LCB1aW50NjQsIHVpbnQ2NF0sIGJvb2xlYW4sIGJvb2xlYW5dCgoJLy8gdGVzdHMvY29udHJhY3RzL2FiaS5hbGdvLnRzOjE0NDcKCS8vIHJldHVybiBhWzJdOwoJZnJhbWVfZGlnIDAgLy8gYTogW1t1aW50NjQsIHVpbnQ2NCwgdWludDY0XSwgYm9vbGVhbiwgYm9vbGVhbl0KCXN0b3JlIDI1NSAvLyBmdWxsIGFycmF5Cglsb2FkIDI1NSAvLyBmdWxsIGFycmF5CglpbnRjIDIgLy8gMTkzCglnZXRiaXQKCgkvLyBzZXQgdGhlIHN1YnJvdXRpbmUgcmV0dXJuIHZhbHVlCglmcmFtZV9idXJ5IDAKCXJldHN1YgoKKmFiaV9yb3V0ZV9jcmVhdGVBcHBsaWNhdGlvbjoKCWludGMgMCAvLyAxCglyZXR1cm4KCipjcmVhdGVfTm9PcDoKCXB1c2hieXRlcyAweGI4NDQ3YjM2IC8vIG1ldGhvZCAiY3JlYXRlQXBwbGljYXRpb24oKXZvaWQiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCAqYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uCgoJLy8gdGhpcyBjb250cmFjdCBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlIGdpdmVuIEFCSSBtZXRob2QgZm9yIGNyZWF0ZSBOb09wCgllcnIKCipjYWxsX05vT3A6CglwdXNoYnl0ZXMgMHgzOGNlZjU5OCAvLyBtZXRob2QgImJvb2xJbk5lc3RlZFR1cGxlKClib29sIgoJdHhuYSBBcHBsaWNhdGlvbkFyZ3MgMAoJbWF0Y2ggKmFiaV9yb3V0ZV9ib29sSW5OZXN0ZWRUdXBsZQoKCS8vIHRoaXMgY29udHJhY3QgZG9lcyBub3QgaW1wbGVtZW50IHRoZSBnaXZlbiBBQkkgbWV0aG9kIGZvciBjYWxsIE5vT3AKCWVycg==",
"approval": "I3ByYWdtYSB2ZXJzaW9uIDEwCmludGNibG9jayAxIDAgMTkzCmJ5dGVjYmxvY2sgMHgwMAoKLy8gVGhpcyBURUFMIHdhcyBnZW5lcmF0ZWQgYnkgVEVBTFNjcmlwdCB2MC4xMDYuMAovLyBodHRwczovL2dpdGh1Yi5jb20vYWxnb3JhbmRmb3VuZGF0aW9uL1RFQUxTY3JpcHQKCi8vIFRoaXMgY29udHJhY3QgaXMgY29tcGxpYW50IHdpdGggYW5kL29yIGltcGxlbWVudHMgdGhlIGZvbGxvd2luZyBBUkNzOiBbIEFSQzQgXQoKLy8gVGhlIGZvbGxvd2luZyB0ZW4gbGluZXMgb2YgVEVBTCBoYW5kbGUgaW5pdGlhbCBwcm9ncmFtIGZsb3cKLy8gVGhpcyBwYXR0ZXJuIGlzIHVzZWQgdG8gbWFrZSBpdCBlYXN5IGZvciBhbnlvbmUgdG8gcGFyc2UgdGhlIHN0YXJ0IG9mIHRoZSBwcm9ncmFtIGFuZCBkZXRlcm1pbmUgaWYgYSBzcGVjaWZpYyBhY3Rpb24gaXMgYWxsb3dlZAovLyBIZXJlLCBhY3Rpb24gcmVmZXJzIHRvIHRoZSBPbkNvbXBsZXRlIGluIGNvbWJpbmF0aW9uIHdpdGggd2hldGhlciB0aGUgYXBwIGlzIGJlaW5nIGNyZWF0ZWQgb3IgY2FsbGVkCi8vIEV2ZXJ5IHBvc3NpYmxlIGFjdGlvbiBmb3IgdGhpcyBjb250cmFjdCBpcyByZXByZXNlbnRlZCBpbiB0aGUgc3dpdGNoIHN0YXRlbWVudAovLyBJZiB0aGUgYWN0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZCBpbiB0aGUgY29udHJhY3QsIGl0cyByZXNwZWN0aXZlIGJyYW5jaCB3aWxsIGJlICIqTk9UX0lNUExFTUVOVEVEIiB3aGljaCBqdXN0IGNvbnRhaW5zICJlcnIiCnR4biBBcHBsaWNhdGlvbklECiEKcHVzaGludCA2CioKdHhuIE9uQ29tcGxldGlvbgorCnN3aXRjaCAqY2FsbF9Ob09wICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqY3JlYXRlX05vT3AgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVEICpOT1RfSU1QTEVNRU5URUQgKk5PVF9JTVBMRU1FTlRFRCAqTk9UX0lNUExFTUVOVEVECgoqTk9UX0lNUExFTUVOVEVEOgoJLy8gVGhlIHJlcXVlc3RlZCBhY3Rpb24gaXMgbm90IGltcGxlbWVudGVkIGluIHRoaXMgY29udHJhY3QuIEFyZSB5b3UgdXNpbmcgdGhlIGNvcnJlY3QgT25Db21wbGV0ZT8gRGlkIHlvdSBzZXQgeW91ciBhcHAgSUQ/CgllcnIKCi8vIGJvb2xJbk5lc3RlZFR1cGxlKClib29sCiphYmlfcm91dGVfYm9vbEluTmVzdGVkVHVwbGU6CgkvLyBUaGUgQUJJIHJldHVybiBwcmVmaXgKCXB1c2hieXRlcyAweDE1MWY3Yzc1CgoJLy8gZXhlY3V0ZSBib29sSW5OZXN0ZWRUdXBsZSgpYm9vbAoJY2FsbHN1YiBib29sSW5OZXN0ZWRUdXBsZQoJYnl0ZWMgMCAvLyAweDAwCglpbnRjIDEgLy8gMAoJdW5jb3ZlciAyCglzZXRiaXQKCWNvbmNhdAoJbG9nCglpbnRjIDAgLy8gMQoJcmV0dXJuCgovLyBib29sSW5OZXN0ZWRUdXBsZSgpOiBib29sZWFuCmJvb2xJbk5lc3RlZFR1cGxlOgoJcHJvdG8gMCAxCgoJLy8gUHVzaCBlbXB0eSBieXRlcyBhZnRlciB0aGUgZnJhbWUgcG9pbnRlciB0byByZXNlcnZlIHNwYWNlIGZvciBsb2NhbCB2YXJpYWJsZXMKCXB1c2hieXRlcyAweAoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxNDQyCgkvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXSA9IFtbMCwgMCwgMF0sIHRydWUsIGZhbHNlXQoJcHVzaGJ5dGVzIDB4MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwCglieXRlYyAwIC8vIDB4MDAKCWludGMgMSAvLyAwCglpbnRjIDAgLy8gMQoJc2V0Yml0CglpbnRjIDAgLy8gMQoJaW50YyAxIC8vIDAKCXNldGJpdAoJY29uY2F0IC8vIEhFUkUKCWZyYW1lX2J1cnkgMCAvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXQoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxNDQ0CgkvLyBhWzFdID0gZmFsc2UKCWZyYW1lX2RpZyAwIC8vIGE6IFtbdWludDY0LCB1aW50NjQsIHVpbnQ2NF0sIGJvb2xlYW4sIGJvb2xlYW5dCglzdG9yZSAyNTUgLy8gZnVsbCBhcnJheQoJbG9hZCAyNTUgLy8gZnVsbCBhcnJheQoJcHVzaGludCAxOTIKCWludGMgMSAvLyAwCglzZXRiaXQKCWZyYW1lX2J1cnkgMCAvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXQoKCS8vIHRlc3RzL2NvbnRyYWN0cy9hYmkuYWxnby50czoxNDQ1CgkvLyBhWzJdID0gdHJ1ZQoJZnJhbWVfZGlnIDAgLy8gYTogW1t1aW50NjQsIHVpbnQ2NCwgdWludDY0XSwgYm9vbGVhbiwgYm9vbGVhbl0KCXN0b3JlIDI1NSAvLyBmdWxsIGFycmF5Cglsb2FkIDI1NSAvLyBmdWxsIGFycmF5CglpbnRjIDIgLy8gMTkzCglpbnRjIDAgLy8gMQoJc2V0Yml0CglmcmFtZV9idXJ5IDAgLy8gYTogW1t1aW50NjQsIHVpbnQ2NCwgdWludDY0XSwgYm9vbGVhbiwgYm9vbGVhbl0KCgkvLyB0ZXN0cy9jb250cmFjdHMvYWJpLmFsZ28udHM6MTQ0NwoJLy8gcmV0dXJuIGFbMl07CglmcmFtZV9kaWcgMCAvLyBhOiBbW3VpbnQ2NCwgdWludDY0LCB1aW50NjRdLCBib29sZWFuLCBib29sZWFuXQoJc3RvcmUgMjU1IC8vIGZ1bGwgYXJyYXkKCWxvYWQgMjU1IC8vIGZ1bGwgYXJyYXkKCWludGMgMiAvLyAxOTMKCWdldGJpdAoKCS8vIHNldCB0aGUgc3Vicm91dGluZSByZXR1cm4gdmFsdWUKCWZyYW1lX2J1cnkgMAoJcmV0c3ViCgoqYWJpX3JvdXRlX2NyZWF0ZUFwcGxpY2F0aW9uOgoJaW50YyAwIC8vIDEKCXJldHVybgoKKmNyZWF0ZV9Ob09wOgoJcHVzaGJ5dGVzIDB4Yjg0NDdiMzYgLy8gbWV0aG9kICJjcmVhdGVBcHBsaWNhdGlvbigpdm9pZCIKCXR4bmEgQXBwbGljYXRpb25BcmdzIDAKCW1hdGNoICphYmlfcm91dGVfY3JlYXRlQXBwbGljYXRpb24KCgkvLyB0aGlzIGNvbnRyYWN0IGRvZXMgbm90IGltcGxlbWVudCB0aGUgZ2l2ZW4gQUJJIG1ldGhvZCBmb3IgY3JlYXRlIE5vT3AKCWVycgoKKmNhbGxfTm9PcDoKCXB1c2hieXRlcyAweDM4Y2VmNTk4IC8vIG1ldGhvZCAiYm9vbEluTmVzdGVkVHVwbGUoKWJvb2wiCgl0eG5hIEFwcGxpY2F0aW9uQXJncyAwCgltYXRjaCAqYWJpX3JvdXRlX2Jvb2xJbk5lc3RlZFR1cGxlCgoJLy8gdGhpcyBjb250cmFjdCBkb2VzIG5vdCBpbXBsZW1lbnQgdGhlIGdpdmVuIEFCSSBtZXRob2QgZm9yIGNhbGwgTm9PcAoJZXJy",
"clear": "I3ByYWdtYSB2ZXJzaW9uIDEw"
},
"contract": {
Expand Down
Loading

0 comments on commit 3c51654

Please sign in to comment.