@aztec/archiver 0.0.1-commit.993d240 → 0.0.1-commit.9a89641
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/dest/archiver.d.ts +44 -8
- package/dest/archiver.d.ts.map +1 -1
- package/dest/archiver.js +103 -35
- package/dest/config.d.ts +5 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +28 -7
- package/dest/factory.d.ts +8 -1
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +41 -5
- package/dest/l1/calldata_retriever.d.ts +8 -1
- package/dest/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/l1/calldata_retriever.js +7 -6
- package/dest/l1/data_retrieval.d.ts +7 -2
- package/dest/l1/data_retrieval.d.ts.map +1 -1
- package/dest/modules/contract_data_source_adapter.d.ts +2 -2
- package/dest/modules/contract_data_source_adapter.d.ts.map +1 -1
- package/dest/modules/contract_data_source_adapter.js +1 -9
- package/dest/modules/data_source_base.d.ts +5 -6
- package/dest/modules/data_source_base.d.ts.map +1 -1
- package/dest/modules/data_source_base.js +9 -38
- package/dest/modules/data_store_updater.d.ts +1 -1
- package/dest/modules/data_store_updater.d.ts.map +1 -1
- package/dest/modules/data_store_updater.js +4 -3
- package/dest/modules/instrumentation.d.ts +9 -1
- package/dest/modules/instrumentation.d.ts.map +1 -1
- package/dest/modules/instrumentation.js +23 -2
- package/dest/modules/l1_synchronizer.d.ts +3 -3
- package/dest/modules/l1_synchronizer.d.ts.map +1 -1
- package/dest/modules/l1_synchronizer.js +78 -41
- package/dest/modules/outbox_trees_resolver.d.ts +64 -0
- package/dest/modules/outbox_trees_resolver.d.ts.map +1 -0
- package/dest/modules/outbox_trees_resolver.js +184 -0
- package/dest/modules/validation.d.ts +29 -7
- package/dest/modules/validation.d.ts.map +1 -1
- package/dest/modules/validation.js +31 -13
- package/dest/store/block_store.d.ts +26 -22
- package/dest/store/block_store.d.ts.map +1 -1
- package/dest/store/block_store.js +105 -78
- package/dest/store/contract_class_store.d.ts +1 -1
- package/dest/store/contract_class_store.d.ts.map +1 -1
- package/dest/store/contract_class_store.js +19 -1
- package/dest/store/contract_instance_store.d.ts +1 -1
- package/dest/store/contract_instance_store.d.ts.map +1 -1
- package/dest/store/contract_instance_store.js +18 -1
- package/dest/store/log_store.d.ts +1 -1
- package/dest/store/log_store.d.ts.map +1 -1
- package/dest/store/log_store.js +3 -3
- package/dest/store/log_store_codec.d.ts +9 -1
- package/dest/store/log_store_codec.d.ts.map +1 -1
- package/dest/store/log_store_codec.js +9 -0
- package/dest/test/fake_l1_state.js +3 -3
- package/dest/test/mock_l1_to_l2_message_source.d.ts +1 -1
- package/dest/test/mock_l1_to_l2_message_source.d.ts.map +1 -1
- package/dest/test/mock_l1_to_l2_message_source.js +1 -2
- package/dest/test/mock_l2_block_source.d.ts +4 -11
- package/dest/test/mock_l2_block_source.d.ts.map +1 -1
- package/dest/test/mock_l2_block_source.js +15 -39
- package/dest/test/mock_structs.d.ts +1 -1
- package/dest/test/mock_structs.d.ts.map +1 -1
- package/dest/test/mock_structs.js +2 -2
- package/dest/test/noop_l1_archiver.d.ts +8 -3
- package/dest/test/noop_l1_archiver.d.ts.map +1 -1
- package/dest/test/noop_l1_archiver.js +12 -9
- package/package.json +13 -13
- package/src/archiver.ts +147 -42
- package/src/config.ts +34 -16
- package/src/factory.ts +48 -4
- package/src/l1/calldata_retriever.ts +13 -6
- package/src/l1/data_retrieval.ts +8 -1
- package/src/modules/contract_data_source_adapter.ts +1 -10
- package/src/modules/data_source_base.ts +17 -44
- package/src/modules/data_store_updater.ts +4 -3
- package/src/modules/instrumentation.ts +15 -2
- package/src/modules/l1_synchronizer.ts +120 -57
- package/src/modules/outbox_trees_resolver.ts +220 -0
- package/src/modules/validation.ts +71 -15
- package/src/store/block_store.ts +108 -101
- package/src/store/contract_class_store.ts +19 -1
- package/src/store/contract_instance_store.ts +18 -1
- package/src/store/log_store.ts +3 -2
- package/src/store/log_store_codec.ts +11 -0
- package/src/test/fake_l1_state.ts +3 -3
- package/src/test/mock_l1_to_l2_message_source.ts +0 -1
- package/src/test/mock_l2_block_source.ts +14 -53
- package/src/test/mock_structs.ts +5 -2
- package/src/test/noop_l1_archiver.ts +30 -11
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
2
|
+
import type { ViemCommitteeAttestations } from '@aztec/ethereum/contracts';
|
|
3
|
+
import { type CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import type { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
5
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
|
-
import { type AttestationInfo, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
4
|
-
import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
6
|
+
import { type AttestationInfo, type CommitteeAttestation, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
7
|
+
import type { CheckpointInfo, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
5
8
|
import { type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
6
|
-
import { type CoordinationSignatureContext } from '@aztec/stdlib/p2p';
|
|
9
|
+
import { ConsensusPayload, type CoordinationSignatureContext } from '@aztec/stdlib/p2p';
|
|
10
|
+
import type { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
7
11
|
export type { ValidateCheckpointResult };
|
|
8
12
|
/**
|
|
9
13
|
* Extracts attestation information from a published checkpoint.
|
|
10
14
|
* Returns info for each attestation, preserving array indices.
|
|
11
15
|
*/
|
|
12
16
|
export declare function getAttestationInfoFromPublishedCheckpoint({ checkpoint, attestations }: PublishedCheckpoint, signatureContext: CoordinationSignatureContext): AttestationInfo[];
|
|
17
|
+
/** The subset of a calldata-only checkpoint needed to validate its committee attestations. */
|
|
18
|
+
export type CalldataCheckpointForAttestations = {
|
|
19
|
+
checkpointNumber: CheckpointNumber;
|
|
20
|
+
archiveRoot: Fr;
|
|
21
|
+
feeAssetPriceModifier: bigint;
|
|
22
|
+
header: CheckpointHeader;
|
|
23
|
+
attestations: CommitteeAttestation[];
|
|
24
|
+
/** The exact packed attestations tuple from L1 calldata, carried verbatim for byte-faithful invalidation. */
|
|
25
|
+
verbatimAttestations: ViemCommitteeAttestations;
|
|
26
|
+
};
|
|
13
27
|
/**
|
|
14
|
-
* Validates the attestations
|
|
15
|
-
*
|
|
28
|
+
* Validates the attestations of a checkpoint from L1 calldata only, without fetching or decoding its blobs.
|
|
29
|
+
* The signed consensus payload (header, archive root, fee asset price modifier) is fully available from
|
|
30
|
+
* calldata, so an invalid-attestation checkpoint can be rejected before any (possibly malformed) blob is
|
|
31
|
+
* fetched and decoded.
|
|
16
32
|
*/
|
|
17
|
-
export declare function
|
|
18
|
-
|
|
33
|
+
export declare function validateCheckpointAttestationsFromCalldata(checkpoint: CalldataCheckpointForAttestations, epochCache: EpochCache, constants: Pick<L1RollupConstants, 'epochDuration'>, signatureContext: CoordinationSignatureContext, logger?: Logger): Promise<ValidateCheckpointResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Core attestation validation over a consensus payload, its attestations, and checkpoint metadata --
|
|
36
|
+
* independent of whether the checkpoint's blocks have been decoded from blobs. Returns true if the
|
|
37
|
+
* attestations are valid and sufficient, false otherwise.
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateAttestations(payload: ConsensusPayload, attestations: CommitteeAttestation[], verbatimAttestations: ViemCommitteeAttestations, checkpointInfo: CheckpointInfo, epochCache: EpochCache, constants: Pick<L1RollupConstants, 'epochDuration'>, logger?: Logger): Promise<ValidateCheckpointResult>;
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21vZHVsZXMvdmFsaWRhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzNFLE9BQU8sRUFBRSxLQUFLLGdCQUFnQixFQUFlLE1BQU0saUNBQWlDLENBQUM7QUFFckYsT0FBTyxLQUFLLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDekQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDcEQsT0FBTyxFQUNMLEtBQUssZUFBZSxFQUNwQixLQUFLLG9CQUFvQixFQUV6QixLQUFLLHdCQUF3QixFQUU5QixNQUFNLHFCQUFxQixDQUFDO0FBQzdCLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxLQUFLLGlCQUFpQixFQUFpQyxNQUFNLDZCQUE2QixDQUFDO0FBQ3BHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxLQUFLLDRCQUE0QixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDeEYsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUU3RCxZQUFZLEVBQUUsd0JBQXdCLEVBQUUsQ0FBQztBQUV6Qzs7O0dBR0c7QUFDSCx3QkFBZ0IseUNBQXlDLENBQ3ZELEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxFQUFFLG1CQUFtQixFQUNqRCxnQkFBZ0IsRUFBRSw0QkFBNEIsR0FDN0MsZUFBZSxFQUFFLENBR25CO0FBRUQsOEZBQThGO0FBQzlGLE1BQU0sTUFBTSxpQ0FBaUMsR0FBRztJQUM5QyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztJQUNuQyxXQUFXLEVBQUUsRUFBRSxDQUFDO0lBQ2hCLHFCQUFxQixFQUFFLE1BQU0sQ0FBQztJQUM5QixNQUFNLEVBQUUsZ0JBQWdCLENBQUM7SUFDekIsWUFBWSxFQUFFLG9CQUFvQixFQUFFLENBQUM7SUFDckMsNkdBQTZHO0lBQzdHLG9CQUFvQixFQUFFLHlCQUF5QixDQUFDO0NBQ2pELENBQUM7QUFFRjs7Ozs7R0FLRztBQUNILHdCQUFnQiwwQ0FBMEMsQ0FDeEQsVUFBVSxFQUFFLGlDQUFpQyxFQUM3QyxVQUFVLEVBQUUsVUFBVSxFQUN0QixTQUFTLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixFQUFFLGVBQWUsQ0FBQyxFQUNuRCxnQkFBZ0IsRUFBRSw0QkFBNEIsRUFDOUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxHQUNkLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQXVCbkM7QUFFRDs7OztHQUlHO0FBQ0gsd0JBQXNCLG9CQUFvQixDQUN4QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQ3pCLFlBQVksRUFBRSxvQkFBb0IsRUFBRSxFQUNwQyxvQkFBb0IsRUFBRSx5QkFBeUIsRUFDL0MsY0FBYyxFQUFFLGNBQWMsRUFDOUIsVUFBVSxFQUFFLFVBQVUsRUFDdEIsU0FBUyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLENBQUMsRUFDbkQsTUFBTSxDQUFDLEVBQUUsTUFBTSxHQUNkLE9BQU8sQ0FBQyx3QkFBd0IsQ0FBQyxDQTRGbkMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/modules/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/modules/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,KAAK,gBAAgB,EAAe,MAAM,iCAAiC,CAAC;AAErF,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EAEzB,KAAK,wBAAwB,EAE9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpF,OAAO,EAAE,KAAK,iBAAiB,EAAiC,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,KAAK,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AACxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,yCAAyC,CACvD,EAAE,UAAU,EAAE,YAAY,EAAE,EAAE,mBAAmB,EACjD,gBAAgB,EAAE,4BAA4B,GAC7C,eAAe,EAAE,CAGnB;AAED,8FAA8F;AAC9F,MAAM,MAAM,iCAAiC,GAAG;IAC9C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,WAAW,EAAE,EAAE,CAAC;IAChB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,oBAAoB,EAAE,CAAC;IACrC,6GAA6G;IAC7G,oBAAoB,EAAE,yBAAyB,CAAC;CACjD,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,0CAA0C,CACxD,UAAU,EAAE,iCAAiC,EAC7C,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EACnD,gBAAgB,EAAE,4BAA4B,EAC9C,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAuBnC;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,oBAAoB,EAAE,EACpC,oBAAoB,EAAE,yBAAyB,EAC/C,cAAc,EAAE,cAAc,EAC9B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,EACnD,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CA4FnC"}
|
|
@@ -10,25 +10,42 @@ import { ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
|
10
10
|
return getAttestationInfoFromPayload(payload, attestations);
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
|
-
* Validates the attestations
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
* Validates the attestations of a checkpoint from L1 calldata only, without fetching or decoding its blobs.
|
|
14
|
+
* The signed consensus payload (header, archive root, fee asset price modifier) is fully available from
|
|
15
|
+
* calldata, so an invalid-attestation checkpoint can be rejected before any (possibly malformed) blob is
|
|
16
|
+
* fetched and decoded.
|
|
17
|
+
*/ export function validateCheckpointAttestationsFromCalldata(checkpoint, epochCache, constants, signatureContext, logger) {
|
|
18
|
+
const payload = new ConsensusPayload(checkpoint.header, checkpoint.archiveRoot, checkpoint.feeAssetPriceModifier, signatureContext);
|
|
19
|
+
const checkpointInfo = {
|
|
20
|
+
archive: checkpoint.archiveRoot,
|
|
21
|
+
lastArchive: checkpoint.header.lastArchiveRoot,
|
|
22
|
+
slotNumber: checkpoint.header.slotNumber,
|
|
23
|
+
checkpointNumber: checkpoint.checkpointNumber,
|
|
24
|
+
timestamp: checkpoint.header.timestamp
|
|
25
|
+
};
|
|
26
|
+
return validateAttestations(payload, checkpoint.attestations, checkpoint.verbatimAttestations, checkpointInfo, epochCache, constants, logger);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Core attestation validation over a consensus payload, its attestations, and checkpoint metadata --
|
|
30
|
+
* independent of whether the checkpoint's blocks have been decoded from blobs. Returns true if the
|
|
31
|
+
* attestations are valid and sufficient, false otherwise.
|
|
32
|
+
*/ export async function validateAttestations(payload, attestations, verbatimAttestations, checkpointInfo, epochCache, constants, logger) {
|
|
33
|
+
const attestorInfos = getAttestationInfoFromPayload(payload, attestations);
|
|
17
34
|
const attestors = compactArray(attestorInfos.map((info)=>'address' in info ? info.address : undefined));
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
35
|
+
const headerHash = payload.header.hash();
|
|
36
|
+
const archiveRoot = payload.archive.toString();
|
|
37
|
+
const slot = payload.header.slotNumber;
|
|
38
|
+
const checkpointNumber = checkpointInfo.checkpointNumber;
|
|
22
39
|
const epoch = getEpochAtSlot(slot, constants);
|
|
23
40
|
const { committee, seed } = await epochCache.getCommitteeForEpoch(epoch);
|
|
24
41
|
const logData = {
|
|
25
|
-
checkpointNumber
|
|
42
|
+
checkpointNumber,
|
|
26
43
|
slot,
|
|
27
44
|
epoch,
|
|
28
45
|
headerHash,
|
|
29
46
|
archiveRoot
|
|
30
47
|
};
|
|
31
|
-
logger?.debug(`Validating attestations for checkpoint ${
|
|
48
|
+
logger?.debug(`Validating attestations for checkpoint ${checkpointNumber} at slot ${slot} in epoch ${epoch}`, {
|
|
32
49
|
committee: (committee ?? []).map((member)=>member.toString()),
|
|
33
50
|
recoveredAttestors: attestorInfos,
|
|
34
51
|
postedAttestations: attestations.map((a)=>(a.address.isZero() ? a.signature : a.address).toString()),
|
|
@@ -50,12 +67,13 @@ import { ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
|
50
67
|
const failedValidationResult = (reason)=>({
|
|
51
68
|
valid: false,
|
|
52
69
|
reason,
|
|
53
|
-
checkpoint:
|
|
70
|
+
checkpoint: checkpointInfo,
|
|
54
71
|
committee,
|
|
55
72
|
seed,
|
|
56
73
|
epoch,
|
|
57
74
|
attestors,
|
|
58
|
-
attestations
|
|
75
|
+
attestations,
|
|
76
|
+
verbatimAttestations
|
|
59
77
|
});
|
|
60
78
|
for(let i = 0; i < attestorInfos.length; i++){
|
|
61
79
|
const info = attestorInfos[i];
|
|
@@ -97,7 +115,7 @@ import { ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
|
97
115
|
});
|
|
98
116
|
return failedValidationResult('insufficient-attestations');
|
|
99
117
|
}
|
|
100
|
-
logger?.debug(`Checkpoint attestations validated successfully for checkpoint ${
|
|
118
|
+
logger?.debug(`Checkpoint attestations validated successfully for checkpoint ${checkpointNumber} at slot ${slot}`, logData);
|
|
101
119
|
return {
|
|
102
120
|
valid: true
|
|
103
121
|
};
|
|
@@ -4,9 +4,8 @@ import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
|
4
4
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
5
5
|
import { type BlockData, BlockHash, CommitteeAttestation, L2Block, type L2Tips, type ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
6
6
|
import { type CheckpointData, type CommonCheckpointData, L1PublishedData, type ProposedCheckpointData, type ProposedCheckpointInput, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
7
|
-
import { type
|
|
8
|
-
|
|
9
|
-
export { TxReceipt, type TxEffect, type TxHash } from '@aztec/stdlib/tx';
|
|
7
|
+
import { type IndexedTxEffect, TxHash } from '@aztec/stdlib/tx';
|
|
8
|
+
export type { TxEffect, TxHash, TxReceipt } from '@aztec/stdlib/tx';
|
|
10
9
|
/** Reason a checkpoint was rejected during sync. */
|
|
11
10
|
export type RejectedCheckpointReason = 'invalid-attestations' | 'descends-from-invalid-attestations';
|
|
12
11
|
/**
|
|
@@ -80,12 +79,15 @@ export declare class BlockStore {
|
|
|
80
79
|
}): Promise<boolean>;
|
|
81
80
|
/**
|
|
82
81
|
* Append new checkpoints to the store's list.
|
|
82
|
+
* Checkpoints at the start of the batch that are already stored (e.g. re-included by an L1 reorg)
|
|
83
|
+
* are accepted if their archive root matches: their L1 metadata is updated but they are not
|
|
84
|
+
* re-inserted, and they are excluded from the returned array.
|
|
83
85
|
* @param checkpoints - The L2 checkpoints to be added to the store.
|
|
84
|
-
* @returns
|
|
86
|
+
* @returns The checkpoints that were actually inserted (excluding already-stored ones).
|
|
85
87
|
*/
|
|
86
88
|
addCheckpoints(checkpoints: PublishedCheckpoint[], opts?: {
|
|
87
89
|
force?: boolean;
|
|
88
|
-
}): Promise<
|
|
90
|
+
}): Promise<PublishedCheckpoint[]>;
|
|
89
91
|
private skipOrUpdateAlreadyStoredCheckpoints;
|
|
90
92
|
private getPreviousCheckpointBlock;
|
|
91
93
|
/**
|
|
@@ -96,6 +98,7 @@ export declare class BlockStore {
|
|
|
96
98
|
private validateCheckpointBlocks;
|
|
97
99
|
private addBlockToDatabase;
|
|
98
100
|
private deleteBlock;
|
|
101
|
+
private deleteTxEffect;
|
|
99
102
|
/**
|
|
100
103
|
* Removes all checkpoints with checkpoint number > checkpointNumber.
|
|
101
104
|
* Also removes ALL blocks (both checkpointed and uncheckpointed) after the last block of the given checkpoint.
|
|
@@ -104,6 +107,13 @@ export declare class BlockStore {
|
|
|
104
107
|
removeCheckpointsAfter(checkpointNumber: CheckpointNumber): Promise<RemoveCheckpointsResult>;
|
|
105
108
|
getCheckpointData(checkpointNumber: CheckpointNumber): Promise<CheckpointData | undefined>;
|
|
106
109
|
getRangeOfCheckpoints(from: CheckpointNumber, limit: number): Promise<CheckpointData[]>;
|
|
110
|
+
/**
|
|
111
|
+
* Returns up to `limit` checkpoints anchored at `fromSlot`, ordered nearest-first, walking the slot index.
|
|
112
|
+
* With `reverse`, takes the checkpoints at or before `fromSlot` (descending by slot); otherwise the
|
|
113
|
+
* checkpoints at or after it (ascending). `limit: 1, reverse: true` yields the latest checkpoint at or
|
|
114
|
+
* before the slot in a single range scan.
|
|
115
|
+
*/
|
|
116
|
+
getCheckpointsBySlot(fromSlot: SlotNumber, limit: number, reverse: boolean): Promise<CheckpointData[]>;
|
|
107
117
|
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */
|
|
108
118
|
getCheckpointDataForSlotRange(startSlot: SlotNumber, endSlot: SlotNumber): Promise<CheckpointData[]>;
|
|
109
119
|
/**
|
|
@@ -202,12 +212,6 @@ export declare class BlockStore {
|
|
|
202
212
|
* @returns The requested tx effect with block info (or undefined if not found).
|
|
203
213
|
*/
|
|
204
214
|
getTxEffect(txHash: TxHash): Promise<IndexedTxEffect | undefined>;
|
|
205
|
-
/**
|
|
206
|
-
* Gets a receipt of a settled tx.
|
|
207
|
-
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
208
|
-
* @returns The requested tx receipt (or undefined if not found).
|
|
209
|
-
*/
|
|
210
|
-
getSettledTxReceipt(txHash: TxHash, l1Constants?: Pick<L1RollupConstants, 'epochDuration'>): Promise<TxReceipt | undefined>;
|
|
211
215
|
/**
|
|
212
216
|
* Looks up which block included the requested tx effect.
|
|
213
217
|
* @param txHash - The txHash of the tx.
|
|
@@ -221,8 +225,9 @@ export declare class BlockStore {
|
|
|
221
225
|
* attach effect data on demand without paying for a full {@link TxEffect} deserialization.
|
|
222
226
|
*
|
|
223
227
|
* The on-disk `IndexedTxEffect` layout starts with a fixed-length header
|
|
224
|
-
* (`blockHash(32) + l2BlockNumber(4) + txIndexInBlock(4) +
|
|
225
|
-
*
|
|
228
|
+
* (`blockHash(32) + l2BlockNumber(4) + txIndexInBlock(4) + slotNumber(4) + revertCode(1) + txHash(32) +
|
|
229
|
+
* transactionFee(32)` = 109 bytes), followed by `noteHashes` and `nullifiers` (both u8-length-prefixed `Fr`
|
|
230
|
+
* vectors). We
|
|
226
231
|
* skip the header, then read the two vectors, and stop — the large tail (`l2ToL1Msgs`,
|
|
227
232
|
* `publicDataWrites`, `privateLogs`, `publicLogs`, `contractClassLogs`) is never touched.
|
|
228
233
|
*/
|
|
@@ -240,14 +245,13 @@ export declare class BlockStore {
|
|
|
240
245
|
getCheckpointedL2BlockNumber(): Promise<BlockNumber>;
|
|
241
246
|
getLatestL2BlockNumber(): Promise<BlockNumber>;
|
|
242
247
|
/**
|
|
243
|
-
* Resolves all
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* back to checkpointed when no pending checkpoint exists).
|
|
248
|
+
* Resolves all four L2 chain tips (proposed, checkpointed, proven, finalized) in a single
|
|
249
|
+
* read-only transaction so the snapshot is internally consistent. Each underlying record is
|
|
250
|
+
* read at most once: latest block and latest confirmed checkpoint are loaded directly (no
|
|
251
|
+
* separate "find the number, then look up data" hop), the proven/finalized checkpoint
|
|
252
|
+
* singletons are read once and their storage entries are reused if they coincide with the
|
|
253
|
+
* latest checkpoint, and per-tip block hashes are deduped when two tips land on the same block
|
|
254
|
+
* (e.g. finalized == proven).
|
|
251
255
|
*
|
|
252
256
|
* The result is guaranteed to satisfy `finalized <= proven <= checkpointed <= proposed` (by
|
|
253
257
|
* block number). Genesis is represented by `(INITIAL_L2_BLOCK_NUM - 1)` and the supplied
|
|
@@ -297,4 +301,4 @@ export declare class BlockStore {
|
|
|
297
301
|
private advanceSynchedL1BlockNumber;
|
|
298
302
|
private rejectedCheckpointFromStorage;
|
|
299
303
|
}
|
|
300
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
304
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfc3RvcmUuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9ibG9ja19zdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUF5QixVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuSCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNcEQsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQTZDLE1BQU0saUJBQWlCLENBQUM7QUFDcEcsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDaEUsT0FBTyxFQUNMLEtBQUssU0FBUyxFQUNkLFNBQVMsRUFFVCxvQkFBb0IsRUFFcEIsT0FBTyxFQUVQLEtBQUssTUFBTSxFQUNYLEtBQUssd0JBQXdCLEVBRzlCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUVMLEtBQUssY0FBYyxFQUNuQixLQUFLLG9CQUFvQixFQUN6QixlQUFlLEVBQ2YsS0FBSyxzQkFBc0IsRUFDM0IsS0FBSyx1QkFBdUIsRUFDNUIsbUJBQW1CLEVBQ3BCLE1BQU0sMEJBQTBCLENBQUM7QUFHbEMsT0FBTyxFQUVMLEtBQUssZUFBZSxFQUVwQixNQUFNLEVBR1AsTUFBTSxrQkFBa0IsQ0FBQztBQW1CMUIsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFZcEUsb0RBQW9EO0FBQ3BELE1BQU0sTUFBTSx3QkFBd0IsR0FBRyxzQkFBc0IsR0FBRyxvQ0FBb0MsQ0FBQztBQUVyRzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxNQUFNLGtCQUFrQixHQUFHO0lBQy9CLCtDQUErQztJQUMvQyxnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztJQUNuQywwR0FBMEc7SUFDMUcsV0FBVyxFQUFFLEVBQUUsQ0FBQztJQUNoQixrRkFBa0Y7SUFD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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../src/store/block_store.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAyB,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACnH,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAMpD,OAAO,KAAK,EAAE,iBAAiB,EAA6C,MAAM,iBAAiB,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EACL,KAAK,SAAS,EACd,SAAS,EAET,oBAAoB,EAEpB,OAAO,EAEP,KAAK,MAAM,EACX,KAAK,wBAAwB,EAG9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,uBAAuB,EAC5B,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"block_store.d.ts","sourceRoot":"","sources":["../../src/store/block_store.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,12 +8,10 @@ import { bufferToHex } from '@aztec/foundation/string';
|
|
|
8
8
|
import { isDefined } from '@aztec/foundation/types';
|
|
9
9
|
import { BlockHash, Body, CommitteeAttestation, GENESIS_CHECKPOINT_HEADER_HASH, L2Block, deserializeValidateCheckpointResult, serializeValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
10
10
|
import { Checkpoint, L1PublishedData } from '@aztec/stdlib/checkpoint';
|
|
11
|
-
import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers';
|
|
12
11
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
13
12
|
import { AppendOnlyTreeSnapshot } from '@aztec/stdlib/trees';
|
|
14
|
-
import { BlockHeader, TxHash,
|
|
13
|
+
import { BlockHeader, TxHash, deserializeIndexedTxEffect, serializeIndexedTxEffect } from '@aztec/stdlib/tx';
|
|
15
14
|
import { BlockAlreadyCheckpointedError, BlockArchiveNotConsistentError, BlockCheckpointNumberNotSequentialError, BlockIndexNotSequentialError, BlockNotFoundError, BlockNumberNotSequentialError, CannotOverwriteCheckpointedBlockError, CheckpointNotFoundError, CheckpointNumberNotSequentialError, InitialCheckpointNumberNotSequentialError, NoProposedCheckpointToPromoteError, ProposedCheckpointArchiveRootMismatchError, ProposedCheckpointNotSequentialError, ProposedCheckpointPromotionNotSequentialError } from '../errors.js';
|
|
16
|
-
export { TxReceipt } from '@aztec/stdlib/tx';
|
|
17
15
|
/**
|
|
18
16
|
* LMDB-based block storage for the archiver.
|
|
19
17
|
*/ export class BlockStore {
|
|
@@ -137,11 +135,14 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
137
135
|
}
|
|
138
136
|
/**
|
|
139
137
|
* Append new checkpoints to the store's list.
|
|
138
|
+
* Checkpoints at the start of the batch that are already stored (e.g. re-included by an L1 reorg)
|
|
139
|
+
* are accepted if their archive root matches: their L1 metadata is updated but they are not
|
|
140
|
+
* re-inserted, and they are excluded from the returned array.
|
|
140
141
|
* @param checkpoints - The L2 checkpoints to be added to the store.
|
|
141
|
-
* @returns
|
|
142
|
+
* @returns The checkpoints that were actually inserted (excluding already-stored ones).
|
|
142
143
|
*/ async addCheckpoints(checkpoints, opts = {}) {
|
|
143
144
|
if (checkpoints.length === 0) {
|
|
144
|
-
return
|
|
145
|
+
return [];
|
|
145
146
|
}
|
|
146
147
|
return await this.db.transactionAsync(async ()=>{
|
|
147
148
|
const firstCheckpointNumber = checkpoints[0].checkpoint.number;
|
|
@@ -152,7 +153,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
152
153
|
if (!opts.force && firstCheckpointNumber <= previousCheckpointNumber) {
|
|
153
154
|
checkpoints = await this.skipOrUpdateAlreadyStoredCheckpoints(checkpoints, previousCheckpointNumber);
|
|
154
155
|
if (checkpoints.length === 0) {
|
|
155
|
-
return
|
|
156
|
+
return [];
|
|
156
157
|
}
|
|
157
158
|
// Re-check sequentiality after skipping
|
|
158
159
|
const newFirstNumber = checkpoints[0].checkpoint.number;
|
|
@@ -199,7 +200,7 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
199
200
|
await this.removeRejectedCheckpointByArchiveRoot(checkpoint.checkpoint.archive.root);
|
|
200
201
|
}
|
|
201
202
|
await this.advanceSynchedL1BlockNumber(checkpoints[checkpoints.length - 1].l1.blockNumber);
|
|
202
|
-
return
|
|
203
|
+
return checkpoints;
|
|
203
204
|
});
|
|
204
205
|
}
|
|
205
206
|
/**
|
|
@@ -302,7 +303,8 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
302
303
|
data: block.body.txEffects[i],
|
|
303
304
|
l2BlockNumber: block.number,
|
|
304
305
|
l2BlockHash: blockHash,
|
|
305
|
-
txIndexInBlock: i
|
|
306
|
+
txIndexInBlock: i,
|
|
307
|
+
slotNumber: block.header.globalVariables.slotNumber
|
|
306
308
|
};
|
|
307
309
|
await this.#txEffects.set(txEffect.data.txHash.toString(), serializeIndexedTxEffect(txEffect));
|
|
308
310
|
}
|
|
@@ -311,17 +313,51 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
311
313
|
await this.#blockHashIndex.set(blockHash.toString(), block.number);
|
|
312
314
|
await this.#blockArchiveIndex.set(block.archive.root.toString(), block.number);
|
|
313
315
|
}
|
|
314
|
-
/** Deletes a block and all associated data (tx effects, indices). */ async deleteBlock(
|
|
316
|
+
/** Deletes a block and all associated data (tx effects, indices). */ async deleteBlock(blockNumber, blockStorage) {
|
|
315
317
|
// Delete the block from the main blocks map
|
|
316
|
-
await this.#blocks.delete(
|
|
317
|
-
|
|
318
|
-
|
|
318
|
+
await this.#blocks.delete(blockNumber);
|
|
319
|
+
const blockHash = bufferToHex(blockStorage.blockHash);
|
|
320
|
+
// Delete the tx effects of the block's txs, skipping entries that no longer point at this block: if
|
|
321
|
+
// another stored block also contains the tx, the entry points at that block, and deleting it here would
|
|
322
|
+
// orphan that block's index. Honest chains never store the same tx twice (duplicate nullifiers are
|
|
323
|
+
// rejected at build, re-execution, and world-state sync), so the store must not turn such a state into
|
|
324
|
+
// corruption of the surviving block if it ever appears.
|
|
325
|
+
const blockTxsBuffer = await this.#blockTxs.getAsync(blockHash);
|
|
326
|
+
if (blockTxsBuffer !== undefined) {
|
|
327
|
+
const reader = BufferReader.asReader(blockTxsBuffer);
|
|
328
|
+
const txHashes = [];
|
|
329
|
+
while(!reader.isEmpty()){
|
|
330
|
+
txHashes.push(reader.readObject(TxHash).toString());
|
|
331
|
+
}
|
|
332
|
+
await Promise.all(txHashes.map((txHash)=>this.deleteTxEffect(txHash, blockStorage.blockHash)));
|
|
333
|
+
}
|
|
319
334
|
// Delete block txs mapping
|
|
320
|
-
const blockHash = (await block.hash()).toString();
|
|
321
335
|
await this.#blockTxs.delete(blockHash);
|
|
322
336
|
// Clean up indices
|
|
323
337
|
await this.#blockHashIndex.delete(blockHash);
|
|
324
|
-
await this.#blockArchiveIndex.delete(
|
|
338
|
+
await this.#blockArchiveIndex.delete(AppendOnlyTreeSnapshot.fromBuffer(blockStorage.archive).root.toString());
|
|
339
|
+
}
|
|
340
|
+
/** Deletes a tx effect only if it is still owned by (points at) the given block. */ async deleteTxEffect(txHash, blockHash) {
|
|
341
|
+
const stored = await this.#txEffects.getAsync(txHash);
|
|
342
|
+
if (stored === undefined) {
|
|
343
|
+
this.#log.warn(`Missing tx effect for tx ${txHash} while removing its block`, {
|
|
344
|
+
txHash,
|
|
345
|
+
blockHash: bufferToHex(blockHash)
|
|
346
|
+
});
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
// An IndexedTxEffect starts with the owning block hash (32 bytes) — see getTxLocation.
|
|
350
|
+
if (!Buffer.from(stored.buffer, stored.byteOffset, 32).equals(blockHash)) {
|
|
351
|
+
// Fires only when two stored blocks listed the same tx — a state upstream validation should make
|
|
352
|
+
// unreachable. Keep the entry (it belongs to the surviving block) but flag the duplication loudly.
|
|
353
|
+
this.#log.warn(`Tx effect for tx ${txHash} is owned by a block other than the one being removed`, {
|
|
354
|
+
txHash,
|
|
355
|
+
removedBlockHash: bufferToHex(blockHash),
|
|
356
|
+
owningBlockHash: bufferToHex(Buffer.from(stored.buffer, stored.byteOffset, 32))
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
await this.#txEffects.delete(txHash);
|
|
325
361
|
}
|
|
326
362
|
/**
|
|
327
363
|
* Removes all checkpoints with checkpoint number > checkpointNumber.
|
|
@@ -390,6 +426,31 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
390
426
|
}
|
|
391
427
|
return checkpoints;
|
|
392
428
|
}
|
|
429
|
+
/**
|
|
430
|
+
* Returns up to `limit` checkpoints anchored at `fromSlot`, ordered nearest-first, walking the slot index.
|
|
431
|
+
* With `reverse`, takes the checkpoints at or before `fromSlot` (descending by slot); otherwise the
|
|
432
|
+
* checkpoints at or after it (ascending). `limit: 1, reverse: true` yields the latest checkpoint at or
|
|
433
|
+
* before the slot in a single range scan.
|
|
434
|
+
*/ async getCheckpointsBySlot(fromSlot, limit, reverse) {
|
|
435
|
+
// The KV range bounds are direction-dependent: forward is [start, end), reverse is (start, end], so a
|
|
436
|
+
// reverse scan uses `end: fromSlot` (inclusive) with no +1 to include the checkpoint at fromSlot itself.
|
|
437
|
+
const range = reverse ? {
|
|
438
|
+
end: fromSlot,
|
|
439
|
+
reverse: true,
|
|
440
|
+
limit
|
|
441
|
+
} : {
|
|
442
|
+
start: fromSlot,
|
|
443
|
+
limit
|
|
444
|
+
};
|
|
445
|
+
const result = [];
|
|
446
|
+
for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync(range)){
|
|
447
|
+
const checkpointStorage = await this.#checkpoints.getAsync(checkpointNumber);
|
|
448
|
+
if (checkpointStorage) {
|
|
449
|
+
result.push(this.checkpointDataFromCheckpointStorage(checkpointStorage));
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return result;
|
|
453
|
+
}
|
|
393
454
|
/** Returns checkpoint data for all checkpoints whose slot falls within the given range (inclusive). */ async getCheckpointDataForSlotRange(startSlot, endSlot) {
|
|
394
455
|
const result = [];
|
|
395
456
|
for await (const [, checkpointNumber] of this.#slotToCheckpoint.entriesAsync({
|
|
@@ -477,16 +538,22 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
477
538
|
const latestBlockNumber = await this.getLatestL2BlockNumber();
|
|
478
539
|
// Iterate from blockNumber + 1 to latestBlockNumber
|
|
479
540
|
for(let bn = blockNumber + 1; bn <= latestBlockNumber; bn++){
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
});
|
|
483
|
-
if (block === undefined) {
|
|
541
|
+
const blockStorage = await this.#blocks.getAsync(bn);
|
|
542
|
+
if (blockStorage === undefined) {
|
|
484
543
|
this.#log.warn(`Cannot remove block ${bn} from the store since we don't have it`);
|
|
485
544
|
continue;
|
|
486
545
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this
|
|
546
|
+
// Load the full block for the returned list when possible, but clean up from the raw row regardless:
|
|
547
|
+
// a block whose body can no longer be fully loaded must still release its row, tx effects, and indices,
|
|
548
|
+
// or later inserts at this number leave stale tx-effect entries pointing into the new chain.
|
|
549
|
+
const block = await this.getBlockFromBlockStorage(bn, blockStorage);
|
|
550
|
+
if (block !== undefined) {
|
|
551
|
+
removedBlocks.push(block);
|
|
552
|
+
} else {
|
|
553
|
+
this.#log.warn(`Removing block ${bn} whose body could not be fully loaded`);
|
|
554
|
+
}
|
|
555
|
+
await this.deleteBlock(bn, blockStorage);
|
|
556
|
+
this.#log.debug(`Removed block ${bn} ${bufferToHex(blockStorage.blockHash)}`);
|
|
490
557
|
}
|
|
491
558
|
return removedBlocks;
|
|
492
559
|
});
|
|
@@ -788,38 +855,6 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
788
855
|
return deserializeIndexedTxEffect(buffer);
|
|
789
856
|
}
|
|
790
857
|
/**
|
|
791
|
-
* Gets a receipt of a settled tx.
|
|
792
|
-
* @param txHash - The hash of a tx we try to get the receipt for.
|
|
793
|
-
* @returns The requested tx receipt (or undefined if not found).
|
|
794
|
-
*/ async getSettledTxReceipt(txHash, l1Constants) {
|
|
795
|
-
const txEffect = await this.getTxEffect(txHash);
|
|
796
|
-
if (!txEffect) {
|
|
797
|
-
return undefined;
|
|
798
|
-
}
|
|
799
|
-
const blockNumber = BlockNumber(txEffect.l2BlockNumber);
|
|
800
|
-
// Use existing archiver methods to determine finalization level
|
|
801
|
-
const [provenBlockNumber, checkpointedBlockNumber, finalizedBlockNumber, blockData] = await Promise.all([
|
|
802
|
-
this.getProvenBlockNumber(),
|
|
803
|
-
this.getCheckpointedL2BlockNumber(),
|
|
804
|
-
this.getFinalizedL2BlockNumber(),
|
|
805
|
-
this.getBlockData({
|
|
806
|
-
number: blockNumber
|
|
807
|
-
})
|
|
808
|
-
]);
|
|
809
|
-
let status;
|
|
810
|
-
if (blockNumber <= finalizedBlockNumber) {
|
|
811
|
-
status = TxStatus.FINALIZED;
|
|
812
|
-
} else if (blockNumber <= provenBlockNumber) {
|
|
813
|
-
status = TxStatus.PROVEN;
|
|
814
|
-
} else if (blockNumber <= checkpointedBlockNumber) {
|
|
815
|
-
status = TxStatus.CHECKPOINTED;
|
|
816
|
-
} else {
|
|
817
|
-
status = TxStatus.PROPOSED;
|
|
818
|
-
}
|
|
819
|
-
const epochNumber = blockData && l1Constants ? getEpochAtSlot(blockData.header.globalVariables.slotNumber, l1Constants) : undefined;
|
|
820
|
-
return new TxReceipt(txHash, status, TxReceipt.executionResultFromRevertCode(txEffect.data.revertCode), undefined, txEffect.data.transactionFee.toBigInt(), txEffect.l2BlockHash, blockNumber, epochNumber);
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
858
|
* Looks up which block included the requested tx effect.
|
|
824
859
|
* @param txHash - The txHash of the tx.
|
|
825
860
|
* @returns The block number and index of the tx.
|
|
@@ -845,8 +880,9 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
845
880
|
* attach effect data on demand without paying for a full {@link TxEffect} deserialization.
|
|
846
881
|
*
|
|
847
882
|
* The on-disk `IndexedTxEffect` layout starts with a fixed-length header
|
|
848
|
-
* (`blockHash(32) + l2BlockNumber(4) + txIndexInBlock(4) +
|
|
849
|
-
*
|
|
883
|
+
* (`blockHash(32) + l2BlockNumber(4) + txIndexInBlock(4) + slotNumber(4) + revertCode(1) + txHash(32) +
|
|
884
|
+
* transactionFee(32)` = 109 bytes), followed by `noteHashes` and `nullifiers` (both u8-length-prefixed `Fr`
|
|
885
|
+
* vectors). We
|
|
850
886
|
* skip the header, then read the two vectors, and stop — the large tail (`l2ToL1Msgs`,
|
|
851
887
|
* `publicDataWrites`, `privateLogs`, `publicLogs`, `contractClassLogs`) is never touched.
|
|
852
888
|
*/ getNoteHashesAndNullifiers(txHashes) {
|
|
@@ -859,8 +895,9 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
859
895
|
];
|
|
860
896
|
}
|
|
861
897
|
const reader = BufferReader.asReader(buffer);
|
|
862
|
-
// Skip the fixed-length header: blockHash + l2BlockNumber + txIndexInBlock +
|
|
863
|
-
|
|
898
|
+
// Skip the fixed-length header: blockHash + l2BlockNumber + txIndexInBlock + slotNumber + revertCode +
|
|
899
|
+
// txHash + transactionFee.
|
|
900
|
+
reader.readBytes(32 + 4 + 4 + 4 + 1 + 32 + 32);
|
|
864
901
|
const noteHashes = reader.readVectorUint8Prefix(Fr);
|
|
865
902
|
const nullifiers = reader.readVectorUint8Prefix(Fr);
|
|
866
903
|
return [
|
|
@@ -895,14 +932,13 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
895
932
|
return typeof lastBlockNumber === 'number' ? BlockNumber(lastBlockNumber) : BlockNumber(INITIAL_L2_BLOCK_NUM - 1);
|
|
896
933
|
}
|
|
897
934
|
/**
|
|
898
|
-
* Resolves all
|
|
899
|
-
*
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
*
|
|
903
|
-
*
|
|
904
|
-
*
|
|
905
|
-
* back to checkpointed when no pending checkpoint exists).
|
|
935
|
+
* Resolves all four L2 chain tips (proposed, checkpointed, proven, finalized) in a single
|
|
936
|
+
* read-only transaction so the snapshot is internally consistent. Each underlying record is
|
|
937
|
+
* read at most once: latest block and latest confirmed checkpoint are loaded directly (no
|
|
938
|
+
* separate "find the number, then look up data" hop), the proven/finalized checkpoint
|
|
939
|
+
* singletons are read once and their storage entries are reused if they coincide with the
|
|
940
|
+
* latest checkpoint, and per-tip block hashes are deduped when two tips land on the same block
|
|
941
|
+
* (e.g. finalized == proven).
|
|
906
942
|
*
|
|
907
943
|
* The result is guaranteed to satisfy `finalized <= proven <= checkpointed <= proposed` (by
|
|
908
944
|
* block number). Genesis is represented by `(INITIAL_L2_BLOCK_NUM - 1)` and the supplied
|
|
@@ -932,10 +968,6 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
932
968
|
reverse: true,
|
|
933
969
|
limit: 1
|
|
934
970
|
}));
|
|
935
|
-
const [proposedCheckpointEntry] = await toArray(this.#proposedCheckpoints.entriesAsync({
|
|
936
|
-
reverse: true,
|
|
937
|
-
limit: 1
|
|
938
|
-
}));
|
|
939
971
|
const [latestCheckpointEntry] = await toArray(this.#checkpoints.entriesAsync({
|
|
940
972
|
reverse: true,
|
|
941
973
|
limit: 1
|
|
@@ -1014,26 +1046,21 @@ export { TxReceipt } from '@aztec/stdlib/tx';
|
|
|
1014
1046
|
const checkpointedTip = await buildTipFromCheckpoint(latestCheckpointEntry?.[1]);
|
|
1015
1047
|
const provenTip = await buildTipFromCheckpoint(provenCheckpoint);
|
|
1016
1048
|
const finalizedTip = await buildTipFromCheckpoint(finalizedCheckpoint);
|
|
1017
|
-
// Proposed checkpoint falls back to the checkpoint tip if it's not set. And if local storage is
|
|
1018
|
-
// inconsistent and the proposed checkpoint is behind the checkpointed tip, we patch that and
|
|
1019
|
-
// report the checkpointed tip as the proposed checkpoint to maintain the invariant.
|
|
1020
|
-
const proposedCheckpointTip = proposedCheckpointEntry === undefined || proposedCheckpointEntry[0] <= latestCheckpointNumber ? checkpointedTip : await buildTipFromCheckpoint(proposedCheckpointEntry[1]);
|
|
1021
1049
|
// A checkpointed block past the latest stored block would mean a checkpoint
|
|
1022
1050
|
// references blocks that aren't in blocks.
|
|
1023
1051
|
if (proposedBlockId.number < checkpointedTip.block.number) {
|
|
1024
1052
|
throw new Error(`Inconsistent block store: latest block ${proposedBlockId.number} is behind checkpointed block ${checkpointedTip.block.number}`);
|
|
1025
1053
|
}
|
|
1026
1054
|
// Assert that checkpoint numbers are increasing
|
|
1027
|
-
if (finalizedTip.checkpoint.number > provenTip.checkpoint.number || provenTip.checkpoint.number > checkpointedTip.checkpoint.number
|
|
1028
|
-
throw new Error(`Inconsistent checkpoint numbers in chain tips: finalized=${finalizedTip.checkpoint.number} proven=${provenTip.checkpoint.number} checkpointed=${checkpointedTip.checkpoint.number}
|
|
1055
|
+
if (finalizedTip.checkpoint.number > provenTip.checkpoint.number || provenTip.checkpoint.number > checkpointedTip.checkpoint.number) {
|
|
1056
|
+
throw new Error(`Inconsistent checkpoint numbers in chain tips: finalized=${finalizedTip.checkpoint.number} proven=${provenTip.checkpoint.number} checkpointed=${checkpointedTip.checkpoint.number}`);
|
|
1029
1057
|
}
|
|
1030
1058
|
// Assert block numbers are increasing
|
|
1031
|
-
if (finalizedTip.block.number > provenTip.block.number || provenTip.block.number > checkpointedTip.block.number || checkpointedTip.block.number >
|
|
1032
|
-
throw new Error(`Inconsistent block numbers in chain tips: finalized=${finalizedTip.block.number} proven=${provenTip.block.number} checkpointed=${checkpointedTip.block.number}
|
|
1059
|
+
if (finalizedTip.block.number > provenTip.block.number || provenTip.block.number > checkpointedTip.block.number || checkpointedTip.block.number > proposedBlockId.number) {
|
|
1060
|
+
throw new Error(`Inconsistent block numbers in chain tips: finalized=${finalizedTip.block.number} proven=${provenTip.block.number} checkpointed=${checkpointedTip.block.number} proposed=${proposedBlockId.number}`);
|
|
1033
1061
|
}
|
|
1034
1062
|
return {
|
|
1035
1063
|
proposed: proposedBlockId,
|
|
1036
|
-
proposedCheckpoint: proposedCheckpointTip,
|
|
1037
1064
|
checkpointed: checkpointedTip,
|
|
1038
1065
|
proven: provenTip,
|
|
1039
1066
|
finalized: finalizedTip
|