Skip to main content

linera_storage_service/
common.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use std::path::PathBuf;
5
6use linera_base::command::resolve_binary;
7use linera_views::{lru_caching::LruCachingConfig, store::KeyValueStoreError};
8use serde::{Deserialize, Serialize};
9use thiserror::Error;
10use tonic::Status;
11
12// The maximal block size on GRPC is 4M.
13//
14// That size occurs in almost every use of GRPC and in particular the
15// `tonic` library. In particular for the `tonic` library, the limit is
16// both for incoming and outgoing messages.
17// We decrease the 4194304 to 4000000 to leave space for the rest of the message
18// (that includes length prefixes)
19/// The maximum size of a gRPC payload, in bytes.
20pub const MAX_PAYLOAD_SIZE: usize = 4000000;
21
22/// Key tags to create the sub keys used for storing data on storage.
23#[repr(u8)]
24pub enum KeyPrefix {
25    /// Key prefix for the storage of the keys of the map
26    Key,
27    /// Key prefix for the storage of existence or not of the namespaces.
28    Namespace,
29    /// Key prefix for the root key
30    RootKey,
31}
32
33/// The errors returned by the storage service store.
34#[derive(Debug, Error)]
35pub enum StorageServiceStoreError {
36    /// Store already exists during a create operation
37    #[error("Store already exists during a create operation")]
38    StoreAlreadyExists,
39
40    /// Not matching entry
41    #[error("Not matching entry")]
42    NotMatchingEntry,
43
44    /// Failed to find the linera-storage-server binary
45    #[error("Failed to find the linera-storage-server binary")]
46    FailedToFindStorageServerBinary,
47
48    /// gRPC error
49    #[error(transparent)]
50    GrpcError(#[from] Box<Status>),
51
52    /// The key size must be at most 1 MB
53    #[error("The key size must be at most 1 MB")]
54    KeyTooLong,
55
56    /// Transport error
57    #[error(transparent)]
58    TransportError(#[from] tonic::transport::Error),
59
60    /// Var error
61    #[error(transparent)]
62    VarError(#[from] std::env::VarError),
63
64    /// An error occurred during BCS serialization
65    #[error(transparent)]
66    BcsError(#[from] bcs::Error),
67}
68
69impl From<Status> for StorageServiceStoreError {
70    fn from(error: Status) -> Self {
71        Box::new(error).into()
72    }
73}
74
75impl KeyValueStoreError for StorageServiceStoreError {
76    const BACKEND: &'static str = "service";
77}
78
79/// Returns the storage service endpoint used for testing, read from the environment.
80pub fn storage_service_test_endpoint() -> Result<String, StorageServiceStoreError> {
81    Ok(std::env::var("LINERA_STORAGE_SERVICE")?)
82}
83
84/// The configuration for connecting to a storage service.
85#[derive(Clone, Debug, Deserialize, Serialize)]
86pub struct StorageServiceStoreInternalConfig {
87    /// The endpoint used by the shared store
88    pub endpoint: String,
89    /// Maximum number of concurrent database queries allowed for this client.
90    pub max_concurrent_queries: Option<usize>,
91    /// Preferred buffer size for async streams.
92    pub max_stream_queries: usize,
93}
94
95/// The config type
96pub type StorageServiceStoreConfig = LruCachingConfig<StorageServiceStoreInternalConfig>;
97
98impl StorageServiceStoreInternalConfig {
99    /// Returns the HTTP address of the endpoint.
100    pub fn http_address(&self) -> String {
101        format!("http://{}", self.endpoint)
102    }
103}
104
105/// Obtains the binary of the executable.
106/// The path depends whether the test are run in the directory "linera-storage-service"
107/// or in the main directory
108pub async fn get_service_storage_binary() -> Result<PathBuf, StorageServiceStoreError> {
109    let binary = resolve_binary("linera-storage-server", "linera-storage-service").await;
110    if let Ok(binary) = binary {
111        return Ok(binary);
112    }
113    let binary = resolve_binary("../linera-storage-server", "linera-storage-service").await;
114    if let Ok(binary) = binary {
115        return Ok(binary);
116    }
117    Err(StorageServiceStoreError::FailedToFindStorageServerBinary)
118}