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

feat(utxo-swap): add utxo burn output for non-kmd taker fee #2112

Open
wants to merge 97 commits into
base: dev
Choose a base branch
from

Conversation

dimxy
Copy link
Collaborator

@dimxy dimxy commented May 6, 2024

Adds a burn output sending 25% of the taker utxo DEX fee to a dedicated pre-burn address. Funds collected on the pre-burn address will be traded for KMD to burn them (thus additionally burning KMD supply).
This PR partially closes #2010

The requirements for this PR: #2269

In this PR:

  • split dex fee for non-kmd utxo coins (apart from zcoin) and added an output to the pre-burn account
  • old-style non-split dex fee non-kmd txns are also allowed in validation code (until all taker nodes upgraded) - this feature is removed in favour of version-based burning activation
  • refactored dex fee pubkey in params: instead of passing dex fee and burn pubkeys in function params new methods dex_pubkey() and burn_pubkey() were added to the SwapOps trait
  • add version to maker/taker negotiation message and activate burning for the new version
  • mocktopus was made optional dependency and activated only for development builds (as its doc suggests).
  • for the burn account no burn part is added (DexFee::Standard used)
  • sending burn part to the burn account for zcoin
  • sending burn part to the burn account for tendermint
  • fix burn pubkey
  • do not pay dex fee if taker is the dex pubkey (for non-privacy utxo)

NOTE: As mocktopus now is marked 'optional = true' in coins Cargo.toml and activated from the mm2_main crate by adding features = ["mocktopus"] in [dev-dependencies] section, you also need to mark your mockable code, called from other crates, this way: #[cfg_attr(feature = "mocktopus", mockable)], otherwise mocks won't work (see samples in code)

TODO:

  • fix burn zaddr (enable burn for zcoin)
  • disable non-split non-kmd dex fee (no burn output) validation when all taker nodes upgrade to new dex fee splitting

