@aztec/validator-client 0.0.1-commit.d431d1c → 0.0.1-commit.d58ff9d0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -19
- package/dest/checkpoint_builder.d.ts +29 -15
- package/dest/checkpoint_builder.d.ts.map +1 -1
- package/dest/checkpoint_builder.js +144 -45
- package/dest/config.d.ts +9 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +49 -13
- package/dest/duties/validation_service.d.ts +12 -13
- package/dest/duties/validation_service.d.ts.map +1 -1
- package/dest/duties/validation_service.js +33 -45
- package/dest/factory.d.ts +10 -4
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +19 -6
- package/dest/index.d.ts +2 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/key_store/ha_key_store.d.ts +1 -1
- package/dest/key_store/ha_key_store.d.ts.map +1 -1
- package/dest/key_store/ha_key_store.js +3 -3
- package/dest/key_store/web3signer_key_store.d.ts +10 -2
- package/dest/key_store/web3signer_key_store.d.ts.map +1 -1
- package/dest/key_store/web3signer_key_store.js +32 -41
- package/dest/metrics.d.ts +16 -3
- package/dest/metrics.d.ts.map +1 -1
- package/dest/metrics.js +58 -5
- package/dest/proposal_handler.d.ts +165 -0
- package/dest/proposal_handler.d.ts.map +1 -0
- package/dest/proposal_handler.js +1207 -0
- package/dest/validator.d.ts +65 -25
- package/dest/validator.d.ts.map +1 -1
- package/dest/validator.js +377 -240
- package/package.json +19 -17
- package/src/checkpoint_builder.ts +196 -54
- package/src/config.ts +57 -15
- package/src/duties/validation_service.ts +59 -54
- package/src/factory.ts +29 -4
- package/src/index.ts +1 -2
- package/src/key_store/ha_key_store.ts +3 -3
- package/src/key_store/web3signer_key_store.ts +43 -59
- package/src/metrics.ts +81 -6
- package/src/proposal_handler.ts +1314 -0
- package/src/validator.ts +512 -291
- package/dest/block_proposal_handler.d.ts +0 -65
- package/dest/block_proposal_handler.d.ts.map +0 -1
- package/dest/block_proposal_handler.js +0 -561
- package/dest/tx_validator/index.d.ts +0 -3
- package/dest/tx_validator/index.d.ts.map +0 -1
- package/dest/tx_validator/index.js +0 -2
- package/dest/tx_validator/nullifier_cache.d.ts +0 -14
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -54
- package/src/block_proposal_handler.ts +0 -576
- package/src/tx_validator/index.ts +0 -2
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/tx_validator_factory.ts +0 -135
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeSignature } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
2
2
|
import { Signature } from '@aztec/foundation/eth-signature';
|
|
3
|
+
/** Default hard timeout (ms) applied to each Web3Signer HTTP request. */ const DEFAULT_WEB3SIGNER_REQUEST_TIMEOUT_MS = 30_000;
|
|
3
4
|
/**
|
|
4
5
|
* Web3Signer Key Store
|
|
5
6
|
*
|
|
@@ -8,9 +9,11 @@ import { Signature } from '@aztec/foundation/eth-signature';
|
|
|
8
9
|
*/ export class Web3SignerKeyStore {
|
|
9
10
|
addresses;
|
|
10
11
|
baseUrl;
|
|
11
|
-
|
|
12
|
+
requestTimeoutMs;
|
|
13
|
+
constructor(addresses, baseUrl, requestTimeoutMs = DEFAULT_WEB3SIGNER_REQUEST_TIMEOUT_MS){
|
|
12
14
|
this.addresses = addresses;
|
|
13
15
|
this.baseUrl = baseUrl;
|
|
16
|
+
this.requestTimeoutMs = requestTimeoutMs;
|
|
14
17
|
}
|
|
15
18
|
/**
|
|
16
19
|
* Get the address of a signer by index
|
|
@@ -78,10 +81,9 @@ import { Signature } from '@aztec/foundation/eth-signature';
|
|
|
78
81
|
* @param address - The Ethereum address to sign with
|
|
79
82
|
* @param data - The data to sign
|
|
80
83
|
* @returns The signature
|
|
81
|
-
*/
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const body = {
|
|
84
|
+
*/ makeJsonRpcSignRequest(address, data) {
|
|
85
|
+
// eth_sign automatically applies Ethereum message prefixing to the raw data.
|
|
86
|
+
return this.sendSignRequest({
|
|
85
87
|
jsonrpc: '2.0',
|
|
86
88
|
method: 'eth_sign',
|
|
87
89
|
params: [
|
|
@@ -89,37 +91,10 @@ import { Signature } from '@aztec/foundation/eth-signature';
|
|
|
89
91
|
data.toString()
|
|
90
92
|
],
|
|
91
93
|
id: 1
|
|
92
|
-
};
|
|
93
|
-
const response = await fetch(url, {
|
|
94
|
-
method: 'POST',
|
|
95
|
-
headers: {
|
|
96
|
-
'Content-Type': 'application/json'
|
|
97
|
-
},
|
|
98
|
-
body: JSON.stringify(body)
|
|
99
94
|
});
|
|
100
|
-
if (!response.ok) {
|
|
101
|
-
const errorText = await response.text();
|
|
102
|
-
throw new Error(`Web3Signer request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
103
|
-
}
|
|
104
|
-
const result = await response.json();
|
|
105
|
-
// Handle JSON-RPC response format
|
|
106
|
-
if (result.error) {
|
|
107
|
-
throw new Error(`Web3Signer JSON-RPC error: ${result.error.code} - ${result.error.message}`);
|
|
108
|
-
}
|
|
109
|
-
if (!result.result) {
|
|
110
|
-
throw new Error('Invalid response from Web3Signer: no result found');
|
|
111
|
-
}
|
|
112
|
-
let signatureHex = result.result;
|
|
113
|
-
// Ensure the signature has the 0x prefix
|
|
114
|
-
if (!signatureHex.startsWith('0x')) {
|
|
115
|
-
signatureHex = '0x' + signatureHex;
|
|
116
|
-
}
|
|
117
|
-
// Parse the signature from the hex string
|
|
118
|
-
return normalizeSignature(Signature.fromString(signatureHex));
|
|
119
95
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const body = {
|
|
96
|
+
makeJsonRpcSignTypedDataRequest(address, typedData) {
|
|
97
|
+
return this.sendSignRequest({
|
|
123
98
|
jsonrpc: '2.0',
|
|
124
99
|
method: 'eth_signTypedData',
|
|
125
100
|
params: [
|
|
@@ -127,19 +102,35 @@ import { Signature } from '@aztec/foundation/eth-signature';
|
|
|
127
102
|
JSON.stringify(typedData)
|
|
128
103
|
],
|
|
129
104
|
id: 1
|
|
130
|
-
};
|
|
131
|
-
const response = await fetch(url, {
|
|
132
|
-
method: 'POST',
|
|
133
|
-
headers: {
|
|
134
|
-
'Content-Type': 'application/json'
|
|
135
|
-
},
|
|
136
|
-
body: JSON.stringify(body)
|
|
137
105
|
});
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Send a JSON-RPC request to Web3Signer under a hard request timeout and parse the signature.
|
|
109
|
+
* A timed-out or aborted request is surfaced as a clear timeout error rather than hanging, so a
|
|
110
|
+
* slow or unreachable signer cannot stall an HA signing operation past its own timeout budget.
|
|
111
|
+
*/ async sendSignRequest(body) {
|
|
112
|
+
let response;
|
|
113
|
+
try {
|
|
114
|
+
response = await fetch(this.baseUrl, {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: {
|
|
117
|
+
'Content-Type': 'application/json'
|
|
118
|
+
},
|
|
119
|
+
body: JSON.stringify(body),
|
|
120
|
+
signal: AbortSignal.timeout(this.requestTimeoutMs)
|
|
121
|
+
});
|
|
122
|
+
} catch (err) {
|
|
123
|
+
if ((err instanceof Error || err instanceof DOMException) && (err.name === 'TimeoutError' || err.name === 'AbortError')) {
|
|
124
|
+
throw new Error(`Web3Signer request timed out after ${this.requestTimeoutMs}ms`);
|
|
125
|
+
}
|
|
126
|
+
throw err;
|
|
127
|
+
}
|
|
138
128
|
if (!response.ok) {
|
|
139
129
|
const errorText = await response.text();
|
|
140
130
|
throw new Error(`Web3Signer request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
141
131
|
}
|
|
142
132
|
const result = await response.json();
|
|
133
|
+
// Handle JSON-RPC response format
|
|
143
134
|
if (result.error) {
|
|
144
135
|
throw new Error(`Web3Signer JSON-RPC error: ${result.error.code} - ${result.error.message}`);
|
|
145
136
|
}
|
package/dest/metrics.d.ts
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
+
import type { EpochNumber } from '@aztec/foundation/branded-types';
|
|
2
|
+
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
1
3
|
import type { BlockProposal } from '@aztec/stdlib/p2p';
|
|
2
4
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
|
+
import type { BlockProposalValidationFailureReason } from './proposal_handler.js';
|
|
3
6
|
export declare class ValidatorMetrics {
|
|
4
7
|
private failedReexecutionCounter;
|
|
5
8
|
private successfulAttestationsCount;
|
|
6
9
|
private failedAttestationsBadProposalCount;
|
|
7
10
|
private failedAttestationsNodeIssueCount;
|
|
11
|
+
private currentEpoch;
|
|
12
|
+
private attestedEpochCount;
|
|
8
13
|
private reexMana;
|
|
9
14
|
private reexTx;
|
|
10
15
|
private reexDuration;
|
|
16
|
+
private checkpointProposalToPipelinedStateDuration;
|
|
17
|
+
private checkpointProposalReceiveOffsetFromNextSlotBoundary;
|
|
11
18
|
constructor(telemetryClient: TelemetryClient);
|
|
12
19
|
recordReex(time: number, txs: number, mManaTotal: number): void;
|
|
20
|
+
recordCheckpointProposalToPipelinedStateDuration(durationMs: number): void;
|
|
21
|
+
recordCheckpointProposalReceiveOffsetFromNextSlotBoundary(offsetMs: number): void;
|
|
13
22
|
recordFailedReexecution(proposal: BlockProposal): void;
|
|
14
23
|
incSuccessfulAttestations(num: number): void;
|
|
15
|
-
incFailedAttestationsBadProposal(num: number, reason:
|
|
16
|
-
incFailedAttestationsNodeIssue(num: number, reason:
|
|
24
|
+
incFailedAttestationsBadProposal(num: number, reason: BlockProposalValidationFailureReason, inCommittee: boolean): void;
|
|
25
|
+
incFailedAttestationsNodeIssue(num: number, reason: BlockProposalValidationFailureReason, inCommittee: boolean): void;
|
|
26
|
+
/** Update the gauge tracking the current epoch number (proxy for total epochs elapsed). */
|
|
27
|
+
setCurrentEpoch(epoch: EpochNumber): void;
|
|
28
|
+
/** Increment the count of epochs in which the given attester submitted at least one attestation. */
|
|
29
|
+
incAttestedEpochCount(attester: EthAddress): void;
|
|
17
30
|
}
|
|
18
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0cmljcy5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL21ldHJpY3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUtMLEtBQUssZUFBZSxFQUdyQixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sS0FBSyxFQUFFLG9DQUFvQyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFFbEYscUJBQWEsZ0JBQWdCO0lBQzNCLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBZ0I7SUFDaEQsT0FBTyxDQUFDLDJCQUEyQixDQUFnQjtJQUNuRCxPQUFPLENBQUMsa0NBQWtDLENBQWdCO0lBQzFELE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBZ0I7SUFDeEQsT0FBTyxDQUFDLFlBQVksQ0FBUTtJQUM1QixPQUFPLENBQUMsa0JBQWtCLENBQWdCO0lBRTFDLE9BQU8sQ0FBQyxRQUFRLENBQVk7SUFDNUIsT0FBTyxDQUFDLE1BQU0sQ0FBWTtJQUMxQixPQUFPLENBQUMsWUFBWSxDQUFRO0lBQzVCLE9BQU8sQ0FBQywwQ0FBMEMsQ0FBWTtJQUM5RCxPQUFPLENBQUMsbURBQW1ELENBQVk7SUFFdkUsWUFBWSxlQUFlLEVBQUUsZUFBZSxFQTBEM0M7SUFFTSxVQUFVLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLFFBSTlEO0lBRU0sZ0RBQWdELENBQUMsVUFBVSxFQUFFLE1BQU0sUUFFekU7SUFFTSx5REFBeUQsQ0FBQyxRQUFRLEVBQUUsTUFBTSxRQUloRjtJQUVNLHVCQUF1QixDQUFDLFFBQVEsRUFBRSxhQUFhLFFBTXJEO0lBRU0seUJBQXlCLENBQUMsR0FBRyxFQUFFLE1BQU0sUUFFM0M7SUFFTSxnQ0FBZ0MsQ0FDckMsR0FBRyxFQUFFLE1BQU0sRUFDWCxNQUFNLEVBQUUsb0NBQW9DLEVBQzVDLFdBQVcsRUFBRSxPQUFPLFFBTXJCO0lBRU0sOEJBQThCLENBQ25DLEdBQUcsRUFBRSxNQUFNLEVBQ1gsTUFBTSxFQUFFLG9DQUFvQyxFQUM1QyxXQUFXLEVBQUUsT0FBTyxRQU1yQjtJQUVELDJGQUEyRjtJQUNwRixlQUFlLENBQUMsS0FBSyxFQUFFLFdBQVcsUUFFeEM7SUFFRCxvR0FBb0c7SUFDN0YscUJBQXFCLENBQUMsUUFBUSxFQUFFLFVBQVUsUUFFaEQ7Q0FDRiJ9
|
package/dest/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAKL,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAKL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,uBAAuB,CAAC;AAElF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,wBAAwB,CAAgB;IAChD,OAAO,CAAC,2BAA2B,CAAgB;IACnD,OAAO,CAAC,kCAAkC,CAAgB;IAC1D,OAAO,CAAC,gCAAgC,CAAgB;IACxD,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,kBAAkB,CAAgB;IAE1C,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,YAAY,CAAQ;IAC5B,OAAO,CAAC,0CAA0C,CAAY;IAC9D,OAAO,CAAC,mDAAmD,CAAY;IAEvE,YAAY,eAAe,EAAE,eAAe,EA0D3C;IAEM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAI9D;IAEM,gDAAgD,CAAC,UAAU,EAAE,MAAM,QAEzE;IAEM,yDAAyD,CAAC,QAAQ,EAAE,MAAM,QAIhF;IAEM,uBAAuB,CAAC,QAAQ,EAAE,aAAa,QAMrD;IAEM,yBAAyB,CAAC,GAAG,EAAE,MAAM,QAE3C;IAEM,gCAAgC,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,oCAAoC,EAC5C,WAAW,EAAE,OAAO,QAMrB;IAEM,8BAA8B,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,oCAAoC,EAC5C,WAAW,EAAE,OAAO,QAMrB;IAED,2FAA2F;IACpF,eAAe,CAAC,KAAK,EAAE,WAAW,QAExC;IAED,oGAAoG;IAC7F,qBAAqB,CAAC,QAAQ,EAAE,UAAU,QAEhD;CACF"}
|
package/dest/metrics.js
CHANGED
|
@@ -1,27 +1,72 @@
|
|
|
1
|
-
import { Attributes, Metrics } from '@aztec/telemetry-client';
|
|
1
|
+
import { Attributes, Metrics, createUpDownCounterWithDefault } from '@aztec/telemetry-client';
|
|
2
2
|
export class ValidatorMetrics {
|
|
3
3
|
failedReexecutionCounter;
|
|
4
4
|
successfulAttestationsCount;
|
|
5
5
|
failedAttestationsBadProposalCount;
|
|
6
6
|
failedAttestationsNodeIssueCount;
|
|
7
|
+
currentEpoch;
|
|
8
|
+
attestedEpochCount;
|
|
7
9
|
reexMana;
|
|
8
10
|
reexTx;
|
|
9
11
|
reexDuration;
|
|
12
|
+
checkpointProposalToPipelinedStateDuration;
|
|
13
|
+
checkpointProposalReceiveOffsetFromNextSlotBoundary;
|
|
10
14
|
constructor(telemetryClient){
|
|
11
15
|
const meter = telemetryClient.getMeter('Validator');
|
|
12
|
-
this.failedReexecutionCounter = meter
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
this.failedReexecutionCounter = createUpDownCounterWithDefault(meter, Metrics.VALIDATOR_FAILED_REEXECUTION_COUNT, {
|
|
17
|
+
[Attributes.STATUS]: [
|
|
18
|
+
'failed'
|
|
19
|
+
]
|
|
20
|
+
});
|
|
21
|
+
this.successfulAttestationsCount = createUpDownCounterWithDefault(meter, Metrics.VALIDATOR_ATTESTATION_SUCCESS_COUNT);
|
|
22
|
+
this.failedAttestationsBadProposalCount = createUpDownCounterWithDefault(meter, Metrics.VALIDATOR_ATTESTATION_FAILED_BAD_PROPOSAL_COUNT, {
|
|
23
|
+
[Attributes.ERROR_TYPE]: [
|
|
24
|
+
'invalid_proposal',
|
|
25
|
+
'state_mismatch',
|
|
26
|
+
'failed_txs',
|
|
27
|
+
'in_hash_mismatch',
|
|
28
|
+
'parent_block_wrong_slot'
|
|
29
|
+
],
|
|
30
|
+
[Attributes.IS_COMMITTEE_MEMBER]: [
|
|
31
|
+
true,
|
|
32
|
+
false
|
|
33
|
+
]
|
|
34
|
+
});
|
|
35
|
+
this.failedAttestationsNodeIssueCount = createUpDownCounterWithDefault(meter, Metrics.VALIDATOR_ATTESTATION_FAILED_NODE_ISSUE_COUNT, {
|
|
36
|
+
[Attributes.ERROR_TYPE]: [
|
|
37
|
+
'parent_block_not_found',
|
|
38
|
+
'global_variables_mismatch',
|
|
39
|
+
'block_number_already_exists',
|
|
40
|
+
'txs_not_available',
|
|
41
|
+
'timeout',
|
|
42
|
+
'unknown_error'
|
|
43
|
+
],
|
|
44
|
+
[Attributes.IS_COMMITTEE_MEMBER]: [
|
|
45
|
+
true,
|
|
46
|
+
false
|
|
47
|
+
]
|
|
48
|
+
});
|
|
49
|
+
this.currentEpoch = meter.createGauge(Metrics.VALIDATOR_CURRENT_EPOCH);
|
|
50
|
+
this.attestedEpochCount = createUpDownCounterWithDefault(meter, Metrics.VALIDATOR_ATTESTED_EPOCH_COUNT);
|
|
16
51
|
this.reexMana = meter.createHistogram(Metrics.VALIDATOR_RE_EXECUTION_MANA);
|
|
17
52
|
this.reexTx = meter.createHistogram(Metrics.VALIDATOR_RE_EXECUTION_TX_COUNT);
|
|
18
53
|
this.reexDuration = meter.createGauge(Metrics.VALIDATOR_RE_EXECUTION_TIME);
|
|
54
|
+
this.checkpointProposalToPipelinedStateDuration = meter.createHistogram(Metrics.VALIDATOR_CHECKPOINT_PROPOSAL_TO_PIPELINED_STATE_DURATION);
|
|
55
|
+
this.checkpointProposalReceiveOffsetFromNextSlotBoundary = meter.createHistogram(Metrics.VALIDATOR_CHECKPOINT_PROPOSAL_RECEIVE_OFFSET_FROM_NEXT_SLOT_BOUNDARY);
|
|
19
56
|
}
|
|
20
57
|
recordReex(time, txs, mManaTotal) {
|
|
21
58
|
this.reexDuration.record(Math.ceil(time));
|
|
22
59
|
this.reexTx.record(txs);
|
|
23
60
|
this.reexMana.record(mManaTotal);
|
|
24
61
|
}
|
|
62
|
+
recordCheckpointProposalToPipelinedStateDuration(durationMs) {
|
|
63
|
+
this.checkpointProposalToPipelinedStateDuration.record(Math.ceil(durationMs));
|
|
64
|
+
}
|
|
65
|
+
recordCheckpointProposalReceiveOffsetFromNextSlotBoundary(offsetMs) {
|
|
66
|
+
this.checkpointProposalReceiveOffsetFromNextSlotBoundary.record(Math.ceil(Math.abs(offsetMs)), {
|
|
67
|
+
[Attributes.SLOT_BOUNDARY_SIDE]: offsetMs < 0 ? 'before' : 'after'
|
|
68
|
+
});
|
|
69
|
+
}
|
|
25
70
|
recordFailedReexecution(proposal) {
|
|
26
71
|
const proposer = proposal.getSender();
|
|
27
72
|
this.failedReexecutionCounter.add(1, {
|
|
@@ -44,4 +89,12 @@ export class ValidatorMetrics {
|
|
|
44
89
|
[Attributes.IS_COMMITTEE_MEMBER]: inCommittee
|
|
45
90
|
});
|
|
46
91
|
}
|
|
92
|
+
/** Update the gauge tracking the current epoch number (proxy for total epochs elapsed). */ setCurrentEpoch(epoch) {
|
|
93
|
+
this.currentEpoch.record(Number(epoch));
|
|
94
|
+
}
|
|
95
|
+
/** Increment the count of epochs in which the given attester submitted at least one attestation. */ incAttestedEpochCount(attester) {
|
|
96
|
+
this.attestedEpochCount.add(1, {
|
|
97
|
+
[Attributes.ATTESTER_ADDRESS]: attester.toString()
|
|
98
|
+
});
|
|
99
|
+
}
|
|
47
100
|
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type { Archiver } from '@aztec/archiver';
|
|
2
|
+
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
3
|
+
import type { EpochCache } from '@aztec/epoch-cache';
|
|
4
|
+
import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
5
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
6
|
+
import type { LogData } from '@aztec/foundation/log';
|
|
7
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
8
|
+
import type { P2P, PeerId } from '@aztec/p2p';
|
|
9
|
+
import { BlockProposalValidator } from '@aztec/p2p/msg_validators';
|
|
10
|
+
import type { L2Block, L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
11
|
+
import type { CheckpointReexecutionTracker } from '@aztec/stdlib/checkpoint';
|
|
12
|
+
import type { ITxProvider, ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
13
|
+
import { type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
14
|
+
import type { BlockProposal, CheckpointProposalCore } from '@aztec/stdlib/p2p';
|
|
15
|
+
import type { ConsensusTimetable } from '@aztec/stdlib/timetable';
|
|
16
|
+
import type { FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
17
|
+
import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
|
|
18
|
+
import type { FullNodeCheckpointsBuilder } from './checkpoint_builder.js';
|
|
19
|
+
import type { ValidatorMetrics } from './metrics.js';
|
|
20
|
+
export type BlockProposalValidationFailureReason = 'invalid_signature' | 'invalid_proposal' | 'parent_block_not_found' | 'parent_block_wrong_slot' | 'in_hash_mismatch' | 'global_variables_mismatch' | 'block_number_already_exists' | 'txs_not_available' | 'state_mismatch' | 'failed_txs' | 'initial_state_mismatch' | 'timeout' | 'block_proposal_beyond_checkpoint' | 'checkpoint_proposal_equivocation' | 'unknown_error';
|
|
21
|
+
type ReexecuteTransactionsResult = {
|
|
22
|
+
block: L2Block;
|
|
23
|
+
failedTxs: FailedTx[];
|
|
24
|
+
reexecutionTimeMs: number;
|
|
25
|
+
totalManaUsed: number;
|
|
26
|
+
};
|
|
27
|
+
export type BlockProposalValidationSuccessResult = {
|
|
28
|
+
isValid: true;
|
|
29
|
+
blockNumber: BlockNumber;
|
|
30
|
+
reexecutionResult?: ReexecuteTransactionsResult;
|
|
31
|
+
};
|
|
32
|
+
export type BlockProposalValidationFailureResult = {
|
|
33
|
+
isValid: false;
|
|
34
|
+
reason: BlockProposalValidationFailureReason;
|
|
35
|
+
blockNumber?: BlockNumber;
|
|
36
|
+
reexecutionResult?: ReexecuteTransactionsResult;
|
|
37
|
+
};
|
|
38
|
+
export type BlockProposalValidationResult = BlockProposalValidationSuccessResult | BlockProposalValidationFailureResult;
|
|
39
|
+
export type CheckpointProposalValidationFailureReason = 'invalid_signature' | 'invalid_fee_asset_price_modifier' | 'last_block_not_found' | 'block_fetch_error' | 'checkpoint_already_published' | 'no_blocks_for_slot' | 'last_block_archive_mismatch' | 'too_many_blocks_in_checkpoint' | 'checkpoint_header_mismatch' | 'archive_mismatch' | 'out_hash_mismatch' | 'checkpoint_validation_failed';
|
|
40
|
+
export type CheckpointProposalValidationSuccessResult = {
|
|
41
|
+
isValid: true;
|
|
42
|
+
checkpointNumber: CheckpointNumber;
|
|
43
|
+
};
|
|
44
|
+
export type CheckpointProposalValidationFailureResult = {
|
|
45
|
+
isValid: false;
|
|
46
|
+
reason: CheckpointProposalValidationFailureReason;
|
|
47
|
+
checkpointNumber?: CheckpointNumber;
|
|
48
|
+
};
|
|
49
|
+
export type CheckpointProposalValidationResult = CheckpointProposalValidationSuccessResult | CheckpointProposalValidationFailureResult;
|
|
50
|
+
export type CheckpointProposalValidationFailureCallback = (proposal: CheckpointProposalCore, result: CheckpointProposalValidationFailureResult, proposalInfo: LogData) => void | Promise<void>;
|
|
51
|
+
/** Block-proposal validation failures that constitute a slashable invalid-block offense. */
|
|
52
|
+
export declare const SLASHABLE_BLOCK_PROPOSAL_VALIDATION_RESULT: BlockProposalValidationFailureReason[];
|
|
53
|
+
/** Checkpoint-proposal validation failures that constitute a slashable invalid-checkpoint offense. */
|
|
54
|
+
export declare const SLASHABLE_CHECKPOINT_PROPOSAL_VALIDATION_RESULT: Record<CheckpointProposalValidationFailureReason, boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* Handles block and checkpoint proposals for both validator and non-validator nodes. Also tracks which slots
|
|
57
|
+
* had a slashable invalid proposal or a proposal equivocation, exposing them via the
|
|
58
|
+
* `InvalidProposalSlotSource` interface consumed by the attested-invalid-proposal slashing watcher. The
|
|
59
|
+
* tracking is populated as a side effect of validating/re-executing proposals, so any node that re-executes
|
|
60
|
+
* proposals (the default) can serve it — not only validators.
|
|
61
|
+
*/
|
|
62
|
+
export declare class ProposalHandler {
|
|
63
|
+
private checkpointsBuilder;
|
|
64
|
+
private worldState;
|
|
65
|
+
private blockSource;
|
|
66
|
+
private l1ToL2MessageSource;
|
|
67
|
+
private txProvider;
|
|
68
|
+
private blockProposalValidator;
|
|
69
|
+
private epochCache;
|
|
70
|
+
private timetable;
|
|
71
|
+
private config;
|
|
72
|
+
private blobClient;
|
|
73
|
+
private reexecutionTracker;
|
|
74
|
+
private metrics?;
|
|
75
|
+
private dateProvider;
|
|
76
|
+
private log;
|
|
77
|
+
readonly tracer: Tracer;
|
|
78
|
+
/** Cached last checkpoint validation result to avoid double-validation on validator nodes.
|
|
79
|
+
* Keyed by signed-payload hash so two proposals at the same (slot, archive) but with a
|
|
80
|
+
* different `feeAssetPriceModifier` (or any other signed field) are validated independently. */
|
|
81
|
+
private lastCheckpointValidationResult?;
|
|
82
|
+
/** Archiver reference for setting proposed checkpoints (pipelining). Set via register(). */
|
|
83
|
+
private archiver?;
|
|
84
|
+
/** Returns current validator addresses for own-proposal detection. Set via register(). */
|
|
85
|
+
private getOwnValidatorAddresses?;
|
|
86
|
+
/** P2P proposal pool access for deciding when retained proposals should block archiver processing. */
|
|
87
|
+
private p2pClient?;
|
|
88
|
+
private checkpointProposalValidationFailureCallback?;
|
|
89
|
+
/** Slots at which a slashable invalid block or checkpoint proposal was observed. */
|
|
90
|
+
private readonly slotsWithInvalidProposals;
|
|
91
|
+
/** Slots at which a proposal equivocation was observed; suppresses attested-to-invalid-proposal slashing. */
|
|
92
|
+
private readonly slotsWithProposalEquivocation;
|
|
93
|
+
constructor(checkpointsBuilder: FullNodeCheckpointsBuilder, worldState: WorldStateSynchronizer, blockSource: L2BlockSource & L2BlockSink, l1ToL2MessageSource: L1ToL2MessageSource, txProvider: ITxProvider, blockProposalValidator: BlockProposalValidator, epochCache: EpochCache, timetable: ConsensusTimetable, config: ValidatorClientFullConfig, blobClient: BlobClientInterface, reexecutionTracker: CheckpointReexecutionTracker, metrics?: ValidatorMetrics | undefined, dateProvider?: DateProvider, telemetry?: TelemetryClient, log?: import("@aztec/foundation/log").Logger);
|
|
94
|
+
updateConfig(config: Partial<ValidatorClientFullConfig>): void;
|
|
95
|
+
setCheckpointProposalValidationFailureCallback(callback?: CheckpointProposalValidationFailureCallback): void;
|
|
96
|
+
/**
|
|
97
|
+
* Records the proposer's own checkpoint proposal as a `valid` outcome in the re-execution
|
|
98
|
+
* tracker. Without this, the node's own checkpoint proposals never flow through
|
|
99
|
+
* `handleCheckpointProposal` (proposers don't validate their own proposals), so its sentinel
|
|
100
|
+
* sees no outcome for slots where it was the proposer and reports itself as inactive.
|
|
101
|
+
*
|
|
102
|
+
* `archive` should be the locally-computed archive (NOT the broadcast archive, which may have
|
|
103
|
+
* been deliberately corrupted in tests via `broadcastInvalidBlockProposal` /
|
|
104
|
+
* `broadcastInvalidCheckpointProposalOnly`). Recording the local archive correctly models the
|
|
105
|
+
* proposer's own view of its own work.
|
|
106
|
+
*/
|
|
107
|
+
recordOwnCheckpointProposalAsValid(slot: SlotNumber, archive: Fr, checkpointNumber: CheckpointNumber): void;
|
|
108
|
+
/** Whether a slashable invalid block or checkpoint proposal was observed at the given slot (InvalidProposalSlotSource). */
|
|
109
|
+
hasInvalidProposals(slotNumber: SlotNumber): boolean;
|
|
110
|
+
/** Whether a proposal equivocation was observed at the given slot (InvalidProposalSlotSource). */
|
|
111
|
+
hasProposalEquivocation(slotNumber: SlotNumber): boolean;
|
|
112
|
+
/** Records a slot as having a slashable invalid proposal, for offense observers (sentinel/slasher watchers). */
|
|
113
|
+
markInvalidProposalSlot(slotNumber: SlotNumber): void;
|
|
114
|
+
/** Records a slot as having a proposal equivocation, which suppresses attested-to-invalid-proposal slashing. */
|
|
115
|
+
markProposalEquivocation(slotNumber: SlotNumber): void;
|
|
116
|
+
/**
|
|
117
|
+
* Registers handlers for block and checkpoint proposals on the p2p client.
|
|
118
|
+
* Records the p2p client so validation can inspect retained proposals.
|
|
119
|
+
* Block proposals are registered for non-validator nodes (validators register their own enhanced handler).
|
|
120
|
+
* The all-nodes checkpoint proposal handler is always registered for validation, caching, and pipelining.
|
|
121
|
+
* @param archiver - Archiver reference for setting proposed checkpoints (pipelining)
|
|
122
|
+
* @param getOwnValidatorAddresses - Returns current validator addresses for own-proposal detection
|
|
123
|
+
*/
|
|
124
|
+
register(p2pClient: P2P, shouldReexecute: boolean, archiver?: Pick<Archiver, 'addProposedCheckpoint' | 'getProposedCheckpointData'>, getOwnValidatorAddresses?: () => string[]): ProposalHandler;
|
|
125
|
+
handleBlockProposal(proposal: BlockProposal, proposalSender: PeerId, shouldReexecute: boolean): Promise<BlockProposalValidationResult>;
|
|
126
|
+
private validateNewBlockInSlot;
|
|
127
|
+
private getParentBlock;
|
|
128
|
+
private resolveExistingBlockAtNumber;
|
|
129
|
+
private computeCheckpointNumber;
|
|
130
|
+
/**
|
|
131
|
+
* Validates that a non-first block in a checkpoint has consistent global variables with its parent.
|
|
132
|
+
* For blocks with indexWithinCheckpoint > 0, all global variables except blockNumber must match the parent.
|
|
133
|
+
* @returns A failure result if validation fails, undefined if validation passes
|
|
134
|
+
*/
|
|
135
|
+
private validateNonFirstBlockInCheckpoint;
|
|
136
|
+
/**
|
|
137
|
+
* Hard re-execution/validation deadline for any block or checkpoint proposal targeting `slotNumber`:
|
|
138
|
+
* the single consensus `attestation_deadline` (`target_slot_start + S - 2E`). This is the latest the
|
|
139
|
+
* checkpoint can land on L1 in the target slot; all nodes agree on it. Loosened from the previous
|
|
140
|
+
* next-wall-clock-slot-boundary bound (see the timetable spec / refactor notes).
|
|
141
|
+
*/
|
|
142
|
+
private getReexecutionDeadline;
|
|
143
|
+
private getReexecuteFailureReason;
|
|
144
|
+
reexecuteTransactions(proposal: BlockProposal, blockNumber: BlockNumber, checkpointNumber: CheckpointNumber, txs: Tx[], l1ToL2Messages: Fr[], previousCheckpointOutHashes: Fr[]): Promise<ReexecuteTransactionsResult>;
|
|
145
|
+
/**
|
|
146
|
+
* Validates a checkpoint proposal, caches the result, and uploads blobs if configured.
|
|
147
|
+
* Returns a cached result if the same proposal (archive + slot) was already validated.
|
|
148
|
+
* Used by both the all-nodes callback (via register) and the validator client (via delegation).
|
|
149
|
+
*/
|
|
150
|
+
handleCheckpointProposal(proposal: CheckpointProposalCore, proposalInfo: LogData): Promise<CheckpointProposalValidationResult>;
|
|
151
|
+
/**
|
|
152
|
+
* Validates a checkpoint proposal by building the full checkpoint and comparing it with the proposal.
|
|
153
|
+
* @returns Validation result with isValid flag and reason if invalid.
|
|
154
|
+
*/
|
|
155
|
+
validateCheckpointProposal(proposal: CheckpointProposalCore, proposalInfo: LogData): Promise<CheckpointProposalValidationResult>;
|
|
156
|
+
/** Extracts checkpoint global variables from a block. */
|
|
157
|
+
private extractCheckpointConstants;
|
|
158
|
+
/** Triggers blob upload for a checkpoint if the blob client can upload (fire and forget). */
|
|
159
|
+
protected tryUploadBlobsForCheckpoint(proposal: CheckpointProposalCore, proposalInfo: LogData): void;
|
|
160
|
+
/** Uploads blobs for a checkpoint to the filestore. */
|
|
161
|
+
protected uploadBlobsForCheckpoint(proposal: CheckpointProposalCore, proposalInfo: LogData): Promise<void>;
|
|
162
|
+
private setProposedCheckpoint;
|
|
163
|
+
}
|
|
164
|
+
export {};
|
|
165
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcG9zYWxfaGFuZGxlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3Byb3Bvc2FsX2hhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDaEQsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUdyRSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVyRCxPQUFPLEVBQ0wsV0FBVyxFQUNYLGdCQUFnQixFQUVoQixVQUFVLEVBQ1gsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHcEQsT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFHckQsT0FBTyxFQUFFLFlBQVksRUFBUyxNQUFNLHlCQUF5QixDQUFDO0FBQzlELE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDOUMsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbkUsT0FBTyxLQUFLLEVBQWEsT0FBTyxFQUFFLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMxRixPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBc0IsTUFBTSwwQkFBMEIsQ0FBQztBQUlqRyxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUseUJBQXlCLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUN0SCxPQUFPLEVBQ0wsS0FBSyxtQkFBbUIsRUFHekIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQXlCLHNCQUFzQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEcsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVsRSxPQUFPLEtBQUssRUFBNkIsUUFBUSxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUWhGLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBRSxLQUFLLE1BQU0sRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQUVoRyxPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzFFLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXJELE1BQU0sTUFBTSxvQ0FBb0MsR0FDNUMsbUJBQW1CLEdBQ25CLGtCQUFrQixHQUNsQix3QkFBd0IsR0FDeEIseUJBQXlCLEdBQ3pCLGtCQUFrQixHQUNsQiwyQkFBMkIsR0FDM0IsNkJBQTZCLEdBQzdCLG1CQUFtQixHQUNuQixnQkFBZ0IsR0FDaEIsWUFBWSxHQUNaLHdCQUF3QixHQUN4QixTQUFTLEdBQ1Qsa0NBQWtDLEdBQ2xDLGtDQUFrQyxHQUNsQyxlQUFlLENBQUM7QUFFcEIsS0FBSywyQkFBMkIsR0FBRztJQUNqQyxLQUFLLEVBQUUsT0FBTyxDQUFDO0lBQ2YsU0FBUyxFQUFFLFFBQVEsRUFBRSxDQUFDO0lBQ3RCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUMxQixhQUFhLEVBQUUsTUFBTSxDQUFDO0NBQ3ZCLENBQUM7QUFFRixNQUFNLE1BQU0sb0NBQW9DLEdBQUc7SUFDakQsT0FBTyxFQUFFLElBQUksQ0FBQztJQUNkLFdBQVcsRUFBRSxXQUFXLENBQUM7SUFDekIsaUJBQWlCLENBQUMsRUFBRSwyQkFBMkIsQ0FBQztDQUNqRCxDQUFDO0FBRUYsTUFBTSxNQUFNLG9DQUFvQyxHQUFHO0lBQ2pELE9BQU8sRUFBRSxLQUFLLENBQUM7SUFDZixNQUFNLEVBQUUsb0NBQW9DLENBQUM7SUFDN0MsV0FBVyxDQUFDLEVBQUUsV0FBVyxDQUFDO0lBQzFCLGlCQUFpQixDQUFDLEVBQUUsMkJBQTJCLENBQUM7Q0FDakQsQ0FBQztBQUVGLE1BQU0sTUFBTSw2QkFBNkIsR0FBRyxvQ0FBb0MsR0FBRyxvQ0FBb0MsQ0FBQztBQUV4SCxNQUFNLE1BQU0seUNBQXlDLEdBQ2pELG1CQUFtQixHQUNuQixrQ0FBa0MsR0FDbEMsc0JBQXNCLEdBQ3RCLG1CQUFtQixHQUNuQiw4QkFBOEIsR0FDOUIsb0JBQW9CLEdBQ3BCLDZCQUE2QixHQUM3QiwrQkFBK0IsR0FDL0IsNEJBQTRCLEdBQzVCLGtCQUFrQixHQUNsQixtQkFBbUIsR0FDbkIsOEJBQThCLENBQUM7QUEwQm5DLE1BQU0sTUFBTSx5Q0FBeUMsR0FBRztJQUN0RCxPQUFPLEVBQUUsSUFBSSxDQUFDO0lBQ2QsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUM7Q0FDcEMsQ0FBQztBQUVGLE1BQU0sTUFBTSx5Q0FBeUMsR0FBRztJQUN0RCxPQUFPLEVBQUUsS0FBSyxDQUFDO0lBQ2YsTUFBTSxFQUFFLHlDQUF5QyxDQUFDO0lBQ2xELGdCQUFnQixDQUFDLEVBQUUsZ0JBQWdCLENBQUM7Q0FDckMsQ0FBQztBQUVGLE1BQU0sTUFBTSxrQ0FBa0MsR0FDMUMseUNBQXlDLEdBQ3pDLHlDQUF5QyxDQUFDO0FBRTlDLE1BQU0sTUFBTSwyQ0FBMkMsR0FBRyxDQUN4RCxRQUFRLEVBQUUsc0JBQXNCLEVBQ2hDLE1BQU0sRUFBRSx5Q0FBeUMsRUFDakQsWUFBWSxFQUFFLE9BQU8sS0FDbEIsSUFBSSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztBQVkxQiw0RkFBNEY7QUFDNUYsZUFBTyxNQUFNLDBDQUEwQyxFQUFFLG9DQUFvQyxFQU81RixDQUFDO0FBRUYsc0dBQXNHO0FBQ3RHLGVBQU8sTUFBTSwrQ0FBK0MsRUFBRSxNQUFNLENBQ2xFLHlDQUF5QyxFQUN6QyxPQUFPLENBbUJSLENBQUM7QUFFRjs7Ozs7O0dBTUc7QUFDSCxxQkFBYSxlQUFlO0lBNkJ4QixPQUFPLENBQUMsa0JBQWtCO0lBQzFCLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxXQUFXO0lBQ25CLE9BQU8sQ0FBQyxtQkFBbUI7SUFDM0IsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLHNCQUFzQjtJQUM5QixPQUFPLENBQUMsVUFBVTtJQUNsQixPQUFPLENBQUMsU0FBUztJQUNqQixPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxVQUFVO0lBQ2xCLE9BQU8sQ0FBQyxrQkFBa0I7SUFDMUIsT0FBTyxDQUFDLE9BQU8sQ0FBQztJQUNoQixPQUFPLENBQUMsWUFBWTtJQUVwQixPQUFPLENBQUMsR0FBRztJQTFDYixTQUFnQixNQUFNLEVBQUUsTUFBTSxDQUFDO0lBRS9COztxR0FFaUc7SUFDakcsT0FBTyxDQUFDLDhCQUE4QixDQUFDLENBR3JDO0lBRUYsNEZBQTRGO0lBQzVGLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBd0U7SUFFekYsMEZBQTBGO0lBQzFGLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQUFpQjtJQUVsRCxzR0FBc0c7SUFDdEcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFtQztJQUVyRCxPQUFPLENBQUMsMkNBQTJDLENBQUMsQ0FBOEM7SUFFbEcsb0ZBQW9GO0lBQ3BGLE9BQU8sQ0FBQyxRQUFRLENBQUMseUJBQXlCLENBQXFFO0lBRS9HLDZHQUE2RztJQUM3RyxPQUFPLENBQUMsUUFBUSxDQUFDLDZCQUE2QixDQUFxRTtJQUVuSCxZQUNVLGtCQUFrQixFQUFFLDBCQUEwQixFQUM5QyxVQUFVLEVBQUUsc0JBQXNCLEVBQ2xDLFdBQVcsRUFBRSxhQUFhLEdBQUcsV0FBVyxFQUN4QyxtQkFBbUIsRUFBRSxtQkFBbUIsRUFDeEMsVUFBVSxFQUFFLFdBQVcsRUFDdkIsc0JBQXNCLEVBQUUsc0JBQXNCLEVBQzlDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFNBQVMsRUFBRSxrQkFBa0IsRUFDN0IsTUFBTSxFQUFFLHlCQUF5QixFQUNqQyxVQUFVLEVBQUUsbUJBQW1CLEVBQy9CLGtCQUFrQixFQUFFLDRCQUE0QixFQUNoRCxPQUFPLENBQUMsOEJBQWtCLEVBQzFCLFlBQVksR0FBRSxZQUFpQyxFQUN2RCxTQUFTLEdBQUUsZUFBc0MsRUFDekMsR0FBRyx5Q0FBNkMsRUFNekQ7SUFFTSxZQUFZLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxHQUFHLElBQUksQ0FFcEU7SUFFTSw4Q0FBOEMsQ0FBQyxRQUFRLENBQUMsRUFBRSwyQ0FBMkMsR0FBRyxJQUFJLENBRWxIO0lBRUQ7Ozs7Ozs7Ozs7T0FVRztJQUNJLGtDQUFrQyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxnQkFBZ0IsRUFBRSxnQkFBZ0IsR0FBRyxJQUFJLENBRWpIO0lBRUQsMkhBQTJIO0lBQ3BILG1CQUFtQixDQUFDLFVBQVUsRUFBRSxVQUFVLEdBQUcsT0FBTyxDQUUxRDtJQUVELGtHQUFrRztJQUMzRix1QkFBdUIsQ0FBQyxVQUFVLEVBQUUsVUFBVSxHQUFHLE9BQU8sQ0FFOUQ7SUFFRCxnSEFBZ0g7SUFDekcsdUJBQXVCLENBQUMsVUFBVSxFQUFFLFVBQVUsR0FBRyxJQUFJLENBRTNEO0lBRUQsZ0hBQWdIO0lBQ3pHLHdCQUF3QixDQUFDLFVBQVUsRUFBRSxVQUFVLEdBQUcsSUFBSSxDQUU1RDtJQUVEOzs7Ozs7O09BT0c7SUFDSCxRQUFRLENBQ04sU0FBUyxFQUFFLEdBQUcsRUFDZCxlQUFlLEVBQUUsT0FBTyxFQUN4QixRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLHVCQUF1QixHQUFHLDJCQUEyQixDQUFDLEVBQ2hGLHdCQUF3QixDQUFDLEVBQUUsTUFBTSxNQUFNLEVBQUUsR0FDeEMsZUFBZSxDQTJIakI7SUFFSyxtQkFBbUIsQ0FDdkIsUUFBUSxFQUFFLGFBQWEsRUFDdkIsY0FBYyxFQUFFLE1BQU0sRUFDdEIsZUFBZSxFQUFFLE9BQU8sR0FDdkIsT0FBTyxDQUFDLDZCQUE2QixDQUFDLENBeUt4QztZQUVhLHNCQUFzQjtZQW9CdEIsY0FBYztZQTJDZCw0QkFBNEI7SUFnRDFDLE9BQU8sQ0FBQyx1QkFBdUI7SUEwQy9COzs7O09BSUc7SUFDSCxPQUFPLENBQUMsaUNBQWlDO0lBNEV6Qzs7Ozs7T0FLRztJQUNILE9BQU8sQ0FBQyxzQkFBc0I7SUFJOUIsT0FBTyxDQUFDLHlCQUF5QjtJQWdCM0IscUJBQXFCLENBQ3pCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLFdBQVcsRUFBRSxXQUFXLEVBQ3hCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQ1QsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQiwyQkFBMkIsRUFBRSxFQUFFLEVBQUUsR0FDaEMsT0FBTyxDQUFDLDJCQUEyQixDQUFDLENBbUh0QztJQUVEOzs7O09BSUc7SUFDRyx3QkFBd0IsQ0FDNUIsUUFBUSxFQUFFLHNCQUFzQixFQUNoQyxZQUFZLEVBQUUsT0FBTyxHQUNwQixPQUFPLENBQUMsa0NBQWtDLENBQUMsQ0FpRDdDO0lBRUQ7OztPQUdHO0lBQ0csMEJBQTBCLENBQzlCLFFBQVEsRUFBRSxzQkFBc0IsRUFDaEMsWUFBWSxFQUFFLE9BQU8sR0FDcEIsT0FBTyxDQUFDLGtDQUFrQyxDQUFDLENBb0w3QztJQUVELHlEQUF5RDtJQUN6RCxPQUFPLENBQUMsMEJBQTBCO0lBYWxDLDZGQUE2RjtJQUM3RixTQUFTLENBQUMsMkJBQTJCLENBQUMsUUFBUSxFQUFFLHNCQUFzQixFQUFFLFlBQVksRUFBRSxPQUFPLEdBQUcsSUFBSSxDQUluRztJQUVELHVEQUF1RDtJQUN2RCxVQUFnQix3QkFBd0IsQ0FBQyxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsWUFBWSxFQUFFLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBeUIvRztZQU9hLHFCQUFxQjtDQXNCcEMifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proposal_handler.d.ts","sourceRoot":"","sources":["../src/proposal_handler.ts"],"names":[],"mappings":"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"}
|