/**
 * # PlatformState
 * Messages that hold platform state in the network state.
 *
 * The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
 * "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
 * document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119)
 * and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174).
 */
syntax = "proto3";

package com.hedera.hapi.platform.state;

// SPDX-License-Identifier: Apache-2.0
option java_package = "com.hedera.hapi.platform.state.legacy";
// <<<pbj.java_package = "com.hedera.hapi.platform.state">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

import "services_basic_types.proto";
import "services_timestamp.proto";

/**
 * The current state of platform consensus.<br/>
 * This message stores the current consensus data for the platform
 * in network state.
 *
 * The platform state SHALL represent the latest round's consensus.<br/>
 * This data SHALL be used to ensure consistency and provide critical data for
 * restart and reconnect.
 */
message PlatformState {

    /**
     * A version describing the current version of application software.
     * <p>
     * This SHALL be the software version that created this state.
     */
    proto.SemanticVersion creation_software_version = 1;

    /**
     * A number of non-ancient rounds.
     * <p>
     * This SHALL be the count of rounds considered non-ancient.
     */
    uint32 rounds_non_ancient = 2;

    /**
     * A snapshot of the consensus state at the end of the round.
     * <p>
     * This SHALL be used for restart/reconnect.
     */
    ConsensusSnapshot consensus_snapshot = 3;

    /**
     * A timestamp for the next scheduled time when a freeze will start.
     * <p>
     * If a freeze is not scheduled, this SHALL NOT be set.<br/>
     * If a freeze is currently scheduled, this MUST be set, and MUST
     * match the timestamp requested for that freeze.
     */
    proto.Timestamp freeze_time = 4;

    /**
     * A timestamp for the last time a freeze was performed.<br/>
     * If not set, there has never been a freeze.
     */
    proto.Timestamp last_frozen_time = 5;

    /**
     * The number of the latest round that was a freeze round. If this round
     * is a freeze round, then the value is the same as the current round. It
     * is set after executing all transactions in this round. <br/>
     * If there has never been a freeze round, this SHALL be zero.<br/>
     */
    uint64 latest_freeze_round = 6;

    // Fields below are to be deprecated in the foreseeable future.

    /**
     * A running event hash.<br/>
     * This is computed by the consensus event stream.
     * <p>
     * This will be _removed_ and the field number reserved once the consensus
     * event stream is retired.
     */
     bytes legacy_running_event_hash = 10000 [deprecated = true];

    /**
     * Previously used to indicate the lowest judge generation before birth round mode was enabled.
     */
    reserved 10001;

    /**
     * Previously used to indicate the last round before the birth round mode was enabled.
     */
    reserved 10002;

    /**
     * Previously used to indicate the software version that enabled birth round mode.
     */
    reserved 10003;

    reserved 10004;
    reserved "address_book";

    reserved 10005;
    reserved "previous_address_book";
}


/**
 * A consensus snapshot.<br/>
 * This is a snapshot of the consensus state for a particular round.
 *
 * This message SHALL record consensus data necessary for restart
 * and reconnect.
 */
message ConsensusSnapshot {
    /**
     * A consensus round.<br/>
     * The round number of this snapshot.
     */
    uint64 round = 1;
    /**
     * Previously used to be judge hashes, replaced by judge ids which contain creator node ID and judge hash.<br/>
     */
    reserved 2;

    /**
     * A list of minimum judge information entries.<br/>
     * These are "minimum ancient" entries for non-ancient rounds.
     */
    repeated MinimumJudgeInfo minimum_judge_info_list = 3;

    /**
     * A single consensus number.<br/>
     * The consensus order of the next event to reach consensus.
     */
    uint64 next_consensus_number = 4;

    /**
     * A "consensus" timestamp.<br/>
     * The consensus timestamp of this snapshot.
     * <p>
     * Depending on the context this timestamp may have different meanings:
     * <ul>
     * <li>if there are transactions, the timestamp is equal to the timestamp of the last transaction</li>
     * <li>if there are no transactions, the timestamp is equal to the timestamp of the last event</li>
     * <li>if there are no events, the timestamp is equal to the timestamp of the previous round plus a small constant</li>
     * </ul>
     * <p>
     * This SHALL be a consensus value and MAY NOT correspond to an actual
     * "wall clock" timestamp.<br/>
     * Consensus Timestamps SHALL always increase.
     */
    proto.Timestamp consensus_timestamp = 5;

    /*
     * A list of judge creator ids and its hashes in a round.<br/>
     */
    repeated JudgeId judge_ids = 6;
}

/**
 * A judge information that includes the creator node ID and the
 * SHA-384 hash value of the judge.
 */
message JudgeId {
    /**
     * The creator node ID who created this judge.
     */
    uint64 creator_id = 1;

    /**
     * SHA-384 hash value of this judge
     */
    bytes judge_hash = 2;
}

/**
 * Records the minimum ancient indicator for all judges in a particular round.
 */
message MinimumJudgeInfo {
    /**
     * A consensus round.<br/>
     * The round this judge information applies to.
     */
    uint64 round = 1;

    /**
     * This is a minimum birth round for all judges for a given round.
     * <p>
     * This SHALL reflect the relevant minimum birth round
     */
    uint64 minimum_judge_birth_round = 2;
}

/**
 * A consensus node identifier.<br/>
 * This value uniquely identifies a single consensus node within the network.
 */
message NodeId {
  /**
   * A numeric identifier.
   */
  uint64 id = 1;
}
