Skip to content

Commit e37d5e4

Browse files
committed
fix api vault auction history
1 parent 67295e7 commit e37d5e4

7 files changed

Lines changed: 122 additions & 71 deletions

File tree

lib/ain-ocean/src/api/common.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::str::FromStr;
22

33
use ain_dftx::{Currency, Token};
4-
use bitcoin::{Address, ScriptBuf};
4+
use bitcoin::{Address, ScriptBuf, Txid};
55
use defichain_rpc::json::token::TokenInfo;
66
use rust_decimal::Decimal;
77
use rust_decimal_macros::dec;
@@ -10,8 +10,8 @@ use snafu::OptionExt;
1010
use super::query::PaginationQuery;
1111
use crate::{
1212
error::{
13-
InvalidAmountSnafu, InvalidFixedIntervalPriceSnafu, InvalidPoolPairSymbolSnafu,
14-
InvalidTokenCurrencySnafu,
13+
Error::ToArrayError, InvalidAmountSnafu, InvalidFixedIntervalPriceSnafu,
14+
InvalidPoolPairSymbolSnafu, InvalidTokenCurrencySnafu,
1515
},
1616
hex_encoder::as_sha256,
1717
network::Network,
@@ -114,6 +114,20 @@ pub fn parse_query_height_txno(item: &str) -> Result<(u32, usize)> {
114114
Ok((height, txno))
115115
}
116116

117+
pub fn parse_query_height_txid(item: &str) -> Result<(u32, Txid)> {
118+
let mut parts = item.split('-');
119+
let encoded_height = parts.next().context(InvalidAmountSnafu { item })?;
120+
let txid = parts.next().context(InvalidAmountSnafu { item })?;
121+
122+
let height_in_bytes: [u8; 4] = hex::decode(encoded_height)?
123+
.try_into()
124+
.map_err(|_| ToArrayError)?;
125+
let height = u32::from_be_bytes(height_in_bytes);
126+
let txid = txid.parse::<Txid>()?;
127+
128+
Ok((height, txid))
129+
}
130+
117131
#[must_use]
118132
pub fn format_number(v: Decimal) -> String {
119133
if v == dec!(0) {

lib/ain-ocean/src/api/loan.rs

Lines changed: 91 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
use std::{str::FromStr, sync::Arc};
22

3+
use ain_dftx::COIN;
34
use ain_macros::ocean_endpoint;
45
use axum::{routing::get, Extension, Router};
5-
use bitcoin::{hashes::Hash, Txid};
6+
use bitcoin::{hashes::Hash, ScriptBuf, Txid};
67
use defichain_rpc::{
78
defichain_rpc_json::{
89
loan::{CollateralTokenDetail, LoanSchemeResult},
@@ -17,15 +18,16 @@ use defichain_rpc::{
1718
};
1819
use futures::future::try_join_all;
1920
use log::trace;
20-
use serde::{Serialize, Serializer};
21+
use rust_decimal::Decimal;
22+
use serde::{Deserialize, Serialize, Serializer};
2123
use serde_with::skip_serializing_none;
2224
use snafu::OptionExt;
2325

2426
use super::{
2527
cache::{get_loan_scheme_cached, get_token_cached},
2628
common::{
2729
from_script, parse_amount, parse_display_symbol, parse_fixed_interval_price,
28-
parse_query_height_txno, Paginate,
30+
parse_query_height_txid, Paginate,
2931
},
3032
path::Path,
3133
query::{PaginationQuery, Query},
@@ -35,7 +37,8 @@ use super::{
3537
};
3638
use crate::{
3739
error::{ApiError, Error, NotFoundKind, NotFoundSnafu},
38-
model::{OraclePriceActive, VaultAuctionBatchHistory},
40+
model::{BlockContext, OraclePriceActive, VaultAuctionBatchHistory},
41+
network::Network,
3942
storage::{RepositoryOps, SortOrder},
4043
Result,
4144
};
@@ -488,55 +491,111 @@ async fn get_vault(
488491
Ok(Response::new(res))
489492
}
490493

494+
#[derive(Serialize, Deserialize, Debug, Clone)]
495+
#[serde(rename_all = "camelCase")]
496+
pub struct VaultAuctionBatchHistoryResponse {
497+
pub id: String,
498+
pub key: String,
499+
pub sort: String,
500+
pub vault_id: Txid,
501+
pub index: u32,
502+
pub from: ScriptBuf,
503+
pub address: String,
504+
pub amount: String,
505+
pub token_id: u64,
506+
pub block: BlockContext,
507+
}
508+
509+
impl VaultAuctionBatchHistoryResponse {
510+
fn from(
511+
data: ((Txid, [u8; 4], [u8; 4], Txid), VaultAuctionBatchHistory),
512+
address: String,
513+
) -> Self {
514+
let id = data.0;
515+
let vault_id = id.0;
516+
let batch_index = u32::from_be_bytes(id.1);
517+
let block_height = id.2;
518+
let txid = id.3;
519+
let history = data.1;
520+
let amount = Decimal::from(history.amount) / Decimal::from(COIN);
521+
522+
Self {
523+
id: format!(
524+
"{}-{}-{}",
525+
vault_id.clone(),
526+
batch_index.clone(),
527+
txid.clone()
528+
),
529+
key: format!("{}-{}", vault_id.clone(), batch_index.clone()),
530+
sort: format!("{}-{}", hex::encode(block_height), txid),
531+
vault_id,
532+
index: batch_index,
533+
from: history.from,
534+
address,
535+
amount: amount.to_string(),
536+
token_id: history.token_id,
537+
block: history.block,
538+
}
539+
}
540+
}
541+
491542
#[ocean_endpoint]
492543
async fn list_vault_auction_history(
493-
Path((vault_id, height, batch_index)): Path<(Txid, u32, u32)>,
544+
Path((vault_id, liquidation_height, batch_index)): Path<(Txid, u32, u32)>,
494545
Query(query): Query<PaginationQuery>,
495546
Extension(ctx): Extension<Arc<AppContext>>,
496-
) -> Result<ApiPagedResponse<VaultAuctionBatchHistory>> {
547+
) -> Result<ApiPagedResponse<VaultAuctionBatchHistoryResponse>> {
497548
trace!(
498-
"Auction history for vault id {}, height {}, batch index {}",
549+
"Auction history for vault id {}, liquidation_height {}, batch index {}",
499550
vault_id,
500-
height,
551+
liquidation_height,
501552
batch_index
502553
);
503554
let next = query
504555
.next
505556
.map(|q| {
506-
let (height, txno) = parse_query_height_txno(&q)?;
507-
Ok::<(u32, usize), Error>((height, txno))
557+
let (height, txid) = parse_query_height_txid(&q)?;
558+
Ok::<(u32, Txid), Error>((height, txid))
508559
})
509560
.transpose()?
510-
.unwrap_or_default();
561+
.unwrap_or((liquidation_height, Txid::from_byte_array([0xffu8; 32])));
562+
563+
let size = if query.size > 0 { query.size } else { 30 };
511564

512-
let size = if query.size > 0 { query.size } else { 20 };
565+
let liquidation_block_expiry = match ctx.network {
566+
Network::Regtest => 36,
567+
_ => 720,
568+
};
513569

514570
let auctions = ctx
515571
.services
516572
.auction
517-
.by_height
573+
.by_id
518574
.list(
519-
Some((vault_id, batch_index, next.0, next.1)),
575+
Some((
576+
vault_id,
577+
batch_index.to_be_bytes(),
578+
next.0.to_be_bytes(),
579+
next.1,
580+
)),
520581
SortOrder::Descending,
521582
)?
522583
.take(size)
523584
.take_while(|item| match item {
524-
Ok((k, _)) => k.0 == vault_id && k.1 == batch_index,
585+
Ok((k, _)) => {
586+
k.0 == vault_id
587+
&& k.1 == batch_index.to_be_bytes()
588+
&& u32::from_be_bytes(k.2) > liquidation_height - liquidation_block_expiry
589+
}
525590
_ => true,
526591
})
527592
.map(|item| {
528-
let (_, id) = item?;
529-
530-
let auction = ctx
531-
.services
532-
.auction
533-
.by_id
534-
.get(&id)?
535-
.context(NotFoundSnafu {
536-
kind: NotFoundKind::Auction,
537-
})?;
538-
539-
Ok(auction)
593+
let (id, history) = item?;
594+
let address = from_script(&history.from, ctx.network)?;
595+
Ok(VaultAuctionBatchHistoryResponse::from(
596+
(id, history),
597+
address,
598+
))
540599
})
541600
.collect::<Result<Vec<_>>>()?;
542601

@@ -611,14 +670,17 @@ async fn map_liquidation_batches(
611670
};
612671
let id = (
613672
Txid::from_str(vault_id)?,
614-
batch.index,
673+
batch.index.to_be_bytes(),
674+
[0xffu8, 0xffu8, 0xffu8, 0xffu8],
615675
Txid::from_byte_array([0xffu8; 32]),
616676
);
617677
let bids = repo
618678
.by_id
619679
.list(Some(id), SortOrder::Descending)?
620680
.take_while(|item| match item {
621-
Ok(((vid, bindex, _), _)) => vid.to_string() == vault_id && bindex == &batch.index,
681+
Ok(((vid, bindex, _, _), _)) => {
682+
vid.to_string() == vault_id && bindex == &batch.index.to_be_bytes()
683+
}
622684
_ => true,
623685
})
624686
.collect::<Vec<_>>();

lib/ain-ocean/src/error.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ pub enum Error {
230230
#[snafu(implicit)]
231231
location: Location,
232232
},
233+
ToArrayError,
233234
#[snafu(display("{}", msg))]
234235
Other {
235236
msg: String,

lib/ain-ocean/src/indexer/auction.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,29 @@ impl Index for PlaceAuctionBid {
1616
trace!("[PlaceAuctionBid] Indexing...");
1717

1818
let auction = VaultAuctionBatchHistory {
19-
id: format!("{}-{}-{}", self.vault_id, self.index, ctx.tx.txid),
20-
key: format!("{}-{}", self.vault_id, self.index),
21-
sort: format!("{}-{}", ctx.block.height, ctx.tx_idx),
22-
vault_id: self.vault_id,
23-
index: ctx.tx_idx,
2419
from: self.from,
2520
amount: self.token_amount.amount,
2621
token_id: self.token_amount.token.0,
2722
block: ctx.block.clone(),
2823
};
2924
trace!("auction : {:?}", auction);
3025

31-
let key = (self.vault_id, self.index, ctx.tx.txid);
32-
services.auction.by_id.put(&key, &auction)?;
33-
services.auction.by_height.put(
34-
&(self.vault_id, self.index, ctx.block.height, ctx.tx_idx),
35-
&key,
36-
)
26+
let id = (
27+
self.vault_id,
28+
self.index.to_be_bytes(),
29+
ctx.block.height.to_be_bytes(),
30+
ctx.tx.txid,
31+
);
32+
services.auction.by_id.put(&id, &auction)
3733
}
3834

3935
fn invalidate(&self, services: &Arc<Services>, ctx: &Context) -> Result<()> {
4036
trace!("[PlaceAuctionBid] Invalidating...");
41-
services
42-
.auction
43-
.by_id
44-
.delete(&(self.vault_id, self.index, ctx.tx.txid))?;
45-
services.auction.by_height.delete(&(
37+
services.auction.by_id.delete(&(
4638
self.vault_id,
47-
self.index,
48-
ctx.block.height,
49-
ctx.tx_idx,
39+
self.index.to_be_bytes(),
40+
ctx.block.height.to_be_bytes(),
41+
ctx.tx.txid,
5042
))
5143
}
5244
}

lib/ain-ocean/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ pub struct BlockService {
4848

4949
pub struct AuctionService {
5050
by_id: VaultAuctionHistory,
51-
by_height: VaultAuctionHistoryByHeight,
5251
}
5352

5453
pub struct PoolService {
@@ -157,7 +156,6 @@ impl Services {
157156
},
158157
auction: AuctionService {
159158
by_id: VaultAuctionHistory::new(Arc::clone(&store)),
160-
by_height: VaultAuctionHistoryByHeight::new(Arc::clone(&store)),
161159
},
162160
result: TxResult::new(Arc::clone(&store)),
163161
pool: PoolService {

lib/ain-ocean/src/model/vault_auction_batch_history.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,11 @@ use serde::{Deserialize, Serialize};
33

44
use super::BlockContext;
55

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

98
#[derive(Serialize, Deserialize, Debug)]
109
#[serde(rename_all = "camelCase")]
1110
pub struct VaultAuctionBatchHistory {
12-
pub id: String,
13-
pub key: String,
14-
pub sort: String,
15-
pub vault_id: Txid,
16-
pub index: usize,
1711
pub from: ScriptBuf,
1812
pub amount: i64,
1913
pub token_id: u64,

lib/ain-ocean/src/storage/mod.rs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,7 @@ define_table! {
408408
}
409409
}
410410

411-
define_table! {
412-
#[derive(Debug)]
413-
pub struct VaultAuctionHistoryByHeight {
414-
key_type = model::AuctionHistoryByHeightKey,
415-
value_type = model::AuctionHistoryKey,
416-
},
417-
SecondaryIndex = VaultAuctionHistory
418-
}
419-
420-
pub const COLUMN_NAMES: [&str; 29] = [
411+
pub const COLUMN_NAMES: [&str; 28] = [
421412
Block::NAME,
422413
BlockByHeight::NAME,
423414
MasternodeStats::NAME,
@@ -446,5 +437,4 @@ pub const COLUMN_NAMES: [&str; 29] = [
446437
TransactionVout::NAME,
447438
TxResult::NAME,
448439
VaultAuctionHistory::NAME,
449-
VaultAuctionHistoryByHeight::NAME,
450440
];

0 commit comments

Comments
 (0)