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

stacks-network / stacks-core / 26205235903-1

21 May 2026 04:21AM UTC coverage: 47.633% (-38.3%) from 85.959%
26205235903-1

Pull #7199

github

81cec7
web-flow
Merge 65279bdff into ca46d23f6
Pull Request #7199: Feat: L1 and L2 early unlocks, updating signer

2 of 6 new or added lines in 1 file covered. (33.33%)

88556 existing lines in 343 files now uncovered.

105032 of 220501 relevant lines covered (47.63%)

12944163.92 hits per line

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

16.13
/stackslib/src/net/api/getstackerdbmetadata.rs
1
// Copyright (C) 2013-2020 Blockstack PBC, a public benefit corporation
2
// Copyright (C) 2020-2023 Stacks Open Internet Foundation
3
//
4
// This program is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// This program is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16

17
use clarity::vm::representations::{CONTRACT_NAME_REGEX_STRING, STANDARD_PRINCIPAL_REGEX_STRING};
18
use clarity::vm::types::QualifiedContractIdentifier;
19
use libstackerdb::SlotMetadata;
20
use regex::{Captures, Regex};
21
use serde_json;
22
use stacks_common::types::net::PeerHost;
23

24
use crate::net::http::{
25
    parse_json, Error, HttpNotFound, HttpRequest, HttpRequestContents, HttpRequestPreamble,
26
    HttpResponse, HttpResponseContents, HttpResponsePayload, HttpResponsePreamble,
27
};
28
use crate::net::httpcore::{request, RPCRequestHandler, StacksHttpRequest, StacksHttpResponse};
29
use crate::net::{Error as NetError, StacksNodeState};
30

31
#[derive(Clone)]
32
pub struct RPCGetStackerDBMetadataRequestHandler {
33
    pub contract_identifier: Option<QualifiedContractIdentifier>,
34
}
35
impl RPCGetStackerDBMetadataRequestHandler {
36
    pub fn new() -> Self {
1,084,767✔
37
        Self {
1,084,767✔
38
            contract_identifier: None,
1,084,767✔
39
        }
1,084,767✔
40
    }
1,084,767✔
41
}
42

43
/// Decode the HTTP request
44
impl HttpRequest for RPCGetStackerDBMetadataRequestHandler {
45
    fn verb(&self) -> &'static str {
1,084,767✔
46
        "GET"
1,084,767✔
47
    }
1,084,767✔
48

49
    fn path_regex(&self) -> Regex {
2,169,534✔
50
        Regex::new(&format!(
2,169,534✔
51
            r#"^/v2/stackerdb/(?P<address>{})/(?P<contract>{})$"#,
2,169,534✔
52
            *STANDARD_PRINCIPAL_REGEX_STRING, *CONTRACT_NAME_REGEX_STRING
2,169,534✔
53
        ))
2,169,534✔
54
        .unwrap()
2,169,534✔
55
    }
2,169,534✔
56

UNCOV
57
    fn metrics_identifier(&self) -> &str {
×
UNCOV
58
        "/v2/stackerdb/:principal/:contract_name"
×
UNCOV
59
    }
×
60

61
    /// Try to decode this request.
62
    /// There's nothing to load here, so just make sure the request is well-formed.
UNCOV
63
    fn try_parse_request(
×
UNCOV
64
        &mut self,
×
UNCOV
65
        preamble: &HttpRequestPreamble,
×
UNCOV
66
        captures: &Captures,
×
UNCOV
67
        query: Option<&str>,
×
UNCOV
68
        _body: &[u8],
×
UNCOV
69
    ) -> Result<HttpRequestContents, Error> {
×
UNCOV
70
        if preamble.get_content_length() != 0 {
×
71
            return Err(Error::DecodeError(
×
72
                "Invalid Http request: expected 0-length body".to_string(),
×
73
            ));
×
UNCOV
74
        }
×
75

UNCOV
76
        let contract_identifier = request::get_contract_address(captures, "address", "contract")?;
×
UNCOV
77
        self.contract_identifier = Some(contract_identifier);
×
78

UNCOV
79
        Ok(HttpRequestContents::new().query_string(query))
×
UNCOV
80
    }
×
81
}
82

