@aztec/archiver 3.0.0-nightly.20251213 → 3.0.0-nightly.20251216
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/archiver_store_test_suite.d.ts +1 -1
- package/dest/archiver/archiver_store_test_suite.d.ts.map +1 -1
- package/dest/archiver/archiver_store_test_suite.js +56 -7
- package/dest/archiver/kv_archiver_store/kv_archiver_store.d.ts +1 -1
- package/dest/archiver/kv_archiver_store/kv_archiver_store.js +1 -1
- package/dest/archiver/kv_archiver_store/log_store.d.ts +3 -3
- package/dest/archiver/kv_archiver_store/log_store.d.ts.map +1 -1
- package/dest/archiver/kv_archiver_store/log_store.js +39 -15
- package/dest/archiver/l1/bin/retrieve-calldata.js +2 -2
- package/dest/archiver/l1/calldata_retriever.d.ts +17 -3
- package/dest/archiver/l1/calldata_retriever.d.ts.map +1 -1
- package/dest/archiver/l1/calldata_retriever.js +75 -7
- package/dest/archiver/l1/data_retrieval.d.ts +1 -1
- package/dest/archiver/l1/data_retrieval.d.ts.map +1 -1
- package/dest/archiver/l1/data_retrieval.js +6 -1
- package/package.json +13 -13
- package/src/archiver/archiver_store_test_suite.ts +76 -7
- package/src/archiver/kv_archiver_store/kv_archiver_store.ts +1 -1
- package/src/archiver/kv_archiver_store/log_store.ts +61 -24
- package/src/archiver/l1/bin/retrieve-calldata.ts +2 -2
- package/src/archiver/l1/calldata_retriever.ts +116 -6
- package/src/archiver/l1/data_retrieval.ts +7 -0
|
@@ -5,4 +5,4 @@ import type { ArchiverDataStore } from './archiver_store.js';
|
|
|
5
5
|
* @param getStore - Returns an instance of a store that's already been initialized.
|
|
6
6
|
*/
|
|
7
7
|
export declare function describeArchiverDataStore(testName: string, getStore: () => ArchiverDataStore | Promise<ArchiverDataStore>): void;
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJjaGl2ZXJfc3RvcmVfdGVzdF9zdWl0ZS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FyY2hpdmVyL2FyY2hpdmVyX3N0b3JlX3Rlc3Rfc3VpdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBcUNBLE9BQU8sNEJBQTRCLENBQUM7QUFJcEMsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQXdCLE1BQU0scUJBQXFCLENBQUM7QUFLbkY7OztHQUdHO0FBQ0gsd0JBQWdCLHlCQUF5QixDQUN2QyxRQUFRLEVBQUUsTUFBTSxFQUNoQixRQUFRLEVBQUUsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsUUFzeEMvRCJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"archiver_store_test_suite.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver_store_test_suite.ts"],"names":[],"mappings":"AAqCA,OAAO,4BAA4B,CAAC;AAIpC,OAAO,KAAK,EAAE,iBAAiB,EAAwB,MAAM,qBAAqB,CAAC;AAKnF;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"archiver_store_test_suite.d.ts","sourceRoot":"","sources":["../../src/archiver/archiver_store_test_suite.ts"],"names":[],"mappings":"AAqCA,OAAO,4BAA4B,CAAC;AAIpC,OAAO,KAAK,EAAE,iBAAiB,EAAwB,MAAM,qBAAqB,CAAC;AAKnF;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAsxC/D"}
|
|
@@ -10,7 +10,7 @@ import { sleep } from '@aztec/foundation/sleep';
|
|
|
10
10
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
11
|
import { CommitteeAttestation, EthAddress, L2Block, L2BlockHash, PublishedL2Block, randomBlockInfo, wrapDataInBlock } from '@aztec/stdlib/block';
|
|
12
12
|
import { SerializableContractInstance, computePublicBytecodeCommitment } from '@aztec/stdlib/contract';
|
|
13
|
-
import { LogId, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
13
|
+
import { ContractClassLog, LogId, PrivateLog, PublicLog } from '@aztec/stdlib/logs';
|
|
14
14
|
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
15
15
|
import { makeContractClassPublic, makeExecutablePrivateFunctionWithMembershipProof, makeUtilityFunctionWithMembershipProof } from '@aztec/stdlib/testing';
|
|
16
16
|
import '@aztec/stdlib/testing/jest';
|
|
@@ -888,6 +888,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
888
888
|
[
|
|
889
889
|
expect.objectContaining({
|
|
890
890
|
blockNumber: 2,
|
|
891
|
+
blockHash: L2BlockHash.fromField(await blocks[2 - 1].block.hash()),
|
|
891
892
|
log: makePrivateLog(tags[0]),
|
|
892
893
|
isFromPublic: false
|
|
893
894
|
})
|
|
@@ -895,6 +896,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
895
896
|
[
|
|
896
897
|
expect.objectContaining({
|
|
897
898
|
blockNumber: 1,
|
|
899
|
+
blockHash: L2BlockHash.fromField(await blocks[1 - 1].block.hash()),
|
|
898
900
|
log: makePrivateLog(tags[1]),
|
|
899
901
|
isFromPublic: false
|
|
900
902
|
})
|
|
@@ -911,11 +913,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
911
913
|
[
|
|
912
914
|
expect.objectContaining({
|
|
913
915
|
blockNumber: 1,
|
|
916
|
+
blockHash: L2BlockHash.fromField(await blocks[1 - 1].block.hash()),
|
|
914
917
|
log: makePrivateLog(tags[0]),
|
|
915
918
|
isFromPublic: false
|
|
916
919
|
}),
|
|
917
920
|
expect.objectContaining({
|
|
918
921
|
blockNumber: 1,
|
|
922
|
+
blockHash: L2BlockHash.fromField(await blocks[1 - 1].block.hash()),
|
|
919
923
|
log: makePublicLog(tags[0]),
|
|
920
924
|
isFromPublic: true
|
|
921
925
|
})
|
|
@@ -943,11 +947,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
943
947
|
[
|
|
944
948
|
expect.objectContaining({
|
|
945
949
|
blockNumber: 1,
|
|
950
|
+
blockHash: L2BlockHash.fromField(await blocks[1 - 1].block.hash()),
|
|
946
951
|
log: makePrivateLog(tags[0]),
|
|
947
952
|
isFromPublic: false
|
|
948
953
|
}),
|
|
949
954
|
expect.objectContaining({
|
|
950
955
|
blockNumber: newBlockNumber,
|
|
956
|
+
blockHash: L2BlockHash.fromField(await blocks[newBlockNumber - 1].block.hash()),
|
|
951
957
|
log: newLog,
|
|
952
958
|
isFromPublic: false
|
|
953
959
|
})
|
|
@@ -965,6 +971,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
965
971
|
[
|
|
966
972
|
expect.objectContaining({
|
|
967
973
|
blockNumber: 1,
|
|
974
|
+
blockHash: L2BlockHash.fromField(await blocks[1 - 1].block.hash()),
|
|
968
975
|
log: makePrivateLog(tags[1]),
|
|
969
976
|
isFromPublic: false
|
|
970
977
|
})
|
|
@@ -1025,6 +1032,16 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1025
1032
|
expect(log.id.txIndex).toEqual(targetTxIndex);
|
|
1026
1033
|
}
|
|
1027
1034
|
});
|
|
1035
|
+
it('returns block hash on public log ids', async ()=>{
|
|
1036
|
+
const targetBlock = blocks[0].block;
|
|
1037
|
+
const expectedBlockHash = L2BlockHash.fromField(await targetBlock.hash());
|
|
1038
|
+
const logs = (await store.getPublicLogs({
|
|
1039
|
+
fromBlock: targetBlock.number,
|
|
1040
|
+
toBlock: targetBlock.number + 1
|
|
1041
|
+
})).logs;
|
|
1042
|
+
expect(logs.length).toBeGreaterThan(0);
|
|
1043
|
+
expect(logs.every((log)=>log.id.blockHash.equals(expectedBlockHash))).toBe(true);
|
|
1044
|
+
});
|
|
1028
1045
|
it('"fromBlock" and "toBlock" filter params are respected', async ()=>{
|
|
1029
1046
|
// Set "fromBlock" and "toBlock"
|
|
1030
1047
|
const fromBlock = 3;
|
|
@@ -1062,7 +1079,8 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1062
1079
|
const targetBlockIndex = randomInt(numBlocks);
|
|
1063
1080
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
1064
1081
|
const targetLogIndex = randomInt(numPublicLogs);
|
|
1065
|
-
const
|
|
1082
|
+
const targetBlockHash = L2BlockHash.fromField(await blocks[targetBlockIndex].block.hash());
|
|
1083
|
+
const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetBlockHash, targetTxIndex, targetLogIndex);
|
|
1066
1084
|
const response = await store.getPublicLogs({
|
|
1067
1085
|
afterLog
|
|
1068
1086
|
});
|
|
@@ -1082,7 +1100,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1082
1100
|
it('"txHash" filter param is ignored when "afterLog" is set', async ()=>{
|
|
1083
1101
|
// Get random txHash
|
|
1084
1102
|
const txHash = TxHash.random();
|
|
1085
|
-
const afterLog = new LogId(BlockNumber(1), 0, 0);
|
|
1103
|
+
const afterLog = new LogId(BlockNumber(1), L2BlockHash.random(), 0, 0);
|
|
1086
1104
|
const response = await store.getPublicLogs({
|
|
1087
1105
|
txHash,
|
|
1088
1106
|
afterLog
|
|
@@ -1129,7 +1147,7 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1129
1147
|
logs = (await store.getPublicLogs({
|
|
1130
1148
|
fromBlock: BlockNumber(2),
|
|
1131
1149
|
toBlock: BlockNumber(5),
|
|
1132
|
-
afterLog: new LogId(BlockNumber(4), 0, 0)
|
|
1150
|
+
afterLog: new LogId(BlockNumber(4), L2BlockHash.random(), 0, 0)
|
|
1133
1151
|
})).logs;
|
|
1134
1152
|
blockNumbers = new Set(logs.map((log)=>log.id.blockNumber));
|
|
1135
1153
|
expect(blockNumbers).toEqual(new Set([
|
|
@@ -1137,13 +1155,13 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1137
1155
|
]));
|
|
1138
1156
|
logs = (await store.getPublicLogs({
|
|
1139
1157
|
toBlock: BlockNumber(5),
|
|
1140
|
-
afterLog: new LogId(BlockNumber(5), 1, 0)
|
|
1158
|
+
afterLog: new LogId(BlockNumber(5), L2BlockHash.random(), 1, 0)
|
|
1141
1159
|
})).logs;
|
|
1142
1160
|
expect(logs.length).toBe(0);
|
|
1143
1161
|
logs = (await store.getPublicLogs({
|
|
1144
1162
|
fromBlock: BlockNumber(2),
|
|
1145
1163
|
toBlock: BlockNumber(5),
|
|
1146
|
-
afterLog: new LogId(BlockNumber(100), 0, 0)
|
|
1164
|
+
afterLog: new LogId(BlockNumber(100), L2BlockHash.random(), 0, 0)
|
|
1147
1165
|
})).logs;
|
|
1148
1166
|
expect(logs.length).toBe(0);
|
|
1149
1167
|
});
|
|
@@ -1152,7 +1170,8 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1152
1170
|
const targetBlockIndex = randomInt(numBlocks);
|
|
1153
1171
|
const targetTxIndex = randomInt(txsPerBlock);
|
|
1154
1172
|
const targetLogIndex = randomInt(numPublicLogs);
|
|
1155
|
-
const
|
|
1173
|
+
const targetBlockHash = L2BlockHash.fromField(await blocks[targetBlockIndex].block.hash());
|
|
1174
|
+
const afterLog = new LogId(BlockNumber(targetBlockIndex + INITIAL_L2_BLOCK_NUM), targetBlockHash, targetTxIndex, targetLogIndex);
|
|
1156
1175
|
const response = await store.getPublicLogs({
|
|
1157
1176
|
afterLog,
|
|
1158
1177
|
fromBlock: afterLog.blockNumber
|
|
@@ -1171,6 +1190,36 @@ import { MessageStoreError } from './kv_archiver_store/message_store.js';
|
|
|
1171
1190
|
}
|
|
1172
1191
|
});
|
|
1173
1192
|
});
|
|
1193
|
+
describe('getContractClassLogs', ()=>{
|
|
1194
|
+
let targetBlock;
|
|
1195
|
+
let expectedContractClassLog;
|
|
1196
|
+
beforeEach(async ()=>{
|
|
1197
|
+
await store.addBlocks(blocks);
|
|
1198
|
+
targetBlock = blocks[0].block;
|
|
1199
|
+
expectedContractClassLog = await ContractClassLog.random();
|
|
1200
|
+
targetBlock.body.txEffects.forEach((txEffect, index)=>{
|
|
1201
|
+
txEffect.contractClassLogs = index === 0 ? [
|
|
1202
|
+
expectedContractClassLog
|
|
1203
|
+
] : [];
|
|
1204
|
+
});
|
|
1205
|
+
await store.addLogs([
|
|
1206
|
+
targetBlock
|
|
1207
|
+
]);
|
|
1208
|
+
});
|
|
1209
|
+
it('returns block hash on contract class log ids', async ()=>{
|
|
1210
|
+
const result = await store.getContractClassLogs({
|
|
1211
|
+
fromBlock: targetBlock.number,
|
|
1212
|
+
toBlock: targetBlock.number + 1
|
|
1213
|
+
});
|
|
1214
|
+
expect(result.maxLogsHit).toBeFalsy();
|
|
1215
|
+
expect(result.logs).toHaveLength(1);
|
|
1216
|
+
const [{ id, log }] = result.logs;
|
|
1217
|
+
const expectedBlockHash = L2BlockHash.fromField(await targetBlock.hash());
|
|
1218
|
+
expect(id.blockHash.equals(expectedBlockHash)).toBe(true);
|
|
1219
|
+
expect(id.blockNumber).toEqual(targetBlock.number);
|
|
1220
|
+
expect(log).toEqual(expectedContractClassLog);
|
|
1221
|
+
});
|
|
1222
|
+
});
|
|
1174
1223
|
describe('pendingChainValidationStatus', ()=>{
|
|
1175
1224
|
it('should return undefined when no status is set', async ()=>{
|
|
1176
1225
|
const status = await store.getPendingChainValidationStatus();
|
|
@@ -13,7 +13,7 @@ import type { UInt64 } from '@aztec/stdlib/types';
|
|
|
13
13
|
import type { ArchiverDataStore, ArchiverL1SynchPoint } from '../archiver_store.js';
|
|
14
14
|
import type { InboxMessage } from '../structs/inbox_message.js';
|
|
15
15
|
import type { PublishedL2Block } from '../structs/published.js';
|
|
16
|
-
export declare const ARCHIVER_DB_VERSION =
|
|
16
|
+
export declare const ARCHIVER_DB_VERSION = 5;
|
|
17
17
|
export declare const MAX_FUNCTION_SIGNATURES = 1000;
|
|
18
18
|
export declare const MAX_FUNCTION_NAME_LEN = 256;
|
|
19
19
|
/**
|
|
@@ -8,7 +8,7 @@ import { ContractClassStore } from './contract_class_store.js';
|
|
|
8
8
|
import { ContractInstanceStore } from './contract_instance_store.js';
|
|
9
9
|
import { LogStore } from './log_store.js';
|
|
10
10
|
import { MessageStore } from './message_store.js';
|
|
11
|
-
export const ARCHIVER_DB_VERSION =
|
|
11
|
+
export const ARCHIVER_DB_VERSION = 5;
|
|
12
12
|
export const MAX_FUNCTION_SIGNATURES = 1000;
|
|
13
13
|
export const MAX_FUNCTION_NAME_LEN = 256;
|
|
14
14
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
2
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
3
|
-
import type
|
|
3
|
+
import { type L2Block } from '@aztec/stdlib/block';
|
|
4
4
|
import type { GetContractClassLogsResponse, GetPublicLogsResponse } from '@aztec/stdlib/interfaces/client';
|
|
5
5
|
import { type LogFilter, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
6
6
|
import type { BlockStore } from './block_store.js';
|
|
@@ -39,4 +39,4 @@ export declare class LogStore {
|
|
|
39
39
|
*/
|
|
40
40
|
getContractClassLogs(filter: LogFilter): Promise<GetContractClassLogsResponse>;
|
|
41
41
|
}
|
|
42
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
42
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nX3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXJjaGl2ZXIva3ZfYXJjaGl2ZXJfc3RvcmUvbG9nX3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUdwRCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxpQkFBaUIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsS0FBSyxPQUFPLEVBQWUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSw0QkFBNEIsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNHLE9BQU8sRUFJTCxLQUFLLFNBQVMsRUFHZCxhQUFhLEVBQ2QsTUFBTSxvQkFBb0IsQ0FBQztBQUU1QixPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVuRDs7R0FFRztBQUNILHFCQUFhLFFBQVE7O0lBU2pCLE9BQU8sQ0FBQyxFQUFFO0lBQ1YsT0FBTyxDQUFDLFVBQVU7SUFGcEIsWUFDVSxFQUFFLEVBQUUsaUJBQWlCLEVBQ3JCLFVBQVUsRUFBRSxVQUFVLEVBQzlCLGVBQWUsR0FBRSxNQUFhLEVBUS9CO0lBcUNEOzs7O09BSUc7SUFDRyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0E4RGpEO0lBZ0JELFVBQVUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQXdCOUM7SUFFRDs7Ozs7T0FLRztJQUNHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsV0FBVyxDQUFDLEVBQUUsTUFBTSxHQUFHLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBUWhGO0lBRUQ7Ozs7T0FJRztJQUNILGFBQWEsQ0FBQyxNQUFNLEVBQUUsU0FBUyxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQVEvRDtJQTZFRDs7OztPQUlHO0lBQ0gsb0JBQW9CLENBQUMsTUFBTSxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsNEJBQTRCLENBQUMsQ0FRN0U7Q0E2R0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/log_store.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"log_store.d.ts","sourceRoot":"","sources":["../../../src/archiver/kv_archiver_store/log_store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAAE,KAAK,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAC3G,OAAO,EAIL,KAAK,SAAS,EAGd,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;GAEG;AACH,qBAAa,QAAQ;;IASjB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,UAAU;IAFpB,YACU,EAAE,EAAE,iBAAiB,EACrB,UAAU,EAAE,UAAU,EAC9B,eAAe,GAAE,MAAa,EAQ/B;IAqCD;;;;OAIG;IACG,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CA8DjD;IAgBD,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB9C;IAED;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAQhF;IAED;;;;OAIG;IACH,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAQ/D;IA6ED;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,4BAA4B,CAAC,CAQ7E;CA6GF"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { INITIAL_L2_BLOCK_NUM, MAX_NOTE_HASHES_PER_TX } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
5
|
import { BufferReader, numToUInt32BE } from '@aztec/foundation/serialize';
|
|
6
|
+
import { L2BlockHash } from '@aztec/stdlib/block';
|
|
5
7
|
import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, PublicLog, TxScopedL2Log } from '@aztec/stdlib/logs';
|
|
6
8
|
/**
|
|
7
9
|
* A store for logs
|
|
@@ -24,7 +26,8 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
24
26
|
this.#contractClassLogsByBlock = db.openMap('archiver_contract_class_logs_by_block');
|
|
25
27
|
this.#logsMaxPageSize = logsMaxPageSize;
|
|
26
28
|
}
|
|
27
|
-
#extractTaggedLogs(block) {
|
|
29
|
+
async #extractTaggedLogs(block) {
|
|
30
|
+
const blockHash = L2BlockHash.fromField(await block.hash());
|
|
28
31
|
const taggedLogs = new Map();
|
|
29
32
|
const dataStartIndexForBlock = block.header.state.partial.noteHashTree.nextAvailableLeafIndex - block.body.txEffects.length * MAX_NOTE_HASHES_PER_TX;
|
|
30
33
|
block.body.txEffects.forEach((txEffect, txIndex)=>{
|
|
@@ -34,14 +37,14 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
34
37
|
const tag = log.fields[0];
|
|
35
38
|
this.#log.debug(`Found private log with tag ${tag.toString()} in block ${block.number}`);
|
|
36
39
|
const currentLogs = taggedLogs.get(tag.toString()) ?? [];
|
|
37
|
-
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
|
|
40
|
+
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, blockHash, log).toBuffer());
|
|
38
41
|
taggedLogs.set(tag.toString(), currentLogs);
|
|
39
42
|
});
|
|
40
43
|
txEffect.publicLogs.forEach((log, logIndex)=>{
|
|
41
44
|
const tag = log.fields[0];
|
|
42
45
|
this.#log.debug(`Found public log with tag ${tag.toString()} in block ${block.number}`);
|
|
43
46
|
const currentLogs = taggedLogs.get(tag.toString()) ?? [];
|
|
44
|
-
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, log).toBuffer());
|
|
47
|
+
currentLogs.push(new TxScopedL2Log(txHash, dataStartIndexForTx, logIndex, block.number, blockHash, log).toBuffer());
|
|
45
48
|
taggedLogs.set(tag.toString(), currentLogs);
|
|
46
49
|
});
|
|
47
50
|
});
|
|
@@ -51,9 +54,10 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
51
54
|
* Append new logs to the store's list.
|
|
52
55
|
* @param blocks - The blocks for which to add the logs.
|
|
53
56
|
* @returns True if the operation is successful.
|
|
54
|
-
*/ addLogs(blocks) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
+
*/ async addLogs(blocks) {
|
|
58
|
+
const taggedLogsInBlocks = await Promise.all(blocks.map((block)=>this.#extractTaggedLogs(block)));
|
|
59
|
+
const taggedLogsToAdd = taggedLogsInBlocks.reduce((acc, taggedLogs)=>{
|
|
60
|
+
for (const [tag, logs] of taggedLogs.entries()){
|
|
57
61
|
const currentLogs = acc.get(tag) ?? [];
|
|
58
62
|
acc.set(tag, currentLogs.concat(logs));
|
|
59
63
|
}
|
|
@@ -71,6 +75,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
71
75
|
}
|
|
72
76
|
});
|
|
73
77
|
for (const block of blocks){
|
|
78
|
+
const blockHash = await block.hash();
|
|
74
79
|
const tagsInBlock = [];
|
|
75
80
|
for (const [tag, logs] of taggedLogsToAdd.entries()){
|
|
76
81
|
await this.#logsByTag.set(tag, logs);
|
|
@@ -87,12 +92,25 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
87
92
|
numToUInt32BE(txEffect.contractClassLogs.length),
|
|
88
93
|
txEffect.contractClassLogs.map((log)=>log.toBuffer())
|
|
89
94
|
].flat()).flat();
|
|
90
|
-
await this.#publicLogsByBlock.set(block.number,
|
|
91
|
-
await this.#contractClassLogsByBlock.set(block.number,
|
|
95
|
+
await this.#publicLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, publicLogsInBlock));
|
|
96
|
+
await this.#contractClassLogsByBlock.set(block.number, this.#packWithBlockHash(blockHash, contractClassLogsInBlock));
|
|
92
97
|
}
|
|
93
98
|
return true;
|
|
94
99
|
});
|
|
95
100
|
}
|
|
101
|
+
#packWithBlockHash(blockHash, data) {
|
|
102
|
+
return Buffer.concat([
|
|
103
|
+
blockHash.toBuffer(),
|
|
104
|
+
...data
|
|
105
|
+
]);
|
|
106
|
+
}
|
|
107
|
+
#unpackBlockHash(reader) {
|
|
108
|
+
const blockHash = reader.remainingBytes() > 0 ? reader.readObject(Fr) : undefined;
|
|
109
|
+
if (!blockHash) {
|
|
110
|
+
throw new Error('Failed to read block hash from log entry buffer');
|
|
111
|
+
}
|
|
112
|
+
return L2BlockHash.fromField(blockHash);
|
|
113
|
+
}
|
|
96
114
|
deleteLogs(blocks) {
|
|
97
115
|
return this.db.transactionAsync(async ()=>{
|
|
98
116
|
const tagsToDelete = (await Promise.all(blocks.map(async (block)=>{
|
|
@@ -149,6 +167,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
149
167
|
[]
|
|
150
168
|
];
|
|
151
169
|
const reader = new BufferReader(buffer);
|
|
170
|
+
const blockHash = this.#unpackBlockHash(reader);
|
|
152
171
|
while(reader.remainingBytes() > 0){
|
|
153
172
|
const indexOfTx = reader.readNumber();
|
|
154
173
|
const numLogsInTx = reader.readNumber();
|
|
@@ -159,7 +178,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
159
178
|
}
|
|
160
179
|
const txLogs = publicLogsInBlock[txIndex];
|
|
161
180
|
const logs = [];
|
|
162
|
-
const maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
181
|
+
const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
|
|
163
182
|
return {
|
|
164
183
|
logs,
|
|
165
184
|
maxLogsHit
|
|
@@ -184,6 +203,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
184
203
|
[]
|
|
185
204
|
];
|
|
186
205
|
const reader = new BufferReader(logBuffer);
|
|
206
|
+
const blockHash = this.#unpackBlockHash(reader);
|
|
187
207
|
while(reader.remainingBytes() > 0){
|
|
188
208
|
const indexOfTx = reader.readNumber();
|
|
189
209
|
const numLogsInTx = reader.readNumber();
|
|
@@ -194,7 +214,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
194
214
|
}
|
|
195
215
|
for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < publicLogsInBlock.length; txIndex++){
|
|
196
216
|
const txLogs = publicLogsInBlock[txIndex];
|
|
197
|
-
maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
217
|
+
maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
|
|
198
218
|
if (maxLogsHit) {
|
|
199
219
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
200
220
|
break loopOverBlocks;
|
|
@@ -235,6 +255,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
235
255
|
[]
|
|
236
256
|
];
|
|
237
257
|
const reader = new BufferReader(contractClassLogsBuffer);
|
|
258
|
+
const blockHash = this.#unpackBlockHash(reader);
|
|
238
259
|
while(reader.remainingBytes() > 0){
|
|
239
260
|
const indexOfTx = reader.readNumber();
|
|
240
261
|
const numLogsInTx = reader.readNumber();
|
|
@@ -245,7 +266,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
245
266
|
}
|
|
246
267
|
const txLogs = contractClassLogsInBlock[txIndex];
|
|
247
268
|
const logs = [];
|
|
248
|
-
const maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
269
|
+
const maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
|
|
249
270
|
return {
|
|
250
271
|
logs,
|
|
251
272
|
maxLogsHit
|
|
@@ -270,6 +291,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
270
291
|
[]
|
|
271
292
|
];
|
|
272
293
|
const reader = new BufferReader(logBuffer);
|
|
294
|
+
const blockHash = this.#unpackBlockHash(reader);
|
|
273
295
|
while(reader.remainingBytes() > 0){
|
|
274
296
|
const indexOfTx = reader.readNumber();
|
|
275
297
|
const numLogsInTx = reader.readNumber();
|
|
@@ -280,7 +302,7 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
280
302
|
}
|
|
281
303
|
for(let txIndex = filter.afterLog?.txIndex ?? 0; txIndex < contractClassLogsInBlock.length; txIndex++){
|
|
282
304
|
const txLogs = contractClassLogsInBlock[txIndex];
|
|
283
|
-
maxLogsHit = this.#accumulateLogs(logs, blockNumber, txIndex, txLogs, filter);
|
|
305
|
+
maxLogsHit = this.#accumulateLogs(logs, blockNumber, blockHash, txIndex, txLogs, filter);
|
|
284
306
|
if (maxLogsHit) {
|
|
285
307
|
this.#log.debug(`Max logs hit at block ${blockNumber}`);
|
|
286
308
|
break loopOverBlocks;
|
|
@@ -292,16 +314,18 @@ import { ContractClassLog, ExtendedContractClassLog, ExtendedPublicLog, LogId, P
|
|
|
292
314
|
maxLogsHit
|
|
293
315
|
};
|
|
294
316
|
}
|
|
295
|
-
#accumulateLogs(results, blockNumber, txIndex, txLogs, filter) {
|
|
317
|
+
#accumulateLogs(results, blockNumber, blockHash, txIndex, txLogs, filter = {}) {
|
|
296
318
|
let maxLogsHit = false;
|
|
297
319
|
let logIndex = typeof filter.afterLog?.logIndex === 'number' ? filter.afterLog.logIndex + 1 : 0;
|
|
298
320
|
for(; logIndex < txLogs.length; logIndex++){
|
|
299
321
|
const log = txLogs[logIndex];
|
|
300
322
|
if (!filter.contractAddress || log.contractAddress.equals(filter.contractAddress)) {
|
|
301
323
|
if (log instanceof ContractClassLog) {
|
|
302
|
-
results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), txIndex, logIndex), log));
|
|
324
|
+
results.push(new ExtendedContractClassLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
|
|
325
|
+
} else if (log instanceof PublicLog) {
|
|
326
|
+
results.push(new ExtendedPublicLog(new LogId(BlockNumber(blockNumber), blockHash, txIndex, logIndex), log));
|
|
303
327
|
} else {
|
|
304
|
-
|
|
328
|
+
throw new Error('Unknown log type');
|
|
305
329
|
}
|
|
306
330
|
if (results.length >= this.#logsMaxPageSize) {
|
|
307
331
|
maxLogsHit = true;
|
|
@@ -111,8 +111,8 @@ async function main() {
|
|
|
111
111
|
logger.info('');
|
|
112
112
|
logger.info('Retrieving block header from rollup transaction...');
|
|
113
113
|
logger.info('');
|
|
114
|
-
// For this script, we don't have blob hashes, so pass empty
|
|
115
|
-
const result = await retriever.getCheckpointFromRollupTx(txHash, [], CheckpointNumber(l2BlockNumber));
|
|
114
|
+
// For this script, we don't have blob hashes or expected hashes, so pass empty arrays/objects
|
|
115
|
+
const result = await retriever.getCheckpointFromRollupTx(txHash, [], CheckpointNumber(l2BlockNumber), {});
|
|
116
116
|
logger.info(' Successfully retrieved block header!');
|
|
117
117
|
logger.info('');
|
|
118
118
|
logger.info('Block Header Details:');
|
|
@@ -32,9 +32,13 @@ export declare class CalldataRetriever {
|
|
|
32
32
|
* @param txHash - Hash of the tx that published it.
|
|
33
33
|
* @param blobHashes - Blob hashes for the checkpoint.
|
|
34
34
|
* @param checkpointNumber - Checkpoint number.
|
|
35
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
35
36
|
* @returns Checkpoint header and metadata from the calldata, deserialized
|
|
36
37
|
*/
|
|
37
|
-
getCheckpointFromRollupTx(txHash: `0x${string}`, blobHashes: Buffer[], checkpointNumber: CheckpointNumber
|
|
38
|
+
getCheckpointFromRollupTx(txHash: `0x${string}`, blobHashes: Buffer[], checkpointNumber: CheckpointNumber, expectedHashes: {
|
|
39
|
+
attestationsHash?: Hex;
|
|
40
|
+
payloadDigest?: Hex;
|
|
41
|
+
}): Promise<{
|
|
38
42
|
checkpointNumber: CheckpointNumber;
|
|
39
43
|
archiveRoot: Fr;
|
|
40
44
|
header: CheckpointHeader;
|
|
@@ -80,14 +84,24 @@ export declare class CalldataRetriever {
|
|
|
80
84
|
* @returns The propose calldata from the successful call
|
|
81
85
|
*/
|
|
82
86
|
protected extractCalldataViaTrace(txHash: Hex): Promise<Hex>;
|
|
87
|
+
/**
|
|
88
|
+
* Extracts the CommitteeAttestations struct definition from RollupAbi.
|
|
89
|
+
* Finds the _attestations parameter by name in the propose function.
|
|
90
|
+
* Lazy-loaded to avoid issues during module initialization.
|
|
91
|
+
*/
|
|
92
|
+
private getCommitteeAttestationsStructDef;
|
|
83
93
|
/**
|
|
84
94
|
* Decodes propose calldata and builds the checkpoint header structure.
|
|
85
95
|
* @param proposeCalldata - The propose function calldata
|
|
86
96
|
* @param blockHash - The L1 block hash containing this transaction
|
|
87
97
|
* @param checkpointNumber - The checkpoint number
|
|
98
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
88
99
|
* @returns The decoded checkpoint header and metadata
|
|
89
100
|
*/
|
|
90
|
-
protected decodeAndBuildCheckpoint(proposeCalldata: Hex, blockHash: Hex, checkpointNumber: CheckpointNumber
|
|
101
|
+
protected decodeAndBuildCheckpoint(proposeCalldata: Hex, blockHash: Hex, checkpointNumber: CheckpointNumber, expectedHashes: {
|
|
102
|
+
attestationsHash?: Hex;
|
|
103
|
+
payloadDigest?: Hex;
|
|
104
|
+
}): {
|
|
91
105
|
checkpointNumber: CheckpointNumber;
|
|
92
106
|
archiveRoot: Fr;
|
|
93
107
|
header: CheckpointHeader;
|
|
@@ -95,4 +109,4 @@ export declare class CalldataRetriever {
|
|
|
95
109
|
blockHash: string;
|
|
96
110
|
};
|
|
97
111
|
}
|
|
98
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
112
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbGRhdGFfcmV0cmlldmVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXJjaGl2ZXIvbDEvY2FsbGRhdGFfcmV0cmlldmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLHFCQUFxQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDbkUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVFwRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUUzRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV4RCxPQUFPLEVBRUwsS0FBSyxHQUFHLEVBQ1IsS0FBSyxXQUFXLEVBT2pCLE1BQU0sTUFBTSxDQUFDO0FBRWQsT0FBTyxLQUFLLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQU1yRTs7O0dBR0c7QUFDSCxxQkFBYSxpQkFBaUI7SUFPMUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZO0lBQzdCLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVztJQUM1QixPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFtQjtJQUNwQyxPQUFPLENBQUMsUUFBUSxDQUFDLGVBQWU7SUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNO0lBVnpCLHVEQUF1RDtJQUN2RCxPQUFPLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFzQjtJQUV6RCxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBYTtJQUUzQyxZQUNtQixZQUFZLEVBQUUsZ0JBQWdCLEVBQzlCLFdB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calldata_retriever.d.ts","sourceRoot":"","sources":["../../../src/archiver/l1/calldata_retriever.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAQpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"calldata_retriever.d.ts","sourceRoot":"","sources":["../../../src/archiver/l1/calldata_retriever.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,9 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
4
|
import { EmpireSlashingProposerAbi, GovernanceProposerAbi, RollupAbi, SlashFactoryAbi, TallySlashingProposerAbi } from '@aztec/l1-artifacts';
|
|
5
5
|
import { CommitteeAttestation } from '@aztec/stdlib/block';
|
|
6
|
+
import { ConsensusPayload, SignatureDomainSeparator } from '@aztec/stdlib/p2p';
|
|
6
7
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
7
|
-
import { decodeFunctionData, hexToBytes, multicall3Abi, toFunctionSelector } from 'viem';
|
|
8
|
+
import { decodeFunctionData, encodeAbiParameters, hexToBytes, keccak256, multicall3Abi, toFunctionSelector } from 'viem';
|
|
8
9
|
import { getSuccessfulCallsFromDebug } from './debug_tx.js';
|
|
9
10
|
import { getCallFromSpireProposer } from './spire_proposer.js';
|
|
10
11
|
import { getSuccessfulCallsFromTrace } from './trace_tx.js';
|
|
@@ -34,14 +35,19 @@ import { getSuccessfulCallsFromTrace } from './trace_tx.js';
|
|
|
34
35
|
* @param txHash - Hash of the tx that published it.
|
|
35
36
|
* @param blobHashes - Blob hashes for the checkpoint.
|
|
36
37
|
* @param checkpointNumber - Checkpoint number.
|
|
38
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
37
39
|
* @returns Checkpoint header and metadata from the calldata, deserialized
|
|
38
|
-
*/ async getCheckpointFromRollupTx(txHash, blobHashes, checkpointNumber) {
|
|
39
|
-
this.logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}
|
|
40
|
+
*/ async getCheckpointFromRollupTx(txHash, blobHashes, checkpointNumber, expectedHashes) {
|
|
41
|
+
this.logger.trace(`Fetching checkpoint ${checkpointNumber} from rollup tx ${txHash}`, {
|
|
42
|
+
willValidateHashes: !!expectedHashes.attestationsHash || !!expectedHashes.payloadDigest,
|
|
43
|
+
hasAttestationsHash: !!expectedHashes.attestationsHash,
|
|
44
|
+
hasPayloadDigest: !!expectedHashes.payloadDigest
|
|
45
|
+
});
|
|
40
46
|
const tx = await this.publicClient.getTransaction({
|
|
41
47
|
hash: txHash
|
|
42
48
|
});
|
|
43
49
|
const proposeCalldata = await this.getProposeCallData(tx, checkpointNumber);
|
|
44
|
-
return this.decodeAndBuildCheckpoint(proposeCalldata, tx.blockHash, checkpointNumber);
|
|
50
|
+
return this.decodeAndBuildCheckpoint(proposeCalldata, tx.blockHash, checkpointNumber, expectedHashes);
|
|
45
51
|
}
|
|
46
52
|
/** Gets rollup propose calldata from a transaction */ async getProposeCallData(tx, checkpointNumber) {
|
|
47
53
|
// Try to decode as multicall3 with validation
|
|
@@ -283,12 +289,37 @@ import { getSuccessfulCallsFromTrace } from './trace_tx.js';
|
|
|
283
289
|
return calls[0].input;
|
|
284
290
|
}
|
|
285
291
|
/**
|
|
292
|
+
* Extracts the CommitteeAttestations struct definition from RollupAbi.
|
|
293
|
+
* Finds the _attestations parameter by name in the propose function.
|
|
294
|
+
* Lazy-loaded to avoid issues during module initialization.
|
|
295
|
+
*/ getCommitteeAttestationsStructDef() {
|
|
296
|
+
const proposeFunction = RollupAbi.find((item)=>item.type === 'function' && item.name === 'propose');
|
|
297
|
+
if (!proposeFunction) {
|
|
298
|
+
throw new Error('propose function not found in RollupAbi');
|
|
299
|
+
}
|
|
300
|
+
// Find the _attestations parameter by name, not by index
|
|
301
|
+
const attestationsParam = proposeFunction.inputs.find((param)=>param.name === '_attestations');
|
|
302
|
+
if (!attestationsParam) {
|
|
303
|
+
throw new Error('_attestations parameter not found in propose function');
|
|
304
|
+
}
|
|
305
|
+
if (attestationsParam.type !== 'tuple') {
|
|
306
|
+
throw new Error(`Expected _attestations parameter to be a tuple, got ${attestationsParam.type}`);
|
|
307
|
+
}
|
|
308
|
+
// Extract the tuple components (struct fields)
|
|
309
|
+
const tupleParam = attestationsParam;
|
|
310
|
+
return {
|
|
311
|
+
type: 'tuple',
|
|
312
|
+
components: tupleParam.components || []
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
286
316
|
* Decodes propose calldata and builds the checkpoint header structure.
|
|
287
317
|
* @param proposeCalldata - The propose function calldata
|
|
288
318
|
* @param blockHash - The L1 block hash containing this transaction
|
|
289
319
|
* @param checkpointNumber - The checkpoint number
|
|
320
|
+
* @param expectedHashes - Optional expected hashes from the CheckpointProposed event for validation
|
|
290
321
|
* @returns The decoded checkpoint header and metadata
|
|
291
|
-
*/ decodeAndBuildCheckpoint(proposeCalldata, blockHash, checkpointNumber) {
|
|
322
|
+
*/ decodeAndBuildCheckpoint(proposeCalldata, blockHash, checkpointNumber, expectedHashes) {
|
|
292
323
|
const { functionName: rollupFunctionName, args: rollupArgs } = decodeFunctionData({
|
|
293
324
|
abi: RollupAbi,
|
|
294
325
|
data: proposeCalldata
|
|
@@ -298,6 +329,45 @@ import { getSuccessfulCallsFromTrace } from './trace_tx.js';
|
|
|
298
329
|
}
|
|
299
330
|
const [decodedArgs, packedAttestations, _signers, _attestationsAndSignersSignature, _blobInput] = rollupArgs;
|
|
300
331
|
const attestations = CommitteeAttestation.fromPacked(packedAttestations, this.targetCommitteeSize);
|
|
332
|
+
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
333
|
+
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
334
|
+
// Validate attestationsHash if provided (skip for backwards compatibility with older events)
|
|
335
|
+
if (expectedHashes.attestationsHash) {
|
|
336
|
+
// Compute attestationsHash: keccak256(abi.encode(CommitteeAttestations))
|
|
337
|
+
const computedAttestationsHash = keccak256(encodeAbiParameters([
|
|
338
|
+
this.getCommitteeAttestationsStructDef()
|
|
339
|
+
], [
|
|
340
|
+
packedAttestations
|
|
341
|
+
]));
|
|
342
|
+
// Compare as buffers to avoid case-sensitivity and string comparison issues
|
|
343
|
+
const computedBuffer = Buffer.from(hexToBytes(computedAttestationsHash));
|
|
344
|
+
const expectedBuffer = Buffer.from(hexToBytes(expectedHashes.attestationsHash));
|
|
345
|
+
if (!computedBuffer.equals(expectedBuffer)) {
|
|
346
|
+
throw new Error(`Attestations hash mismatch for checkpoint ${checkpointNumber}: ` + `computed=${computedAttestationsHash}, expected=${expectedHashes.attestationsHash}`);
|
|
347
|
+
}
|
|
348
|
+
this.logger.trace(`Validated attestationsHash for checkpoint ${checkpointNumber}`, {
|
|
349
|
+
computedAttestationsHash,
|
|
350
|
+
expectedAttestationsHash: expectedHashes.attestationsHash
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// Validate payloadDigest if provided (skip for backwards compatibility with older events)
|
|
354
|
+
if (expectedHashes.payloadDigest) {
|
|
355
|
+
// Use ConsensusPayload to compute the digest - this ensures we match the exact logic
|
|
356
|
+
// used by the network for signing and verification
|
|
357
|
+
const consensusPayload = new ConsensusPayload(header, archiveRoot);
|
|
358
|
+
const payloadToSign = consensusPayload.getPayloadToSign(SignatureDomainSeparator.blockAttestation);
|
|
359
|
+
const computedPayloadDigest = keccak256(payloadToSign);
|
|
360
|
+
// Compare as buffers to avoid case-sensitivity and string comparison issues
|
|
361
|
+
const computedBuffer = Buffer.from(hexToBytes(computedPayloadDigest));
|
|
362
|
+
const expectedBuffer = Buffer.from(hexToBytes(expectedHashes.payloadDigest));
|
|
363
|
+
if (!computedBuffer.equals(expectedBuffer)) {
|
|
364
|
+
throw new Error(`Payload digest mismatch for checkpoint ${checkpointNumber}: ` + `computed=${computedPayloadDigest}, expected=${expectedHashes.payloadDigest}`);
|
|
365
|
+
}
|
|
366
|
+
this.logger.trace(`Validated payloadDigest for checkpoint ${checkpointNumber}`, {
|
|
367
|
+
computedPayloadDigest,
|
|
368
|
+
expectedPayloadDigest: expectedHashes.payloadDigest
|
|
369
|
+
});
|
|
370
|
+
}
|
|
301
371
|
this.logger.trace(`Decoded propose calldata`, {
|
|
302
372
|
checkpointNumber,
|
|
303
373
|
archive: decodedArgs.archive,
|
|
@@ -307,8 +377,6 @@ import { getSuccessfulCallsFromTrace } from './trace_tx.js';
|
|
|
307
377
|
packedAttestations,
|
|
308
378
|
targetCommitteeSize: this.targetCommitteeSize
|
|
309
379
|
});
|
|
310
|
-
const header = CheckpointHeader.fromViem(decodedArgs.header);
|
|
311
|
-
const archiveRoot = new Fr(Buffer.from(hexToBytes(decodedArgs.archive)));
|
|
312
380
|
return {
|
|
313
381
|
checkpointNumber,
|
|
314
382
|
archiveRoot,
|