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