Skip to content

Commit

Permalink
feat: broadcast ObserverEvent::BitcoinPredicateTriggered on successfu…
Browse files Browse the repository at this point in the history
…l requests
  • Loading branch information
Ludo Galabru committed Dec 26, 2023
1 parent 53f4cc4 commit a6164ea
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 47 deletions.
95 changes: 52 additions & 43 deletions components/chainhook-sdk/src/chainhooks/bitcoin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,44 @@ pub struct BitcoinChainhookOccurrencePayload {
pub chainhook: BitcoinChainhookPayload,
}

impl BitcoinChainhookOccurrencePayload {
pub fn from_trigger<'a>(
trigger: BitcoinTriggerChainhook<'a>,
) -> BitcoinChainhookOccurrencePayload {
BitcoinChainhookOccurrencePayload {
apply: trigger
.apply
.into_iter()
.map(|(transactions, block)| {
let mut block = block.clone();
block.transactions = transactions
.into_iter()
.map(|t| t.clone())
.collect::<Vec<_>>();
BitcoinTransactionPayload { block }
})
.collect::<Vec<_>>(),
rollback: trigger
.rollback
.into_iter()
.map(|(transactions, block)| {
let mut block = block.clone();
block.transactions = transactions
.into_iter()
.map(|t| t.clone())
.collect::<Vec<_>>();
BitcoinTransactionPayload { block }
})
.collect::<Vec<_>>(),
chainhook: BitcoinChainhookPayload {
uuid: trigger.chainhook.uuid.clone(),
},
}
}
}

pub enum BitcoinChainhookOccurrence {
Http(RequestBuilder),
Http(RequestBuilder, BitcoinChainhookOccurrencePayload),
File(String, Vec<u8>),
Data(BitcoinChainhookOccurrencePayload),
}
Expand Down Expand Up @@ -156,12 +192,12 @@ pub fn evaluate_bitcoin_chainhooks_on_chain_event<'a>(
}

pub fn serialize_bitcoin_payload_to_json<'a>(
trigger: BitcoinTriggerChainhook<'a>,
trigger: &BitcoinTriggerChainhook<'a>,
proofs: &HashMap<&'a TransactionIdentifier, String>,
) -> JsonValue {
let predicate_spec = &trigger.chainhook;
let predicate_spec = trigger.chainhook;
json!({
"apply": trigger.apply.into_iter().map(|(transactions, block)| {
"apply": trigger.apply.iter().map(|(transactions, block)| {
json!({
"block_identifier": block.block_identifier,
"parent_block_identifier": block.parent_block_identifier,
Expand All @@ -170,7 +206,7 @@ pub fn serialize_bitcoin_payload_to_json<'a>(
"metadata": block.metadata,
})
}).collect::<Vec<_>>(),
"rollback": trigger.rollback.into_iter().map(|(transactions, block)| {
"rollback": trigger.rollback.iter().map(|(transactions, block)| {
json!({
"block_identifier": block.block_identifier,
"parent_block_identifier": block.parent_block_identifier,
Expand Down Expand Up @@ -252,54 +288,27 @@ pub fn handle_bitcoin_hook_action<'a>(
.map_err(|e| format!("unable to build http client: {}", e.to_string()))?;
let host = format!("{}", http.url);
let method = Method::POST;
let body = serde_json::to_vec(&serialize_bitcoin_payload_to_json(trigger, proofs))
let body = serde_json::to_vec(&serialize_bitcoin_payload_to_json(&trigger, proofs))
.map_err(|e| format!("unable to serialize payload {}", e.to_string()))?;
Ok(BitcoinChainhookOccurrence::Http(
client
.request(method, &host)
.header("Content-Type", "application/json")
.header("Authorization", http.authorization_header.clone())
.body(body),
))
let request = client
.request(method, &host)
.header("Content-Type", "application/json")
.header("Authorization", http.authorization_header.clone())
.body(body);

let data = BitcoinChainhookOccurrencePayload::from_trigger(trigger);
Ok(BitcoinChainhookOccurrence::Http(request, data))
}
HookAction::FileAppend(disk) => {
let bytes = serde_json::to_vec(&serialize_bitcoin_payload_to_json(trigger, proofs))
let bytes = serde_json::to_vec(&serialize_bitcoin_payload_to_json(&trigger, proofs))
.map_err(|e| format!("unable to serialize payload {}", e.to_string()))?;
Ok(BitcoinChainhookOccurrence::File(
disk.path.to_string(),
bytes,
))
}
HookAction::Noop => Ok(BitcoinChainhookOccurrence::Data(
BitcoinChainhookOccurrencePayload {
apply: trigger
.apply
.into_iter()
.map(|(transactions, block)| {
let mut block = block.clone();
block.transactions = transactions
.into_iter()
.map(|t| t.clone())
.collect::<Vec<_>>();
BitcoinTransactionPayload { block }
})
.collect::<Vec<_>>(),
rollback: trigger
.rollback
.into_iter()
.map(|(transactions, block)| {
let mut block = block.clone();
block.transactions = transactions
.into_iter()
.map(|t| t.clone())
.collect::<Vec<_>>();
BitcoinTransactionPayload { block }
})
.collect::<Vec<_>>(),
chainhook: BitcoinChainhookPayload {
uuid: trigger.chainhook.uuid.clone(),
},
},
BitcoinChainhookOccurrencePayload::from_trigger(trigger),
)),
}
}
Expand Down
12 changes: 8 additions & 4 deletions components/chainhook-sdk/src/observer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,8 +1121,8 @@ pub async fn start_observer_commands_handler(
slog::error!(logger, "unable to handle action {}", e)
});
}
Ok(BitcoinChainhookOccurrence::Http(request)) => {
requests.push(request);
Ok(BitcoinChainhookOccurrence::Http(request, data)) => {
requests.push((request, data));
}
Ok(BitcoinChainhookOccurrence::File(_path, _bytes)) => {
ctx.try_log(|logger| {
Expand Down Expand Up @@ -1168,8 +1168,12 @@ pub async fn start_observer_commands_handler(
}
}

for request in requests.into_iter() {
let _ = send_request(request, 3, 1, &ctx).await;
for (request, data) in requests.into_iter() {
if send_request(request, 3, 1, &ctx).await.is_ok() {
if let Some(ref tx) = observer_events_tx {
let _ = tx.send(ObserverEvent::BitcoinPredicateTriggered(data));
}
}
}

if let Some(ref tx) = observer_events_tx {
Expand Down

0 comments on commit a6164ea

Please sign in to comment.