Skip to content

Commit

Permalink
feat: match on all print_events if contract_identifier is None (#…
Browse files Browse the repository at this point in the history
…356)

This PR fixes #294 by making the `contract_identifier` and `contains`
fields on the `print_event` stacks predicate optional. If the
`contract_identifier` value is not provided, all `print_event` values
are checked for a match. If the `contains` value is not provided, all
event values are considered a match.
  • Loading branch information
MicaiahReid authored Aug 2, 2023
1 parent ebf8762 commit bc5d0e2
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 26 deletions.
8 changes: 4 additions & 4 deletions components/chainhook-cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,8 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
end_block: Some(50000),
blocks: None,
predicate: StacksPredicate::PrintEvent(StacksPrintEventBasedPredicate {
contract_identifier: "ST1SVA0SST0EDT4MFYGWGP6GNSXMMQJDVP1G8QTTC.arkadiko-freddie-v1-1".into(),
contains: "vault".into(),
contract_identifier: Some("ST1SVA0SST0EDT4MFYGWGP6GNSXMMQJDVP1G8QTTC.arkadiko-freddie-v1-1".into()),
contains: Some("vault".into()),
}),
expire_after_occurrence: None,
capture_all_events: None,
Expand All @@ -356,8 +356,8 @@ async fn handle_command(opts: Opts, ctx: Context) -> Result<(), String> {
end_block: Some(50000),
blocks: None,
predicate: StacksPredicate::PrintEvent(StacksPrintEventBasedPredicate {
contract_identifier: "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-freddie-v1-1".into(),
contains: "vault".into(),
contract_identifier: Some("SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-freddie-v1-1".into()),
contains: Some("vault".into()),
}),
expire_after_occurrence: None,
capture_all_events: None,
Expand Down
5 changes: 4 additions & 1 deletion components/chainhook-cli/src/service/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,10 @@ async fn it_handles_stacks_predicates_with_network(network: &str) {
#[test_case(json!({"scope":"block_height", "between": [100,102]}); "with scope block_height between match")]
#[test_case(json!({"scope":"contract_deployment", "deployer": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM"}); "with scope contract_deployment type deployer")]
#[test_case(json!({"scope":"contract_call","contract_identifier": "SP000000000000000000002Q6VF78.pox","method": "stack-stx"}); "with scope contract_call")]
#[test_case(json!({"scope":"print_event","contract_identifier": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.monkey-sip09","contains": "vault"}); "with scope print_event")]
#[test_case(json!({"scope":"print_event","contract_identifier": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.monkey-sip09","contains": "vault"}); "with scope print_event both fields")]
#[test_case(json!({"scope":"print_event","contract_identifier": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.monkey-sip09"}); "with scope print_event just contract_identifier")]
#[test_case(json!({"scope":"print_event","contains": "vault"}); "with scope print_event just contains")]
#[test_case(json!({"scope":"print_event"}); "with scope print_event no fields")]
#[test_case(json!({"scope":"ft_event","asset_identifier": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.cbtc-token::cbtc","actions": ["burn"]}); "with scope ft_event")]
#[test_case(json!({"scope":"nft_event","asset_identifier": "ST1PQHQKV0RJXZFY1DGX8MNSNYVE3VGZJSRTPGZGM.monkey-sip09::monkeys","actions": ["mint", "transfer", "burn"]}); "with scope nft_event")]
#[test_case(json!({"scope":"stx_event","actions": ["transfer", "lock"]}); "with scope stx_event")]
Expand Down
28 changes: 23 additions & 5 deletions components/chainhook-sdk/src/chainhooks/stacks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ pub fn evaluate_stacks_predicate_on_transaction<'a>(
expected_deployer,
)) => match &transaction.metadata.kind {
StacksTransactionKind::ContractDeployment(actual_deployment) => {
if expected_deployer.eq("*") {
true
} else {
if let Some(expected_deployer) = expected_deployer {
actual_deployment
.contract_identifier
.starts_with(expected_deployer)
} else {
true
}
}
_ => false,
Expand Down Expand Up @@ -386,10 +386,28 @@ pub fn evaluate_stacks_predicate_on_transaction<'a>(
for event in transaction.metadata.receipt.events.iter() {
match event {
StacksTransactionEvent::SmartContractEvent(actual) => {
if actual.contract_identifier == expected_event.contract_identifier {
// if the predicate doesn't specify a contract identifier, check every event's values
// if the predicate doesn't specify a contains, match all values
if let Some(contract_identifier) = &expected_event.contract_identifier {
if &actual.contract_identifier == contract_identifier {
let value =
format!("{}", expect_decoded_clarity_value(&actual.hex_value));
if let Some(contains) = &expected_event.contains {
if value.contains(contains) {
return true;
}
} else {
return true;
}
}
} else {
let value =
format!("{}", expect_decoded_clarity_value(&actual.hex_value));
if value.contains(&expected_event.contains) {
if let Some(contains) = &expected_event.contains {
if value.contains(contains) {
return true;
}
} else {
return true;
}
}
Expand Down
22 changes: 14 additions & 8 deletions components/chainhook-sdk/src/chainhooks/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
use chainhook_types::{StacksChainEvent, StacksChainUpdatedWithBlocksData, StacksBlockUpdate};
use super::{
stacks::evaluate_stacks_chainhooks_on_chain_event,
types::{StacksChainhookSpecification, StacksPrintEventBasedPredicate},
};
use crate::chainhooks::types::{HookAction, StacksPredicate};
use crate::utils::Context;
use chainhook_types::StacksNetwork;
use crate::chainhooks::types::{StacksPredicate, HookAction};
use super::{stacks::evaluate_stacks_chainhooks_on_chain_event, types::{StacksChainhookSpecification, StacksPrintEventBasedPredicate}};
use chainhook_types::{StacksBlockUpdate, StacksChainEvent, StacksChainUpdatedWithBlocksData};

pub mod fixtures;

Expand All @@ -15,7 +18,7 @@ fn test_stacks_predicate_print_event() {
parent_microblocks_to_apply: vec![],
parent_microblocks_to_rollback: vec![],
}],
confirmed_blocks: vec![]
confirmed_blocks: vec![],
});

// Prepare predicate
Expand All @@ -32,14 +35,17 @@ fn test_stacks_predicate_print_event() {
capture_all_events: None,
decode_clarity_values: None,
predicate: StacksPredicate::PrintEvent(StacksPrintEventBasedPredicate {
contract_identifier: "ST3AXH4EBHD63FCFPTZ8GR29TNTVWDYPGY0KDY5E5.loan-data".to_string(),
contains: "set-loan".to_string(),
contract_identifier: Some(
"ST3AXH4EBHD63FCFPTZ8GR29TNTVWDYPGY0KDY5E5.loan-data".to_string(),
),
contains: Some("set-loan".to_string()),
}),
action: HookAction::Noop,
enabled: true,
};

let predicates = vec![&print_predicate];
let (triggered, _blocks) = evaluate_stacks_chainhooks_on_chain_event(&event, predicates, &Context::empty());
let (triggered, _blocks) =
evaluate_stacks_chainhooks_on_chain_event(&event, predicates, &Context::empty());
assert_eq!(triggered.len(), 1);
}
}
8 changes: 5 additions & 3 deletions components/chainhook-sdk/src/chainhooks/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -762,16 +762,18 @@ pub struct StacksContractCallBasedPredicate {
#[serde(rename_all = "snake_case")]
// #[serde(tag = "type", content = "rule")]
pub enum StacksContractDeploymentPredicate {
Deployer(String),
Deployer(Option<String>),
ImplementSip09,
ImplementSip10,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct StacksPrintEventBasedPredicate {
pub contract_identifier: String,
pub contains: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contract_identifier: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contains: Option<String>,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, JsonSchema)]
Expand Down
10 changes: 5 additions & 5 deletions docs/chainhook-openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"openapi": "3.0.0",
"info": {
"title": "chainhook",
"version": "0.16.0"
"version": "0.17.0"
},
"paths": {
"/ping": {
Expand Down Expand Up @@ -993,8 +993,6 @@
{
"type": "object",
"required": [
"contains",
"contract_identifier",
"scope"
],
"properties": {
Expand All @@ -1005,10 +1003,12 @@
]
},
"contract_identifier": {
"type": "string"
"type": "string",
"nullable": true
},
"contains": {
"type": "string"
"type": "string",
"nullable": true
}
}
},
Expand Down

0 comments on commit bc5d0e2

Please sign in to comment.