forked from simpleledger/SLPDB
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatus.ts
123 lines (108 loc) · 4.7 KB
/
status.ts
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
import { Db } from "./db";
import { RpcClient } from "./rpc";
import { ChainSyncCheckpoint } from "./info";
var pjson = require('./package.json');
enum context {
"SLPDB" = "SLPDB"
}
export class SlpdbStatus {
static db: Db;
static version: string;
static context: context = context.SLPDB;
static lastStatusUpdate: string = '';
static state: SlpdbState;
static network: string = '';
static pastStackTraces: any[] = [];
static rpc: RpcClient;
static getSlpMempoolSize = function() { return -1; }
static getSlpTokensCount = function() { return -1; }
static getSyncdCheckpoint: () => Promise<ChainSyncCheckpoint> = async function() { return { hash: '', height: -1 }; }
constructor(db: Db, rpc: RpcClient) {
SlpdbStatus.version = pjson.version;
SlpdbStatus.db = db;
SlpdbStatus.rpc = rpc;
SlpdbStatus.state = SlpdbState.PRE_STARTUP;
}
static async changeStateToStartupBlockSync({ network, getSyncdCheckpoint }: { network: string, getSyncdCheckpoint: () => Promise<ChainSyncCheckpoint> }) {
SlpdbStatus.network = network;
SlpdbStatus.getSyncdCheckpoint = getSyncdCheckpoint;
SlpdbStatus.state = SlpdbState.STARTUP_BLOCK_SYNC;
await SlpdbStatus.saveStatus();
}
static async changeStateToStartupSlpProcessing({ getSlpTokensCount }: { getSlpTokensCount: () => number }) {
SlpdbStatus.state = SlpdbState.STARTUP_TOKEN_PROCESSING;
SlpdbStatus.getSlpTokensCount = getSlpTokensCount;
await SlpdbStatus.saveStatus();
}
static async changeStateToRunning({ getSlpMempoolSize }: { getSlpMempoolSize: () => number }) {
SlpdbStatus.state = SlpdbState.RUNNING;
SlpdbStatus.getSlpMempoolSize = getSlpMempoolSize;
await SlpdbStatus.saveStatus();
}
static async changeStateToExitOnError(trace: string) {
SlpdbStatus.state = SlpdbState.EXITED_ON_ERROR;
SlpdbStatus.pastStackTraces.unshift(trace);
if(SlpdbStatus.pastStackTraces.length > 5)
SlpdbStatus.pastStackTraces.pop();
await SlpdbStatus.saveStatus();
}
static async saveStatus() {
let dbo = await SlpdbStatus.toDbo();
await SlpdbStatus.db.statusUpdate(dbo);
}
static async logExitReason(error: string) {
if(error) {
await SlpdbStatus.changeStateToExitOnError(error);
} else {
SlpdbState.EXITED_NORMAL;
await SlpdbStatus.saveStatus();
}
}
private static async toDbo() {
let checkpoint = await SlpdbStatus.getSyncdCheckpoint();
let mempoolInfo = null;
try {
mempoolInfo = await SlpdbStatus.rpc.getMempoolInfo();
} catch (_) { }
let stackTraces = SlpdbStatus.pastStackTraces.map(t => {
if(typeof t === 'string')
return t;
else {
try {
return t.toString();
} catch(_) {
return "Unknown stack trace."
}
}
})
let date = new Date();
return {
version: SlpdbStatus.version,
context: SlpdbStatus.context,
lastStatusUpdate: { utc: date.toUTCString(), unix: Math.floor(date.getTime()/1000) },
state: SlpdbStatus.state,
network: SlpdbStatus.network,
blockHeight: checkpoint.height,
blockHash: checkpoint.hash,
mempoolInfoBch: mempoolInfo,
mempoolSizeSlp: SlpdbStatus.getSlpMempoolSize(),
tokensCount: SlpdbStatus.getSlpTokensCount(),
pastStackTraces: stackTraces,
mongoDbStats: await SlpdbStatus.db.db.stats({ scale: 1048576 })
}
}
static async loadPreviousAttributes() {
let dbo = await SlpdbStatus.db.statusFetch("SLPDB");
try {
SlpdbStatus.pastStackTraces = dbo.pastStackTraces;
} catch(_) {}
}
}
export enum SlpdbState {
"PRE_STARTUP" = "PRE_STARTUP", // phase 1) checking connections with mongodb and bitcoin rpc
"STARTUP_BLOCK_SYNC" = "STARTUP_BLOCK_SYNC", // phase 2) indexing blockchain data into confirmed collection (allows crawling tokens dag quickly)
"STARTUP_TOKEN_PROCESSING" = "STARTUP_TOKEN_PROCESSING", // phase 3) load/update token graphs, hold a cache (allows fastest SLP validation)
"RUNNING" = "RUNNING", // phase 4) startup completed, running normally
"EXITED_ON_ERROR" = "EXITED_ON_ERROR", // process exited due to an error during normal operation
"EXITED_NORMAL" = "EXITED_NORMAL" // process exited normally, clean shutdown or finished running a command
}