From 7711cd74c3ca81ccf2132e973bd164eca6cfe221 Mon Sep 17 00:00:00 2001 From: "Jeff Washington (jwash)" Date: Thu, 13 Jan 2022 17:02:42 -0600 Subject: [PATCH] partition_from_pubkey (#22430) * Revert "chore: bump dashmap from 4.0.2 to 5.0.0 (#21824)" This reverts commit 8aa3d690b5e87e2d4872bc751215cc8c0dd657ec. * partition_from_pubkey --- runtime/src/bank.rs | 107 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 90176b9a9c..b5d5a71140 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -4459,6 +4459,41 @@ impl Bank { account_count } + /// This is the inverse of pubkey_range_from_partition. + /// return the lowest end_index which would contain this pubkey + #[cfg(test)] + pub fn partition_from_pubkey( + pubkey: &Pubkey, + partition_count: PartitionsPerCycle, + ) -> PartitionIndex { + type Prefix = u64; + const PREFIX_SIZE: usize = mem::size_of::(); + const PREFIX_MAX: Prefix = Prefix::max_value(); + + if partition_count == 1 { + return 0; + } + + // not-overflowing way of `(Prefix::max_value() + 1) / partition_count` + let partition_width = (PREFIX_MAX - partition_count + 1) / partition_count + 1; + + let prefix = u64::from_be_bytes(pubkey.as_ref()[0..PREFIX_SIZE].try_into().unwrap()); + if prefix == 0 { + return 0; + } + + if prefix == PREFIX_MAX { + return partition_count - 1; + } + + let mut result = (prefix + 1) / partition_width; + if (prefix + 1) % partition_width == 0 { + // adjust for integer divide + result = result.saturating_sub(1); + } + result + } + // Mostly, the pair (start_index & end_index) is equivalent to this range: // start_index..=end_index. But it has some exceptional cases, including // this important and valid one: @@ -4514,6 +4549,19 @@ impl Bank { start_pubkey[0..PREFIX_SIZE].copy_from_slice(&start_key_prefix.to_be_bytes()); end_pubkey[0..PREFIX_SIZE].copy_from_slice(&end_key_prefix.to_be_bytes()); + let start_pubkey_final = Pubkey::new_from_array(start_pubkey); + let end_pubkey_final = Pubkey::new_from_array(end_pubkey); + if start_index != 0 && start_index == end_index { + error!( + "start=end, {}, {}, start, end: {:?}, {:?}, pubkeys: {}, {}", + start_pubkey.iter().map(|x| format!("{:02x}", x)).join(""), + end_pubkey.iter().map(|x| format!("{:02x}", x)).join(""), + start_key_prefix, + end_key_prefix, + start_pubkey_final, + end_pubkey_final + ); + } trace!( "pubkey_range_from_partition: ({}-{})/{} [{}]: {}-{}", start_index, @@ -4523,9 +4571,66 @@ impl Bank { start_pubkey.iter().map(|x| format!("{:02x}", x)).join(""), end_pubkey.iter().map(|x| format!("{:02x}", x)).join(""), ); + #[cfg(test)] + if start_index != end_index { + assert_eq!( + if start_index == 0 && end_index == 0 { + 0 + } else { + start_index + 1 + }, + Self::partition_from_pubkey(&start_pubkey_final, partition_count), + "{}, {}, start_key_prefix: {}, {}, {}", + start_index, + end_index, + start_key_prefix, + start_pubkey_final, + partition_count + ); + assert_eq!( + end_index, + Self::partition_from_pubkey(&end_pubkey_final, partition_count), + "{}, {}, {}, {}", + start_index, + end_index, + end_pubkey_final, + partition_count + ); + if start_index != 0 { + start_pubkey[0..PREFIX_SIZE] + .copy_from_slice(&start_key_prefix.saturating_sub(1).to_be_bytes()); + let pubkey_test = Pubkey::new_from_array(start_pubkey); + assert_eq!( + start_index, + Self::partition_from_pubkey(&pubkey_test, partition_count), + "{}, {}, start_key_prefix-1: {}, {}, {}", + start_index, + end_index, + start_key_prefix.saturating_sub(1), + pubkey_test, + partition_count + ); + } + if end_index != partition_count - 1 && end_index != 0 { + end_pubkey[0..PREFIX_SIZE] + .copy_from_slice(&end_key_prefix.saturating_add(1).to_be_bytes()); + let pubkey_test = Pubkey::new_from_array(end_pubkey); + assert_eq!( + end_index.saturating_add(1), + Self::partition_from_pubkey(&pubkey_test, partition_count), + "start: {}, end: {}, pubkey: {}, partition_count: {}, prefix_before_addition: {}, prefix after: {}", + start_index, + end_index, + pubkey_test, + partition_count, + end_key_prefix, + end_key_prefix.saturating_add(1), + ); + } + } // should be an inclusive range (a closed interval) like this: // [0xgg00-0xhhff], [0xii00-0xjjff], ... (where 0xii00 == 0xhhff + 1) - Pubkey::new_from_array(start_pubkey)..=Pubkey::new_from_array(end_pubkey) + start_pubkey_final..=end_pubkey_final } pub fn get_partitions(