/*
Copyright IBM Corp. All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

syntax = "proto3";

option go_package = "github.com/hyperledger/fabric/protos/peer";
option java_package = "org.hyperledger.fabric.protos.peer";
option java_outer_classname = "TransactionPackage";

package protos;

import "google/protobuf/timestamp.proto";
import "peer/proposal_response.proto";
import "common/common.proto";

// This message is necessary to facilitate the verification of the signature
// (in the signature field) over the bytes of the transaction (in the
// transactionBytes field).
message SignedTransaction {

	// The bytes of the Transaction. NDD
	bytes transaction_bytes = 1;

	// Signature of the transactionBytes The public key of the signature is in
	// the header field of TransactionAction There might be multiple
	// TransactionAction, so multiple headers, but there should be same
	// transactor identity (cert) in all headers
	bytes signature = 2;
}

// ProcessedTransaction wraps an Envelope that includes a transaction along with an indication
// of whether the transaction was validated or invalidated by committing peer.
// The use case is that GetTransactionByID API needs to retrieve the transaction Envelope
// from block storage, and return it to a client, and indicate whether the transaction
// was validated or invalidated by committing peer. So that the originally submitted
// transaction Envelope is not modified, the ProcessedTransaction wrapper is returned.
message ProcessedTransaction {
    // An Envelope which includes a processed transaction
    common.Envelope transactionEnvelope = 1;

    // An indication of whether the transaction was validated or invalidated by committing peer
    int32 validationCode = 2;
}

// The transaction to be sent to the ordering service. A transaction contains
// one or more TransactionAction. Each TransactionAction binds a proposal to
// potentially multiple actions. The transaction is atomic meaning that either
// all actions in the transaction will be committed or none will.  Note that
// while a Transaction might include more than one Header, the Header.creator
// field must be the same in each.
// A single client is free to issue a number of independent Proposal, each with
// their header (Header) and request payload (ChaincodeProposalPayload).  Each
// proposal is independently endorsed generating an action
// (ProposalResponsePayload) with one signature per Endorser. Any number of
// independent proposals (and their action) might be included in a transaction
// to ensure that they are treated atomically.
message Transaction {

	// The payload is an array of TransactionAction. An array is necessary to
	// accommodate multiple actions per transaction
	repeated TransactionAction actions = 1;
}

// TransactionAction binds a proposal to its action.  The type field in the
// header dictates the type of action to be applied to the ledger.
message TransactionAction {

	// The header of the proposal action, which is the proposal header
	bytes header = 1;

	// The payload of the action as defined by the type in the header For
	// chaincode, it's the bytes of ChaincodeActionPayload
	bytes payload = 2;
}

//---------- Chaincode Transaction ------------

// ChaincodeActionPayload is the message to be used for the TransactionAction's
// payload when the Header's type is set to CHAINCODE.  It carries the
// chaincodeProposalPayload and an endorsed action to apply to the ledger.
message ChaincodeActionPayload {

	// This field contains the bytes of the ChaincodeProposalPayload message from
	// the original invocation (essentially the arguments) after the application
	// of the visibility function. The main visibility modes are "full" (the
	// entire ChaincodeProposalPayload message is included here), "hash" (only
	// the hash of the ChaincodeProposalPayload message is included) or
	// "nothing".  This field will be used to check the consistency of
	// ProposalResponsePayload.proposalHash.  For the CHAINCODE type,
	// ProposalResponsePayload.proposalHash is supposed to be H(ProposalHeader ||
	// f(ChaincodeProposalPayload)) where f is the visibility function.
	bytes chaincode_proposal_payload = 1;

	// The list of actions to apply to the ledger
	ChaincodeEndorsedAction action = 2;
}

// ChaincodeEndorsedAction carries information about the endorsement of a
// specific proposal
message ChaincodeEndorsedAction {

	// This is the bytes of the ProposalResponsePayload message signed by the
	// endorsers.  Recall that for the CHAINCODE type, the
	// ProposalResponsePayload's extenstion field carries a ChaincodeAction
	bytes proposal_response_payload = 1;

	// The endorsement of the proposal, basically the endorser's signature over
	// proposalResponsePayload
	repeated Endorsement endorsements = 2;
}

enum TxValidationCode {
	VALID = 0;
	NIL_ENVELOPE = 1;
	BAD_PAYLOAD = 2;
	BAD_COMMON_HEADER = 3;
	BAD_CREATOR_SIGNATURE = 4;
	INVALID_ENDORSER_TRANSACTION = 5;
	INVALID_CONFIG_TRANSACTION = 6;
	UNSUPPORTED_TX_PAYLOAD = 7;
	BAD_PROPOSAL_TXID = 8;
	DUPLICATE_TXID = 9;
	ENDORSEMENT_POLICY_FAILURE = 10;
	MVCC_READ_CONFLICT = 11;
	PHANTOM_READ_CONFLICT = 12;
	UNKNOWN_TX_TYPE = 13;
	TARGET_CHAIN_NOT_FOUND = 14;
	MARSHAL_TX_ERROR = 15;
	NIL_TXACTION = 16;
	EXPIRED_CHAINCODE = 17;
	CHAINCODE_VERSION_CONFLICT = 18;
	BAD_HEADER_EXTENSION = 19;
	BAD_CHANNEL_HEADER = 20;
	BAD_RESPONSE_PAYLOAD = 21;
	BAD_RWSET = 22;
	ILLEGAL_WRITESET = 23;
	INVALID_WRITESET = 24;
	NOT_VALIDATED = 254;
	INVALID_OTHER_REASON = 255;
}

// Reserved entries in the key-level metadata map
enum MetaDataKeys {
	VALIDATION_PARAMETER = 0;
}
