Skip to content

Commit

Permalink
fix api vault auction history
Browse files Browse the repository at this point in the history
  • Loading branch information
canonbrother committed Oct 28, 2024
1 parent 32428fb commit c7b22d2
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 69 deletions.
17 changes: 16 additions & 1 deletion lib/ain-ocean/src/api/common.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::str::FromStr;

use ain_dftx::{Currency, Token};
use bitcoin::{Address, ScriptBuf};
use bitcoin::{Address, ScriptBuf, Txid};
use defichain_rpc::json::token::TokenInfo;
use rust_decimal::Decimal;
use rust_decimal_macros::dec;
Expand All @@ -10,6 +10,7 @@ use snafu::OptionExt;
use super::query::PaginationQuery;
use crate::{
error::{
Error::ToArrayError,
InvalidAmountSnafu, InvalidFixedIntervalPriceSnafu, InvalidPoolPairSymbolSnafu,
InvalidTokenCurrencySnafu,
},
Expand Down Expand Up @@ -114,6 +115,20 @@ pub fn parse_query_height_txno(item: &str) -> Result<(u32, usize)> {
Ok((height, txno))
}

pub fn parse_query_height_txid(item: &str) -> Result<(u32, Txid)> {
let mut parts = item.split('-');
let encoded_height = parts.next().context(InvalidAmountSnafu { item })?;
let txid = parts.next().context(InvalidAmountSnafu { item })?;

let height_in_bytes: [u8; 4] = hex::decode(encoded_height)?
.try_into()
.map_err(|_| ToArrayError)?;
let height = u32::from_be_bytes(height_in_bytes);
let txid = txid.parse::<Txid>()?;

Ok((height, txid))
}

#[must_use]
pub fn format_number(v: Decimal) -> String {
if v == dec!(0) {
Expand Down
120 changes: 91 additions & 29 deletions lib/ain-ocean/src/api/loan.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::{str::FromStr, sync::Arc};

use ain_dftx::COIN;
use ain_macros::ocean_endpoint;
use axum::{routing::get, Extension, Router};
use bitcoin::{hashes::Hash, Txid};
use bitcoin::{hashes::Hash, ScriptBuf, Txid};
use defichain_rpc::{
defichain_rpc_json::{
loan::{CollateralTokenDetail, LoanSchemeResult},
Expand All @@ -17,15 +18,16 @@ use defichain_rpc::{
};
use futures::future::try_join_all;
use log::trace;
use serde::{Serialize, Serializer};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize, Serializer};
use serde_with::skip_serializing_none;
use snafu::OptionExt;

use super::{
cache::{get_loan_scheme_cached, get_token_cached},
common::{
from_script, parse_amount, parse_display_symbol, parse_fixed_interval_price,
parse_query_height_txno, Paginate,
parse_query_height_txid, Paginate,
},
path::Path,
query::{PaginationQuery, Query},
Expand All @@ -35,7 +37,8 @@ use super::{
};
use crate::{
error::{ApiError, Error, NotFoundKind, NotFoundSnafu},
model::{OraclePriceActive, VaultAuctionBatchHistory},
model::{BlockContext, OraclePriceActive, VaultAuctionBatchHistory},
network::Network,
storage::{RepositoryOps, SortOrder},
Result,
};
Expand Down Expand Up @@ -488,55 +491,111 @@ async fn get_vault(
Ok(Response::new(res))
}

#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct VaultAuctionBatchHistoryResponse {
pub id: String,
pub key: String,
pub sort: String,
pub vault_id: Txid,
pub index: u32,
pub from: ScriptBuf,
pub address: String,
pub amount: String,
pub token_id: u64,
pub block: BlockContext,
}

impl VaultAuctionBatchHistoryResponse {
fn from(
data: ((Txid, [u8; 4], [u8; 4], Txid), VaultAuctionBatchHistory),
address: String,
) -> Self {
let id = data.0;
let vault_id = id.0;
let batch_index = u32::from_be_bytes(id.1);
let block_height = id.2;
let txid = id.3;
let history = data.1;
let amount = Decimal::from(history.amount) / Decimal::from(COIN);

Self {
id: format!(
"{}-{}-{}",
vault_id.clone(),
batch_index.clone(),
txid.clone()
),
key: format!("{}-{}", vault_id.clone(), batch_index.clone()),
sort: format!("{}-{}", hex::encode(block_height), txid),
vault_id,
index: batch_index,
from: history.from,
address,
amount: amount.to_string(),
token_id: history.token_id,
block: history.block,
}
}
}

#[ocean_endpoint]
async fn list_vault_auction_history(
Path((vault_id, height, batch_index)): Path<(Txid, u32, u32)>,
Path((vault_id, liquidation_height, batch_index)): Path<(Txid, u32, u32)>,
Query(query): Query<PaginationQuery>,
Extension(ctx): Extension<Arc<AppContext>>,
) -> Result<ApiPagedResponse<VaultAuctionBatchHistory>> {
) -> Result<ApiPagedResponse<VaultAuctionBatchHistoryResponse>> {
trace!(
"Auction history for vault id {}, height {}, batch index {}",
"Auction history for vault id {}, liquidation_height {}, batch index {}",
vault_id,
height,
liquidation_height,
batch_index
);
let next = query
.next
.map(|q| {
let (height, txno) = parse_query_height_txno(&q)?;
Ok::<(u32, usize), Error>((height, txno))
let (height, txid) = parse_query_height_txid(&q)?;
Ok::<(u32, Txid), Error>((height, txid))
})
.transpose()?
.unwrap_or_default();
.unwrap_or((liquidation_height, Txid::from_byte_array([0xffu8; 32])));

let size = if query.size > 0 { query.size } else { 30 };

let size = if query.size > 0 { query.size } else { 20 };
let liquidation_block_expiry = match ctx.network {
Network::Regtest => 36,
_ => 720,
};

let auctions = ctx
.services
.auction
.by_height
.by_id
.list(
Some((vault_id, batch_index, next.0, next.1)),
Some((
vault_id,
batch_index.to_be_bytes(),
next.0.to_be_bytes(),
next.1,
)),
SortOrder::Descending,
)?
.take(size)
.take_while(|item| match item {
Ok((k, _)) => k.0 == vault_id && k.1 == batch_index,
Ok((k, _)) => {
k.0 == vault_id
&& k.1 == batch_index.to_be_bytes()
&& u32::from_be_bytes(k.2) > liquidation_height - liquidation_block_expiry
}
_ => true,
})
.map(|item| {
let (_, id) = item?;

let auction = ctx
.services
.auction
.by_id
.get(&id)?
.context(NotFoundSnafu {
kind: NotFoundKind::Auction,
})?;

Ok(auction)
let (id, history) = item?;
let address = from_script(&history.from, ctx.network)?;
Ok(VaultAuctionBatchHistoryResponse::from(
(id, history),
address,
))
})
.collect::<Result<Vec<_>>>()?;

Expand Down Expand Up @@ -611,14 +670,17 @@ async fn map_liquidation_batches(
};
let id = (
Txid::from_str(vault_id)?,
batch.index,
batch.index.to_be_bytes(),
[0xffu8, 0xffu8, 0xffu8, 0xffu8],
Txid::from_byte_array([0xffu8; 32]),
);
let bids = repo
.by_id
.list(Some(id), SortOrder::Descending)?
.take_while(|item| match item {
Ok(((vid, bindex, _), _)) => vid.to_string() == vault_id && bindex == &batch.index,
Ok(((vid, bindex, _, _), _)) => {
vid.to_string() == vault_id && bindex == &batch.index.to_be_bytes()
}
_ => true,
})
.collect::<Vec<_>>();
Expand Down
1 change: 1 addition & 0 deletions lib/ain-ocean/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ pub enum Error {
#[snafu(implicit)]
location: Location,
},
ToArrayError,
#[snafu(display("{}", msg))]
Other {
msg: String,
Expand Down
30 changes: 11 additions & 19 deletions lib/ain-ocean/src/indexer/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,37 +16,29 @@ impl Index for PlaceAuctionBid {
trace!("[PlaceAuctionBid] Indexing...");

let auction = VaultAuctionBatchHistory {
id: format!("{}-{}-{}", self.vault_id, self.index, ctx.tx.txid),
key: format!("{}-{}", self.vault_id, self.index),
sort: format!("{}-{}", ctx.block.height, ctx.tx_idx),
vault_id: self.vault_id,
index: ctx.tx_idx,
from: self.from,
amount: self.token_amount.amount,
token_id: self.token_amount.token.0,
block: ctx.block.clone(),
};
trace!("auction : {:?}", auction);

let key = (self.vault_id, self.index, ctx.tx.txid);
services.auction.by_id.put(&key, &auction)?;
services.auction.by_height.put(
&(self.vault_id, self.index, ctx.block.height, ctx.tx_idx),
&key,
)
let id = (
self.vault_id,
self.index.to_be_bytes(),
ctx.block.height.to_be_bytes(),
ctx.tx.txid,
);
services.auction.by_id.put(&id, &auction)
}

fn invalidate(&self, services: &Arc<Services>, ctx: &Context) -> Result<()> {
trace!("[PlaceAuctionBid] Invalidating...");
services
.auction
.by_id
.delete(&(self.vault_id, self.index, ctx.tx.txid))?;
services.auction.by_height.delete(&(
services.auction.by_id.delete(&(
self.vault_id,
self.index,
ctx.block.height,
ctx.tx_idx,
self.index.to_be_bytes(),
ctx.block.height.to_be_bytes(),
ctx.tx.txid,
))
}
}
2 changes: 0 additions & 2 deletions lib/ain-ocean/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub struct BlockService {

pub struct AuctionService {
by_id: VaultAuctionHistory,
by_height: VaultAuctionHistoryByHeight,
}

pub struct PoolService {
Expand Down Expand Up @@ -157,7 +156,6 @@ impl Services {
},
auction: AuctionService {
by_id: VaultAuctionHistory::new(Arc::clone(&store)),
by_height: VaultAuctionHistoryByHeight::new(Arc::clone(&store)),
},
result: TxResult::new(Arc::clone(&store)),
pool: PoolService {
Expand Down
8 changes: 1 addition & 7 deletions lib/ain-ocean/src/model/vault_auction_batch_history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ use serde::{Deserialize, Serialize};

use super::BlockContext;

pub type AuctionHistoryKey = (Txid, u32, Txid); // (vault_id, auction_batch_index, txid)
pub type AuctionHistoryByHeightKey = (Txid, u32, u32, usize); // (vault_id, auction_batch_index, block_height, txid)
pub type AuctionHistoryKey = (Txid, [u8; 4], [u8; 4], Txid); // (vault_id, auction_batch_index, block_height, txid)

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct VaultAuctionBatchHistory {
pub id: String,
pub key: String,
pub sort: String,
pub vault_id: Txid,
pub index: usize,
pub from: ScriptBuf,
pub amount: i64,
pub token_id: u64,
Expand Down
12 changes: 1 addition & 11 deletions lib/ain-ocean/src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,16 +408,7 @@ define_table! {
}
}

define_table! {
#[derive(Debug)]
pub struct VaultAuctionHistoryByHeight {
key_type = model::AuctionHistoryByHeightKey,
value_type = model::AuctionHistoryKey,
},
SecondaryIndex = VaultAuctionHistory
}

pub const COLUMN_NAMES: [&str; 29] = [
pub const COLUMN_NAMES: [&str; 28] = [
Block::NAME,
BlockByHeight::NAME,
MasternodeStats::NAME,
Expand Down Expand Up @@ -446,5 +437,4 @@ pub const COLUMN_NAMES: [&str; 29] = [
TransactionVout::NAME,
TxResult::NAME,
VaultAuctionHistory::NAME,
VaultAuctionHistoryByHeight::NAME,
];

0 comments on commit c7b22d2

Please sign in to comment.