From 71364c15a88a06d5c71b3f3d3c88c489ff4733d1 Mon Sep 17 00:00:00 2001 From: Matthew Little Date: Thu, 24 Oct 2024 19:54:28 +0200 Subject: [PATCH] fix: update SignerMessage deserializing (#663) --- .vscode/chainhook.toml | 46 +++++++++++++++++++ .vscode/launch.json | 24 ++++++++++ Cargo.lock | 4 +- Cargo.toml | 2 +- .../src/chainhooks/stacks/mod.rs | 7 ++- .../chainhook-sdk/src/indexer/stacks/mod.rs | 18 +++++--- .../chainhook-sdk/src/indexer/stacks/tests.rs | 2 +- components/chainhook-types-rs/src/signers.rs | 16 ++++++- .../typescript/src/schemas/stacks/signers.ts | 20 +++++++- 9 files changed, 123 insertions(+), 16 deletions(-) create mode 100644 .vscode/chainhook.toml diff --git a/.vscode/chainhook.toml b/.vscode/chainhook.toml new file mode 100644 index 000000000..a01390bea --- /dev/null +++ b/.vscode/chainhook.toml @@ -0,0 +1,46 @@ +[storage] +working_dir = "cache" + +# The HTTP API allows you to register / deregister +# predicates dynamically. +# This is disabled by default. +# +[http_api] +http_port = 20456 +database_uri = "redis://localhost:6379/" + +[network] +mode = "testnet" +bitcoind_rpc_url = "http://localhost:18443" +bitcoind_rpc_username = "btc" +bitcoind_rpc_password = "btc" + +# Chainhook must be able to receive Bitcoin block events. +# These events can originate from either a Stacks node or a Bitcoin node's ZeroMQ interface. + +# By default, the service is set to receive Bitcoin block events from the Stacks node: +stacks_node_rpc_url = "http://localhost:20443" +stacks_events_ingestion_port = 20455 + +# However, events can also be received directly from a Bitcoin node. +# To achieve this, comment out the `stacks_node_rpc_url` line and uncomment the following line: +# bitcoind_zmq_url = "tcp://0.0.0.0:18543" + +[limits] +max_number_of_bitcoin_predicates = 100 +max_number_of_concurrent_bitcoin_scans = 100 +max_number_of_stacks_predicates = 10 +max_number_of_concurrent_stacks_scans = 10 +max_number_of_processing_threads = 16 +max_number_of_networking_threads = 16 +max_caching_memory_size_mb = 32000 + +# The TSV file is required for downloading historical data for your predicates. +# If this is not a requirement, you can comment out the `tsv_file_url` line. +# [[event_source]] +# tsv_file_url = "https://archive.hiro.so/regtest/stacks-blockchain-api/regtest-stacks-blockchain-api-latest" + +# Enables a server that provides metrics that can be scraped by Prometheus. +# This is disabled by default. +# [monitoring] +# prometheus_monitoring_port = 20457 diff --git a/.vscode/launch.json b/.vscode/launch.json index 448c74c77..9d0644e2c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,30 @@ { "version": "0.2.0", "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug executable 'chainhook'", + "cargo": { + "args": [ + "build", + "--bin=chainhook", + "--package=chainhook" + ], + "filter": { + "name": "chainhook", + "kind": "bin" + } + }, + "args": [ + "service", + "start", + "--config-path=${workspaceFolder}/.vscode/chainhook.toml", + ], + "cwd": "${workspaceFolder}", + "preLaunchTask": "redis:start", + "postDebugTask": "redis:stop" + }, { "type": "lldb", "request": "launch", diff --git a/Cargo.lock b/Cargo.lock index 23d5c23e3..989eeb269 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3549,8 +3549,8 @@ dependencies = [ [[package]] name = "stacks-codec" -version = "2.9.0" -source = "git+https://github.com/hirosystems/clarinet.git?rev=b0683675115562d719ed4b5245f620e0990030a0#b0683675115562d719ed4b5245f620e0990030a0" +version = "2.10.0" +source = "git+https://github.com/hirosystems/clarinet.git?rev=fcebfb5a986ded32d5a450c34f8e5e5f2da97de4#fcebfb5a986ded32d5a450c34f8e5e5f2da97de4" dependencies = [ "clarity", "serde", diff --git a/Cargo.toml b/Cargo.toml index e7694ce18..97b5fc91f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,4 +8,4 @@ default-members = ["components/chainhook-cli", "components/chainhook-sdk"] resolver = "2" [patch.crates-io] -stacks-codec = { git = "https://github.com/hirosystems/clarinet.git", rev = "b0683675115562d719ed4b5245f620e0990030a0" } +stacks-codec = { git = "https://github.com/hirosystems/clarinet.git", rev = "fcebfb5a986ded32d5a450c34f8e5e5f2da97de4" } diff --git a/components/chainhook-sdk/src/chainhooks/stacks/mod.rs b/components/chainhook-sdk/src/chainhooks/stacks/mod.rs index 1eb2c7fbf..a59344ea4 100644 --- a/components/chainhook-sdk/src/chainhooks/stacks/mod.rs +++ b/components/chainhook-sdk/src/chainhooks/stacks/mod.rs @@ -873,7 +873,10 @@ pub fn evaluate_stacks_predicate_on_non_consensus_events<'a>( | StacksPredicate::NftEvent(_) | StacksPredicate::StxEvent(_) | StacksPredicate::PrintEvent(_) - | StacksPredicate::Txid(_) => unreachable!(), + | StacksPredicate::Txid(_) => { + // Ignore, possibly expected behavior? + // https://github.com/hirosystems/chainhook/pull/663#discussion_r1814995429 + }, }; } (occurrences, expired_predicates) @@ -1107,7 +1110,7 @@ fn serialize_stacks_non_consensus_event( }; json!({ "payload": payload, - "received_at": event.received_at_ms, + "received_at_ms": event.received_at_ms, "received_at_block": event.received_at_block, }) } diff --git a/components/chainhook-sdk/src/indexer/stacks/mod.rs b/components/chainhook-sdk/src/indexer/stacks/mod.rs index 7478dddd8..7ebf90c16 100644 --- a/components/chainhook-sdk/src/indexer/stacks/mod.rs +++ b/components/chainhook-sdk/src/indexer/stacks/mod.rs @@ -714,10 +714,13 @@ pub fn standardize_stacks_stackerdb_chunks( }) } SignerMessage::BlockResponse(block_response) => match block_response { - BlockResponse::Accepted((block_hash, sig)) => StacksSignerMessage::BlockResponse( + BlockResponse::Accepted(block_accepted) => StacksSignerMessage::BlockResponse( BlockResponseData::Accepted(BlockAcceptedResponse { - signer_signature_hash: format!("0x{}", block_hash.to_hex()), - sig: format!("0x{}", sig.to_hex()), + signer_signature_hash: format!("0x{}", block_accepted.signer_signature_hash.to_hex()), + signature: format!("0x{}", block_accepted.signature.to_hex()), + metadata: SignerMessageMetadata { + server_version: block_accepted.metadata.server_version, + } }), ), BlockResponse::Rejected(block_rejection) => StacksSignerMessage::BlockResponse( @@ -725,8 +728,8 @@ pub fn standardize_stacks_stackerdb_chunks( reason: block_rejection.reason, reason_code: match block_rejection.reason_code { RejectCode::ValidationFailed(validate_reject_code) => { - BlockRejectReasonCode::ValidationFailed( - match validate_reject_code { + BlockRejectReasonCode::ValidationFailed { + validation_failed: match validate_reject_code { ValidateRejectCode::BadBlockHash => { BlockValidationFailedCode::BadBlockHash } @@ -749,7 +752,7 @@ pub fn standardize_stacks_stackerdb_chunks( BlockValidationFailedCode::NoSuchTenure } }, - ) + } } RejectCode::NoSortitionView => BlockRejectReasonCode::NoSortitionView, RejectCode::ConnectivityIssues => { @@ -769,6 +772,9 @@ pub fn standardize_stacks_stackerdb_chunks( ), chain_id: block_rejection.chain_id, signature: format!("0x{}", block_rejection.signature.to_hex()), + metadata: SignerMessageMetadata { + server_version: block_rejection.metadata.server_version, + }, }), ), }, diff --git a/components/chainhook-sdk/src/indexer/stacks/tests.rs b/components/chainhook-sdk/src/indexer/stacks/tests.rs index 493f6fd5e..f4a005c97 100644 --- a/components/chainhook-sdk/src/indexer/stacks/tests.rs +++ b/components/chainhook-sdk/src/indexer/stacks/tests.rs @@ -440,7 +440,7 @@ fn parses_block_response_signer_message() { match &message.message { StacksSignerMessage::BlockResponse(response) => match response { BlockResponseData::Accepted(accepted) => { - assert_eq!(accepted.sig, "0x00a1c66742e665e981d10f7a70a5df312c9cba729331129ff1b510e71133d79c0122b25266bf47e8c1c923b4fde0464756ced884030e9983f797c902961fc9b0b1"); + assert_eq!(accepted.signature, "0x00a1c66742e665e981d10f7a70a5df312c9cba729331129ff1b510e71133d79c0122b25266bf47e8c1c923b4fde0464756ced884030e9983f797c902961fc9b0b1"); assert_eq!( accepted.signer_signature_hash, "0x8f913dd2bcc2cfbd1c82166e0ad99230f76de098a5ba6ee1b15b042c8f67c6f0" diff --git a/components/chainhook-types-rs/src/signers.rs b/components/chainhook-types-rs/src/signers.rs index 131a32b67..c0754dd28 100644 --- a/components/chainhook-types-rs/src/signers.rs +++ b/components/chainhook-types-rs/src/signers.rs @@ -33,10 +33,17 @@ pub struct BlockProposalData { #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub struct BlockAcceptedResponse { pub signer_signature_hash: String, - pub sig: String, + pub signature: String, + pub metadata: SignerMessageMetadata, +} + +#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +pub struct SignerMessageMetadata { + pub server_version: String, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum BlockValidationFailedCode { BadBlockHash, BadTransaction, @@ -50,7 +57,11 @@ pub enum BlockValidationFailedCode { #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum BlockRejectReasonCode { - ValidationFailed(BlockValidationFailedCode), + #[serde(rename_all = "SCREAMING_SNAKE_CASE")] + ValidationFailed { + #[serde(rename = "VALIDATION_FAILED")] + validation_failed: BlockValidationFailedCode, + }, ConnectivityIssues, RejectedInPriorRound, NoSortitionView, @@ -65,6 +76,7 @@ pub struct BlockRejectedResponse { pub signer_signature_hash: String, pub chain_id: u32, pub signature: String, + pub metadata: SignerMessageMetadata, } #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] diff --git a/components/client/typescript/src/schemas/stacks/signers.ts b/components/client/typescript/src/schemas/stacks/signers.ts index caa0e2e3a..7b9ceeb8f 100644 --- a/components/client/typescript/src/schemas/stacks/signers.ts +++ b/components/client/typescript/src/schemas/stacks/signers.ts @@ -40,7 +40,10 @@ export const StacksSignerMessageBlockResponseAcceptedSchema = Type.Object({ type: Type.Literal('Accepted'), data: Type.Object({ signer_signature_hash: Type.String(), - sig: Type.String(), + signature: Type.String(), + metadata: Type.Object({ + server_version: Type.String(), + }), }), }); export type StacksSignerMessageBlockResponseAccepted = Static< @@ -52,7 +55,17 @@ export const StacksSignerMessageBlockResponseRejectedSchema = Type.Object({ data: Type.Object({ reason: Type.String(), reason_code: Type.Union([ - Type.Literal('VALIDATION_FAILED'), + Type.Object({ + VALIDATION_FAILED: Type.Union([ + Type.Literal('BAD_BLOCK_HASH'), + Type.Literal('BAD_TRANSACTION'), + Type.Literal('INVALID_BLOCK'), + Type.Literal('CHAINSTATE_ERROR'), + Type.Literal('UNKNOWN_PARENT'), + Type.Literal('NON_CANONICAL_TENURE'), + Type.Literal('NO_SUCH_TENURE'), + ]), + }), Type.Literal('CONNECTIVITY_ISSUES'), Type.Literal('REJECTED_IN_PRIOR_ROUND'), Type.Literal('NO_SORTITION_VIEW'), @@ -62,6 +75,9 @@ export const StacksSignerMessageBlockResponseRejectedSchema = Type.Object({ signer_signature_hash: Type.String(), chain_id: Type.Integer(), signature: Type.String(), + metadata: Type.Object({ + server_version: Type.String(), + }), }), }); export type StacksSignerMessageBlockResponseRejected = Static<