move message parsing and change webhook
This commit is contained in:
Generated
+1
-1
@@ -5739,7 +5739,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-data-observatory"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
||||
@@ -11,17 +11,13 @@ use crate::storage::transaction::PostgresStorageTransaction;
|
||||
use async_trait::async_trait;
|
||||
use nyxd_scraper_shared::storage::helpers::log_db_operation_time;
|
||||
use nyxd_scraper_shared::storage::{NyxdScraperStorage, NyxdScraperStorageError};
|
||||
use nyxd_scraper_shared::{default_message_registry, MessageRegistry};
|
||||
use sqlx::types::time::{OffsetDateTime, PrimitiveDateTime};
|
||||
use tokio::time::Instant;
|
||||
use tracing::{debug, error, info, instrument};
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PostgresScraperStorage {
|
||||
pub(crate) manager: StorageManager,
|
||||
|
||||
// kinda like very limited cosmos sdk codec
|
||||
pub(crate) message_registry: MessageRegistry,
|
||||
}
|
||||
|
||||
impl PostgresScraperStorage {
|
||||
@@ -41,8 +37,8 @@ impl PostgresScraperStorage {
|
||||
.run(&connection_pool)
|
||||
.await
|
||||
{
|
||||
error!("Failed to initialize SQLx database: {err}");
|
||||
return Err(err.into());
|
||||
warn!("Failed to initialize SQLx database: {err}");
|
||||
// return Err(err.into());
|
||||
}
|
||||
|
||||
info!("Database migration finished!");
|
||||
@@ -50,10 +46,7 @@ impl PostgresScraperStorage {
|
||||
let manager = StorageManager { connection_pool };
|
||||
manager.set_initial_metadata().await?;
|
||||
|
||||
let storage = PostgresScraperStorage {
|
||||
manager,
|
||||
message_registry: default_message_registry(),
|
||||
};
|
||||
let storage = PostgresScraperStorage { manager };
|
||||
|
||||
Ok(storage)
|
||||
}
|
||||
@@ -94,10 +87,7 @@ impl PostgresScraperStorage {
|
||||
.connection_pool
|
||||
.begin()
|
||||
.await
|
||||
.map(|inner| PostgresStorageTransaction {
|
||||
inner,
|
||||
registry: self.message_registry.clone(),
|
||||
})
|
||||
.map(|inner| PostgresStorageTransaction { inner })
|
||||
.map_err(|source| PostgresScraperError::StorageTxBeginFailure { source })
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ use nyxd_scraper_shared::storage::validators::Response;
|
||||
use nyxd_scraper_shared::storage::{
|
||||
validators, Block, Commit, CommitSig, NyxdScraperStorageError, NyxdScraperTransaction,
|
||||
};
|
||||
use nyxd_scraper_shared::{Any, MessageRegistry, ParsedTransactionResponse};
|
||||
use nyxd_scraper_shared::ParsedTransactionResponse;
|
||||
use serde_json::{json, Value};
|
||||
use sqlx::types::time::{OffsetDateTime, PrimitiveDateTime};
|
||||
use sqlx::{Postgres, Transaction};
|
||||
@@ -30,8 +30,6 @@ use tracing::{debug, trace, warn};
|
||||
|
||||
pub struct PostgresStorageTransaction {
|
||||
pub(super) inner: Transaction<'static, Postgres>,
|
||||
|
||||
pub(super) registry: MessageRegistry,
|
||||
}
|
||||
|
||||
impl Deref for PostgresStorageTransaction {
|
||||
@@ -48,16 +46,6 @@ impl DerefMut for PostgresStorageTransaction {
|
||||
}
|
||||
|
||||
impl PostgresStorageTransaction {
|
||||
fn decode_or_skip(&self, msg: &Any) -> Option<serde_json::Value> {
|
||||
match self.registry.try_decode(msg) {
|
||||
Ok(decoded) => Some(decoded),
|
||||
Err(err) => {
|
||||
warn!("{err}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn persist_validators(
|
||||
&mut self,
|
||||
validators: &validators::Response,
|
||||
@@ -169,11 +157,9 @@ impl PostgresStorageTransaction {
|
||||
.collect();
|
||||
|
||||
let messages = chain_tx
|
||||
.tx
|
||||
.body
|
||||
.messages
|
||||
.iter()
|
||||
.filter_map(|msg| self.decode_or_skip(msg))
|
||||
.parsed_messages
|
||||
.values()
|
||||
.map(|v| v.clone())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let signer_infos = chain_tx
|
||||
@@ -220,7 +206,8 @@ impl PostgresStorageTransaction {
|
||||
let mut wasm_message_type: Option<String> = None;
|
||||
let mut funds: Option<Vec<Coin>> = None;
|
||||
|
||||
let value = serde_json::to_value(self.decode_or_skip(msg))?;
|
||||
let parsed_message = chain_tx.parsed_messages.get(&index);
|
||||
let value = serde_json::to_value(parsed_message)?;
|
||||
|
||||
if msg.type_url == "/cosmwasm.wasm.v1.MsgExecuteContract" {
|
||||
if let Ok(wasm_execute) = MsgExecuteContract::decode(msg.value.as_ref()) {
|
||||
@@ -270,7 +257,7 @@ impl PostgresStorageTransaction {
|
||||
}
|
||||
|
||||
fn get_first_field_name(value: &Value) -> Option<String> {
|
||||
debug!("value:\n{value}");
|
||||
trace!("value:\n{value}");
|
||||
match value.as_object() {
|
||||
Some(map) => map.keys().next().cloned(),
|
||||
None => None,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
use crate::error::ScraperError;
|
||||
use crate::helpers;
|
||||
use std::collections::HashMap;
|
||||
use tendermint::{Block, Hash, abci, block, tx};
|
||||
use tendermint_rpc::endpoint::{block as block_endpoint, block_results, validators};
|
||||
use tendermint_rpc::event::{Event, EventData};
|
||||
@@ -26,6 +27,8 @@ pub struct ParsedTransactionResponse {
|
||||
pub tx: cosmrs::tx::Tx,
|
||||
|
||||
pub proof: Option<tx::Proof>,
|
||||
|
||||
pub parsed_messages: HashMap<usize, serde_json::Value>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
@@ -6,15 +6,16 @@ use crate::block_processor::types::{
|
||||
};
|
||||
use crate::error::ScraperError;
|
||||
use crate::helpers::tx_hash;
|
||||
use crate::{default_message_registry, Any, MessageRegistry};
|
||||
use futures::StreamExt;
|
||||
use futures::future::join3;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::sync::Arc;
|
||||
use tendermint::Hash;
|
||||
use tendermint_rpc::endpoint::{block, block_results, tx, validators};
|
||||
use tendermint_rpc::{Client, HttpClient, Paging};
|
||||
use tokio::sync::Mutex;
|
||||
use tracing::{debug, instrument};
|
||||
use tracing::{debug, instrument, warn};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -22,6 +23,9 @@ pub struct RpcClient {
|
||||
// right now I don't care about anything nym specific, so a simple http client is sufficient,
|
||||
// once this is inadequate, we can switch to a NyxdClient
|
||||
inner: Arc<HttpClient>,
|
||||
|
||||
// kinda like very limited cosmos sdk codec
|
||||
pub(crate) message_registry: MessageRegistry,
|
||||
}
|
||||
|
||||
impl RpcClient {
|
||||
@@ -35,9 +39,20 @@ impl RpcClient {
|
||||
|
||||
Ok(RpcClient {
|
||||
inner: Arc::new(http_client),
|
||||
message_registry: default_message_registry(),
|
||||
})
|
||||
}
|
||||
|
||||
fn decode_or_skip(&self, msg: &Any) -> Option<serde_json::Value> {
|
||||
match self.message_registry.try_decode(msg) {
|
||||
Ok(decoded) => Some(decoded),
|
||||
Err(err) => {
|
||||
warn!("Failed to decode raw message: {err}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, block), fields(height = block.height))]
|
||||
pub async fn try_get_full_details(
|
||||
&self,
|
||||
@@ -56,19 +71,29 @@ impl RpcClient {
|
||||
|
||||
let raw_transactions = raw_transactions?;
|
||||
let mut transactions = Vec::with_capacity(raw_transactions.len());
|
||||
for tx in raw_transactions {
|
||||
for raw_tx in raw_transactions {
|
||||
let mut parsed_messages = HashMap::new();
|
||||
let tx = cosmrs::Tx::from_bytes(&raw_tx.tx).map_err(|source| {
|
||||
ScraperError::TxParseFailure {
|
||||
hash: raw_tx.hash,
|
||||
source,
|
||||
}
|
||||
})?;
|
||||
|
||||
for (index, msg) in tx.body.messages.iter().enumerate() {
|
||||
if let Some(value) = self.decode_or_skip(msg) {
|
||||
parsed_messages.insert(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
transactions.push(ParsedTransactionResponse {
|
||||
hash: tx.hash,
|
||||
height: tx.height,
|
||||
index: tx.index,
|
||||
tx_result: tx.tx_result,
|
||||
tx: cosmrs::Tx::from_bytes(&tx.tx).map_err(|source| {
|
||||
ScraperError::TxParseFailure {
|
||||
hash: tx.hash,
|
||||
source,
|
||||
}
|
||||
})?,
|
||||
proof: tx.proof,
|
||||
hash: raw_tx.hash,
|
||||
height: raw_tx.height,
|
||||
index: raw_tx.index,
|
||||
tx_result: raw_tx.tx_result,
|
||||
tx,
|
||||
proof: raw_tx.proof,
|
||||
parsed_messages,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-data-observatory"
|
||||
version = "0.1.0"
|
||||
version = "1.0.0"
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
@@ -11,7 +11,6 @@ documentation.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
readme.workspace = true
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
|
||||
@@ -9,14 +9,12 @@ use nym_validator_client::nyxd::{Any, Msg, MsgSend, Name};
|
||||
use nyxd_scraper_psql::{
|
||||
MsgModule, NyxdScraperTransaction, ParsedTransactionResponse, ScraperError,
|
||||
};
|
||||
use nyxd_scraper_shared::{default_message_registry, MessageRegistry};
|
||||
use reqwest::{Client, Url};
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::{error, info};
|
||||
use utoipa::gen::serde_json;
|
||||
|
||||
pub struct WebhookModule {
|
||||
webhooks: Vec<Webhook>,
|
||||
registry: MessageRegistry,
|
||||
}
|
||||
|
||||
impl WebhookModule {
|
||||
@@ -27,20 +25,7 @@ impl WebhookModule {
|
||||
.iter()
|
||||
.map(|watcher_cfg| Webhook::new(watcher_cfg.clone()))
|
||||
.collect::<anyhow::Result<Vec<_>>>()?;
|
||||
Ok(Self {
|
||||
webhooks,
|
||||
registry: default_message_registry(),
|
||||
})
|
||||
}
|
||||
|
||||
fn decode_or_skip(&self, msg: &Any) -> Option<serde_json::Value> {
|
||||
match self.registry.try_decode(msg) {
|
||||
Ok(decoded) => Some(decoded),
|
||||
Err(err) => {
|
||||
warn!("webhook processing failed {err}");
|
||||
None
|
||||
}
|
||||
}
|
||||
Ok(Self { webhooks })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,11 +38,11 @@ impl MsgModule for WebhookModule {
|
||||
async fn handle_msg(
|
||||
&mut self,
|
||||
index: usize,
|
||||
msg: &Any,
|
||||
_msg: &Any,
|
||||
tx: &ParsedTransactionResponse,
|
||||
_storage_tx: &mut dyn NyxdScraperTransaction,
|
||||
) -> Result<(), ScraperError> {
|
||||
let message = serde_json::to_value(self.decode_or_skip(msg)).ok();
|
||||
let message = serde_json::to_value(tx.parsed_messages.get(&index)).ok();
|
||||
|
||||
let payload = WebhookPayload {
|
||||
height: tx.height.value(),
|
||||
@@ -66,6 +51,11 @@ impl MsgModule for WebhookModule {
|
||||
message,
|
||||
};
|
||||
|
||||
println!(
|
||||
"->>>>>>>>>>>>>>>>>>>>>>>>> {}",
|
||||
serde_json::to_string(&payload).unwrap()
|
||||
);
|
||||
|
||||
for webhook in self.webhooks.clone() {
|
||||
let payload = payload.clone();
|
||||
tokio::spawn(async move {
|
||||
|
||||
Reference in New Issue
Block a user