@aztec/simulator 0.24.0 → 0.26.2
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/acvm/deserialize.d.ts +5 -0
- package/dest/acvm/deserialize.d.ts.map +1 -1
- package/dest/acvm/deserialize.js +8 -1
- package/dest/acvm/oracle/oracle.d.ts +5 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +24 -11
- package/dest/acvm/oracle/typed_oracle.d.ts +7 -9
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +9 -9
- package/dest/avm/avm_context.d.ts +4 -4
- package/dest/avm/avm_context.d.ts.map +1 -1
- package/dest/avm/avm_context.js +6 -6
- package/dest/avm/avm_memory_types.d.ts +11 -2
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +11 -1
- package/dest/avm/avm_simulator.d.ts +6 -4
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +17 -18
- package/dest/avm/fixtures/index.d.ts +17 -5
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +19 -8
- package/dest/avm/journal/host_storage.d.ts.map +1 -1
- package/dest/avm/journal/host_storage.js +1 -1
- package/dest/avm/journal/journal.d.ts +78 -50
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +125 -169
- package/dest/avm/journal/nullifiers.d.ts +85 -0
- package/dest/avm/journal/nullifiers.d.ts.map +1 -0
- package/dest/avm/journal/nullifiers.js +147 -0
- package/dest/avm/journal/public_storage.d.ts +88 -0
- package/dest/avm/journal/public_storage.d.ts.map +1 -0
- package/dest/avm/journal/public_storage.js +135 -0
- package/dest/avm/journal/trace.d.ts +43 -0
- package/dest/avm/journal/trace.d.ts.map +1 -0
- package/dest/avm/journal/trace.js +204 -0
- package/dest/avm/journal/trace_types.d.ts +26 -0
- package/dest/avm/journal/trace_types.d.ts.map +1 -0
- package/dest/avm/journal/trace_types.js +6 -0
- package/dest/avm/opcodes/accrued_substate.d.ts +37 -4
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +109 -12
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +5 -8
- package/dest/avm/opcodes/environment_getters.d.ts +14 -13
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +1 -1
- package/dest/avm/opcodes/external_calls.js +5 -5
- package/dest/avm/opcodes/hashing.d.ts +48 -0
- package/dest/avm/opcodes/hashing.d.ts.map +1 -0
- package/dest/avm/opcodes/hashing.js +127 -0
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +1 -1
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +3 -3
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +12 -8
- package/dest/avm/serialization/instruction_serialization.d.ts +10 -7
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +12 -9
- package/dest/avm/temporary_executor_migration.d.ts.map +1 -1
- package/dest/avm/temporary_executor_migration.js +5 -5
- package/dest/client/client_execution_context.d.ts +9 -5
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +46 -24
- package/dest/client/db_oracle.d.ts +7 -0
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/db_oracle.js +1 -1
- package/dest/client/execution_note_cache.js +1 -1
- package/dest/client/execution_result.d.ts +2 -2
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +4 -4
- package/dest/client/simulator.d.ts +1 -1
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +3 -2
- package/dest/client/view_data_oracle.d.ts +9 -2
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +13 -5
- package/dest/public/db.d.ts +17 -4
- package/dest/public/db.d.ts.map +1 -1
- package/dest/public/execution.d.ts +9 -4
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +17 -4
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +18 -9
- package/dest/public/public_execution_context.d.ts +5 -4
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +23 -12
- package/dest/public/state_actions.js +2 -2
- package/dest/test/utils.js +4 -4
- package/dest/utils.js +2 -3
- package/package.json +6 -5
- package/src/acvm/deserialize.ts +8 -0
- package/src/acvm/oracle/oracle.ts +30 -6
- package/src/acvm/oracle/typed_oracle.ts +13 -5
- package/src/avm/avm_context.ts +5 -5
- package/src/avm/avm_memory_types.ts +18 -3
- package/src/avm/avm_simulator.ts +22 -24
- package/src/avm/fixtures/index.ts +34 -9
- package/src/avm/journal/host_storage.ts +5 -11
- package/src/avm/journal/journal.ts +147 -182
- package/src/avm/journal/nullifiers.ts +170 -0
- package/src/avm/journal/public_storage.ts +149 -0
- package/src/avm/journal/trace.ts +223 -0
- package/src/avm/journal/trace_types.ts +79 -0
- package/src/avm/opcodes/accrued_substate.ts +132 -10
- package/src/avm/opcodes/comparators.ts +4 -7
- package/src/avm/opcodes/environment_getters.ts +15 -13
- package/src/avm/opcodes/external_calls.ts +4 -4
- package/src/avm/opcodes/hashing.ts +170 -0
- package/src/avm/opcodes/memory.ts +1 -0
- package/src/avm/opcodes/storage.ts +5 -2
- package/src/avm/serialization/bytecode_serialization.ts +13 -6
- package/src/avm/serialization/instruction_serialization.ts +6 -3
- package/src/avm/temporary_executor_migration.ts +4 -3
- package/src/client/client_execution_context.ts +53 -23
- package/src/client/db_oracle.ts +8 -0
- package/src/client/execution_note_cache.ts +1 -1
- package/src/client/execution_result.ts +2 -2
- package/src/client/private_execution.ts +5 -4
- package/src/client/simulator.ts +2 -1
- package/src/client/view_data_oracle.ts +14 -4
- package/src/public/db.ts +19 -4
- package/src/public/execution.ts +30 -6
- package/src/public/executor.ts +29 -9
- package/src/public/public_execution_context.ts +36 -12
- package/src/public/state_actions.ts +1 -1
- package/src/test/utils.ts +3 -3
- package/src/utils.ts +1 -1
|
@@ -1,139 +1,154 @@
|
|
|
1
|
+
import { UnencryptedL2Log } from '@aztec/circuit-types';
|
|
2
|
+
import { AztecAddress, EthAddress, L2ToL1Message } from '@aztec/circuits.js';
|
|
3
|
+
import { EventSelector } from '@aztec/foundation/abi';
|
|
4
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
5
|
+
import { Nullifiers } from './nullifiers.js';
|
|
6
|
+
import { PublicStorage } from './public_storage.js';
|
|
7
|
+
import { WorldStateAccessTrace } from './trace.js';
|
|
1
8
|
/**
|
|
2
|
-
* A
|
|
3
|
-
*
|
|
9
|
+
* A class to manage persistable AVM state for contract calls.
|
|
10
|
+
* Maintains a cache of the current world state,
|
|
11
|
+
* a trace of all world state accesses, and a list of accrued substate items.
|
|
4
12
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
13
|
+
* The simulator should make any world state and accrued substate queries through this object.
|
|
14
|
+
*
|
|
15
|
+
* Manages merging of successful/reverted child state into current state.
|
|
8
16
|
*/
|
|
9
|
-
export class
|
|
10
|
-
constructor(hostStorage,
|
|
11
|
-
|
|
12
|
-
// contract address -> key -> value[] (array stored in order of reads)
|
|
13
|
-
this.storageReads = new Map();
|
|
14
|
-
this.storageWrites = new Map();
|
|
15
|
-
// New written state
|
|
16
|
-
this.newNoteHashes = [];
|
|
17
|
-
this.newNullifiers = [];
|
|
18
|
-
// New Substate
|
|
17
|
+
export class AvmPersistableStateManager {
|
|
18
|
+
constructor(hostStorage, parent) {
|
|
19
|
+
/** Accrued Substate **/
|
|
19
20
|
this.newL1Messages = [];
|
|
20
21
|
this.newLogs = [];
|
|
21
|
-
// contract address -> key -> value
|
|
22
|
-
this.currentStorageValue = new Map();
|
|
23
|
-
// Create an instance of journalUpdate that appends to the read array
|
|
24
|
-
this.journalRead = this.journalUpdate.bind(this, this.storageReads);
|
|
25
|
-
// Create an instance of journalUpdate that appends to the writes array
|
|
26
|
-
this.journalWrite = this.journalUpdate.bind(this, this.storageWrites);
|
|
27
22
|
this.hostStorage = hostStorage;
|
|
28
|
-
this.
|
|
23
|
+
this.publicStorage = new PublicStorage(hostStorage.publicStateDb, parent?.publicStorage);
|
|
24
|
+
this.nullifiers = new Nullifiers(hostStorage.commitmentsDb, parent?.nullifiers);
|
|
25
|
+
this.trace = new WorldStateAccessTrace(parent?.trace);
|
|
29
26
|
}
|
|
30
27
|
/**
|
|
31
|
-
* Create a new
|
|
28
|
+
* Create a new state manager forked from this one
|
|
32
29
|
*/
|
|
33
30
|
fork() {
|
|
34
|
-
return new
|
|
31
|
+
return new AvmPersistableStateManager(this.hostStorage, this);
|
|
35
32
|
}
|
|
36
33
|
/**
|
|
37
|
-
* Write storage
|
|
34
|
+
* Write to public storage, journal/trace the write.
|
|
38
35
|
*
|
|
39
|
-
* @param
|
|
40
|
-
* @param
|
|
41
|
-
* @param value -
|
|
36
|
+
* @param storageAddress - the address of the contract whose storage is being written to
|
|
37
|
+
* @param slot - the slot in the contract's storage being written to
|
|
38
|
+
* @param value - the value being written to the slot
|
|
42
39
|
*/
|
|
43
|
-
writeStorage(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
contractMap.set(key.toBigInt(), value);
|
|
50
|
-
// We want to keep track of all performed writes in the journal
|
|
51
|
-
this.journalWrite(contractAddress, key, value);
|
|
40
|
+
writeStorage(storageAddress, slot, value) {
|
|
41
|
+
// Cache storage writes for later reference/reads
|
|
42
|
+
this.publicStorage.write(storageAddress, slot, value);
|
|
43
|
+
// Trace all storage writes (even reverted ones)
|
|
44
|
+
this.trace.tracePublicStorageWrite(storageAddress, slot, value);
|
|
52
45
|
}
|
|
53
46
|
/**
|
|
54
|
-
* Read storage
|
|
55
|
-
* Read from host storage on cache miss
|
|
47
|
+
* Read from public storage, trace the read.
|
|
56
48
|
*
|
|
57
|
-
* @param
|
|
58
|
-
* @param
|
|
59
|
-
* @returns
|
|
49
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
50
|
+
* @param slot - the slot in the contract's storage being read from
|
|
51
|
+
* @returns the latest value written to slot, or 0 if never written to before
|
|
60
52
|
*/
|
|
61
|
-
async readStorage(
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
// Do not early return as we want to keep track of reads in this.storageReads
|
|
66
|
-
let value = this.currentStorageValue.get(contractAddress.toBigInt())?.get(key.toBigInt());
|
|
67
|
-
if (!value && this.parentJournal) {
|
|
68
|
-
value = await this.parentJournal?.readStorage(contractAddress, key);
|
|
69
|
-
}
|
|
70
|
-
if (!value) {
|
|
71
|
-
value = await this.hostStorage.publicStateDb.storageRead(contractAddress, key);
|
|
72
|
-
}
|
|
73
|
-
this.journalRead(contractAddress, key, value);
|
|
53
|
+
async readStorage(storageAddress, slot) {
|
|
54
|
+
const [_exists, value] = await this.publicStorage.read(storageAddress, slot);
|
|
55
|
+
// We want to keep track of all performed reads (even reverted ones)
|
|
56
|
+
this.trace.tracePublicStorageRead(storageAddress, slot, value);
|
|
74
57
|
return Promise.resolve(value);
|
|
75
58
|
}
|
|
59
|
+
// TODO(4886): We currently don't silo note hashes.
|
|
76
60
|
/**
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
|
|
80
|
-
* @param
|
|
81
|
-
* @param
|
|
82
|
-
* @
|
|
61
|
+
* Check if a note hash exists at the given leaf index, trace the check.
|
|
62
|
+
*
|
|
63
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
64
|
+
* @param noteHash - the unsiloed note hash being checked
|
|
65
|
+
* @param leafIndex - the leaf index being checked
|
|
66
|
+
* @returns true if the note hash exists at the given leaf index, false otherwise
|
|
83
67
|
*/
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
let accessArray = contractMap.get(key.toBigInt());
|
|
91
|
-
if (!accessArray) {
|
|
92
|
-
accessArray = new Array();
|
|
93
|
-
contractMap.set(key.toBigInt(), accessArray);
|
|
94
|
-
}
|
|
95
|
-
accessArray.push(value);
|
|
68
|
+
async checkNoteHashExists(storageAddress, noteHash, leafIndex) {
|
|
69
|
+
const gotLeafIndex = await this.hostStorage.commitmentsDb.getCommitmentIndex(noteHash);
|
|
70
|
+
const exists = gotLeafIndex === leafIndex.toBigInt();
|
|
71
|
+
this.trace.traceNoteHashCheck(storageAddress, noteHash, exists, leafIndex);
|
|
72
|
+
return Promise.resolve(exists);
|
|
96
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Write a note hash, trace the write.
|
|
76
|
+
* @param noteHash - the unsiloed note hash to write
|
|
77
|
+
*/
|
|
97
78
|
writeNoteHash(noteHash) {
|
|
98
|
-
this.
|
|
79
|
+
this.trace.traceNewNoteHash(/*storageAddress*/ Fr.ZERO, noteHash);
|
|
99
80
|
}
|
|
100
|
-
|
|
101
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Check if a nullifier exists, trace the check.
|
|
83
|
+
* @param storageAddress - address of the contract that the nullifier is associated with
|
|
84
|
+
* @param nullifier - the unsiloed nullifier to check
|
|
85
|
+
* @returns exists - whether the nullifier exists in the nullifier set
|
|
86
|
+
*/
|
|
87
|
+
async checkNullifierExists(storageAddress, nullifier) {
|
|
88
|
+
const [exists, isPending, leafIndex] = await this.nullifiers.checkExists(storageAddress, nullifier);
|
|
89
|
+
this.trace.traceNullifierCheck(storageAddress, nullifier, exists, isPending, leafIndex);
|
|
90
|
+
return Promise.resolve(exists);
|
|
102
91
|
}
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Write a nullifier to the nullifier set, trace the write.
|
|
94
|
+
* @param storageAddress - address of the contract that the nullifier is associated with
|
|
95
|
+
* @param nullifier - the unsiloed nullifier to write
|
|
96
|
+
*/
|
|
97
|
+
async writeNullifier(storageAddress, nullifier) {
|
|
98
|
+
// Cache pending nullifiers for later access
|
|
99
|
+
await this.nullifiers.append(storageAddress, nullifier);
|
|
100
|
+
// Trace all nullifier creations (even reverted ones)
|
|
101
|
+
this.trace.traceNewNullifier(storageAddress, nullifier);
|
|
105
102
|
}
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Check if an L1 to L2 message exists, trace the check.
|
|
105
|
+
* @param msgHash - the message hash to check existence of
|
|
106
|
+
* @param msgLeafIndex - the message leaf index to use in the check
|
|
107
|
+
* @returns exists - whether the message exists in the L1 to L2 Messages tree
|
|
108
|
+
*/
|
|
109
|
+
async checkL1ToL2MessageExists(msgHash, msgLeafIndex) {
|
|
110
|
+
let exists = false;
|
|
111
|
+
try {
|
|
112
|
+
const gotMessage = await this.hostStorage.commitmentsDb.getL1ToL2MembershipWitness(msgHash);
|
|
113
|
+
exists = gotMessage !== undefined && gotMessage.index == msgLeafIndex.toBigInt();
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// error getting message - doesn't exist!
|
|
117
|
+
exists = false;
|
|
118
|
+
}
|
|
119
|
+
this.trace.traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists);
|
|
120
|
+
return Promise.resolve(exists);
|
|
108
121
|
}
|
|
109
122
|
/**
|
|
110
|
-
*
|
|
111
|
-
* -
|
|
112
|
-
*
|
|
113
|
-
* - Public state journals (r/w logs), with the accessing being appended in chronological order
|
|
123
|
+
* Write an L2 to L1 message.
|
|
124
|
+
* @param recipient - L1 contract address to send the message to.
|
|
125
|
+
* @param content - Message content.
|
|
114
126
|
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.
|
|
127
|
+
writeL1Message(recipient, content) {
|
|
128
|
+
const recipientAddress = recipient instanceof EthAddress ? recipient : EthAddress.fromField(recipient);
|
|
129
|
+
this.newL1Messages.push(new L2ToL1Message(recipientAddress, content));
|
|
130
|
+
}
|
|
131
|
+
writeLog(contractAddress, event, log) {
|
|
132
|
+
this.newLogs.push(new UnencryptedL2Log(AztecAddress.fromField(contractAddress), EventSelector.fromField(event), Buffer.concat(log.map(f => f.toBuffer()))));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Accept nested world state modifications, merging in its trace and accrued substate
|
|
136
|
+
*/
|
|
137
|
+
acceptNestedCallState(nestedJournal) {
|
|
138
|
+
// Merge Public Storage
|
|
139
|
+
this.publicStorage.acceptAndMerge(nestedJournal.publicStorage);
|
|
140
|
+
// Merge World State Access Trace
|
|
141
|
+
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
142
|
+
// Accrued Substate
|
|
118
143
|
this.newL1Messages = this.newL1Messages.concat(nestedJournal.newL1Messages);
|
|
119
|
-
this.newNullifiers = this.newNullifiers.concat(nestedJournal.newNullifiers);
|
|
120
144
|
this.newLogs = this.newLogs.concat(nestedJournal.newLogs);
|
|
121
|
-
// Merge Public State
|
|
122
|
-
mergeCurrentValueMaps(this.currentStorageValue, nestedJournal.currentStorageValue);
|
|
123
|
-
// Merge storage read and write journals
|
|
124
|
-
mergeContractJournalMaps(this.storageReads, nestedJournal.storageReads);
|
|
125
|
-
mergeContractJournalMaps(this.storageWrites, nestedJournal.storageWrites);
|
|
126
145
|
}
|
|
127
146
|
/**
|
|
128
|
-
* Reject nested world state, merging in its
|
|
129
|
-
* - Utxo objects are concatenated
|
|
130
|
-
* - Public state changes are dropped
|
|
131
|
-
* - Public state journals (r/w logs) are maintained, with the accessing being appended in chronological order
|
|
147
|
+
* Reject nested world state, merging in its trace, but not accepting any state modifications
|
|
132
148
|
*/
|
|
133
|
-
|
|
134
|
-
// Merge
|
|
135
|
-
|
|
136
|
-
mergeContractJournalMaps(this.storageWrites, nestedJournal.storageWrites);
|
|
149
|
+
rejectNestedCallState(nestedJournal) {
|
|
150
|
+
// Merge World State Access Trace
|
|
151
|
+
this.trace.acceptAndMerge(nestedJournal.trace);
|
|
137
152
|
}
|
|
138
153
|
/**
|
|
139
154
|
* Access the current state of the journal
|
|
@@ -142,76 +157,17 @@ export class AvmWorldStateJournal {
|
|
|
142
157
|
*/
|
|
143
158
|
flush() {
|
|
144
159
|
return {
|
|
145
|
-
|
|
146
|
-
|
|
160
|
+
noteHashChecks: this.trace.noteHashChecks,
|
|
161
|
+
newNoteHashes: this.trace.newNoteHashes,
|
|
162
|
+
nullifierChecks: this.trace.nullifierChecks,
|
|
163
|
+
newNullifiers: this.trace.newNullifiers,
|
|
164
|
+
l1ToL2MessageChecks: this.trace.l1ToL2MessageChecks,
|
|
147
165
|
newL1Messages: this.newL1Messages,
|
|
148
166
|
newLogs: this.newLogs,
|
|
149
|
-
currentStorageValue: this.
|
|
150
|
-
storageReads: this.
|
|
151
|
-
storageWrites: this.
|
|
167
|
+
currentStorageValue: this.publicStorage.getCache().cachePerContract,
|
|
168
|
+
storageReads: this.trace.publicStorageReads,
|
|
169
|
+
storageWrites: this.trace.publicStorageWrites,
|
|
152
170
|
};
|
|
153
171
|
}
|
|
154
172
|
}
|
|
155
|
-
|
|
156
|
-
* Merges two contract current value together
|
|
157
|
-
* Where childMap keys will take precedent over the hostMap
|
|
158
|
-
* The assumption being that the child map is created at a later time
|
|
159
|
-
* And thus contains more up to date information
|
|
160
|
-
*
|
|
161
|
-
* @param hostMap - The map to be merged into
|
|
162
|
-
* @param childMap - The map to be merged from
|
|
163
|
-
*/
|
|
164
|
-
function mergeCurrentValueMaps(hostMap, childMap) {
|
|
165
|
-
for (const [key, value] of childMap) {
|
|
166
|
-
const map1Value = hostMap.get(key);
|
|
167
|
-
if (!map1Value) {
|
|
168
|
-
hostMap.set(key, value);
|
|
169
|
-
}
|
|
170
|
-
else {
|
|
171
|
-
mergeStorageCurrentValueMaps(map1Value, value);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* @param hostMap - The map to be merge into
|
|
177
|
-
* @param childMap - The map to be merged from
|
|
178
|
-
*/
|
|
179
|
-
function mergeStorageCurrentValueMaps(hostMap, childMap) {
|
|
180
|
-
for (const [key, value] of childMap) {
|
|
181
|
-
hostMap.set(key, value);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Merges two contract journalling maps together
|
|
186
|
-
* For read maps, we just append the childMap arrays into the host map arrays, as the order is important
|
|
187
|
-
*
|
|
188
|
-
* @param hostMap - The map to be merged into
|
|
189
|
-
* @param childMap - The map to be merged from
|
|
190
|
-
*/
|
|
191
|
-
function mergeContractJournalMaps(hostMap, childMap) {
|
|
192
|
-
for (const [key, value] of childMap) {
|
|
193
|
-
const map1Value = hostMap.get(key);
|
|
194
|
-
if (!map1Value) {
|
|
195
|
-
hostMap.set(key, value);
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
mergeStorageJournalMaps(map1Value, value);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* @param hostMap - The map to be merge into
|
|
204
|
-
* @param childMap - The map to be merged from
|
|
205
|
-
*/
|
|
206
|
-
function mergeStorageJournalMaps(hostMap, childMap) {
|
|
207
|
-
for (const [key, value] of childMap) {
|
|
208
|
-
const readArr = hostMap.get(key);
|
|
209
|
-
if (!readArr) {
|
|
210
|
-
hostMap.set(key, value);
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
hostMap.set(key, readArr?.concat(...value));
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam91cm5hbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9qb3VybmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQXNCQTs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLG9CQUFvQjtJQXNCL0IsWUFBWSxXQUF3QixFQUFFLGFBQW9DO1FBbEIxRSxtREFBbUQ7UUFDbkQsc0VBQXNFO1FBQzlELGlCQUFZLEdBQW1DLElBQUksR0FBRyxFQUFFLENBQUM7UUFDekQsa0JBQWEsR0FBbUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUVsRSxvQkFBb0I7UUFDWixrQkFBYSxHQUFTLEVBQUUsQ0FBQztRQUN6QixrQkFBYSxHQUFTLEVBQUUsQ0FBQztRQUVqQyxlQUFlO1FBQ1Asa0JBQWEsR0FBVyxFQUFFLENBQUM7UUFDM0IsWUFBTyxHQUFXLEVBQUUsQ0FBQztRQUU3QixtQ0FBbUM7UUFDM0Isd0JBQW1CLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7UUFvRnRFLHFFQUFxRTtRQUM3RCxnQkFBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDdkUsdUVBQXVFO1FBQy9ELGlCQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQWxGdkUsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0ksSUFBSTtRQUNULE9BQU8sSUFBSSxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxZQUFZLENBQUMsZUFBbUIsRUFBRSxHQUFPLEVBQUUsS0FBUztR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
|
|
173
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiam91cm5hbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9qb3VybmFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUF5Qm5EOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxPQUFPLDBCQUEwQjtJQWlCckMsWUFBWSxXQUF3QixFQUFFLE1BQW1DO1FBSnpFLHdCQUF3QjtRQUNoQixrQkFBYSxHQUFvQixFQUFFLENBQUM7UUFDcEMsWUFBTyxHQUF1QixFQUFFLENBQUM7UUFHdkMsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUM7UUFDL0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLGFBQWEsQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztRQUN6RixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksVUFBVSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ2hGLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ksSUFBSTtRQUNULE9BQU8s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
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import type { CommitmentsDB } from '../../index.js';
|
|
3
|
+
/**
|
|
4
|
+
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
5
|
+
* Maintains a nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
6
|
+
* When a contract call completes, its cached nullifier set can be merged into its parent's.
|
|
7
|
+
*/
|
|
8
|
+
export declare class Nullifiers {
|
|
9
|
+
/** Cached nullifiers. */
|
|
10
|
+
private cache;
|
|
11
|
+
/** Parent's nullifier cache. Checked on cache-miss. */
|
|
12
|
+
private readonly parentCache;
|
|
13
|
+
/** Reference to node storage. Checked on parent cache-miss. */
|
|
14
|
+
private readonly hostNullifiers;
|
|
15
|
+
constructor(hostNullifiers: CommitmentsDB, parent?: Nullifiers);
|
|
16
|
+
/**
|
|
17
|
+
* Get a nullifier's existence status.
|
|
18
|
+
* 1. Check cache.
|
|
19
|
+
* 2. Check parent's cache.
|
|
20
|
+
* 3. Fall back to the host state.
|
|
21
|
+
* 4. Not found! Nullifier does not exist.
|
|
22
|
+
*
|
|
23
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
24
|
+
* @param nullifier - the nullifier to check for
|
|
25
|
+
* @returns exists: whether the nullifier exists at all,
|
|
26
|
+
* isPending: whether the nullifier was found in a cache,
|
|
27
|
+
* leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state).
|
|
28
|
+
*/
|
|
29
|
+
checkExists(storageAddress: Fr, nullifier: Fr): Promise<[/*exists=*/ boolean, /*isPending=*/ boolean, /*leafIndex=*/ Fr]>;
|
|
30
|
+
/**
|
|
31
|
+
* Stage a new nullifier (append it to the cache).
|
|
32
|
+
*
|
|
33
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
34
|
+
* @param nullifier - the nullifier to stage
|
|
35
|
+
*/
|
|
36
|
+
append(storageAddress: Fr, nullifier: Fr): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Merges another nullifier cache into this one.
|
|
39
|
+
*
|
|
40
|
+
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
41
|
+
*/
|
|
42
|
+
acceptAndMerge(incomingNullifiers: Nullifiers): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A class to cache nullifiers created during a contract call's AVM simulation.
|
|
46
|
+
* "append" updates a map, "exists" checks that map.
|
|
47
|
+
* An instance of this class can merge another instance's cached nullifiers into its own.
|
|
48
|
+
*/
|
|
49
|
+
export declare class NullifierCache {
|
|
50
|
+
/**
|
|
51
|
+
* Map for staging nullifiers.
|
|
52
|
+
* One inner-set per contract storage address,
|
|
53
|
+
* each entry being a nullifier.
|
|
54
|
+
*/
|
|
55
|
+
private cachePerContract;
|
|
56
|
+
/**
|
|
57
|
+
* Check whether a nullifier exists in the cache.
|
|
58
|
+
*
|
|
59
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
60
|
+
* @param nullifier - the nullifier to check existence of
|
|
61
|
+
* @returns whether the nullifier is found in the cache
|
|
62
|
+
*/
|
|
63
|
+
exists(storageAddress: Fr, nullifier: Fr): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Stage a new nullifier (append it to the cache).
|
|
66
|
+
*
|
|
67
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
68
|
+
* @param nullifier - the nullifier to stage
|
|
69
|
+
*/
|
|
70
|
+
append(storageAddress: Fr, nullifier: Fr): void;
|
|
71
|
+
/**
|
|
72
|
+
* Merge another cache's nullifiers into this instance's.
|
|
73
|
+
*
|
|
74
|
+
* Cached nullifiers in "incoming" must not collide with any present in "this".
|
|
75
|
+
*
|
|
76
|
+
* In practice, "this" is a parent call's pending nullifiers, and "incoming" is a nested call's.
|
|
77
|
+
*
|
|
78
|
+
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
79
|
+
*/
|
|
80
|
+
acceptAndMerge(incomingNullifiers: NullifierCache): void;
|
|
81
|
+
}
|
|
82
|
+
export declare class NullifierCollisionError extends Error {
|
|
83
|
+
constructor(message: string, ...rest: any[]);
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=nullifiers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nullifiers.d.ts","sourceRoot":"","sources":["../../../src/avm/journal/nullifiers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AAE9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD;;;;GAIG;AACH,qBAAa,UAAU;IACrB,yBAAyB;IACzB,OAAO,CAAC,KAAK,CAAiB;IAC9B,uDAAuD;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,+DAA+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;gBAEnC,cAAc,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,UAAU;IAM9D;;;;;;;;;;;;OAYG;IACU,WAAW,CACtB,cAAc,EAAE,EAAE,EAClB,SAAS,EAAE,EAAE,GACZ,OAAO,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,cAAc,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;IAmB5E;;;;;OAKG;IACU,MAAM,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE;IAUrD;;;;OAIG;IACI,cAAc,CAAC,kBAAkB,EAAE,UAAU;CAGrD;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAuC;IAE/D;;;;;;OAMG;IACI,MAAM,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,GAAG,OAAO;IAKzD;;;;;OAKG;IACI,MAAM,CAAC,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE;IAe/C;;;;;;;;OAQG;IACI,cAAc,CAAC,kBAAkB,EAAE,cAAc;CAsBzD;AAED,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE;CAI5C"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { siloNullifier } from '@aztec/circuits.js/hash';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
/**
|
|
4
|
+
* A class to manage new nullifier staging and existence checks during a contract call's AVM simulation.
|
|
5
|
+
* Maintains a nullifier cache, and ensures that existence checks fall back to the correct source.
|
|
6
|
+
* When a contract call completes, its cached nullifier set can be merged into its parent's.
|
|
7
|
+
*/
|
|
8
|
+
export class Nullifiers {
|
|
9
|
+
constructor(hostNullifiers, parent) {
|
|
10
|
+
this.hostNullifiers = hostNullifiers;
|
|
11
|
+
this.parentCache = parent?.cache;
|
|
12
|
+
this.cache = new NullifierCache();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Get a nullifier's existence status.
|
|
16
|
+
* 1. Check cache.
|
|
17
|
+
* 2. Check parent's cache.
|
|
18
|
+
* 3. Fall back to the host state.
|
|
19
|
+
* 4. Not found! Nullifier does not exist.
|
|
20
|
+
*
|
|
21
|
+
* @param storageAddress - the address of the contract whose storage is being read from
|
|
22
|
+
* @param nullifier - the nullifier to check for
|
|
23
|
+
* @returns exists: whether the nullifier exists at all,
|
|
24
|
+
* isPending: whether the nullifier was found in a cache,
|
|
25
|
+
* leafIndex: the nullifier's leaf index if it exists and is not pending (comes from host state).
|
|
26
|
+
*/
|
|
27
|
+
async checkExists(storageAddress, nullifier) {
|
|
28
|
+
// First check this cache
|
|
29
|
+
let existsAsPending = this.cache.exists(storageAddress, nullifier);
|
|
30
|
+
// Then check parent's cache
|
|
31
|
+
if (!existsAsPending && this.parentCache) {
|
|
32
|
+
existsAsPending = this.parentCache?.exists(storageAddress, nullifier);
|
|
33
|
+
}
|
|
34
|
+
// Finally try the host's Aztec state (a trip to the database)
|
|
35
|
+
// If the value is found in the database, it will be associated with a leaf index!
|
|
36
|
+
let leafIndex = undefined;
|
|
37
|
+
if (!existsAsPending) {
|
|
38
|
+
// silo the nullifier before checking for its existence in the host
|
|
39
|
+
leafIndex = await this.hostNullifiers.getNullifierIndex(siloNullifier(storageAddress, nullifier));
|
|
40
|
+
}
|
|
41
|
+
const exists = existsAsPending || leafIndex !== undefined;
|
|
42
|
+
leafIndex = leafIndex === undefined ? BigInt(0) : leafIndex;
|
|
43
|
+
return Promise.resolve([exists, existsAsPending, new Fr(leafIndex)]);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Stage a new nullifier (append it to the cache).
|
|
47
|
+
*
|
|
48
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
49
|
+
* @param nullifier - the nullifier to stage
|
|
50
|
+
*/
|
|
51
|
+
async append(storageAddress, nullifier) {
|
|
52
|
+
const [exists, ,] = await this.checkExists(storageAddress, nullifier);
|
|
53
|
+
if (exists) {
|
|
54
|
+
throw new NullifierCollisionError(`Nullifier ${nullifier} at contract ${storageAddress} already exists in parent cache or host.`);
|
|
55
|
+
}
|
|
56
|
+
this.cache.append(storageAddress, nullifier);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Merges another nullifier cache into this one.
|
|
60
|
+
*
|
|
61
|
+
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
62
|
+
*/
|
|
63
|
+
acceptAndMerge(incomingNullifiers) {
|
|
64
|
+
this.cache.acceptAndMerge(incomingNullifiers.cache);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A class to cache nullifiers created during a contract call's AVM simulation.
|
|
69
|
+
* "append" updates a map, "exists" checks that map.
|
|
70
|
+
* An instance of this class can merge another instance's cached nullifiers into its own.
|
|
71
|
+
*/
|
|
72
|
+
export class NullifierCache {
|
|
73
|
+
constructor() {
|
|
74
|
+
/**
|
|
75
|
+
* Map for staging nullifiers.
|
|
76
|
+
* One inner-set per contract storage address,
|
|
77
|
+
* each entry being a nullifier.
|
|
78
|
+
*/
|
|
79
|
+
this.cachePerContract = new Map();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check whether a nullifier exists in the cache.
|
|
83
|
+
*
|
|
84
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
85
|
+
* @param nullifier - the nullifier to check existence of
|
|
86
|
+
* @returns whether the nullifier is found in the cache
|
|
87
|
+
*/
|
|
88
|
+
exists(storageAddress, nullifier) {
|
|
89
|
+
const exists = this.cachePerContract.get(storageAddress.toBigInt())?.has(nullifier.toBigInt());
|
|
90
|
+
return exists ? true : false;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Stage a new nullifier (append it to the cache).
|
|
94
|
+
*
|
|
95
|
+
* @param storageAddress - the address of the contract that the nullifier is associated with
|
|
96
|
+
* @param nullifier - the nullifier to stage
|
|
97
|
+
*/
|
|
98
|
+
append(storageAddress, nullifier) {
|
|
99
|
+
let nullifiersForContract = this.cachePerContract.get(storageAddress.toBigInt());
|
|
100
|
+
// If this contract's nullifier set has no cached nullifiers, create a new Set to store them
|
|
101
|
+
if (!nullifiersForContract) {
|
|
102
|
+
nullifiersForContract = new Set();
|
|
103
|
+
this.cachePerContract.set(storageAddress.toBigInt(), nullifiersForContract);
|
|
104
|
+
}
|
|
105
|
+
if (nullifiersForContract.has(nullifier.toBigInt())) {
|
|
106
|
+
throw new NullifierCollisionError(`Nullifier ${nullifier} at contract ${storageAddress} already exists in cache.`);
|
|
107
|
+
}
|
|
108
|
+
nullifiersForContract.add(nullifier.toBigInt());
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Merge another cache's nullifiers into this instance's.
|
|
112
|
+
*
|
|
113
|
+
* Cached nullifiers in "incoming" must not collide with any present in "this".
|
|
114
|
+
*
|
|
115
|
+
* In practice, "this" is a parent call's pending nullifiers, and "incoming" is a nested call's.
|
|
116
|
+
*
|
|
117
|
+
* @param incomingNullifiers - the incoming cached nullifiers to merge into this instance's
|
|
118
|
+
*/
|
|
119
|
+
acceptAndMerge(incomingNullifiers) {
|
|
120
|
+
// Iterate over all contracts with staged writes in the child.
|
|
121
|
+
for (const [incomingAddress, incomingCacheAtContract] of incomingNullifiers.cachePerContract) {
|
|
122
|
+
const thisCacheAtContract = this.cachePerContract.get(incomingAddress);
|
|
123
|
+
if (!thisCacheAtContract) {
|
|
124
|
+
// This contract has no nullifiers cached here
|
|
125
|
+
// so just accept incoming cache as-is for this contract.
|
|
126
|
+
this.cachePerContract.set(incomingAddress, incomingCacheAtContract);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
// "Incoming" and "this" both have cached nullifiers for this contract.
|
|
130
|
+
// Merge in incoming nullifiers, erroring if there are any duplicates.
|
|
131
|
+
for (const nullifier of incomingCacheAtContract) {
|
|
132
|
+
if (thisCacheAtContract.has(nullifier)) {
|
|
133
|
+
throw new NullifierCollisionError(`Failed to accept child call's nullifiers. Nullifier ${nullifier} already exists at contract ${incomingAddress}.`);
|
|
134
|
+
}
|
|
135
|
+
thisCacheAtContract.add(nullifier);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class NullifierCollisionError extends Error {
|
|
142
|
+
constructor(message, ...rest) {
|
|
143
|
+
super(message, ...rest);
|
|
144
|
+
this.name = 'NullifierCollisionError';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbGlmaWVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9hdm0vam91cm5hbC9udWxsaWZpZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFJOUM7Ozs7R0FJRztBQUNILE1BQU0sT0FBTyxVQUFVO0lBUXJCLFlBQVksY0FBNkIsRUFBRSxNQUFtQjtRQUM1RCxJQUFJLENBQUMsY0FBYyxHQUFHLGNBQWMsQ0FBQztRQUNyQyxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sRUFBRSxLQUFLLENBQUM7UUFDakMsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLGNBQWMsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSSxLQUFLLENBQUMsV0FBVyxDQUN0QixjQUFrQixFQUNsQixTQUFhO1FBRWIseUJBQXlCO1FBQ3pCLElBQUksZUFBZSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNuRSw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekMsZUFBZSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLGNBQWMsRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsOERBQThEO1FBQzlELGtGQUFrRjtRQUNsRixJQUFJLFNBQVMsR0FBdUIsU0FBUyxDQUFDO1FBQzlDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNyQixtRUFBbUU7WUFDbkUsU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxDQUFD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
|