-
-
Notifications
You must be signed in to change notification settings - Fork 189
/
Copy pathblocks.js
217 lines (197 loc) · 5.78 KB
/
blocks.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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
'use strict';
var constants = require('../helpers/constants.js');
var sandboxHelper = require('../helpers/sandbox.js');
// Submodules
var blocksAPI = require('./blocks/api');
var blocksVerify = require('./blocks/verify');
var blocksProcess = require('./blocks/process');
var blocksUtils = require('./blocks/utils');
var blocksChain = require('./blocks/chain');
// Private fields
var modules, library, self, __private = {};
__private.lastBlock = {};
__private.lastReceipt = null;
__private.loaded = false;
__private.cleanup = false;
__private.isActive = false;
/**
* Initializes submodules with scope content.
* Calls submodules.chain.saveGenesisBlock.
* @memberof module:blocks
* @class
* @classdesc Main Blocks methods.
* @param {function} cb - Callback function.
* @param {scope} scope - App instance.
* @return {setImmediateCallback} Callback function with `self` as data.
*/
// Constructor
function Blocks (cb, scope) {
library = {
logger: scope.logger
};
// Initialize submodules with library content
this.submodules = {
api: new blocksAPI(
scope.logger, scope.db, scope.logic.block, scope.schema, scope.dbSequence
),
verify: new blocksVerify(scope.logger, scope.logic.block,
scope.logic.transaction, scope.db
),
process: new blocksProcess(
scope.logger, scope.logic.block, scope.logic.peers, scope.logic.transaction,
scope.schema, scope.db, scope.dbSequence, scope.sequence, scope.genesisblock
),
utils: new blocksUtils(scope.logger, scope.logic.block, scope.logic.transaction,
scope.db, scope.dbSequence, scope.genesisblock
),
chain: new blocksChain(
scope.logger, scope.logic.block, scope.logic.transaction, scope.db,
scope.genesisblock, scope.bus, scope.balancesSequence
)
};
// Expose submodules
this.shared = this.submodules.api;
this.verify = this.submodules.verify;
this.process = this.submodules.process;
this.utils = this.submodules.utils;
this.chain = this.submodules.chain;
self = this;
this.submodules.chain.saveGenesisBlock(function (err) {
return setImmediate(cb, err, self);
});
}
/**
* PUBLIC METHODS
*/
/**
* Last block functions, getter, setter and isFresh
* @property {function} get Returns lastBlock
* @property {function} set Sets lastBlock
* @property {function} isFresh Returns status of last block - if it fresh or not
*/
Blocks.prototype.lastBlock = {
get: function () {
return __private.lastBlock;
},
set: function (lastBlock) {
__private.lastBlock = lastBlock;
return __private.lastBlock;
},
/**
* Returns status of last block - if it fresh or not
*
* @function isFresh
* @return {Boolean} Fresh status of last block
*/
isFresh: function () {
if (!__private.lastBlock) { return false; }
// Current time in seconds - (epoch start in seconds + block timestamp)
var secondsAgo = Math.floor(Date.now() / 1000) - (Math.floor(constants.epochTime / 1000) + __private.lastBlock.timestamp);
return (secondsAgo < constants.blockReceiptTimeOut);
}
};
/**
* Last Receipt functions: get, update and isStale.
* @property {function} get Returns lastReceipt
* @property {function} update Updates lastReceipt
* @property {function} isStale Returns status of last receipt - if it fresh or not
*/
Blocks.prototype.lastReceipt = {
get: function () {
return __private.lastReceipt;
},
update: function () {
__private.lastReceipt = Math.floor(Date.now() / 1000);
return __private.lastReceipt;
},
/**
* Returns status of last receipt - if it stale or not
*
* @public
* @method lastReceipt.isStale
* @return {Boolean} Stale status of last receipt
*/
isStale: function () {
if (!__private.lastReceipt) { return true; }
// Current time in seconds - lastReceipt (seconds)
var secondsAgo = Math.floor(Date.now() / 1000) - __private.lastReceipt;
return (secondsAgo > constants.blockReceiptTimeOut);
}
};
Blocks.prototype.isActive = {
get: function () {
return __private.isActive;
},
set: function (isActive) {
__private.isActive = isActive;
return __private.isActive;
}
};
Blocks.prototype.isCleaning = {
get: function () {
return __private.cleanup;
}
};
/**
* Sandbox API wrapper
*
* @public
* @async
* @method sandboxApi
* @param {string} call Name of the function to be called
* @param {Object} args Arguments
* @param {Function} cb Callback function
*/
Blocks.prototype.sandboxApi = function (call, args, cb) {
sandboxHelper.callMethod(Blocks.prototype.shared, call, args, cb);
};
/**
* Handle modules initialization.
* Modules are not required in this file.
* @param {modules} scope Exposed modules
*/
Blocks.prototype.onBind = function (scope) {
// TODO: move here blocks submodules modules load from app.js.
// Set module as loaded
__private.loaded = true;
};
/**
* Handle node shutdown request
*
* @public
* @method cleanup
* @listens module:app~event:cleanup
* @param {Function} cb Callback function
* @return {Function} cb Callback function from params (through setImmediate)
*/
Blocks.prototype.cleanup = function (cb) {
__private.loaded = false;
__private.cleanup = true;
if (!__private.isActive) {
// Module ready for shutdown
return setImmediate(cb);
} else {
// Module is not ready, repeat
setImmediate(function nextWatch () {
if (__private.isActive) {
library.logger.info('Waiting for block processing to finish...');
setTimeout(nextWatch, 10000); // 10 sec
} else {
return setImmediate(cb);
}
});
}
};
/**
* Get module loading status
*
* @public
* @method isLoaded
* @return {boolean} status Module loading status
*/
Blocks.prototype.isLoaded = function () {
// Return 'true' if 'modules' are present
return __private.loaded;
};
// Export
module.exports = Blocks;