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

bug: change_utxo not always present #5340

Merged
merged 8 commits into from
Oct 24, 2024
Merged

bug: change_utxo not always present #5340

merged 8 commits into from
Oct 24, 2024

Conversation

marcellorigotti
Copy link
Contributor

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.

  • I am confident that the code works.
  • I have written sufficient tests.
  • I have written and tested required migrations.
  • I have updated documentation where appropriate.

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

@marcellorigotti marcellorigotti added the non-breaking Merging this PR will create a cherry-pick onto release label Oct 18, 2024
@marcellorigotti marcellorigotti marked this pull request as ready for review October 18, 2024 12:22
Copy link

codecov bot commented Oct 18, 2024

Codecov Report

Attention: Patch coverage is 45.23810% with 23 lines in your changes missing coverage. Please review.

Project coverage is 71%. Comparing base (09f7507) to head (94c44cc).
Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
state-chain/runtime/src/lib.rs 8% 0 Missing and 23 partials ⚠️
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.
📢 Have feedback on the report? Share it here.

@marcellorigotti marcellorigotti changed the title Feature/pro 1716 bug: change_utxo not always present Oct 18, 2024
batch_transfer.change_utxo_key,
);
} else {
log_or_panic!("Keys do not match, no change_utxo available");
Copy link
Contributor

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"

Comment on lines 2097 to 2098
let outputs = batch_transfer.bitcoin_transaction.outputs;
let change_output = outputs.last().unwrap();
Copy link
Contributor

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();

@ramizhasan111
Copy link
Contributor

small comment, otherwise looks good (apart from Martin's comment).

state-chain/runtime/src/chainflip.rs Outdated Show resolved Hide resolved
state-chain/runtime/src/chainflip.rs Outdated Show resolved Hide resolved
Comment on lines 824 to 827
if ScriptPubkey::Taproot(batch_transfer.change_utxo_key) ==
change_output.script_pubkey
{
Environment::add_bitcoin_change_utxo(
Copy link
Collaborator

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
	}
}

@martin-chainflip ?

Copy link
Collaborator

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
	),
}

Copy link
Contributor

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.

Copy link
Contributor

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?

Copy link
Collaborator

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?)

Copy link
Contributor

@ramizhasan111 ramizhasan111 Oct 24, 2024

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Comment on lines +2114 to +2119
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 {
Copy link
Collaborator

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)

@dandanlen dandanlen added this pull request to the merge queue Oct 24, 2024
Merged via the queue into main with commit 734c419 Oct 24, 2024
48 of 49 checks passed
@dandanlen dandanlen deleted the feature/pro-1716 branch October 24, 2024 11:51
syan095 added a commit that referenced this pull request Oct 29, 2024
…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
dandanlen pushed a commit that referenced this pull request Oct 30, 2024
* 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
dandanlen pushed a commit that referenced this pull request Oct 31, 2024
* 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
non-breaking Merging this PR will create a cherry-pick onto release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants