From 899f3e6ea48c0ebcc9282f527b747af07119b7bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=BAc=C3=A1s=20Meier?= Date: Thu, 25 Jul 2024 17:42:38 -0700 Subject: [PATCH] fix(pindexer): correct encoding of Amount into Postgres (#4772) I tried and tried to actually use Numeric directly in a smart way, instead the hack is to just cast text into it in the SQL query. Oh well. ## Checklist before requesting a review - [x] If this code contains consensus-breaking changes, I have added the "consensus-breaking" label. Otherwise, I declare my belief that there are not consensus-breaking changes, for the following reason: > pindexer bug fix --- Cargo.lock | 15 -------------- crates/bin/pindexer/Cargo.toml | 2 +- crates/bin/pindexer/src/dex/mod.rs | 22 ++++++++++---------- crates/bin/pindexer/src/sql.rs | 32 +----------------------------- 4 files changed, 13 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 208726b8a4..c2c790b52b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -761,17 +761,6 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "bincode" version = "1.3.3" @@ -7362,7 +7351,6 @@ checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" dependencies = [ "ahash", "atoi", - "bigdecimal", "byteorder", "bytes", "chrono", @@ -7446,7 +7434,6 @@ checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" dependencies = [ "atoi", "base64 0.21.7", - "bigdecimal", "bitflags 2.6.0", "byteorder", "bytes", @@ -7490,7 +7477,6 @@ checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" dependencies = [ "atoi", "base64 0.21.7", - "bigdecimal", "bitflags 2.6.0", "byteorder", "chrono", @@ -7509,7 +7495,6 @@ dependencies = [ "log", "md-5", "memchr", - "num-bigint", "once_cell", "rand", "serde", diff --git a/crates/bin/pindexer/Cargo.toml b/crates/bin/pindexer/Cargo.toml index a02dae2b84..5d2c82c7ec 100644 --- a/crates/bin/pindexer/Cargo.toml +++ b/crates/bin/pindexer/Cargo.toml @@ -24,5 +24,5 @@ penumbra-asset = {workspace = true, default-features = false} penumbra-proto = {workspace = true, default-features = false} tokio = {workspace = true, features = ["full"]} serde_json = {workspace = true} -sqlx = { workspace = true, features = ["bigdecimal", "chrono", "postgres"] } +sqlx = { workspace = true, features = ["chrono", "postgres"] } tracing = {workspace = true} diff --git a/crates/bin/pindexer/src/dex/mod.rs b/crates/bin/pindexer/src/dex/mod.rs index 18884bbc96..1409f965c0 100644 --- a/crates/bin/pindexer/src/dex/mod.rs +++ b/crates/bin/pindexer/src/dex/mod.rs @@ -56,11 +56,11 @@ impl Event { sqlx::query( r#" INSERT INTO dex_value_circuit_breaker_change - VALUES ($1, $2); + VALUES ($1, CAST($2 AS Amount)); "#, ) .bind(Sql::from(*asset_id)) - .bind(Sql::from(amount)) + .bind(amount.to_string()) .execute(dbtx.as_mut()) .await?; Ok(()) @@ -78,11 +78,11 @@ impl Event { sqlx::query( r#" INSERT INTO dex_value_circuit_breaker_change - VALUES ($1, -$2); + VALUES ($1, -(CAST($2 AS Amount))); "#, ) .bind(Sql::from(*asset_id)) - .bind(Sql::from(amount)) + .bind(amount.to_string()) .execute(dbtx.as_mut()) .await?; Ok(()) @@ -94,10 +94,10 @@ impl Event { let mut step_start = None; let mut step_end = None; for step in trace { - let (id,): (i64,) = sqlx::query_as( - r#"INSERT INTO trace_step VALUES (DEFAULT, ($1, $2)) RETURNING id;"#, + let (id,): (i32,) = sqlx::query_as( + r#"INSERT INTO trace_step VALUES (DEFAULT, (CAST($1 AS Amount), $2)) RETURNING id;"#, ) - .bind(Sql::from(step.amount)) + .bind(step.amount.to_string()) .bind(Sql::from(step.asset_id)) .fetch_one(dbtx.as_mut()) .await?; @@ -106,7 +106,7 @@ impl Event { } step_end = Some(id); } - let (id,): (i64,) = sqlx::query_as( + let (id,): (i32,) = sqlx::query_as( r#"INSERT INTO trace VALUES (DEFAULT, $1, $2) RETURNING id;"#, ) .bind(step_start) @@ -118,11 +118,11 @@ impl Event { } trace_end = Some(id); } - sqlx::query(r#"INSERT INTO arb VALUES ($1, ($2, $3), ($4, $5), $6, $7);"#) + sqlx::query(r#"INSERT INTO arb VALUES ($1, (CAST($2 AS Amount), $3), (CAST($4 AS AMOUNT), $5), $6, $7);"#) .bind(i64::try_from(*height)?) - .bind(Sql::from(execution.input.amount)) + .bind(execution.input.amount.to_string()) .bind(Sql::from(execution.input.asset_id)) - .bind(Sql::from(execution.output.amount)) + .bind(execution.output.amount.to_string()) .bind(Sql::from(execution.output.asset_id)) .bind(trace_start) .bind(trace_end) diff --git a/crates/bin/pindexer/src/sql.rs b/crates/bin/pindexer/src/sql.rs index d36d566ab6..9d17faa978 100644 --- a/crates/bin/pindexer/src/sql.rs +++ b/crates/bin/pindexer/src/sql.rs @@ -1,10 +1,7 @@ use std::error::Error; -use anyhow::anyhow; -use num_bigint::{BigInt, Sign}; use penumbra_asset::asset::Id as AssetId; -use penumbra_num::Amount; -use sqlx::{types::BigDecimal, Decode, Encode, Postgres, Type}; +use sqlx::{Decode, Encode, Postgres, Type}; /// An extension trait to make it easier to implement serialization for existing Penumbra types. /// @@ -74,33 +71,6 @@ where } } -impl SqlExt for Amount { - type SqlT = BigDecimal; - - fn to_sql_type(&self) -> Self::SqlT { - BigDecimal::from(BigInt::from_bytes_le( - Sign::Plus, - self.to_le_bytes().as_slice(), - )) - } - - fn from_sql_type(value: Self::SqlT) -> anyhow::Result { - if !value.is_integer() { - return Err(anyhow!("database value is not an integer").into()); - } - let big_int = value.as_bigint_and_exponent().0; - // Get the bytes only from a positive BigInt - let bytes = match big_int.to_bytes_le() { - (Sign::Plus | Sign::NoSign, bytes) => bytes, - (Sign::Minus, bytes) => bytes, - }; - let bytes: [u8; 16] = bytes - .try_into() - .map_err(|_| anyhow!("failed to convert slice to 16 bytes"))?; - Ok(Amount::from_le_bytes(bytes)) - } -} - impl SqlExt for AssetId { type SqlT = [u8; 32];