This repository has been archived by the owner on Jul 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
rewards.js
executable file
·128 lines (101 loc) · 3.08 KB
/
rewards.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
#!/usr/bin/env node
/**
* Usage: ./rewards.js [input file] [output file]
* The input file must be passed in and must exist.
* The default value of the output file is logs.csv.
*
* MIT License
* Copyright (c) 2020, Mark Tyneway
* Copyright (c) 2020 Spacemesh
*/
'use strict';
const readline = require('readline');
const fs = require('fs');
const path = require('path');
const {once} = require('events');
let accounts = new Map();
if (typeof BigInt !== 'function')
throw new Error('Requires BigInt');
async function main() {
const args = process.argv.slice(2);
if (!args[0])
throw new Error('Must pass input log file name as first argument.');
const input = path.resolve(args[0]);
if (!fs.existsSync(input))
throw new Error(`Input log file ${input} not found.`);
let output = args[1] ? path.resolve(args[1]) : path.resolve('logs.csv');
const fileStream = fs.createReadStream(input);
const writer = fs.createWriteStream(output);
await write('account, rewards, amount, out_txs, in_txs\n');
const rl = await readline.createInterface({
input: fileStream
});
// set to false to parse local log text file (not server generated json)
const log_frmt_json = true;
rl.on('line', (line) => {
if (log_frmt_json) {
const logEntry = JSON.parse(line);
const data = logEntry._source.sm;
parseRewards(data);
parseTransactions(data);
} else {
parseRewards(line);
parseTransactions(line);
}
});
await once(rl, 'close');
for (const [key, value] of accounts.entries()) {
await write (`${key}, ${value.total}, ${value.amount.toString()}, ${value.out_txs}, ${value.in_txs}\n`);
}
async function write(data) {
return new Promise((resolve, reject) => {
writer.write(data, (err) => {
if (err)
return reject(err);
resolve();
});
});
}
}
function parseTransactions(data) {
if (data === undefined || data.M !== "transaction processed") {
return;
}
// ugly but the current tx data in the log is not valid json
const items = data.transaction.split(', ');
const origin = items[1].split(' ')[1];
const recipient = items[2].split(' ')[1];
if (accounts.has(origin)) {
let v = accounts.get(origin);
v.out_txs++;
accounts.set(origin, v);
} else {
accounts.set(origin, {total: 0, amount: BigInt(0), in_txs: 0, out_txs: 1});
}
if (accounts.has(recipient)) {
let v = accounts.get(recipient);
v.in_txs++;
accounts.set(recipient, v);
} else {
accounts.set(recipient, {total: 0, amount: BigInt(0), in_txs: 1, out_txs: 0});
}
}
function parseRewards(data) {
if (data == undefined || data.reward == null || data.account == null || data.account === '0x00000') {
return;
}
if (accounts.has(data.account)) {
let v = accounts.get(data.account);
v.total++;
v.amount = v.amount + BigInt(data.reward);
accounts.set (data.account, v);
} else {
accounts.set(data.account, {total: 0, amount: BigInt(data.reward), in_txs: 0, out_txs: 0});
}
}
(async () => {
await main();
})().catch(err => {
console.log(err);
process.exit(1);
});