dimxy added 9 commits April 27, 2024 14:33
* dev:
  docs(README): remove outdated information from the README (#2097)
  fix(sia): fix sia compilation after hd wallet PR merge (#2103)
  feat(hd_wallet): utxo and evm hd wallet and trezor (#1962)
  feat(sia): initial Sia integration (#2086)
  fix(BCH): deserialize BCH header that uses KAWPOW version correctly (#2099)
  fix(eth_tests): remove ETH_DEV_NODE from tests (#2101)
@dimxy dimxy changed the title Add utxo burn output for non-kmd taker fee feat(utxo-swap): add utxo burn output for non-kmd taker fee May 6, 2024
* dev:
  feat(tendermint): pubkey-only activation and unsigned tx (#2088)
  fix(tests): set txfee for some tbtc tests (#2116)
  fix(eth): remove my_address from sign_and_send_transaction_with_keypair (#2115)
  fix(utxo-swap): apply events occurred while taker down (#2114)
  refactor(memory): memory usage improvements (#2098)
  feat(app-dir): implement root application dir `.kdf` (#2102)
  fix tendermint fee calculation (#2106)
  update dockerfile (#2104)
* dev:
  feat(ETH): eip1559 gas fee estimator and rpcs (#2051)
  fix(p2pk-tests): fix p2pk tests post merge (#2119)
  fix(p2pk): show and spend P2PK balance (#2053)
  fix(swap): use tmp file for swap and order files (#2118)
dimxy added 9 commits June 14, 2024 20:54
fix zhtlc send and spend tests
add should_burn_dex_fee method to indicate which coin has burn output
* dev:
  fix(indexeddb): window usage in worker env (#2131)
  feat(tx-history): handle encoded transaction values (#2133)
  fix(core): tendermint withdraws on hd accounts (#2130)
  fix(core): improve validation rules for table names (#2123)
  fix(test): improve log wait condition to fix taker restart test (#2125)
…er test

add timeout in wait for fee in qrc20 docker test
… docker test failed due to different dex fee values if trait default impl was used)
Copy link
Member

@laruh laruh left a comment

Choose a reason for hiding this comment

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

Great progress! Here is the first review iteration

mm2src/coins/lp_coins.rs Outdated Show resolved Hide resolved
mm2src/coins/lp_coins.rs Outdated Show resolved Hide resolved
mm2src/coins/lp_coins.rs Outdated Show resolved Hide resolved
mm2src/coins/lp_coins.rs Outdated Show resolved Hide resolved
mm2src/coins/lp_coins.rs Outdated Show resolved Hide resolved
dimxy added 2 commits June 19, 2024 13:05
use same ovk for dex fee and burn outputs
add sanity check for dex_fee in calc_burn_amount_for_op_return
let burn_amount = dex_fee - min_tx_amount;
(min_tx_amount.clone(), burn_amount)
} else {
(dex_fee.clone(), MmNumber::from(0))
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't this be (min_tx_amount.clone(), 0), if we reach this case then we know dex_fee is dust already.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

dex_fee is not dust in both calc_burn_amount_for_burn_account() and calc_burn_amount_for_op_return(): it was checked in the caller fn.

Comment on lines +3832 to +3833
// Default case where burn_amount is considered dust
(dex_fee.clone(), 0.into())
Copy link
Collaborator

Choose a reason for hiding this comment

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

similar to the case above, we don't know for sure here if dex_fee is dust or not though.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same as above: dexfee is not dust

Comment on lines +3820 to +3831
let new_fee = dex_fee * &MmNumber::from(Self::DEX_FEE_SHARE);
let burn_amount = dex_fee - &new_fee;
if &new_fee >= min_tx_amount && &burn_amount >= min_tx_amount {
// Use the max burn value, which is 25%. Ensure burn_amount is not dust
return (new_fee, burn_amount);
}
// If the new dex fee is dust set it to min_tx_amount and check the updated burn_amount is not dust.
let burn_amount = dex_fee - min_tx_amount;
if &new_fee < min_tx_amount && &burn_amount >= min_tx_amount {
// actually currently burn_amount (25%) < new_fee (75%) so this never happens. Added for a case if 25/75 will ever change
return (min_tx_amount.clone(), burn_amount);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

i find matches usually good for when the conditions get complicated:

match (dex_cut > min_tx_amount, burn_cut > min_tx_amount) {
    (true, true) => (dex_cut, burn_cut),
    (true, false) => (both_cuts, 0),
    (false, true) => (both_cuts, 0),
    (false, false) => (max(both_cuts, min_tx_amount), 0)
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, looks a bit unusual for me.
I guess, expressions like traditional boolean algebra logic are more comprehensible?

Comment on lines 490 to 495
#[cfg(feature = "run-docker-tests")]
if let Ok(env_pubkey) = std::env::var("TEST_DEX_FEE_ADDR_RAW_PUBKEY") {
unsafe {
TEST_DEX_FEE_ADDR_RAW_PUBKEY = Some(hex::decode(env_pubkey).expect("valid hex"));
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

i meant the static variable not the environment one


if taker_coin.is_kmd() {
// use a special dex fee option for kmd
let (fee_amount, burn_amount) = Self::calc_burn_amount_for_op_return(&dex_fee, &min_tx_amount);
Copy link
Collaborator

Choose a reason for hiding this comment

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

if we came to find the burn_amount = 0 in this branch we should return dex fee standard (just like the non-kmd counterpart), otherwise the code down the call tree will generate a tx with a zero op_return burn and spike the miner fee (tx size) for no reason.

tbh i think we should merge Standard & WithBurn to something general that has both dex and burn fee and to always check the burn (and dex) fee aren't zero before generating their output (legacy standard & dust burn would both have 0 burn fee).

Copy link
Collaborator

Choose a reason for hiding this comment

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

We can also use non-zero-u* for the burn field to make sure it's always set (if we don't wanna go to the route of merging both variants & checking for 0 at tx generation).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

if we came to find the burn_amount = 0 in this branch we should return dex fee standard

This changes already working code. I guess we could do this only as version activated feature

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

tbh i think we should merge Standard & WithBurn to something general

Eventually we will eliminate the Standard option (when all nodes are upgraded), so in fact this will be done.
For now I suggest to retain it as it would be easier to eliminated the code related to Standard.


pub fn is_active(feature: SwapFeature, version: u16) -> bool {
if let Some(found) = Self::SWAP_FEATURE_ACTIVATION.iter().find(|fv| fv.1 == feature) {
return version >= found.0;
Copy link
Collaborator

Choose a reason for hiding this comment

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

this always assumes that a remote version greater than activation version will always activation such a feature (but might we not disable it?). this is not the most extensible.

e.g.: what if we activated some feature in version 3 and disabled it in version 5, a version 3/4 peer will think the feature is active since 5 >= 3.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

added deactivation in 05feb72 (may be of use indeed)

Comment on lines 801 to 813
let remote_version = self
.r()
.data
.taker_version
.ok_or("No swap protocol version".to_owned())?;
let is_burn_active = SwapFeature::is_active(SwapFeature::SendToPreBurnAccount, remote_version);
let dex_fee = dex_fee_from_taker_coin(
self.taker_coin.deref(),
&self.r().data.maker_coin,
&taker_amount,
Some(self.r().other_taker_coin_htlc_pub.to_vec().as_ref()),
Some(is_burn_active),
);
Copy link
Collaborator

Choose a reason for hiding this comment

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

i don't think this would be dev-friendly to upgrade to the next feature set. I like the versioning mechanism and think we should have one, but also think it should be abstracted away in each entities impl (here DexFee).

so how i imagine something like this would be is: taker and maker settle on a version together (deterministically, pick the min version for e.g. or have a deterministic mapping rules), and we pass that version to whoever needs it to apply some version specific rules (in here this is the DexFee, so something like DexFee::using_version(version, taker_coin, maker_coin, etc...) and inside we match against the version and apply the appropriate rule),

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I started to do this but realised there is a problem here:
We support both legacy and TPU protocols, each of both may have own versioning. So it looks like it's better to deal with versions outside the lower level components like DexFee (which is called both from legacy and TPU), don't you think?

.r()
.data
.taker_version
.ok_or("No swap protocol version".to_owned())?;
Copy link
Collaborator

Choose a reason for hiding this comment

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

shouldn't this be unwrap_or(0)? or maybe just not let this be an option and default it to 0 right away.

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 reason why this taker_version is optional is because it is discovered on the negotiation phase.
I think it is not correct to set it to some specific version on the swap start.
Also, if it is not defined at this stage (wait_taker_fee) - I think this is a clear logic error and probably also not very good to default it to 0 or another version (we should determine it explicitly on the negotiation phase).

Comment on lines 189 to 197
TakerPayment(Vec<u8>),
}

// Extension to SwapMsg with version added to negotiation exchange
#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub enum SwapMsgExt {
NegotiationVersioned(NegotiationDataMsgVersion),
NegotiationReplyVersioned(NegotiationDataMsgVersion),
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

why not merge the new msgs into the old struct (and have a comment separating this is version x)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I did this on purpose: the old struct should be intact for old nodes to be able to parse it.
(I tried to test this though, in principle it could be tweaked to allow the merged struct to be parsed but I chose not to do this cause it involves knowledge about internal lib behaviour)

@@ -72,7 +72,7 @@ mm2_number = { path = "../mm2_number"}
mm2_p2p = { path = "../mm2_p2p" }
mm2_rpc = { path = "../mm2_rpc" }
mm2_state_machine = { path = "../mm2_state_machine" }
mocktopus = "0.8.0"
mocktopus = { version = "0.8.0", optional = true }
Copy link
Collaborator

Choose a reason for hiding this comment

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

from tests inside the crate -> dev-deps section
from tests from outside/integration -> for-test flag to activate it, this has the downside though as u said will enable all and every extra test features we have, but it's a for-test build anyway so i wouldn't worry much about that and instead prioritize having less complex cfgs around the code base.

@shamardy shamardy added the priority: high Important tasks that need attention soon. label Jan 14, 2025
Copy link
Collaborator

@shamardy shamardy left a comment

Choose a reason for hiding this comment

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

I have some minor comments. The review is still in progress, and I will provide more iterations for this PR throughout the week.

@@ -394,18 +394,14 @@ impl MarketCoinOps for SiaCoin {

fn min_trading_vol(&self) -> MmNumber { unimplemented!() }

fn should_burn_dex_fee(&self) -> bool { unimplemented!() }
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please set this to false for now c.c. @Alrighttt

@@ -296,6 +296,7 @@ pub fn select_unfinished_swaps_uuids(conn: &Connection, swap_type: u8) -> SqlRes

/// The SQL query selecting upgraded swap data and send it to user through RPC API
/// It omits sensitive data (swap secret, p2p privkey, etc) for security reasons
/// TODO: should we add burn amount for rpc?
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not needed as the taker/user only cares about the total amount they paid and not how it's used later. But I see that we only return the fee sent to the fee address and not total fee paid by the taker. You can open an issue for this to fix it later as it's not related to this PR.

mm2src/coins/z_coin.rs Outdated Show resolved Hide resolved
@shamardy
Copy link
Collaborator

@dimxy please resolve merge conflicts

Copy link
Member

@borngraced borngraced left a comment

Choose a reason for hiding this comment

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

One question regarding NoFee

Comment on lines +1059 to +1073
let fee_to_send_dex_fee = if matches!(dex_fee, DexFee::NoFee) {
TradeFee {
coin: self.taker_coin.ticker().to_owned(),
amount: MmNumber::from(0),
paid_from_trading_vol: false,
}
} else {
let fee_to_send_dex_fee_fut = self.taker_coin.get_fee_to_send_taker_fee(dex_fee.clone(), stage);
match fee_to_send_dex_fee_fut.await {
Ok(fee) => fee,
Err(e) => {
return Ok((Some(TakerSwapCommand::Finish), vec![TakerSwapEvent::StartFailed(
ERRL!("!taker_coin.get_fee_to_send_taker_fee {}", e).into(),
)]))
},
Copy link
Member

Choose a reason for hiding this comment

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

why not move this logic inside get_fee_to_send_taker_fee

if matches!(dex_fee, DexFee::NoFee) {
            TradeFee {
                coin: self.taker_coin.ticker().to_owned(),
                amount: MmNumber::from(0),
                paid_from_trading_vol: false,
            }
}

dimxy added 6 commits January 16, 2025 17:14
* dev: (35 commits)
  fix(crypto): allow non bip39 mnemonics storage (#2312)
  fix(legacy_swap): check for existing maker/taker payment before timeout (#2283)
  feat(tendermint): validators RPC (#2310)
  chore(CI): validate Cargo lock file (#2309)
  test(P2P): add test for peer time sync validation (#2304)
  fix mm2_p2p dev build (#2311)
  update Cargo.lock (#2308)
  chore(CI): unlock wasm-pack version (#2307)
  add `wasm` feature on WASM for timed-map (#2306)
  replace broken rpc link (#2305)
  chore(eth-websocket): remove some unnecessary wrappers (#2291)
  improvement(CI): switch to proper rust caching (#2303)
  fix(wasm): add test-ext-api feature to mm2_main and mm2_bin_lib tomls (#2295)
  chore(ci): Update docker build for wasm (#2294)
  chore(p2p): follow-up nits (#2302)
  feat(p2p): ensure time synchronization in the network (#2255)
  bump libp2p (#2296)
  chore(adex-cli): use "Komodo DeFi Framework" name in adex_cli  (#2290)
  chore(ctx): replace gstuff constructible with oncelock (#2267)
  don't rely on core (#2289)
  ...
Copy link
Member

@borngraced borngraced left a comment

Choose a reason for hiding this comment

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

Great work! I have one more review after this

Comment on lines +95 to +97
#[cfg(feature = "for-tests")]
pub static mut TEST_BURN_ADDR_RAW_PUBKEY: Option<Vec<u8>> = None;

Copy link
Member

@borngraced borngraced Jan 20, 2025

Choose a reason for hiding this comment

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

please can you move this down to where all const are declared? to avoid having declaration before import statements.

Q: TEST_BURN_ADDR_RAW_PUBKEY is read with run-docker-tests and for-tests features

why not initialize TEST_BURN_ADDR_RAW_PUBKEY with lazy_static once with docker-test and for-tests feature directives to avoid doing something like mutating/writing unsafe

Comment on lines 3594 to +3596
MmCoinEnum::SlpToken(ref c) => c.as_ref().rpc_client.is_native(),
#[cfg(all(not(target_arch = "wasm32"), feature = "zhtlc"))]
// TODO: we do not have such feature = "zhtlc" in toml. Remove this cfg part?
Copy link
Member

Choose a reason for hiding this comment

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

Yes, I believe it can be removed.
#[cfg(not(target_arch = "wasm32"))] should be enough

Comment on lines +956 to +958
let activated_priv_key = if let Ok(activated_priv_key) = self.activation_policy.activated_key_or_err() {
activated_priv_key
} else {
Copy link
Member

Choose a reason for hiding this comment

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

why?

Comment on lines +1043 to +1045
let priv_key = if let Some(priv_key) = priv_key {
priv_key
} else {
Copy link
Member

Choose a reason for hiding this comment

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

same as above

Comment on lines +1117 to +1120
let account_prefix = self.account_prefix.clone();
let base_account = match BaseAccount::decode(account.value.as_slice()) {
Ok(account) => account,
Err(err) if &self.account_prefix == "iaa" => {
Err(err) if account_prefix.as_str() == "iaa" => {
Copy link
Member

Choose a reason for hiding this comment

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

why?


pub const PROXY_REQUEST_EXPIRATION_SEC: i64 = 15;

lazy_static! {
pub static ref DEX_FEE_ADDR_RAW_PUBKEY: Vec<u8> =
hex::decode(DEX_FEE_ADDR_PUBKEY).expect("DEX_FEE_ADDR_PUBKEY is expected to be a hexadecimal string");
pub static ref DEX_BURN_ADDR_RAW_PUBKEY: Vec<u8> =
hex::decode(DEX_BURN_ADDR_PUBKEY).expect("DEX_BURN_ADDR_PUBKEY is expected to be a hexadecimal string");
}
Copy link
Member

Choose a reason for hiding this comment

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

I believe TEST_DEX_BURN_ADDR_RAW_PUBKEY belongs here...

use common::executor::Timer;
use common::log::{debug, error, info, warn};
use common::{bits256, now_ms, now_sec, wait_until_sec, DEX_FEE_ADDR_RAW_PUBKEY};
use common::{bits256, env_var_as_bool, now_ms, now_sec, wait_until_sec};
Copy link
Member

Choose a reason for hiding this comment

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

env_var_as_bool unused?

Comment on lines +913 to +918
/// NegotiationDataMsg with version
#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub struct NegotiationDataMsgVersion {
version: u16,
msg: NegotiationDataMsg,
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// NegotiationDataMsg with version
#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub struct NegotiationDataMsgVersion {
version: u16,
msg: NegotiationDataMsg,
}
/// NegotiationDataMsg with version
#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub struct NegotiationDataMsgWithVersion {
version: u16,
msg: NegotiationDataMsg,
}

NegotiationDataMsgWithVersion is a better name

Comment on lines +920 to +936
impl NegotiationDataMsgVersion {
pub fn version(&self) -> u16 { self.version }

pub fn started_at(&self) -> u64 { self.msg.started_at() }

pub fn payment_locktime(&self) -> u64 { self.msg.payment_locktime() }

pub fn secret_hash(&self) -> &[u8] { self.msg.secret_hash() }

pub fn maker_coin_htlc_pub(&self) -> &[u8] { self.msg.maker_coin_htlc_pub() }

pub fn taker_coin_htlc_pub(&self) -> &[u8] { self.msg.taker_coin_htlc_pub() }

pub fn maker_coin_swap_contract(&self) -> Option<&[u8]> { self.msg.maker_coin_swap_contract() }

pub fn taker_coin_swap_contract(&self) -> Option<&[u8]> { self.msg.taker_coin_swap_contract() }
}
Copy link
Member

Choose a reason for hiding this comment

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

these are redundancy, we should remove or is there a reason why we can't make msg and version pub?

Comment on lines +459 to +467
#[cfg(feature = "run-docker-tests")]
let version = if !env_var_as_bool("USE_OLD_VERSION_MAKER") {
LEGACY_SWAP_MSG_VERSION
} else {
0 // use old version for tests
};

#[cfg(not(feature = "run-docker-tests"))]
let version = LEGACY_SWAP_MSG_VERSION;
Copy link
Member

Choose a reason for hiding this comment

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

can this be extracted to a separate inline function and reuse in taker_swap too?

/// NegotiationDataMsg with version
#[derive(Clone, Debug, Eq, Deserialize, PartialEq, Serialize)]
pub struct NegotiationDataMsgVersion {
version: u16,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As our discussion about versioning is inclining to put maker and taker version into orders, maybe we don't need this version field.

Copy link
Member

@laruh laruh Jan 21, 2025

Choose a reason for hiding this comment

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

As our discussion about versioning is inclining to put maker and taker version into orders, maybe we don't need this version field.

I believe if we currently don’t require such feature, it’s better to leave it out for now. We can always introduce it later when we are sure that negotiation version support is necessary. This helps keep things simpler and avoids adding unused fields/types.

Copy link
Member

@laruh laruh left a comment

Choose a reason for hiding this comment

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

Thanks for the updates, here is quick note I want to cover

Comment on lines 129 to 130
/// Swap message exchange version supported by remote taker peer. Optional because it is found at negotiation
pub taker_version: Option<u16>,
Copy link
Member

Choose a reason for hiding this comment

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

Why you didnt use skip_serializing_if annotation? Not sure its safe to not to use it, please re check it.
Also Its better to rename field to taker_negotiation_msg_v. It is clearer.

Same for LEGACY_SWAP_MSG_VERSION. Its about negotiation msg version, not all swap p2p messages. Should be LEGACY_SWAP_NEGOTIATION_MSG_V

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Its about negotiation msg version, not all swap p2p messages.

Not quite: it's about the swap message version supported by a party. I meant it for the whole message set used in the swap, not only negotiation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Why you didnt use skip_serializing_if annotation?

skip_serializing_if does not matter for rmp (checked with a test sample).
There is also the same var in the MakerSwapData struct. Not sure it's worth adding skip_serializing_if there: IMO it's easier to analyse swap jsons if "taker_version": null present, don't you think?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also Its better to rename field to taker_negotiation_msg_v. It is clearer.

I renamed it to taker_msg_version and maker_msg_version 897aa4d.
It's worth renaming indeed but I did not like losing the key work 'version'. Also did not add 'negotiation' considering the above

Copy link
Member

@laruh laruh Jan 22, 2025

Choose a reason for hiding this comment

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

Its about negotiation msg version, not all swap p2p messages.

Not quite: it's about the swap message version supported by a party. I meant it for the whole message set used in the swap, not only negotiation

I think then it doesnt make sense, p2p message versions (I mean all topic related messages) are handled in process_p2p_message. If you change p2p msg version it means user should be subscribed to another topic version

let mut split = message.topic.as_str().split(TOPIC_SEPARATOR);
match split.next() {
Some(lp_ordermatch::ORDERBOOK_PREFIX) => {
if let Err(e) = lp_ordermatch::handle_orderbook_msg(
ctx.clone(),
&message.topic,
peer_id.to_string(),
&message.data,
i_am_relay,
)
.await
{
if e.get_inner().is_warning() {
log::warn!("{}", e);
} else {
log::error!("{}", e);
}
return;
}
to_propagate = true;
},
Some(lp_swap::SWAP_PREFIX) => {
if let Err(e) =
lp_swap::process_swap_msg(ctx.clone(), split.next().unwrap_or_default(), &message.data).await

You added version field in Negotiation msg of legacy swap topic, which belongs to SWAP_PREFIX.
But when we change all p2p messages version, it means we need to create a new topic, what we actually did for SWAP_V2_PREFIX
image

I dont get why we would need version inside the "swap" msg topic. to be able to version this topic?

mm2src/coins/solana.rs Outdated Show resolved Hide resolved
mm2src/coins/solana/spl.rs Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: high Important tasks that need attention soon. status: pending review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants