Skip to content

Identifiers for aliases are not built properly #2041

Closed
@enitrat

Description

@enitrat

TLDR: I think the Identifiers for aliases are missing some useful data; example: in this test I would expect the identifier to have the full_path set to to the "destination" value - or something similar

Identifier {
pc: None,
type_: Some(String::from("alias")),
value: None,
full_name: None,
members: None,
cairo_type: None,
size: None,
},


I'm working on making all python hints compatible to use with the RustVM, and for that, i'm currently working on making the constant of the programs resolvable and accessible through an ids object.

For that I need to properly retrieve the values associated to constants.
Here are my tests (done in https://github.com/kkrt-labs/keth repo & hard to repro as i'm still fiddling around):

from ethereum.exceptions import ValueError
const MY_CONST = 100;
func test__access_local_const() {
    %{ assert ids.MY_CONST == 100 %}
    ret;
}

func test__access_non_imported_const_should_fail() {
    %{ ids.HALF_SHIFT %}
    ret;
}

func test__access_imported_const() {
    %{ assert ids.ValueError == int.from_bytes('ValueError'.encode("ascii"), "big") %}
    ret;
}

Test 1: test with a locally defined constant. This works. If I log some information, I can see that at some point, I'm doing:

Checking identifier for if __main__.MY_CONST - result: Some(Identifier { pc: None, type_: Some("const"), value: Some(0x64), full_name: None, members: None, cairo_type: None, size: None })

Test 2: verifying that non-important program constants are not accssible. works fine

Test 3: verifying if imported program constants are accessible. This however is problematic: here's what searching the Identifiers yields:

Checking identifier for __main__.ValueError - result: Some(Identifier { pc: None, type_: Some("alias"), value: None, full_name: None, members: None, cairo_type: None, size: None })

As you can see this is correctly being retrieved as an Identifier of type alias which is expected. However there's no associated value, nor any other type information.

I don't know if this is intended or not? I would expect there to be more info, perhaps, full_name resolving to the path of the constant in the program? This way I could easily use the constants argument passed in all hints execution to get the proper value.

This is happening during the execute_hint step, relevant code that I wrote:

    pub fn execute_hint(
        &mut self,
        hint_code: &str,
        vm: &mut VirtualMachine,
        exec_scopes: &mut ExecutionScopes,
        ids_data: &HashMap<String, HintReference>,
        ap_tracking: &ApTracking,
        constants: &HashMap<String, Felt252>,
        hint_accessible_scopes: &Vec<String>,
    ) -> Result<(), HintError> {
...
    for (name, value) in constants {
        // A constant is accessible if any of the hint accessible scopes is a prefix of the constant
        // name
        let name_parts = name.split('.').collect::<Vec<_>>();
        let name_parts_without_last = name_parts[..name_parts.len() - 1].join(".");
        let name_last_part = name_parts[name_parts.len() - 1].to_string();
        if hint_accessible_scopes.iter().any(|scope| name_parts_without_last == *scope) {
            println!("{} is accessible", name);
            py_ids_dict
                .borrow_mut(py)
                .items
                .insert(name_last_part.clone(), value.to_biguint().into_bound_py_any(py)?.into());
        }

        //TODO: this works fine if the constant is not an alias(==imported in current module), but if it is, we need to resolve the
        //alias to the actual name!
        // Start by checking for each accessible scope if scope + name_last_part is an alias
        // If it is, resolve the alias to the actual name and use that instead.
        for scope in hint_accessible_scopes {
            let alias = format!("{}.{}", scope, name_last_part);
            let identifier = identifiers.get(&alias);
            println!("Checking if {} is an alias - result: {:?}", alias, identifier);
        }

Second note: I made of fork of the CairoVM to have hint_accessible_scopes available during hint executions. Which I believe should be there. I will submit a PR isolated for this.

For reference, in the python VM, I can get the original path from the alias.

Resolving alias __main__.ValueError
Resolved __main__.ValueError to IdentifierSearchResult(identifier_definition=ConstDefinition(value=407920666966016633499506), canonical_name=ScopedName(path=('ethereum', 'exceptions', 'ValueError')), non_parsed=ScopedName(path=()))

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions