1 | var fs = require("fs");
|
2 | var async = require("async");
|
3 | var request = require("request");
|
4 | var accountHelper = require("../helpers/account.js");
|
5 | var blockHelper = require("../helpers/block.js");
|
6 | var cryptoLib = require("../lib/crypto.js");
|
7 | var dappHelper = require("../helpers/dapp.js");
|
8 | var Api = require('../helpers/api.js');
|
9 | var AschUtils = require('asch-js').utils;
|
10 |
|
11 | var globalOptions;
|
12 |
|
13 | function getApi() {
|
14 | return new Api({host: globalOptions.host, port: globalOptions.port, mainnet: !!globalOptions.main});
|
15 | }
|
16 |
|
17 | function writeFileSync(file, obj) {
|
18 | var content = (typeof obj === "string" ? obj : JSON.stringify(obj, null, 2));
|
19 | fs.writeFileSync(file, content, "utf8");
|
20 | }
|
21 |
|
22 | function appendFileSync(file, obj) {
|
23 | var content = (typeof obj === "string" ? obj : JSON.stringify(obj, null, 2));
|
24 | fs.appendFileSync(file, content, "utf8");
|
25 | }
|
26 |
|
27 | function genGenesisBlock(options) {
|
28 | var genesisAccount = accountHelper.account(cryptoLib.generateSecret());
|
29 | var newBlockInfo = blockHelper.new(genesisAccount, null, options.file);
|
30 | var delegateSecrets = newBlockInfo.delegates.map(function(i) {
|
31 | return i.secret;
|
32 | });
|
33 | writeFileSync("./genesisBlock.json", newBlockInfo.block);
|
34 |
|
35 | var logFile = "./genGenesisBlock.log";
|
36 | writeFileSync(logFile, "genesis account:\n");
|
37 | appendFileSync(logFile, genesisAccount);
|
38 | appendFileSync(logFile, "\ndelegates secrets:\n");
|
39 | appendFileSync(logFile, delegateSecrets);
|
40 | }
|
41 |
|
42 | function peerstat() {
|
43 | var api = getApi();
|
44 | api.get('/api/peers/', {}, function (err, result) {
|
45 | if (err) {
|
46 | console.log('Failed to get peers', err);
|
47 | return;
|
48 | }
|
49 | async.map(result.peers, function (peer, next) {
|
50 | getApi().get('/api/blocks/getHeight', function (err, result) {
|
51 | if (err) {
|
52 | console.log('%s:%d %s %d', peer.ip, peer.port, peer.version, err);
|
53 | next(null, {peer: peer, error: err});
|
54 | } else {
|
55 | console.log('%s:%d %s %d', peer.ip, peer.port, peer.version, result.height);
|
56 | next(null, {peer: peer, height: result.height});
|
57 | }
|
58 | });
|
59 | }, function (err, results) {
|
60 | var heightMap = {};
|
61 | var errorMap = {};
|
62 | for (var i = 0; i < results.length; ++i) {
|
63 | var item = results[i];
|
64 | if (item.error) {
|
65 | if (!errorMap[item.error]) {
|
66 | errorMap[item.error] = [];
|
67 | }
|
68 | errorMap[item.error].push(item.peer);
|
69 | } else {
|
70 | if (!heightMap[item.height]) {
|
71 | heightMap[item.height] = [];
|
72 | }
|
73 | heightMap[item.height].push(item.peer);
|
74 | }
|
75 | }
|
76 | var normalList = [];
|
77 | var errList = [];
|
78 | for (var k in heightMap) {
|
79 | normalList.push({peers: heightMap[k], height: k});
|
80 | }
|
81 | for (var k in errorMap) {
|
82 | errList.push({peers: errorMap[k], error: k});
|
83 | }
|
84 | normalList.sort(function (l, r) {
|
85 | return r.height - l.height;
|
86 | });
|
87 |
|
88 | function joinPeerAddrs(peers) {
|
89 | var peerAddrs = [];
|
90 | peers.forEach(function (p) {
|
91 | peerAddrs.push(p.ip + ':' + p.port);
|
92 | });
|
93 | return peerAddrs.join(',');
|
94 | }
|
95 | console.log('======================================');
|
96 | for (var i = 0; i < normalList.length; ++i) {
|
97 | var item = normalList[i];
|
98 | if (i == 0) {
|
99 | console.log(item.peers.length + ' height: ' + item.height);
|
100 | } else {
|
101 | console.log(item.peers.length + ' height: ' + item.height, joinPeerAddrs(item.peers));
|
102 | }
|
103 | }
|
104 | for (var i = 0; i < errList.length; ++i) {
|
105 | var item = errList[i];
|
106 | console.log(item.peers.length + ' error: ' + item.error, joinPeerAddrs(item.peers));
|
107 | }
|
108 | });
|
109 | });
|
110 | }
|
111 |
|
112 | function delegatestat() {
|
113 | var api = getApi();
|
114 | api.get('/api/delegates', {}, function (err, result) {
|
115 | if (err) {
|
116 | console.log('Failed to get delegates', err);
|
117 | return;
|
118 | }
|
119 | async.map(result.delegates, function (delegate, next) {
|
120 | var params = {
|
121 | generatorPublicKey: delegate.publicKey,
|
122 | limit: 1,
|
123 | offset: 0,
|
124 | orderBy: 'height:desc'
|
125 | };
|
126 | api.get('/api/blocks', params, function (err, result) {
|
127 | if (err) {
|
128 | next(err);
|
129 | } else {
|
130 | next(null, {delegate: delegate, block: result.blocks[0]});
|
131 | }
|
132 | });
|
133 | }, function (err, delegates) {
|
134 | if (err) {
|
135 | console.log('Failed to get forged block', err);
|
136 | return;
|
137 | }
|
138 | delegates = delegates.sort(function (l, r) {
|
139 | if (!l.block) {
|
140 | return -1;
|
141 | }
|
142 | if (!r.block) {
|
143 | return 1;
|
144 | }
|
145 | return l.block.timestamp - r.block.timestamp;
|
146 | });
|
147 | console.log("name\taddress\trate\tapproval\tproductivity\tproduced\tbalance\theight\tid\ttime");
|
148 | for (var i in delegates) {
|
149 | var d = delegates[i].delegate;
|
150 | var b = delegates[i].block;
|
151 | console.log('%s\t%s\t%d\t%s%%\t%s%%\t%d\t%d\t%s\t%s\t%s(%s)',
|
152 | d.username,
|
153 | d.address,
|
154 | d.rate,
|
155 | d.approval,
|
156 | d.productivity,
|
157 | d.producedblocks,
|
158 | d.balance / 100000000,
|
159 | b ? b.height : '',
|
160 | b ? b.id : '',
|
161 | AschUtils.format.fullTimestamp(b ? b.timestamp : ''),
|
162 | AschUtils.format.timeAgo(b ? b.timestamp : ''));
|
163 | }
|
164 | });
|
165 | });
|
166 | }
|
167 |
|
168 | function ipstat() {
|
169 | var api = getApi();
|
170 | api.get('/api/peers/', {}, function (err, result) {
|
171 | if (err) {
|
172 | console.log('Failed to get peers', err);
|
173 | return;
|
174 | }
|
175 | async.mapLimit(result.peers, 5, function (peer, next) {
|
176 | var url = 'http://ip.taobao.com/service/getIpInfo.php?ip=' + peer.ip;
|
177 | request(url, function (err, resp, body) {
|
178 | if (err || resp.statusCode != 200) {
|
179 | console.error('Failed to get ip info:', err);
|
180 | next(null, {});
|
181 | } else {
|
182 | next(null, JSON.parse(body).data);
|
183 | }
|
184 | });
|
185 | }, function (err, ips) {
|
186 | for (var i = 0; i < ips.length; ++i) {
|
187 | var ip = ips[i];
|
188 | if (ip.country_id) {
|
189 | console.log('%s\t%s', ip.country, ip.country_id);
|
190 | }
|
191 | }
|
192 | });
|
193 | });
|
194 | }
|
195 |
|
196 | module.exports = function(program) {
|
197 | globalOptions = program;
|
198 |
|
199 | program
|
200 | .command("creategenesis")
|
201 | .description("create genesis block")
|
202 | .option("-f, --file <file>", "genesis accounts balance file")
|
203 | .action(genGenesisBlock);
|
204 |
|
205 | program
|
206 | .command("peerstat")
|
207 | .description("analyze block height of all peers")
|
208 | .action(peerstat);
|
209 |
|
210 | program
|
211 | .command("delegatestat")
|
212 | .description("analyze delegates status")
|
213 | .action(delegatestat);
|
214 |
|
215 | program
|
216 | .command("ipstat")
|
217 | .description("analyze peer ip info")
|
218 | .action(ipstat);
|
219 | } |
\ | No newline at end of file |