syntax = "proto3";
package coop.rchain.casper.protocol;

import "google/protobuf/empty.proto";

// If you are building for other languages "scalapb.proto"
// can be manually obtained here:
// https://raw.githubusercontent.com/scalapb/ScalaPB/master/protobuf/scalapb/scalapb.proto
// make a scalapb directory in this file's location and place it inside

import "scalapb/scalapb.proto";
import "RhoTypes.proto";

option (scalapb.options) = {
  package_name: "coop.rchain.casper.protocol"
  flat_package: true
};

// --------- DeployService  --------
service DeployService {
  rpc DoDeploy(DeployData) returns (DeployServiceResponse) {}
  rpc addBlock(BlockMessage) returns (DeployServiceResponse) {}
  rpc createBlock(google.protobuf.Empty) returns (DeployServiceResponse) {}
  rpc showBlock(BlockQuery) returns (BlockQueryResponse) {}
  rpc showBlocks(google.protobuf.Empty) returns (stream BlockInfo) {}
  rpc listenForDataAtName(Channel) returns (ListeningNameDataResponse) {}
  rpc listenForContinuationAtName(Channels) returns (ListeningNameContinuationResponse) {}
}

message DeployData {
  bytes  user         = 1; //public key
  string term         = 2; //rholang source code to deploy (will be parsed into `Par`)
  int64  timestamp    = 3; //millisecond timestamp
  bytes  sig          = 4; //signature of (hash(term) + timestamp) using private key
  string sigAlgorithm = 5; // name of the algorithm used to sign
  string from         = 6; //wallet address which will be used to pay for the deployment
  int32 phloPrice     = 7; //phlo price
  int32 phloLimit     = 8; //phlo limit for the deployment
  int32 nonce         = 9; //nonce for transaction made against `from` wallet
}

message BlockRequest {
  //Fields are redundant to allow for validity check.
  //Such a check can definitively distinguish this
  //from other message types with similar serializations.
  string base16Hash = 1;
  bytes  hash       = 2;
}

message BlockQuery {
  string hash = 1;
}

message Channels {
  repeated Channel channels = 1;
}

message DeployServiceResponse {
  bool   success = 1;
  string message = 2;
}

message MaybeBlockMessage {
  BlockMessage block = 1;
}

message BlockQueryResponse {
  string status = 1;
  BlockInfo blockInfo = 2;
}

message ListeningNameDataResponse {
  string status = 1;
  repeated DataWithBlockInfo blockResults = 2;
  int32 length = 3;
}

message ListeningNameContinuationResponse {
  string status = 1;
  repeated ContinuationsWithBlockInfo blockResults = 2;
  int32 length = 3;
}

message DataWithBlockInfo {
  repeated Par postBlockData = 1;
  BlockInfoWithoutTuplespace block = 2;
}

message ContinuationsWithBlockInfo {
  repeated WaitingContinuationInfo postBlockContinuations = 1;
  BlockInfoWithoutTuplespace block = 2;
}

message WaitingContinuationInfo {
  repeated BindPattern postBlockPatterns = 1;
  Par postBlockContinuation = 2;
}

message BlocksResponse {
  string status = 1;
  repeated BlockInfo blocks = 2;
  int64 length = 3;
}

message BlockInfoWithoutTuplespace {
  string blockHash = 1;
  string blockSize = 2;
  int64 blockNumber = 3;
  int64 version = 4;
  int32 deployCount = 5;
  string tupleSpaceHash = 6; // Same as postStateHash of BlockMessage
  int64 timestamp = 7;
  float faultTolerance = 8;
  string mainParentHash = 9;
  repeated string parentsHashList = 10;
  string sender = 11;
}

// For node clients, see BlockMessage for actual Casper protocol Block representation
message BlockInfo {
  string blockHash = 1;
  string blockSize = 2;
  int64 blockNumber = 3;
  int64 version = 4;
  int32 deployCount = 5;
  string tupleSpaceHash = 6; // Same as postStateHash of BlockMessage
  string tupleSpaceDump = 7;
  int64 timestamp = 8;
  float faultTolerance = 9;
  string mainParentHash = 10;
  repeated string parentsHashList = 11;
  string sender = 12;
  string shardId = 13;
}

// --------- End DeployService  --------

// ---------- Signing Protocol ---------
message ApprovedBlockCandidate {
  BlockMessage block        = 1;
  int32        requiredSigs = 2;
}

message UnapprovedBlock {
  ApprovedBlockCandidate candidate = 1; 
  int64                  timestamp = 2;
  int64                  duration  = 3;
}

message Signature {
  bytes  publicKey = 1;
  string algorithm = 2;
  bytes  sig       = 3;
}

message BlockApproval {
  ApprovedBlockCandidate candidate = 1; 
  Signature              sig       = 2;
}

message ApprovedBlock  {
  ApprovedBlockCandidate candidate = 1; 
  repeated Signature     sigs      = 2;
}

message ApprovedBlockRequest {
  string identifier = 1;
}

message NoApprovedBlockAvailable {
  string identifier = 1;
  string nodeIdentifer = 2;
}

// ------- End Signing Protocol --------

// --------- Core Protocol  --------
message BlockMessage {
  bytes                  blockHash      = 1; // obtained by hashing the information in the header
  Header                 header         = 2;
  Body                   body           = 3;
  repeated Justification justifications = 4; // map of all validators to latest blocks based on current view
  bytes                  sender         = 5; // public key of the validator that created the block
  int32                  seqNum         = 6; // number of blocks created by the validator
  bytes                  sig            = 7; // signature generated by signing `hash(hash(justification) concat blockHash)`.
  string                 sigAlgorithm   = 8; // name of the algorithm used to sign
  string                 shardId        = 9; // identifier of the shard where the block was created
  bytes extraBytes = 10;
}

message Header {
  repeated bytes parentsHashList = 1; //list of parent block hashes
  bytes postStateHash      = 2;
  bytes deploysHash        = 3;
  int64 timestamp = 5;
  int64 version = 6;
  int32 deployCount = 7;
  bytes extraBytes = 8;
}

message ProcessedDeploy {
    Deploy deploy = 1;
    PCost cost = 2 ;
    repeated Event log = 3; //the new terms and comm. rule reductions from this deploy
    bool errored = 4; //true if deploy encountered a user error
}

message Body {
  RChainState              postState    = 1;
  repeated ProcessedDeploy deploys      = 2;
  bytes                    extraBytes   = 3;
}

message Justification {
  bytes validator       = 1;
  bytes latestBlockHash = 2;
}

message RChainState {
  bytes tuplespace = 1; //hash of the tuplespace contents

  //Internals of what will be the "blessed" PoS contract
  //(which will be part of the tuplespace in the real implementation).
  repeated Bond bonds        = 2;
  int64         blockNumber  = 3;
}

message Deploy {
  Par          term  = 1; //rholang term to deploy
  DeployData   raw   = 2;
}

message Event {
  oneof event_instance {
    ProduceEvent produce = 1;
    ConsumeEvent consume = 2;
    CommEvent comm = 3;
  }
}

message ProduceEvent {
  bytes channelsHash = 1;
  bytes hash = 2;
}

message ConsumeEvent {
  bytes channelsHash = 1;
  bytes hash = 2;
}

message CommEvent {
  ConsumeEvent consume = 1;
  repeated ProduceEvent produces = 2;
}

message Bond {
  bytes validator = 1;
  int32 stake     = 2;
}
// --------- End Core Protocol  --------


