/*
Copyright IBM Corp. 2016 All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

		 http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

syntax = "proto3";

import "../common/common.proto";
import "../google/protobuf/timestamp.proto";
import "chaincode_event.proto";
import "transaction.proto";

option java_package = "org.hyperledger.fabric.protos.peer";
option java_outer_classname = "EventsPackage";
option go_package = "github.com/hyperledger/fabric/protos/peer";

package protos;

//----Event objects----

enum EventType {
    REGISTER = 0;
    BLOCK = 1;
    CHAINCODE = 2;
    REJECTION = 3;
    FILTEREDBLOCK = 4;
}

//ChaincodeReg is used for registering chaincode Interests
//when EventType is CHAINCODE
message ChaincodeReg {
    string chaincode_id = 1;
    string event_name = 2;
}

message Interest {
    EventType event_type = 1;
    //Ideally we should just have the following oneof for different
    //Reg types and get rid of EventType. But this is an API change
    //Additional Reg types may add messages specific to their type
    //to the oneof.
    oneof RegInfo {
        ChaincodeReg chaincode_reg_info = 2;
    }
    string chainID = 3;
}

//---------- consumer events ---------
//Register is sent by consumers for registering events
//string type - "register"
message Register {
    repeated Interest events = 1;
}

//Rejection is sent by consumers for erroneous transaction rejection events
//string type - "rejection"
message Rejection {
    Transaction tx = 1;
    string error_msg = 2;
}

//---------- producer events ---------
message Unregister {
    repeated Interest events = 1;
}

//FilteredBlock is sent by producers and contains minimal information
//about the block.
message FilteredBlock {
    string channel_id = 1;
    uint64 number = 2; // The position in the blockchain
    repeated FilteredTransaction filtered_tx = 4;
}

// FilteredTransaction is a minimal set of information about a transaction
// within a block.
message FilteredTransaction {
    string txid = 1;
    common.HeaderType type = 2;
    TxValidationCode tx_validation_code = 3;
    oneof Data {
        FilteredTransactionActions transaction_actions = 4;
    }
}

// FilteredTransactionActions is a wrapper for array of TransactionAction
// message from regular block
message FilteredTransactionActions {
    repeated FilteredChaincodeAction chaincode_actions = 1;
}

//FilteredChaincodeAction is a minimal set of information about an action within a
//transaction.
message FilteredChaincodeAction {
    ChaincodeEvent ccEvent = 1;
}

// SignedEvent is used for any communication between consumer and producer
message SignedEvent {
    // Signature over the event bytes
    bytes signature = 1;
    // Marshal of Event object
    bytes eventBytes = 2;
}

//Event is used by
//  - consumers (adapters) to send Register
//  - producer to advertise supported types and events
message Event {
    oneof Event {
        //Register consumer sent event
        Register register = 1;

        //producer events
        common.Block block = 2;
        ChaincodeEvent chaincode_event = 3;
        Rejection rejection = 4;

        //Unregister consumer sent events
        Unregister unregister = 5;

        FilteredBlock filtered_block = 7;
    }
    // Creator of the event, specified as a certificate chain
    bytes creator = 6;
    // Timestamp of the client - used to mitigate replay attacks
    google.protobuf.Timestamp timestamp = 8;

    // If mutual TLS is employed, this represents
    // the hash of the client's TLS certificate
    bytes tls_cert_hash = 9;
}

// Interface exported by the events server
service Events {
    // event chatting using Event
    rpc Chat (stream SignedEvent) returns (stream Event) {
    }
}

// DeliverResponse
message DeliverResponse {
    oneof Type {
        common.Status status = 1;
        common.Block block = 2;
        FilteredBlock filtered_block = 3;
    }
}

service Deliver {
    // deliver first requires an Envelope of type ab.DELIVER_SEEK_INFO with Payload data as a marshaled orderer.SeekInfo message,
    // then a stream of block replies is received.
    rpc Deliver (stream common.Envelope) returns (stream DeliverResponse) {
    }
    // deliver first requires an Envelope of type ab.DELIVER_SEEK_INFO with Payload data as a marshaled orderer.SeekInfo message,
    // then a stream of **filtered** block replies is received.
    rpc DeliverFiltered (stream common.Envelope) returns (stream DeliverResponse) {
    }
}
