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

Fix: Correct Select Median Implementation #3934

Merged
merged 2 commits into from Sep 4, 2023
Merged

Fix: Correct Select Median Implementation #3934

merged 2 commits into from Sep 4, 2023

Conversation

msgmaxim
Copy link
Contributor

@msgmaxim msgmaxim commented Sep 1, 2023

Pull Request

Closes: PRO-805

Checklist

Please conduct a thorough self-review before opening the PR.

  • I am confident that the code works.
  • I have updated documentation where appropriate.

Summary

As proposed in PRO-805, I changed the code to decode values before select_median (which now requires Ord rather than Encode/Decode), so now the comparison is done on integers correctly. For BTC, the median is selected for each field independently.

@linear
Copy link

linear bot commented Sep 1, 2023

PRO-805 [BUG] Median value is computed incorrectly in witnessing

select_median from decompose_recompose.rs which we use to derive a value "agreed on" by all witnessers is using Scale encoded values when sorting, but that doesn't really work. Specifically for integers Scale uses little endian which means the bytes are "out of order".

For example, given values [1, 8, 32, 256, 768] it returns 1 (the smallest value in this case):

#[test]
fn select_median_test() {
	let mut values = [1_u16, 8, 32, 256, 768].into_iter().map(|v| v.encode()).collect::<Vec<_>>();
	assert_eq!(select_median::<u16>(&mut values).unwrap(), 1);
}

I noticed that we have test_medians tests, but we only test values < 255 where byte order doesn't matter.

For multi-field values (e.g. BitcoinFeeInfo used in bitcoin witnessing) this obviously doesn't work either since sorting will essentially be done on the field encoded first, and the other two will effectively be selected arbitrarily. (This means for example, that you can keep submitting rubbish for the other fields and we will eventually accept them).

daniel kylezs

@codecov
Copy link

codecov bot commented Sep 1, 2023

Codecov Report

Merging #3934 (d2a5ee2) into main (3cfdab0) will increase coverage by 1%.
Report is 9 commits behind head on main.
The diff coverage is 98%.

@@          Coverage Diff           @@
##            main   #3934    +/-   ##
======================================
+ Coverage     71%     73%    +1%     
======================================
  Files        366     367     +1     
  Lines      56773   56037   -736     
  Branches   56773   56037   -736     
======================================
+ Hits       40554   40634    +80     
+ Misses     14210   13345   -865     
- Partials    2009    2058    +49     
Files Changed Coverage Δ
...chain/runtime/src/chainflip/decompose_recompose.rs 98% <98%> (+3%) ⬆️
state-chain/pallets/cf-witnesser/src/lib.rs 80% <100%> (+2%) ⬆️

... and 77 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

// working correctly previously, so this serves as a regression test:
#[test]
fn select_median_multi_bytes_ints() {
let values = vec![1_u16, 8, 32, 256, 768];
Copy link
Contributor

Choose a reason for hiding this comment

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

we should also test when they're not in order

Copy link
Contributor

Choose a reason for hiding this comment

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

also here, good practice to test base case of empty (especially when removing the empty check would result in a panic)

// For BTC, we witness multiple values, and median should be
// selected for each value independently:
#[test]
fn select_median_btc_info_test() {
Copy link
Contributor

@kylezs kylezs Sep 1, 2023

Choose a reason for hiding this comment

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

we should have a test for when the input is empty, that it returns None + doesn't panic

@msgmaxim msgmaxim enabled auto-merge (squash) September 4, 2023 00:37
@msgmaxim msgmaxim merged commit a5205b9 into main Sep 4, 2023
42 checks passed
@msgmaxim msgmaxim deleted the fix/select_median branch September 4, 2023 01:12
syan095 added a commit that referenced this pull request Sep 4, 2023
* origin/main:
  Fix: Correct Select Median Implementation (#3934)
  fix: independent witnessing startup (#3913)
  🍒 cherry-pick: changes in release for CI and chainspec (#3933)
  refactor: Re-arrange Chains traits for better composability (#3912)
  fix: log error when we try to transfer *more* than we have fetched (#3930)
  chore: add checks and increase timeout (#3928)
  Add `bind_redeem_address` to CLI (#3908)
  🍒 cherry-pick: add missing prod dockerfiles (#3926)
  chore: skip localnet specific tests in devnet 🤫 (#3919)
  fix: broadcast success should be witnessable after a rotation (#3921)

# Conflicts:
#	state-chain/chains/src/eth/api.rs
#	state-chain/runtime/src/chainflip.rs
syan095 added a commit that referenced this pull request Sep 5, 2023
…on-integration

* origin/main:
  Added CFE setting for logging span lifecycles (#3936)
  fix: only burn flip if non zero (#3932)
  Fix: Correct Select Median Implementation (#3934)
  fix: independent witnessing startup (#3913)
  🍒 cherry-pick: changes in release for CI and chainspec (#3933)
  refactor: Re-arrange Chains traits for better composability (#3912)
  fix: log error when we try to transfer *more* than we have fetched (#3930)
  chore: add checks and increase timeout (#3928)
  Add `bind_redeem_address` to CLI (#3908)
  🍒 cherry-pick: add missing prod dockerfiles (#3926)
  chore: skip localnet specific tests in devnet 🤫 (#3919)
  fix: broadcast success should be witnessable after a rotation (#3921)

# Conflicts:
#	state-chain/cf-integration-tests/src/network.rs
dandanlen pushed a commit that referenced this pull request Sep 6, 2023
* fix: correct select median implementation

* test: more select median tests
dandanlen pushed a commit that referenced this pull request Sep 6, 2023
* fix: correct select median implementation

* test: more select median tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants