eth_state_diff/eth1_data_votes.rs
1//! Delta encoding for the Eth1 data vote list.
2//!
3//! The vote list is monotonic within an Eth1 voting period but is reset when
4//! the voting period changes. This module encodes both cases compactly:
5//!
6//! - Appending newly added votes to the existing list.
7//! - Replacing the entire list after a reset.
8
9use crate::types::{ArchivedEth1DataVotesDiff, Eth1DataVotesDiff};
10
11/// Computes the delta between two serialized Eth1 data vote lists.
12///
13/// If the target list extends the base list, only the newly appended votes are
14/// recorded.
15///
16/// If the target list is shorter than the base list, the encoder assumes the
17/// vote list has been reset and stores the entire target list.
18pub fn diff_eth1_votes(base: &[u8], target: &[u8]) -> Eth1DataVotesDiff {
19 let base_len = base.len();
20 let target_len = target.len();
21
22 if target_len >= base_len {
23 let new_votes_bytes = &target[base_len..];
24 Eth1DataVotesDiff::Append(new_votes_bytes.to_vec())
25 } else {
26 Eth1DataVotesDiff::ResetAndAppend(target.to_vec())
27 }
28}
29
30/// Applies an Eth1 data vote delta in place.
31///
32/// # Behavior
33///
34/// - [`Eth1DataVotesDiff::Append`] appends the recorded votes to the existing
35/// vote list.
36/// - [`Eth1DataVotesDiff::ResetAndAppend`] clears the destination list before
37/// writing the recorded votes.
38///
39/// # Complexity
40///
41/// O(number of appended vote bytes)
42pub fn apply_eth1_votes(base: &mut Vec<u8>, delta: &ArchivedEth1DataVotesDiff) {
43 match delta {
44 ArchivedEth1DataVotesDiff::Append(appended_votes) => {
45 base.extend_from_slice(appended_votes.as_slice());
46 }
47 ArchivedEth1DataVotesDiff::ResetAndAppend(appended_votes) => {
48 base.clear();
49 base.extend_from_slice(appended_votes.as_slice());
50 }
51 }
52}