forked from qtumproject/qtumx-benchmark-script
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bench.js
156 lines (130 loc) · 4.27 KB
/
bench.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* prepare enough UTXOs, then send them
*/
var readlineSync = require('readline-sync');
const { QtumRPC } = require('qtumjs')
const sleep = require('sleep');
/**
* get change addresses for UTXO split
*/
async function getAddressList(rpc, splitNum) {
let addrList = []
for (let i = 0; i != splitNum; i++) {
let changeAddr = await rpc.rawCall('getrawchangeaddress')
addrList.push(changeAddr)
}
return addrList
}
async function createTransaction(rpc, utxo, gas, isSplit, splitNum, addrList) {
let left = Math.floor(utxo.amount - gas, 2)
let change = 0
if (isSplit) {
change = Math.floor(left / splitNum, 2)
left = left - change * (splitNum - 1)
}
let data = [
[{ 'txid': utxo.txid, 'vout': utxo.vout }],
{ [addrList[0]]: left }
]
if (isSplit) {
for (let i = 1; i != splitNum; i++) {
let changeAddr = addrList[i]
data[1][changeAddr] = change
}
}
// console.log(data)
return await rpc.rawCall('createrawtransaction', data)
}
async function getUtxoList(rpc) {
let utxoList = await rpc.rawCall('listunspent')
utxoList = utxoList.filter(function (utxo) { // make sure UTXO has enough money
return utxo.amount > 10
})
console.log('valid UTXO number: ' + utxoList.length)
return utxoList
}
/**
* wait all txs in mempool to be packed into block
*/
async function waitMempool(rpc) {
while (true) {
sleep.sleep(1)
let mempoolInfo = await rpc.rawCall('getmempoolinfo')
console.log('transaction number left in mempool: ' + mempoolInfo.size)
if (mempoolInfo.size == 0) {
break
}
}
}
/**
* prepare UTXOs
*/
async function prepare(rpc, num, splitNum, gas, addrList) {
console.log('start prepare')
while (true) {
let utxoList = await getUtxoList(rpc)
if (utxoList.length >= num) { // enough UTXOs, finish prepare
break
}
// split every UTXO into splitNum UTXOs
let utxoNum = utxoList.length
for (let i = 0; i != utxoList.length; i++) {
let rawTransaction = await createTransaction(rpc, utxoList[i], gas, true, splitNum, addrList)
rawTransaction = await rpc.rawCall('signrawtransaction', [rawTransaction])
rpc.rawCall('sendrawtransaction', [rawTransaction.hex])
utxoNum = utxoNum + (splitNum - 1)
if (utxoNum >= num) {
break
}
}
console.log('generated UTXO number: ' + (utxoNum - utxoList.length))
await waitMempool(rpc)
}
console.log('finish prepare')
}
/**
* prepare UTXOs
*/
async function send(rpc, num, gas, addrList) {
console.log('start benchmark')
while (true) {
let utxoList = await getUtxoList(rpc)
if (utxoList.length < num) { // not enough UTXOs
console.log('not enough UTXOs')
break
}
// prepare signed txs
let rawTransactionList = []
for (let i = 0; i != utxoList.length; i++) {
let rawTransaction = await createTransaction(rpc, utxoList[i], gas, false, 0, addrList)
rawTransaction = await rpc.rawCall('signrawtransaction', [rawTransaction])
rawTransactionList.push(rawTransaction.hex)
}
console.log('prepared transaction number: ' + rawTransactionList.length)
readlineSync.question('Send? ');
// send txs
let callList = []
for (let i = 0; i != rawTransactionList.length; i++) {
callList.push(rpc.rawCall('sendrawtransaction', [rawTransactionList[i], false, false])) // use a modified sendrawtransaction API
if (callList.length == 50) { // threads of rpc
await Promise.all(callList)
callList = []
}
}
await waitMempool(rpc)
}
console.log('finish benchmark')
}
/**
* rpcurl
* number of UTXO to prepare
* how many UTXOs to split one UTXO into
* gas per transaction
*/
async function run(url, num, splitNum, gas) {
const rpc = new QtumRPC(url)
let addrList = await getAddressList(rpc, splitNum)
await prepare(rpc, num, splitNum, gas, addrList)
await send(rpc, num, gas, addrList)
}
run('http://test:test@127.0.0.1:12581', 8096, 2, 0.1).then()