For VM tests, specify the code that is being run as well as the current state of
    the EVM. State tests don't support this object. The parameter is a dictionary specifying some
    or all of the following keys:

    +--------------------+------------------------------------------------------------+
    |  key               | description                                                |
    +====================+============================================================+
    | ``"address"``      | the address of the account executing the code              |
    +--------------------+------------------------------------------------------------+
    | ``"caller"``       | the caller address                                         |
    +--------------------+------------------------------------------------------------+
    | ``"origin"``       | the origin address (defaulting to the caller address)      |
    +--------------------+------------------------------------------------------------+
    | ``"value"``        | the value of the call                                      |
    +--------------------+------------------------------------------------------------+
    | ``"data"``         | the data passed with the call                              |
    +--------------------+------------------------------------------------------------+
    | ``"gasPrice"``     | the gas price of the call                                  |
    +--------------------+------------------------------------------------------------+
    | ``"gas"``          | the amount of gas allocated for the call                   |
    +--------------------+------------------------------------------------------------+
    | ``"code"``         | the bytecode to execute                                    |
    +--------------------+------------------------------------------------------------+
    | ``"vyperLLLCode"`` | the code in Vyper LLL (compiled to bytecode automatically) |
    +--------------------+------------------------------------------------------------+

def execution(execution: Dict[str, Any], filler: Dict[str, Any]) -> Dict[str, Any]:
    """
    For VM tests, specify the code that is being run as well as the current state of
    the EVM. State tests don't support this object. The parameter is a dictionary specifying some
    or all of the following keys:

    +--------------------+------------------------------------------------------------+
    |  key               | description                                                |
    +====================+============================================================+
    | ``"address"``      | the address of the account executing the code              |
    +--------------------+------------------------------------------------------------+
    | ``"caller"``       | the caller address                                         |
    +--------------------+------------------------------------------------------------+
    | ``"origin"``       | the origin address (defaulting to the caller address)      |
    +--------------------+------------------------------------------------------------+
    | ``"value"``        | the value of the call                                      |
    +--------------------+------------------------------------------------------------+
    | ``"data"``         | the data passed with the call                              |
    +--------------------+------------------------------------------------------------+
    | ``"gasPrice"``     | the gas price of the call                                  |
    +--------------------+------------------------------------------------------------+
    | ``"gas"``          | the amount of gas allocated for the call                   |
    +--------------------+------------------------------------------------------------+
    | ``"code"``         | the bytecode to execute                                    |
    +--------------------+------------------------------------------------------------+
    | ``"vyperLLLCode"`` | the code in Vyper LLL (compiled to bytecode automatically) |
    +--------------------+------------------------------------------------------------+
    """
    execution = normalize_execution(execution or {})

    # user caller as origin if not explicitly given
    if "caller" in execution and "origin" not in execution:
        execution = assoc(execution, "origin", execution["caller"])

    if "vyperLLLCode" in execution:
        code = compile_vyper_lll(execution["vyperLLLCode"])
        if "code" in execution:
            if code != execution["code"]:
                raise ValueError("Compiled Vyper LLL code does not match")
        execution = assoc(execution, "code", code)

    execution = merge(DEFAULT_EXECUTION, execution)

    test_name = get_test_name(filler)
    return deep_merge(
        filler,
        {
            test_name: {
                "exec": execution,
            }
        }
    )