diff --git a/CHANGELOG.md b/CHANGELOG.md index 52c4ac070..1275687f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ - [BREAKING] Renamed `SubmitProvenBatch` RPC endpoint to `SubmitProvenTxBatch` ([#2094](https://github.com/0xMiden/node/pull/2094)). - Fixed block producer mempool panic when selecting transactions that depend on notes created by pruned committed transactions ([#2097](https://github.com/0xMiden/node/pull/2097)). - Implemented filtering based on the network account note script root allowlist in ntx-builder ([#2042](https://github.com/0xMiden/node/issues/2042)). +- Documented FPI support and diagnostics for network-account notes that call public foreign accounts ([#2046](https://github.com/0xMiden/node/issues/2046)). - [BREAKING] Renamed `ExplorerStatusDetails` fields in the network monitor's `/status` payload from `number_of_*` to `total_*` (`total_transactions`, `total_nullifiers`, `total_notes`, `total_account_updates`). The values now represent network-wide cumulative totals from the explorer's `overviewStats` query instead of last-block counts. - [BREAKING] Removed `--wallet-filepath` / `--counter-filepath` flags and the `MIDEN_MONITOR_WALLET_FILEPATH` / `MIDEN_MONITOR_COUNTER_FILEPATH` env vars from the network monitor. The monitor now keeps wallet and counter accounts fully in memory and regenerates them on every startup; the dashboard's counter value resets to zero on restart. diff --git a/bin/ntx-builder/src/actor/execute.rs b/bin/ntx-builder/src/actor/execute.rs index 69bc22013..c83a08b97 100644 --- a/bin/ntx-builder/src/actor/execute.rs +++ b/bin/ntx-builder/src/actor/execute.rs @@ -608,7 +608,8 @@ impl DataStore for NtxDataStore { async move { debug_assert_eq!(ref_block, self.reference_block.block_num()); - // Get foreign account inputs from store, retrying on transient gRPC failures. + // Network-note FPI resolves public foreign accounts from the store at the transaction's + // reference block. The account code is loaded below so the executor can call it. let account_inputs = (|| async { self.store.get_account_inputs(foreign_account_id, ref_block).await }) .retry(self.store_backoff()) diff --git a/bin/ntx-builder/src/clients/store.rs b/bin/ntx-builder/src/clients/store.rs index c901fc69a..7e609ccbf 100644 --- a/bin/ntx-builder/src/clients/store.rs +++ b/bin/ntx-builder/src/clients/store.rs @@ -163,7 +163,7 @@ impl StoreClient { account_id: AccountId, block_num: BlockNumber, ) -> Result { - // Construct proto request. + // Request the public foreign account data needed for FPI at the execution reference block. let proto_request = proto::rpc::AccountRequest { account_id: Some(proto::account::AccountId { id: account_id.to_bytes() }), block_num: Some(block_num.into()), diff --git a/docs/external/src/operator/architecture.md b/docs/external/src/operator/architecture.md index de7b3690a..2b5843bd5 100644 --- a/docs/external/src/operator/architecture.md +++ b/docs/external/src/operator/architecture.md @@ -75,6 +75,24 @@ The builder also exposes an internal gRPC server that the RPC component uses to `GetNetworkNoteStatus`. In bundled mode this is wired automatically; in distributed mode operators must set `--ntx-builder.url` (or `MIDEN_NODE_NTX_BUILDER_URL`) on the RPC component. +### Foreign account calls from network notes + +Network-account notes may use Foreign Procedure Invocation (FPI) to call procedures from another public account while +the network transaction builder executes the note. When execution requests a foreign account, the builder asks the store +for that account at the same reference block used for the network transaction, loads the foreign account code into the +transaction executor, and passes the resulting transaction inputs to the validator. The validator then reloads the same +foreign account code from the transaction inputs while re-executing the proven transaction. + +Application developers do not import the foreign account directly when submitting a network note. Instead, they must +ensure that the FPI target is a public account whose code and header are available from the store at execution time. This +is the supported path for registry or AMM-style flows where a network account validates code or state commitments from +another public account. + +If the foreign account is private, missing, not yet visible at the reference block, or otherwise unavailable from the +store, network note execution fails and is retried according to the builder's retry policy. The latest failure is exposed +through `GetNetworkNoteStatus.last_error`, and the note is eventually discarded once the configured attempt limit is +reached. + ## Validator The validator is responsible for verifying the integrity of the blockchain by signing new blocks before they can be committed. diff --git a/docs/external/src/rpc.md b/docs/external/src/rpc.md index c530bd96f..29e958ae1 100644 --- a/docs/external/src/rpc.md +++ b/docs/external/src/rpc.md @@ -95,6 +95,11 @@ Returns the current lifecycle status of a network note. The status indicates whe This endpoint is only available when the network transaction builder is enabled and connected. If it is not configured, the endpoint returns `UNAVAILABLE`. +For network notes that perform FPI into another account, `last_error` is the first place to check when the foreign +account cannot be loaded. A missing, private, or not-yet-visible foreign account causes execution to fail in the network +transaction builder. The note remains pending while retries are available, and the same failure is returned in +`last_error` until a later attempt succeeds or the note is discarded. + #### Request ```protobuf