Conversation
There was a problem hiding this comment.
there was a bug when messages was overwriting itself
There was a problem hiding this comment.
I removed must_match and used escrow_public + address_prefix so I can easily use validate_pskts in the demo
There was a problem hiding this comment.
I added validation to the demo (without any hub call though)
There was a problem hiding this comment.
I created this function to build WithdrawFXG without any hub calls
a975f39 to
b7e36bc
Compare
| .map_err(|e| eyre::eyre!("Estimate TX mass: {e}"))?; | ||
|
|
||
| // Apply TX mass multiplier and feerate | ||
| let tx_fee = (tx_mass as f64 * TX_MASS_MULTIPLIER * feerate).round() as u64; |
| Ok((anchor_input, escrow_inputs)) | ||
| } | ||
|
|
||
| fn estimate_mass( |
There was a problem hiding this comment.
I updated estimate_fee (now it is estimate_mass) to use a different MassCalculator which kaspa is using in the tx generator. I found it more accurate and I stopped getting insufficient fee errors.
| let tx_id = pskt.calculate_id(); | ||
|
|
||
| // If there are no messages and payload is empty, then the PSKT | ||
| // is a sweeping tx which does not spend the anchor | ||
| let tx_type = if expected_messages.is_empty() && pskt.global.payload.is_none() { | ||
| info!("PSKT is a sweeping tx: {tx_id}"); | ||
| TxType::Sweeping | ||
| } else { | ||
| info!("PSKT is a withdrawal tx: {tx_id}"); | ||
| TxType::Withdrawal | ||
| }; | ||
|
|
||
| let ix = validate_pskt_application_semantics( | ||
| &pskt, | ||
| must_spend, | ||
| tx_type, | ||
| expected_messages, | ||
| escrow_public, | ||
| address_prefix, | ||
| )?; | ||
|
|
||
| match tx_type { | ||
| // In case of the sweeping tx, try to spend the anchor in the next PSKT | ||
| TxType::Sweeping => Ok(must_spend), | ||
| TxType::Withdrawal => Ok(TransactionOutpoint::new(pskt.calculate_id(), ix)), | ||
| } |
There was a problem hiding this comment.
This config worked for me, maybe worth copying from https://github.com/dymensionxyz/hyperlane-deployments/blob/main/playground/guide_kaspa_kas/roles/relayer/agent-config.json
| let args = Args::parse(); | ||
| let mut args = Args::parse(); | ||
|
|
||
| args.wallet_secret = Some("123456qwe".to_string()); |
danwt
left a comment
There was a problem hiding this comment.
Great work! Just a few clarifying questions
| let utxos = rpc | ||
| .get_utxos_by_addresses(vec![addr.clone()]) | ||
| .await | ||
| .map_err(|e| Error::Custom(format!("Getting balance for address: {e}")))?; | ||
| .map_err(|e| Error::Custom(format!("Getting UTXOs for address: {e}")))?; | ||
|
|
||
| let num = utxos.len(); | ||
| let balance: u64 = utxos.into_iter().map(|u| u.utxo_entry.amount).sum(); | ||
|
|
||
| info!("{} has {} UTXOs and {} balance", source, num, balance); | ||
|
|
||
| info!("{} balance: {}", source, balance); | ||
| Ok(balance) |
There was a problem hiding this comment.
@keruch what was wrong with the old way?
There was a problem hiding this comment.
nothing, I just wanted to know the number of UTXOs
| // Add this small priproty fee to every sweeping TX to ensure the sufficient fee even if there | ||
| // is one validator. 3_000 is a magic number. | ||
| // TODO: make it configurable? | ||
| pub const RELAYER_SWEEPING_PRIORITY_FEE: u64 = 3_000; |
There was a problem hiding this comment.
not sure, that's why I think it's worth making it configurable. 3000 is just what I came up with while testing.
| let tx_hash = h512_to_cosmos_hash(outcome.transaction_id).encode_hex_upper::<String>(); | ||
|
|
||
| if !outcome.executed { | ||
| return Err(eyre::eyre!( | ||
| "Indicate progress failed, TX was not executed on-chain, tx hash: {tx_hash}" | ||
| )); | ||
| } | ||
|
|
||
| info!( | ||
| "Dymension, indicated progress on hub: {:?}, outcome: {:?}", | ||
| fxg.progress_indication, outcome | ||
| "Dymension, indicated progress on hub: {:?}, outcome: {:?}, tx hash: {:?}", | ||
| fxg.progress_indication, outcome, tx_hash, | ||
| ); |
| let messages = { | ||
| let sweep_count = sweeping_bundle.as_ref().map_or(0, |b| b.0.len()); | ||
| let mut messages = Vec::with_capacity(sweep_count + valid_msgs.len()); | ||
| messages.extend(vec![Vec::new(); sweep_count]); |
There was a problem hiding this comment.
vec![V; N] (with semicolon) is a macro to create a vector of V repeated N times. so with vec![Vec::new(); sweep_count] I create a vector of sweep_count empty vectors, ie [[], [], [], ...].
| _ => {} | ||
| } | ||
|
|
||
| let payload_expect = MessageIDs::from(expected_messages).to_bytes(); |
There was a problem hiding this comment.
the payload check still works properly? i.e. sweep is checked to be empty?
There was a problem hiding this comment.
yes! it's here
hyperlane-monorepo/dymension/libs/kaspa/lib/validator/src/withdraw.rs
Lines 274 to 280 in 78be165
|
|
||
| // If there are no messages and payload is empty, then the PSKT | ||
| // is a sweeping tx which does not spend the anchor | ||
| let tx_type = if expected_messages.is_empty() && pskt.global.payload.is_none() { |
There was a problem hiding this comment.
is this clause strictly needed?
&& pskt.global.payload.is_none()
it's confusing me
i think the code will still be correct without this?
There was a problem hiding this comment.
I wanted to distinguish between sweeping and withdrawal TXs in the validation. In case of sweeping, we don't want the anchor to be an input. In case of withdrawal, we do.
hyperlane-monorepo/dymension/libs/kaspa/lib/validator/src/withdraw.rs
Lines 329 to 340 in 78be165
There was a problem hiding this comment.
Right, but I mean, you can check expected messages empty, there is no need to check the payload too in this if statement?
It makes it harder to understand IMO because then there is the payload correctness check in the next function clal
There was a problem hiding this comment.
the payload correctness check in the next function
now I got it! fixed
- Changed PopulatedInput to include optional redeem_script as third element - Keep signature_script empty for unsigned transactions (as it should be) - Store redeem_script separately and only add to PSKT when needed - Update all usages to handle the new tuple structure This fixes the semantic confusion where redeem_script was incorrectly stored in the signature_script field of TransactionInput.
#214