syntax = "proto3";

package utxorpc.v1beta.sync;

import "google/protobuf/field_mask.proto";
import "utxorpc/v1beta/cardano/cardano.proto";

// Represents a reference to a specific block by a chosen combination of fields
message BlockRef {
  uint64 slot = 1; // Height or slot number (depending on the blockchain)
  bytes hash = 2; // Hash of the content of the block
  uint64 height = 3; // Block height
  uint64 timestamp = 4; // Block ms timestamp
}

message AnyChainBlock {
  bytes native_bytes = 1; // Original bytes as defined by the chain
  oneof chain {
    utxorpc.v1beta.cardano.Block cardano = 2; // A parsed Cardano block.
  }
}

// Request to fetch a block by its reference.
message FetchBlockRequest {
  BlockRef ref = 1; // Block reference to fetch.
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields.
}

// Response containing the fetched block.
message FetchBlockResponse {
  AnyChainBlock block = 1; // The fetched block.
}

// Request to dump the block history.
message DumpHistoryRequest {
  BlockRef start_token = 2; // Starting point for the block history dump.
  uint32 max_items = 3; // Maximum number of items to return.
  google.protobuf.FieldMask field_mask = 4; // Field mask to selectively return fields.
}

// Response containing the dumped block history.
message DumpHistoryResponse {
  repeated AnyChainBlock block = 1; // List of blocks in the history.
  BlockRef next_token = 2; // Next token for pagination.
}

// Request to follow the tip of the blockchain.
message FollowTipRequest {
  repeated BlockRef intersect = 1; // List of block references to find the intersection.
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields.
}

// Response containing the action to perform while following the tip.
message FollowTipResponse {
  oneof action {
    AnyChainBlock apply = 1; // Apply this block.
    AnyChainBlock undo = 2; // Undo this block.
    BlockRef reset = 3; // Reset to this block reference.
  }
  BlockRef tip = 4; // The current tip of the blockchain after this action.
}

// Request to read the current tip of the blockchain.
message ReadTipRequest {}

// Response containing the current tip of the blockchain.
message ReadTipResponse {
  BlockRef tip = 1; // The current tip of the blockchain.
}

// Service definition for syncing chain data.
service SyncService {
  rpc FetchBlock(FetchBlockRequest) returns (FetchBlockResponse); // Fetch a block by its reference.
  rpc DumpHistory(DumpHistoryRequest) returns (DumpHistoryResponse); // Dump the block history.
  rpc FollowTip(FollowTipRequest) returns (stream FollowTipResponse); // Follow the tip of the blockchain.
  rpc ReadTip(ReadTipRequest) returns (ReadTipResponse); // Read the current tip of the blockchain.
}