83
impl RPCRequestHandler for RPCGetStackerDBMetadataRequestHandler {
84
    /// Reset internal state
UNCOV
85
    fn restart(&mut self) {
×
UNCOV
86
        self.contract_identifier = None;
×
UNCOV
87
    }
×
88

89
    /// Make the response
UNCOV
90
    fn try_handle_request(
×
UNCOV
91
        &mut self,
×
UNCOV
92
        preamble: HttpRequestPreamble,
×
UNCOV
93
        _contents: HttpRequestContents,
×
UNCOV
94
        node: &mut StacksNodeState,
×
UNCOV
95
    ) -> Result<(HttpResponsePreamble, HttpResponseContents), NetError> {
×
UNCOV
96
        let contract_identifier = self
×
UNCOV
97
            .contract_identifier
×
UNCOV
98
            .take()
×
UNCOV
99
            .ok_or(NetError::SendError("`contract_identifier` not set".into()))?;
×
100

UNCOV
101
        let metadata_resp =
×
UNCOV
102
            node.with_node_state(|network, _sortdb, _chainstate, _mempool, _rpc_args| {
×
UNCOV
103
                network
×
UNCOV
104
                    .get_stackerdbs()
×
UNCOV
105
                    .get_db_slot_metadata(&contract_identifier)
×
UNCOV
106
                    .map_err(|_e| {
×
UNCOV
107
                        StacksHttpResponse::new_error(
×
UNCOV
108
                            &preamble,
×
UNCOV
109
                            &HttpNotFound::new("StackerDB contract not found".to_string()),
×
110
                        )
UNCOV
111
                    })
×
UNCOV
112
            });
×
113

UNCOV
114
        let metadata_resp = match metadata_resp {
×
UNCOV
115
            Ok(metadata) => metadata,
×
UNCOV
116
            Err(response) => {
×
UNCOV
117
                return response.try_into_contents().map_err(NetError::from);
×
118
            }
119
        };
120

UNCOV
121
        let preamble = HttpResponsePreamble::ok_json(&preamble);
×
UNCOV
122
        let body = HttpResponseContents::try_from_json(&metadata_resp)?;
×
UNCOV
123
        Ok((preamble, body))
×
UNCOV
124
    }
×
125
}
126

127
/// Decode the HTTP response
128
impl HttpResponse for RPCGetStackerDBMetadataRequestHandler {
129
    /// Decode this response from a byte stream.  This is called by the client to decode this
130
    /// message
UNCOV
131
    fn try_parse_response(
×
UNCOV
132
        &self,
×
UNCOV
133
        preamble: &HttpResponsePreamble,
×
UNCOV
134
        body: &[u8],
×
UNCOV
135
    ) -> Result<HttpResponsePayload, Error> {
×
UNCOV
136
        let metadata: Vec<SlotMetadata> = parse_json(preamble, body)?;
×
UNCOV
137
        Ok(HttpResponsePayload::try_from_json(metadata)?)
×
UNCOV
138
    }
×
139
}
140

141
impl StacksHttpRequest {
UNCOV
142
    pub fn new_get_stackerdb_metadata(
×
UNCOV
143
        host: PeerHost,
×
UNCOV
144
        stackerdb_contract_id: QualifiedContractIdentifier,
×
UNCOV
145
    ) -> StacksHttpRequest {
×
UNCOV
146
        StacksHttpRequest::new_for_peer(
×
UNCOV
147
            host,
×
UNCOV
148
            "GET".into(),
×
UNCOV
149
            format!(
×
150
                "/v2/stackerdb/{}/{}",
UNCOV
151
                &stackerdb_contract_id.issuer, &stackerdb_contract_id.name
×
152
            ),
UNCOV
153
            HttpRequestContents::new(),
×
154
        )
UNCOV
155
        .expect("FATAL: failed to construct request from infallible data")
×
UNCOV
156
    }
×
157
}
158

159
impl StacksHttpResponse {
160
    /// Decode an HTTP response into a block.
161
    /// If it fails, return Self::Error(..)
UNCOV
162
    pub fn decode_stackerdb_metadata(self) -> Result<Vec<SlotMetadata>, NetError> {
×
UNCOV
163
        let contents = self.get_http_payload_ok()?;
×
UNCOV
164
        let contents_json: serde_json::Value = contents.try_into()?;
×
UNCOV
165
        let resp: Vec<SlotMetadata> = serde_json::from_value(contents_json)
×
UNCOV
166
            .map_err(|_e| NetError::DeserializeError("Failed to load from JSON".to_string()))?;
×
UNCOV
167
        Ok(resp)
×
UNCOV
168
    }
×
169
}
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