Browse Source

Use a better-id format

Cesar Rodas 1 year ago
parent
commit
bedcd3f371
6 changed files with 30 additions and 21 deletions
  1. 7 1
      Cargo.lock
  2. 1 1
      utxo/Cargo.toml
  3. 13 16
      utxo/src/id/binary.rs
  4. 6 0
      utxo/src/id/error.rs
  5. 2 2
      utxo/src/id/mod.rs
  6. 1 1
      utxo/src/transaction/revision.rs

+ 7 - 1
Cargo.lock

@@ -532,6 +532,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
 
 [[package]]
+name = "bech32"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
+
+[[package]]
 name = "bitflags"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3253,10 +3259,10 @@ name = "verax"
 version = "0.1.0"
 dependencies = [
  "async-trait",
+ "bech32",
  "borsh",
  "chrono",
  "futures",
- "hex",
  "rand 0.8.5",
  "serde",
  "sha2",

+ 1 - 1
utxo/Cargo.toml

@@ -5,10 +5,10 @@ edition = "2021"
 
 [dependencies]
 async-trait = "0.1.73"
+bech32 = "0.11.0"
 borsh = { version = "1.3.1", features = ["derive", "bytes", "de_strict_order"] }
 chrono = { version = "0.4.31", features = ["serde"] }
 futures = { version = "0.3.30", optional = true }
-hex = "0.4.3"
 serde = { version = "1.0.188", features = ["derive"] }
 sha2 = "0.10.7"
 sqlx = { version = "0.7.1", features = [

+ 13 - 16
utxo/src/id/binary.rs

@@ -61,25 +61,16 @@ macro_rules! BinaryId {
         impl TryFrom<&str> for $id {
             type Error = Error;
             fn try_from(value: &str) -> Result<Self, Self::Error> {
-                if $suffix.len() + 64 != value.len() {
-                    return Err(Error::InvalidLength(
-                        stringify!($id).to_owned(),
-                        value.len(),
-                        $suffix.len() + 64,
-                    ));
-                }
-
-                if !value.starts_with($suffix) {
-                    return Err(Error::InvalidLength(
+                let (hrp, bytes) = bech32::decode(&value)?;
+                let hrp = hrp.to_string();
+                if hrp != $suffix {
+                    return Err(Error::InvalidPrefix(
                         stringify!($id).to_owned(),
-                        value.len(),
-                        $suffix.len() + 64,
+                        $suffix.to_owned(),
+                        hrp,
                     ));
                 }
 
-                let bytes = hex::decode(&value[$suffix.len()..]).map_err(|_| {
-                    Error::InvalidLength(stringify!($id).to_owned(), value.len(), 32)
-                })?;
                 bytes.try_into()
             }
         }
@@ -120,7 +111,13 @@ macro_rules! BinaryId {
 
         impl Display for $id {
             fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-                write!(f, "{}{}", $suffix, hex::encode(self.bytes))
+                let hrp = bech32::Hrp::parse($suffix).map_err(|_| std::fmt::Error)?;
+                write!(
+                    f,
+                    "{}",
+                    bech32::encode::<bech32::Bech32m>(hrp, &self.bytes)
+                        .map_err(|_| std::fmt::Error)?
+                )
             }
         }
 

+ 6 - 0
utxo/src/id/error.rs

@@ -7,9 +7,15 @@ pub enum Error {
     #[error("Invalid length for {0}: {1} (expected: {2})")]
     InvalidLength(String, usize, usize),
 
+    #[error("Invalid prefix in {0}, expecting {1}, got {2}")]
+    InvalidPrefix(String, String, String),
+
     #[error("The string is too long (max length is {0}")]
     TooLong(usize),
 
     #[error("Invalid PaymentId: {0}")]
     InvalidPaymentId(#[from] ParseIntError),
+
+    #[error("Encoding issue: {0}")]
+    Bech32(#[from] bech32::DecodeError),
 }

+ 2 - 2
utxo/src/id/mod.rs

@@ -72,8 +72,8 @@ impl<'de, const MAX_LENGTH: usize> de::Deserialize<'de> for MaxLengthString<MAX_
 
 /// The AccountId data type
 pub type AccountId = MaxLengthString<64>;
-crate::BinaryId!(TxId, "tx-");
-crate::BinaryId!(RevId, "rev-");
+crate::BinaryId!(TxId, "tx");
+crate::BinaryId!(RevId, "rev");
 
 /// A generic ID wrapper
 ///

+ 1 - 1
utxo/src/transaction/revision.rs

@@ -11,7 +11,7 @@ pub struct Revision {
     pub transaction_id: TxId,
 
     /// Previous revision or None if this is the first revision
-    #[serde(rename = "_prev_rev")]
+    #[serde(rename = "_prev_rev", skip_serializing_if = "Option::is_none")]
     pub previous: Option<RevId>,
 
     /// A human-readable changelog for this revision