syntax = "proto3";

package soma.rpc;

import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";
import "soma/rpc/checkpoint.proto";
import "soma/rpc/epoch.proto";
import "soma/rpc/executed_transaction.proto";
import "soma/rpc/object.proto";
import "soma/rpc/object_reference.proto";

service LedgerService {
  // Query the service for general information about its current state.
  rpc GetServiceInfo(GetServiceInfoRequest) returns (GetServiceInfoResponse);

  rpc GetObject(GetObjectRequest) returns (GetObjectResponse);
  rpc BatchGetObjects(BatchGetObjectsRequest) returns (BatchGetObjectsResponse);

  rpc GetTransaction(GetTransactionRequest) returns (GetTransactionResponse);
  rpc BatchGetTransactions(BatchGetTransactionsRequest) returns (BatchGetTransactionsResponse);

  rpc GetCheckpoint(GetCheckpointRequest) returns (GetCheckpointResponse);

  rpc GetEpoch(GetEpochRequest) returns (GetEpochResponse);
}

message GetServiceInfoRequest {}

message GetServiceInfoResponse {
  // The chain identifier of the chain that this node is on.
  //
  // The chain identifier is the digest of the genesis checkpoint, the
  // checkpoint with sequence number 0.
  optional string chain_id = 1;

  // Human-readable name of the chain that this node is on.
  //
  // This is intended to be a human-readable name like `mainnet`, `testnet`, and so on.
  optional string chain = 2;

  // Current epoch of the node based on its highest executed checkpoint.
  optional uint64 epoch = 3;

  // Checkpoint height of the most recently executed checkpoint.
  optional uint64 checkpoint_height = 4;

  // Unix timestamp of the most recently executed checkpoint.
  optional google.protobuf.Timestamp timestamp = 5;

  // The lowest checkpoint for which checkpoints and transaction data are available.
  optional uint64 lowest_available_checkpoint = 6;

  // The lowest checkpoint for which object data is available.
  optional uint64 lowest_available_checkpoint_objects = 7;

  // Software version of the service. Similar to the `server` http header.
  optional string server = 8;
}

message GetObjectRequest {
  // Required. The `ObjectId` of the requested object.
  optional string object_id = 1;

  // Request a specific version of the object.
  // If no version is specified, and the object is live, then the latest
  // version of the object is returned.
  optional uint64 version = 2;

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `object_id,version,digest`.
  optional google.protobuf.FieldMask read_mask = 3;
}

message GetObjectResponse {
  optional Object object = 1;
}

message BatchGetObjectsRequest {
  repeated GetObjectRequest requests = 1;

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `object_id,version,digest`.
  optional google.protobuf.FieldMask read_mask = 2;
}

message BatchGetObjectsResponse {
  repeated GetObjectResult objects = 1;
}

message GetObjectResult {
  oneof result {
    Object object = 1;
    google.rpc.Status error = 2;
  }
}

message GetTransactionRequest {
  // Required. The digest of the requested transaction.
  optional string digest = 1;

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `digest`.
  optional google.protobuf.FieldMask read_mask = 2;
}

message GetTransactionResponse {
  optional ExecutedTransaction transaction = 1;
}

message BatchGetTransactionsRequest {
  // Required. The digests of the requested transactions.
  repeated string digests = 1;

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `digest`.
  optional google.protobuf.FieldMask read_mask = 2;
}

message BatchGetTransactionsResponse {
  repeated GetTransactionResult transactions = 1;
}

message GetTransactionResult {
  oneof result {
    ExecutedTransaction transaction = 1;
    google.rpc.Status error = 2;
  }
}

message GetCheckpointRequest {
  // If neither is provided, return the latest
  oneof checkpoint_id {
    // The sequence number of the requested checkpoint.
    uint64 sequence_number = 1;

    // The digest of the requested checkpoint.
    string digest = 2;
  }

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `sequence_number,digest`.
  optional google.protobuf.FieldMask read_mask = 3;
}

message GetCheckpointResponse {
  optional Checkpoint checkpoint = 1;
}

message GetEpochRequest {
  // The requested epoch.
  // If no epoch is provided the current epoch will be returned.
  optional uint64 epoch = 1;

  // Mask specifying which fields to read.
  // If no mask is specified, defaults to `epoch`.
  optional google.protobuf.FieldMask read_mask = 2;
}

message GetEpochResponse {
  optional Epoch epoch = 1;
}
