-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bid Status Visibility #42
Changes from 11 commits
3ab5f4d
613c14d
cbeeea6
6f7d698
5540b4b
60f6285
8f433d6
51a561a
a7e9c76
895b484
5fb3f38
0c2499e
13c8ef1
227eae8
329c517
e4d53e2
de3edd8
e11b810
9cc5efd
52abd3f
809d653
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE auction; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
CREATE TABLE auction | ||
( | ||
id UUID PRIMARY KEY, | ||
conclusion_time TIMESTAMP NOT NULL, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's add another column |
||
permission_key BYTEA NOT NULL, | ||
chain_id TEXT NOT NULL, | ||
tx_hash BYTEA NOT NULL CHECK (LENGTH(tx_hash) = 32) | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
use { | ||
crate::{ | ||
api::{ | ||
opportunity::ChainIdQueryParams, | ||
ErrorBodyResponse, | ||
RestError, | ||
}, | ||
state::{ | ||
AuctionId, | ||
AuctionParams, | ||
PermissionKey, | ||
Store, | ||
}, | ||
}, | ||
axum::{ | ||
extract::{ | ||
Path, | ||
Query, | ||
State, | ||
}, | ||
Json, | ||
}, | ||
ethers::types::H256, | ||
serde::{ | ||
Deserialize, | ||
Serialize, | ||
}, | ||
std::sync::Arc, | ||
utoipa::ToSchema, | ||
}; | ||
|
||
#[derive(Serialize, Deserialize, ToSchema, Clone)] | ||
pub struct AuctionParamsWithId { | ||
#[schema(value_type = String)] | ||
pub id: AuctionId, | ||
pub params: AuctionParams, | ||
} | ||
|
||
/// Query for auctions with the permission key and (optionally) chain ID specified. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure who is gonna use this endpoint, let's discuss the access patterns and how we want searchers to have more visibility. |
||
#[utoipa::path(get, path = "/v1/auctions/{permission_key}", | ||
params( | ||
("permission_key"=String, description = "Permission key to query for"), | ||
ChainIdQueryParams | ||
), | ||
responses( | ||
(status = 200, description = "Array of auctions with the permission key", body = Vec<AuctionParams>), | ||
(status = 400, response = ErrorBodyResponse), | ||
(status = 404, description = "Permission key was not found", body = ErrorBodyResponse), | ||
) | ||
)] | ||
pub async fn get_auctions( | ||
State(store): State<Arc<Store>>, | ||
Path(permission_key): Path<PermissionKey>, | ||
query_params: Query<ChainIdQueryParams>, | ||
) -> Result<Json<Vec<AuctionParams>>, RestError> { | ||
let auctions = match &query_params.chain_id { | ||
Some(chain_id) => { | ||
let auction_records = sqlx::query!( | ||
"SELECT * FROM auction WHERE permission_key = $1 AND chain_id = $2", | ||
permission_key.as_ref(), | ||
chain_id | ||
) | ||
.fetch_all(&store.db) | ||
.await | ||
.map_err(|_| RestError::AuctionNotFound)?; | ||
|
||
auction_records | ||
.into_iter() | ||
.map(|auction| AuctionParams { | ||
chain_id: auction.chain_id, | ||
permission_key: auction.permission_key.into(), | ||
tx_hash: H256::from_slice(auction.tx_hash.as_ref()), | ||
}) | ||
.collect() | ||
} | ||
None => { | ||
let auction_records = sqlx::query!( | ||
"SELECT * FROM auction WHERE permission_key = $1", | ||
permission_key.as_ref() | ||
) | ||
.fetch_all(&store.db) | ||
.await | ||
.map_err(|_| RestError::AuctionNotFound)?; | ||
|
||
auction_records | ||
.into_iter() | ||
.map(|auction| AuctionParams { | ||
chain_id: auction.chain_id, | ||
permission_key: auction.permission_key.into(), | ||
tx_hash: H256::from_slice(auction.tx_hash.as_ref()), | ||
}) | ||
.collect() | ||
} | ||
}; | ||
|
||
Ok(Json(auctions)) | ||
} | ||
|
||
// Get auction with the specified ID. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no additional information in this comment. |
||
pub async fn get_auction_with_id( | ||
store: Arc<Store>, | ||
auction_id: AuctionId, | ||
) -> Result<AuctionParamsWithId, RestError> { | ||
let auction = sqlx::query!("SELECT * FROM auction WHERE id = $1", auction_id) | ||
.fetch_one(&store.db) | ||
.await | ||
.map_err(|_| RestError::BidNotFound)?; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be |
||
|
||
Ok(AuctionParamsWithId { | ||
id: auction.id, | ||
params: AuctionParams { | ||
chain_id: auction.chain_id, | ||
permission_key: auction.permission_key.into(), | ||
tx_hash: H256::from_slice(auction.tx_hash.as_ref()), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
}, | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
use { | ||
crate::{ | ||
api::{ | ||
auction::get_auction_with_id, | ||
ErrorBodyResponse, | ||
RestError, | ||
}, | ||
|
@@ -80,8 +81,52 @@ pub async fn bid_status( | |
State(store): State<Arc<Store>>, | ||
Path(bid_id): Path<BidId>, | ||
) -> Result<Json<BidStatus>, RestError> { | ||
match store.bids.read().await.get(&bid_id) { | ||
Some(bid) => Ok(bid.status.clone().into()), | ||
None => Err(RestError::BidNotFound), | ||
let status_data = sqlx::query!( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would move this to state. Also no need to have 2 separate queries, we can join these 2 tables and have a single query. I think the code will become simpler. |
||
// TODO: improve the call here to not cast to text | ||
"SELECT status::text, auction_id FROM bid WHERE id = $1", | ||
bid_id | ||
) | ||
.fetch_one(&store.db) | ||
.await | ||
.map_err(|_| RestError::BidNotFound)?; | ||
|
||
let status_json: Json<BidStatus>; | ||
match status_data.status { | ||
Some(status) => { | ||
if status == "pending" { | ||
status_json = BidStatus::Pending.into(); | ||
} else if status == "lost" { | ||
match status_data.auction_id { | ||
Some(auction_id) => { | ||
let auction_info = get_auction_with_id(store.clone(), auction_id).await?; | ||
status_json = BidStatus::Lost(auction_info.params.tx_hash).into(); | ||
} | ||
None => { | ||
return Err(RestError::BadParameters( | ||
"Lost bid must have auction id".to_string(), | ||
)); | ||
} | ||
} | ||
} else if status == "submitted" { | ||
match status_data.auction_id { | ||
Some(auction_id) => { | ||
let auction_info = get_auction_with_id(store.clone(), auction_id).await?; | ||
status_json = BidStatus::Submitted(auction_info.params.tx_hash).into(); | ||
} | ||
None => { | ||
return Err(RestError::BadParameters( | ||
"Submitted bid must have auction id".to_string(), | ||
)); | ||
} | ||
} | ||
} else { | ||
return Err(RestError::BadParameters("Invalid status".to_string())); | ||
} | ||
} | ||
None => { | ||
return Err(RestError::BidNotFound); | ||
} | ||
} | ||
|
||
Ok(status_json) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,8 +142,8 @@ pub async fn post_opportunity( | |
|
||
#[derive(Serialize, Deserialize, IntoParams)] | ||
pub struct ChainIdQueryParams { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's move this to some more general file (maybe the base api.rs?) . This doesn't particularly belong to opportunity or bid or ... |
||
#[param(example = "sepolia", value_type = Option < String >)] | ||
chain_id: Option<ChainId>, | ||
#[param(example = "op_sepolia", value_type = Option < String >)] | ||
pub chain_id: Option<ChainId>, | ||
} | ||
|
||
/// Fetch all opportunities ready to be exectued. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add another column here that shows the position of this bid in the bundle. Having a null value while having an auction id means that this bid was not submitted on-chain (it lost)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a foreign key with protect constraint.