Skip to content
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

Rust improvement #9

Merged
merged 11 commits into from
Jan 23, 2024
Merged

Rust improvement #9

merged 11 commits into from
Jan 23, 2024

Conversation

m30m
Copy link
Collaborator

@m30m m30m commented Jan 12, 2024

No description provided.

.collect()
}

pub fn verify_signature(params: liquidation_adapter::LiquidationCallParams) -> Result<(), String> {
Copy link
Contributor

@ali-bahjati ali-bahjati Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err Result of String is a bit weird. Why not anyhow?

let nonce = params.valid_until;
let digest = H256(keccak256(
abi::encode_packed(&[data.into_token(), nonce.into_token()]).map_err(|x| x.to_string())?,
)); // TODO: Fix unwrap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no unwrap left here

Comment on lines 67 to 70
.map(|token| liquidation_adapter::TokenQty {
token: token.0,
amount: token.1,
})
Copy link
Contributor

@ali-bahjati ali-bahjati Jan 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

impl From<(Address, U256)> For TokenQty would be nice here and then you can remove the whole function.

@@ -6,6 +6,11 @@
LIQUIDATION_ADAPTER_ADDRESS = "0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6"


class TokenAmount(TypedDict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's rename this TokenQty, for consistency with the naming in the solidity contracts? can also use a better name for both, but let's keep the naming consistent

BEACON_SERVER_ENDPOINT_SURFACE = f"{BEACON_SERVER_ENDPOINT}/surface"
BEACON_SERVER_ENDPOINT_GETOPPS = f"{BEACON_SERVER_ENDPOINT}/getOpps"
BEACON_SERVER_ENDPOINT_SURFACE = f"{
BEACON_SERVER_ENDPOINT}/orders/submit_order"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a confusing name, bc submit order almost sounds like something the end user would do. perhaps something like expose/surface opportunities, in coordination with "beacon"?

BEACON_SERVER_ENDPOINT_SURFACE = f"{
BEACON_SERVER_ENDPOINT}/orders/submit_order"
BEACON_SERVER_ENDPOINT_GETOPPS = f"{
BEACON_SERVER_ENDPOINT}/orders/fetch_orders"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's refer to these as opportunities, as opposed to orders. we aren't handling users' orders

@@ -84,16 +31,30 @@ pub struct SimulatedBid {
// simulation_time:
}

#[derive(Clone)]
pub struct VerifiedOrder {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note on the naming again--we should change this to something like opportunity

};

#[derive(Serialize, Deserialize, ToSchema, Clone)]
pub struct TokenAmount {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name consistency

amount: amount.to_string(),
})
.collect(),
receipt_tokens: order
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we just make the receipt_tokens and repay_tokens have the same type across Order and VerifiedOrder?


//TODO: Verify if the call actually works

store.liquidation_store.orders.write().await.insert(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need to consider the following when deciding on how to store opportunities

  1. users may want to fetch opps by filters, such as repay_tokens, receipt_tokens, contract
  2. how do we want to remove opps once they are no longer eligible? either bc someone performed the liquidation already or bc the vault is no longer stale?

for 1, we may want to store opportunity UUIDs in hash maps keyed by each of those filters. tradeoff is we would have to handle deletion in duplicate cases.

for 2, we may want to have a slow path that is regularly going through the list of UUIDs and removing ones that are stale. perhaps when an opportunity is fulfilled on-chain via liquidation adapter, we also have an event emitted with UUID, so we can track it down and remove it from the store

),)]
pub async fn submit_order(
State(store): State<Arc<Store>>,
Json(order): Json<Order>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will still have prices in it on the Python side, should remove that field

//TODO: Verify if the call actually works

store.liquidation_store.orders.write().await.insert(
Uuid::new_v4(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

relatedly, we may want to create a 1:1 mapping from vault liquidation opportunity to ID? this way it becomes easy to update the right UUID if the calldata changes (e.g. update prices). To do this however, we would need an additional field in the Opportunity/Order structs that indicates vault number or something

@@ -32,7 +31,8 @@ pub struct SimulatedBid {
}

#[derive(Clone)]
pub struct VerifiedOrder {
pub struct VerifiedLiquidationOpportunity {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we standardize LiquidationOpportunity and VerifiedLiquidationOpportunity to have the same field names (except for id ofc)

@@ -50,7 +50,7 @@ pub struct ChainStore {

#[derive(Default)]
pub struct LiquidationStore {
pub orders: RwLock<HashMap<OrderId, VerifiedOrder>>,
pub opportunities: RwLock<HashMap<PermissionKey, VerifiedLiquidationOpportunity>>,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we decided to kick down the road whether to include tokenqty in the dedup, so this looks good to me

.repay_tokens
.into_iter()
.map(TokenQty::from)
.collect(), // TODO: consistent naming across rust, rest, and solidity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think you can remove this todo

let bid_amount = U256::from_dec_str(order_bid.bid_amount.as_str())
let liquidation = opportunities
.get(&opportunity_bid.permission_key)
.ok_or(RestError::OpportunityNotFound)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i forget if we discussed how we would handle opportunities no longer being liquidatable. how are we going to handle removing them from the server a) once they become stale (but still actionable bc price on-chain is stale), b) once they become stale (and no longer actionable bc price updated on-chain), c) once they are liquidated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we decided to have a separate loop which validates the liquidations periodically and removes invalid ones. will address separately

@@ -32,7 +31,8 @@ pub struct SimulatedBid {
}

#[derive(Clone)]
pub struct VerifiedOrder {
pub struct VerifiedLiquidationOpportunity {
pub id: Uuid,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we standardize the types of the token fields across LiquidationOpportunity and VerifiedLiquidationOpportunity to both be TokenQty vectors?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the main issue here is having U256 in our api structs. When users pass in strings, it is treated as hex strings and not decimal which is not our desired behavior. I didn't find an easy way to fix this so decided to split some structs between X and VerifiedX where the VerifiedX is input-checked and sanitized.

@m30m m30m merged commit 44cf436 into main Jan 23, 2024
1 check passed
@m30m m30m deleted the rust-improv branch January 23, 2024 10:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants