1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const client_common_1 = require("@neo-one/client-common");
|
4 | const logger_1 = require("@neo-one/logger");
|
5 | const utils_1 = require("@neo-one/utils");
|
6 | const asynciterablex_1 = require("@reactivex/ix-es2015-cjs/asynciterable/asynciterablex");
|
7 | const scan_1 = require("@reactivex/ix-es2015-cjs/asynciterable/pipe/scan");
|
8 | const common_1 = require("./common");
|
9 | const ConsensusContext_1 = require("./ConsensusContext");
|
10 | const ConsensusQueue_1 = require("./ConsensusQueue");
|
11 | const handleConsensusPayload_1 = require("./handleConsensusPayload");
|
12 | const handlePersistBlock_1 = require("./handlePersistBlock");
|
13 | const handleTransactionReceived_1 = require("./handleTransactionReceived");
|
14 | const runConsensus_1 = require("./runConsensus");
|
15 | const logger = logger_1.createChild(logger_1.nodeLogger, { component: 'consensus' });
|
16 | const MS_IN_SECOND = 1000;
|
17 | class Consensus {
|
18 | constructor({ options, node }) {
|
19 | this.mutableQueue = new ConsensusQueue_1.ConsensusQueue();
|
20 | const privateKey = client_common_1.common.stringToPrivateKey(options.privateKey);
|
21 | const publicKey = client_common_1.crypto.privateKeyToPublicKey(privateKey);
|
22 | const feeAddress = client_common_1.crypto.publicKeyToScriptHash(publicKey);
|
23 | this.options = {
|
24 | privateKey,
|
25 | publicKey,
|
26 | feeAddress,
|
27 | privateNet: options.privateNet,
|
28 | };
|
29 | this.node = node;
|
30 | this.mutableConsensusContext = new ConsensusContext_1.ConsensusContext();
|
31 | }
|
32 | async start() {
|
33 | let disposable = utils_1.noopDisposable;
|
34 | try {
|
35 | await this.pause();
|
36 | this.doStart(this.options);
|
37 | disposable = utils_1.composeDisposables(disposable, async () => {
|
38 | await this.pause();
|
39 | });
|
40 | return disposable;
|
41 | }
|
42 | catch (err) {
|
43 | await disposable();
|
44 | throw err;
|
45 | }
|
46 | }
|
47 | onPersistBlock() {
|
48 | this.mutableQueue.write({ type: 'handlePersistBlock' });
|
49 | }
|
50 | onConsensusPayloadReceived(payload) {
|
51 | this.mutableQueue.write({
|
52 | type: 'handleConsensusPayload',
|
53 | payload,
|
54 | });
|
55 | }
|
56 | onTransactionReceived(transaction) {
|
57 | this.mutableQueue.write({
|
58 | type: 'handleTransactionReceived',
|
59 | transaction,
|
60 | });
|
61 | }
|
62 | async runConsensusNow() {
|
63 | if (this.options.privateNet) {
|
64 | await new Promise((resolve, reject) => {
|
65 | this.mutableQueue.write({ type: 'timer', promise: { resolve, reject } });
|
66 | });
|
67 | }
|
68 | else {
|
69 | throw new Error('Can only force consensus on a private network.');
|
70 | }
|
71 | }
|
72 | nowSeconds() {
|
73 | return this.mutableConsensusContext.nowSeconds();
|
74 | }
|
75 | async fastForwardOffset(seconds) {
|
76 | if (this.options.privateNet) {
|
77 | this.mutableConsensusContext.fastForwardOffset(seconds);
|
78 | }
|
79 | else {
|
80 | throw new Error('Can only fast forward on a private network.');
|
81 | }
|
82 | }
|
83 | async fastForwardToTime(seconds) {
|
84 | if (this.options.privateNet) {
|
85 | this.mutableConsensusContext.fastForwardToTime(seconds);
|
86 | }
|
87 | else {
|
88 | throw new Error('Can only fast forward on a private network.');
|
89 | }
|
90 | }
|
91 | async pause() {
|
92 | this.clearTimer();
|
93 | this.mutableQueue.done();
|
94 | this.mutableQueue = new ConsensusQueue_1.ConsensusQueue();
|
95 | if (this.mutableStartPromise !== undefined) {
|
96 | await this.mutableStartPromise;
|
97 | }
|
98 | }
|
99 | async reset() {
|
100 | this.mutableConsensusContext = new ConsensusContext_1.ConsensusContext();
|
101 | }
|
102 | async resume() {
|
103 | this.doStart(this.options);
|
104 | }
|
105 | doStart(options) {
|
106 | let completed = false;
|
107 | const mutableStartPromise = this.startInternal(options).then(() => {
|
108 | completed = true;
|
109 | this.mutableStartPromise = undefined;
|
110 | });
|
111 | if (!completed) {
|
112 | this.mutableStartPromise = mutableStartPromise;
|
113 | }
|
114 | }
|
115 | async startInternal(options) {
|
116 | logger.info({ name: 'neo_consensus_start' }, 'Consensus started.');
|
117 | const initialResult = await common_1.initializeNewConsensus({
|
118 | blockchain: this.node.blockchain,
|
119 | publicKey: options.publicKey,
|
120 | consensusContext: this.mutableConsensusContext,
|
121 | });
|
122 | await asynciterablex_1.AsyncIterableX.from(this.mutableQueue)
|
123 | .pipe(scan_1.scan(async (context, event) => {
|
124 | let result;
|
125 | switch (event.type) {
|
126 | case 'handlePersistBlock':
|
127 | result = await handlePersistBlock_1.handlePersistBlock({
|
128 | blockchain: this.node.blockchain,
|
129 | publicKey: options.publicKey,
|
130 | consensusContext: this.mutableConsensusContext,
|
131 | });
|
132 | break;
|
133 | case 'handleConsensusPayload':
|
134 | result = await handleConsensusPayload_1.handleConsensusPayload({
|
135 | context,
|
136 | node: this.node,
|
137 | privateKey: options.privateKey,
|
138 | payload: event.payload,
|
139 | consensusContext: this.mutableConsensusContext,
|
140 | });
|
141 | break;
|
142 | case 'handleTransactionReceived':
|
143 | result = await handleTransactionReceived_1.handleTransactionReceived({
|
144 | context,
|
145 | node: this.node,
|
146 | privateKey: options.privateKey,
|
147 | transaction: event.transaction,
|
148 | consensusContext: this.mutableConsensusContext,
|
149 | });
|
150 | break;
|
151 | case 'timer':
|
152 | result = await runConsensus_1.runConsensus({
|
153 | context,
|
154 | node: this.node,
|
155 | options,
|
156 | consensusContext: this.mutableConsensusContext,
|
157 | }).catch((err) => {
|
158 | if (event.promise !== undefined) {
|
159 | event.promise.reject(err);
|
160 | }
|
161 | throw err;
|
162 | });
|
163 | if (event.promise !== undefined) {
|
164 | event.promise.resolve();
|
165 | }
|
166 | break;
|
167 | default:
|
168 | utils_1.utils.assertNever(event);
|
169 | throw new Error('For TS');
|
170 | }
|
171 | return this.handleResult(result);
|
172 | }, this.handleResult(initialResult)))
|
173 | .forEach(() => {
|
174 | });
|
175 | logger.info({ name: 'neo_consensus_stop' }, 'Consensus stopped.');
|
176 | }
|
177 | handleResult(result) {
|
178 | if (result.timerSeconds !== undefined) {
|
179 | this.handleTimer(result.timerSeconds);
|
180 | }
|
181 | return result.context;
|
182 | }
|
183 | handleTimer(mutableTimerSeconds) {
|
184 | this.clearTimer();
|
185 | this.mutableTimer = setTimeout(() => this.mutableQueue.write({ type: 'timer' }), mutableTimerSeconds * MS_IN_SECOND);
|
186 | }
|
187 | clearTimer() {
|
188 | if (this.mutableTimer !== undefined) {
|
189 | clearTimeout(this.mutableTimer);
|
190 | this.mutableTimer = undefined;
|
191 | }
|
192 | }
|
193 | }
|
194 | exports.Consensus = Consensus;
|
195 |
|
196 | //# sourceMappingURL=data:application/json;charset=utf8;base64,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LEtBQUssQ0FBQyxDQUFDO29CQUMvQixNQUFNLElBQUksS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQzdCO1lBRUQsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ25DLENBQUMsRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQ3JDO2FBQ0EsT0FBTyxDQUFDLEdBQUcsRUFBRTtRQUVkLENBQUMsQ0FBQyxDQUFDO1FBRUwsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxvQkFBb0IsRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDcEUsQ0FBQztJQUVPLFlBQVksQ0FBQyxNQUF1QjtRQUMxQyxJQUFJLE1BQU0sQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFO1lBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1NBQ3ZDO1FBRUQsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDO0lBQ3hCLENBQUM7SUFFTyxXQUFXLENBQUMsbUJBQTJCO1FBQzdDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FDNUIsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFDaEQsbUJBQW1CLEdBQUcsWUFBWSxDQUU1QixDQUFDO0lBQ1gsQ0FBQztJQUVPLFVBQVU7UUFDaEIsSUFBSSxJQUFJLENBQUMsWUFBWSxLQUFLLFNBQVMsRUFBRTtZQUNuQyxZQUFZLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1NBQy9CO0lBQ0gsQ0FBQztDQUNGO0FBeE5ELDhCQXdOQyIsImZpbGUiOiJuZW8tb25lLW5vZGUtY29uc2Vuc3VzL3NyYy9Db25zZW5zdXMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSB0eXBlcz1cIkByZWFjdGl2ZXgvaXgtZXMyMDE1LWNqc1wiIC8+XG5pbXBvcnQgeyBjb21tb24sIGNyeXB0bywgRUNQb2ludCwgUHJpdmF0ZUtleSwgVUludDE2MCB9IGZyb20gJ0BuZW8tb25lL2NsaWVudC1jb21tb24nO1xuaW1wb3J0IHsgY3JlYXRlQ2hpbGQsIG5vZGVMb2dnZXIgfSBmcm9tICdAbmVvLW9uZS9sb2dnZXInO1xuaW1wb3J0IHsgQ29uc2Vuc3VzUGF5bG9hZCwgTm9kZSwgVHJhbnNhY3Rpb24gfSBmcm9tICdAbmVvLW9uZS9ub2RlLWNvcmUnO1xuaW1wb3J0IHsgY29tcG9zZURpc3Bvc2FibGVzLCBEaXNwb3NhYmxlLCBub29wRGlzcG9zYWJsZSwgdXRpbHMgYXMgY29tbW9uVXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscyc7XG5pbXBvcnQgeyBBc3luY0l0ZXJhYmxlWCB9IGZyb20gJ0ByZWFjdGl2ZXgvaXgtZXMyMDE1LWNqcy9hc3luY2l0ZXJhYmxlL2FzeW5jaXRlcmFibGV4JztcbmltcG9ydCB7IHNjYW4gfSBmcm9tICdAcmVhY3RpdmV4L2l4LWVzMjAxNS1janMvYXN5bmNpdGVyYWJsZS9waXBlL3NjYW4nO1xuaW1wb3J0IHsgaW5pdGlhbGl6ZU5ld0NvbnNlbnN1cyB9IGZyb20gJy4vY29tbW9uJztcbmltcG9ydCB7IENvbnNlbnN1c0NvbnRleHQgfSBmcm9tICcuL0NvbnNlbnN1c0NvbnRleHQnO1xuaW1wb3J0IHsgQ29uc2Vuc3VzUXVldWUgfSBmcm9tICcuL0NvbnNlbnN1c1F1ZXVlJztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgaGFuZGxlQ29uc2Vuc3VzUGF5bG9hZCB9IGZyb20gJy4vaGFuZGxlQ29uc2Vuc3VzUGF5bG9hZCc7XG5pbXBvcnQgeyBoYW5kbGVQZXJzaXN0QmxvY2sgfSBmcm9tICcuL2hhbmRsZVBlcnNpc3RCbG9jayc7XG5pbXBvcnQgeyBoYW5kbGVUcmFuc2FjdGlvblJlY2VpdmVkIH0gZnJvbSAnLi9oYW5kbGVUcmFuc2FjdGlvblJlY2VpdmVkJztcbmltcG9ydCB7IHJ1bkNvbnNlbnN1cyB9IGZyb20gJy4vcnVuQ29uc2Vuc3VzJztcbmltcG9ydCB7IEV2ZW50LCBSZXN1bHQgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgbG9nZ2VyID0gY3JlYXRlQ2hpbGQobm9kZUxvZ2dlciwgeyBjb21wb25lbnQ6ICdjb25zZW5zdXMnIH0pO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wdGlvbnMge1xuICByZWFkb25seSBwcml2YXRlS2V5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHByaXZhdGVOZXQ6IGJvb2xlYW47XG59XG5leHBvcnQgaW50ZXJmYWNlIEludGVybmFsT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHByaXZhdGVLZXk6IFByaXZhdGVLZXk7XG4gIHJlYWRvbmx5IHB1YmxpY0tleTogRUNQb2ludDtcbiAgcmVhZG9ubHkgZmVlQWRkcmVzczogVUludDE2MDtcbiAgcmVhZG9ubHkgcHJpdmF0ZU5ldDogYm9vbGVhbjtcbn1cblxuY29uc3QgTVNfSU5fU0VDT05EID0gMTAwMDtcblxuZXhwb3J0IGNsYXNzIENvbnNlbnN1cyB7XG4gIHByaXZhdGUgbXV0YWJsZVF1ZXVlOiBDb25zZW5zdXNRdWV1ZTtcbiAgcHJpdmF0ZSBtdXRhYmxlVGltZXI6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBJbnRlcm5hbE9wdGlvbnM7XG4gIHByaXZhdGUgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcHJpdmF0ZSBtdXRhYmxlQ29uc2Vuc3VzQ29udGV4dDogQ29uc2Vuc3VzQ29udGV4dDtcbiAgcHJpdmF0ZSBtdXRhYmxlU3RhcnRQcm9taXNlOiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcih7IG9wdGlvbnMsIG5vZGUgfTogeyByZWFkb25seSBvcHRpb25zOiBPcHRpb25zOyByZWFkb25seSBub2RlOiBOb2RlIH0pIHtcbiAgICB0aGlzLm11dGFibGVRdWV1ZSA9IG5ldyBDb25zZW5zdXNRdWV1ZSgpO1xuXG4gICAgY29uc3QgcHJpdmF0ZUtleSA9IGNvbW1vbi5zdHJpbmdUb1ByaXZhdGVLZXkob3B0aW9ucy5wcml2YXRlS2V5KTtcbiAgICBjb25zdCBwdWJsaWNLZXkgPSBjcnlwdG8ucHJpdmF0ZUtleVRvUHVibGljS2V5KHByaXZhdGVLZXkpO1xuICAgIGNvbnN0IGZlZUFkZHJlc3MgPSBjcnlwdG8ucHVibGljS2V5VG9TY3JpcHRIYXNoKHB1YmxpY0tleSk7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgcHJpdmF0ZUtleSxcbiAgICAgIHB1YmxpY0tleSxcbiAgICAgIGZlZUFkZHJlc3MsXG4gICAgICBwcml2YXRlTmV0OiBvcHRpb25zLnByaXZhdGVOZXQsXG4gICAgfTtcblxuICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gICAgdGhpcy5tdXRhYmxlQ29uc2Vuc3VzQ29udGV4dCA9IG5ldyBDb25zZW5zdXNDb250ZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTxEaXNwb3NhYmxlPiB7XG4gICAgbGV0IGRpc3Bvc2FibGUgPSBub29wRGlzcG9zYWJsZTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wYXVzZSgpO1xuICAgICAgdGhpcy5kb1N0YXJ0KHRoaXMub3B0aW9ucyk7XG5cbiAgICAgIGRpc3Bvc2FibGUgPSBjb21wb3NlRGlzcG9zYWJsZXMoZGlzcG9zYWJsZSwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLnBhdXNlKCk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRpc3Bvc2FibGU7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBhd2FpdCBkaXNwb3NhYmxlKCk7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uUGVyc2lzdEJsb2NrKCk6IHZvaWQge1xuICAgIHRoaXMubXV0YWJsZVF1ZXVlLndyaXRlKHsgdHlwZTogJ2hhbmRsZVBlcnNpc3RCbG9jaycgfSk7XG4gIH1cblxuICBwdWJsaWMgb25Db25zZW5zdXNQYXlsb2FkUmVjZWl2ZWQocGF5bG9hZDogQ29uc2Vuc3VzUGF5bG9hZCk6IHZvaWQge1xuICAgIHRoaXMubXV0YWJsZVF1ZXVlLndyaXRlKHtcbiAgICAgIHR5cGU6ICdoYW5kbGVDb25zZW5zdXNQYXlsb2FkJyxcbiAgICAgIHBheWxvYWQsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgb25UcmFuc2FjdGlvblJlY2VpdmVkKHRyYW5zYWN0aW9uOiBUcmFuc2FjdGlvbik6IHZvaWQge1xuICAgIHRoaXMubXV0YWJsZVF1ZXVlLndyaXRlKHtcbiAgICAgIHR5cGU6ICdoYW5kbGVUcmFuc2FjdGlvblJlY2VpdmVkJyxcbiAgICAgIHRyYW5zYWN0aW9uLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHJ1bkNvbnNlbnN1c05vdygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5vcHRpb25zLnByaXZhdGVOZXQpIHtcbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBwcm9taXNlLW11c3QtY29tcGxldGVcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgdGhpcy5tdXRhYmxlUXVldWUud3JpdGUoeyB0eXBlOiAndGltZXInLCBwcm9taXNlOiB7IHJlc29sdmUsIHJlamVjdCB9IH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ2FuIG9ubHkgZm9yY2UgY29uc2Vuc3VzIG9uIGEgcHJpdmF0ZSBuZXR3b3JrLicpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBub3dTZWNvbmRzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMubXV0YWJsZUNvbnNlbnN1c0NvbnRleHQubm93U2Vjb25kcygpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGZhc3RGb3J3YXJkT2Zmc2V0KHNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnMucHJpdmF0ZU5ldCkge1xuICAgICAgdGhpcy5tdXRhYmxlQ29uc2Vuc3VzQ29udGV4dC5mYXN0Rm9yd2FyZE9mZnNldChzZWNvbmRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gb25seSBmYXN0IGZvcndhcmQgb24gYSBwcml2YXRlIG5ldHdvcmsuJyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIGZhc3RGb3J3YXJkVG9UaW1lKHNlY29uZHM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm9wdGlvbnMucHJpdmF0ZU5ldCkge1xuICAgICAgdGhpcy5tdXRhYmxlQ29uc2Vuc3VzQ29udGV4dC5mYXN0Rm9yd2FyZFRvVGltZShzZWNvbmRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW4gb25seSBmYXN0IGZvcndhcmQgb24gYSBwcml2YXRlIG5ldHdvcmsuJyk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGFzeW5jIHBhdXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuY2xlYXJUaW1lcigpO1xuICAgIHRoaXMubXV0YWJsZVF1ZXVlLmRvbmUoKTtcbiAgICB0aGlzLm11dGFibGVRdWV1ZSA9IG5ldyBDb25zZW5zdXNRdWV1ZSgpO1xuICAgIGlmICh0aGlzLm11dGFibGVTdGFydFByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgdGhpcy5tdXRhYmxlU3RhcnRQcm9taXNlO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZXNldCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLm11dGFibGVDb25zZW5zdXNDb250ZXh0ID0gbmV3IENvbnNlbnN1c0NvbnRleHQoKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyByZXN1bWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWZsb2F0aW5nLXByb21pc2VzXG4gICAgdGhpcy5kb1N0YXJ0KHRoaXMub3B0aW9ucyk7XG4gIH1cblxuICBwcml2YXRlIGRvU3RhcnQob3B0aW9uczogSW50ZXJuYWxPcHRpb25zKTogdm9pZCB7XG4gICAgbGV0IGNvbXBsZXRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IG11dGFibGVTdGFydFByb21pc2UgPSB0aGlzLnN0YXJ0SW50ZXJuYWwob3B0aW9ucykudGhlbigoKSA9PiB7XG4gICAgICBjb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgdGhpcy5tdXRhYmxlU3RhcnRQcm9taXNlID0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGlmICghY29tcGxldGVkKSB7XG4gICAgICB0aGlzLm11dGFibGVTdGFydFByb21pc2UgPSBtdXRhYmxlU3RhcnRQcm9taXNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3RhcnRJbnRlcm5hbChvcHRpb25zOiBJbnRlcm5hbE9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBsb2dnZXIuaW5mbyh7IG5hbWU6ICduZW9fY29uc2Vuc3VzX3N0YXJ0JyB9LCAnQ29uc2Vuc3VzIHN0YXJ0ZWQuJyk7XG5cbiAgICBjb25zdCBpbml0aWFsUmVzdWx0ID0gYXdhaXQgaW5pdGlhbGl6ZU5ld0NvbnNlbnN1cyh7XG4gICAgICBibG9ja2NoYWluOiB0aGlzLm5vZGUuYmxvY2tjaGFpbixcbiAgICAgIHB1YmxpY0tleTogb3B0aW9ucy5wdWJsaWNLZXksXG4gICAgICBjb25zZW5zdXNDb250ZXh0OiB0aGlzLm11dGFibGVDb25zZW5zdXNDb250ZXh0LFxuICAgIH0pO1xuXG4gICAgYXdhaXQgQXN5bmNJdGVyYWJsZVguZnJvbSh0aGlzLm11dGFibGVRdWV1ZSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzY2FuKGFzeW5jIChjb250ZXh0OiBDb250ZXh0LCBldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICBsZXQgcmVzdWx0O1xuICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaGFuZGxlUGVyc2lzdEJsb2NrJzpcbiAgICAgICAgICAgICAgcmVzdWx0ID0gYXdhaXQgaGFuZGxlUGVyc2lzdEJsb2NrKHtcbiAgICAgICAgICAgICAgICBibG9ja2NoYWluOiB0aGlzLm5vZGUuYmxvY2tjaGFpbixcbiAgICAgICAgICAgICAgICBwdWJsaWNLZXk6IG9wdGlvbnMucHVibGljS2V5LFxuICAgICAgICAgICAgICAgIGNvbnNlbnN1c0NvbnRleHQ6IHRoaXMubXV0YWJsZUNvbnNlbnN1c0NvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnaGFuZGxlQ29uc2Vuc3VzUGF5bG9hZCc6XG4gICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IGhhbmRsZUNvbnNlbnN1c1BheWxvYWQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5ub2RlLFxuICAgICAgICAgICAgICAgIHByaXZhdGVLZXk6IG9wdGlvbnMucHJpdmF0ZUtleSxcbiAgICAgICAgICAgICAgICBwYXlsb2FkOiBldmVudC5wYXlsb2FkLFxuICAgICAgICAgICAgICAgIGNvbnNlbnN1c0NvbnRleHQ6IHRoaXMubXV0YWJsZUNvbnNlbnN1c0NvbnRleHQsXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnaGFuZGxlVHJhbnNhY3Rpb25SZWNlaXZlZCc6XG4gICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IGhhbmRsZVRyYW5zYWN0aW9uUmVjZWl2ZWQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5ub2RlLFxuICAgICAgICAgICAgICAgIHByaXZhdGVLZXk6IG9wdGlvbnMucHJpdmF0ZUtleSxcbiAgICAgICAgICAgICAgICB0cmFuc2FjdGlvbjogZXZlbnQudHJhbnNhY3Rpb24sXG4gICAgICAgICAgICAgICAgY29uc2Vuc3VzQ29udGV4dDogdGhpcy5tdXRhYmxlQ29uc2Vuc3VzQ29udGV4dCxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0aW1lcic6XG4gICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHJ1bkNvbnNlbnN1cyh7XG4gICAgICAgICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICAgICAgICBub2RlOiB0aGlzLm5vZGUsXG4gICAgICAgICAgICAgICAgb3B0aW9ucyxcbiAgICAgICAgICAgICAgICBjb25zZW5zdXNDb250ZXh0OiB0aGlzLm11dGFibGVDb25zZW5zdXNDb250ZXh0LFxuICAgICAgICAgICAgICB9KS5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGV2ZW50LnByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgZXZlbnQucHJvbWlzZS5yZWplY3QoZXJyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgaWYgKGV2ZW50LnByb21pc2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgY29tbW9uVXRpbHMuYXNzZXJ0TmV2ZXIoZXZlbnQpO1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZvciBUUycpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzLmhhbmRsZVJlc3VsdChyZXN1bHQpO1xuICAgICAgICB9LCB0aGlzLmhhbmRsZVJlc3VsdChpbml0aWFsUmVzdWx0KSksXG4gICAgICApXG4gICAgICAuZm9yRWFjaCgoKSA9PiB7XG4gICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgIH0pO1xuXG4gICAgbG9nZ2VyLmluZm8oeyBuYW1lOiAnbmVvX2NvbnNlbnN1c19zdG9wJyB9LCAnQ29uc2Vuc3VzIHN0b3BwZWQuJyk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVJlc3VsdChyZXN1bHQ6IFJlc3VsdDxDb250ZXh0Pik6IENvbnRleHQge1xuICAgIGlmIChyZXN1bHQudGltZXJTZWNvbmRzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuaGFuZGxlVGltZXIocmVzdWx0LnRpbWVyU2Vjb25kcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdC5jb250ZXh0O1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVUaW1lcihtdXRhYmxlVGltZXJTZWNvbmRzOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmNsZWFyVGltZXIoKTtcbiAgICB0aGlzLm11dGFibGVUaW1lciA9IHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiB0aGlzLm11dGFibGVRdWV1ZS53cml0ZSh7IHR5cGU6ICd0aW1lcicgfSksXG4gICAgICBtdXRhYmxlVGltZXJTZWNvbmRzICogTVNfSU5fU0VDT05ELFxuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueVxuICAgICkgYXMgYW55O1xuICB9XG5cbiAgcHJpdmF0ZSBjbGVhclRpbWVyKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm11dGFibGVUaW1lciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5tdXRhYmxlVGltZXIpO1xuICAgICAgdGhpcy5tdXRhYmxlVGltZXIgPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG4iXX0=
|