• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

oasisprotocol / oasis-core / #6868

12 Feb 2026 01:11PM UTC coverage: 48.237% (-0.1%) from 48.357%
#6868

push

web-flow
Merge pull request #6460 from oasisprotocol/kostko/feature/rust-2026-02-11

5 of 8 new or added lines in 3 files covered. (62.5%)

43 existing lines in 14 files now uncovered.

4650 of 9640 relevant lines covered (48.24%)

1.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/runtime/src/host/mod.rs
1
//! Host interface.
2
use async_trait::async_trait;
3
use thiserror::Error;
4

5
use crate::{
6
    common::{crypto::signature::PublicKey, namespace::Namespace},
7
    enclave_rpc,
8
    protocol::Protocol,
9
    storage::mkvs::sync,
10
    types::{self, Body},
11
};
12

13
pub mod attestation;
14
pub mod bundle_manager;
15
pub mod log_manager;
16
pub mod volume_manager;
17

18
/// Errors.
19
#[derive(Error, Debug)]
20
pub enum Error {
21
    #[error("bad response from host")]
22
    BadResponse,
23

24
    #[error("{0}")]
25
    Host(#[from] types::Error),
26

27
    #[error("{0}")]
28
    Decode(#[from] cbor::DecodeError),
29
}
30

31
/// Transaction submission options.
32
#[derive(Clone, Default, Debug)]
33
pub struct SubmitTxOpts {
34
    /// Target runtime identifier. If not specified, own runtime identifier is used.
35
    pub runtime_id: Option<Namespace>,
36
    /// Whether the call should wait until the transaction is included in a block.
37
    pub wait: bool,
38
    /// Whether the response should include a proof of transaction being included in a block.
39
    pub prove: bool,
40
}
41

42
/// Transaction submission result.
43
#[derive(Clone, Default, Debug)]
44
pub struct TxResult {
45
    /// Transaction output.
46
    pub output: Vec<u8>,
47
    /// Round in which the transaction was executed.
48
    pub round: u64,
49
    /// Order of the transaction in the execution batch.
50
    pub batch_order: u32,
51
    /// Optional inclusion proof.
52
    pub proof: Option<sync::Proof>,
53
}
54

55
/// Interface to the (untrusted) host node.
56
#[async_trait]
57
pub trait Host: Send + Sync {
58
    /// Returns the identity of the host node.
59
    async fn identity(&self) -> Result<PublicKey, Error>;
60

61
    /// Submit a transaction.
62
    async fn submit_tx(&self, data: Vec<u8>, opts: SubmitTxOpts)
63
        -> Result<Option<TxResult>, Error>;
64

65
    /// Bundle manager interface.
66
    fn bundle_manager(&self) -> &dyn bundle_manager::BundleManager;
67

68
    /// Volume manager interface.
69
    fn volume_manager(&self) -> &dyn volume_manager::VolumeManager;
70

71
    /// Log manager interface.
72
    fn log_manager(&self) -> &dyn log_manager::LogManager;
73

74
    /// Attestation interface.
75
    fn attestation(&self) -> &dyn attestation::Attestation;
76
}
77

78
#[async_trait]
79
impl Host for Protocol {
80
    async fn identity(&self) -> Result<PublicKey, Error> {
×
81
        match self.call_host_async(Body::HostIdentityRequest {}).await? {
×
82
            Body::HostIdentityResponse { node_id } => Ok(node_id),
×
83
            _ => Err(Error::BadResponse),
×
84
        }
85
    }
86

UNCOV
87
    async fn submit_tx(
×
88
        &self,
89
        data: Vec<u8>,
90
        opts: SubmitTxOpts,
91
    ) -> Result<Option<TxResult>, Error> {
92
        match self
×
93
            .call_host_async(Body::HostSubmitTxRequest {
×
94
                runtime_id: opts.runtime_id.unwrap_or_else(|| self.get_runtime_id()),
×
95
                data,
×
96
                wait: opts.wait,
×
97
                prove: opts.prove,
×
98
            })
99
            .await?
×
100
        {
101
            Body::HostSubmitTxResponse {
×
102
                output,
103
                round,
104
                batch_order,
105
                proof,
106
            } => {
107
                if opts.wait {
×
108
                    Ok(Some(TxResult {
×
109
                        output,
×
110
                        round,
111
                        batch_order,
112
                        proof,
×
113
                    }))
114
                } else {
115
                    // If we didn't wait for inclusion then there is no result.
116
                    Ok(None)
×
117
                }
118
            }
119
            _ => Err(Error::BadResponse),
×
120
        }
121
    }
122

123
    fn bundle_manager(&self) -> &dyn bundle_manager::BundleManager {
×
124
        self
125
    }
126

127
    fn volume_manager(&self) -> &dyn volume_manager::VolumeManager {
×
128
        self
129
    }
130

131
    fn log_manager(&self) -> &dyn log_manager::LogManager {
×
132
        self
133
    }
134

135
    fn attestation(&self) -> &dyn attestation::Attestation {
×
136
        self
137
    }
138
}
139

140
/// Wrapper to call the host via local RPC.
141
pub(super) async fn host_rpc_call<Rq: cbor::Encode, Rs: cbor::Decode>(
×
142
    protocol: &Protocol,
143
    endpoint: &str,
144
    method: &str,
145
    args: Rq,
146
) -> Result<Rs, Error> {
147
    match protocol
×
148
        .call_host_async(Body::HostRPCCallRequest {
×
149
            endpoint: endpoint.to_string(),
×
150
            request_id: 0,
×
151
            request: cbor::to_vec(enclave_rpc::types::Request {
×
152
                method: method.to_string(),
×
153
                args: cbor::to_value(args),
×
154
            }),
155
            kind: enclave_rpc::types::Kind::LocalQuery,
×
156
            nodes: vec![],
×
157
        })
158
        .await?
×
159
    {
160
        Body::HostRPCCallResponse { response, .. } => Ok(cbor::from_slice(&response)?),
×
161
        _ => Err(Error::BadResponse),
×
162
    }
163
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc