Skip to content

Commit

Permalink
Restrict get_tx by relayer id (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dzejkop authored Jun 18, 2024
1 parent bd16c17 commit 6fa9eff
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 14 deletions.
129 changes: 124 additions & 5 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -874,7 +874,30 @@ impl Database {
}

#[instrument(skip(self), level = "debug")]
pub async fn read_txs(
pub async fn read_relayer_tx(
&self,
relayer_id: &str,
tx_id: &str,
) -> eyre::Result<Option<ReadTxData>> {
Ok(sqlx::query_as(
r#"
SELECT t.id as tx_id, t.tx_to as to, t.data, t.value, t.gas_limit, t.nonce,
t.blobs, h.tx_hash, s.status
FROM transactions t
LEFT JOIN sent_transactions s ON t.id = s.tx_id
LEFT JOIN tx_hashes h ON s.valid_tx_hash = h.tx_hash
WHERE t.id = $1
AND t.relayer_id = $2
"#,
)
.bind(tx_id)
.bind(relayer_id)
.fetch_optional(&self.pool)
.await?)
}

#[instrument(skip(self), level = "debug")]
pub async fn read_relayer_txs(
&self,
relayer_id: &str,
tx_status_filter: Option<Option<TxStatus>>,
Expand Down Expand Up @@ -902,6 +925,32 @@ impl Database {
.await?)
}

#[instrument(skip(self), level = "debug")]
pub async fn read_txs(
&self,
tx_status_filter: Option<Option<TxStatus>>,
) -> eyre::Result<Vec<ReadTxData>> {
let (should_filter, status_filter) = match tx_status_filter {
Some(status) => (true, status),
None => (false, None),
};

Ok(sqlx::query_as(
r#"
SELECT t.id as tx_id, t.tx_to as to, t.data, t.value, t.gas_limit, t.nonce,
t. blobs, h.tx_hash, s.status
FROM transactions t
LEFT JOIN sent_transactions s ON t.id = s.tx_id
LEFT JOIN tx_hashes h ON s.valid_tx_hash = h.tx_hash
WHERE ($1 = true AND s.status = $2) OR $1 = false
"#,
)
.bind(should_filter)
.bind(status_filter)
.fetch_all(&self.pool)
.await?)
}

#[instrument(skip(self), level = "debug")]
pub async fn update_relayer_nonce(
&self,
Expand Down Expand Up @@ -1495,7 +1544,7 @@ mod tests {
assert_eq!(tx.tx_hash, None);
assert_eq!(tx.blobs, None);

let unsent_txs = db.read_txs(relayer_id, None).await?;
let unsent_txs = db.read_relayer_txs(relayer_id, None).await?;
assert_eq!(unsent_txs.len(), 1, "1 unsent tx");

let tx_hash_1 = H256::from_low_u64_be(1);
Expand All @@ -1516,15 +1565,15 @@ mod tests {
assert_eq!(tx.tx_hash.unwrap().0, tx_hash_1);
assert_eq!(tx.status, Some(TxStatus::Pending));

let unsent_txs = db.read_txs(relayer_id, Some(None)).await?;
let unsent_txs = db.read_relayer_txs(relayer_id, Some(None)).await?;
assert_eq!(unsent_txs.len(), 0, "0 unsent tx");

let pending_txs = db
.read_txs(relayer_id, Some(Some(TxStatus::Pending)))
.read_relayer_txs(relayer_id, Some(Some(TxStatus::Pending)))
.await?;
assert_eq!(pending_txs.len(), 1, "1 pending tx");

let all_txs = db.read_txs(relayer_id, None).await?;
let all_txs = db.read_relayer_txs(relayer_id, None).await?;

assert_eq!(all_txs, pending_txs);

Expand Down Expand Up @@ -1610,6 +1659,76 @@ mod tests {
Ok(())
}

#[tokio::test]
async fn read_tx() -> eyre::Result<()> {
let (db, _db_container) = setup_db().await?;

let chain_id = 123;
let network_name = "network_name";
let http_rpc = "http_rpc";
let ws_rpc = "ws_rpc";

db.upsert_network(chain_id, network_name, http_rpc, ws_rpc)
.await?;

let relayer_1_id = uuid();
let relayer_1_id = relayer_1_id.as_str();
let relayer_1_name = "relayer_1";

let relayer_2_id = uuid();
let relayer_2_id = relayer_2_id.as_str();
let relayer_2_name = "relayer_2";

let key_id = "key_id";
let relayer_address = Address::from_low_u64_be(1);

db.create_relayer(
relayer_1_id,
relayer_1_name,
chain_id,
key_id,
relayer_address,
)
.await?;

db.create_relayer(
relayer_2_id,
relayer_2_name,
chain_id,
key_id,
relayer_address,
)
.await?;

let tx_id = "tx_id";
let to = Address::from_low_u64_be(1);
let data: &[u8] = &[];
let value = U256::from(0);
let gas_limit = U256::from(0);
let priority = TransactionPriority::Regular;
let blobs = None;

db.create_transaction(
tx_id,
to,
data,
value,
gas_limit,
priority,
blobs,
relayer_1_id,
)
.await?;

let tx = db.read_tx(tx_id).await?;
assert!(tx.is_some(), "Tx can be read via read_tx");

let tx = db.read_relayer_tx(relayer_2_id, tx_id).await?;
assert!(tx.is_none(), "Tx cannot be read by relayer 2");

Ok(())
}

#[tokio::test]
async fn blocks() -> eyre::Result<()> {
let (db, _db_container) = setup_db().await?;
Expand Down
28 changes: 19 additions & 9 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,12 +278,18 @@ impl RelayerApi {
) -> Result<Json<GetTxResponse>> {
api_token.validate(app).await?;

let tx = app.db.read_tx(&tx_id).await?.ok_or_else(|| {
poem::error::Error::from_string(
"Transaction not found".to_string(),
StatusCode::NOT_FOUND,
)
})?;
let relayer_id = api_token.relayer_id();

let tx = app
.db
.read_relayer_tx(relayer_id, &tx_id)
.await?
.ok_or_else(|| {
poem::error::Error::from_string(
"Transaction not found".to_string(),
StatusCode::NOT_FOUND,
)
})?;

let get_tx_response = GetTxResponse {
tx_id: tx.tx_id,
Expand Down Expand Up @@ -318,13 +324,17 @@ impl RelayerApi {
api_token.validate(app).await?;

let txs = if unsent {
app.db.read_txs(api_token.relayer_id(), Some(None)).await?
app.db
.read_relayer_txs(api_token.relayer_id(), Some(None))
.await?
} else if let Some(status) = status {
app.db
.read_txs(api_token.relayer_id(), Some(Some(status)))
.read_relayer_txs(api_token.relayer_id(), Some(Some(status)))
.await?
} else {
app.db.read_txs(api_token.relayer_id(), None).await?
app.db
.read_relayer_txs(api_token.relayer_id(), None)
.await?
};

let txs = txs
Expand Down

0 comments on commit 6fa9eff

Please sign in to comment.