Skip to content

Commit 437b494

Browse files
authored
feat: support bool types on schemas (#2591)
1 parent cc719f6 commit 437b494

File tree

4 files changed

+59
-3
lines changed

4 files changed

+59
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
- Added `MockChain::add_pending_batch()` to allow submitting user batches directly ([#2565](https://github.com/0xMiden/protocol/pull/2565)).
3434
- Added `create_fungible_key` for construction of fungible asset keys ([#2575](https://github.com/0xMiden/protocol/pull/2575)).
3535
- Added `InputNoteCommitment::from_parts()` for construction of input note commitments from a nullifier and optional note header ([#2588](https://github.com/0xMiden/protocol/pull/2588)).
36+
- Added `bool` schema type to the type registry and updated ACL auth component to use it for boolean config fields ([#2591](https://github.com/0xMiden/protocol/pull/2591)).
3637

3738
### Changes
3839

crates/miden-protocol/src/account/component/storage/schema/felt.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ impl FeltSchema {
9393
Self::new_typed(SchemaType::u32(), name)
9494
}
9595

96+
/// Creates a new required felt field typed as [`SchemaType::bool()`].
97+
pub fn bool(name: impl Into<String>) -> Self {
98+
Self::new_typed(SchemaType::bool(), name)
99+
}
100+
96101
/// Sets the default value of the [`FeltSchema`] and returns `self`.
97102
pub fn with_default(self, default_value: Felt) -> Self {
98103
FeltSchema {

crates/miden-protocol/src/account/component/storage/type_registry.rs

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub static SCHEMA_TYPE_REGISTRY: LazyLock<SchemaTypeRegistry> = LazyLock::new(||
2929
registry.register_felt_type::<u8>();
3030
registry.register_felt_type::<u16>();
3131
registry.register_felt_type::<u32>();
32+
registry.register_felt_type::<Bool>();
3233
registry.register_felt_type::<Felt>();
3334
registry.register_felt_type::<TokenSymbol>();
3435
registry.register_felt_type::<AuthScheme>();
@@ -163,6 +164,11 @@ impl SchemaType {
163164
SchemaType::new("u32").expect("type is well formed")
164165
}
165166

167+
/// Returns the schema type for the native `bool` type.
168+
pub fn bool() -> SchemaType {
169+
SchemaType::new("bool").expect("type is well formed")
170+
}
171+
166172
/// Returns the schema type for auth scheme identifiers.
167173
pub fn auth_scheme() -> SchemaType {
168174
SchemaType::new("miden::standards::auth::scheme").expect("type is well formed")
@@ -291,6 +297,35 @@ where
291297
// FELT IMPLS FOR NATIVE TYPES
292298
// ================================================================================================
293299

300+
/// A boolean felt type: `0` (false) or `1` (true).
301+
struct Bool;
302+
303+
impl FeltType for Bool {
304+
fn type_name() -> SchemaType {
305+
SchemaType::bool()
306+
}
307+
308+
fn parse_str(input: &str) -> Result<Felt, SchemaTypeError> {
309+
match input {
310+
"true" | "1" => Ok(Felt::new(1)),
311+
"false" | "0" => Ok(Felt::new(0)),
312+
_ => Err(SchemaTypeError::ConversionError(format!(
313+
"invalid bool value `{input}`: expected `true`, `false`, `1`, or `0`"
314+
))),
315+
}
316+
}
317+
318+
fn display_felt(value: Felt) -> Result<String, SchemaTypeError> {
319+
match value.as_canonical_u64() {
320+
0 => Ok("false".into()),
321+
1 => Ok("true".into()),
322+
other => Err(SchemaTypeError::ConversionError(format!(
323+
"value `{other}` is not a valid bool (expected 0 or 1)"
324+
))),
325+
}
326+
}
327+
}
328+
294329
/// A felt type that represents irrelevant elements in a storage schema definition.
295330
struct Void;
296331

@@ -761,7 +796,8 @@ mod tests {
761796
}
762797

763798
#[test]
764-
fn auth_scheme_type_rejects_invalid_values() {
799+
fn schema_types_reject_invalid_values() {
800+
// Auth scheme rejects out-of-range and unknown values.
765801
let auth_scheme_type = SchemaType::auth_scheme();
766802

767803
assert!(SCHEMA_TYPE_REGISTRY.try_parse_word(&auth_scheme_type, "9").is_err());
@@ -773,5 +809,19 @@ mod tests {
773809
.validate_word_value(&auth_scheme_type, invalid_word)
774810
.is_err()
775811
);
812+
813+
// Bool type parses "true"/"false"/"1"/"0" and rejects everything else.
814+
let bool_type = SchemaType::bool();
815+
816+
assert_eq!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "true").unwrap(), Felt::new(1));
817+
assert_eq!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "false").unwrap(), Felt::new(0));
818+
assert_eq!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "1").unwrap(), Felt::new(1));
819+
assert_eq!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "0").unwrap(), Felt::new(0));
820+
assert_eq!(SCHEMA_TYPE_REGISTRY.display_felt(&bool_type, Felt::new(0)), "false");
821+
assert_eq!(SCHEMA_TYPE_REGISTRY.display_felt(&bool_type, Felt::new(1)), "true");
822+
823+
assert!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "yes").is_err());
824+
assert!(SCHEMA_TYPE_REGISTRY.try_parse_felt(&bool_type, "2").is_err());
825+
assert!(SCHEMA_TYPE_REGISTRY.validate_felt_value(&bool_type, Felt::new(2)).is_err());
776826
}
777827
}

crates/miden-standards/src/account/auth/singlesig_acl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ impl AuthSingleSigAcl {
214214
"ACL configuration",
215215
[
216216
FeltSchema::u32("num_trigger_procs").with_default(Felt::new(0)),
217-
FeltSchema::u32("allow_unauthorized_output_notes").with_default(Felt::new(0)),
218-
FeltSchema::u32("allow_unauthorized_input_notes").with_default(Felt::new(0)),
217+
FeltSchema::bool("allow_unauthorized_output_notes").with_default(Felt::new(0)),
218+
FeltSchema::bool("allow_unauthorized_input_notes").with_default(Felt::new(0)),
219219
FeltSchema::new_void(),
220220
],
221221
),

0 commit comments

Comments
 (0)