Skip to content

Commit 51572ef

Browse files
author
Ludo Galabru
committedJun 6, 2023
feat: HTTP responses adjustments
1 parent 156c463 commit 51572ef

File tree

4 files changed

+101
-98
lines changed

4 files changed

+101
-98
lines changed
 

‎components/chainhook-cli/src/scan/stacks.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::{HashMap, VecDeque};
33
use crate::{
44
archive::download_stacks_dataset_if_required,
55
block::{Record, RecordKind},
6-
config::{Config, PredicatesApi, PredicatesApiConfig},
6+
config::{Config, PredicatesApi},
77
service::{
88
open_readwrite_predicates_db_conn_or_panic, update_predicate_status, PredicateStatus,
99
ScanningData,
@@ -15,7 +15,7 @@ use crate::{
1515
},
1616
};
1717
use chainhook_event_observer::{
18-
chainhooks::{stacks::evaluate_stacks_chainhook_on_blocks, types::ChainhookSpecification},
18+
chainhooks::stacks::evaluate_stacks_chainhook_on_blocks,
1919
indexer::{self, stacks::standardize_stacks_serialized_block_header, Indexer},
2020
rocksdb::DB,
2121
utils::Context,

‎components/chainhook-cli/src/service/http_api.rs

+78-73
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ pub async fn start_predicate_api_server(
7979
#[openapi(tag = "Chainhooks")]
8080
#[get("/ping")]
8181
fn handle_ping(ctx: &State<Context>) -> Json<JsonValue> {
82-
ctx.try_log(|logger| slog::info!(logger, "GET /ping"));
82+
ctx.try_log(|logger| slog::info!(logger, "Handling HTTP GET /ping"));
8383
Json(json!({
8484
"status": 200,
8585
"result": "Ok",
@@ -92,42 +92,21 @@ fn handle_get_predicates(
9292
predicate_db: &State<Arc<RwLock<Connection>>>,
9393
ctx: &State<Context>,
9494
) -> Json<JsonValue> {
95-
ctx.try_log(|logger| slog::info!(logger, "GET /v1/chainhooks"));
96-
if let Ok(chainhook_store_reader) = chainhook_store.inner().read() {
97-
let mut predicates = vec![];
98-
let mut stacks_predicates = chainhook_store_reader
99-
.predicates
100-
.get_serialized_stacks_predicates()
101-
.iter()
102-
.map(|(uuid, network, predicate)| {
103-
json!({
104-
"chain": "stacks",
105-
"uuid": uuid,
106-
"network": network,
107-
"predicate": predicate,
108-
})
109-
})
110-
.collect::<Vec<_>>();
111-
predicates.append(&mut stacks_predicates);
95+
ctx.try_log(|logger| slog::info!(logger, "Handling HTTP GET /v1/chainhooks"));
96+
if let Ok(mut predicates_db_conn) = predicate_db.inner().write() {
97+
let predicates = match get_entries_from_predicates_db(&mut predicates_db_conn, &ctx) {
98+
Ok(predicates) => predicates,
99+
Err(e) => unimplemented!(),
100+
};
112101

113-
let mut bitcoin_predicates = chainhook_store_reader
114-
.predicates
115-
.get_serialized_bitcoin_predicates()
102+
let serialized_predicates = predicates
116103
.iter()
117-
.map(|(uuid, network, predicate)| {
118-
json!({
119-
"chain": "bitcoin",
120-
"uuid": uuid,
121-
"network": network,
122-
"predicate": predicate,
123-
})
124-
})
104+
.map(|(p, _)| p.into_serialized_json())
125105
.collect::<Vec<_>>();
126-
predicates.append(&mut bitcoin_predicates);
127106

128107
Json(json!({
129108
"status": 200,
130-
"result": predicates
109+
"result": serialized_predicates
131110
}))
132111
} else {
133112
Json(json!({
@@ -145,7 +124,7 @@ fn handle_create_predicate(
145124
background_job_tx: &State<Arc<Mutex<Sender<ObserverCommand>>>>,
146125
ctx: &State<Context>,
147126
) -> Json<JsonValue> {
148-
ctx.try_log(|logger| slog::info!(logger, "POST /v1/chainhooks"));
127+
ctx.try_log(|logger| slog::info!(logger, "Handling HTTP POST /v1/chainhooks"));
149128
let predicate = predicate.into_inner();
150129
if let Err(e) = predicate.validate() {
151130
return Json(json!({
@@ -155,7 +134,11 @@ fn handle_create_predicate(
155134
}
156135

157136
if let Ok(mut predicates_db_conn) = predicate_db.inner().write() {
158-
match get_entry_from_predicates_db(&predicate.get_uuid(), &mut predicates_db_conn, &ctx) {
137+
match get_entry_from_predicates_db(
138+
&ChainhookSpecification::either_stx_or_btc_key(predicate.get_uuid()),
139+
&mut predicates_db_conn,
140+
&ctx,
141+
) {
159142
Ok(Some(_)) => {
160143
return Json(json!({
161144
"status": 409,
@@ -187,28 +170,44 @@ fn handle_get_predicate(
187170
predicate_db: &State<Arc<RwLock<Connection>>>,
188171
ctx: &State<Context>,
189172
) -> Json<JsonValue> {
190-
ctx.try_log(|logger| slog::info!(logger, "GET /v1/chainhooks/{}", predicate_uuid));
173+
ctx.try_log(|logger| {
174+
slog::info!(
175+
logger,
176+
"Handling HTTP GET /v1/chainhooks/{}",
177+
predicate_uuid
178+
)
179+
});
191180

192181
if let Ok(mut predicates_db_conn) = predicate_db.inner().write() {
193-
match get_entry_from_predicates_db(&predicate_uuid, &mut predicates_db_conn, &ctx) {
194-
Ok(Some((ChainhookSpecification::Stacks(spec), status))) => Json(json!({
182+
let entry = match get_entry_from_predicates_db(
183+
&ChainhookSpecification::either_stx_or_btc_key(&predicate_uuid),
184+
&mut predicates_db_conn,
185+
&ctx,
186+
) {
187+
Ok(Some((ChainhookSpecification::Stacks(spec), status))) => json!({
195188
"chain": "stacks",
196189
"uuid": spec.uuid,
197190
"network": spec.network,
198191
"predicate": spec.predicate,
199192
"status": status
200-
})),
201-
Ok(Some((ChainhookSpecification::Bitcoin(spec), status))) => Json(json!({
193+
}),
194+
Ok(Some((ChainhookSpecification::Bitcoin(spec), status))) => json!({
202195
"chain": "bitcoin",
203196
"uuid": spec.uuid,
204197
"network": spec.network,
205198
"predicate": spec.predicate,
206199
"status": status
207-
})),
208-
_ => Json(json!({
209-
"status": 404,
210-
})),
211-
}
200+
}),
201+
_ => {
202+
return Json(json!({
203+
"status": 404,
204+
}))
205+
}
206+
};
207+
Json(json!({
208+
"status": 200,
209+
"result": entry
210+
}))
212211
} else {
213212
Json(json!({
214213
"status": 500,
@@ -224,7 +223,13 @@ fn handle_delete_stacks_predicate(
224223
background_job_tx: &State<Arc<Mutex<Sender<ObserverCommand>>>>,
225224
ctx: &State<Context>,
226225
) -> Json<JsonValue> {
227-
ctx.try_log(|logger| slog::info!(logger, "DELETE /v1/chainhooks/stacks/{}", predicate_uuid));
226+
ctx.try_log(|logger| {
227+
slog::info!(
228+
logger,
229+
"Handling HTTP DELETE /v1/chainhooks/stacks/{}",
230+
predicate_uuid
231+
)
232+
});
228233

229234
let background_job_tx = background_job_tx.inner();
230235
match background_job_tx.lock() {
@@ -247,7 +252,13 @@ fn handle_delete_bitcoin_predicate(
247252
background_job_tx: &State<Arc<Mutex<Sender<ObserverCommand>>>>,
248253
ctx: &State<Context>,
249254
) -> Json<JsonValue> {
250-
ctx.try_log(|logger| slog::info!(logger, "DELETE /v1/chainhooks/bitcoin/{}", predicate_uuid));
255+
ctx.try_log(|logger| {
256+
slog::info!(
257+
logger,
258+
"Handling HTTP DELETE /v1/chainhooks/bitcoin/{}",
259+
predicate_uuid
260+
)
261+
});
251262

252263
let background_job_tx = background_job_tx.inner();
253264
match background_job_tx.lock() {
@@ -264,19 +275,17 @@ fn handle_delete_bitcoin_predicate(
264275
}
265276

266277
pub fn get_entry_from_predicates_db(
267-
uuid: &str,
278+
predicate_key: &str,
268279
predicate_db_conn: &mut Connection,
269280
_ctx: &Context,
270281
) -> Result<Option<(ChainhookSpecification, PredicateStatus)>, String> {
271-
let entry: HashMap<String, String> = predicate_db_conn
272-
.hgetall(ChainhookSpecification::either_stx_or_btc_key(uuid))
273-
.map_err(|e| {
274-
format!(
275-
"unable to load chainhook associated with key {}: {}",
276-
uuid,
277-
e.to_string()
278-
)
279-
})?;
282+
let entry: HashMap<String, String> = predicate_db_conn.hgetall(predicate_key).map_err(|e| {
283+
format!(
284+
"unable to load chainhook associated with key {}: {}",
285+
predicate_key,
286+
e.to_string()
287+
)
288+
})?;
280289

281290
let encoded_spec = match entry.get("specification") {
282291
None => return Ok(None),
@@ -294,7 +303,7 @@ pub fn get_entry_from_predicates_db(
294303
};
295304

296305
let status = match serde_json::from_str(&encoded_status) {
297-
Err(e) => unimplemented!(),
306+
Err(e) => unimplemented!(), // TODO
298307
Ok(status) => status,
299308
};
300309

@@ -304,33 +313,29 @@ pub fn get_entry_from_predicates_db(
304313
pub fn get_entries_from_predicates_db(
305314
predicate_db_conn: &mut Connection,
306315
ctx: &Context,
307-
) -> Result<Vec<ChainhookSpecification>, String> {
316+
) -> Result<Vec<(ChainhookSpecification, PredicateStatus)>, String> {
308317
let chainhooks_to_load: Vec<String> = predicate_db_conn
309318
.scan_match(ChainhookSpecification::either_stx_or_btc_key("*"))
310319
.map_err(|e| format!("unable to connect to redis: {}", e.to_string()))?
311320
.into_iter()
312321
.collect();
313322

314323
let mut predicates = vec![];
315-
for key in chainhooks_to_load.iter() {
316-
let chainhook = match predicate_db_conn.hget::<_, _, String>(key, "specification") {
317-
Ok(spec) => match ChainhookSpecification::deserialize_specification(&spec) {
318-
Ok(spec) => spec,
319-
Err(e) => {
320-
error!(
321-
ctx.expect_logger(),
322-
"unable to load chainhook associated with key {}: {}",
323-
key,
324-
e.to_string()
325-
);
326-
continue;
327-
}
328-
},
324+
for predicate_key in chainhooks_to_load.iter() {
325+
let chainhook = match get_entry_from_predicates_db(predicate_key, predicate_db_conn, ctx) {
326+
Ok(Some((spec, status))) => (spec, status),
327+
Ok(None) => {
328+
warn!(
329+
ctx.expect_logger(),
330+
"unable to load chainhook associated with key {}", predicate_key,
331+
);
332+
continue;
333+
}
329334
Err(e) => {
330335
error!(
331336
ctx.expect_logger(),
332337
"unable to load chainhook associated with key {}: {}",
333-
key,
338+
predicate_key,
334339
e.to_string()
335340
);
336341
continue;
@@ -344,7 +349,7 @@ pub fn get_entries_from_predicates_db(
344349
pub fn load_predicates_from_redis(
345350
config: &crate::config::Config,
346351
ctx: &Context,
347-
) -> Result<Vec<ChainhookSpecification>, String> {
352+
) -> Result<Vec<(ChainhookSpecification, PredicateStatus)>, String> {
348353
let redis_uri: &str = config.expected_api_database_uri();
349354
let client = redis::Client::open(redis_uri.clone())
350355
.map_err(|e| format!("unable to connect to redis: {}", e.to_string()))?;

‎components/chainhook-cli/src/service/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl Service {
4949
vec![]
5050
}
5151
};
52-
for predicate in registered_predicates.into_iter() {
52+
for (predicate, _status) in registered_predicates.into_iter() {
5353
let predicate_uuid = predicate.uuid().to_string();
5454
match chainhook_config.register_specification(predicate, true) {
5555
Ok(_) => {
@@ -327,6 +327,7 @@ impl Service {
327327
}
328328

329329
#[derive(Debug, Clone, Serialize, Deserialize)]
330+
#[serde(rename_all = "snake_case")]
330331
pub enum PredicateStatus {
331332
Scanning(ScanningData),
332333
Streaming(StreamingData),

‎components/chainhook-event-observer/src/chainhooks/types.rs

+19-22
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use std::collections::BTreeMap;
22

3+
use chainhook_types::{BitcoinNetwork, StacksNetwork};
34
use clarity_repl::clarity::util::hash::hex_bytes;
45
use reqwest::Url;
56
use serde::ser::{SerializeSeq, Serializer};
67
use serde::{Deserialize, Serialize};
7-
8-
use chainhook_types::{BitcoinNetwork, StacksNetwork};
8+
use serde_json::Value as JsonValue;
99

1010
use schemars::JsonSchema;
1111

@@ -44,26 +44,6 @@ impl ChainhookConfig {
4444
None
4545
}
4646

47-
pub fn get_serialized_stacks_predicates(
48-
&self,
49-
) -> Vec<(&String, &StacksNetwork, &StacksPredicate)> {
50-
let mut stacks = vec![];
51-
for chainhook in self.stacks_chainhooks.iter() {
52-
stacks.push((&chainhook.uuid, &chainhook.network, &chainhook.predicate));
53-
}
54-
stacks
55-
}
56-
57-
pub fn get_serialized_bitcoin_predicates(
58-
&self,
59-
) -> Vec<(&String, &BitcoinNetwork, &BitcoinPredicateType)> {
60-
let mut bitcoin = vec![];
61-
for chainhook in self.bitcoin_chainhooks.iter() {
62-
bitcoin.push((&chainhook.uuid, &chainhook.network, &chainhook.predicate));
63-
}
64-
bitcoin
65-
}
66-
6747
pub fn register_full_specification(
6848
&mut self,
6949
networks: (&BitcoinNetwork, &StacksNetwork),
@@ -203,6 +183,23 @@ impl ChainhookSpecification {
203183
format!("predicate:{}", uuid)
204184
}
205185

186+
pub fn into_serialized_json(&self) -> JsonValue {
187+
match &self {
188+
Self::Bitcoin(data) => json!({
189+
"chain": "stacks",
190+
"uuid": data.uuid,
191+
"network": data.network,
192+
"predicate": data.predicate,
193+
}),
194+
Self::Stacks(data) => json!({
195+
"chain": "bitcoin",
196+
"uuid": data.uuid,
197+
"network": data.network,
198+
"predicate": data.predicate,
199+
}),
200+
}
201+
}
202+
206203
pub fn key(&self) -> String {
207204
match &self {
208205
Self::Bitcoin(data) => Self::bitcoin_key(&data.uuid),

0 commit comments

Comments
 (0)