keep-starknet-strange / snos

Rust Library for running the Starknet OS via the Cairo VM
MIT License
53 stars 24 forks source link

bug: find_element(): No value found for key #376

Closed ftheirs closed 47 minutes ago

ftheirs commented 1 day ago

Current behavior: block_prover is not working for block 164333 and 169206

Expected behavior: block_prover should be able to process the block

Steps to reproduce: cargo run --release -p prove_block -- --block-number block_number --rpc-provider rpc_provider_url

ftheirs commented 1 day ago

After running prove_block with these blocks, we get this console output.

[ERROR prove_block] 
    inner_exc error: Got an exception while executing a hint: find_element(): No value found for key: 2470367566547082658569904768345892767152013479465620269280041730159904098783

Block could not be proven: SnOsError(Runner(VmException(VmException { pc: Relocatable { segment_index: 0, offset: 2279 }, inst_location: Some(Location { end_line: 65, end_col: 7, input_file: InputFile { filename: "/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/cairo/common/find_element.cairo" }, parent_location: None, start_line: 35, start_col: 5 }), inner_exc: Hint((0, NoValueForKeyFindElement(0x5762db1b9135a9b54921d89d3aa564bb83e6441927bf7e7415860b9150109df))), error_attr_value: None, traceback: Some("Cairo traceback (most recent call last):\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_transactions.cairo:267:20: (pc=0:10463)\n            return execute_transactions_inner(block_context=block_context, n_txs=n_txs - 1);\n                   ^**********************************************************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_transactions.cairo:267:20: (pc=0:10463)\n            return execute_transactions_inner(block_context=block_context, n_txs=n_txs - 1);\n                   ^**********************************************************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_transactions.cairo:265:13: (pc=0:10453)\n            execute_invoke_function_transaction(block_context=block_context);\n            ^**************************************************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_transactions.cairo:508:9: (pc=0:10796)\n        select_execute_entry_point_func(\n        ^******************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_entry_point.cairo:225:35: (pc=0:5050)\n    let (retdata_size, retdata) = execute_entry_point(\n                                  ^******************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_entry_point.cairo:286:9: (pc=0:4829)\n        call_execute_syscalls(\n        ^********************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:205:16: (pc=0:7347)\n        return execute_syscalls(\n               ^***************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:215:16: (pc=0:7370)\n        return execute_syscalls(\n               ^***************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:225:16: (pc=0:7389)\n        return execute_syscalls(\n               ^***************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:233:9: (pc=0:7404)\n        execute_call_contract(\n        ^********************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:477:12: (pc=0:7832)\n    return contract_call_helper(\n           ^*******************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_syscalls.cairo:538:55: (pc=0:7895)\n        let (retdata_size, retdata, _is_deprecated) = select_execute_entry_point_func(\n                                                      ^******************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_entry_point.cairo:219:46: (pc=0:5029)\n        let (retdata_size, retdata: felt*) = deprecated_execute_entry_point(\n                                             ^*****************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_entry_point.cairo:194:5: (pc=0:5011)\n    call_execute_deprecated_syscalls(\n    ^*******************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_syscalls.cairo:542:16: (pc=0:5488)\n        return execute_deprecated_syscalls(\n               ^**************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_syscalls.cairo:617:9: (pc=0:5613)\n        execute_deploy_syscall(\n        ^*********************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_syscalls.cairo:272:9: (pc=0:5229)\n        deploy_contract(\n        ^**************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_syscalls.cairo:761:51: (pc=0:5783)\n    let (retdata_size, retdata, _is_deprecated) = select_execute_entry_point_func(\n                                                  ^******************************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/deprecated_execute_entry_point.cairo:225:35: (pc=0:5050)\n    let (retdata_size, retdata) = execute_entry_point(\n                                  ^******************^\n/Users/ftheirs/Repositories/snos/cairo-lang/src/starkware/starknet/core/os/execution/execute_entry_point.cairo:155:53: (pc=0:4737)\n    let (compiled_class_fact: CompiledClassFact*) = find_element(\n                                                    ^***********^\n") })))
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

After following the output, we realized that the issue is triggered in this part from cairo-lang It basically complains that it cannot find compiled_class_hash. After some debugging, the compiled_class_hash that is missing is the one from the class that was declared in the same block

ftheirs commented 1 day ago

If we check some lines above, we can see that contract_class_changes the map where the compiled_class_hash should be present. After carefully reviewing, the contract_class_changes is generated with in load_class_facts and it depends on compiled_classes from OS_INPUT variable

ftheirs commented 1 day ago

Ok.. now that we have isolated the issue, we're a step closer to the fix. We need to be sure that compiled_classes contains the entry with the compiled_class_hash and the compiled code.

After following how this map is created, we reached this function that delivers two maps that are needed to process this block: For declare transactions: class_hash_to_compiled_class_hash: HashMap<ClassHash, CompiledClassHash> needs to be initialized with Zero for all new classes

For deploy transactions: compiled_classes: HashMap<CompiledClassHash, GenericCasmContractClass> needs to be set with the compiled_class_hash from declared class and the corresponding binary.

On this commit, the class_hash_to_compiled_class_hash was initialized with zeros for declared classes and that was correct because the OS expects a zero for new classes. However, the order of initialization here matters and it was making a conflict with this part that avoids to populating compiled_classes with the necessary entries.

ftheirs commented 1 day ago

The proposed solutions consists of moving the step that set zeroes at the end, after everything was initialized. You can check in this commit the changes that are needed to fix this issue. Basically, with this logic the compiled_classes hashmap is initialized with all correct values and we need to overwrite the declared class from class_hash_to_compiled_class_hash

After applying the fix, prove_block can finish the process from the blocks.