Skip to content

Commit 3a25fca

Browse files
committed
taker(api2): support manually selected makers and fix bad-maker checks
Signed-off-by: Abhay349 <[email protected]>
1 parent 878cf12 commit 3a25fca

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed

src/bin/taker.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ fn main() -> Result<(), TakerError> {
228228
tx_count: 1,
229229
required_confirms: 1,
230230
manually_selected_outpoints: None,
231+
manually_selected_makers: None,
231232
};
232233
taproot_taker.do_coinswap(taproot_swap_params)?;
233234
}

src/taker/api2.rs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ pub struct SwapParams {
9595
pub required_confirms: u32,
9696
/// User selected UTXOs (optional, for manual UTXO selection)
9797
pub manually_selected_outpoints: Option<Vec<OutPoint>>,
98+
/// Optional list of maker addresses explicitly selected by the user for the swap.
99+
/// If set, the taker will only attempt to use these makers instead of selecting
100+
/// from the offerbook automatically.
101+
pub manually_selected_makers: Option<Vec<MakerAddress>>,
98102
}
99103

100104
#[derive(Clone)]
@@ -738,6 +742,13 @@ impl Taker {
738742

739743
/// Choose makers for the swap by negotiating with them
740744
fn choose_makers_for_swap(&mut self, swap_params: SwapParams) -> Result<(), TakerError> {
745+
if let Some(ref makers) = swap_params.manually_selected_makers {
746+
if makers.len() != swap_params.maker_count {
747+
return Err(TakerError::General(
748+
"Number of manually selected makers must equal maker_count".to_string(),
749+
));
750+
}
751+
}
741752
// Find suitable maker asks for an offer from the makers
742753
let mut suitable_makers = self.find_suitable_makers(&swap_params);
743754
log::info!(
@@ -758,6 +769,9 @@ impl Taker {
758769

759770
// Set swap params early so they're available for SwapDetails
760771
self.ongoing_swap_state.swap_params = swap_params.clone();
772+
if let Some(manual_makers) = &swap_params.manually_selected_makers {
773+
return self.choose_manual_makers(manual_makers);
774+
}
761775

762776
// Send SwapDetails message to all the makers
763777
// Receive the Ack or Nack message from the maker
@@ -881,7 +895,89 @@ impl Taker {
881895

882896
Ok(())
883897
}
898+
fn choose_manual_makers(&mut self, manual_makers: &[MakerAddress]) -> Result<(), TakerError> {
899+
for (chain_position, maker_addr) in manual_makers.iter().enumerate() {
900+
// Find maker in offerbook
901+
let maker = self
902+
.offerbook
903+
.active_makers(&MakerProtocol::Taproot)
904+
.into_iter()
905+
.find(|oa| &oa.address == maker_addr)
906+
.ok_or_else(|| {
907+
TakerError::General(format!("Maker {} not found in offerbook", maker_addr))
908+
})?;
909+
910+
// Reject bad makers
911+
if self.offerbook.is_bad_maker(&maker) {
912+
return Err(TakerError::General(format!(
913+
"Maker {} is marked as bad",
914+
maker.address
915+
)));
916+
}
884917

918+
// Perform the same GetOffer + SwapDetails handshake
919+
let get_offer_msg = GetOffer {
920+
id: self.ongoing_swap_state.id.clone(),
921+
protocol_version_min: 1,
922+
protocol_version_max: 1,
923+
number_of_transactions: 1,
924+
};
925+
926+
let response = self.send_to_maker_and_get_response(
927+
&maker.address,
928+
TakerToMakerMessage::GetOffer(get_offer_msg),
929+
)?;
930+
931+
match response {
932+
MakerToTakerMessage::RespOffer(fresh_offer) => {
933+
let mut maker = maker.clone();
934+
maker.offer.tweakable_point = fresh_offer.tweakable_point;
935+
936+
let maker_timelock = REFUND_LOCKTIME
937+
+ REFUND_LOCKTIME_STEP
938+
* (self.ongoing_swap_state.swap_params.maker_count - chain_position - 1)
939+
as u16;
940+
941+
let swap_details = SwapDetails {
942+
id: self.ongoing_swap_state.id.clone(),
943+
amount: self.ongoing_swap_state.swap_params.send_amount,
944+
no_of_tx: self.ongoing_swap_state.swap_params.tx_count as u8,
945+
timelock: maker_timelock,
946+
};
947+
948+
let ack = self.send_to_maker_and_get_response(
949+
&maker.address,
950+
TakerToMakerMessage::SwapDetails(swap_details),
951+
)?;
952+
953+
match ack {
954+
MakerToTakerMessage::AckResponse(AckResponse::Ack) => {
955+
self.ongoing_swap_state.chosen_makers.push(maker);
956+
}
957+
_ => {
958+
return Err(TakerError::General(format!(
959+
"Maker {} rejected swap",
960+
maker.address
961+
)));
962+
}
963+
}
964+
}
965+
_ => {
966+
return Err(TakerError::General(format!(
967+
"Unexpected response from maker {}",
968+
maker.address
969+
)));
970+
}
971+
}
972+
}
973+
974+
// Init storage
975+
let n = self.ongoing_swap_state.chosen_makers.len();
976+
self.ongoing_swap_state.maker_outgoing_privkeys = vec![None; n];
977+
self.ongoing_swap_state.maker_contract_txs = vec![Vec::new(); n];
978+
979+
Ok(())
980+
}
885981
/// Fetch offers from available makers
886982
/// This syncs the offerbook first and then returns a reference to it
887983
pub fn fetch_offers(&mut self) -> Result<OfferBook, TakerError> {

0 commit comments

Comments
 (0)