Skip to content

feat: add .contractaddr to contract class log#12197

Merged
MirandaWood merged 3 commits intomw/cc-logs-pos-hashfrom
mw/cc-logs-pos-hash-addr
Feb 24, 2025
Merged

feat: add .contractaddr to contract class log#12197
MirandaWood merged 3 commits intomw/cc-logs-pos-hashfrom
mw/cc-logs-pos-hash-addr

Conversation

@MirandaWood
Copy link
Contributor

Tracking an address alongside the cc log to aid filters in the archiver. The address is always constrained to be that of the registerer, but many archiver tests use random addresses so they brick without ugly hacks

Copy link
Contributor

@iAmMichaelConnor iAmMichaelConnor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflecting, I think I can't properly review PRs in this "backwards" order, because the code that it's building upon hasn't been reviewed to be a good "basis", and because once it's merged, this same code will need to be re-reviewed when reviewing the PR that this merges into. So I think if we're going to stack PRs, the review order has to match the order in which the PRs are stacked, with the one closest to master being reviewed first.

So with all that being said, I can either:

  • Wait until the PR closest to master is ready to
    review; or
  • We can just merge this into that big branch and I can review that big PR once it's ready. (And in future we can do it in the proper order).

Sorry for any confusion. I've added some comments, which can be addressed in either this PR or the lower-down PR.

pub global CONTRACT_CLASS_LOG_SIZE_IN_FIELDS: u32 = MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS
pub global CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS: u32 = MAX_PACKED_BYTECODE_SIZE_PER_PRIVATE_FUNCTION_IN_FIELDS
+ REGISTERER_PRIVATE_FUNCTION_BROADCASTED_ADDITIONAL_FIELDS;
pub global CONTRACT_CLASS_LOG_SIZE_IN_FIELDS: u32 = CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS + 1; // This includes the contract address, since it is always emitted with a contract class log
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing the term SCOPED_ in other names in this file. Does "scoped" mean "includes the contract address of the app"? If so, perhaps we can match that naming here? (The reason I suggest this is because I first saw these two names in a different file, and was like "What's the difference between "log size" and "log data size"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was following the existing usage of DATA as we do for public logs. Also (I was a little confused by this) to 'scope' a log is to hash the first element with the address and drop the address, so technically a scoped log would just be CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS.
E.g.

pub struct PublicLog {
    pub log: Log<PUBLIC_LOG_DATA_SIZE_IN_FIELDS>,
    pub contract_address: AztecAddress,
}

But I think I prefer something lke:

pub struct PublicLog {
    pub log: Log<PUBLIC_LOG_SIZE_IN_FIELDS>,
    pub contract_address: AztecAddress,
}

Where the struct is SCOPED_PUBLIC_LOG_SIZE_IN_FIELDS long.

} else {
let mut log = contract_class_log;
log.fields[0] = compute_siloed_contract_class_log_field(contract_address, log.fields[0]);
log.log.fields[0] = compute_siloed_contract_class_log_field(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a private log, we keep field 0 of the log as "special", and we put a tag there, so hashing field 0 doesn't corrupt the main, meaty part of a log.
I'm worried this will corrupt the 0th field of the contract class log. What goes into field 0?
What did we do with the old "unencrypted logs" that we used to emit from private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how we've always done it for the dpeloyer and is required to be able to detect a log came from the protocol contract:

  • The first element of a contract class log is always a magic value corresponding to what we are broadcasting e.g. REGISTERER_UNCONSTRAINED_FUNCTION_BROADCASTED_MAGIC_VALUE or REGISTERER_PRIVATE_FUNCTION_BROADCASTED_MAGIC_VALUE.
  • We then silo that first element here with the address, which for cc logs is just 3.
  • When reading and dealing with broadcated logs, we look for the hash of 3 with some magic value.

Though we do constrain that only the address 3 contract can emit cc logs, I imagine the siloing is an extra layer of security. I can't remember, but I may have added it to match how the deployer contract does it, just to maintain some continuity.

log: ContractClassLog,
log_hash: ScopedLogHash,
) -> ContractClassLog {
// Validate address
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this function called solely by the BaseRollup circuit? If so, perhaps it should live there. (Not necessary this PR).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, will do! I originally had it as something implemented for the cc log (like log.validate(log_hash)), can't remember why I changed it now...

let padded_log_fields: [Field; CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS] =
array_concat(log_fields, [0; CONTRACT_CLASS_LOG_DATA_SIZE_IN_FIELDS - N]);
let log = ContractClassLog {
contract_address: self.tube_data.contract_address,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does tube_data carry a contract_address which happens to match the address of the Contract Class Registerer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all in the tests - tube_data is just a FixtureBuilder that carries around everything you could possibly need at every step of the circuits. We use it for basically all nr tests here to avoid having like 20 different structs for each kernel and rollup circuit.

offset += total_private_logs_len;
// cc logs
let total_contract_class_logs_len = NUM_CC_LOGS * (cc_log.len() + 1);
let total_contract_class_logs_len = NUM_CC_LOGS * (cc_log.len() + 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's +2?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the address - this is just a test and it should be documented everywhere else. I can add it here too though?

offset += total_private_logs_len;
// cc logs
let total_contract_class_logs_len = NUM_CC_LOGS * (cc_log.len() + 1);
let total_contract_class_logs_len = NUM_CC_LOGS * (cc_log.len() + 2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just opened an issue for the pattern in this file #12217

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI I think this behaviour is mostly in tests. We need it for the blob because we don't want to concat arrays, we want to fill an array with certain elements conditionally.

@MirandaWood MirandaWood merged commit c2ebf15 into mw/cc-logs-pos-hash Feb 24, 2025
10 checks passed
@MirandaWood MirandaWood deleted the mw/cc-logs-pos-hash-addr branch February 24, 2025 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants