UNPKG

22.1 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const client_common_1 = require("@neo-one/client-common");
4const node_core_1 = require("@neo-one/node-core");
5const utils_1 = require("@neo-one/utils");
6const common_1 = require("./common");
7const context_1 = require("./context");
8const handleChangeView = ({ context: contextIn, node, payload, consensusContext, message, }) => {
9 let context = contextIn;
10 const viewNumber = message.newViewNumber;
11 if (viewNumber > context.expectedView[payload.validatorIndex]) {
12 const mutableExpectedView = [...context.expectedView];
13 mutableExpectedView[payload.validatorIndex] = viewNumber;
14 context = context.cloneExpectedView({ expectedView: mutableExpectedView });
15 if (common_1.checkExpectedView({ context, viewNumber })) {
16 return common_1.initializeConsensus({
17 node,
18 context,
19 viewNumber,
20 consensusContext,
21 });
22 }
23 }
24 return { context };
25};
26const TEN_MINUTES_IN_SECONDS = 10 * 60;
27const handlePrepareRequest = async ({ context: contextIn, node, privateKey, payload, consensusContext, message, }) => {
28 let context = contextIn;
29 if (context.type !== 'backup' ||
30 context instanceof context_1.RequestReceivedContext ||
31 payload.validatorIndex !== context.primaryIndex ||
32 payload.timestamp > consensusContext.nowSeconds() + TEN_MINUTES_IN_SECONDS) {
33 return { context };
34 }
35 const header = await node.blockchain.header.get({
36 hashOrIndex: context.previousHash,
37 });
38 if (payload.timestamp <= header.timestamp) {
39 return { context };
40 }
41 const mutableSignatures = [];
42 mutableSignatures[payload.validatorIndex] = message.signature;
43 const newContext = new context_1.RequestReceivedContext({
44 viewNumber: context.viewNumber,
45 myIndex: context.myIndex,
46 primaryIndex: context.primaryIndex,
47 expectedView: context.expectedView,
48 validators: context.validators,
49 blockReceivedTimeSeconds: context.blockReceivedTimeSeconds,
50 transactions: {},
51 signatures: mutableSignatures,
52 header: {
53 type: 'new',
54 previousHash: context.previousHash,
55 transactionHashes: message.transactionHashes.map((hash) => client_common_1.common.uInt256ToHex(hash)),
56 blockIndex: context.blockIndex,
57 nonce: message.nonce,
58 timestamp: payload.timestamp,
59 nextConsensus: message.nextConsensus,
60 },
61 });
62 const verified = client_common_1.crypto.verify({
63 message: newContext.header.message,
64 signature: message.signature,
65 publicKey: context.validators[payload.validatorIndex],
66 });
67 if (!verified) {
68 return { context };
69 }
70 let nextContext = newContext;
71 for (const hash of newContext.transactionHashes.slice(1)) {
72 const transaction = node.memPool[hash];
73 if (transaction !== undefined) {
74 const res = await common_1.addTransaction({
75 context: nextContext,
76 node,
77 privateKey,
78 transaction,
79 verify: false,
80 consensusContext,
81 });
82 if (!(res.context instanceof context_1.RequestReceivedContext)) {
83 return res;
84 }
85 nextContext = res.context;
86 }
87 }
88 const result = await common_1.addTransaction({
89 context: nextContext,
90 node,
91 privateKey,
92 transaction: message.minerTransaction,
93 verify: true,
94 consensusContext,
95 });
96 if (!(result.context instanceof context_1.RequestReceivedContext)) {
97 return result;
98 }
99 context = result.context;
100 node.syncMemPool();
101 return { context };
102};
103const handlePrepareResponse = async ({ context, node, payload, message, }) => {
104 if (context instanceof context_1.HeaderContext &&
105 context.signatures[payload.validatorIndex] === undefined &&
106 client_common_1.crypto.verify({
107 message: context.header.message,
108 signature: message.signature,
109 publicKey: context.validators[payload.validatorIndex],
110 })) {
111 const mutableSignatures = [...context.signatures];
112 mutableSignatures[payload.validatorIndex] = message.signature;
113 const newContext = context.cloneSignatures({ signatures: mutableSignatures });
114 return common_1.checkSignatures({ context: newContext, node });
115 }
116 return { context };
117};
118exports.handleConsensusPayload = async ({ context, node, privateKey, payload, consensusContext, }) => {
119 const { consensusMessage } = payload;
120 if (payload.validatorIndex === context.myIndex ||
121 payload.version !== context.version ||
122 !client_common_1.common.uInt256Equal(payload.previousHash, context.previousHash) ||
123 payload.blockIndex !== context.blockIndex ||
124 payload.validatorIndex >= context.validators.length ||
125 (consensusMessage.type !== node_core_1.ConsensusMessageType.ChangeView && consensusMessage.viewNumber !== context.viewNumber)) {
126 return { context };
127 }
128 switch (consensusMessage.type) {
129 case node_core_1.ConsensusMessageType.ChangeView:
130 return handleChangeView({
131 context,
132 node,
133 payload,
134 consensusContext,
135 message: consensusMessage,
136 });
137 case node_core_1.ConsensusMessageType.PrepareRequest:
138 return handlePrepareRequest({
139 context,
140 node,
141 privateKey,
142 payload,
143 consensusContext,
144 message: consensusMessage,
145 });
146 case node_core_1.ConsensusMessageType.PrepareResponse:
147 return handlePrepareResponse({
148 context,
149 node,
150 payload,
151 message: consensusMessage,
152 });
153 default:
154 utils_1.utils.assertNever(consensusMessage);
155 throw new Error('For TS');
156 }
157};
158
159//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImhhbmRsZUNvbnNlbnN1c1BheWxvYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwwREFBb0U7QUFDcEUsa0RBUTRCO0FBQzVCLDBDQUFzRDtBQUN0RCxxQ0FBbUc7QUFFbkcsdUNBQTJFO0FBRzNFLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxFQUN4QixPQUFPLEVBQUUsU0FBUyxFQUNsQixJQUFJLEVBQ0osT0FBTyxFQUNQLGdCQUFnQixFQUNoQixPQUFPLEdBT1IsRUFBbUIsRUFBRTtJQUNwQixJQUFJLE9BQU8sR0FBRyxTQUFTLENBQUM7SUFDeEIsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztJQUN6QyxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRTtRQUM3RCxNQUFNLG1CQUFtQixHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdEQsbUJBQW1CLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxHQUFHLFVBQVUsQ0FBQztRQUN6RCxPQUFPLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsWUFBWSxFQUFFLG1CQUFtQixFQUFFLENBQUMsQ0FBQztRQUMzRSxJQUFJLDBCQUFpQixDQUFDLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUU7WUFDOUMsT0FBTyw0QkFBbUIsQ0FBQztnQkFDekIsSUFBSTtnQkFDSixPQUFPO2dCQUNQLFVBQVU7Z0JBQ1YsZ0JBQWdCO2FBQ2pCLENBQUMsQ0FBQztTQUNKO0tBQ0Y7SUFFRCxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDckIsQ0FBQyxDQUFDO0FBRUYsTUFBTSxzQkFBc0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBRXZDLE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxFQUFFLEVBQ2xDLE9BQU8sRUFBRSxTQUFTLEVBQ2xCLElBQUksRUFDSixVQUFVLEVBQ1YsT0FB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LGdDQUFvQixDQUFDLGNBQWM7WUFDdEMsT0FBTyxvQkFBb0IsQ0FBQztnQkFDMUIsT0FBTztnQkFDUCxJQUFJO2dCQUNKLFVBQVU7Z0JBQ1YsT0FBTztnQkFDUCxnQkFBZ0I7Z0JBQ2hCLE9BQU8sRUFBRSxnQkFBZ0I7YUFDMUIsQ0FBQyxDQUFDO1FBRUwsS0FBSyxnQ0FBb0IsQ0FBQyxlQUFlO1lBQ3ZDLE9BQU8scUJBQXFCLENBQUM7Z0JBQzNCLE9BQU87Z0JBQ1AsSUFBSTtnQkFDSixPQUFPO2dCQUNQLE9BQU8sRUFBRSxnQkFBZ0I7YUFDMUIsQ0FBQyxDQUFDO1FBRUw7WUFDRSxhQUFXLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDMUMsTUFBTSxJQUFJLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztLQUM3QjtBQUNILENBQUMsQ0FBQyIsImZpbGUiOiJuZW8tb25lLW5vZGUtY29uc2Vuc3VzL3NyYy9oYW5kbGVDb25zZW5zdXNQYXlsb2FkLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29tbW9uLCBjcnlwdG8sIFByaXZhdGVLZXkgfSBmcm9tICdAbmVvLW9uZS9jbGllbnQtY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZVZpZXdDb25zZW5zdXNNZXNzYWdlLFxuICBDb25zZW5zdXNNZXNzYWdlVHlwZSxcbiAgQ29uc2Vuc3VzUGF5bG9hZCxcbiAgTm9kZSxcbiAgUHJlcGFyZVJlcXVlc3RDb25zZW5zdXNNZXNzYWdlLFxuICBQcmVwYXJlUmVzcG9uc2VDb25zZW5zdXNNZXNzYWdlLFxuICBUcmFuc2FjdGlvbixcbn0gZnJvbSAnQG5lby1vbmUvbm9kZS1jb3JlJztcbmltcG9ydCB7IHV0aWxzIGFzIGNvbW1vblV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IHsgYWRkVHJhbnNhY3Rpb24sIGNoZWNrRXhwZWN0ZWRWaWV3LCBjaGVja1NpZ25hdHVyZXMsIGluaXRpYWxpemVDb25zZW5zdXMgfSBmcm9tICcuL2NvbW1vbic7XG5pbXBvcnQgeyBDb25zZW5zdXNDb250ZXh0IH0gZnJvbSAnLi9Db25zZW5zdXNDb250ZXh0JztcbmltcG9ydCB7IENvbnRleHQsIEhlYWRlckNvbnRleHQsIFJlcXVlc3RSZWNlaXZlZENvbnRleHQgfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgUmVzdWx0IH0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IGhhbmRsZUNoYW5nZVZpZXcgPSAoe1xuICBjb250ZXh0OiBjb250ZXh0SW4sXG4gIG5vZGUsXG4gIHBheWxvYWQsXG4gIGNvbnNlbnN1c0NvbnRleHQsXG4gIG1lc3NhZ2UsXG59OiB7XG4gIHJlYWRvbmx5IGNvbnRleHQ6IENvbnRleHQ7XG4gIHJlYWRvbmx5IG5vZGU6IE5vZGU7XG4gIHJlYWRvbmx5IHBheWxvYWQ6IENvbnNlbnN1c1BheWxvYWQ7XG4gIHJlYWRvbmx5IGNvbnNlbnN1c0NvbnRleHQ6IENvbnNlbnN1c0NvbnRleHQ7XG4gIHJlYWRvbmx5IG1lc3NhZ2U6IENoYW5nZVZpZXdDb25zZW5zdXNNZXNzYWdlO1xufSk6IFJlc3VsdDxDb250ZXh0PiA9PiB7XG4gIGxldCBjb250ZXh0ID0gY29udGV4dEluO1xuICBjb25zdCB2aWV3TnVtYmVyID0gbWVzc2FnZS5uZXdWaWV3TnVtYmVyO1xuICBpZiAodmlld051bWJlciA+IGNvbnRleHQuZXhwZWN0ZWRWaWV3W3BheWxvYWQudmFsaWRhdG9ySW5kZXhdKSB7XG4gICAgY29uc3QgbXV0YWJsZUV4cGVjdGVkVmlldyA9IFsuLi5jb250ZXh0LmV4cGVjdGVkVmlld107XG4gICAgbXV0YWJsZUV4cGVjdGVkVmlld1twYXlsb2FkLnZhbGlkYXRvckluZGV4XSA9IHZpZXdOdW1iZXI7XG4gICAgY29udGV4dCA9IGNvbnRleHQuY2xvbmVFeHBlY3RlZFZpZXcoeyBleHBlY3RlZFZpZXc6IG11dGFibGVFeHBlY3RlZFZpZXcgfSk7XG4gICAgaWYgKGNoZWNrRXhwZWN0ZWRWaWV3KHsgY29udGV4dCwgdmlld051bWJlciB9KSkge1xuICAgICAgcmV0dXJuIGluaXRpYWxpemVDb25zZW5zdXMoe1xuICAgICAgICBub2RlLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICB2aWV3TnVtYmVyLFxuICAgICAgICBjb25zZW5zdXNDb250ZXh0LFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgY29udGV4dCB9O1xufTtcblxuY29uc3QgVEVOX01JTlVURVNfSU5fU0VDT05EUyA9IDEwICogNjA7XG5cbmNvbnN0IGhhbmRsZVByZXBhcmVSZXF1ZXN0ID0gYXN5bmMgKHtcbiAgY29udGV4dDogY29udGV4dEluLFxuICBub2RlLFxuICBwcml2YXRlS2V5LFxuICBwYXlsb2FkLFxuICBjb25zZW5zdXNDb250ZXh0LFxuICBtZXNzYWdlLFxufToge1xuICByZWFkb25seSBjb250ZXh0OiBDb250ZXh0O1xuICByZWFkb25seSBub2RlOiBOb2RlO1xuICByZWFkb25seSBwcml2YXRlS2V5OiBQcml2YXRlS2V5O1xuICByZWFkb25seSBwYXlsb2FkOiBDb25zZW5zdXNQYXlsb2FkO1xuICByZWFkb25seSBjb25zZW5zdXNDb250ZXh0OiBDb25zZW5zdXNDb250ZXh0O1xuICByZWFkb25seSBtZXNzYWdlOiBQcmVwYXJlUmVxdWVzdENvbnNlbnN1c01lc3NhZ2U7XG59KTogUHJvbWlzZTxSZXN1bHQ8Q29udGV4dD4+ID0+IHtcbiAgbGV0IGNvbnRleHQgPSBjb250ZXh0SW47XG4gIGlmIChcbiAgICBjb250ZXh0LnR5cGUgIT09ICdiYWNrdXAnIHx8XG4gICAgY29udGV4dCBpbnN0YW5jZW9mIFJlcXVlc3RSZWNlaXZlZENvbnRleHQgfHxcbiAgICBwYXlsb2FkLnZhbGlkYXRvckluZGV4ICE9PSBjb250ZXh0LnByaW1hcnlJbmRleCB8fFxuICAgIHBheWxvYWQudGltZXN0YW1wID4gY29uc2Vuc3VzQ29udGV4dC5ub3dTZWNvbmRzKCkgKyBURU5fTUlOVVRFU19JTl9TRUNPTkRTXG4gICkge1xuICAgIHJldHVybiB7IGNvbnRleHQgfTtcbiAgfVxuICBjb25zdCBoZWFkZXIgPSBhd2FpdCBub2RlLmJsb2NrY2hhaW4uaGVhZGVyLmdldCh7XG4gICAgaGFzaE9ySW5kZXg6IGNvbnRleHQucHJldmlvdXNIYXNoLFxuICB9KTtcblxuICBpZiAocGF5bG9hZC50aW1lc3RhbXAgPD0gaGVhZGVyLnRpbWVzdGFtcCkge1xuICAgIHJldHVybiB7IGNvbnRleHQgfTtcbiAgfVxuXG4gIGNvbnN0IG11dGFibGVTaWduYXR1cmVzID0gW107XG4gIG11dGFibGVTaWduYXR1cmVzW3BheWxvYWQudmFsaWRhdG9ySW5kZXhdID0gbWVzc2FnZS5zaWduYXR1cmU7XG4gIGNvbnN0IG5ld0NvbnRleHQgPSBuZXcgUmVxdWVzdFJlY2VpdmVkQ29udGV4dCh7XG4gICAgdmlld051bWJlcjogY29udGV4dC52aWV3TnVtYmVyLFxuICAgIG15SW5kZXg6IGNvbnRleHQubXlJbmRleCxcbiAgICBwcmltYXJ5SW5kZXg6IGNvbnRleHQucHJpbWFyeUluZGV4LFxuICAgIGV4cGVjdGVkVmlldzogY29udGV4dC5leHBlY3RlZFZpZXcsXG4gICAgdmFsaWRhdG9yczogY29udGV4dC52YWxpZGF0b3JzLFxuICAgIGJsb2NrUmVjZWl2ZWRUaW1lU2Vjb25kczogY29udGV4dC5ibG9ja1JlY2VpdmVkVGltZVNlY29uZHMsXG4gICAgdHJhbnNhY3Rpb25zOiB7fSxcbiAgICBzaWduYXR1cmVzOiBtdXRhYmxlU2lnbmF0dXJlcyxcbiAgICBoZWFkZXI6IHtcbiAgICAgIHR5cGU6ICduZXcnLFxuICAgICAgcHJldmlvdXNIYXNoOiBjb250ZXh0LnByZXZpb3VzSGFzaCxcbiAgICAgIHRyYW5zYWN0aW9uSGFzaGVzOiBtZXNzYWdlLnRyYW5zYWN0aW9uSGFzaGVzLm1hcCgoaGFzaCkgPT4gY29tbW9uLnVJbnQyNTZUb0hleChoYXNoKSksXG5cbiAgICAgIGJsb2NrSW5kZXg6IGNvbnRleHQuYmxvY2tJbmRleCxcbiAgICAgIG5vbmNlOiBtZXNzYWdlLm5vbmNlLFxuICAgICAgdGltZXN0YW1wOiBwYXlsb2FkLnRpbWVzdGFtcCxcbiAgICAgIG5leHRDb25zZW5zdXM6IG1lc3NhZ2UubmV4dENvbnNlbnN1cyxcbiAgICB9LFxuICB9KTtcblxuICBjb25zdCB2ZXJpZmllZCA9IGNyeXB0by52ZXJpZnkoe1xuICAgIG1lc3NhZ2U6IG5ld0NvbnRleHQuaGVhZGVyLm1lc3NhZ2UsXG4gICAgc2lnbmF0dXJlOiBtZXNzYWdlLnNpZ25hdHVyZSxcbiAgICBwdWJsaWNLZXk6IGNvbnRleHQudmFsaWRhdG9yc1twYXlsb2FkLnZhbGlkYXRvckluZGV4XSxcbiAgfSk7XG5cbiAgaWYgKCF2ZXJpZmllZCkge1xuICAgIHJldHVybiB7IGNvbnRleHQgfTtcbiAgfVxuXG4gIGxldCBuZXh0Q29udGV4dCA9IG5ld0NvbnRleHQ7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1sb29wLXN0YXRlbWVudFxuICBmb3IgKGNvbnN0IGhhc2ggb2YgbmV3Q29udGV4dC50cmFuc2FjdGlvbkhhc2hlcy5zbGljZSgxKSkge1xuICAgIGNvbnN0IHRyYW5zYWN0aW9uID0gbm9kZS5tZW1Qb29sW2hhc2hdIGFzIFRyYW5zYWN0aW9uIHwgdW5kZWZpbmVkO1xuICAgIGlmICh0cmFuc2FjdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBhZGRUcmFuc2FjdGlvbih7XG4gICAgICAgIGNvbnRleHQ6IG5leHRDb250ZXh0LFxuICAgICAgICBub2RlLFxuICAgICAgICBwcml2YXRlS2V5LFxuICAgICAgICB0cmFuc2FjdGlvbixcbiAgICAgICAgdmVyaWZ5OiBmYWxzZSxcbiAgICAgICAgY29uc2Vuc3VzQ29udGV4dCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAoIShyZXMuY29udGV4dCBpbnN0YW5jZW9mIFJlcXVlc3RSZWNlaXZlZENvbnRleHQpKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgIG5leHRDb250ZXh0ID0gcmVzLmNvbnRleHQ7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgYWRkVHJhbnNhY3Rpb24oe1xuICAgIGNvbnRleHQ6IG5leHRDb250ZXh0LFxuICAgIG5vZGUsXG4gICAgcHJpdmF0ZUtleSxcbiAgICB0cmFuc2FjdGlvbjogbWVzc2FnZS5taW5lclRyYW5zYWN0aW9uLFxuICAgIHZlcmlmeTogdHJ1ZSxcbiAgICBjb25zZW5zdXNDb250ZXh0LFxuICB9KTtcblxuICBpZiAoIShyZXN1bHQuY29udGV4dCBpbnN0YW5jZW9mIFJlcXVlc3RSZWNlaXZlZENvbnRleHQpKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgY29udGV4dCA9IHJlc3VsdC5jb250ZXh0O1xuICBub2RlLnN5bmNNZW1Qb29sKCk7XG5cbiAgcmV0dXJuIHsgY29udGV4dCB9O1xufTtcblxuY29uc3QgaGFuZGxlUHJlcGFyZVJlc3BvbnNlID0gYXN5bmMgKHtcbiAgY29udGV4dCxcbiAgbm9kZSxcbiAgcGF5bG9hZCxcbiAgbWVzc2FnZSxcbn06IHtcbiAgcmVhZG9ubHkgY29udGV4dDogQ29udGV4dDtcbiAgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcmVhZG9ubHkgcGF5bG9hZDogQ29uc2Vuc3VzUGF5bG9hZDtcbiAgcmVhZG9ubHkgbWVzc2FnZTogUHJlcGFyZVJlc3BvbnNlQ29uc2Vuc3VzTWVzc2FnZTtcbn0pOiBQcm9taXNlPFJlc3VsdDxDb250ZXh0Pj4gPT4ge1xuICBpZiAoXG4gICAgY29udGV4dCBpbnN0YW5jZW9mIEhlYWRlckNvbnRleHQgJiZcbiAgICBjb250ZXh0LnNpZ25hdHVyZXNbcGF5bG9hZC52YWxpZGF0b3JJbmRleF0gPT09IHVuZGVmaW5lZCAmJlxuICAgIGNyeXB0by52ZXJpZnkoe1xuICAgICAgbWVzc2FnZTogY29udGV4dC5oZWFkZXIubWVzc2FnZSxcbiAgICAgIHNpZ25hdHVyZTogbWVzc2FnZS5zaWduYXR1cmUsXG4gICAgICBwdWJsaWNLZXk6IGNvbnRleHQudmFsaWRhdG9yc1twYXlsb2FkLnZhbGlkYXRvckluZGV4XSxcbiAgICB9KVxuICApIHtcbiAgICBjb25zdCBtdXRhYmxlU2lnbmF0dXJlcyA9IFsuLi5jb250ZXh0LnNpZ25hdHVyZXNdO1xuICAgIG11dGFibGVTaWduYXR1cmVzW3BheWxvYWQudmFsaWRhdG9ySW5kZXhdID0gbWVzc2FnZS5zaWduYXR1cmU7XG4gICAgY29uc3QgbmV3Q29udGV4dCA9IGNvbnRleHQuY2xvbmVTaWduYXR1cmVzKHsgc2lnbmF0dXJlczogbXV0YWJsZVNpZ25hdHVyZXMgfSk7XG5cbiAgICByZXR1cm4gY2hlY2tTaWduYXR1cmVzKHsgY29udGV4dDogbmV3Q29udGV4dCwgbm9kZSB9KTtcbiAgfVxuXG4gIHJldHVybiB7IGNvbnRleHQgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBoYW5kbGVDb25zZW5zdXNQYXlsb2FkID0gYXN5bmMgKHtcbiAgY29udGV4dCxcbiAgbm9kZSxcbiAgcHJpdmF0ZUtleSxcbiAgcGF5bG9hZCxcbiAgY29uc2Vuc3VzQ29udGV4dCxcbn06IHtcbiAgcmVhZG9ubHkgY29udGV4dDogQ29udGV4dDtcbiAgcmVhZG9ubHkgbm9kZTogTm9kZTtcbiAgcmVhZG9ubHkgcHJpdmF0ZUtleTogUHJpdmF0ZUtleTtcbiAgcmVhZG9ubHkgcGF5bG9hZDogQ29uc2Vuc3VzUGF5bG9hZDtcbiAgcmVhZG9ubHkgY29uc2Vuc3VzQ29udGV4dDogQ29uc2Vuc3VzQ29udGV4dDtcbn0pOiBQcm9taXNlPFJlc3VsdDxDb250ZXh0Pj4gPT4ge1xuICBjb25zdCB7IGNvbnNlbnN1c01lc3NhZ2UgfSA9IHBheWxvYWQ7XG4gIGlmIChcbiAgICBwYXlsb2FkLnZhbGlkYXRvckluZGV4ID09PSBjb250ZXh0Lm15SW5kZXggfHxcbiAgICBwYXlsb2FkLnZlcnNpb24gIT09IGNvbnRleHQudmVyc2lvbiB8fFxuICAgICFjb21tb24udUludDI1NkVxdWFsKHBheWxvYWQucHJldmlvdXNIYXNoLCBjb250ZXh0LnByZXZpb3VzSGFzaCkgfHxcbiAgICBwYXlsb2FkLmJsb2NrSW5kZXggIT09IGNvbnRleHQuYmxvY2tJbmRleCB8fFxuICAgIHBheWxvYWQudmFsaWRhdG9ySW5kZXggPj0gY29udGV4dC52YWxpZGF0b3JzLmxlbmd0aCB8fFxuICAgIChjb25zZW5zdXNNZXNzYWdlLnR5cGUgIT09IENvbnNlbnN1c01lc3NhZ2VUeXBlLkNoYW5nZVZpZXcgJiYgY29uc2Vuc3VzTWVzc2FnZS52aWV3TnVtYmVyICE9PSBjb250ZXh0LnZpZXdOdW1iZXIpXG4gICkge1xuICAgIHJldHVybiB7IGNvbnRleHQgfTtcbiAgfVxuXG4gIHN3aXRjaCAoY29uc2Vuc3VzTWVzc2FnZS50eXBlKSB7XG4gICAgY2FzZSBDb25zZW5zdXNNZXNzYWdlVHlwZS5DaGFuZ2VWaWV3OlxuICAgICAgcmV0dXJuIGhhbmRsZUNoYW5nZVZpZXcoe1xuICAgICAgICBjb250ZXh0LFxuICAgICAgICBub2RlLFxuICAgICAgICBwYXlsb2FkLFxuICAgICAgICBjb25zZW5zdXNDb250ZXh0LFxuICAgICAgICBtZXNzYWdlOiBjb25zZW5zdXNNZXNzYWdlLFxuICAgICAgfSk7XG5cbiAgICBjYXNlIENvbnNlbnN1c01lc3NhZ2VUeXBlLlByZXBhcmVSZXF1ZXN0OlxuICAgICAgcmV0dXJuIGhhbmRsZVByZXBhcmVSZXF1ZXN0KHtcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgcHJpdmF0ZUtleSxcbiAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgY29uc2Vuc3VzQ29udGV4dCxcbiAgICAgICAgbWVzc2FnZTogY29uc2Vuc3VzTWVzc2FnZSxcbiAgICAgIH0pO1xuXG4gICAgY2FzZSBDb25zZW5zdXNNZXNzYWdlVHlwZS5QcmVwYXJlUmVzcG9uc2U6XG4gICAgICByZXR1cm4gaGFuZGxlUHJlcGFyZVJlc3BvbnNlKHtcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgbm9kZSxcbiAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgbWVzc2FnZTogY29uc2Vuc3VzTWVzc2FnZSxcbiAgICAgIH0pO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGNvbW1vblV0aWxzLmFzc2VydE5ldmVyKGNvbnNlbnN1c01lc3NhZ2UpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3IgVFMnKTtcbiAgfVxufTtcbiJdfQ==