refactor: enforce component metadata in account component#2373
refactor: enforce component metadata in account component#2373
Conversation
f579a7d to
021d423
Compare
53c8f94 to
7358008
Compare
| storage_schema, | ||
| name: name.into(), | ||
| description: String::new(), | ||
| version: Version::new(0, 1, 0), |
There was a problem hiding this comment.
This may be better suited to be a parameter of AccountComponentMetadata::new instead
There was a problem hiding this comment.
Maybe defaulting to 1.0 would be a better approach? Most components will be shipped as that stable version for the first time so it seems it would be the best default. For V2, V3, ... we can then overwrite explicitly.
Where do we actually display or use this version?
There was a problem hiding this comment.
I changed it to 1.0. I don't think this gets explicitly used other than just being there for metadata purposes right now.
PhilippGackstatter
left a comment
There was a problem hiding this comment.
Looks good to me!
| pub fn new( | ||
| code: impl Into<AccountComponentCode>, | ||
| storage_slots: Vec<StorageSlot>, | ||
| metadata: AccountComponentMetadata, | ||
| ) -> Result<Self, AccountError> { |
There was a problem hiding this comment.
It would be nice if we could enforce that metadata.name matches the library path of the library, e.g. something like:
let code = code.into();
for export in code.as_library().exports() {
let path = export.path();
if !path.as_str().starts_with(metadata.name()) {
todo!("path {} does not start with {}", path.as_str(), metadata.name())
}
}This doesn't work exactly like that (because paths start with ::), but conceptually I think it could. I'm not sure if there's a real downside to enforcing this. I think it could be a nice benefit for DevX to see a component's name be x::y::z and be able to use the same path in code. For example, currently we have things like library_path = ::incr_nonce::auth_incr_nonce and metadata_name = miden::testing::incr_nonce_auth, which don't quite line up and this would enforce consistency.
I think it may make sense to do this after we have changed standard account component paths to be prefixed with miden::standards, e.g. from ::ecdsa_k256_keccak::auth_tx_ecdsa_k256_keccak to something like ::miden::standards::auth::ecdsa_k256_keccak. I have opened #2399 for this. Once we've done that, we could change the component names in one go.
Also, there may be cases where it makes sense for the name to be different, and I just can't think of it, so not really a strong opinion. Just wanted to bring it up.
There was a problem hiding this comment.
Thanks for opening the issue! I think that makes sense
crates/miden-agglayer/src/lib.rs
Outdated
| pub fn agglayer_faucet_component(storage_slots: Vec<StorageSlot>) -> AccountComponent { | ||
| let library = agglayer_faucet_library(); | ||
| let metadata = AccountComponentMetadata::new("agglayer::faucet") | ||
| .with_description("AggLayer faucet component with bridge validation") | ||
| .with_supports_all_types(); |
There was a problem hiding this comment.
Not from this PR, but the agglayer faucet probably shouldn't support regular accounts? Iiuc, it should only support accounts of type fungible faucet.
There was a problem hiding this comment.
I changed this to just be supported on faucets, (ccing @mmagician and @partylikeits1983 as a heads up)
| AccountComponent::new(ecdsa_k256_keccak_acl_library(), storage_slots) | ||
| .expect( | ||
| "ACL auth component should satisfy the requirements of a valid account component", | ||
| let metadata = AccountComponentMetadata::new("miden::auth::ecdsa_k256_keccak_acl") |
There was a problem hiding this comment.
I think it would make sense to make these names constants on their respective types, e.g.:
impl AuthEcdsaK256KeccakAcl {
pub const NAME: &str = "miden::auth::ecdsa_k256_keccak_acl";
}I think we might want to access the name from other contexts as well and this would easily allow for that, e.g. for #2399. It may also be useful when we implement an AccountComponentInterface trait that has a name method. Applies to all standard components.
There was a problem hiding this comment.
Good point as well, changed
| /// Creates a test metadata for account components that supports all account types. | ||
| pub fn test_metadata(name: &str) -> AccountComponentMetadata { |
There was a problem hiding this comment.
Nit: Could this be AccountComponentMetadata::mock instead, defined somewhere in crates/miden-protocol/src/testing/? This would be more consistent with other such mock methods like NoteScript::mock, StorageSlotName::mock, AccountStorage::mock, etc.
There was a problem hiding this comment.
I debated removing this altogether but kept it for now at least
…nto igamigo-enforce-metadata
…ename test consturctor to mock()
|
All comments should be addressed so leaving it up in case @bobbinth wants to take a look |
There was a problem hiding this comment.
nit: in other places we name this just metadata.
bobbinth
left a comment
There was a problem hiding this comment.
Looks good! Thank you! I left a couple of comments above - but we can also do them in a follow-up PR.
| let token_symbol_type = | ||
| SchemaTypeId::new("miden::standards::fungible_faucets::metadata::token_symbol") | ||
| .expect("valid"); | ||
| let storage_schema = StorageSchema::new([( | ||
| BasicFungibleFaucet::metadata_slot().clone(), | ||
| StorageSlotSchema::value( | ||
| "Token metadata", | ||
| [ | ||
| FeltSchema::felt("token_supply").with_default(Felt::new(0)), | ||
| FeltSchema::felt("max_supply"), | ||
| FeltSchema::u8("decimals"), | ||
| FeltSchema::new_typed(token_symbol_type, "symbol"), | ||
| ], | ||
| ), | ||
| )]) | ||
| .expect("storage schema should be valid"); |
There was a problem hiding this comment.
A couple of comments here:
- It may be good to define
miden::standards::fungible_faucets::metadata::token_symbolas a constant at the top of the file. - To improve readability, it may be good to create accessor methods that return the slot schema - something like
BasicFungibleFaucet::metadata_slot_schema(). And then the cod here could look like:
let storage_schema = StorageSchema::new([
BasicFungibleFaucet::metadata_slot_schema(),
])
.expect("storage schema should be valid");| let pub_key_type = | ||
| SchemaTypeId::new("miden::standards::auth::falcon512_rpo::pub_key").expect("valid"); | ||
| let storage_schema = StorageSchema::new([ | ||
| ( | ||
| AuthFalcon512RpoMultisig::threshold_config_slot().clone(), | ||
| StorageSlotSchema::value( | ||
| "Threshold configuration", |
There was a problem hiding this comment.
Same comment as above. And this is also applicable to other standard components.
…nto igamigo-enforce-metadata
b33dbe4 to
d40b962
Compare
bobbinth
left a comment
There was a problem hiding this comment.
All looks good! Thank you!
Closes #2297
This PR:
AccountComponentMetadataa required parameter inAccountComponent::new(), enforcing that all components have metadata (also adds them to the standard components)supported_typesfromAccountComponentstruct - now delegated tometadata.supported_types()AccountComponentMetadata::new()to only require a name, with sensible defaults (empty description, version 0.1.0, empty supported types, empty storage schema); adds mutators for simplicityAccountSchemaCommitment::new()to returnAccountErrorinstead ofAccountComponentTemplateErrorError rename was pushed to a different PR: #2395