fix: CIS should return null if nothing found

This commit is contained in:
Tadeuchi
2023-07-20 11:47:20 +02:00
committed by just_ppe
parent b321456db8
commit d21d1213a6
5 changed files with 40 additions and 32 deletions

View File

@@ -130,17 +130,31 @@ describe('Testing deep internal reads', () => {
});
it('root contract should have the latest balance', async () => {
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 200 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 25 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 25 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 50 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 50 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 50 });
await mineBlock(warp);
await node20Contract.writeInteraction({ function: 'readBalanceFrom', tokenAddress: leafId, contractTxId: 'asd' });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 400 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 200 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 400 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await node22Contract.writeInteraction({ function: 'readBalanceFrom', tokenAddress: leafId, contractTxId: 'asd' });
await mineBlock(warp);
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 250 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 50 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await leafContract.writeInteraction({ function: 'increase', target: 'asd', qty: 100 });
await mineBlock(warp);
await node21Contract.writeInteraction({ function: 'readBalanceFrom', tokenAddress: leafId, contractTxId: 'asd' });
await mineBlock(warp);
@@ -154,7 +168,10 @@ describe('Testing deep internal reads', () => {
await mineBlock(warp);
const rootResult = await warp.pst(rootId).readState();
const rootResult = await warp.pst(rootId)
.setEvaluationOptions({
cacheEveryNInteractions: 1,
}).readState();
expect(rootResult.cachedValue.state.balances['asd']).toEqual(1100);
const node20Result = await warp.pst(node20Id).readState();

View File

@@ -30,8 +30,10 @@ export class ContractInteractionState implements InteractionState {
}
keys = keys.sort((a, b) => a.localeCompare(b));
const resultSortKey = keys[keys.length - 1];
if (states.get(resultSortKey)) {
return new SortKeyCacheResult<EvalStateResult<unknown>>(resultSortKey, states.get(resultSortKey));
}
}
return null;
}
@@ -87,9 +89,9 @@ export class ContractInteractionState implements InteractionState {
this._kv.clear();
}
async rollback(interaction: GQLNodeInterface): Promise<void> {
async rollback(interaction: GQLNodeInterface, forceStateStoreToCache: boolean): Promise<void> {
try {
await this.doStoreJson(this._initialJson, interaction);
await this.doStoreJson(this._initialJson, interaction, forceStateStoreToCache);
await this.rollbackKVs();
} finally {
this.reset();

View File

@@ -38,7 +38,7 @@ export interface InteractionState {
* - IFF the result.type != 'ok'.
* This ensures atomicity of state changes withing any given interaction - also in case of internal contract calls.
*/
rollback(interaction: GQLNodeInterface): Promise<void>;
rollback(interaction: GQLNodeInterface, forceStateStoreToCache: boolean): Promise<void>;
has(contractTxId: string, sortKey: string): boolean;

View File

@@ -86,11 +86,6 @@ export class CacheableStateEvaluator extends DefaultStateEvaluator {
);
}
// {
// contractTxId: this.contractDefinition.txId,
// interactionTxId: this.swGlobal.transaction.id
// }
async onStateEvaluated<State>(
transaction: GQLNodeInterface,
executionContext: ExecutionContext<State>,

View File

@@ -14,7 +14,6 @@ import { TagsParser } from './TagsParser';
import { VrfPluginFunctions } from '../../WarpPlugin';
import { BasicSortKeyCache } from '../../../cache/BasicSortKeyCache';
import { KnownErrors } from './handler/JsHandlerApi';
import { genesisSortKey } from "./LexicographicalInteractionsSorter";
type EvaluationProgressInput = {
contractTxId: string;
@@ -91,17 +90,12 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
break;
}
const missingInteraction = missingInteractions[i];
currentSortKey = missingInteraction.sortKey;
contract
.interactionState()
.setInitial(
contract.txId(),
new EvalStateResult(currentState, validity, errorMessages),
lastConfirmedTxState?.tx?.sortKey || executionContext.cachedState?.sortKey || genesisSortKey
);
const missingInteraction = missingInteractions[i];
.setInitial(contract.txId(), new EvalStateResult(currentState, validity, errorMessages), currentSortKey);
const singleInteractionBenchmark = Benchmark.measure();
currentSortKey = missingInteraction.sortKey;
if (missingInteraction.vrf) {
if (!vrfPlugin) {
@@ -311,27 +305,27 @@ export abstract class DefaultStateEvaluator implements StateEvaluator {
}
}
const forceStateStoreToCache =
executionContext.evaluationOptions.cacheEveryNInteractions > 0 &&
i % executionContext.evaluationOptions.cacheEveryNInteractions === 0;
// if that's the end of the root contract's interaction - commit all the uncommitted states to cache.
if (contract.isRoot()) {
contract.clearChildren();
// update the uncommitted state of the root contract
if (lastConfirmedTxState) {
contract.interactionState().update(contract.txId(), lastConfirmedTxState.state, lastConfirmedTxState.tx.sortKey);
contract
.interactionState()
.update(contract.txId(), lastConfirmedTxState.state, lastConfirmedTxState.tx.sortKey);
if (validity[missingInteraction.id]) {
let forceStateStoreToCache = false;
if (executionContext.evaluationOptions.cacheEveryNInteractions > 0) {
forceStateStoreToCache = i % executionContext.evaluationOptions.cacheEveryNInteractions === 0;
}
await contract.interactionState().commit(missingInteraction, forceStateStoreToCache);
} else {
await contract.interactionState().rollback(missingInteraction);
await contract.interactionState().rollback(missingInteraction, forceStateStoreToCache);
}
}
} else {
// if that's an inner contract call - only update the state in the uncommitted states
contract
.interactionState()
.update(contract.txId(), new EvalStateResult(currentState, validity, errorMessages), currentSortKey);
const interactionState = new EvalStateResult(currentState, validity, errorMessages);
contract.interactionState().update(contract.txId(), interactionState, currentSortKey);
}
}
const evalStateResult = new EvalStateResult<State>(currentState, validity, errorMessages);