"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = __importDefault(require("assert"));
const _1 = require(".");
const MAX_TRANSFERS = 51200;
const MAX_REQUEST_BATCH_SIZE = 253;
const IS_TWO_PHASE_TRANSFER = false;
const client = (0, _1.createClient)({
    cluster_id: 0n,
    replica_addresses: [process.env.TB_ADDRESS || '3000']
});
const TRANSFER_SIZE = 128;
const accountA = {
    id: 137n,
    debits_pending: 0n,
    debits_posted: 0n,
    credits_pending: 0n,
    credits_posted: 0n,
    user_data_128: 0n,
    user_data_64: 0n,
    user_data_32: 0,
    reserved: 0,
    ledger: 1,
    code: 1,
    flags: 0,
    timestamp: 0n,
};
const accountB = {
    id: 138n,
    debits_pending: 0n,
    debits_posted: 0n,
    credits_pending: 0n,
    credits_posted: 0n,
    user_data_128: 0n,
    user_data_64: 0n,
    user_data_32: 0,
    reserved: 0,
    ledger: 1,
    code: 1,
    flags: 0,
    timestamp: 0n,
};
const runBenchmark = async () => {
    console.log(`pre-allocating ${MAX_TRANSFERS} transfers and posts...`);
    const transfers = [];
    const posts = [];
    let count = 0;
    while (count < MAX_TRANSFERS) {
        const pendingBatch = [];
        const postBatch = [];
        for (let i = 0; i < MAX_REQUEST_BATCH_SIZE; i++) {
            if (count === MAX_TRANSFERS)
                break;
            count += 1;
            pendingBatch.push({
                id: BigInt(count),
                debit_account_id: accountA.id,
                credit_account_id: accountB.id,
                amount: 1n,
                pending_id: 0n,
                user_data_128: 0n,
                user_data_64: 0n,
                user_data_32: 0,
                timeout: IS_TWO_PHASE_TRANSFER ? 2 : 0,
                code: 1,
                ledger: 1,
                flags: IS_TWO_PHASE_TRANSFER ? _1.TransferFlags.pending : 0,
                timestamp: 0n,
            });
            if (IS_TWO_PHASE_TRANSFER) {
                postBatch.push({
                    id: BigInt(MAX_TRANSFERS + count),
                    debit_account_id: accountA.id,
                    credit_account_id: accountB.id,
                    amount: 1n,
                    pending_id: BigInt(count),
                    user_data_128: 0n,
                    user_data_64: 0n,
                    user_data_32: 0,
                    timeout: 0,
                    code: 1,
                    ledger: 1,
                    flags: IS_TWO_PHASE_TRANSFER ? _1.TransferFlags.post_pending_transfer : 0,
                    timestamp: 0n,
                });
            }
        }
        transfers.push(pendingBatch);
        if (IS_TWO_PHASE_TRANSFER)
            posts.push(postBatch);
    }
    (0, assert_1.default)(count === MAX_TRANSFERS);
    console.log(`starting benchmark. MAX_TRANSFERS=${MAX_TRANSFERS} REQUEST_BATCH_SIZE=${MAX_REQUEST_BATCH_SIZE} NUMBER_OF_BATCHES=${transfers.length}`);
    let maxCreateTransfersLatency = 0;
    let maxCommitTransfersLatency = 0;
    const start = Date.now();
    for (let i = 0; i < transfers.length; i++) {
        const ms1 = Date.now();
        const transferResults = await client.createTransfers(transfers[i]);
        (0, assert_1.default)(transferResults.length === transfers[i].length);
        const ms2 = Date.now();
        const createTransferLatency = ms2 - ms1;
        if (createTransferLatency > maxCreateTransfersLatency) {
            maxCreateTransfersLatency = createTransferLatency;
        }
        if (IS_TWO_PHASE_TRANSFER) {
            const postTransferResults = await client.createTransfers(posts[i]);
            (0, assert_1.default)(postTransferResults.length === posts[i].length);
            const ms3 = Date.now();
            const commitTransferLatency = ms3 - ms2;
            if (commitTransferLatency > maxCommitTransfersLatency) {
                maxCommitTransfersLatency = commitTransferLatency;
            }
        }
    }
    const ms = Date.now() - start;
    return {
        ms,
        maxCommitTransfersLatency,
        maxCreateTransfersLatency
    };
};
const main = async () => {
    console.log("creating the accounts...");
    await client.createAccounts([accountA, accountB]);
    const accountResults = await client.lookupAccounts([accountA.id, accountB.id]);
    (0, assert_1.default)(accountResults.length === 2);
    (0, assert_1.default)(accountResults[0].debits_posted === 0n);
    (0, assert_1.default)(accountResults[1].debits_posted === 0n);
    const benchmark = await runBenchmark();
    const accounts = await client.lookupAccounts([accountA.id, accountB.id]);
    const result = Math.floor((1000 * MAX_TRANSFERS) / benchmark.ms);
    console.log("=============================");
    console.log(`${IS_TWO_PHASE_TRANSFER ? 'two-phase ' : ''}transfers per second: ${result}`);
    console.log(`create transfers max p100 latency per 10 000 transfers = ${benchmark.maxCreateTransfersLatency}ms`);
    console.log(`commit transfers max p100 latency per 10 000 transfers = ${benchmark.maxCommitTransfersLatency}ms`);
    (0, assert_1.default)(accounts.length === 2);
    (0, assert_1.default)(accounts[0].debits_posted === BigInt(MAX_TRANSFERS));
    (0, assert_1.default)(accounts[1].credits_posted === BigInt(MAX_TRANSFERS));
};
main().catch(error => {
    console.log(error);
}).finally(async () => {
    await client.destroy();
});
//# sourceMappingURL=benchmark.js.map