Skip to content

Commit 246ee9a

Browse files
committed
Add a script measuring tps by transaction propagation
1 parent d7d7470 commit 246ee9a

File tree

1 file changed

+219
-0
lines changed

1 file changed

+219
-0
lines changed
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
// Copyright 2018-2019 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
import { SignedTransaction } from "codechain-sdk/lib/core/classes";
18+
import { existsSync, readFileSync, writeFileSync } from "fs";
19+
import {
20+
faucetAddress,
21+
faucetSecret,
22+
validator0Address,
23+
validator0Secret,
24+
validator1Address,
25+
validator1Secret,
26+
validator2Address,
27+
validator2Secret,
28+
validator3Address,
29+
validator3Secret
30+
} from "../helper/constants";
31+
import { wait } from "../helper/promise";
32+
import { makeRandomH256 } from "../helper/random";
33+
import CodeChain from "../helper/spawn";
34+
35+
(async () => {
36+
let nodes: CodeChain[];
37+
38+
const validatorAddresses = [
39+
validator0Address,
40+
validator1Address,
41+
validator2Address,
42+
validator3Address
43+
];
44+
nodes = validatorAddresses.map(address => {
45+
return new CodeChain({
46+
chain: `${__dirname}/../scheme/tendermint-tps.json`,
47+
argv: [
48+
"--engine-signer",
49+
address.toString(),
50+
"--password-path",
51+
"test/tendermint/password.json",
52+
"--force-sealing",
53+
"--no-discovery",
54+
"--enable-devel-api"
55+
],
56+
additionalKeysPath: "tendermint/keys"
57+
});
58+
});
59+
const nonValNode = new CodeChain({
60+
chain: `${__dirname}/../scheme/tendermint-tps.json`,
61+
argv: [
62+
"--no-miner",
63+
]
64+
});
65+
await Promise.all([...nodes, nonValNode].map(node => node.start()));
66+
67+
await Promise.all([
68+
nodes[0].connect(nodes[1]),
69+
nodes[0].connect(nodes[2]),
70+
nodes[0].connect(nodes[3]),
71+
nodes[1].connect(nodes[2]),
72+
nodes[1].connect(nodes[3]),
73+
nodes[2].connect(nodes[3]),
74+
nonValNode.connect(nodes[3]),
75+
]);
76+
await Promise.all([
77+
nodes[0].waitPeers(4 - 1),
78+
nodes[1].waitPeers(4 - 1),
79+
nodes[2].waitPeers(4 - 1),
80+
nodes[3].waitPeers(4),
81+
nonValNode.waitPeers(1),
82+
]);
83+
84+
const secrets = [
85+
validator0Secret,
86+
validator1Secret,
87+
validator2Secret,
88+
validator3Secret
89+
];
90+
const transactions: string[][] = [[], [], [], []];
91+
const numTransactions = 20000;
92+
93+
if (existsSync("./txcache.json")) {
94+
const buf = readFileSync("./txcache.json", "utf8");
95+
const txRaw: string[][] = JSON.parse(buf);
96+
for (let k = 0; k < 4; k++) {
97+
for (let i = 0; i < numTransactions; i++) {
98+
if (i % 1000 === 0) {
99+
console.log(`${i}`);
100+
}
101+
transactions[k].push(txRaw[k][i]);
102+
}
103+
}
104+
} else {
105+
for (let k = 0; k < 4; k++) {
106+
const value = makeRandomH256();
107+
const baseSeq = await nodes[k].sdk.rpc.chain.getSeq(
108+
validatorAddresses[k]
109+
);
110+
const accountId = nodes[k].sdk.util.getAccountIdFromPrivate(value);
111+
const recipient = nodes[
112+
k
113+
].sdk.core.classes.PlatformAddress.fromAccountId(accountId, {
114+
networkId: "tc"
115+
});
116+
for (let i = 0; i < numTransactions; i++) {
117+
if (i % 1000 === 0) {
118+
console.log(`${i}`);
119+
}
120+
const transaction = nodes[k].sdk.core
121+
.createPayTransaction({
122+
recipient,
123+
quantity: 1
124+
})
125+
.sign({
126+
secret: secrets[k],
127+
seq: baseSeq + i,
128+
fee: 10
129+
});
130+
transactions[k].push(transaction.rlpBytes().toString("hex"));
131+
}
132+
}
133+
writeFileSync("./txcache.json", JSON.stringify(transactions));
134+
}
135+
136+
console.log("Txes prepared");
137+
138+
for (let k = 0; k < 4; k++) {
139+
140+
let i = numTransactions - 1;
141+
while(i > 0) {
142+
console.log(`${i}`);
143+
const txes = [];
144+
for (let j = 0; j < 2000; j++) {
145+
txes.push( "0x" + transactions[k][i]);
146+
i--;
147+
if (i ===0) {
148+
break;
149+
}
150+
}
151+
await nonValNode.sdk.rpc.sendRpcRequest("mempool_sendSignedTransactions", [
152+
txes
153+
]);
154+
}
155+
}
156+
157+
const startTime = new Date();
158+
console.log(`Start at: ${startTime}`);
159+
160+
for (let k = 0; k < 4; k++) {
161+
await nonValNode.sdk.rpc.sendRpcRequest("mempool_sendSignedTransaction", [
162+
"0x" + transactions[k][0]
163+
]);
164+
}
165+
166+
const bnStart = await nodes[0].sdk.rpc.chain.getBestBlockNumber();
167+
console.log(`BLOCK_START: ${bnStart}`);
168+
169+
let lastNum = 0;
170+
let consumed = 0;
171+
172+
while (true) {
173+
const num = await nodes[0].sdk.rpc.chain.getBestBlockNumber();
174+
if (lastNum !== num) {
175+
lastNum = num;
176+
console.log("---------------------");
177+
console.log(`Block ${lastNum}`);
178+
const block = await nodes[0].sdk.rpc.chain.getBlock(lastNum);
179+
const txnum = block!.transactions.length!;
180+
consumed += txnum;
181+
console.log(`Txs: ${txnum}`);
182+
183+
for (let i = 0; i < 4; i++) {
184+
const currentfutureTxnum = await nodes[
185+
i
186+
].sdk.rpc.sendRpcRequest("mempool_getCurrentFuturueCount", [
187+
null,
188+
null
189+
]);
190+
console.log(`Txs in ${i}: $${currentfutureTxnum}`);
191+
}
192+
193+
if (consumed === numTransactions * 4) {
194+
break;
195+
}
196+
}
197+
await wait(100);
198+
}
199+
const endTime = new Date();
200+
console.log(`End at: ${endTime}`);
201+
const tps =
202+
(numTransactions * 1000.0 * 4) /
203+
(endTime.getTime() - startTime.getTime());
204+
console.log(
205+
`Elapsed time (ms): ${endTime.getTime() - startTime.getTime()}`
206+
);
207+
208+
const bnEnd = await nodes[0].sdk.rpc.chain.getBestBlockNumber();
209+
console.log(`BLOCK: ${bnEnd}`);
210+
211+
for (let i = 0; i <= bnEnd; i++) {
212+
const block = await nodes[0].sdk.rpc.chain.getBlock(i);
213+
console.log(`BLOCK${i} : ${block!.transactions.length}`);
214+
}
215+
216+
console.log(`TPS: ${tps}`);
217+
218+
await Promise.all([...nodes, nonValNode].map(node => node.clean()));
219+
})().catch(console.error);

0 commit comments

Comments
 (0)