Skip to content

Commit

Permalink
fix: [BUG] unsafeClient evaluationOptions vs manifest #425
Browse files Browse the repository at this point in the history
  • Loading branch information
ppedziwiatr committed Jun 15, 2023
1 parent 5603b91 commit 7bc3003
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
version: 'latest'
- name: Install modules
run: yarn
- name: Lint
run: yarn lint
- name: Build package
run: yarn build
- name: Run unit tests
Expand Down
108 changes: 105 additions & 3 deletions src/__tests__/unit/evaluation-options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,115 @@ describe('Evaluation options evaluator', () => {
walletBalanceUrl: 'http://nyc-1.dev.arweave.net:1984/'
});

expect(function () {
const result = new EvaluationOptionsEvaluator(contract2.evaluationOptions(), {
expect(new EvaluationOptionsEvaluator(contract2.evaluationOptions(), {
internalWrites: false
}).rootOptions).toEqual({
allowBigInt: false,
cacheEveryNInteractions: -1,
gasLimit: 2222,
ignoreExceptions: true,
internalWrites: false,
maxCallDepth: 5,
maxInteractionEvaluationTimeSeconds: 60,
mineArLocalBlocks: true,
remoteStateSyncEnabled: false,
remoteStateSyncSource: 'https://dre-1.warp.cc/contract',
sequencerUrl: 'https://d1o5nlqr4okus2.cloudfront.net/',
sourceType: 'both',
stackTrace: {
saveState: false
},
throwOnInternalWriteError: true,
unsafeClient: 'allow',
updateCacheForEachInteraction: false,
useKVStorage: false,
waitForConfirmation: false,
useConstructor: false,
walletBalanceUrl: 'http://nyc-1.dev.arweave.net:1984/'
});

expect(new EvaluationOptionsEvaluator(contract2.evaluationOptions(), {
unsafeClient: 'throw'
}).rootOptions).toEqual({
allowBigInt: false,
cacheEveryNInteractions: -1,
gasLimit: 2222,
ignoreExceptions: true,
internalWrites: true,
maxCallDepth: 5,
maxInteractionEvaluationTimeSeconds: 60,
mineArLocalBlocks: true,
remoteStateSyncEnabled: false,
remoteStateSyncSource: 'https://dre-1.warp.cc/contract',
sequencerUrl: 'https://d1o5nlqr4okus2.cloudfront.net/',
sourceType: 'both',
stackTrace: {
saveState: false
},
throwOnInternalWriteError: true,
unsafeClient: 'throw',
updateCacheForEachInteraction: false,
useKVStorage: false,
waitForConfirmation: false,
useConstructor: false,
walletBalanceUrl: 'http://nyc-1.dev.arweave.net:1984/'
});

expect(new EvaluationOptionsEvaluator(contract2.evaluationOptions(), {
unsafeClient: 'skip'
}).rootOptions).toEqual({
allowBigInt: false,
cacheEveryNInteractions: -1,
gasLimit: 2222,
ignoreExceptions: true,
internalWrites: true,
maxCallDepth: 5,
maxInteractionEvaluationTimeSeconds: 60,
mineArLocalBlocks: true,
remoteStateSyncEnabled: false,
remoteStateSyncSource: 'https://dre-1.warp.cc/contract',
sequencerUrl: 'https://d1o5nlqr4okus2.cloudfront.net/',
sourceType: 'both',
stackTrace: {
saveState: false
},
throwOnInternalWriteError: true,
unsafeClient: 'skip',
updateCacheForEachInteraction: false,
useKVStorage: false,
waitForConfirmation: false,
useConstructor: false,
walletBalanceUrl: 'http://nyc-1.dev.arweave.net:1984/'
});


const contract3 = warp.contract(null).setEvaluationOptions({
internalWrites: false,
unsafeClient: 'throw',
gasLimit: 2222,
maxCallDepth: 5
});

expect(function () {
const result = new EvaluationOptionsEvaluator(contract3.evaluationOptions(), {
internalWrites: true
}).rootOptions;
}).toThrow('Option {internalWrites} differs.');
}).toThrow('Cannot proceed with contract evaluation.');

expect(function () {
const result = new EvaluationOptionsEvaluator(contract3.evaluationOptions(), {
unsafeClient: 'allow'
}).rootOptions;
}).toThrow('Cannot proceed with contract evaluation.');

expect(function () {
const result = new EvaluationOptionsEvaluator(contract3.evaluationOptions(), {
unsafeClient: 'skip'
}).rootOptions;
}).toThrow('Cannot proceed with contract evaluation.');
});


it('should properly set foreign evaluation options - unsafeClient - allow', async () => {
const contract = warp.contract(null).setEvaluationOptions({
unsafeClient: 'allow'
Expand Down
32 changes: 27 additions & 5 deletions src/contract/EvaluationOptionsEvaluator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,35 @@ export class EvaluationOptionsEvaluator {
if (manifestOptions) {
const errors = [];
for (const k in manifestOptions) {
if (this.notConflictingEvaluationOptions.includes(k as keyof EvaluationOptions)) {
const optionKey = k as keyof EvaluationOptions;
const manifestValue = manifestOptions[k];
const userValue = userSetOptions[k];
if (this.notConflictingEvaluationOptions.includes(optionKey)) {
continue;
}
if (userSetOptions[k] !== manifestOptions[k]) {
errors.push(
`Option {${k}} differs. EvaluationOptions: [${userSetOptions[k]}], manifest: [${manifestOptions[k]}]. Use contract.setEvaluationOptions({${k}: ${manifestOptions[k]}}) to evaluate contract state.`
);
// https://github.com/warp-contracts/warp/issues/425#issuecomment-1591212639
if (optionKey === 'internalWrites') {
if (userValue === false && manifestValue === true) {
throw new Error(
'Cannot proceed with contract evaluation. User is blocking internal writes, while contract requires them.'
);
}
} else if (optionKey === 'unsafeClient') {
// 'allow' | 'skip' | 'throw'
if (
(userValue === 'throw' && manifestValue !== 'throw') ||
(userValue === 'skip' && manifestValue === 'allow')
) {
throw new Error(
`Cannot proceed with contract evaluation. User requires to ${userValue} on any unsafeClient usage, while contract uses ${manifestValue} option.`
);
}
} else {
if (userSetOptions[k] !== manifestOptions[k]) {
errors.push(
`Option {${k}} differs. EvaluationOptions: [${userSetOptions[k]}], manifest: [${manifestOptions[k]}]. Use contract.setEvaluationOptions({${k}: ${manifestOptions[k]}}) to evaluate contract state.`
);
}
}
}
if (errors.length) {
Expand Down

0 comments on commit 7bc3003

Please sign in to comment.