Skip to content

Network account component for detection and note script enforcement #2285

@PhilippGackstatter

Description

@PhilippGackstatter

One way to make network accounts more secure is by letting them specify a set of note script roots that they are willing to consume. Any other note script would be rejected. This can be defined as an account auth component, i.e. it has an auth procedure that enforces that only the configured set of note scripts is consumed.

Somewhat related, think we should remove AccountStorageMode::Network and instead define a network account by whether it has a NetworkAccount component or not. This simplifies the protocol by not having to deal with any network account related things.

Based on this, I can think of two ways to go about this:

  • Create only a dummy NetworkAccount component for network account identification that occupies a single storage slot, conceptually containing just a bool flag is_network_account = true. This would not have to be an auth component. The main advantage is that network account creators have the full flexibility of defining their own auth procedure.
    • The actual enforcement for note script roots would be one additional account auth component, say NetworkAccountNoteScriptsAuth. In this approach, to create a network account with note script enforcement, add the NetworkAccount and NetworkAccountNoteScriptsAuth components to the account in the AccountBuilder.
  • Enforce note script roots in NetworkAccount and also use it for network account detection (specifically by checking for the presence of a named storage slot). Since auth procedures of network accounts will surely have to be customized, we would likely need "auth templating" (Templating of auth procedures #1956), here which conceptually means making it extensible as NetworkAccount<MyCustomAuth>. We'd then have the option of enabling or disabling the note script root check, so users can also fully customize the account authentication, if desired.

I think most network accounts will want to consume only a specific set of notes, and so the second option, making this check part of NetworkAccount seems reasonable to me. However, the downside of templating is that we may not be able to reconstruct the NetworkAccount component in Rust from an AccountInterface, and while I'm not sure if this is needed, I would prefer keeping this separate. If we end up having other network account configuration parameters, then the NetworkAccount component would become more useful as well. So while I think both options are fine, I'd probably go with option 1.

Since I already sketched it, here is the second option.
pub struct NetworkAccount<AUTH: Into<AccountComponent>> {
    auth_extension: AUTH,
    notes: NetworkAccountNotes,
}

pub enum NetworkAccountNotes {
    AllowAll,
    // Maybe this should be a stronger type than Word.
    Allow(BTreeSet<Word>),
}

// Usage could be:
fn create_network_account() -> Account {
    // Network account that can consume P2ID and SWAP notes and has no custom auth extension.
    let notes = NetworkAccountNotes::Allow(
        [WellKnownNote::P2ID.script().root(), WellKnownNote::SWAP.script().root()].into(),
    );
    let network_account_component = NetworkAccount::<()>::new(notes);
    AccountBuilder::new([0; 32])
        .with_auth_component(network_account_component)
        .with_component(BasicWallet)
        .build()
        .expect("TODO")
}

In the auth procedure, it enforces that all note script roots of input notes are in the map:

const NOTE_SCRIPT_ROOTS_SLOT = word("miden::standards::network_account::note_script_roots")

pub proc auth_network_account(auth_args: BeWord)
    # pseudo logic
    for note_idx in 0..miden::protocol::tx::get_num_input_notes {
        let script_root = miden::protocol::input_note::get_script_root(note_idx);
        let map_value = miden::protocol::account::get_map_item(
          NOTE_SCRIPT_ROOTS_SLOT.slot_id(),
          script_root,
        );
        if map_value[3] == Felt::ZERO {
            panic!("disallowed note script root")
        }
    }
end

Some Context: #2219 (comment)

cc @Mirko-von-Leipzig @sergerad

Metadata

Metadata

Assignees

No one assigned

    Labels

    standardsRelated to standard note scripts or account components

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions