Advice around logging the Bytes stdlib type

(resubmitting this because the auto moderator flagged it for spam – I also can’t paste GitHub links in here, so they have a space between github and the .com)

Hi!

For some context, our protocol (Hyperlane) requires some data to be encoded in a specific manner & hashed, which we achieve using the std Bytes type and the keccak256 function. We also require this data, i.e. all the bytes in the Bytes type, to be logged. The logging is crucial for us so that we can index this data.

Passing the Bytes into the std lib logging::log function (which uses the __log intrinsic) doesn’t work for a couple reasons:

  1. iiuc the intrinsic doesn’t recognize that it should be logging the memory range that the Bytes type is pointing to. So the data that’s logged is incorrect. If I recall correctly the actual ptr was being logged
  2. this causes the Bytes type to leak into the contract’s ABI, which atm breaks the Rust SDK’s abigen because there isn’t Bytes support yet (seems this is coming fwiw)

So what we decided to do is add our own impl Bytes with a function that lets us log the memory “manually” ourselves in an asm block using logd: https://github .com/hyperlane-xyz/fuel-contracts/blob/895fbc260d14d6cdbbc76961936805185707df9a/contracts/bytes-extended/src/main.sw#L254-L260. We also have a version that lets us log with a specific ID that we can set ourselves, so that our indexer can easily spot these logs: https://github .com/hyperlane-xyz/fuel-contracts/blob/895fbc260d14d6cdbbc76961936805185707df9a/contracts/bytes-extended/src/main.sw#L262-L271

This works well for getting the data we need logged, but now because we’re circumventing the compiler, things are starting to feel a little weird. Because now our contract is logging data that isn’t reflected in the generated ABI (because the log ID won’t have a valid entry in the generated ABI), e.g. the TS SDK will throw an error if we try to call a function that logs these bytes because it’s unable to decode the log. For this specifically there’s a simple enough workaround, which is to send the transaction via the provider where it won’t try to auto-parse any receipts, but I mention it mostly as an example consequence of our asm usage

So my question is:
Does what we’re doing to log this memory feel reasonable, or is this a footgun waiting to happen? Are there any other ideas that wouldn’t require us to circumvent the compiler’s nice log ID handling?

3 Likes

you are right.thanks.

There is currently an open issue for this. You can track it here: feat: enable `Bytes` logging in contracts · Issue #901 · FuelLabs/fuels-rs · GitHub