-
Notifications
You must be signed in to change notification settings - Fork 15
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
bug: change_utxo not always present #5340
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5340 +/- ##
======================================
- Coverage 71% 71% -0%
======================================
Files 494 494
Lines 86142 86037 -105
Branches 86142 86037 -105
======================================
- Hits 61164 60976 -188
- Misses 22245 22298 +53
- Partials 2733 2763 +30 ☔ View full report in Codecov by Sentry. |
state-chain/runtime/src/chainflip.rs
Outdated
batch_transfer.change_utxo_key, | ||
); | ||
} else { | ||
log_or_panic!("Keys do not match, no change_utxo available"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a weird message and also shouldn't panic in debug? I think we should just log "Witnessed BTC egress without change UTXO"
state-chain/runtime/src/lib.rs
Outdated
let outputs = batch_transfer.bitcoin_transaction.outputs; | ||
let change_output = outputs.last().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could just directly be
let change_output = batch_transfer.bitcoin_transaction.outputs.last().unwrap();
small comment, otherwise looks good (apart from Martin's comment). |
state-chain/runtime/src/chainflip.rs
Outdated
if ScriptPubkey::Taproot(batch_transfer.change_utxo_key) == | ||
change_output.script_pubkey | ||
{ | ||
Environment::add_bitcoin_change_utxo( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also consider checking against the previous_pubkey: imagine we send a tx before but witness it after a rotation/key handover.
Also: Maybe we should do this check for each of the outputs?
For example imagine someone sends funds to the vault (I don't know why...)
ie we could do:
for output in outputs {
if [vault.current_key, vault.previous_key].contains(output.address) {
// add to utxos
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively: we encode the change amount directly in the BatchTransfer type, then we don't need to parse anything from the utxos.
(ie. we change the type to:
pub struct BatchTransfer {
pub bitcoin_transaction: BitcoinTransaction,
// Use a struct:
pub change_utxo_details: (
[u8; 32], VOut, TxId, Amount
),
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think Dan's first suggestions is best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont understand why we need to check all the outputs? The change utxo will always be the last output due to how the tx is constructed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Anyone can open a channel sending funds to the vault. (could be by accident, could be on purpose: maybe we want to top up the vault?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But why would that change the order of the outputs of the tx? When we create a btc tx, we select some utxos from the vault, and create output utxos (transfers, and possibly change utxo appended at the end), and save this output utxo list in the BitcoinTransaction
type. So when the tx is successfully signed, we then take the change utxo and add it to the available utxo list which is what we are doing here. I dont see how someone sending funds to the vault is relevant here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imagine I request a swap with the BTC vault as the destination address. Then we construct a transaction with two outputs, both of which will go into the vault. Pretty theoretical example, but this code clearly does the right thing, whereas just checking the last output adds a lot of unnecessary assumptions that might break in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that theoretical example, i would say that the right thing to do is not egress at all because you are basically taking a utxo from the vault, splitting it in two and sending it back to the vault (which is pointless if not actually harmful because we are splitting utxos) and so instead of allowing the egress to happen and deal with it here in an indirect way, I would just not egress.
The code here is specifically to add the change utxo to the available utxo list and is tightly coupled with the code of creating btc tx. I dont think we are making assumptions here because we construct the btc tx a certain way (putting the change utxo at the end) and until we change how we construct btc tx, this should always be the case.
0b0ba6a
to
94c44cc
Compare
let btc_key = pallet_cf_threshold_signature::Pallet::<Runtime, BitcoinInstance>::keys( | ||
pallet_cf_threshold_signature::Pallet::<Runtime, BitcoinInstance>::current_key_epoch() | ||
.expect("We should always have an epoch set")).expect("We should always have a key set for the current epoch"); | ||
for ceremony in btc_ceremonies { | ||
if let RuntimeCall::BitcoinBroadcaster(pallet_cf_broadcast::pallet::Call::on_signature_ready{ api_call, ..}) = pallet_cf_threshold_signature::RequestCallback::<Runtime, BitcoinInstance>::get(ceremony).unwrap() { | ||
if let BitcoinApi::BatchTransfer(batch_transfer) = *api_call { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of doing all this it might be nicer to just store the change utxo somewhere else on-chain temporarily and then move it back to the utxo set when it's ready...
This also would avoid needing to reconstruct it, removing another source of assumptions.
(can wait for another time though)
…waps-close-accounts * origin/main: (44 commits) fix: expire all previous epochs (#5279) feat: add/update contract swaps parameters (#5343) chore: add address to solana logging (#5353) fix: ignore dust underflows in order fills rpc (#5352) chore: consistent naming prewitnessed (#5351) feat: engine-runner verifies gpg signature of old dylib when downloaded (#5339) feat: tainted transaction reporting (#5310) bug: change_utxo not always present (#5340) feat: structured error return types for rpcs (#5346) chore: unify dependencies to root cargo.toml (#5333) feat: Submit a slot number alongside nonce (#5297) chore: use node version from `.nvmrc` 📌 (#5336) chore: add engine account_info logging (#5347) chore: replace manual scale encoding for ts-scale (#5335) chore: more consistent params in Broker API (#5342) feat: broker can encode btc smart contract call (#5329) chore: localnet recreate script can use defaults (#5338) feat: witnessing btc smart contract swaps (#5331) feat: Solana CCM fallback (#5316) fix: scale types for pending ceremonies (#5286) ... # Conflicts: # Cargo.lock # state-chain/chains/src/sol/api.rs # state-chain/pallets/cf-broadcast/src/migrations.rs # state-chain/pallets/cf-environment/Cargo.toml
* fix bug: change_utxo not always present Add logic to btc_utxos_balance rpc * change comment * fmt * update logic in the rpc to match the callback * address comments * use log::info! * address comments: check old key as well * update rpc btc_utxos
* fix bug: change_utxo not always present Add logic to btc_utxos_balance rpc * change comment * fmt * update logic in the rpc to match the callback * address comments * use log::info! * address comments: check old key as well * update rpc btc_utxos
Add logic to btc_utxos_balance rpc
Pull Request
Closes: PRO-1716, PRO-1739
Checklist
Please conduct a thorough self-review before opening the PR.
Summary
Please include a succinct description of the purpose and content of the PR. What problem does it solve, and how? Link issues, discussions, other PRs, and anything else that will help the reviewer.
Non-Breaking changes