From 5caf365d2afa345805fa2b97abed319e2416dd79 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 5 Jan 2024 11:48:27 +0000 Subject: [PATCH 01/18] feat: start working on counters --- .../acir-simulator/src/acvm/deserialize.ts | 4 +- .../acir-simulator/src/acvm/oracle/oracle.ts | 4 + .../src/acvm/oracle/typed_oracle.ts | 2 + .../src/client/client_execution_context.ts | 31 +- .../src/client/private_execution.test.ts | 4 +- .../acir-simulator/src/client/simulator.ts | 2 +- .../acir-simulator/src/public/index.test.ts | 14 +- .../src/public/public_execution_context.ts | 2 +- yarn-project/aztec-nr/aztec/src/context.nr | 16 +- .../aztec/src/oracle/call_private_function.nr | 13 +- .../oracle/enqueue_public_function_call.nr | 13 +- yarn-project/circuits.js/src/abis/abis.ts | 2 +- .../circuits.js/src/structs/call_context.ts | 8 +- .../circuits.js/src/tests/factories.ts | 4 +- .../src/__snapshots__/index.test.ts.snap | 360 +++++++++--------- .../nested-call-private-kernel-inner.hex | 2 +- .../noir-protocol-circuits/src/index.test.ts | 11 +- .../src/type_conversion.ts | 4 +- .../src/sequencer/public_processor.test.ts | 11 +- 19 files changed, 268 insertions(+), 239 deletions(-) diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index e9320f92c2bb..d8d9866454fa 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -172,7 +172,7 @@ export function extractPrivateCircuitPublicInputs( frToBoolean(witnessReader.readField()), frToBoolean(witnessReader.readField()), frToBoolean(witnessReader.readField()), - witnessReader.readField(), + frToNumber(witnessReader.readField()), ); const argsHash = witnessReader.readField(); @@ -251,7 +251,7 @@ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, ac frToBoolean(witnessReader.readField()), frToBoolean(witnessReader.readField()), frToBoolean(witnessReader.readField()), - witnessReader.readField(), + frToNumber(witnessReader.readField()), ); const argsHash = witnessReader.readField(); diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index 1bc1200f2ffb..fd014c9da2ba 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -291,11 +291,13 @@ export class Oracle { [contractAddress]: ACVMField[], [functionSelector]: ACVMField[], [argsHash]: ACVMField[], + [sideffectCounter]: ACVMField[], ): Promise { const callStackItem = await this.typedOracle.callPrivateFunction( AztecAddress.fromField(fromACVMField(contractAddress)), FunctionSelector.fromField(fromACVMField(functionSelector)), fromACVMField(argsHash), + frToNumber(fromACVMField(sideffectCounter)), ); return toAcvmCallPrivateStackItem(callStackItem); } @@ -317,11 +319,13 @@ export class Oracle { [contractAddress]: ACVMField[], [functionSelector]: ACVMField[], [argsHash]: ACVMField[], + [sideffectCounter]: ACVMField[], ) { const enqueuedRequest = await this.typedOracle.enqueuePublicFunctionCall( AztecAddress.fromString(contractAddress), FunctionSelector.fromField(fromACVMField(functionSelector)), fromACVMField(argsHash), + frToNumber(fromACVMField(sideffectCounter)), ); return toAcvmEnqueuePublicFunctionResult(enqueuedRequest); } diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index d1d4419b1f25..be8596717ed4 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -181,6 +181,7 @@ export abstract class TypedOracle { _targetContractAddress: AztecAddress, _functionSelector: FunctionSelector, _argsHash: Fr, + _sideffectCounter: number, ): Promise { throw new Error('Not available.'); } @@ -197,6 +198,7 @@ export abstract class TypedOracle { _targetContractAddress: AztecAddress, _functionSelector: FunctionSelector, _argsHash: Fr, + _sideffectCounter: number, ): Promise { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 8a33b50ef90c..94e2a2a799e4 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -301,9 +301,15 @@ export class ClientExecutionContext extends ViewDataOracle { * @param targetContractAddress - The address of the contract to call. * @param functionSelector - The function selector of the function to call. * @param argsHash - The packed arguments to pass to the function. + * @param sideffectCounter - The side effect counter at the start of the call. * @returns The execution result. */ - async callPrivateFunction(targetContractAddress: AztecAddress, functionSelector: FunctionSelector, argsHash: Fr) { + async callPrivateFunction( + targetContractAddress: AztecAddress, + functionSelector: FunctionSelector, + argsHash: Fr, + sideffectCounter: number, + ) { this.log( `Calling private function ${this.contractAddress}:${functionSelector} from ${this.callContext.storageContractAddress}`, ); @@ -320,7 +326,13 @@ export class ClientExecutionContext extends ViewDataOracle { this.txContext.version, ); - const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, false, false); + const derivedCallContext = await this.deriveCallContext( + targetContractAddress, + targetArtifact, + sideffectCounter, + false, + false, + ); const context = new ClientExecutionContext( targetContractAddress, @@ -355,17 +367,24 @@ export class ClientExecutionContext extends ViewDataOracle { * @param targetContractAddress - The address of the contract to call. * @param functionSelector - The function selector of the function to call. * @param argsHash - The packed arguments to pass to the function. + * @param sideEffectCounter - The side effect counter at the start of the call. * @returns The public call stack item with the request information. */ public async enqueuePublicFunctionCall( targetContractAddress: AztecAddress, functionSelector: FunctionSelector, argsHash: Fr, + sideEffectCounter: number, ): Promise { const targetArtifact = await this.db.getFunctionArtifact(targetContractAddress, functionSelector); - const derivedCallContext = await this.deriveCallContext(targetContractAddress, targetArtifact, false, false); + const derivedCallContext = await this.deriveCallContext( + targetContractAddress, + targetArtifact, + sideEffectCounter, + false, + false, + ); const args = this.packedArgsCache.unpack(argsHash); - const sideEffectCounter = this.sideEffectCounter.count(); const enqueuedRequest = PublicCallRequest.from({ args, callContext: derivedCallContext, @@ -391,6 +410,7 @@ export class ClientExecutionContext extends ViewDataOracle { * Derives the call context for a nested execution. * @param targetContractAddress - The address of the contract being called. * @param targetArtifact - The artifact of the function being called. + * @param startSideEffectCounter - The side effect counter at the start of the call. * @param isDelegateCall - Whether the call is a delegate call. * @param isStaticCall - Whether the call is a static call. * @returns The derived call context. @@ -398,6 +418,7 @@ export class ClientExecutionContext extends ViewDataOracle { private async deriveCallContext( targetContractAddress: AztecAddress, targetArtifact: FunctionArtifact, + startSideEffectCounter: number, isDelegateCall = false, isStaticCall = false, ) { @@ -410,7 +431,7 @@ export class ClientExecutionContext extends ViewDataOracle { isDelegateCall, isStaticCall, false, - Fr.ZERO, + startSideEffectCounter, ); } } diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 2b9d4d66972b..fd5f096ed5ea 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -581,9 +581,9 @@ describe('Private Execution test suite', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 1, }), - sideEffectCounter: 0, + sideEffectCounter: 1, }); const publicCallRequestHash = publicCallRequest.toPublicCallStackItem().hash(); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index b34093e983cc..551b2820253c 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -88,7 +88,7 @@ export class AcirSimulator { false, false, request.functionData.isConstructor, - Fr.ZERO, // TODO(dan): actual value + 1, // TODO(alvaro): reevaluate this ); const context = new ClientExecutionContext( contractAddress, diff --git a/yarn-project/acir-simulator/src/public/index.test.ts b/yarn-project/acir-simulator/src/public/index.test.ts index 59823b69d2bb..05d9654ae476 100644 --- a/yarn-project/acir-simulator/src/public/index.test.ts +++ b/yarn-project/acir-simulator/src/public/index.test.ts @@ -62,7 +62,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintArtifact.bytecode, 'base64')); @@ -140,7 +140,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); recipientStorageSlot = computeSlotForMapping(new Fr(6n), recipient.toField()); @@ -236,7 +236,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); // eslint-disable-next-line require-await @@ -305,7 +305,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); publicContracts.getBytecode.mockResolvedValue(Buffer.from(shieldArtifact.bytecode, 'base64')); @@ -338,7 +338,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); publicContracts.getBytecode.mockResolvedValue(Buffer.from(createL2ToL1MessagePublicArtifact.bytecode, 'base64')); @@ -388,7 +388,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); publicContracts.getBytecode.mockResolvedValue(Buffer.from(mintPublicArtifact.bytecode, 'base64')); @@ -431,7 +431,7 @@ describe('ACIR public execution simulator', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, }); publicContracts.getBytecode.mockResolvedValue(Buffer.from(createNullifierPublicArtifact.bytecode, 'base64')); diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index 8f6a40e8a50e..f5b9cd7c1133 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -199,7 +199,7 @@ export class PublicExecutionContext extends TypedOracle { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: Fr.ZERO, + startSideEffectCounter: 0, // TODO(alvaro) reevaluate this }); const nestedExecution: PublicExecution = { diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index 39bab7bce955..8747499be8f1 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -93,9 +93,7 @@ impl PrivateContext { pub fn new(inputs: PrivateContextInputs, args_hash: Field) -> PrivateContext { PrivateContext { inputs: inputs, - // starts at 1 because all private calls have txhash nullifier as 0th nullifier - // and therefore 0th sideeffect. increment this for each side effect in this context - side_effect_counter: 1, + side_effect_counter: inputs.call_context.start_side_effect_counter, args_hash: args_hash, return_values: BoundedVec::new(0), @@ -270,6 +268,7 @@ impl PrivateContext { contract_address, function_selector, args_hash, + self.side_effect_counter, ); let mut reader = Reader::new(fields); @@ -332,6 +331,9 @@ impl PrivateContext { }; reader.finish(); + + assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter); + self.side_effect_counter = item.public_inputs.end_side_effect_counter + 1; assert(contract_address.eq(item.contract_address)); assert(function_selector.eq(item.function_data.selector)); @@ -383,7 +385,8 @@ impl PrivateContext { let fields = enqueue_public_function_call_internal( contract_address, function_selector, - args_hash + args_hash, + self.side_effect_counter ); let item = PublicCallStackItem { contract_address: AztecAddress::from_field(fields[0]), @@ -422,6 +425,9 @@ impl PrivateContext { assert(contract_address.eq(item.contract_address)); assert(function_selector.eq(item.function_data.selector)); + + assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter); + self.side_effect_counter = self.side_effect_counter + 1; assert(args_hash == item.public_inputs.args_hash); @@ -468,7 +474,7 @@ impl PublicContext { let empty_storage_update = StorageUpdateRequest::empty(); PublicContext { inputs: inputs, - side_effect_counter: 0, // no initial nullifier in new public context. increment on every side effect + side_effect_counter: inputs.call_context.start_side_effect_counter, args_hash: args_hash, return_values: BoundedVec::new(0), diff --git a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr index ce4054e91c6c..b1e9a95bb63b 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr @@ -8,13 +8,20 @@ use dep::protocol_types::{ fn call_private_function_oracle( _contract_address: AztecAddress, _function_selector: FunctionSelector, - _args_hash: Field + _args_hash: Field, + _start_side_effect_counter: Field ) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {} unconstrained pub fn call_private_function_internal( contract_address: AztecAddress, function_selector: FunctionSelector, - args_hash: Field + args_hash: Field, + start_side_effect_counter: Field ) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] { - call_private_function_oracle(contract_address, function_selector, args_hash) + call_private_function_oracle( + contract_address, + function_selector, + args_hash, + start_side_effect_counter + ) } diff --git a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index 308a75dc5ccd..d5beb083ed60 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -14,13 +14,20 @@ global ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 14; fn enqueue_public_function_call_oracle( _contract_address: AztecAddress, _function_selector: FunctionSelector, - _args_hash: Field + _args_hash: Field, + _side_effect_counter: Field ) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {} unconstrained pub fn enqueue_public_function_call_internal( contract_address: AztecAddress, function_selector: FunctionSelector, - args_hash: Field + args_hash: Field, + side_effect_counter: Field ) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] { - enqueue_public_function_call_oracle(contract_address, function_selector, args_hash) + enqueue_public_function_call_oracle( + contract_address, + function_selector, + args_hash, + side_effect_counter + ) } diff --git a/yarn-project/circuits.js/src/abis/abis.ts b/yarn-project/circuits.js/src/abis/abis.ts index 37d3d2d70c2b..c190edd9d1f8 100644 --- a/yarn-project/circuits.js/src/abis/abis.ts +++ b/yarn-project/circuits.js/src/abis/abis.ts @@ -518,7 +518,7 @@ function computeCallContextHash(input: CallContext) { boolToBuffer(input.isDelegateCall, 32), boolToBuffer(input.isStaticCall, 32), boolToBuffer(input.isContractDeployment, 32), - input.startSideEffectCounter.toBuffer(), + numToUInt32BE(input.startSideEffectCounter, 32), ], GeneratorIndex.CALL_CONTEXT, ); diff --git a/yarn-project/circuits.js/src/structs/call_context.ts b/yarn-project/circuits.js/src/structs/call_context.ts index fd5d24c676cb..be12ebf4c131 100644 --- a/yarn-project/circuits.js/src/structs/call_context.ts +++ b/yarn-project/circuits.js/src/structs/call_context.ts @@ -50,7 +50,7 @@ export class CallContext { /** * The start side effect counter for this call context. */ - public startSideEffectCounter: Fr, + public startSideEffectCounter: number, ) { this.portalContractAddress = portalContractAddress instanceof EthAddress ? portalContractAddress : EthAddress.fromField(portalContractAddress); @@ -69,7 +69,7 @@ export class CallContext { false, false, false, - Fr.ZERO, + 0, ); } @@ -79,7 +79,7 @@ export class CallContext { this.storageContractAddress.isZero() && this.portalContractAddress.isZero() && this.functionSelector.isEmpty() && - this.startSideEffectCounter.isZero() + Fr.ZERO ); } @@ -123,7 +123,7 @@ export class CallContext { reader.readBoolean(), reader.readBoolean(), reader.readBoolean(), - reader.readObject(Fr), + reader.readNumber(), ); } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 1fa052237e0c..2b77ce79c207 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -326,7 +326,7 @@ export function makeCallContext(seed = 0, storageContractAddress = makeAztecAddr false, false, false, - Fr.ZERO, + 0, ); } @@ -682,7 +682,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn true, true, true, - Fr.ZERO, + 0, ), argsHash: fr(seed + 0x100), returnValues: makeTuple(RETURN_VALUES_LENGTH, fr, seed + 0x200), diff --git a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap index 914862b4c8ba..5467270f4d88 100644 --- a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap @@ -32629,121 +32629,121 @@ KernelCircuitPublicInputs { "constants": CombinedConstantData { "blockHeader": BlockHeader { "archiveRoot": Fr { - "asBigInt": 3299595034698027116738088638163396111360028306801805379304156120235869845371n, + "asBigInt": 20372018159471621712773206616781399243089284083897629004165638733497278836368n, "asBuffer": { "data": [ - 7, - 75, - 129, 45, - 249, - 140, - 58, - 172, - 75, - 153, - 16, - 20, - 63, - 150, - 246, - 163, - 224, - 99, + 10, 39, - 175, - 89, - 147, - 23, - 121, + 86, + 151, + 28, 147, - 204, - 156, + 221, + 193, 180, - 11, - 229, - 183, - 123, + 251, + 133, + 176, + 163, + 143, + 86, + 29, + 222, + 109, + 190, + 209, + 92, + 25, + 252, + 185, + 2, + 148, + 253, + 230, + 102, + 174, + 144, ], "type": "Buffer", }, }, "contractTreeRoot": Fr { - "asBigInt": 2879234336266878181756829670765400405971457647584261815888127470791174819386n, + "asBigInt": 14917511466805779502198250944232247270950372922289035175844919622811814316704n, "asBuffer": { "data": [ - 6, - 93, - 150, - 193, - 23, - 240, - 156, - 175, - 64, - 114, - 139, - 161, - 45, - 5, - 225, - 173, - 232, + 32, + 251, + 3, + 36, + 219, + 51, + 241, + 141, + 112, + 62, + 65, + 78, + 49, + 138, + 228, + 237, + 96, + 212, + 126, + 208, + 2, + 74, + 124, + 46, 56, - 22, - 137, + 24, + 184, 115, - 178, - 218, - 102, - 11, - 243, 169, - 102, - 226, - 118, - 142, - 58, + 153, + 202, + 160, ], "type": "Buffer", }, }, "globalVariablesHash": Fr { - "asBigInt": 18254267241644890096728458946550484409940937079286178749169742669812331885298n, + "asBigInt": 2339684137567523517345226739343572726453743526214691264476956870525775001728n, "asBuffer": { "data": [ - 40, - 91, - 140, - 147, - 74, - 62, - 47, - 64, - 236, + 5, + 44, + 54, + 219, + 239, + 243, + 182, + 206, + 85, + 90, + 124, + 142, + 224, + 106, 84, + 231, + 191, + 155, + 56, + 48, + 46, + 91, + 242, + 101, + 182, + 41, + 102, 190, - 127, - 168, - 224, 62, - 116, - 135, - 215, - 129, - 120, - 214, - 16, - 179, - 80, - 25, - 105, - 252, - 49, - 42, - 150, - 178, - 242, + 204, + 56, + 128, ], "type": "Buffer", }, @@ -32789,81 +32789,81 @@ KernelCircuitPublicInputs { }, }, "noteHashTreeRoot": Fr { - "asBigInt": 20703490723412199954362500516772754147411917280953300915777405940555593478689n, + "asBigInt": 981923962123739841860000837864904074407773873785560232542331187019926149423n, "asBuffer": { "data": [ - 45, - 197, - 194, - 175, - 81, - 222, - 190, - 31, - 122, - 39, - 236, - 120, - 188, - 231, - 38, - 223, - 14, - 174, - 178, - 71, + 2, + 43, + 191, + 207, + 255, 135, - 50, - 140, - 92, - 94, - 242, - 192, - 182, + 229, + 206, + 199, + 96, + 16, + 217, 240, - 118, - 242, - 33, + 31, + 71, + 249, + 233, + 174, + 64, + 191, + 114, + 239, + 27, + 52, + 163, + 196, + 167, + 143, + 3, + 163, + 25, + 47, ], "type": "Buffer", }, }, "nullifierTreeRoot": Fr { - "asBigInt": 17652333472279191628437064764403898538839808648712907820426539548317448237907n, + "asBigInt": 13649330571405803453188645801233118952397925720323129467963581146586569980764n, "asBuffer": { "data": [ - 39, - 6, - 221, - 222, - 228, - 197, - 54, - 156, - 4, - 14, - 202, - 231, - 239, - 136, - 56, - 187, - 11, - 132, - 61, - 32, - 78, - 231, - 77, + 30, + 45, 63, - 38, + 81, + 21, + 13, + 218, + 53, + 98, 33, - 135, - 88, + 245, 88, - 145, - 115, - 83, + 96, + 244, + 62, + 153, + 244, + 25, + 156, + 226, + 242, + 63, + 191, + 240, + 25, + 13, + 33, + 222, + 114, + 251, + 59, + 92, ], "type": "Buffer", }, @@ -39102,41 +39102,41 @@ KernelCircuitPublicInputs { }, }, "value": Fr { - "asBigInt": 439257366008177876615157226684274709274740260231685565681056234861272560222n, + "asBigInt": 6829908051101542233177273165904445376377164813196839000974832044882663163261n, "asBuffer": { "data": [ - 0, - 248, - 156, - 97, - 60, - 193, - 49, - 109, - 87, - 103, - 168, - 144, - 202, - 124, + 15, + 25, + 151, + 73, 132, - 122, - 167, - 27, - 144, - 231, - 198, + 139, + 131, + 68, + 116, + 226, + 229, + 188, + 245, + 21, + 243, + 85, + 158, + 211, + 129, + 202, + 99, + 245, + 133, + 199, + 248, + 228, + 115, + 65, + 249, 201, - 143, - 233, + 197, 125, - 145, - 132, - 41, - 183, - 72, - 242, - 94, ], "type": "Buffer", }, diff --git a/yarn-project/noir-protocol-circuits/src/fixtures/nested-call-private-kernel-inner.hex b/yarn-project/noir-protocol-circuits/src/fixtures/nested-call-private-kernel-inner.hex index 5b60aa0a6fb4..cf767299f914 100644 --- a/yarn-project/noir-protocol-circuits/src/fixtures/nested-call-private-kernel-inner.hex +++ b/yarn-project/noir-protocol-circuits/src/fixtures/nested-call-private-kernel-inner.hex @@ -1 +1 @@ -0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f89c613cc1316d5767a890ca7c847aa71b90e7c6c98fe97d918429b748f25e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000179e8197f0e67b6fb7a3b790dd5c1252e735ee560df89d1c72042bb3309f562a0079a595831a8626aa3bc41db79e8f59cbcc0e811f8b511634651b6d416c997900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb2000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002dc5c2af51debe1f7a27ec78bce726df0eaeb24787328c5c5ef2c0b6f076f2212706dddee4c5369c040ecae7ef8838bb0b843d204ee74d3f2621875858917353065d96c117f09caf40728ba12d05e1ade838168973b2da660bf3a966e2768e3a1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80074b812df98c3aac4b9910143f96f6a3e06327af5993177993cc9cb40be5b77b00000000000000000000000000000000000000000000000000000000000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0285b8c934a3e2f40ec54be7fa8e03e7487d78178d610b3501969fc312a96b2f20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000001de3e3a312406f1cc4bd44a25b3a826f60ac227760cd564f0a239af234e340b20388a53040e1fda7ea40c501ee9af343d7a495a4886734cb0ea6f7943d814e871b36f5070d67d75f4f16d194141a5601171d2e5997221d9674c7ed66c8f66b8a25fd053f219608ec8c79a81d9bddaf834d51cef1a223d1e10ab92f41f8b3c38f0906bca10001000079a595831a8626aa3bc41db79e8f59cbcc0e811f8b511634651b6d416c997925fd053f219608ec8c79a81d9bddaf834d51cef1a223d1e10ab92f41f8b3c38f00000000000000000000000000000000000000000000000000000000000000000906bca100000000000000000000000000000000000000000000000000000000000000000000001124bf00bac5cd7fc8570fe0e40c34b8d093801a155d53e0b478d960b3a424810000000000000000000000000000000000000000000000000000000000007a6a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b855000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000042dc5c2af51debe1f7a27ec78bce726df0eaeb24787328c5c5ef2c0b6f076f2212706dddee4c5369c040ecae7ef8838bb0b843d204ee74d3f2621875858917353065d96c117f09caf40728ba12d05e1ade838168973b2da660bf3a966e2768e3a1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80074b812df98c3aac4b9910143f96f6a3e06327af5993177993cc9cb40be5b77b00000000000000000000000000000000000000000000000000000000000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0285b8c934a3e2f40ec54be7fa8e03e7487d78178d610b3501969fc312a96b2f20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000000000000000000000000000000000000000000000000000000000000722a1419dd08e208cd862bb66fb009fa540fb7178d01108f79eb78a891064685603f30687851ce0bc4df8e4fa8a5809643e9ae7f752a3ec1e3c120b251036c92e14ae899cd34041169f2476b70040373713d6eb363e74dca7f7f70f36d286b92f044b59fe1a64065611c9ec171fc760af4337fd13bbb833a9b021cfdde27a7f621a9fdb505152f9c2baaffe4a30ee80775b58ebf8c2dde76435835b085c6f70ca0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000027b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed0aa5aaf3632eb02010fb1cefb82a6de258870b1c579d3fd3bf435631ead8fcb90bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa015d28cad4c0736decea8997cb324cf0a0e0602f4d74472cd977bce2c8dd9923f268ed1e1c94c3a45a14db4108bc306613a1c23fab68e0466a002dfb0a3f8d2ab0cd8d5695bc2dde99dd531671f76f1482f14ddba8eeca7cb9686d4a62359c257047fbb7eb974155702149e58ea6ad91f4c6e953e693db35e953e250d8ceac9a900c5ae2526e665e2c7c698c11a06098b7159f720606d50e7660deb55758b0b022ced19489ab456b8b6c424594cdbbae59c36dfdd4c4621c4032da2d8a9674be51df5a245ffc1da14b46fe56a605f2a47b1cff1592bab4f66cfe5dfe990af6ab52871d090615d14eadb52228c635c90e0adf31176f0814f6525c23e7d7b318c931a2b85ff013d4b2b25074297c7e44aa61f4836d0862b36db2e6ce2b5542f9ea9177b9a10bbee32f77c719c6f8d071a18476cbeb021e155c642bbf93c716ce94300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file +0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000001000000bd300000bd400000bd500000bd600000bd700000bd800000bd900000bda00000bdb00000bdc00000bdd00000bde00000bdf00000be000000be100000be2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f199749848b834474e2e5bcf515f3559ed381ca63f585c7f8e47341f9c9c57d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c2c4914c4adc9d775bd7eeee09cc5a37fc71593bd318e6b486221e53ee87b911c94912f5dcbc89ea72a8a498cdf68c5b74512b32b5ebc27dfd044cde2c6369600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000d3735899d9fa7162447ca631f0ba2cd500000000000000000000000000000000eb57d0965a756d78291da33072610eb200000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022bbfcfff87e5cec76010d9f01f47f9e9ae40bf72ef1b34a3c4a78f03a3192f1e2d3f51150dda356221f55860f43e99f4199ce2f23fbff0190d21de72fb3b5c20fb0324db33f18d703e414e318ae4ed60d47ed0024a7c2e3818b873a999caa01864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f802d0a2756971c93ddc1b4fb85b0a38f561dde6dbed15c19fcb90294fde666ae9000000000000000000000000000000000000000000000000000000000000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0052c36dbeff3b6ce555a7c8ee06a54e7bf9b38302e5bf265b62966be3ecc38800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000101000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f0000000021f11a5439c373c3d91f5e4910a93aa16f061a642d7d2706be18a85ca84956d92fdcf6231c3596a614cfaa28a09bc402a7a34bf9382931cfed022a77d99f3c8825d97e44dac3772af165e47e72c0e495c079c18217001478c687ec883706c41d090f534a8ef74012c96f8b4b842a0107e0ab6b043ab130d394cdad8f21518c9e0906bca10001001c94912f5dcbc89ea72a8a498cdf68c5b74512b32b5ebc27dfd044cde2c63696090f534a8ef74012c96f8b4b842a0107e0ab6b043ab130d394cdad8f21518c9e00000000000000000000000000000000000000000000000000000000000000000906bca1000000000000021124bf00bac5cd7fc8570fe0e40c34b8d093801a155d53e0b478d960b3a424810000000000000000000000000000000000000000000000000000000000007a6a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000e3b0c44298fc1c149afbf4c8996fb9240000000000000000000000000000000027ae41e4649b934ca495991b7852b85500000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004022bbfcfff87e5cec76010d9f01f47f9e9ae40bf72ef1b34a3c4a78f03a3192f1e2d3f51150dda356221f55860f43e99f4199ce2f23fbff0190d21de72fb3b5c20fb0324db33f18d703e414e318ae4ed60d47ed0024a7c2e3818b873a999caa01864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f802d0a2756971c93ddc1b4fb85b0a38f561dde6dbed15c19fcb90294fde666ae9000000000000000000000000000000000000000000000000000000000000000001ed250ed73db6e70805c4efcf0056e8695b79cd3ba418e827c184dee6c6fb0e0052c36dbeff3b6ce555a7c8ee06a54e7bf9b38302e5bf265b62966be3ecc38800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007a69000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000800000000740000000f00000003515f3109623eb3c25aa5b16a1a79fd558bac7a7ce62c4560a8c537c77ce80dd339128d1d37b6582ee9e6df9567efb64313471dfa18f520f9ce53161b50dbf7731bc5f900000003515f322bc4cce83a486a92c92fd59bd84e0f92595baa639fc2ed86b00ffa0dfded2a092a669a3bdb7a273a015eda494457cc7ed5236f26cee330c290d45a33b9daa94800000003515f332729426c008c085a81bd34d8ef12dd31e80130339ef99d50013a89e4558eee6d0fa4ffe2ee7b7b62eb92608b2251ac31396a718f9b34978888789042b790a30100000003515f342be6b6824a913eb7a57b03cb1ee7bfb4de02f2f65fe8a4e97baa7766ddb353a82a8a25c49dc63778cd9fe96173f12a2bc77f3682f4c4448f98f1df82c75234a100000003515f351f85760d6ab567465aadc2f180af9eae3800e6958fec96aef53fd8a7b195d7c000c6267a0dd5cfc22b3fe804f53e266069c0e36f51885baec1e7e67650c62e170000000c515f41524954484d455449430d9d0f8ece2aa12012fa21e6e5c859e97bd5704e5c122064a66051294bc5e04213f61f54a0ebdf6fee4d4a6ecf693478191de0c2899bcd8e86a636c8d3eff43400000003515f43224a99d02c86336737c8dd5b746c40d2be6aead8393889a76a18d664029096e90f7fe81adcc92a74350eada9622ac453f49ebac24a066a1f83b394df54dfa0130000000c515f46495845445f42415345060e8a013ed289c2f9fd7473b04f6594b138ddb4b4cf6b901622a14088f04b8d2c83ff74fce56e3d5573b99c7b26d85d5046ce0c6559506acb7a675e7713eb3a00000007515f4c4f4749430721a91cb8da4b917e054f72147e1760cfe0ef3d45090ac0f4961d84ec1996961a25e787b26bd8b50b1a99450f77a424a83513c2b33af268cd253b0587ff50c700000003515f4d05dbd8623b8652511e1eb38d38887a69eceb082f807514f09e127237c5213b401b9325b48c6c225968002318095f89d0ef9cf629b2b7f0172e03bc39aacf6ed800000007515f52414e474504b57a3805e41df328f5ca9aefa40fad5917391543b7b65c6476e60b8f72e9ad07c92f3b3e11c8feae96dedc4b14a6226ef3201244f37cfc1ee5b96781f48d2b000000075349474d415f3125001d1954a18571eaa007144c5a567bb0d2be4def08a8be918b8c05e3b27d312c59ed41e09e144eab5de77ca89a2fd783be702a47c951d3112e3de02ce6e47c000000075349474d415f3223994e6a23618e60fa01c449a7ab88378709197e186d48d604bfb6931ffb15ad11c5ec7a0700570f80088fd5198ab5d5c227f2ad2a455a6edeec024156bb7beb000000075349474d415f3300cda5845f23468a13275d18bddae27c6bb189cf9aa95b6a03a0cb6688c7e8d829639b45cf8607c525cc400b55ebf90205f2f378626dc3406cc59b2d1b474fba000000075349474d415f342d299e7928496ea2d37f10b43afd6a80c90a33b483090d18069ffa275eedb2fc2f82121e8de43dc036d99b478b6227ceef34248939987a19011f065d8b5cef5c0000000010000000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000000000000000000000000000000000000000000000000000000000000722a1419dd08e208cd862bb66fb009fa540fb7178d01108f79eb78a891064685603f30687851ce0bc4df8e4fa8a5809643e9ae7f752a3ec1e3c120b251036c92e14ae899cd34041169f2476b70040373713d6eb363e74dca7f7f70f36d286b92f044b59fe1a64065611c9ec171fc760af4337fd13bbb833a9b021cfdde27a7f621a9fdb505152f9c2baaffe4a30ee80775b58ebf8c2dde76435835b085c6f70ca0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000027b1d0839a5b23baf12a8d195b18ac288fcf401afb2f70b8a4b529ede5fa9fed0136d5c45fb886add133b29521494cbb3b13851ed146d0bfa6448d71dacb7c170bcd1f91cf7bdd471d0a30c58c4706f3fdab3807a954b8f5b5e3bfec87d001bb06e62084ee7b602fe9abc15632dda3269f56fb0c6e12519a2eb2ec897091919d03c9e2e67178ac638746f068907e6677b4cc7a9592ef234ab6ab518f17efffa015d28cad4c0736decea8997cb324cf0a0e0602f4d74472cd977bce2c8dd9923f268ed1e1c94c3a45a14db4108bc306613a1c23fab68e0466a002dfb0a3f8d2ab0cd8d5695bc2dde99dd531671f76f1482f14ddba8eeca7cb9686d4a62359c257047fbb7eb974155702149e58ea6ad91f4c6e953e693db35e953e250d8ceac9a900c5ae2526e665e2c7c698c11a06098b7159f720606d50e7660deb55758b0b022ced19489ab456b8b6c424594cdbbae59c36dfdd4c4621c4032da2d8a9674be51df5a245ffc1da14b46fe56a605f2a47b1cff1592bab4f66cfe5dfe990af6ab52871d090615d14eadb52228c635c90e0adf31176f0814f6525c23e7d7b318c931a2b85ff013d4b2b25074297c7e44aa61f4836d0862b36db2e6ce2b5542f9ea9177b9a10bbee32f77c719c6f8d071a18476cbeb021e155c642bbf93c716ce94300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index 3a5986cffa25..84aacbbfea77 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -113,16 +113,7 @@ describe('Private kernel', () => { Fr.ZERO, ); - const callContext = new CallContext( - AztecAddress.ZERO, - contractAddress, - Fr.ZERO, - selector, - false, - false, - true, - Fr.ZERO, - ); + const callContext = new CallContext(AztecAddress.ZERO, contractAddress, Fr.ZERO, selector, false, false, true, 0); const blockHeader = new BlockHeader( Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 4a250ab6eec1..0ddc38b0775d 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -373,7 +373,7 @@ export function mapCallContextFromNoir(callContext: CallContextNoir): CallContex callContext.is_delegate_call, callContext.is_static_call, callContext.is_contract_deployment, - Fr.ZERO, // TODO: actual counter + mapNumberFromNoir(callContext.start_side_effect_counter), ); } @@ -391,7 +391,7 @@ export function mapCallContextToNoir(callContext: CallContext): CallContextNoir is_delegate_call: callContext.isDelegateCall, is_static_call: callContext.isStaticCall, is_contract_deployment: callContext.isContractDeployment, - start_side_effect_counter: mapFieldToNoir(callContext.startSideEffectCounter), + start_side_effect_counter: mapNumberToNoir(callContext.startSideEffectCounter), }; } diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index 21c7863789d7..ca45e5353d81 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -289,16 +289,7 @@ function makePublicExecutionResult( tx: FunctionCall, nestedExecutions: PublicExecutionResult[] = [], ): PublicExecutionResult { - const callContext = new CallContext( - from, - tx.to, - EthAddress.ZERO, - tx.functionData.selector, - false, - false, - false, - Fr.ZERO, - ); + const callContext = new CallContext(from, tx.to, EthAddress.ZERO, tx.functionData.selector, false, false, false, 0); const execution: PublicExecution = { callContext, contractAddress: tx.to, From 5eb661844409ee81b952c20711cb24ad4643828c Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 5 Jan 2024 12:53:42 +0000 Subject: [PATCH 02/18] feat: remove sideffectCounter from public call request --- .../src/client/client_execution_context.ts | 1 - .../src/client/execution_result.ts | 2 +- .../src/client/private_execution.test.ts | 1 - yarn-project/aztec-nr/aztec/src/context.nr | 32 +++++++++++-------- .../oracle/enqueue_public_function_call.nr | 4 +-- .../src/structs/public_call_request.ts | 21 ++---------- .../circuits.js/src/tests/factories.ts | 1 - 7 files changed, 23 insertions(+), 39 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 94e2a2a799e4..2f5f5c434d0e 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -390,7 +390,6 @@ export class ClientExecutionContext extends ViewDataOracle { callContext: derivedCallContext, functionData: FunctionData.fromAbi(targetArtifact), contractAddress: targetContractAddress, - sideEffectCounter, }); // TODO($846): if enqueued public calls are associated with global diff --git a/yarn-project/acir-simulator/src/client/execution_result.ts b/yarn-project/acir-simulator/src/client/execution_result.ts index 8dc812ee963d..c04de6e63a61 100644 --- a/yarn-project/acir-simulator/src/client/execution_result.ts +++ b/yarn-project/acir-simulator/src/client/execution_result.ts @@ -83,5 +83,5 @@ export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult): return [ ...execResult.enqueuedPublicFunctionCalls, ...[...execResult.nestedExecutions].flatMap(collectEnqueuedPublicFunctionCalls), - ].sort((a, b) => b.sideEffectCounter! - a.sideEffectCounter!); // REVERSE SORT! + ].sort((a, b) => b.callContext.startSideEffectCounter - a.callContext.startSideEffectCounter); } diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index fd5f096ed5ea..fa7c6fd8ebac 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -583,7 +583,6 @@ describe('Private Execution test suite', () => { isStaticCall: false, startSideEffectCounter: 1, }), - sideEffectCounter: 1, }); const publicCallRequestHash = publicCallRequest.toPublicCallStackItem().hash(); diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index 8747499be8f1..949a173f0364 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -388,26 +388,29 @@ impl PrivateContext { args_hash, self.side_effect_counter ); + + let mut reader = Reader::new(fields); + let item = PublicCallStackItem { - contract_address: AztecAddress::from_field(fields[0]), + contract_address: AztecAddress::from_field(reader.read()), function_data: FunctionData { - selector: FunctionSelector::from_field(fields[1]), - is_internal: fields[2] as bool, - is_private: fields[3] as bool, - is_constructor: fields[4] as bool, + selector: FunctionSelector::from_field(reader.read()), + is_internal: reader.read() as bool, + is_private: reader.read() as bool, + is_constructor: reader.read() as bool, }, public_inputs: PublicCircuitPublicInputs { call_context: CallContext { - msg_sender : AztecAddress::from_field(fields[5]), - storage_contract_address : AztecAddress::from_field(fields[6]), - portal_contract_address : EthAddress::from_field(fields[7]), - function_selector: FunctionSelector::from_field(fields[8]), // practically same as fields[1] - is_delegate_call : fields[9] as bool, - is_static_call : fields[10] as bool, - is_contract_deployment: fields[11] as bool, - start_side_effect_counter: fields[12], + msg_sender : AztecAddress::from_field(reader.read()), + storage_contract_address : AztecAddress::from_field(reader.read()), + portal_contract_address : EthAddress::from_field(reader.read()), + function_selector: FunctionSelector::from_field(reader.read()), // practically same as fields[1] + is_delegate_call : reader.read() as bool, + is_static_call : reader.read() as bool, + is_contract_deployment: reader.read() as bool, + start_side_effect_counter: reader.read(), }, - args_hash: fields[13], + args_hash: reader.read(), return_values: [0; RETURN_VALUES_LENGTH], contract_storage_update_requests: [StorageUpdateRequest::empty(); MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL], contract_storage_reads: [StorageRead::empty(); MAX_PUBLIC_DATA_READS_PER_CALL], @@ -422,6 +425,7 @@ impl PrivateContext { }, is_execution_request: true, }; + reader.finish(); assert(contract_address.eq(item.contract_address)); assert(function_selector.eq(item.function_data.selector)); diff --git a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index d5beb083ed60..7cf6068a44a8 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -6,8 +6,8 @@ use dep::protocol_types::{ // contract_address + // args_hash + // crate::abi::FUNCTION_DATA_SIZE + -// crate::abi::CALL_CONTEXT_SIZE + side_effect_counter -// = 2 + 4 + 7 + 1 +// crate::abi::CALL_CONTEXT_SIZE +// = 2 + 4 + 8 global ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE: Field = 14; #[oracle(enqueuePublicFunctionCall)] diff --git a/yarn-project/circuits.js/src/structs/public_call_request.ts b/yarn-project/circuits.js/src/structs/public_call_request.ts index 337a07484594..60c756c00335 100644 --- a/yarn-project/circuits.js/src/structs/public_call_request.ts +++ b/yarn-project/circuits.js/src/structs/public_call_request.ts @@ -39,10 +39,6 @@ export class PublicCallRequest { * Function arguments. */ public args: Fr[], - /** - * Optional side effect counter tracking position of this event in tx execution. - */ - public sideEffectCounter: number, ) {} /** @@ -50,13 +46,7 @@ export class PublicCallRequest { * @returns The buffer. */ toBuffer() { - return serializeToBuffer( - this.contractAddress, - this.functionData, - this.callContext, - new Vector(this.args), - this.sideEffectCounter, - ); + return serializeToBuffer(this.contractAddress, this.functionData, this.callContext, new Vector(this.args)); } /** @@ -71,7 +61,6 @@ export class PublicCallRequest { FunctionData.fromBuffer(reader), CallContext.fromBuffer(reader), reader.readVector(Fr), - reader.readNumber(), ); } @@ -90,13 +79,7 @@ export class PublicCallRequest { * @returns The array. */ static getFields(fields: FieldsOf) { - return [ - fields.contractAddress, - fields.functionData, - fields.callContext, - fields.args, - fields.sideEffectCounter, - ] as const; + return [fields.contractAddress, fields.functionData, fields.callContext, fields.args] as const; } /** diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 2b77ce79c207..2a9f7de3b53c 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -393,7 +393,6 @@ export function makePublicCallRequest(seed = 1): PublicCallRequest { new FunctionData(makeSelector(seed + 0x1), false, false, false), makeCallContext(seed + 0x2, makeAztecAddress(seed)), makeTuple(ARGS_LENGTH, fr, seed + 0x10), - 0, ); } From 89b06c0250719badb71eef55efa8f8d3850c2e3f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 5 Jan 2024 13:35:14 +0000 Subject: [PATCH 03/18] feat: squash read requests against later commitments --- yarn-project/aztec-nr/aztec/src/context.nr | 10 +++---- .../aztec/src/oracle/call_private_function.nr | 4 +-- .../oracle/enqueue_public_function_call.nr | 4 +-- .../src/private_kernel_inner.nr | 2 +- .../src/private_kernel_ordering.nr | 28 ++++++++----------- .../src/crates/types/src/abis/call_context.nr | 4 +-- .../src/abis/private_circuit_public_inputs.nr | 6 ++-- .../src/crates/types/src/abis/side_effect.nr | 12 ++++---- .../noir-protocol-circuits/src/index.ts | 25 +++++++++++++++++ .../src/type_conversion.ts | 2 +- .../src/types/private_kernel_init_types.ts | 12 ++++---- .../src/types/private_kernel_inner_types.ts | 12 ++++---- .../types/private_kernel_ordering_types.ts | 8 +++--- .../public_kernel_private_previous_types.ts | 10 +++---- .../public_kernel_public_previous_types.ts | 10 +++---- .../src/types/rollup_base_types.ts | 8 +++--- 16 files changed, 89 insertions(+), 68 deletions(-) diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index 949a173f0364..ddc093d7466d 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -67,7 +67,7 @@ use dep::std::option::Option; struct PrivateContext { // docs:start:private-context inputs: PrivateContextInputs, - side_effect_counter: Field, + side_effect_counter: u32, args_hash : Field, return_values : BoundedVec, @@ -289,7 +289,7 @@ impl PrivateContext { is_delegate_call : reader.read() as bool, is_static_call : reader.read() as bool, is_contract_deployment: reader.read() as bool, - start_side_effect_counter: reader.read(), + start_side_effect_counter: reader.read() as u32, }, args_hash: reader.read(), return_values: reader.read_array([0; RETURN_VALUES_LENGTH]), // +1 @@ -299,7 +299,7 @@ impl PrivateContext { private_call_stack_hashes: reader.read_array([0; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL]), public_call_stack_hashes: reader.read_array([0; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL]), new_l2_to_l1_msgs: reader.read_array([0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL]), - end_side_effect_counter: reader.read(), + end_side_effect_counter: reader.read() as u32, encrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]), unencrypted_logs_hash: reader.read_array([0; NUM_FIELDS_PER_SHA256]), encrypted_log_preimages_length: reader.read(), @@ -408,7 +408,7 @@ impl PrivateContext { is_delegate_call : reader.read() as bool, is_static_call : reader.read() as bool, is_contract_deployment: reader.read() as bool, - start_side_effect_counter: reader.read(), + start_side_effect_counter: reader.read() as u32, }, args_hash: reader.read(), return_values: [0; RETURN_VALUES_LENGTH], @@ -451,7 +451,7 @@ impl PrivateContext { struct PublicContext { inputs: PublicContextInputs, - side_effect_counter: Field, + side_effect_counter: u32, args_hash : Field, return_values : BoundedVec, diff --git a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr index b1e9a95bb63b..98a0ab385a21 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/call_private_function.nr @@ -9,14 +9,14 @@ fn call_private_function_oracle( _contract_address: AztecAddress, _function_selector: FunctionSelector, _args_hash: Field, - _start_side_effect_counter: Field + _start_side_effect_counter: u32 ) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] {} unconstrained pub fn call_private_function_internal( contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - start_side_effect_counter: Field + start_side_effect_counter: u32 ) -> [Field; CALL_PRIVATE_FUNCTION_RETURN_SIZE] { call_private_function_oracle( contract_address, diff --git a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr index 7cf6068a44a8..d48f6b2ab63e 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle/enqueue_public_function_call.nr @@ -15,14 +15,14 @@ fn enqueue_public_function_call_oracle( _contract_address: AztecAddress, _function_selector: FunctionSelector, _args_hash: Field, - _side_effect_counter: Field + _side_effect_counter: u32 ) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] {} unconstrained pub fn enqueue_public_function_call_internal( contract_address: AztecAddress, function_selector: FunctionSelector, args_hash: Field, - side_effect_counter: Field + side_effect_counter: u32 ) -> [Field; ENQUEUE_PUBLIC_FUNCTION_CALL_RETURN_SIZE] { enqueue_public_function_call_oracle( contract_address, diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index de3b83f95346..ccac97f7e1d7 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -528,7 +528,7 @@ mod tests { for i in 0..MAX_NEW_COMMITMENTS_PER_TX { full_new_commitments[i] = SideEffect { value: i + 1, - counter: i, + counter: i as u32, }; } builder.previous_kernel.end.new_commitments.push_array(full_new_commitments); diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index db8a51445335..4f5b99d41b9b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -43,18 +43,14 @@ impl PrivateKernelInputsOrdering { // match reads to commitments from the previous call(s) for rr_idx in 0..MAX_READ_REQUESTS_PER_TX { - let read_request = read_requests.get_unchecked(rr_idx).value; - let read_commitment_hint = self.read_commitment_hints[rr_idx]; + let read_request = read_requests.get_unchecked(rr_idx); + let read_commitment_hint = self.read_commitment_hints[rr_idx] as u64; //TODO(David): Shouldn't this just be a uint64? - let hint_pos = read_commitment_hint as u64; - - if (read_request != 0) { - let mut match_pos = MAX_NEW_COMMITMENTS_PER_TX as u64; - if (hint_pos < MAX_NEW_COMMITMENTS_PER_TX as u64) { - match_pos = if read_request == new_commitments.get_unchecked(hint_pos as Field).value { hint_pos } else { match_pos }; - } - - assert(match_pos != MAX_NEW_COMMITMENTS_PER_TX as u64, "read request is transient but does not match any commitment"); + + if (read_request.value != 0) { + let commitment = new_commitments.get_unchecked(read_commitment_hint as Field); + assert_eq(read_request.value, commitment.value, "Hinted commitment does not match"); + assert(read_request.counter > commitment.counter, "Read request counter must be greater than commitment counter"); } } @@ -124,13 +120,13 @@ impl PrivateKernelInputsOrdering { // Apply nonce to all non-zero/non-empty commitments // Nonce is the hash of the first (0th) nullifier and the commitment's index into new_commitments array let nonce = compute_commitment_nonce(first_nullifier.value, c_idx); - let commitment = unique_commitments[c_idx].value; - if commitment != 0 { - let unique_commitment = compute_unique_siloed_commitment(nonce, commitment); + let commitment = unique_commitments[c_idx]; + if commitment.value != 0 { + let unique_commitment = compute_unique_siloed_commitment(nonce, commitment.value); unique_commitments[c_idx] = SideEffect{ value: unique_commitment, - counter: 0 - }; + counter: commitment.counter + }; } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr index 668dd8fce90e..bc454eae072d 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_context.nr @@ -22,7 +22,7 @@ struct CallContext { is_static_call : bool, is_contract_deployment : bool, - start_side_effect_counter : Field, + start_side_effect_counter : u32, } // docs:end:call-context @@ -56,7 +56,7 @@ impl CallContext { self.is_delegate_call as Field, self.is_static_call as Field, self.is_contract_deployment as Field, - self.start_side_effect_counter, + self.start_side_effect_counter as Field, ] } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index b788881c7685..7f42e892ac51 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -38,7 +38,7 @@ struct PrivateCircuitPublicInputs { private_call_stack_hashes: [Field; MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL], public_call_stack_hashes: [Field; MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL], new_l2_to_l1_msgs: [Field; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], - end_side_effect_counter : Field, + end_side_effect_counter : u32, encrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], @@ -76,7 +76,7 @@ impl Hash for PrivateCircuitPublicInputs { fields.push_array(self.private_call_stack_hashes); fields.push_array(self.public_call_stack_hashes); fields.push_array(self.new_l2_to_l1_msgs); - fields.push(self.end_side_effect_counter); + fields.push(self.end_side_effect_counter as Field); fields.push_array(self.encrypted_logs_hash); fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); @@ -111,7 +111,7 @@ impl PrivateCircuitPublicInputs { fields.push_array(self.private_call_stack_hashes); fields.push_array(self.public_call_stack_hashes); fields.push_array(self.new_l2_to_l1_msgs); - fields.push(self.end_side_effect_counter); + fields.push(self.end_side_effect_counter as Field); fields.push_array(self.encrypted_logs_hash); fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index da13d853fe91..2a9f1fcce56f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -4,7 +4,7 @@ use crate::traits::{Empty, Hash}; struct SideEffect{ value: Field, - counter: Field, + counter: u32, } impl Eq for SideEffect { @@ -32,13 +32,13 @@ impl Hash for SideEffect { impl SideEffect { pub fn serialize(self) -> [Field; 2] { - [self.value, self.counter] + [self.value, self.counter as Field] } pub fn deserialise(values: [Field; 2]) -> Self { Self { value: values[0], - counter: values[1], + counter: values[1] as u32, } } @@ -51,7 +51,7 @@ impl SideEffect { struct SideEffectLinkedToNoteHash{ value: Field, note_hash: Field, - counter: Field, + counter: u32, } impl Eq for SideEffectLinkedToNoteHash { @@ -82,14 +82,14 @@ impl Hash for SideEffectLinkedToNoteHash { impl SideEffectLinkedToNoteHash{ pub fn serialize(self) -> [Field; 3] { - [self.value, self.note_hash, self.counter] + [self.value, self.note_hash, self.counter as Field] } pub fn deserialise(values: [Field; 3]) -> Self { Self { value: values[0], note_hash: values[1], - counter: values[2], + counter: values[2] as u32, } } diff --git a/yarn-project/noir-protocol-circuits/src/index.ts b/yarn-project/noir-protocol-circuits/src/index.ts index 89954211e99e..07b782c8e1cb 100644 --- a/yarn-project/noir-protocol-circuits/src/index.ts +++ b/yarn-project/noir-protocol-circuits/src/index.ts @@ -140,6 +140,31 @@ export async function executeOrdering( input: mapPrivateKernelInputsOrderingToNoir(privateKernelInputsOrdering), }; + // console.log( + // privateKernelInputsOrdering.previousKernel.publicInputs.end.newNullifiers + // .filter(sideffect => !sideffect.value.isZero()) + // .map(sideffect => ({ + // val: sideffect.value.toString(), + // counter: sideffect.counter.toString(), + // })), + // ); + // console.log( + // privateKernelInputsOrdering.previousKernel.publicInputs.end.newCommitments + // .filter(sideffect => !sideffect.value.isZero()) + // .map(sideffect => ({ + // val: sideffect.value.toString(), + // counter: sideffect.counter.toString(), + // })), + // ); + // console.log( + // privateKernelInputsOrdering.previousKernel.publicInputs.end.readRequests + // .filter(sideffect => !sideffect.value.isZero()) + // .map(sideffect => ({ + // val: sideffect.value.toString(), + // counter: sideffect.counter.toString(), + // })), + // ); + const returnType = await executePrivateKernelOrderingWithACVM(params); return mapKernelCircuitPublicInputsFinalFromNoir(returnType); diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 0ddc38b0775d..085d1e3a87d4 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -87,7 +87,7 @@ import { AztecAddress as NoirAztecAddress, EthAddress as NoirEthAddress, Field as NoirField, - Point as NoirPoint, + GrumpkinPoint as NoirPoint, OptionallyRevealedData as OptionallyRevealedDataNoir, PrivateCallData as PrivateCallDataNoir, PrivateCallStackItem as PrivateCallStackItemNoir, diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts index 014514bdbd2d..eb28f5a925ab 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts @@ -11,7 +11,7 @@ export interface AztecAddress { inner: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } @@ -21,7 +21,7 @@ export interface EthAddress { } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; @@ -63,18 +63,18 @@ export interface CallContext { is_delegate_call: boolean; is_static_call: boolean; is_contract_deployment: boolean; - start_side_effect_counter: Field; + start_side_effect_counter: u32; } export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface BlockHeader { @@ -97,7 +97,7 @@ export interface PrivateCircuitPublicInputs { private_call_stack_hashes: FixedLengthArray; public_call_stack_hashes: FixedLengthArray; new_l2_to_l1_msgs: FixedLengthArray; - end_side_effect_counter: Field; + end_side_effect_counter: u32; encrypted_logs_hash: FixedLengthArray; unencrypted_logs_hash: FixedLengthArray; encrypted_log_preimages_length: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts index 3305c67df499..4d548214a7c3 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts @@ -11,13 +11,13 @@ export interface AggregationObject {} export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface AztecAddress { @@ -108,13 +108,13 @@ export interface BlockHeader { global_variables_hash: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; @@ -161,7 +161,7 @@ export interface CallContext { is_delegate_call: boolean; is_static_call: boolean; is_contract_deployment: boolean; - start_side_effect_counter: Field; + start_side_effect_counter: u32; } export interface PrivateCircuitPublicInputs { @@ -174,7 +174,7 @@ export interface PrivateCircuitPublicInputs { private_call_stack_hashes: FixedLengthArray; public_call_stack_hashes: FixedLengthArray; new_l2_to_l1_msgs: FixedLengthArray; - end_side_effect_counter: Field; + end_side_effect_counter: u32; encrypted_logs_hash: FixedLengthArray; unencrypted_logs_hash: FixedLengthArray; encrypted_log_preimages_length: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts index b26501d646bc..cd6972abdcc4 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts @@ -11,13 +11,13 @@ export interface AggregationObject {} export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface AztecAddress { @@ -108,13 +108,13 @@ export interface BlockHeader { global_variables_hash: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts index 9b5836579b1d..0ccfadf5f231 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts @@ -11,13 +11,13 @@ export interface AggregationObject {} export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface AztecAddress { @@ -108,13 +108,13 @@ export interface BlockHeader { global_variables_hash: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; @@ -161,7 +161,7 @@ export interface CallContext { is_delegate_call: boolean; is_static_call: boolean; is_contract_deployment: boolean; - start_side_effect_counter: Field; + start_side_effect_counter: u32; } export interface StorageUpdateRequest { diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts index 3be8bcf5fa4b..c7f5b049d9c7 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts @@ -11,13 +11,13 @@ export interface AggregationObject {} export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface AztecAddress { @@ -108,13 +108,13 @@ export interface BlockHeader { global_variables_hash: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; @@ -161,7 +161,7 @@ export interface CallContext { is_delegate_call: boolean; is_static_call: boolean; is_contract_deployment: boolean; - start_side_effect_counter: Field; + start_side_effect_counter: u32; } export interface StorageUpdateRequest { diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts index 5958cb3e182f..756998005a75 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts @@ -11,13 +11,13 @@ export interface AggregationObject {} export interface SideEffect { value: Field; - counter: Field; + counter: u32; } export interface SideEffectLinkedToNoteHash { value: Field; note_hash: Field; - counter: Field; + counter: u32; } export interface AztecAddress { @@ -108,13 +108,13 @@ export interface BlockHeader { global_variables_hash: Field; } -export interface Point { +export interface GrumpkinPoint { x: Field; y: Field; } export interface ContractDeploymentData { - deployer_public_key: Point; + deployer_public_key: GrumpkinPoint; constructor_vk_hash: Field; function_tree_root: Field; contract_address_salt: Field; From 59127e910b548a05f318bfb44d36d81abaa8386d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 5 Jan 2024 14:25:44 +0000 Subject: [PATCH 04/18] feat: ensure nullifiers after commitments --- .../src/private_kernel_ordering.nr | 12 ++++++------ .../types/src/tests/previous_kernel_data_builder.nr | 7 ++++++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 4f5b99d41b9b..4d723b4ce4c8 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -45,11 +45,10 @@ impl PrivateKernelInputsOrdering { for rr_idx in 0..MAX_READ_REQUESTS_PER_TX { let read_request = read_requests.get_unchecked(rr_idx); let read_commitment_hint = self.read_commitment_hints[rr_idx] as u64; - //TODO(David): Shouldn't this just be a uint64? if (read_request.value != 0) { let commitment = new_commitments.get_unchecked(read_commitment_hint as Field); - assert_eq(read_request.value, commitment.value, "Hinted commitment does not match"); + assert_eq(read_request.value, commitment.value, "Hinted commitment does not match read request"); assert(read_request.counter > commitment.counter, "Read request counter must be greater than commitment counter"); } } @@ -68,8 +67,7 @@ impl PrivateKernelInputsOrdering { let nullifier = new_nullifiers[n_idx]; // TODO - should not be able to squash the first nullifier. let nullified_commitment = nullifier.note_hash; - let nullifier_commitment_hint = self.nullifier_commitment_hints[n_idx]; - let hint_pos = nullifier_commitment_hint as u64; + let hint_pos = self.nullifier_commitment_hints[n_idx] as u64; // Nullified_commitment of value `0` implies non-transient (persistable) // nullifier in which case no attempt will be made to match it to a commitment. @@ -77,7 +75,9 @@ impl PrivateKernelInputsOrdering { // 0-valued nullified_commitment is empty and will be ignored if nullified_commitment != 0 { assert(hint_pos < MAX_NEW_COMMITMENTS_PER_TX as u64, "New nullifier is transient but hint is invalid"); - assert_eq(nullified_commitment, new_commitments[hint_pos].value, "Hinted commitment does not match"); + let commitment = new_commitments[hint_pos]; + assert_eq(nullified_commitment, commitment.value, "Hinted commitment does not match"); + assert(nullifier.counter > commitment.counter, "Nullifier counter must be greater than commitment counter"); // match found! // squash both the nullifier and the commitment // (set to 0 here and then rearrange array after loop) @@ -285,7 +285,7 @@ mod tests { } } - #[test(should_fail_with="read request is transient but does not match any commitment")] + #[test(should_fail_with="Hinted commitment does not match read request")] fn native_read_request_unknown_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr index e1e0905ca202..b1cce1f6766f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr @@ -110,7 +110,12 @@ impl PreviousKernelDataBuilder { pub fn add_read_request_for_transient_commitment(&mut self, commitment_index: Field) -> Field { let new_read_request_index = self.end.read_requests.len(); - self.end.read_requests.push(self.end.new_commitments.get(commitment_index)); + let commitment = self.end.new_commitments.get(commitment_index); + let read_request = SideEffect { + value: commitment.value, + counter: commitment.counter+1, + }; + self.end.read_requests.push(read_request); new_read_request_index } From ad6a69b879c542a82d92a674379cec0bfe8059d7 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Fri, 5 Jan 2024 14:35:21 +0000 Subject: [PATCH 05/18] tests: fix nullifier tests --- .../src/crates/private-kernel-lib/src/private_kernel_ordering.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 4d723b4ce4c8..2a6814f8b02b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -224,6 +224,7 @@ mod tests { pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; + self.previous_kernel.end.new_nullifiers.storage[nullifier_index].counter = self.previous_kernel.end.new_commitments.get(commitment_index).counter + 1; self.nullifier_commitment_hints[nullifier_index] = commitment_index; } From 06023b0b447b72dd69ec9403b332edbba12dc6e1 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 8 Jan 2024 15:23:07 +0000 Subject: [PATCH 06/18] wip sorting sideffects --- .../src/structs/kernel/private_kernel.ts | 28 +- .../circuits.js/src/structs/side_effects.ts | 4 +- .../src/private_kernel_ordering.nr | 720 +++++++++--------- .../src/crates/types/src/abis/side_effect.nr | 16 + .../src/crates/types/src/traits.nr | 6 + .../noir-protocol-circuits/src/index.test.ts | 200 ++--- .../src/type_conversion.ts | 4 + .../types/private_kernel_ordering_types.ts | 4 + .../pxe/src/kernel_prover/kernel_prover.ts | 44 +- 9 files changed, 578 insertions(+), 448 deletions(-) diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts index fb1740afa673..0a583aba9987 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts @@ -4,6 +4,7 @@ import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT, + MAX_NEW_COMMITMENTS_PER_TX, MAX_NEW_NULLIFIERS_PER_TX, MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL, MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL, @@ -17,6 +18,7 @@ import { PrivateCallStackItem } from '../call_stack_item.js'; import { MembershipWitness } from '../membership_witness.js'; import { Proof } from '../proof.js'; import { ReadRequestMembershipWitness } from '../read_request_membership_witness.js'; +import { SideEffect, SideEffectLinkedToNoteHash } from '../side_effects.js'; import { TxRequest } from '../tx_request.js'; import { VerificationKey } from '../verification_key.js'; import { PreviousKernelData } from './previous_kernel_data.js'; @@ -190,10 +192,26 @@ export class PrivateKernelInputsOrdering { * The previous kernel data */ public previousKernel: PreviousKernelData, + /** + * The sorted new commitments. + */ + public sortedNewCommitments: Tuple, + /** + * The sorted new commitments indexes. + */ + public sortedNewCommitmentsIndexes: Tuple, /** * Contains hints for the transient read requests to localize corresponding commitments. */ public readCommitmentHints: Tuple, + /** + * The sorted new nullifiers. + */ + public sortedNewNullifiers: Tuple, + /** + * The sorted new nullifiers indexes. + */ + public sortedNewNullifiersIndexes: Tuple, /** * Contains hints for the transient nullifiers to localize corresponding commitments. */ @@ -205,6 +223,14 @@ export class PrivateKernelInputsOrdering { * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.previousKernel, this.readCommitmentHints); + return serializeToBuffer( + this.previousKernel, + this.sortedNewCommitments, + this.sortedNewCommitmentsIndexes, + this.readCommitmentHints, + this.sortedNewNullifiers, + this.sortedNewNullifiersIndexes, + this.nullifierCommitmentHints, + ); } } diff --git a/yarn-project/circuits.js/src/structs/side_effects.ts b/yarn-project/circuits.js/src/structs/side_effects.ts index e49e62cccbcd..603b21a6c5e4 100644 --- a/yarn-project/circuits.js/src/structs/side_effects.ts +++ b/yarn-project/circuits.js/src/structs/side_effects.ts @@ -6,9 +6,11 @@ import { Fr } from './index.js'; /** * Essential members and functions of all SideEffect variants */ -interface SideEffectType { +export interface SideEffectType { /** The actual value associated with the SideEffect */ value: Fr; + /** The counter associated with the SideEffect */ + counter: Fr; /** Convert to a buffer */ toBuffer(): Buffer; /** Convert to a field array */ diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 2a6814f8b02b..0b45c02cd260 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -1,5 +1,6 @@ use crate::common; use dep::std::unsafe; +use dep::std::ops::Eq; use dep::types::{ abis::{ call_request::CallRequest, @@ -8,7 +9,7 @@ use dep::types::{ KernelCircuitPublicInputsBuilder, KernelCircuitPublicInputsFinal, }, - side_effect::{SideEffect, SideEffectLinkedToNoteHash}, + side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered}, }, constants::{ MAX_NEW_COMMITMENTS_PER_TX, @@ -23,11 +24,16 @@ use dep::types::{ arrays::{array_length, struct_array_length, struct_array_eq, is_empty_struct_array}, bounded_vec::BoundedVec, }, + traits::{Empty, is_empty} }; struct PrivateKernelInputsOrdering { previous_kernel: PreviousKernelData, + sorted_new_commitments: [SideEffect; MAX_NEW_COMMITMENTS_PER_TX], + sorted_new_commitments_indexes: [u32; MAX_NEW_COMMITMENTS_PER_TX], read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], + sorted_new_nullifiers: [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX], + sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_TX], nullifier_commitment_hints: [Field; MAX_NEW_NULLIFIERS_PER_TX], } @@ -57,11 +63,44 @@ impl PrivateKernelInputsOrdering { public_inputs.end.read_requests = BoundedVec::new(SideEffect::empty()); } + fn assert_sorted_counters(original: [T; N], sorted: [T; N], indexes: [u32; N]) where T: Eq + Ordered + Empty { + let mut seen = [false; N]; + let mut prev_counter = 0; + let mut prev_was_empty = false; + + for i in 0..N { + let item = sorted[i]; + + let index = indexes[i]; + assert(index < N, "Index out of bounds"); + assert(!seen[index], "Duplicate index"); + seen[index] = true; + + assert(item.eq(original[index]), "Not equal"); + let counter = item.counter(); + let is_empty = is_empty(item); + + if prev_was_empty { + assert(is_empty, "Empty items must be at the end"); + } else if !is_empty { + assert(counter >= prev_counter, "Not sorted"); + } + + prev_was_empty = is_empty; + prev_counter = counter; + } + } + fn match_nullifiers_to_commitments_and_squash(self, public_inputs: &mut KernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // Match nullifiers/nullified_commitments to commitments from the previous call(s) - let mut new_commitments = public_inputs.end.new_commitments.storage; - let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; + PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_commitments.storage, self.sorted_new_commitments, self.sorted_new_commitments_indexes); + PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_nullifiers.storage, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes); + let mut new_commitments = self.sorted_new_commitments; + let mut new_nullifiers = self.sorted_new_nullifiers; + // Order new_commitments and new_nullifiers arrays + // new_commitments = new_commitments.sort_via(|a: SideEffect, b: SideEffect| a.counter < b.counter); + // new_nullifiers = new_nullifiers.sort_via(|a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.counter < b.counter); for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { let nullifier = new_nullifiers[n_idx]; @@ -87,6 +126,7 @@ impl PrivateKernelInputsOrdering { // non-transient (persistable) nullifiers are just kept in new_nullifiers array and forwarded // to public inputs (used later by base rollup circuit) } + // Move all zero-ed (removed) entries of these arrays to the end and preserve ordering of other entries let mut new_commitments_vec = BoundedVec::new(SideEffect::empty()); @@ -154,340 +194,340 @@ impl PrivateKernelInputsOrdering { } } -mod tests { - use crate::private_kernel_ordering::PrivateKernelInputsOrdering; - use dep::types::constants::{ - MAX_READ_REQUESTS_PER_TX, - MAX_NEW_COMMITMENTS_PER_TX, - MAX_NEW_NULLIFIERS_PER_TX, - }; - use dep::types::{ - abis::{ - kernel_circuit_public_inputs::KernelCircuitPublicInputsFinal, - side_effect::{SideEffect, SideEffectLinkedToNoteHash}, - }, - hash::compute_unique_siloed_commitments, - tests::previous_kernel_data_builder::PreviousKernelDataBuilder, - utils::{ - arrays::{array_eq, struct_array_eq, array_length, struct_array_length, is_empty_array, is_empty_struct_array}, - bounded_vec::BoundedVec, - }, - }; - - struct PrivateKernelOrderingInputsBuilder { - previous_kernel: PreviousKernelDataBuilder, - read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], - nullifier_commitment_hints: [Field; MAX_NEW_NULLIFIERS_PER_TX], - } - - impl PrivateKernelOrderingInputsBuilder { - pub fn new() -> Self { - PrivateKernelOrderingInputsBuilder { - previous_kernel: PreviousKernelDataBuilder::new(), - read_commitment_hints: [0; MAX_READ_REQUESTS_PER_TX], - nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], - } - } - - pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { - self.previous_kernel.end.new_commitments.storage - } - - pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { - self.previous_kernel.end.new_nullifiers.storage - } - - pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { - self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) - } - - // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed - // commitments for the given commitments. - pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { - let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); - compute_unique_siloed_commitments(first_nullifier.value, commitments) - } - - pub fn append_transient_commitments(&mut self, num_commitments: Field) { - // All new commitments aggregated in the previous kernel are transient commitments. - self.previous_kernel.append_new_commitments(num_commitments); - } - - pub fn add_transient_read(&mut self, commitment_index: Field) { - let read_request_index = self.previous_kernel.add_read_request_for_transient_commitment(commitment_index); - self.read_commitment_hints[read_request_index] = commitment_index; - } - - pub fn append_nullifiers(&mut self, num_nullifiers: Field) { - self.previous_kernel.append_new_nullifiers(num_nullifiers); - } - - pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { - self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; - self.previous_kernel.end.new_nullifiers.storage[nullifier_index].counter = self.previous_kernel.end.new_commitments.get(commitment_index).counter + 1; - self.nullifier_commitment_hints[nullifier_index] = commitment_index; - } - - pub fn execute(self) -> KernelCircuitPublicInputsFinal { - let kernel = PrivateKernelInputsOrdering { - previous_kernel: self.previous_kernel.finish(), - read_commitment_hints: self.read_commitment_hints, - nullifier_commitment_hints: self.nullifier_commitment_hints, - }; - kernel.native_private_kernel_circuit_ordering() - } - - pub fn failed(self) { - let _ = self.execute(); - } - } - - #[test] - fn native_matching_one_read_request_to_commitment_works() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(1); - builder.add_transient_read(0); - - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); - - let public_inputs = builder.execute(); - assert( - struct_array_length( - public_inputs.end.new_commitments, - |r: SideEffect| r.is_empty() - ) - == 1 - ); - assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); - } - - #[test] - fn native_matching_some_read_requests_to_commitments_works() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); - // Read the commitment at index 1; - builder.add_transient_read(1); - // Read the commitment at index 3; - builder.add_transient_read(3); - - let unique_siloed_commitments = builder.get_unique_siloed_commitments(); - - let public_inputs = builder.execute(); - assert_eq( - struct_array_length( - public_inputs.end.new_commitments, - |r: SideEffect| r.is_empty() - ), MAX_NEW_COMMITMENTS_PER_TX - ); - for i in 0..MAX_NEW_COMMITMENTS_PER_TX { - assert(public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[i])); - } - } - - #[test(should_fail_with="Hinted commitment does not match read request")] - fn native_read_request_unknown_fails() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(1); - builder.add_transient_read(0); - // Tweak the read request so that it does not match the commitment at index 0; - let read_request = builder.previous_kernel.end.read_requests.pop(); - builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); - - builder.failed(); - } - - #[test] - fn native_squash_one_of_one_transient_matches_works() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(1); - builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; - builder.nullify_transient_commitment(1, 0); - let new_nullifiers = builder.get_new_nullifiers(); - - let public_inputs = builder.execute(); - assert( - is_empty_struct_array( - public_inputs.end.new_commitments, - |c: SideEffect| c.is_empty() - ) - ); - - // The nullifier at index 1 is chopped. - let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; - assert( - struct_array_eq( - public_inputs.end.new_nullifiers, - expected_new_nullifiers, - |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), - |a: SideEffectLinkedToNoteHash| a.is_empty() - ) - ); - } - - #[test] - fn native_squash_one_of_two_transient_matches_works() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(2); - builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 0; - builder.nullify_transient_commitment(1, 0); - - let new_commitments = builder.get_new_commitments(); - // The 0th commitment will be chopped. - let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); - let new_nullifiers = builder.get_new_nullifiers(); - - let public_inputs = builder.execute(); - - assert( - struct_array_eq( - public_inputs.end.new_commitments, - [unique_siloed_commitments[0]], - |a: SideEffect, b: SideEffect| a.eq(b), - |a: SideEffect| a.is_empty() - ) - ); - - // The nullifier at index 1 is chopped. - let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; - assert( - struct_array_eq( - public_inputs.end.new_nullifiers, - expected_new_nullifiers, - |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), - |a: SideEffectLinkedToNoteHash| a.is_empty() - ) - ); - } - - #[test] - fn native_squash_two_of_two_transient_matches_works() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(2); - builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; - builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; - builder.nullify_transient_commitment(2, 0); - - let new_nullifiers = builder.get_new_nullifiers(); - - let public_inputs = builder.execute(); - assert( - is_empty_struct_array( - public_inputs.end.new_commitments, - |c: SideEffect| c.is_empty() - ) - ); - assert( - struct_array_eq( - public_inputs.end.new_nullifiers, - [new_nullifiers[0]], - |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), - |a: SideEffectLinkedToNoteHash| a.is_empty() - ) - ); - } - - #[test] - fn native_empty_nullified_commitment_means_persistent_nullifier_0() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(2); - builder.append_nullifiers(2); - - let public_inputs = builder.execute(); - assert_eq( - struct_array_length( - public_inputs.end.new_commitments, - |r: SideEffect| r.is_empty() - ), 2 - ); - assert_eq( - struct_array_length( - public_inputs.end.new_nullifiers, - |r: SideEffectLinkedToNoteHash| r.is_empty() - ), 3 - ); - } - - // same as previous test, but this time there are 0 commitments! - // (Do we really need this test?) - #[test] - fn native_empty_nullified_commitment_means_persistent_nullifier_1() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_nullifiers(2); - - let public_inputs = builder.execute(); - assert( - struct_array_length( - public_inputs.end.new_commitments, - |r: SideEffect| r.is_empty() - ) - == 0 - ); - assert( - struct_array_length( - public_inputs.end.new_nullifiers, - |r: SideEffectLinkedToNoteHash| r.is_empty() - ) - == 3 - ); - } - - #[test(should_fail_with="New nullifier is transient but hint is invalid")] - fn invalid_nullifier_commitment_hint_fails() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(1); - builder.append_nullifiers(1); - // The nullifier at index 1 is nullifying the commitment at index 0; - builder.nullify_transient_commitment(1, 0); - // Change the hint to be out of bounds. - builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; - - builder.failed(); - } - - #[test(should_fail_with="Hinted commitment does not match")] - fn wrong_nullifier_commitment_hint_fails() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.append_transient_commitments(2); - builder.append_nullifiers(2); - // The nullifier at index 1 is nullifying the commitment at index 1; - builder.nullify_transient_commitment(1, 1); - // The nullifier at index 2 is nullifying the commitment at index 0; - builder.nullify_transient_commitment(2, 0); - // Tweak the hint to be for the commitment at index 1. - builder.nullifier_commitment_hints[2] = 1; - - builder.failed(); - } - - #[test(should_fail_with="Private call stack must be empty when executing the ordering circuit")] - fn non_empty_private_call_stack_should_fail() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.previous_kernel.push_private_call_request(1, false); - - builder.failed(); - } - - #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] - fn zero_0th_nullifier_fails() { - let mut builder = PrivateKernelOrderingInputsBuilder::new(); - - builder.previous_kernel.end.new_nullifiers = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); - - builder.failed(); - } -} +// mod tests { +// use crate::private_kernel_ordering::PrivateKernelInputsOrdering; +// use dep::types::constants::{ +// MAX_READ_REQUESTS_PER_TX, +// MAX_NEW_COMMITMENTS_PER_TX, +// MAX_NEW_NULLIFIERS_PER_TX, +// }; +// use dep::types::{ +// abis::{ +// kernel_circuit_public_inputs::KernelCircuitPublicInputsFinal, +// side_effect::{SideEffect, SideEffectLinkedToNoteHash}, +// }, +// hash::compute_unique_siloed_commitments, +// tests::previous_kernel_data_builder::PreviousKernelDataBuilder, +// utils::{ +// arrays::{array_eq, struct_array_eq, array_length, struct_array_length, is_empty_array, is_empty_struct_array}, +// bounded_vec::BoundedVec, +// }, +// }; + +// struct PrivateKernelOrderingInputsBuilder { +// previous_kernel: PreviousKernelDataBuilder, +// read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], +// nullifier_commitment_hints: [Field; MAX_NEW_NULLIFIERS_PER_TX], +// } + +// impl PrivateKernelOrderingInputsBuilder { +// pub fn new() -> Self { +// PrivateKernelOrderingInputsBuilder { +// previous_kernel: PreviousKernelDataBuilder::new(), +// read_commitment_hints: [0; MAX_READ_REQUESTS_PER_TX], +// nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], +// } +// } + +// pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { +// self.previous_kernel.end.new_commitments.storage +// } + +// pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { +// self.previous_kernel.end.new_nullifiers.storage +// } + +// pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { +// self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) +// } + +// // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed +// // commitments for the given commitments. +// pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { +// let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); +// compute_unique_siloed_commitments(first_nullifier.value, commitments) +// } + +// pub fn append_transient_commitments(&mut self, num_commitments: Field) { +// // All new commitments aggregated in the previous kernel are transient commitments. +// self.previous_kernel.append_new_commitments(num_commitments); +// } + +// pub fn add_transient_read(&mut self, commitment_index: Field) { +// let read_request_index = self.previous_kernel.add_read_request_for_transient_commitment(commitment_index); +// self.read_commitment_hints[read_request_index] = commitment_index; +// } + +// pub fn append_nullifiers(&mut self, num_nullifiers: Field) { +// self.previous_kernel.append_new_nullifiers(num_nullifiers); +// } + +// pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { +// self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; +// self.previous_kernel.end.new_nullifiers.storage[nullifier_index].counter = self.previous_kernel.end.new_commitments.get(commitment_index).counter + 1; +// self.nullifier_commitment_hints[nullifier_index] = commitment_index; +// } + +// pub fn execute(self) -> KernelCircuitPublicInputsFinal { +// let kernel = PrivateKernelInputsOrdering { +// previous_kernel: self.previous_kernel.finish(), +// read_commitment_hints: self.read_commitment_hints, +// nullifier_commitment_hints: self.nullifier_commitment_hints, +// }; +// kernel.native_private_kernel_circuit_ordering() +// } + +// pub fn failed(self) { +// let _ = self.execute(); +// } +// } + +// #[test] +// fn native_matching_one_read_request_to_commitment_works() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(1); +// builder.add_transient_read(0); + +// let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + +// let public_inputs = builder.execute(); +// assert( +// struct_array_length( +// public_inputs.end.new_commitments, +// |r: SideEffect| r.is_empty() +// ) +// == 1 +// ); +// assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); +// } + +// #[test] +// fn native_matching_some_read_requests_to_commitments_works() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); +// // Read the commitment at index 1; +// builder.add_transient_read(1); +// // Read the commitment at index 3; +// builder.add_transient_read(3); + +// let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + +// let public_inputs = builder.execute(); +// assert_eq( +// struct_array_length( +// public_inputs.end.new_commitments, +// |r: SideEffect| r.is_empty() +// ), MAX_NEW_COMMITMENTS_PER_TX +// ); +// for i in 0..MAX_NEW_COMMITMENTS_PER_TX { +// assert(public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[i])); +// } +// } + +// #[test(should_fail_with="Hinted commitment does not match read request")] +// fn native_read_request_unknown_fails() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(1); +// builder.add_transient_read(0); +// // Tweak the read request so that it does not match the commitment at index 0; +// let read_request = builder.previous_kernel.end.read_requests.pop(); +// builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); + +// builder.failed(); +// } + +// #[test] +// fn native_squash_one_of_one_transient_matches_works() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(1); +// builder.append_nullifiers(2); +// // The nullifier at index 1 is nullifying the commitment at index 0; +// builder.nullify_transient_commitment(1, 0); +// let new_nullifiers = builder.get_new_nullifiers(); + +// let public_inputs = builder.execute(); +// assert( +// is_empty_struct_array( +// public_inputs.end.new_commitments, +// |c: SideEffect| c.is_empty() +// ) +// ); + +// // The nullifier at index 1 is chopped. +// let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; +// assert( +// struct_array_eq( +// public_inputs.end.new_nullifiers, +// expected_new_nullifiers, +// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), +// |a: SideEffectLinkedToNoteHash| a.is_empty() +// ) +// ); +// } + +// #[test] +// fn native_squash_one_of_two_transient_matches_works() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(2); +// builder.append_nullifiers(2); +// // The nullifier at index 1 is nullifying the commitment at index 0; +// builder.nullify_transient_commitment(1, 0); + +// let new_commitments = builder.get_new_commitments(); +// // The 0th commitment will be chopped. +// let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); +// let new_nullifiers = builder.get_new_nullifiers(); + +// let public_inputs = builder.execute(); + +// assert( +// struct_array_eq( +// public_inputs.end.new_commitments, +// [unique_siloed_commitments[0]], +// |a: SideEffect, b: SideEffect| a.eq(b), +// |a: SideEffect| a.is_empty() +// ) +// ); + +// // The nullifier at index 1 is chopped. +// let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; +// assert( +// struct_array_eq( +// public_inputs.end.new_nullifiers, +// expected_new_nullifiers, +// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), +// |a: SideEffectLinkedToNoteHash| a.is_empty() +// ) +// ); +// } + +// #[test] +// fn native_squash_two_of_two_transient_matches_works() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(2); +// builder.append_nullifiers(2); +// // The nullifier at index 1 is nullifying the commitment at index 1; +// builder.nullify_transient_commitment(1, 1); +// // The nullifier at index 2 is nullifying the commitment at index 0; +// builder.nullify_transient_commitment(2, 0); + +// let new_nullifiers = builder.get_new_nullifiers(); + +// let public_inputs = builder.execute(); +// assert( +// is_empty_struct_array( +// public_inputs.end.new_commitments, +// |c: SideEffect| c.is_empty() +// ) +// ); +// assert( +// struct_array_eq( +// public_inputs.end.new_nullifiers, +// [new_nullifiers[0]], +// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), +// |a: SideEffectLinkedToNoteHash| a.is_empty() +// ) +// ); +// } + +// #[test] +// fn native_empty_nullified_commitment_means_persistent_nullifier_0() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(2); +// builder.append_nullifiers(2); + +// let public_inputs = builder.execute(); +// assert_eq( +// struct_array_length( +// public_inputs.end.new_commitments, +// |r: SideEffect| r.is_empty() +// ), 2 +// ); +// assert_eq( +// struct_array_length( +// public_inputs.end.new_nullifiers, +// |r: SideEffectLinkedToNoteHash| r.is_empty() +// ), 3 +// ); +// } + +// // same as previous test, but this time there are 0 commitments! +// // (Do we really need this test?) +// #[test] +// fn native_empty_nullified_commitment_means_persistent_nullifier_1() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_nullifiers(2); + +// let public_inputs = builder.execute(); +// assert( +// struct_array_length( +// public_inputs.end.new_commitments, +// |r: SideEffect| r.is_empty() +// ) +// == 0 +// ); +// assert( +// struct_array_length( +// public_inputs.end.new_nullifiers, +// |r: SideEffectLinkedToNoteHash| r.is_empty() +// ) +// == 3 +// ); +// } + +// #[test(should_fail_with="New nullifier is transient but hint is invalid")] +// fn invalid_nullifier_commitment_hint_fails() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(1); +// builder.append_nullifiers(1); +// // The nullifier at index 1 is nullifying the commitment at index 0; +// builder.nullify_transient_commitment(1, 0); +// // Change the hint to be out of bounds. +// builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; + +// builder.failed(); +// } + +// #[test(should_fail_with="Hinted commitment does not match")] +// fn wrong_nullifier_commitment_hint_fails() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.append_transient_commitments(2); +// builder.append_nullifiers(2); +// // The nullifier at index 1 is nullifying the commitment at index 1; +// builder.nullify_transient_commitment(1, 1); +// // The nullifier at index 2 is nullifying the commitment at index 0; +// builder.nullify_transient_commitment(2, 0); +// // Tweak the hint to be for the commitment at index 1. +// builder.nullifier_commitment_hints[2] = 1; + +// builder.failed(); +// } + +// #[test(should_fail_with="Private call stack must be empty when executing the ordering circuit")] +// fn non_empty_private_call_stack_should_fail() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.previous_kernel.push_private_call_request(1, false); + +// builder.failed(); +// } + +// #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] +// fn zero_0th_nullifier_fails() { +// let mut builder = PrivateKernelOrderingInputsBuilder::new(); + +// builder.previous_kernel.end.new_nullifiers = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); + +// builder.failed(); +// } +// } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr index 2a9f1fcce56f..b13ff46d1d6f 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/side_effect.nr @@ -2,11 +2,21 @@ use crate::constants::{GENERATOR_INDEX__SIDE_EFFECT}; use dep::std::ops::Eq; use crate::traits::{Empty, Hash}; +trait Ordered { + fn counter(self) -> u32; +} + struct SideEffect{ value: Field, counter: u32, } +impl Ordered for SideEffect { + fn counter(self) -> u32 { + self.counter + } +} + impl Eq for SideEffect { fn eq(self, side_effect: SideEffect) -> bool { (self.value == side_effect.value) @@ -54,6 +64,12 @@ struct SideEffectLinkedToNoteHash{ counter: u32, } +impl Ordered for SideEffectLinkedToNoteHash { + fn counter(self) -> u32 { + self.counter + } +} + impl Eq for SideEffectLinkedToNoteHash { fn eq(self, side_effect: SideEffectLinkedToNoteHash) -> bool { (self.value == side_effect.value) diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index 03ddb8d9bb8f..6d5c92817d4a 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -1,3 +1,5 @@ +use dep::std::ops::Eq; + // Preferred over Default trait to convey intent, as default doesn't necessarily mean empty. trait Empty { fn empty() -> Self; @@ -6,3 +8,7 @@ trait Empty { trait Hash { fn hash(self) -> Field; } + +pub fn is_empty(item: T) -> bool where T: Empty + Eq { + item.eq(T::empty()) +} diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index 84aacbbfea77..e5eae658eed9 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -168,106 +168,106 @@ describe('Private kernel', () => { expect(kernelOutputs).toMatchSnapshot(); }); - // Taken from e2e_nested_contract => performs nested calls => first ordering - it('Executes private kernel ordering after a deployment', async () => { - const contractAddress = AztecAddress.fromString( - '0x25e2c017f5da1f994401e61d26be435e3cfa26efee784c6b4e947f7651bd4104', - ); - - const deployerPubKey = new Point( - Fr.fromString('0x1de02ddacac6d2f427e5f0d3ce59d7294f146280455dd4c582254e0b4c254b23'), - Fr.fromString('0x23cd081dfe9c0d1873b65a36a08858e73a9b30d0339e94c4915d7110e2f07ecd'), - ); - - const contractDeploymentData = new ContractDeploymentData( - deployerPubKey, - Fr.fromString('0x0aefd90a69a643324c7bf0a9bd3b23ada090ad883773fdf0b0ad52a9f7d6f1f6'), - Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), - Fr.fromString('0x1ec59b0313fa504302c3336fc911d688edae67c4fbf229d68c7f36ed8797045c'), - EthAddress.ZERO, - ); - const txContext = new TxContext(false, false, true, contractDeploymentData, Fr.ZERO, Fr.ZERO); - - const newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); - newCommitments[0] = new SideEffect( - Fr.fromString('0x0aced88c953b70873e4a33dde4620dc43a709c15013c46c60d167de8e1c32315'), - Fr.ZERO, - ); - - const newNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => SideEffectLinkedToNoteHash.empty()); - newNullifiers[0] = new SideEffectLinkedToNoteHash( - Fr.fromString('0x0faf656089e5a8d321b64f420fc008005736a0b4f0b8588891241392c82655b9'), - Fr.ZERO, - Fr.ZERO, - ); - newNullifiers[1] = new SideEffectLinkedToNoteHash( - Fr.fromString('0x4a5d6bc34e84c5a3d7a625a3772f4d2f84c7d46637691ef64ee2711e6c6202'), - Fr.ZERO, - Fr.ZERO, - ); - newNullifiers[2] = new SideEffectLinkedToNoteHash( - Fr.fromString('0x19085a4478c4aa3994d4a5935eaf5e0d58726a758d398a97f634df22d33d388a'), - Fr.ZERO, - Fr.ZERO, - ); - - const combinedAccumulatedData = new CombinedAccumulatedData( - AggregationObject.makeFake(), - makeTuple(MAX_READ_REQUESTS_PER_TX, () => SideEffect.empty()), - newCommitments, - newNullifiers, - makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), - makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), - makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, () => new Fr(0n)), - [Fr.fromString('0x57ee9bb1264085ecf4ba8274b233cdc4'), Fr.fromString('0x8a8910cc6b93b4399a1ebd8fbfb405f8')], - [Fr.fromString('0x1c9ecec90e28d2461650418635878a5c'), Fr.fromString('0x91e49f47586ecf75f2b0cbb94e897112')], - Fr.fromString('0xf8'), - new Fr(4), - [ - new NewContractData( - contractAddress, - EthAddress.ZERO, - Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), - ), - ], - makeTuple(MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX, () => OptionallyRevealedData.empty()), - makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, () => PublicDataUpdateRequest.empty()), - makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), - ); - - const blockHeader = new BlockHeader( - Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), - Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), - Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), - Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), - Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), - Fr.ZERO, // TODO(#3441) - Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), - Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), - ); - - const constants = new CombinedConstantData(blockHeader, txContext); - - const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); - - const previousKernelData = new PreviousKernelData( - kernelPublicInputs, - makeEmptyProof(), - VerificationKey.makeFake(), - 0, - makeTuple(VK_TREE_HEIGHT, () => Fr.ZERO), - ); - - const kernelInputs = new PrivateKernelInputsOrdering( - previousKernelData, - makeTuple(MAX_READ_REQUESTS_PER_TX, () => Fr.ZERO), - makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => Fr.ZERO), - ); - - const kernelOutputs = await executeOrdering(kernelInputs); - - expect(kernelOutputs).toMatchSnapshot(); - }); + // // Taken from e2e_nested_contract => performs nested calls => first ordering + // it('Executes private kernel ordering after a deployment', async () => { + // const contractAddress = AztecAddress.fromString( + // '0x25e2c017f5da1f994401e61d26be435e3cfa26efee784c6b4e947f7651bd4104', + // ); + + // const deployerPubKey = new Point( + // Fr.fromString('0x1de02ddacac6d2f427e5f0d3ce59d7294f146280455dd4c582254e0b4c254b23'), + // Fr.fromString('0x23cd081dfe9c0d1873b65a36a08858e73a9b30d0339e94c4915d7110e2f07ecd'), + // ); + + // const contractDeploymentData = new ContractDeploymentData( + // deployerPubKey, + // Fr.fromString('0x0aefd90a69a643324c7bf0a9bd3b23ada090ad883773fdf0b0ad52a9f7d6f1f6'), + // Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), + // Fr.fromString('0x1ec59b0313fa504302c3336fc911d688edae67c4fbf229d68c7f36ed8797045c'), + // EthAddress.ZERO, + // ); + // const txContext = new TxContext(false, false, true, contractDeploymentData, Fr.ZERO, Fr.ZERO); + + // const newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); + // newCommitments[0] = new SideEffect( + // Fr.fromString('0x0aced88c953b70873e4a33dde4620dc43a709c15013c46c60d167de8e1c32315'), + // Fr.ZERO, + // ); + + // const newNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => SideEffectLinkedToNoteHash.empty()); + // newNullifiers[0] = new SideEffectLinkedToNoteHash( + // Fr.fromString('0x0faf656089e5a8d321b64f420fc008005736a0b4f0b8588891241392c82655b9'), + // Fr.ZERO, + // Fr.ZERO, + // ); + // newNullifiers[1] = new SideEffectLinkedToNoteHash( + // Fr.fromString('0x4a5d6bc34e84c5a3d7a625a3772f4d2f84c7d46637691ef64ee2711e6c6202'), + // Fr.ZERO, + // Fr.ZERO, + // ); + // newNullifiers[2] = new SideEffectLinkedToNoteHash( + // Fr.fromString('0x19085a4478c4aa3994d4a5935eaf5e0d58726a758d398a97f634df22d33d388a'), + // Fr.ZERO, + // Fr.ZERO, + // ); + + // const combinedAccumulatedData = new CombinedAccumulatedData( + // AggregationObject.makeFake(), + // makeTuple(MAX_READ_REQUESTS_PER_TX, () => SideEffect.empty()), + // newCommitments, + // newNullifiers, + // makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), + // makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), + // makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, () => new Fr(0n)), + // [Fr.fromString('0x57ee9bb1264085ecf4ba8274b233cdc4'), Fr.fromString('0x8a8910cc6b93b4399a1ebd8fbfb405f8')], + // [Fr.fromString('0x1c9ecec90e28d2461650418635878a5c'), Fr.fromString('0x91e49f47586ecf75f2b0cbb94e897112')], + // Fr.fromString('0xf8'), + // new Fr(4), + // [ + // new NewContractData( + // contractAddress, + // EthAddress.ZERO, + // Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), + // ), + // ], + // makeTuple(MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX, () => OptionallyRevealedData.empty()), + // makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, () => PublicDataUpdateRequest.empty()), + // makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), + // ); + + // const blockHeader = new BlockHeader( + // Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), + // Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), + // Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), + // Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), + // Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), + // Fr.ZERO, // TODO(#3441) + // Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), + // Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), + // ); + + // const constants = new CombinedConstantData(blockHeader, txContext); + + // const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); + + // const previousKernelData = new PreviousKernelData( + // kernelPublicInputs, + // makeEmptyProof(), + // VerificationKey.makeFake(), + // 0, + // makeTuple(VK_TREE_HEIGHT, () => Fr.ZERO), + // ); + + // const kernelInputs = new PrivateKernelInputsOrdering( + // previousKernelData, + // makeTuple(MAX_READ_REQUESTS_PER_TX, () => Fr.ZERO), + // makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => Fr.ZERO), + // ); + + // const kernelOutputs = await executeOrdering(kernelInputs); + + // expect(kernelOutputs).toMatchSnapshot(); + // }); // Taken from e2e_nested_contract => performs nested calls => last inner // To regenerate fixture data run the following on the yarn-project/e2e folder diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 085d1e3a87d4..2f77f04e72fd 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -1022,7 +1022,11 @@ export function mapPrivateKernelInputsOrderingToNoir( ): PrivateKernelInputsOrderingNoir { return { previous_kernel: mapPreviousKernelDataToNoir(inputs.previousKernel), + sorted_new_commitments: mapTuple(inputs.sortedNewCommitments, mapSideEffectToNoir), + sorted_new_commitments_indexes: mapTuple(inputs.sortedNewCommitmentsIndexes, mapNumberToNoir), read_commitment_hints: mapTuple(inputs.readCommitmentHints, mapFieldToNoir), + sorted_new_nullifiers: mapTuple(inputs.sortedNewNullifiers, mapSideEffectLinkedToNoir), + sorted_new_nullifiers_indexes: mapTuple(inputs.sortedNewNullifiersIndexes, mapNumberToNoir), nullifier_commitment_hints: mapTuple(inputs.nullifierCommitmentHints, mapFieldToNoir), }; } diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts index cd6972abdcc4..13134477898c 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts @@ -155,7 +155,11 @@ export interface PreviousKernelData { export interface PrivateKernelInputsOrdering { previous_kernel: PreviousKernelData; + sorted_new_commitments: FixedLengthArray; + sorted_new_commitments_indexes: FixedLengthArray; read_commitment_hints: FixedLengthArray; + sorted_new_nullifiers: FixedLengthArray; + sorted_new_nullifiers_indexes: FixedLengthArray; nullifier_commitment_hints: FixedLengthArray; } diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index a09699540cff..66d9f7f5d43c 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -19,6 +19,8 @@ import { PrivateKernelPublicInputs, ReadRequestMembershipWitness, SideEffect, + SideEffectLinkedToNoteHash, + SideEffectType, TxRequest, VK_TREE_HEIGHT, VerificationKey, @@ -166,19 +168,30 @@ export class KernelProver { assertLength(previousVkMembershipWitness.siblingPath, VK_TREE_HEIGHT), ); - const readCommitmentHints = this.getReadRequestHints( - output.publicInputs.end.readRequests, - output.publicInputs.end.newCommitments, - ); + const [sortedCommitments, sortedCommitmentsIndexes] = this.sortSideEffects< + SideEffect, + typeof MAX_NEW_COMMITMENTS_PER_TX + >(output.publicInputs.end.newCommitments); + + const [sortedNullifiers, sortedNullifiersIndexes] = this.sortSideEffects< + SideEffectLinkedToNoteHash, + typeof MAX_NEW_NULLIFIERS_PER_TX + >(output.publicInputs.end.newNullifiers); + + const readCommitmentHints = this.getReadRequestHints(output.publicInputs.end.readRequests, sortedCommitments); const nullifierCommitmentHints = this.getNullifierHints( - mapTuple(output.publicInputs.end.newNullifiers, n => n.noteHash), - output.publicInputs.end.newCommitments, + mapTuple(sortedNullifiers, n => n.noteHash), + sortedCommitments, ); const privateInputs = new PrivateKernelInputsOrdering( previousKernelData, + sortedCommitments, + sortedCommitmentsIndexes, readCommitmentHints, + sortedNullifiers, + sortedNullifiersIndexes, nullifierCommitmentHints, ); const outputFinal = await this.proofCreator.createProofOrdering(privateInputs); @@ -190,6 +203,25 @@ export class KernelProver { return { ...outputFinal, outputNotes }; } + private sortSideEffects( + sideEffects: Tuple, + ): [Tuple, Tuple] { + const sorted = sideEffects + .map((sideEffect, index) => ({ sideEffect, index })) + .sort((a, b) => { + // Empty ones go to the right + if (a.sideEffect.isEmpty()) { + return 1; + } + return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt()); + }); + + return [ + sorted.map(({ sideEffect }) => sideEffect) as Tuple, + sorted.map(({ index }) => index) as Tuple, + ]; + } + private async createPrivateCallData( { callStackItem, vk }: ExecutionResult, privateCallRequests: CallRequest[], From 36aada35044ea8a6799fcb574a2a690841b37295 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 8 Jan 2024 15:56:09 +0000 Subject: [PATCH 07/18] fix: ordering --- .../acir-simulator/src/client/simulator.ts | 2 +- .../src/crates/private-kernel-lib/src/common.nr | 2 +- .../src/private_kernel_ordering.nr | 15 +++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 551b2820253c..7aed4d8220ce 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -88,7 +88,7 @@ export class AcirSimulator { false, false, request.functionData.isConstructor, - 1, // TODO(alvaro): reevaluate this + 2, // 2 counters are reserved for tx hash and contract deployment nullifier ); const context = new ClientExecutionContext( contractAddress, diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index 069a232fd531..5d124e20e1c5 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -347,7 +347,7 @@ pub fn contract_logic( let new_contract_address_nullifier = compute_new_contract_address_hash(new_contract_address); public_inputs.end.new_nullifiers.push( - SideEffectLinkedToNoteHash { value: new_contract_address_nullifier, note_hash: 0, counter: 0 } + SideEffectLinkedToNoteHash { value: new_contract_address_nullifier, note_hash: 0, counter: 1 } ); } else { // non-contract deployments must specify contract address being interacted with diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 0b45c02cd260..38884d128e1b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -91,13 +91,18 @@ impl PrivateKernelInputsOrdering { } } + fn sort_arrays(self, public_inputs: &mut KernelCircuitPublicInputsBuilder) { + PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_commitments.storage, self.sorted_new_commitments, self.sorted_new_commitments_indexes); + PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_nullifiers.storage, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes); + public_inputs.end.new_commitments.storage = self.sorted_new_commitments; + public_inputs.end.new_nullifiers.storage = self.sorted_new_nullifiers; + } + fn match_nullifiers_to_commitments_and_squash(self, public_inputs: &mut KernelCircuitPublicInputsBuilder) { // Remark: The commitments in public_inputs.end have already been siloed by contract address! // Match nullifiers/nullified_commitments to commitments from the previous call(s) - PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_commitments.storage, self.sorted_new_commitments, self.sorted_new_commitments_indexes); - PrivateKernelInputsOrdering::assert_sorted_counters(public_inputs.end.new_nullifiers.storage, self.sorted_new_nullifiers, self.sorted_new_nullifiers_indexes); - let mut new_commitments = self.sorted_new_commitments; - let mut new_nullifiers = self.sorted_new_nullifiers; + let mut new_commitments = public_inputs.end.new_commitments.storage; + let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; // Order new_commitments and new_nullifiers arrays // new_commitments = new_commitments.sort_via(|a: SideEffect, b: SideEffect| a.counter < b.counter); // new_nullifiers = new_nullifiers.sort_via(|a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.counter < b.counter); @@ -184,6 +189,8 @@ impl PrivateKernelInputsOrdering { // Do this before any functions can modify the inputs. common::initialize_end_values(self.previous_kernel, &mut public_inputs); + self.sort_arrays(&mut public_inputs); + self.match_reads_to_commitments(&mut public_inputs); self.match_nullifiers_to_commitments_and_squash(&mut public_inputs); From 4fbd548c187bbe0e1327b068e2ce50345696b8d1 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Mon, 8 Jan 2024 16:37:04 +0000 Subject: [PATCH 08/18] fix: don't allow repeated counters --- .../private-kernel-lib/src/private_kernel_ordering.nr | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 38884d128e1b..ff24da98b194 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -1,5 +1,6 @@ use crate::common; use dep::std::unsafe; +use dep::std::option::Option; use dep::std::ops::Eq; use dep::types::{ abis::{ @@ -65,7 +66,7 @@ impl PrivateKernelInputsOrdering { fn assert_sorted_counters(original: [T; N], sorted: [T; N], indexes: [u32; N]) where T: Eq + Ordered + Empty { let mut seen = [false; N]; - let mut prev_counter = 0; + let mut prev_counter = Option::none(); let mut prev_was_empty = false; for i in 0..N { @@ -77,17 +78,18 @@ impl PrivateKernelInputsOrdering { seen[index] = true; assert(item.eq(original[index]), "Not equal"); + let counter = item.counter(); let is_empty = is_empty(item); if prev_was_empty { assert(is_empty, "Empty items must be at the end"); - } else if !is_empty { - assert(counter >= prev_counter, "Not sorted"); + } else if !is_empty & prev_counter.is_some() { + assert(counter > prev_counter.unwrap(), "Not sorted"); } prev_was_empty = is_empty; - prev_counter = counter; + prev_counter = Option::some(counter); } } From 4e47454e66ca8e9727606ffe8457edd4213db830 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 9 Jan 2024 09:34:28 +0000 Subject: [PATCH 09/18] fix: import of eq trait --- .../crates/private-kernel-lib/src/private_kernel_ordering.nr | 2 +- .../noir-protocol-circuits/src/crates/types/src/traits.nr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index ff24da98b194..3ee9b92853d2 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -1,7 +1,7 @@ use crate::common; use dep::std::unsafe; use dep::std::option::Option; -use dep::std::ops::Eq; +use dep::std::cmp::Eq; use dep::types::{ abis::{ call_request::CallRequest, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr index 6d5c92817d4a..2c83af0195b5 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/traits.nr @@ -1,4 +1,4 @@ -use dep::std::ops::Eq; +use dep::std::cmp::Eq; // Preferred over Default trait to convey intent, as default doesn't necessarily mean empty. trait Empty { From 026c43dc44cacc6e6a2e8fa0be0352baaf84bd63 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 9 Jan 2024 11:17:36 +0000 Subject: [PATCH 10/18] test: fix ordering tests --- .../src/__snapshots__/index.test.ts.snap | 260 +++---- .../src/private_kernel_ordering.nr | 689 +++++++++--------- .../src/crates/types/src/abis/call_request.nr | 4 +- .../src/tests/previous_kernel_data_builder.nr | 23 +- .../src/tests/public_call_data_builder.nr | 4 +- .../noir-protocol-circuits/src/index.test.ts | 214 +++--- 6 files changed, 614 insertions(+), 580 deletions(-) diff --git a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap index 5467270f4d88..62013a5826c5 100644 --- a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap @@ -6742,7 +6742,7 @@ KernelCircuitPublicInputs { }, SideEffectLinkedToNoteHash { "counter": Fr { - "asBigInt": 0n, + "asBigInt": 1n, "asBuffer": { "data": [ 0, @@ -6776,7 +6776,7 @@ KernelCircuitPublicInputs { 0, 0, 0, - 0, + 1, ], "type": "Buffer", }, @@ -66143,41 +66143,41 @@ KernelCircuitPublicInputsFinal { }, }, "value": Fr { - "asBigInt": 3009448547919161079798226041696583891221172499459514963757313019677832133161n, + "asBigInt": 12771775224118191483898915169603387229405021446030587347982956765852896294728n, "asBuffer": { "data": [ - 6, - 167, - 73, - 154, - 164, - 37, - 20, - 195, + 28, + 60, + 145, + 144, + 42, + 59, 23, - 47, - 202, - 195, - 108, - 196, - 31, + 71, 27, - 39, - 218, - 157, - 33, - 150, - 100, - 217, - 13, - 118, - 109, - 235, - 67, - 121, - 120, + 191, + 185, + 73, + 59, + 54, + 69, + 245, + 187, + 21, + 225, 58, - 41, + 128, + 182, + 212, + 12, + 224, + 176, + 240, + 147, + 18, + 147, + 119, + 72, ], "type": "Buffer", }, @@ -71626,41 +71626,41 @@ KernelCircuitPublicInputsFinal { }, }, "value": Fr { - "asBigInt": 7094590644143379362066385400655107720501862419669243795306142485975929345465n, + "asBigInt": 11322578994265849565401386951246010528140686424276775038536393177707801557130n, "asBuffer": { "data": [ - 15, - 175, - 101, - 96, - 137, - 229, - 168, - 211, - 33, - 182, - 79, - 66, - 15, - 192, + 25, 8, - 0, - 87, - 54, - 160, - 180, - 240, - 184, + 90, + 68, + 120, + 196, + 170, + 57, + 148, + 212, + 165, + 147, + 94, + 175, + 94, + 13, 88, - 136, - 145, - 36, - 19, - 146, - 200, - 38, - 85, - 185, + 114, + 106, + 117, + 141, + 57, + 138, + 151, + 246, + 52, + 223, + 34, + 211, + 61, + 56, + 138, ], "type": "Buffer", }, @@ -71668,7 +71668,7 @@ KernelCircuitPublicInputsFinal { }, SideEffectLinkedToNoteHash { "counter": Fr { - "asBigInt": 0n, + "asBigInt": 1n, "asBuffer": { "data": [ 0, @@ -71702,7 +71702,7 @@ KernelCircuitPublicInputsFinal { 0, 0, 0, - 0, + 1, ], "type": "Buffer", }, @@ -71748,41 +71748,41 @@ KernelCircuitPublicInputsFinal { }, }, "value": Fr { - "asBigInt": 131391450486342918604555900920288880952936359657946230216264970318333633026n, + "asBigInt": 7094590644143379362066385400655107720501862419669243795306142485975929345465n, "asBuffer": { "data": [ + 15, + 175, + 101, + 96, + 137, + 229, + 168, + 211, + 33, + 182, + 79, + 66, + 15, + 192, + 8, 0, - 74, - 93, - 107, - 195, - 78, - 132, - 197, - 163, - 215, - 166, - 37, - 163, - 119, - 47, - 77, - 47, - 132, - 199, - 212, - 102, - 55, - 105, - 30, - 246, - 78, - 226, - 113, - 30, - 108, - 98, - 2, + 87, + 54, + 160, + 180, + 240, + 184, + 88, + 136, + 145, + 36, + 19, + 146, + 200, + 38, + 85, + 185, ], "type": "Buffer", }, @@ -71790,7 +71790,7 @@ KernelCircuitPublicInputsFinal { }, SideEffectLinkedToNoteHash { "counter": Fr { - "asBigInt": 0n, + "asBigInt": 2n, "asBuffer": { "data": [ 0, @@ -71824,7 +71824,7 @@ KernelCircuitPublicInputsFinal { 0, 0, 0, - 0, + 2, ], "type": "Buffer", }, @@ -71870,41 +71870,41 @@ KernelCircuitPublicInputsFinal { }, }, "value": Fr { - "asBigInt": 11322578994265849565401386951246010528140686424276775038536393177707801557130n, + "asBigInt": 131391450486342918604555900920288880952936359657946230216264970318333633026n, "asBuffer": { "data": [ - 25, - 8, - 90, - 68, - 120, - 196, - 170, - 57, - 148, + 0, + 74, + 93, + 107, + 195, + 78, + 132, + 197, + 163, + 215, + 166, + 37, + 163, + 119, + 47, + 77, + 47, + 132, + 199, 212, - 165, - 147, - 94, - 175, - 94, - 13, - 88, - 114, - 106, - 117, - 141, - 57, - 138, - 151, + 102, + 55, + 105, + 30, 246, - 52, - 223, - 34, - 211, - 61, - 56, - 138, + 78, + 226, + 113, + 30, + 108, + 98, + 2, ], "type": "Buffer", }, diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 3ee9b92853d2..9abf6103f462 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -105,9 +105,6 @@ impl PrivateKernelInputsOrdering { // Match nullifiers/nullified_commitments to commitments from the previous call(s) let mut new_commitments = public_inputs.end.new_commitments.storage; let mut new_nullifiers = public_inputs.end.new_nullifiers.storage; - // Order new_commitments and new_nullifiers arrays - // new_commitments = new_commitments.sort_via(|a: SideEffect, b: SideEffect| a.counter < b.counter); - // new_nullifiers = new_nullifiers.sort_via(|a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.counter < b.counter); for n_idx in 0..MAX_NEW_NULLIFIERS_PER_TX { let nullifier = new_nullifiers[n_idx]; @@ -203,340 +200,352 @@ impl PrivateKernelInputsOrdering { } } -// mod tests { -// use crate::private_kernel_ordering::PrivateKernelInputsOrdering; -// use dep::types::constants::{ -// MAX_READ_REQUESTS_PER_TX, -// MAX_NEW_COMMITMENTS_PER_TX, -// MAX_NEW_NULLIFIERS_PER_TX, -// }; -// use dep::types::{ -// abis::{ -// kernel_circuit_public_inputs::KernelCircuitPublicInputsFinal, -// side_effect::{SideEffect, SideEffectLinkedToNoteHash}, -// }, -// hash::compute_unique_siloed_commitments, -// tests::previous_kernel_data_builder::PreviousKernelDataBuilder, -// utils::{ -// arrays::{array_eq, struct_array_eq, array_length, struct_array_length, is_empty_array, is_empty_struct_array}, -// bounded_vec::BoundedVec, -// }, -// }; - -// struct PrivateKernelOrderingInputsBuilder { -// previous_kernel: PreviousKernelDataBuilder, -// read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], -// nullifier_commitment_hints: [Field; MAX_NEW_NULLIFIERS_PER_TX], -// } - -// impl PrivateKernelOrderingInputsBuilder { -// pub fn new() -> Self { -// PrivateKernelOrderingInputsBuilder { -// previous_kernel: PreviousKernelDataBuilder::new(), -// read_commitment_hints: [0; MAX_READ_REQUESTS_PER_TX], -// nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], -// } -// } - -// pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { -// self.previous_kernel.end.new_commitments.storage -// } - -// pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { -// self.previous_kernel.end.new_nullifiers.storage -// } - -// pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { -// self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) -// } - -// // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed -// // commitments for the given commitments. -// pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { -// let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); -// compute_unique_siloed_commitments(first_nullifier.value, commitments) -// } - -// pub fn append_transient_commitments(&mut self, num_commitments: Field) { -// // All new commitments aggregated in the previous kernel are transient commitments. -// self.previous_kernel.append_new_commitments(num_commitments); -// } - -// pub fn add_transient_read(&mut self, commitment_index: Field) { -// let read_request_index = self.previous_kernel.add_read_request_for_transient_commitment(commitment_index); -// self.read_commitment_hints[read_request_index] = commitment_index; -// } - -// pub fn append_nullifiers(&mut self, num_nullifiers: Field) { -// self.previous_kernel.append_new_nullifiers(num_nullifiers); -// } - -// pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { -// self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; -// self.previous_kernel.end.new_nullifiers.storage[nullifier_index].counter = self.previous_kernel.end.new_commitments.get(commitment_index).counter + 1; -// self.nullifier_commitment_hints[nullifier_index] = commitment_index; -// } - -// pub fn execute(self) -> KernelCircuitPublicInputsFinal { -// let kernel = PrivateKernelInputsOrdering { -// previous_kernel: self.previous_kernel.finish(), -// read_commitment_hints: self.read_commitment_hints, -// nullifier_commitment_hints: self.nullifier_commitment_hints, -// }; -// kernel.native_private_kernel_circuit_ordering() -// } - -// pub fn failed(self) { -// let _ = self.execute(); -// } -// } - -// #[test] -// fn native_matching_one_read_request_to_commitment_works() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(1); -// builder.add_transient_read(0); - -// let unique_siloed_commitments = builder.get_unique_siloed_commitments(); - -// let public_inputs = builder.execute(); -// assert( -// struct_array_length( -// public_inputs.end.new_commitments, -// |r: SideEffect| r.is_empty() -// ) -// == 1 -// ); -// assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); -// } - -// #[test] -// fn native_matching_some_read_requests_to_commitments_works() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); -// // Read the commitment at index 1; -// builder.add_transient_read(1); -// // Read the commitment at index 3; -// builder.add_transient_read(3); - -// let unique_siloed_commitments = builder.get_unique_siloed_commitments(); - -// let public_inputs = builder.execute(); -// assert_eq( -// struct_array_length( -// public_inputs.end.new_commitments, -// |r: SideEffect| r.is_empty() -// ), MAX_NEW_COMMITMENTS_PER_TX -// ); -// for i in 0..MAX_NEW_COMMITMENTS_PER_TX { -// assert(public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[i])); -// } -// } - -// #[test(should_fail_with="Hinted commitment does not match read request")] -// fn native_read_request_unknown_fails() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(1); -// builder.add_transient_read(0); -// // Tweak the read request so that it does not match the commitment at index 0; -// let read_request = builder.previous_kernel.end.read_requests.pop(); -// builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); - -// builder.failed(); -// } - -// #[test] -// fn native_squash_one_of_one_transient_matches_works() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(1); -// builder.append_nullifiers(2); -// // The nullifier at index 1 is nullifying the commitment at index 0; -// builder.nullify_transient_commitment(1, 0); -// let new_nullifiers = builder.get_new_nullifiers(); - -// let public_inputs = builder.execute(); -// assert( -// is_empty_struct_array( -// public_inputs.end.new_commitments, -// |c: SideEffect| c.is_empty() -// ) -// ); - -// // The nullifier at index 1 is chopped. -// let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; -// assert( -// struct_array_eq( -// public_inputs.end.new_nullifiers, -// expected_new_nullifiers, -// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), -// |a: SideEffectLinkedToNoteHash| a.is_empty() -// ) -// ); -// } - -// #[test] -// fn native_squash_one_of_two_transient_matches_works() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(2); -// builder.append_nullifiers(2); -// // The nullifier at index 1 is nullifying the commitment at index 0; -// builder.nullify_transient_commitment(1, 0); - -// let new_commitments = builder.get_new_commitments(); -// // The 0th commitment will be chopped. -// let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); -// let new_nullifiers = builder.get_new_nullifiers(); - -// let public_inputs = builder.execute(); - -// assert( -// struct_array_eq( -// public_inputs.end.new_commitments, -// [unique_siloed_commitments[0]], -// |a: SideEffect, b: SideEffect| a.eq(b), -// |a: SideEffect| a.is_empty() -// ) -// ); - -// // The nullifier at index 1 is chopped. -// let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; -// assert( -// struct_array_eq( -// public_inputs.end.new_nullifiers, -// expected_new_nullifiers, -// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), -// |a: SideEffectLinkedToNoteHash| a.is_empty() -// ) -// ); -// } - -// #[test] -// fn native_squash_two_of_two_transient_matches_works() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(2); -// builder.append_nullifiers(2); -// // The nullifier at index 1 is nullifying the commitment at index 1; -// builder.nullify_transient_commitment(1, 1); -// // The nullifier at index 2 is nullifying the commitment at index 0; -// builder.nullify_transient_commitment(2, 0); - -// let new_nullifiers = builder.get_new_nullifiers(); - -// let public_inputs = builder.execute(); -// assert( -// is_empty_struct_array( -// public_inputs.end.new_commitments, -// |c: SideEffect| c.is_empty() -// ) -// ); -// assert( -// struct_array_eq( -// public_inputs.end.new_nullifiers, -// [new_nullifiers[0]], -// |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), -// |a: SideEffectLinkedToNoteHash| a.is_empty() -// ) -// ); -// } - -// #[test] -// fn native_empty_nullified_commitment_means_persistent_nullifier_0() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(2); -// builder.append_nullifiers(2); - -// let public_inputs = builder.execute(); -// assert_eq( -// struct_array_length( -// public_inputs.end.new_commitments, -// |r: SideEffect| r.is_empty() -// ), 2 -// ); -// assert_eq( -// struct_array_length( -// public_inputs.end.new_nullifiers, -// |r: SideEffectLinkedToNoteHash| r.is_empty() -// ), 3 -// ); -// } - -// // same as previous test, but this time there are 0 commitments! -// // (Do we really need this test?) -// #[test] -// fn native_empty_nullified_commitment_means_persistent_nullifier_1() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_nullifiers(2); - -// let public_inputs = builder.execute(); -// assert( -// struct_array_length( -// public_inputs.end.new_commitments, -// |r: SideEffect| r.is_empty() -// ) -// == 0 -// ); -// assert( -// struct_array_length( -// public_inputs.end.new_nullifiers, -// |r: SideEffectLinkedToNoteHash| r.is_empty() -// ) -// == 3 -// ); -// } - -// #[test(should_fail_with="New nullifier is transient but hint is invalid")] -// fn invalid_nullifier_commitment_hint_fails() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(1); -// builder.append_nullifiers(1); -// // The nullifier at index 1 is nullifying the commitment at index 0; -// builder.nullify_transient_commitment(1, 0); -// // Change the hint to be out of bounds. -// builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; - -// builder.failed(); -// } - -// #[test(should_fail_with="Hinted commitment does not match")] -// fn wrong_nullifier_commitment_hint_fails() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.append_transient_commitments(2); -// builder.append_nullifiers(2); -// // The nullifier at index 1 is nullifying the commitment at index 1; -// builder.nullify_transient_commitment(1, 1); -// // The nullifier at index 2 is nullifying the commitment at index 0; -// builder.nullify_transient_commitment(2, 0); -// // Tweak the hint to be for the commitment at index 1. -// builder.nullifier_commitment_hints[2] = 1; - -// builder.failed(); -// } - -// #[test(should_fail_with="Private call stack must be empty when executing the ordering circuit")] -// fn non_empty_private_call_stack_should_fail() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.previous_kernel.push_private_call_request(1, false); - -// builder.failed(); -// } - -// #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] -// fn zero_0th_nullifier_fails() { -// let mut builder = PrivateKernelOrderingInputsBuilder::new(); - -// builder.previous_kernel.end.new_nullifiers = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); - -// builder.failed(); -// } -// } +mod tests { + use dep::std::cmp::Eq; + use crate::private_kernel_ordering::PrivateKernelInputsOrdering; + use dep::types::constants::{ + MAX_READ_REQUESTS_PER_TX, + MAX_NEW_COMMITMENTS_PER_TX, + MAX_NEW_NULLIFIERS_PER_TX, + }; + use dep::types::{ + abis::{ + kernel_circuit_public_inputs::KernelCircuitPublicInputsFinal, + side_effect::{SideEffect, SideEffectLinkedToNoteHash, Ordered}, + }, + hash::compute_unique_siloed_commitments, + tests::previous_kernel_data_builder::PreviousKernelDataBuilder, + utils::{ + arrays::{array_eq, struct_array_eq, array_length, struct_array_length, is_empty_array, is_empty_struct_array}, + bounded_vec::BoundedVec, + }, + traits::{Empty, is_empty} + }; + + struct PrivateKernelOrderingInputsBuilder { + previous_kernel: PreviousKernelDataBuilder, + read_commitment_hints: [Field; MAX_READ_REQUESTS_PER_TX], + nullifier_commitment_hints: [Field; MAX_NEW_NULLIFIERS_PER_TX], + } + + impl PrivateKernelOrderingInputsBuilder { + pub fn new() -> Self { + PrivateKernelOrderingInputsBuilder { + previous_kernel: PreviousKernelDataBuilder::new(), + read_commitment_hints: [0; MAX_READ_REQUESTS_PER_TX], + nullifier_commitment_hints: [0; MAX_NEW_NULLIFIERS_PER_TX], + } + } + + pub fn get_new_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { + self.previous_kernel.end.new_commitments.storage + } + + pub fn get_new_nullifiers(self) -> [SideEffectLinkedToNoteHash; MAX_NEW_NULLIFIERS_PER_TX] { + self.previous_kernel.end.new_nullifiers.storage + } + + pub fn get_unique_siloed_commitments(self) -> [SideEffect; MAX_NEW_COMMITMENTS_PER_TX] { + self.compute_unique_siloed_commitments(self.previous_kernel.end.new_commitments.storage) + } + + // A helper function that uses the first nullifer in the previous kernel to compute the unique siloed + // commitments for the given commitments. + pub fn compute_unique_siloed_commitments(self, commitments: [SideEffect; N]) -> [SideEffect; N] { + let first_nullifier = self.previous_kernel.end.new_nullifiers.get_unchecked(0); + compute_unique_siloed_commitments(first_nullifier.value, commitments) + } + + pub fn append_transient_commitments(&mut self, num_commitments: Field) { + // All new commitments aggregated in the previous kernel are transient commitments. + self.previous_kernel.append_new_commitments(num_commitments); + } + + pub fn add_transient_read(&mut self, commitment_index: Field) { + let read_request_index = self.previous_kernel.add_read_request_for_transient_commitment(commitment_index); + self.read_commitment_hints[read_request_index] = commitment_index; + } + + pub fn append_nullifiers(&mut self, num_nullifiers: Field) { + self.previous_kernel.append_new_nullifiers(num_nullifiers); + } + + pub fn nullify_transient_commitment(&mut self, nullifier_index: Field, commitment_index: Field) { + self.previous_kernel.end.new_nullifiers.storage[nullifier_index].note_hash = self.previous_kernel.end.new_commitments.get(commitment_index).value; + self.nullifier_commitment_hints[nullifier_index] = commitment_index; + } + + fn sort_sideffects(original: [T; N]) -> ([T; N], [u32; N], [u32; N]) where T: Ordered + Eq + Empty { + let mut indexes = [0; N]; + for i in 0..N { + indexes[i] = i as u32; + } + let sorted_indexes = indexes.sort_via(|a_index: u32, b_index: u32| { + let a = original[a_index]; + let b = original[b_index]; + if is_empty(b) { + true + } else if is_empty(a) { + false + } else { + a.counter() < b.counter() + } + }); + let sorted_sideffects = sorted_indexes.map(|i: u32| original[i]); + let mut reverse_map = [0; N]; + for i in 0..N { + reverse_map[sorted_indexes[i]] = i; + } + + (sorted_sideffects, sorted_indexes, reverse_map) + } + + pub fn execute(self) -> KernelCircuitPublicInputsFinal { + let (sorted_new_commitments, sorted_new_commitments_indexes, commiments_reverse_map) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); + let mut sorted_read_commitment_hints = [0; MAX_READ_REQUESTS_PER_TX]; + for i in 0..sorted_read_commitment_hints.len() { + sorted_read_commitment_hints[i] = commiments_reverse_map[self.read_commitment_hints[i]] as Field; + } + let (sorted_new_nullifiers, sorted_new_nullifiers_indexes, nullifiers_reverse_map) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_nullifiers()); + let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; + for i in 0..sorted_nullifier_commitment_hints.len() { + sorted_nullifier_commitment_hints[i] = nullifiers_reverse_map[self.nullifier_commitment_hints[i]] as Field; + } + let kernel = PrivateKernelInputsOrdering { + previous_kernel: self.previous_kernel.finish(), + sorted_new_commitments, + sorted_new_commitments_indexes, + read_commitment_hints: sorted_read_commitment_hints, + sorted_new_nullifiers, + sorted_new_nullifiers_indexes, + nullifier_commitment_hints: sorted_nullifier_commitment_hints, + }; + kernel.native_private_kernel_circuit_ordering() + } + + pub fn failed(self) { + let _ = self.execute(); + } + } + + #[test] + unconstrained fn native_matching_one_read_request_to_commitment_works() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + + builder.append_transient_commitments(1); + builder.add_transient_read(0); + + let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + + let public_inputs = builder.execute(); + assert( + struct_array_length( + public_inputs.end.new_commitments, + |r: SideEffect| r.is_empty() + ) + == 1 + ); + assert(public_inputs.end.new_commitments[0].eq(unique_siloed_commitments[0])); + } + + #[test] + unconstrained fn native_matching_some_read_requests_to_commitments_works() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(MAX_NEW_COMMITMENTS_PER_TX); + // Read the commitment at index 1; + builder.add_transient_read(1); + // Read the commitment at index 3; + builder.add_transient_read(3); + let unique_siloed_commitments = builder.get_unique_siloed_commitments(); + let public_inputs = builder.execute(); + assert_eq( + struct_array_length( + public_inputs.end.new_commitments, + |r: SideEffect| r.is_empty() + ), MAX_NEW_COMMITMENTS_PER_TX + ); + for i in 0..MAX_NEW_COMMITMENTS_PER_TX { + assert(public_inputs.end.new_commitments[i].eq(unique_siloed_commitments[i])); + } + } + + #[test(should_fail_with="Hinted commitment does not match read request")] + unconstrained fn native_read_request_unknown_fails() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(1); + builder.add_transient_read(0); + // Tweak the read request so that it does not match the commitment at index 0; + let read_request = builder.previous_kernel.end.read_requests.pop(); + builder.previous_kernel.end.read_requests.push(SideEffect { value: read_request.value + 1, counter: 0 }); + builder.failed(); + } + + #[test] + unconstrained fn native_squash_one_of_one_transient_matches_works() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(1); + builder.append_nullifiers(2); + // The nullifier at index 1 is nullifying the commitment at index 0; + builder.nullify_transient_commitment(1, 0); + let new_nullifiers = builder.get_new_nullifiers(); + let public_inputs = builder.execute(); + assert( + is_empty_struct_array( + public_inputs.end.new_commitments, + |c: SideEffect| c.is_empty() + ) + ); + // The nullifier at index 1 is chopped. + let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; + assert( + struct_array_eq( + public_inputs.end.new_nullifiers, + expected_new_nullifiers, + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), + |a: SideEffectLinkedToNoteHash| a.is_empty() + ) + ); + } + + #[test] + unconstrained fn native_squash_one_of_two_transient_matches_works() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(2); + builder.append_nullifiers(2); + // The nullifier at index 1 is nullifying the commitment at index 0; + builder.nullify_transient_commitment(1, 0); + let new_commitments = builder.get_new_commitments(); + // The 0th commitment will be chopped. + let unique_siloed_commitments = builder.compute_unique_siloed_commitments([new_commitments[1]]); + let new_nullifiers = builder.get_new_nullifiers(); + let public_inputs = builder.execute(); + assert( + struct_array_eq( + public_inputs.end.new_commitments, + [unique_siloed_commitments[0]], + |a: SideEffect, b: SideEffect| a.eq(b), + |a: SideEffect| a.is_empty() + ) + ); + // The nullifier at index 1 is chopped. + let expected_new_nullifiers = [new_nullifiers[0], new_nullifiers[2]]; + assert( + struct_array_eq( + public_inputs.end.new_nullifiers, + expected_new_nullifiers, + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), + |a: SideEffectLinkedToNoteHash| a.is_empty() + ) + ); + } + + #[test] + unconstrained fn native_squash_two_of_two_transient_matches_works() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(2); + builder.append_nullifiers(2); + // The nullifier at index 1 is nullifying the commitment at index 1; + builder.nullify_transient_commitment(1, 1); + // The nullifier at index 2 is nullifying the commitment at index 0; + builder.nullify_transient_commitment(2, 0); + let new_nullifiers = builder.get_new_nullifiers(); + let public_inputs = builder.execute(); + assert( + is_empty_struct_array( + public_inputs.end.new_commitments, + |c: SideEffect| c.is_empty() + ) + ); + assert( + struct_array_eq( + public_inputs.end.new_nullifiers, + [new_nullifiers[0]], + |a: SideEffectLinkedToNoteHash, b: SideEffectLinkedToNoteHash| a.eq(b), + |a: SideEffectLinkedToNoteHash| a.is_empty() + ) + ); + } + + #[test] + unconstrained fn native_empty_nullified_commitment_means_persistent_nullifier_0() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(2); + builder.append_nullifiers(2); + let public_inputs = builder.execute(); + assert_eq( + struct_array_length( + public_inputs.end.new_commitments, + |r: SideEffect| r.is_empty() + ), 2 + ); + assert_eq( + struct_array_length( + public_inputs.end.new_nullifiers, + |r: SideEffectLinkedToNoteHash| r.is_empty() + ), 3 + ); + } + // same as previous test, but this time there are 0 commitments! + // (Do we really need this test?) + + #[test] + unconstrained fn native_empty_nullified_commitment_means_persistent_nullifier_1() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_nullifiers(2); + let public_inputs = builder.execute(); + assert( + struct_array_length( + public_inputs.end.new_commitments, + |r: SideEffect| r.is_empty() + ) + == 0 + ); + assert( + struct_array_length( + public_inputs.end.new_nullifiers, + |r: SideEffectLinkedToNoteHash| r.is_empty() + ) + == 3 + ); + } + + #[test(should_fail_with="New nullifier is transient but hint is invalid")] + unconstrained fn invalid_nullifier_commitment_hint_fails() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(1); + builder.append_nullifiers(1); + // The nullifier at index 1 is nullifying the commitment at index 0; + builder.nullify_transient_commitment(1, 0); + // Change the hint to be out of bounds. + builder.nullifier_commitment_hints[1] = MAX_NEW_COMMITMENTS_PER_TX; + builder.failed(); + } + + #[test(should_fail_with="Hinted commitment does not match")] + unconstrained fn wrong_nullifier_commitment_hint_fails() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.append_transient_commitments(2); + builder.append_nullifiers(2); + // The nullifier at index 1 is nullifying the commitment at index 1; + builder.nullify_transient_commitment(1, 1); + // The nullifier at index 2 is nullifying the commitment at index 0; + builder.nullify_transient_commitment(2, 0); + // Tweak the hint to be for the commitment at index 1. + builder.nullifier_commitment_hints[2] = 1; + builder.failed(); + } + + #[test(should_fail_with="Private call stack must be empty when executing the ordering circuit")] + unconstrained fn non_empty_private_call_stack_should_fail() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.previous_kernel.push_private_call_request(1, false); + builder.failed(); + } + + #[test(should_fail_with="The 0th nullifier in the accumulated nullifier array is zero")] + unconstrained fn zero_0th_nullifier_fails() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + builder.previous_kernel.end.new_nullifiers = BoundedVec::new(SideEffectLinkedToNoteHash::empty()); + builder.failed(); + } +} diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr index c1dd67a1bdad..9d6f71fa5ddc 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/call_request.nr @@ -33,8 +33,8 @@ struct CallRequest { hash: Field, caller_contract_address: AztecAddress, caller_context: CallerContext, - start_side_effect_counter: Field, - end_side_effect_counter: Field, + start_side_effect_counter: u32, + end_side_effect_counter: u32, } impl Eq for CallRequest { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr index b1cce1f6766f..8aff95325df4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr @@ -39,6 +39,7 @@ struct PreviousKernelDataBuilder { vk: VerificationKey, vk_index: u32, vk_path: [Field; VK_TREE_HEIGHT], + sideffect_counter: u32, } impl PreviousKernelDataBuilder { @@ -63,6 +64,7 @@ impl PreviousKernelDataBuilder { vk: VerificationKey {}, vk_index: 0, vk_path: [0; VK_TREE_HEIGHT], + sideffect_counter: 2, } } @@ -108,12 +110,18 @@ impl PreviousKernelDataBuilder { } } + fn next_sideffect_counter(&mut self) -> u32 { + let counter = self.sideffect_counter; + self.sideffect_counter += 1; + counter + } + pub fn add_read_request_for_transient_commitment(&mut self, commitment_index: Field) -> Field { let new_read_request_index = self.end.read_requests.len(); let commitment = self.end.new_commitments.get(commitment_index); let read_request = SideEffect { value: commitment.value, - counter: commitment.counter+1, + counter: self.next_sideffect_counter(), }; self.end.read_requests.push(read_request); new_read_request_index @@ -126,7 +134,7 @@ impl PreviousKernelDataBuilder { // The default value is its index + 1. self.end.new_commitments.push(SideEffect{ value: i + mocked_value_offset, - counter: 0 + counter: self.next_sideffect_counter() }); } } @@ -141,7 +149,7 @@ impl PreviousKernelDataBuilder { self.end.new_nullifiers.push(SideEffectLinkedToNoteHash{ value: i + mocked_value_offset, note_hash: first_nullifier.note_hash, - counter: 0 + counter: self.next_sideffect_counter() }); } } @@ -167,18 +175,21 @@ impl PreviousKernelDataBuilder { self.end.public_call_stack.push(call_stack_item); } - fn generate_call_request(self, hash: Field, is_delegate_call: bool) -> CallRequest { + fn generate_call_request(&mut self, hash: Field, is_delegate_call: bool) -> CallRequest { let mut caller_context = CallerContext::empty(); if is_delegate_call { caller_context.msg_sender = fixtures::MSG_SENDER; caller_context.storage_contract_address = self.contract_address; } + let counter = self.next_sideffect_counter(); + let end_counter = counter + 10; + self.sideffect_counter = end_counter; CallRequest { hash, caller_contract_address: self.contract_address, caller_context, - start_side_effect_counter: 0, - end_side_effect_counter: 0, + start_side_effect_counter: counter, + end_side_effect_counter: end_counter, } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr index 84709242dbfd..a9f85427c666 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_call_data_builder.nr @@ -115,8 +115,8 @@ impl PublicCallDataBuilder { caller_contract_address: self.contract_address, caller_context, // todo: real values? - start_side_effect_counter: i, - end_side_effect_counter: i + 1, + start_side_effect_counter: i as u32, + end_side_effect_counter: (i + 1) as u32, }; self.public_inputs.public_call_stack_hashes.push(hash); diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index e5eae658eed9..e2570c92c185 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -168,106 +168,120 @@ describe('Private kernel', () => { expect(kernelOutputs).toMatchSnapshot(); }); - // // Taken from e2e_nested_contract => performs nested calls => first ordering - // it('Executes private kernel ordering after a deployment', async () => { - // const contractAddress = AztecAddress.fromString( - // '0x25e2c017f5da1f994401e61d26be435e3cfa26efee784c6b4e947f7651bd4104', - // ); - - // const deployerPubKey = new Point( - // Fr.fromString('0x1de02ddacac6d2f427e5f0d3ce59d7294f146280455dd4c582254e0b4c254b23'), - // Fr.fromString('0x23cd081dfe9c0d1873b65a36a08858e73a9b30d0339e94c4915d7110e2f07ecd'), - // ); - - // const contractDeploymentData = new ContractDeploymentData( - // deployerPubKey, - // Fr.fromString('0x0aefd90a69a643324c7bf0a9bd3b23ada090ad883773fdf0b0ad52a9f7d6f1f6'), - // Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), - // Fr.fromString('0x1ec59b0313fa504302c3336fc911d688edae67c4fbf229d68c7f36ed8797045c'), - // EthAddress.ZERO, - // ); - // const txContext = new TxContext(false, false, true, contractDeploymentData, Fr.ZERO, Fr.ZERO); - - // const newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); - // newCommitments[0] = new SideEffect( - // Fr.fromString('0x0aced88c953b70873e4a33dde4620dc43a709c15013c46c60d167de8e1c32315'), - // Fr.ZERO, - // ); - - // const newNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => SideEffectLinkedToNoteHash.empty()); - // newNullifiers[0] = new SideEffectLinkedToNoteHash( - // Fr.fromString('0x0faf656089e5a8d321b64f420fc008005736a0b4f0b8588891241392c82655b9'), - // Fr.ZERO, - // Fr.ZERO, - // ); - // newNullifiers[1] = new SideEffectLinkedToNoteHash( - // Fr.fromString('0x4a5d6bc34e84c5a3d7a625a3772f4d2f84c7d46637691ef64ee2711e6c6202'), - // Fr.ZERO, - // Fr.ZERO, - // ); - // newNullifiers[2] = new SideEffectLinkedToNoteHash( - // Fr.fromString('0x19085a4478c4aa3994d4a5935eaf5e0d58726a758d398a97f634df22d33d388a'), - // Fr.ZERO, - // Fr.ZERO, - // ); - - // const combinedAccumulatedData = new CombinedAccumulatedData( - // AggregationObject.makeFake(), - // makeTuple(MAX_READ_REQUESTS_PER_TX, () => SideEffect.empty()), - // newCommitments, - // newNullifiers, - // makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), - // makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), - // makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, () => new Fr(0n)), - // [Fr.fromString('0x57ee9bb1264085ecf4ba8274b233cdc4'), Fr.fromString('0x8a8910cc6b93b4399a1ebd8fbfb405f8')], - // [Fr.fromString('0x1c9ecec90e28d2461650418635878a5c'), Fr.fromString('0x91e49f47586ecf75f2b0cbb94e897112')], - // Fr.fromString('0xf8'), - // new Fr(4), - // [ - // new NewContractData( - // contractAddress, - // EthAddress.ZERO, - // Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), - // ), - // ], - // makeTuple(MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX, () => OptionallyRevealedData.empty()), - // makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, () => PublicDataUpdateRequest.empty()), - // makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), - // ); - - // const blockHeader = new BlockHeader( - // Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), - // Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), - // Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), - // Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), - // Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), - // Fr.ZERO, // TODO(#3441) - // Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), - // Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), - // ); - - // const constants = new CombinedConstantData(blockHeader, txContext); - - // const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); - - // const previousKernelData = new PreviousKernelData( - // kernelPublicInputs, - // makeEmptyProof(), - // VerificationKey.makeFake(), - // 0, - // makeTuple(VK_TREE_HEIGHT, () => Fr.ZERO), - // ); - - // const kernelInputs = new PrivateKernelInputsOrdering( - // previousKernelData, - // makeTuple(MAX_READ_REQUESTS_PER_TX, () => Fr.ZERO), - // makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => Fr.ZERO), - // ); - - // const kernelOutputs = await executeOrdering(kernelInputs); - - // expect(kernelOutputs).toMatchSnapshot(); - // }); + // Taken from e2e_nested_contract => performs nested calls => first ordering + it('Executes private kernel ordering after a deployment', async () => { + const contractAddress = AztecAddress.fromString( + '0x25e2c017f5da1f994401e61d26be435e3cfa26efee784c6b4e947f7651bd4104', + ); + + const deployerPubKey = new Point( + Fr.fromString('0x1de02ddacac6d2f427e5f0d3ce59d7294f146280455dd4c582254e0b4c254b23'), + Fr.fromString('0x23cd081dfe9c0d1873b65a36a08858e73a9b30d0339e94c4915d7110e2f07ecd'), + ); + + const contractDeploymentData = new ContractDeploymentData( + deployerPubKey, + Fr.fromString('0x0aefd90a69a643324c7bf0a9bd3b23ada090ad883773fdf0b0ad52a9f7d6f1f6'), + Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), + Fr.fromString('0x1ec59b0313fa504302c3336fc911d688edae67c4fbf229d68c7f36ed8797045c'), + EthAddress.ZERO, + ); + const txContext = new TxContext(false, false, true, contractDeploymentData, Fr.ZERO, Fr.ZERO); + + const newCommitments = makeTuple(MAX_NEW_COMMITMENTS_PER_TX, () => SideEffect.empty()); + newCommitments[0] = new SideEffect( + Fr.fromString('0x0aced88c953b70873e4a33dde4620dc43a709c15013c46c60d167de8e1c32315'), + Fr.ZERO, + ); + + const newNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => SideEffectLinkedToNoteHash.empty()); + const sortedNewNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => newNullifiers[i]); + + newNullifiers[0] = new SideEffectLinkedToNoteHash( + Fr.fromString('0x0faf656089e5a8d321b64f420fc008005736a0b4f0b8588891241392c82655b9'), + Fr.ZERO, + new Fr(1), + ); + newNullifiers[1] = new SideEffectLinkedToNoteHash( + Fr.fromString('0x4a5d6bc34e84c5a3d7a625a3772f4d2f84c7d46637691ef64ee2711e6c6202'), + Fr.ZERO, + new Fr(2), + ); + newNullifiers[2] = new SideEffectLinkedToNoteHash( + Fr.fromString('0x19085a4478c4aa3994d4a5935eaf5e0d58726a758d398a97f634df22d33d388a'), + Fr.ZERO, + Fr.ZERO, + ); + + sortedNewNullifiers[0] = newNullifiers[2]; + sortedNewNullifiers[1] = newNullifiers[0]; + sortedNewNullifiers[2] = newNullifiers[1]; + + const sortedNewNullifiersIndexes = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => + newNullifiers.indexOf(sortedNewNullifiers[i]), + ); + + const combinedAccumulatedData = new CombinedAccumulatedData( + AggregationObject.makeFake(), + makeTuple(MAX_READ_REQUESTS_PER_TX, () => SideEffect.empty()), + newCommitments, + newNullifiers, + makeTuple(MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), + makeTuple(MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, () => CallRequest.empty()), + makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, () => new Fr(0n)), + [Fr.fromString('0x57ee9bb1264085ecf4ba8274b233cdc4'), Fr.fromString('0x8a8910cc6b93b4399a1ebd8fbfb405f8')], + [Fr.fromString('0x1c9ecec90e28d2461650418635878a5c'), Fr.fromString('0x91e49f47586ecf75f2b0cbb94e897112')], + Fr.fromString('0xf8'), + new Fr(4), + [ + new NewContractData( + contractAddress, + EthAddress.ZERO, + Fr.fromString('0x0cad3b5391e40af8743e1053c015e16abac6100a8b917512c083cb4cbb8ccc03'), + ), + ], + makeTuple(MAX_OPTIONALLY_REVEALED_DATA_LENGTH_PER_TX, () => OptionallyRevealedData.empty()), + makeTuple(MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, () => PublicDataUpdateRequest.empty()), + makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), + ); + + const blockHeader = new BlockHeader( + Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), + Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), + Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), + Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), + Fr.fromString('0x1759d221795419503f86c032e8f8762f2b739e74835099584b6531f5f27390fe'), + Fr.ZERO, // TODO(#3441) + Fr.fromString('0x0ccaafdc9c353743970d4e305ae73641ce694f07db67886d2769c9ed88e969d8'), + Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), + ); + + const constants = new CombinedConstantData(blockHeader, txContext); + + const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); + + const previousKernelData = new PreviousKernelData( + kernelPublicInputs, + makeEmptyProof(), + VerificationKey.makeFake(), + 0, + makeTuple(VK_TREE_HEIGHT, () => Fr.ZERO), + ); + + const kernelInputs = new PrivateKernelInputsOrdering( + previousKernelData, + newCommitments, + makeTuple(MAX_NEW_COMMITMENTS_PER_TX, i => i), + makeTuple(MAX_READ_REQUESTS_PER_TX, () => Fr.ZERO), + sortedNewNullifiers, + sortedNewNullifiersIndexes, + makeTuple(MAX_NEW_NULLIFIERS_PER_TX, () => Fr.ZERO), + ); + + const kernelOutputs = await executeOrdering(kernelInputs); + + expect(kernelOutputs).toMatchSnapshot(); + }); // Taken from e2e_nested_contract => performs nested calls => last inner // To regenerate fixture data run the following on the yarn-project/e2e folder From a7178b29553986ba2e3390dcba4cb1898643d648 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 9 Jan 2024 11:35:10 +0000 Subject: [PATCH 11/18] test: fix acir simulator test --- .../acir-simulator/src/client/private_execution.test.ts | 2 +- yarn-project/acir-simulator/src/client/simulator.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index fa7c6fd8ebac..cd232cd177c9 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -581,7 +581,7 @@ describe('Private Execution test suite', () => { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: 1, + startSideEffectCounter: 2, }), }); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 7aed4d8220ce..3ec021742396 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -88,6 +88,7 @@ export class AcirSimulator { false, false, request.functionData.isConstructor, + // TODO: when contract deployment is done in-app, we should only reserve one counter for the tx hash 2, // 2 counters are reserved for tx hash and contract deployment nullifier ); const context = new ClientExecutionContext( From f0a5d9bbae6a6a3622a2d12782acba16bdd53e87 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 9 Jan 2024 12:32:07 +0000 Subject: [PATCH 12/18] feat: remove usage of TS side effect counter in private --- .../acir-simulator/src/client/client_execution_context.ts | 3 --- yarn-project/acir-simulator/src/client/simulator.ts | 2 -- 2 files changed, 5 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 2f5f5c434d0e..c991bd244281 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -24,7 +24,6 @@ import { toACVMContractDeploymentData, toACVMWitness, } from '../acvm/index.js'; -import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; import { DBOracle } from './db_oracle.js'; import { ExecutionNoteCache } from './execution_note_cache.js'; @@ -71,7 +70,6 @@ export class ClientExecutionContext extends ViewDataOracle { protected readonly authWitnesses: AuthWitness[], private readonly packedArgsCache: PackedArgsCache, private readonly noteCache: ExecutionNoteCache, - private readonly sideEffectCounter: SideEffectCounter, protected readonly db: DBOracle, private readonly curve: Grumpkin, protected log = createDebugLogger('aztec:simulator:client_execution_context'), @@ -343,7 +341,6 @@ export class ClientExecutionContext extends ViewDataOracle { this.authWitnesses, this.packedArgsCache, this.noteCache, - this.sideEffectCounter, this.db, this.curve, ); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index 3ec021742396..087b641e5224 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -10,7 +10,6 @@ import { AztecNode, FunctionCall, Note, TxExecutionRequest } from '@aztec/types' import { WasmBlackBoxFunctionSolver, createBlackBoxSolver } from '@noir-lang/acvm_js'; import { createSimulationError } from '../common/errors.js'; -import { SideEffectCounter } from '../common/index.js'; import { PackedArgsCache } from '../common/packed_args_cache.js'; import { ClientExecutionContext } from './client_execution_context.js'; import { DBOracle, FunctionArtifactWithDebugMetadata } from './db_oracle.js'; @@ -100,7 +99,6 @@ export class AcirSimulator { request.authWitnesses, PackedArgsCache.create(request.packedArguments), new ExecutionNoteCache(), - new SideEffectCounter(), this.db, curve, ); From 220ecf52ae1851b5defa94190a88f7235c15747d Mon Sep 17 00:00:00 2001 From: sirasistant Date: Tue, 9 Jan 2024 13:04:14 +0000 Subject: [PATCH 13/18] test: add ordering test for sideffects --- .../src/private_kernel_ordering.nr | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 9abf6103f462..4b3183a22c92 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -466,6 +466,37 @@ mod tests { ); } + #[test] + unconstrained fn ordering_of_commitments_and_nullifiers() { + let mut builder = PrivateKernelOrderingInputsBuilder::new(); + + let mut sorted_new_commitments = [SideEffect::empty(); 10]; + let mut sorted_new_nullifiers = [SideEffectLinkedToNoteHash::empty(); 10]; + + for i in 0..10 { + sorted_new_commitments[i] = SideEffect { value: (i + 1) as Field, counter: i + 1 }; + sorted_new_nullifiers[i] = SideEffectLinkedToNoteHash { value: (i + 11) as Field, counter: i + 11, note_hash: 0 }; + } + + for i in 0..10 { + builder.previous_kernel.end.new_commitments.push(sorted_new_commitments[9 - i]); + builder.previous_kernel.end.new_nullifiers.push(sorted_new_nullifiers[9 - i]); + } + + let public_inputs = builder.execute(); + + let sorted_unique_commitments = compute_unique_siloed_commitments( + public_inputs.end.new_nullifiers[0].value, + sorted_new_commitments + ); + + for i in 0..10 { + assert(public_inputs.end.new_commitments[i].eq(sorted_unique_commitments[i])); + // +1 due to the 0th nullifier being the tx hash + assert(public_inputs.end.new_nullifiers[i + 1].eq(sorted_new_nullifiers[i])); + } + } + #[test] unconstrained fn native_empty_nullified_commitment_means_persistent_nullifier_0() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); From c38b741af4cd183668aee7daf59566ad223c0801 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 10 Jan 2024 08:32:38 +0000 Subject: [PATCH 14/18] chore: comments --- .../acir-simulator/src/public/public_execution_context.ts | 2 +- yarn-project/aztec-nr/aztec/src/context.nr | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index f5b9cd7c1133..16a0d531d44e 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -199,7 +199,7 @@ export class PublicExecutionContext extends TypedOracle { isContractDeployment: false, isDelegateCall: false, isStaticCall: false, - startSideEffectCounter: 0, // TODO(alvaro) reevaluate this + startSideEffectCounter: 0, // TODO use counters in public execution }); const nestedExecution: PublicExecution = { diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index ddc093d7466d..b89e570f53fd 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -431,6 +431,7 @@ impl PrivateContext { assert(function_selector.eq(item.function_data.selector)); assert_eq(item.public_inputs.call_context.start_side_effect_counter, self.side_effect_counter); + // We increment the sideffect counter by one, to account for the call itself being a side effect. self.side_effect_counter = self.side_effect_counter + 1; assert(args_hash == item.public_inputs.args_hash); From bc8ad13409967274909f7289af9179a2bde342e6 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Wed, 10 Jan 2024 15:38:49 +0000 Subject: [PATCH 15/18] chore: remove extraneous comment --- .../noir-protocol-circuits/src/index.ts | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/yarn-project/noir-protocol-circuits/src/index.ts b/yarn-project/noir-protocol-circuits/src/index.ts index 07b782c8e1cb..89954211e99e 100644 --- a/yarn-project/noir-protocol-circuits/src/index.ts +++ b/yarn-project/noir-protocol-circuits/src/index.ts @@ -140,31 +140,6 @@ export async function executeOrdering( input: mapPrivateKernelInputsOrderingToNoir(privateKernelInputsOrdering), }; - // console.log( - // privateKernelInputsOrdering.previousKernel.publicInputs.end.newNullifiers - // .filter(sideffect => !sideffect.value.isZero()) - // .map(sideffect => ({ - // val: sideffect.value.toString(), - // counter: sideffect.counter.toString(), - // })), - // ); - // console.log( - // privateKernelInputsOrdering.previousKernel.publicInputs.end.newCommitments - // .filter(sideffect => !sideffect.value.isZero()) - // .map(sideffect => ({ - // val: sideffect.value.toString(), - // counter: sideffect.counter.toString(), - // })), - // ); - // console.log( - // privateKernelInputsOrdering.previousKernel.publicInputs.end.readRequests - // .filter(sideffect => !sideffect.value.isZero()) - // .map(sideffect => ({ - // val: sideffect.value.toString(), - // counter: sideffect.counter.toString(), - // })), - // ); - const returnType = await executePrivateKernelOrderingWithACVM(params); return mapKernelCircuitPublicInputsFinalFromNoir(returnType); From 78c188709795dd656b06f31565be2c9e08052f3f Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 11 Jan 2024 13:12:03 +0000 Subject: [PATCH 16/18] feat: optimize checking ordering --- .../src/structs/kernel/private_kernel.ts | 4 +-- .../src/private_kernel_ordering.nr | 35 ++++++++----------- .../pxe/src/kernel_prover/kernel_prover.ts | 10 +++--- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts index 0a583aba9987..0690feff073f 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts @@ -197,7 +197,7 @@ export class PrivateKernelInputsOrdering { */ public sortedNewCommitments: Tuple, /** - * The sorted new commitments indexes. + * The sorted new commitments indexes. Maps original to sorted. */ public sortedNewCommitmentsIndexes: Tuple, /** @@ -205,7 +205,7 @@ export class PrivateKernelInputsOrdering { */ public readCommitmentHints: Tuple, /** - * The sorted new nullifiers. + * The sorted new nullifiers. Maps original to sorted. */ public sortedNewNullifiers: Tuple, /** diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index f21915617afb..cedf5c470800 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -65,31 +65,24 @@ impl PrivateKernelInputsOrdering { } fn assert_sorted_counters(original: [T; N], sorted: [T; N], indexes: [u32; N]) where T: Eq + Ordered + Empty { - let mut seen = [false; N]; - let mut prev_counter = Option::none(); let mut prev_was_empty = false; for i in 0..N { - let item = sorted[i]; - - let index = indexes[i]; - assert(index < N, "Index out of bounds"); - assert(!seen[index], "Duplicate index"); - seen[index] = true; - - assert(item.eq(original[index]), "Not equal"); - - let counter = item.counter(); + let item = if prev_was_empty { + sorted[i] + } else { + sorted[indexes[i]] + }; + assert(item.eq(original[i]), "Sorted item is not equal"); let is_empty = is_empty(item); if prev_was_empty { assert(is_empty, "Empty items must be at the end"); - } else if !is_empty & prev_counter.is_some() { - assert(counter > prev_counter.unwrap(), "Not sorted"); + } else if (i != 0) & !is_empty { + assert(sorted[i].counter() > sorted[i - 1].counter(), "Not sorted"); } prev_was_empty = is_empty; - prev_counter = Option::some(counter); } } @@ -275,7 +268,7 @@ mod tests { self.nullifier_commitment_hints[nullifier_index] = commitment_index; } - fn sort_sideffects(original: [T; N]) -> ([T; N], [u32; N], [u32; N]) where T: Ordered + Eq + Empty { + fn sort_sideffects(original: [T; N]) -> ([T; N],[u32; N]) where T: Ordered + Eq + Empty { let mut indexes = [0; N]; for i in 0..N { indexes[i] = i as u32; @@ -297,19 +290,19 @@ mod tests { reverse_map[sorted_indexes[i]] = i; } - (sorted_sideffects, sorted_indexes, reverse_map) + (sorted_sideffects, reverse_map) } pub fn execute(self) -> KernelCircuitPublicInputsFinal { - let (sorted_new_commitments, sorted_new_commitments_indexes, commiments_reverse_map) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); + let (sorted_new_commitments, sorted_new_commitments_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_commitments()); let mut sorted_read_commitment_hints = [0; MAX_READ_REQUESTS_PER_TX]; for i in 0..sorted_read_commitment_hints.len() { - sorted_read_commitment_hints[i] = commiments_reverse_map[self.read_commitment_hints[i]] as Field; + sorted_read_commitment_hints[i] = sorted_new_commitments_indexes[self.read_commitment_hints[i]] as Field; } - let (sorted_new_nullifiers, sorted_new_nullifiers_indexes, nullifiers_reverse_map) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_nullifiers()); + let (sorted_new_nullifiers, sorted_new_nullifiers_indexes) = PrivateKernelOrderingInputsBuilder::sort_sideffects(self.get_new_nullifiers()); let mut sorted_nullifier_commitment_hints = [0; MAX_NEW_NULLIFIERS_PER_TX]; for i in 0..sorted_nullifier_commitment_hints.len() { - sorted_nullifier_commitment_hints[i] = nullifiers_reverse_map[self.nullifier_commitment_hints[i]] as Field; + sorted_nullifier_commitment_hints[i] = sorted_new_nullifiers_indexes[self.nullifier_commitment_hints[i]] as Field; } let kernel = PrivateKernelInputsOrdering { previous_kernel: self.previous_kernel.finish(), diff --git a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts index 66d9f7f5d43c..307304e48887 100644 --- a/yarn-project/pxe/src/kernel_prover/kernel_prover.ts +++ b/yarn-project/pxe/src/kernel_prover/kernel_prover.ts @@ -216,10 +216,12 @@ export class KernelProver { return Number(a.sideEffect.counter.toBigInt() - b.sideEffect.counter.toBigInt()); }); - return [ - sorted.map(({ sideEffect }) => sideEffect) as Tuple, - sorted.map(({ index }) => index) as Tuple, - ]; + const originalToSorted = sorted.map(() => 0); + sorted.forEach(({ index }, i) => { + originalToSorted[index] = i; + }); + + return [sorted.map(({ sideEffect }) => sideEffect) as Tuple, originalToSorted as Tuple]; } private async createPrivateCallData( From 6755e1a19ca5af1d0d2c32516f20996d2685fc99 Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 11 Jan 2024 13:46:40 +0000 Subject: [PATCH 17/18] tests: fix unit tests --- yarn-project/noir-protocol-circuits/src/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index e2570c92c185..623e0bc7b9b2 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -218,7 +218,7 @@ describe('Private kernel', () => { sortedNewNullifiers[2] = newNullifiers[1]; const sortedNewNullifiersIndexes = makeTuple(MAX_NEW_NULLIFIERS_PER_TX, i => - newNullifiers.indexOf(sortedNewNullifiers[i]), + sortedNewNullifiers.indexOf(newNullifiers[i]), ); const combinedAccumulatedData = new CombinedAccumulatedData( From 1335d888a3866ae7df90f62571544e5b3490118b Mon Sep 17 00:00:00 2001 From: sirasistant Date: Thu, 11 Jan 2024 15:18:06 +0000 Subject: [PATCH 18/18] test: fix test --- .../crates/private-kernel-lib/src/private_kernel_ordering.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr index 4d82f6d08810..8ba937ce90e4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_ordering.nr @@ -469,7 +469,7 @@ mod tests { } #[test(should_fail)] - fn invalid_nullifier_commitment_hint_fails() { + unconstrained fn invalid_nullifier_commitment_hint_fails() { let mut builder = PrivateKernelOrderingInputsBuilder::new(); builder.append_transient_commitments(1); builder.append_nullifiers(1);