Skip to content

Commit

Permalink
Simulation: Lift log limits option in SimulateRequest (#768)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahangsu authored Apr 28, 2023
1 parent e5abc27 commit 88aa843
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/client/v2/algod/simulateTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default class SimulateRawTransactions extends JSONRequest<
constructor(c: HTTPClient, request: SimulateRequest) {
super(c);
this.query.format = 'msgpack';
this.requestBytes = encoding.encode(request.get_obj_for_encoding(true));
this.requestBytes = encoding.rawEncode(request.get_obj_for_encoding(true));
}

// eslint-disable-next-line class-methods-use-this
Expand Down
30 changes: 27 additions & 3 deletions src/composer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ import {
ABIValue,
} from './abi';
import Algodv2 from './client/v2/algod/algod';
import { SimulateResponse } from './client/v2/algod/models/types';
import {
SimulateResponse,
SimulateRequest,
SimulateRequestTransactionGroup,
} from './client/v2/algod/models/types';
import { EncodedSignedTransaction } from './types';
import { assignGroupID } from './group';
import { makeApplicationCallTxnFromObject } from './makeTxn';
import {
Expand All @@ -27,6 +32,7 @@ import {
SuggestedParams,
} from './types/transactions/base';
import { waitForConfirmation } from './wait';
import * as encoding from './encoding/encoding';

// First 4 bytes of SHA-512/256 hash of "return"
const RETURN_PREFIX = Buffer.from([21, 31, 124, 117]);
Expand Down Expand Up @@ -609,13 +615,17 @@ export class AtomicTransactionComposer {
* Simulating the group will not change the composer's status.
*
* @param client - An Algodv2 client
* @param request - SimulateRequest with options in simulation.
* If provided, the request's transaction group will be overrwritten by the composer's group,
* only simulation related options will be used.
*
* @returns A promise that, upon success, resolves to an object containing an
* array of results containing one element for each method call transaction
* in this group (ABIResult[]) and the SimulateResponse object.
*/
async simulate(
client: Algodv2
client: Algodv2,
request?: SimulateRequest
): Promise<{
methodResults: ABIResult[];
simulateResponse: SimulateResponse;
Expand All @@ -627,8 +637,22 @@ export class AtomicTransactionComposer {
}

const stxns = await this.gatherSignatures();
const txnObjects: EncodedSignedTransaction[] = stxns.map(
(stxn) => encoding.decode(stxn) as EncodedSignedTransaction
);

const currentRequest: SimulateRequest =
request == null ? new SimulateRequest({ txnGroups: [] }) : request;

currentRequest.txnGroups = [
new SimulateRequestTransactionGroup({
txns: txnObjects,
}),
];

const simulateResponse = await client.simulateRawTransactions(stxns).do();
const simulateResponse = await client
.simulateTransactions(currentRequest)
.do();

// Parse method response
const methodResults: ABIResult[] = [];
Expand Down
2 changes: 2 additions & 0 deletions tests/cucumber/integration.tags
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
@rekey_v1
@send
@send.keyregtxn
@simulate
@simulate.lift_log_limits
43 changes: 40 additions & 3 deletions tests/cucumber/steps/steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -4666,7 +4666,9 @@ module.exports = function getSteps(options) {
Then(
'the simulation should succeed without any failure message',
async function () {
assert.deepStrictEqual(true, this.simulateResponse.wouldSucceed);
for (const txnGroup of this.simulateResponse.txnGroups) {
assert.deepStrictEqual(undefined, txnGroup.failedMessage);
}
}
);

Expand All @@ -4678,7 +4680,6 @@ module.exports = function getSteps(options) {
const txnIndexes = stringPath.map((n) => parseInt(n, 10));
const groupNum = parseInt(txnGroupIndex, 10);

assert.deepStrictEqual(false, this.simulateResponse.wouldSucceed);
// Check for missing signature flag
for (const txnIndex of txnIndexes) {
assert.deepStrictEqual(
Expand All @@ -4702,7 +4703,6 @@ module.exports = function getSteps(options) {

const failedMessage = this.simulateResponse.txnGroups[groupNum]
.failureMessage;
assert.ok(!this.simulateResponse.wouldSucceed);
assert.ok(
failedMessage.includes(errorMsg),
`Error message: "${failedMessage}" does not contain "${errorMsg}"`
Expand All @@ -4714,6 +4714,43 @@ module.exports = function getSteps(options) {
}
);

When('I make a new simulate request.', async function () {
this.simulateRequest = new algosdk.modelsv2.SimulateRequest({
txnGroups: [],
});
});

Then('I allow more logs on that simulate request.', async function () {
this.simulateRequest.allowMoreLogging = true;
});

Then(
'I simulate the transaction group with the simulate request.',
async function () {
this.composerExecuteResponse = await this.composer.simulate(
this.v2Client,
this.simulateRequest
);
this.simulateResponse = this.composerExecuteResponse.simulateResponse;
this.methodResults = this.composerExecuteResponse.methodResults;
}
);

Then(
'I check the simulation result has power packs allow-more-logging.',
async function () {
assert.notDeepStrictEqual(undefined, this.simulateResponse.evalOverrides);
assert.notDeepStrictEqual(
undefined,
this.simulateResponse.evalOverrides.maxLogCalls
);
assert.notDeepStrictEqual(
undefined,
this.simulateResponse.evalOverrides.maxLogSize
);
}
);

When('we make a Ready call', async function () {
await this.v2Client.ready().do();
});
Expand Down

0 comments on commit 88aa843

Please sign in to comment.