syntax = "proto3";
package requests;

import "account.proto";
import "digest.proto";

// Applies changes of a new block to the DB and in-memory data structures.
message ApplyBlockRequest {
    // Block data encoded using [winter_utils::Serializable] implementation for
    // [miden_objects::block::Block].
    bytes block = 1;
}

// Returns a list of nullifiers that match the specified prefixes and are recorded in the node.
message CheckNullifiersByPrefixRequest {
    // Number of bits used for nullifier prefix. Currently the only supported value is 16.
    uint32 prefix_len = 1;
    // List of nullifiers to check. Each nullifier is specified by its prefix with length equal
    // to `prefix_len`.
    repeated uint32 nullifiers = 2;
    // Block number from which the nullifiers are requested (inclusive).
    fixed32 block_num = 3;
}

// Returns a nullifier proof for each of the requested nullifiers.
message CheckNullifiersRequest {
    // List of nullifiers to return proofs for.
    repeated digest.Digest nullifiers = 1;
}

// Returns the block header corresponding to the requested block number, as well as the merkle
// path and current forest which validate the block's inclusion in the chain.
//
// The Merkle path is an MMR proof for the block's leaf, based on the current chain length.
message GetBlockHeaderByNumberRequest {
    // The target block height, defaults to latest if not provided.
    optional uint32 block_num = 1;
    // Whether or not to return authentication data for the block header.
    optional bool include_mmr_proof = 2;
}

// State synchronization request.
//
// Specifies state updates the client is interested in. The server will return the first block which
// contains a note matching `note_tags` or the chain tip. And the corresponding updates to
// `account_ids` for that block range.
message SyncStateRequest {
    // Last block known by the client. The response will contain data starting from the next block,
    // until the first block which contains a note of matching the requested tag, or the chain tip
    // if there are no notes.
    fixed32 block_num = 1;

    // Accounts' commitment to include in the response.
    //
    // An account commitment will be included if-and-only-if it is the latest update. Meaning it is
    // possible there was an update to the account for the given range, but if it is not the latest,
    // it won't be included in the response.
    repeated account.AccountId account_ids = 2;

    // Specifies the tags which the client is interested in.
    repeated fixed32 note_tags = 3;
}

// Note synchronization request.
//
// Specifies note tags that client is interested in. The server will return the first block which
// contains a note matching `note_tags` or the chain tip.
message SyncNoteRequest {
    // Last block known by the client. The response will contain data starting from the next block,
    // until the first block which contains a note of matching the requested tag.
    fixed32 block_num = 1;

    // Specifies the tags which the client is interested in.
    repeated fixed32 note_tags = 2;
}

// Returns data required to prove the next block.
message GetBlockInputsRequest {
    // IDs of all accounts updated in the proposed block for which to retrieve account witnesses.
    repeated account.AccountId account_ids = 1;

    // Nullifiers of all notes consumed by the block for which to retrieve witnesses.
    //
    // Due to note erasure it will generally not be possible to know the exact set of nullifiers
    // a block will create, unless we pre-execute note erasure. So in practice, this set of
    // nullifiers will be the set of nullifiers of all proven batches in the block, which is a
    // superset of the nullifiers the block may create.
    //
    // However, if it is known that a certain note will be erased, it would not be necessary to
    // provide a nullifier witness for it.
    repeated digest.Digest nullifiers = 2;

    // Array of note IDs for which to retrieve note inclusion proofs, **if they exist in the store**.
    repeated digest.Digest unauthenticated_notes = 3;

    // Array of block numbers referenced by all batches in the block.
    repeated fixed32 reference_blocks = 4;
}

// Returns the inputs for a transaction batch.
message GetBatchInputsRequest {
  // List of unauthenticated notes to be queried from the database.
  repeated digest.Digest note_ids = 1;
  // Set of block numbers referenced by transactions.
  repeated fixed32 reference_blocks = 2;
}

// Returns data required to validate a new transaction.
message GetTransactionInputsRequest {
    // ID of the account against which a transaction is executed.
    account.AccountId account_id = 1;
    // Set of nullifiers consumed by this transaction.
    repeated digest.Digest nullifiers = 2;
    // Set of unauthenticated notes to check for existence on-chain.
    //
    // These are notes which were not on-chain at the state the transaction was proven,
    // but could by now be present.
    repeated digest.Digest unauthenticated_notes = 3;
}

// Submits proven transaction to the Miden network.
message SubmitProvenTransactionRequest {
    // Transaction encoded using [winter_utils::Serializable] implementation for
    // [miden_objects::transaction::proven_tx::ProvenTransaction].
    bytes transaction = 1;
}

// Returns a list of notes matching the provided note IDs.
message GetNotesByIdRequest {
    // List of notes to be queried from the database.
    repeated digest.Digest note_ids = 1;
}

// Returns the latest state of an account with the specified ID.
message GetAccountDetailsRequest {
    // Account ID to get details.
    account.AccountId account_id = 1;
}

// Retrieves block data by given block number.
message GetBlockByNumberRequest {
    // The block number of the target block.
    fixed32 block_num = 1;
}

// Returns delta of the account states in the range from `from_block_num` (exclusive) to
// `to_block_num` (inclusive).
message GetAccountStateDeltaRequest {
    // ID of the account for which the delta is requested.
    account.AccountId account_id = 1;
    // Block number from which the delta is requested (exclusive).
    fixed32 from_block_num = 2;
    // Block number up to which the delta is requested (inclusive).
    fixed32 to_block_num = 3;
}

// Returns the latest state proofs of the specified accounts.
message GetAccountProofsRequest {
    // Represents per-account requests where each account ID has its own list of
    // (storage_slot_index, map_keys) pairs.
    message AccountRequest {
        // The account ID for this request.
        account.AccountId account_id = 1;

        // List of storage requests for this account.
        repeated StorageRequest storage_requests = 2;
    }

    // Represents a storage slot index and the associated map keys.
    message StorageRequest {
        // Storage slot index ([0..255])
        uint32 storage_slot_index = 1;

        // A list of map keys (Digests) associated with this storage slot.
        repeated digest.Digest map_keys = 2;
    }

    // A list of account requests, including map keys + values.
    repeated AccountRequest account_requests = 1;

    // Optional flag to include account headers and account code in the response. If false, storage
    // requests are also ignored. False by default.
    optional bool include_headers = 2;

    // Account code commitments corresponding to the last-known `AccountCode` for requested
    // accounts. Responses will include only the ones that are not known to the caller.
    // These are not associated with a specific account but rather, they will be matched against
    // all requested accounts.
    repeated digest.Digest code_commitments = 3;
}
