onflow/flow-emulator

Register source files for scripts/transactions

m-Peter opened this issue ยท 6 comments

Issue To Be Solved

Currently, when viewing coverage reports either from tests or interaction with the emulator, the script/transaction locations are very difficult to interpret, as only the hash ID is presented. For example:

"t.147b164ddb574a408ed4f503df8511caea1887db3bd0444729a0f54ef183b070": {
  "line_hits": {
    "13": 1,
    "14": 0,
    "5": 1,
    "8": 1,
    "9": 1
  },
  "missed_lines": [
    14
  ],
  "statements": 5,
  "percentage": "80.0%"
}

Screenshot from 2023-05-22 15-05-00

From this, developers are not able to map a script/transaction hash ID, to its corresponding source file.

Suggest A Solution

One possible solution would be to keep a global mapping, from script/transaction hash ID, to its corresponding source file. This will be a many-to-one mapping, where many keys (script/transaction IDs) can point to the same source file. This can happen, because the script/transaction hash ID is affected by user-provided arguments, among other things (such as signers for a particular transaction).
This global mapping, can then be used to substitute script/transaction hash IDs, with the mapped source files. We would need to hook into script/transaction execution, and register the corresponding source file.

Remarks: The emulator does not deal with source files when executing scripts/transactions. The source code of scripts/transactions is in the form of []byte.

When emulator is used from within flow-cli the files are read from the respective commands:

When emulator is used from within cadence-tools/test, the files are read from the testing framework itself (https://github.com/onflow/cadence/blob/master/runtime/stdlib/contracts/crypto_test.cdc#L23).

Context

This would be useful for tools such as:

I think it's ok if the file location is not known because that's another layer of mapping based on the client loading the location (if that makes sense). I feel that if we keep a map in case of transactions from the source code to the transaction ID, that's enough to then reverse it, so the client that has the source files can calculate the same ID from the source code and then can map that to file locations. Also for mapping IDs, I would just suggest a simple hash of the content, but maybe with stripped formatting (no whitespace characters etc.).

or we can just not show scripts and transactions :)

if you want to make coverage for your transactions / scripts, deploying a contract and putting code inside works great

But it's not just about coverage right? debugging is another thing, also maybe profiling.

Yes, exactly. It's not just about coverage. I just used coverage as a context, because in this context I came across this missing feature, so to speak.

if you want to make coverage for your transactions / scripts, deploying a contract and putting code inside works great

But transactions have their own specifics, such as prepare/pre/execute/post etc. Which you can't test in a contract.

another idea: ( as I am lately fan of pragmas ) Maybe we can add a pragram to source file ? Then map that value to script/tx id on emulator side?

That is indeed quite an interesting idea ๐Ÿ’ฏ . This way, we can also give identifiers to dynamically created scripts&transactions, I will investigate how that works outs ๐Ÿ‘