Skip to content

Commit fcf341e

Browse files
authored
fix(cat-gateway): regex and parse param (#2514)
* fix(cat-gateway): regex and parse param Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): asset name Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): bin data and code format Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): test dat for catid or stake address Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): use regex for pre check Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): format Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): asset name condition Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): format + schema Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): revert change Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): regex bin data Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): revert back to policy hash Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): regex Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): typo Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): format Signed-off-by: bkioshn <[email protected]> * fix(cat-gateway): regex Signed-off-by: bkioshn <[email protected]> --------- Signed-off-by: bkioshn <[email protected]>
1 parent 54195bf commit fcf341e

File tree

20 files changed

+436
-147
lines changed

20 files changed

+436
-147
lines changed

catalyst-gateway/bin/src/db/index/block/txo/insert_txo_asset.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ pub(crate) struct Params {
2929
txn_index: DbTxnIndex,
3030
/// Transaction Output Offset inside the transaction.
3131
txo: DbTxnOutputOffset,
32-
/// Policy hash of the asset
32+
/// Asset policy hash (28 bytes).
3333
policy_id: Vec<u8>,
34-
/// Name of the asset, within the Policy.
34+
/// Asset name (range of 0 - 32 bytes).
3535
asset_name: Vec<u8>,
3636
/// Value of the asset
3737
value: num_bigint::BigInt,

catalyst-gateway/bin/src/db/index/block/txo/insert_unstaked_txo_asset.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ pub(crate) struct Params {
2525
txn_id: DbTransactionId,
2626
/// Transaction Output Offset inside the transaction.
2727
txo: DbTxnOutputOffset,
28-
/// Policy hash of the asset
28+
/// Asset policy hash (28 bytes).
2929
policy_id: Vec<u8>,
30-
/// Policy name of the asset
30+
/// Asset name (range of 0 - 32 bytes).
3131
asset_name: Vec<u8>,
3232
/// Block Slot Number
3333
slot_no: DbSlot,

catalyst-gateway/bin/src/db/index/queries/purge/txo_assets.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ pub(crate) struct Params {
5151
pub(crate) txn_index: DbTxnIndex,
5252
/// Transaction Output Offset inside the transaction.
5353
pub(crate) txo: DbTxnOutputOffset,
54-
/// Asset Policy Hash - Binary 28 bytes.
54+
/// Asset policy hash (28 bytes).
5555
policy_id: Vec<u8>,
56-
/// Name of the asset, within the Policy.
56+
/// Asset name (range of 0 - 32 bytes).
5757
asset_name: Vec<u8>,
5858
}
5959

catalyst-gateway/bin/src/db/index/queries/purge/unstaked_txo_assets.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ pub(crate) struct Params {
4646
pub(crate) txn_id: DbTransactionId,
4747
/// Offset in the txo list of the transaction the txo is in.
4848
pub(crate) txo: DbTxnOutputOffset,
49-
/// Asset Policy Hash - Binary 28 bytes.
49+
/// Asset policy hash (28 bytes).
5050
pub(crate) policy_id: Vec<u8>,
51-
/// Name of the asset, within the Policy.
51+
/// Asset name (range of 0 - 32 bytes).
5252
pub(crate) asset_name: Vec<u8>,
5353
}
5454

catalyst-gateway/bin/src/db/index/queries/staked_ada/get_assets_by_stake_address.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ pub(crate) struct GetAssetsByStakeAddressQuery {
4848
pub txo: DbTxnOutputOffset,
4949
/// TXO transaction slot number.
5050
pub slot_no: DbSlot,
51-
/// Asset hash.
51+
/// Asset policy hash (28 bytes).
5252
pub policy_id: Vec<u8>,
53-
/// Asset name.
53+
/// Asset name (range of 0 - 32 bytes)
5454
pub asset_name: Vec<u8>,
5555
/// Asset value.
5656
pub value: num_bigint::BigInt,

catalyst-gateway/bin/src/db/index/schema/cql/txo_assets_by_stake_table.cql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ CREATE TABLE IF NOT EXISTS txo_assets_by_stake (
77
txn_index smallint, -- Which Transaction in the Slot is the TXO.
88
txo smallint, -- offset in the txo list of the transaction the txo is in.
99
policy_id blob, -- asset policy hash (id) (28 byte binary hash)
10-
asset_name blob, -- name of the asset policy (UTF8) (32 bytes)
10+
asset_name blob, -- name of the asset policy (UTF8) (0 - 32 bytes)
1111

1212

1313
-- None Key Data of the asset.

catalyst-gateway/bin/src/db/index/schema/cql/unstaked_txo_assets_by_txn_id.cql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ CREATE TABLE IF NOT EXISTS unstaked_txo_assets_by_txn_id (
44
txn_id blob, -- 32 byte hash of this transaction.
55
txo smallint, -- offset in the txo list of the transaction the txo is in.
66
policy_id blob, -- asset policy hash (id) (28 byte binary hash)
7-
asset_name blob, -- name of the policy (UTF8) (32 bytes)
7+
asset_name blob, -- name of the policy (UTF8) (0 - 32 bytes)
88

99
-- Secondary Location information for the transaction.
1010
slot_no varint, -- slot number the txo was created in.

catalyst-gateway/bin/src/service/api/cardano/rbac/registrations_get/binary_data.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use poem_openapi::{
66
registry::{MetaSchema, MetaSchemaRef},
77
types::{Example, ParseError, ParseFromJSON, ParseFromParameter, ParseResult, ToJSON, Type},
88
};
9+
use regex::Regex;
910
use serde_json::Value;
1011

1112
use crate::service::{
@@ -22,7 +23,7 @@ const DESCRIPTION: &str = "A hex encoded binary data.";
2223
/// An example.
2324
const EXAMPLE: &str = "0x56CDD154355E078A0990F9E633F9553F7D43A68B2FF9BEF78B9F5C71C808A7C8";
2425
/// A validation regex pattern.
25-
const PATTERN: &str = "0x[A-Fa-f0-9]+";
26+
const PATTERN: &str = "^0x[A-Fa-f0-9]+$";
2627
/// A format.
2728
const FORMAT: &str = "hex";
2829

@@ -37,12 +38,28 @@ static SCHEMA: LazyLock<MetaSchema> = LazyLock::new(|| {
3738
}
3839
});
3940

41+
/// Validate the `HexEncodedBinaryData`.
42+
/// This part is done separately from the `PATTERN`
43+
fn is_valid(hash: &str) -> bool {
44+
/// Regex to validate `HexEncodedBinaryData`
45+
#[allow(clippy::unwrap_used)] // Safe because the Regex is constant
46+
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(PATTERN).unwrap());
47+
48+
if RE.is_match(hash) {
49+
if let Some(h) = hash.strip_prefix("0x") {
50+
return hex::decode(h).is_ok();
51+
}
52+
}
53+
false
54+
}
55+
4056
impl_string_types!(
4157
/// A hex encoded binary data.
4258
HexEncodedBinaryData,
4359
"string",
4460
FORMAT,
45-
Some(SCHEMA.clone())
61+
Some(SCHEMA.clone()),
62+
is_valid
4663
);
4764

4865
impl From<Vec<u8>> for HexEncodedBinaryData {
@@ -62,3 +79,18 @@ impl Example for HexEncodedBinaryData {
6279
Self(EXAMPLE.to_owned())
6380
}
6481
}
82+
83+
#[cfg(test)]
84+
mod tests {
85+
use super::*;
86+
87+
#[test]
88+
fn test_hex_binary_data() {
89+
assert!(HexEncodedBinaryData::parse_from_parameter(EXAMPLE).is_ok());
90+
91+
let invalid = ["123", "0x", "0xqw", "abcdefghijk"];
92+
for v in invalid {
93+
assert!(HexEncodedBinaryData::parse_from_parameter(v).is_err());
94+
}
95+
}
96+
}

catalyst-gateway/bin/src/service/common/objects/cardano/stake_info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::service::common::types::{
1818
#[derive(Object, Debug, Clone)]
1919
#[oai(example)]
2020
pub(crate) struct StakedTxoAssetInfo {
21-
/// Token policy hash.
21+
/// Asset policy hash (28 bytes).
2222
pub(crate) policy_hash: HexEncodedHash28,
2323
/// Token policies Asset Name.
2424
pub(crate) asset_name: AssetName,

catalyst-gateway/bin/src/service/common/types/cardano/asset_name.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
33
use std::sync::LazyLock;
44

5+
use const_format::concatcp;
56
use poem_openapi::{
67
registry::{MetaSchema, MetaSchemaRef},
78
types::{Example, ParseError, ParseFromJSON, ParseFromParameter, ParseResult, ToJSON, Type},
89
};
10+
use regex::Regex;
911
use serde_json::Value;
1012

1113
use crate::service::common::types::string_types::impl_string_types;
@@ -17,14 +19,19 @@ const DESCRIPTION: &str = r"The name given to the native asset when it was minte
1719
If the name can be converted to UTF8, its string is represented directly.
1820
Otherwise it will be represented as escaped ascii.
1921
Any `\` present in the name will be replaced with `\\` in all cases.";
22+
2023
/// Example.
2124
const EXAMPLE: &str = "My Cool\nAsset";
25+
/// Maximum asset name in bytes.
26+
const ASSET_NAME_MAX_BYTES: usize = 32;
2227
/// Minimum length.
2328
const MIN_LENGTH: usize = 0;
24-
/// Maximum length. (True length is 32, but escaping can double its size).
25-
const MAX_LENGTH: usize = 64;
29+
/// Maximum length calculated from maximum length of escaped string * max number of bytes
30+
/// of asset name. <https://www.gnu.org/software/gawk/manual/html_node/Escape-Sequences.html>
31+
const MAX_LENGTH: usize = ASSET_NAME_MAX_BYTES * 4;
2632
/// Validation Regex Pattern
27-
const PATTERN: &str = r"[\S\s]{0,64}";
33+
/// Can be anything
34+
const PATTERN: &str = concatcp!(r"^[\S\s]{", "0,", MAX_LENGTH, "}$");
2835

2936
/// Schema.
3037
static SCHEMA: LazyLock<MetaSchema> = LazyLock::new(|| {
@@ -39,12 +46,12 @@ static SCHEMA: LazyLock<MetaSchema> = LazyLock::new(|| {
3946
}
4047
});
4148

42-
/// Because ALL the constraints are defined above, we do not ever need to define them in
43-
/// the API. BUT we do need to make a validator.
44-
/// This helps enforce uniform validation.
45-
fn is_valid(_name: &str) -> bool {
46-
// Anything is valid.
47-
true
49+
/// Validate `AssetName` This part is done separately from the `PATTERN`
50+
fn is_valid(name: &str) -> bool {
51+
/// Regex to validate `AssetName`
52+
#[allow(clippy::unwrap_used)] // Safe because the Regex is constant.
53+
static RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(PATTERN).unwrap());
54+
RE.is_match(name)
4855
}
4956

5057
impl_string_types!(
@@ -80,3 +87,31 @@ impl From<String> for AssetName {
8087
Self(value)
8188
}
8289
}
90+
91+
#[cfg(test)]
92+
mod tests {
93+
use super::*;
94+
95+
#[test]
96+
fn test_asset_name() {
97+
let escape_octal = r"\nnn".repeat(32);
98+
// Test Data
99+
// <https://preprod.cardanoscan.io/tokens>
100+
let valid = [
101+
EXAMPLE,
102+
"This_Is_A_Very_Long_String______",
103+
&escape_octal,
104+
"SPLASH",
105+
];
106+
for v in valid {
107+
assert!(AssetName::parse_from_parameter(v).is_ok());
108+
}
109+
let invalid = [
110+
// Add additional char
111+
&format!("{escape_octal}a"),
112+
];
113+
for v in invalid {
114+
assert!(AssetName::parse_from_parameter(v).is_err());
115+
}
116+
}
117+
}

0 commit comments

Comments
 (0)