-
Notifications
You must be signed in to change notification settings - Fork 4
/
explore.js
168 lines (151 loc) · 5.63 KB
/
explore.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
157
158
159
160
161
162
163
164
165
166
167
/* eslint-disable capitalized-comments */
/* eslint-disable camelcase */
/* eslint-disable no-await-in-loop */
'use strict';
const assert = require('assert');
const util = require('./lib/util.js');
const explore = {
bc: null,
db: null
};
function Crono() {
this.fStart = new Date();
this.delta = () => {
return new Date() - this.fStart;
};
}
function DeltaSigma(delta, sigma) {
this.delta = delta;
this.sigma = sigma;
this.update = delta => {
this.delta = delta;
this.sigma += delta;
};
this.increment = delta => {
this.delta += delta;
this.sigma += delta;
};
}
const profile = {
height: 0,
rpc: new DeltaSigma(0, 0), // ticks executing RPC call
db: {
query: new DeltaSigma(0, 0), // ticks executing query on db
commit: new DeltaSigma(0, 0), // ticks executing commit on db
vout: new DeltaSigma(0, 0), // ticks executing commit on vout
vin: new DeltaSigma(0, 0) // ticks executing commit on vin
},
tx: new DeltaSigma(0, 0), // number of transactions
profile: new DeltaSigma(0, 0),
change: 0,
'tx/s': null // new DeltaSigma(0, 0)
};
const handleTransaction = async (raw, block_ref) => {
assert(typeof raw !== 'undefined');
assert(typeof block_ref !== 'undefined');
const transaction = await explore.db.transaction.insert(raw.txid, block_ref);
// console.log (raw);
const voutCrono = new Crono();
for (let i = 0; i < raw.vout.length; ++i) {
// await raw.vout.forEach(async vout => {
const vout = raw.vout[i];
assert(typeof vout !== 'undefined');
await explore.db.spkType.upsert(vout.scriptPubKey.type);
const transaction_ref = transaction.lastInsertRowid;
const utxo = await explore.db.utxo.insert(transaction_ref, vout.n, vout.value);
const utxo_ref = utxo.lastInsertRowid;
const spk_type_ref = await explore.db.spkType.getCachedRefIf(vout.scriptPubKey.type);
const hash = util.sha256(vout.scriptPubKey.hex);
const hexUpsertResult = await explore.db.hex.upsert(vout.scriptPubKey.hex, hash, spk_type_ref, util.bitcoinToSatoshi(vout.value));
if (util.sha256(vout.scriptPubKey.hex) === 'b58bb87c47b96d1a4dff14b4cc042e2aa88d1a92da80c683f3fc84a6bddceb6b') {
console.log(vout.scriptPubKey.hex); // 18jANvQ6AuVGJnea4EhmXiAf6bHR5qKjPB, p2pk and p2pkh
}
let hex_ref = hexUpsertResult.lastInsertRowid;
if (typeof hex_ref === 'undefined') {
hex_ref = await explore.db.hex.getCachedRefByHashIf(hash);
}
await explore.db.utxoHex.insert(utxo_ref, hex_ref);
if (vout.scriptPubKey.addresses) {
for (let j = 0; j < vout.scriptPubKey.addresses.length; ++j) {
await explore.db.address.upsert(vout.scriptPubKey.addresses[j], hex_ref, spk_type_ref);
}
}
}
// });
profile.db.vout.increment(voutCrono.delta());
const vinCrono = new Crono();
for (let z = 0; z < raw.vin.length; ++z) {
const vin = raw.vin[z];
if (!vin.coinbase) {
// txid, vout -> value, satoshi, hex_id, utxo_id
const voutFound = await explore.db.vout.select(vin.txid, vin.vout);
assert(typeof voutFound !== 'undefined');
const satoshi = voutFound.satoshi - util.bitcoinToSatoshi(voutFound.value);
assert(satoshi >= 0);
await explore.db.hex.update(voutFound.hex_id, satoshi);
await explore.db.utxo.updateSpent(voutFound.id);
}
}
profile.db.vin.increment(vinCrono.delta());
};
const main = async () => {
const BitcoinCore = require('bitcoin-core');
const configuration = require('./configuration');
explore.db = await require('./db-engine/explore/' + configuration.dbEngine.explore.name);
console.log('Current db-engine: ' + configuration.dbEngine.explore.name);
const stoppedSuccesfully = await explore.db.controlFlow.stoppedSuccesfully();
assert(stoppedSuccesfully === true);
explore.bc = new BitcoinCore(configuration.bitcoinCore);
let lastBlock = {};
const count = (await explore.db.block.selectCount()).ts_counter;
if (count > 0) {
lastBlock = await explore.db.block.selectLast(count);
} else {
// genesis block.hash
lastBlock.nextblockhash = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f';
}
console.log({lastBlock});
while (true) { // eslint-disable-line no-constant-condition
const hasToStop = await explore.db.controlFlow.hasToStop();
if (hasToStop === true) {
break;
}
const profileCrono = new Crono();
explore.db.beginTransaction();
for (let i = 0; i < 1; ++i) {
const rpcCrono = new Crono();
assert(typeof lastBlock.nextblockhash !== 'undefined');
lastBlock = await explore.bc.getBlock(lastBlock.nextblockhash, 2);
profile.rpc.increment(rpcCrono.delta());
assert(typeof lastBlock !== 'undefined');
profile.height = lastBlock.height;
const dbCrono = new Crono();
const insertBlockResult = await explore.db.block.insert(lastBlock);
profile.tx.increment(lastBlock.tx.length);
for (let z = 0; z < lastBlock.tx.length; ++z) {
await handleTransaction(lastBlock.tx[z], insertBlockResult.lastInsertRowid);
}
/*
lastBlock.tx.forEach(raw => {
handleTransaction(raw, insertBlockResult.lastInsertRowid);
});
*/
profile.db.query.increment(dbCrono.delta());
}
const commitCrono = new Crono();
explore.db.commit();
profile.db.commit.update(commitCrono.delta());
profile.profile.update(profileCrono.delta());
profile.change = profile.profile.sigma - (profile.rpc.sigma + profile.db.query.sigma + profile.db.commit.sigma);
profile['tx/s'] = new DeltaSigma(1000 * profile.tx.delta / profile.profile.delta, 1000 * profile.tx.sigma / profile.profile.sigma);
console.log(JSON.stringify({profile, info: explore.db.info()}));
profile.db.query.delta = 0;
profile.rpc.delta = 0;
profile.tx.delta = 0;
profile.db.vout.delta = 0;
profile.db.vin.delta = 0;
}
await explore.db.controlFlow.setStopSuccesfully();
console.log('Stopped succesfully');
};
main();