2023-01-19 06:38:42 -08:00
|
|
|
import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, TransactionSignature, Transaction } from '@solana/web3.js';
|
|
|
|
import * as fs from 'fs';
|
|
|
|
import * as splToken from "@solana/spl-token";
|
|
|
|
import * as os from 'os';
|
|
|
|
|
|
|
|
// number of users
|
|
|
|
const tps: number = +process.argv[2];
|
|
|
|
const forSeconds: number = +process.argv[3];
|
|
|
|
// url
|
|
|
|
const url = process.argv.length > 4 ? process.argv[4] : "http://localhost:8899";
|
|
|
|
const skip_confirmations = process.argv.length > 5 ? process.argv[5] === "true" : false;
|
|
|
|
|
2023-03-29 14:01:15 -07:00
|
|
|
(async function main() {
|
|
|
|
//@ts-ignore
|
|
|
|
const InFile: {
|
|
|
|
fee_payers: [Keypair],
|
|
|
|
users: [{
|
|
|
|
publicKey: string;
|
|
|
|
secretKey: Uint8Array;
|
|
|
|
}];
|
|
|
|
tokenAccounts: [PublicKey];
|
|
|
|
mint: PublicKey;
|
|
|
|
minted_amount: number;
|
|
|
|
} = fs.readFileSync('out.json').toJSON();
|
2023-01-19 06:38:42 -08:00
|
|
|
|
2023-03-29 14:01:15 -07:00
|
|
|
console.log("benching " + tps + " transactions per second on " + url + " for " + forSeconds + " seconds");
|
2023-01-19 06:38:42 -08:00
|
|
|
|
2023-02-06 07:15:26 -08:00
|
|
|
const connection = new Connection(url, 'finalized');
|
|
|
|
console.log('get latest blockhash')
|
|
|
|
const blockhash = await connection.getLatestBlockhash({
|
|
|
|
commitment: 'finalized'
|
|
|
|
});
|
|
|
|
console.log('blockhash : ' + blockhash.blockhash);
|
2023-01-19 06:38:42 -08:00
|
|
|
const authority = Keypair.fromSecretKey(
|
|
|
|
Uint8Array.from(
|
|
|
|
JSON.parse(
|
|
|
|
process.env.KEYPAIR ||
|
|
|
|
fs.readFileSync(os.homedir() + '/.config/solana/id.json', 'utf-8'),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
|
|
|
|
const users = InFile.users.map(x => Keypair.fromSecretKey(Uint8Array.from(x.secretKey)));
|
|
|
|
const userAccounts = InFile.tokenAccounts.map(x => new PublicKey(x));
|
2023-02-06 07:15:26 -08:00
|
|
|
let signatures_to_unpack: TransactionSignature[][] = new Array<TransactionSignature[]>(forSeconds);
|
2023-01-19 06:38:42 -08:00
|
|
|
let time_taken_to_send = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < forSeconds; ++i) {
|
2023-02-06 07:15:26 -08:00
|
|
|
console.log('Sending transaction ' + i);
|
2023-01-19 06:38:42 -08:00
|
|
|
const start = performance.now();
|
2023-02-06 07:15:26 -08:00
|
|
|
signatures_to_unpack[i] = new Array<TransactionSignature>(tps);
|
|
|
|
let blockhash = (await connection.getLatestBlockhash()).blockhash;
|
2023-01-19 06:38:42 -08:00
|
|
|
for (let j = 0; j < tps; ++j) {
|
2023-03-29 14:01:15 -07:00
|
|
|
if (j % 100 == 0) {
|
2023-02-06 07:15:26 -08:00
|
|
|
blockhash = (await connection.getLatestBlockhash()).blockhash;
|
|
|
|
}
|
2023-01-19 06:38:42 -08:00
|
|
|
const toIndex = Math.floor(Math.random() * users.length);
|
|
|
|
let fromIndex = toIndex;
|
|
|
|
while (fromIndex === toIndex) {
|
|
|
|
fromIndex = Math.floor(Math.random() * users.length);
|
|
|
|
}
|
|
|
|
const userFrom = userAccounts[fromIndex];
|
|
|
|
const userTo = userAccounts[toIndex];
|
2023-02-06 07:15:26 -08:00
|
|
|
|
|
|
|
const transaction = new Transaction().add(
|
2023-03-29 14:01:15 -07:00
|
|
|
splToken.createTransferInstruction(userFrom, userTo, users[fromIndex].publicKey, Math.ceil((Math.random() + 1) * 100))
|
2023-02-06 07:15:26 -08:00
|
|
|
);
|
|
|
|
transaction.recentBlockhash = blockhash;
|
|
|
|
transaction.feePayer = authority.publicKey;
|
|
|
|
|
2023-03-29 14:01:15 -07:00
|
|
|
connection.sendTransaction(transaction, [authority, users[fromIndex]], { skipPreflight: true }).then(p => { signatures_to_unpack[i][j] = p });
|
2023-01-19 06:38:42 -08:00
|
|
|
}
|
|
|
|
const end = performance.now();
|
|
|
|
const diff = (end - start);
|
|
|
|
time_taken_to_send[i] = diff;
|
|
|
|
if (diff > 0 && diff < 1000) {
|
|
|
|
await sleep(1000 - diff)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('finish sending transactions');
|
2023-02-06 07:15:26 -08:00
|
|
|
await delay(10000)
|
2023-01-19 06:38:42 -08:00
|
|
|
console.log('checking for confirmations');
|
|
|
|
if (skip_confirmations === false) {
|
|
|
|
const size = signatures_to_unpack.length
|
|
|
|
let successes: Uint32Array = new Uint32Array(size).fill(0);
|
|
|
|
let failures: Uint32Array = new Uint32Array(size).fill(0);
|
|
|
|
for (let i = 0; i < size; ++i) {
|
|
|
|
const signatures = signatures_to_unpack[i];
|
|
|
|
for (const signature of signatures) {
|
|
|
|
const confirmed = await connection.getSignatureStatus(signature);
|
|
|
|
if (confirmed != null && confirmed.value != null && confirmed.value.err == null) {
|
|
|
|
successes[i]++;
|
|
|
|
} else {
|
|
|
|
failures[i]++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
console.log("sucesses : " + successes)
|
|
|
|
console.log("failures : " + failures)
|
|
|
|
//console.log("time taken to send : " + time_taken_to_send)
|
|
|
|
}
|
2023-03-29 14:01:15 -07:00
|
|
|
})()
|