eth_state_diff/eth1_data_votes.rs
1//! Delta encoding for the Eth1 data vote list.
2//!
3//! Eth1 data votes accumulate during an Eth1 voting period and are reset when
4//! the voting period changes. This module represents those transitions using
5//! either an append-only update or a complete replacement.
6//!
7//! The delta operates directly on the serialized SSZ representation and does
8//! not deserialize individual Eth1 data values.
9
10use crate::types::{ArchivedEth1DataVotesDiff, Eth1DataVotesDiff};
11
12/// Computes a delta between two serialized Eth1 data vote lists.
13///
14/// The target length determines which representation is used:
15///
16/// - If `target` is at least as long as `base`, the bytes beyond the base
17/// length are stored as [`Eth1DataVotesDiff::Append`].
18/// - If `target` is shorter than `base`, the vote list is treated as having
19/// been reset and the complete target list is stored in
20/// [`Eth1DataVotesDiff::ResetAndAppend`].
21///
22/// This function operates directly on serialized SSZ bytes and does not
23/// deserialize individual votes.
24///
25/// # Arguments
26///
27/// * `base` - Serialized SSZ representation of the current vote list.
28/// * `target` - Serialized SSZ representation of the target vote list.
29///
30/// # Returns
31///
32/// A delta that represents the transition from `base` to `target` according
33/// to the length-based append/reset semantics described above.
34///
35/// # Complexity
36///
37/// O(n), where *n* is the size of the target buffer, due to copying the
38/// resulting delta payload.
39///
40/// # Example
41///
42/// ```
43/// use eth_state_diff::eth1_data_votes::diff_eth1_votes;
44/// use eth_state_diff::types::Eth1DataVotesDiff;
45///
46/// let base = b"AAAA";
47/// let target = b"AAAABBBB";
48///
49/// let delta = diff_eth1_votes(base, target);
50///
51/// assert_eq!(delta, Eth1DataVotesDiff::Append(b"BBBB".to_vec()));
52/// ```
53pub fn diff_eth1_votes(base: &[u8], target: &[u8]) -> Eth1DataVotesDiff {
54 let base_len = base.len();
55 let target_len = target.len();
56
57 if target_len >= base_len {
58 let new_votes_bytes = &target[base_len..];
59 Eth1DataVotesDiff::Append(new_votes_bytes.to_vec())
60 } else {
61 Eth1DataVotesDiff::ResetAndAppend(target.to_vec())
62 }
63}
64
65/// Applies an Eth1 data vote delta to a serialized vote list in place.
66///
67/// [`Eth1DataVotesDiff::Append`] preserves the existing bytes and appends the
68/// delta payload.
69///
70/// [`Eth1DataVotesDiff::ResetAndAppend`] clears the existing vote list before
71/// writing the replacement payload.
72///
73/// The delta is assumed to have been produced for the current base state.
74/// This function does not validate that an append delta's base bytes match
75/// the state being modified.
76///
77/// # Arguments
78///
79/// * `base` - Serialized SSZ vote list to modify.
80/// * `delta` - Archived delta to apply.
81///
82/// # Complexity
83///
84/// - [`Eth1DataVotesDiff::Append`]: O(k), where *k* is the number of appended
85/// bytes.
86/// - [`Eth1DataVotesDiff::ResetAndAppend`]: O(k), where *k* is the size of the
87/// replacement payload.
88///
89/// # Example
90///
91/// ```
92/// use eth_state_diff::eth1_data_votes::{apply_eth1_votes, diff_eth1_votes};
93/// use eth_state_diff::types::ArchivedEth1DataVotesDiff;
94///
95/// let mut base = b"AAAA".to_vec();
96/// let delta = diff_eth1_votes(&base, b"AAAABBBB");
97///
98/// let bytes = rkyv::to_bytes::<rkyv::rancor::Error>(&delta).unwrap();
99/// let archived = unsafe {
100/// rkyv::access_unchecked::<ArchivedEth1DataVotesDiff>(&bytes)
101/// };
102///
103/// apply_eth1_votes(&mut base, archived);
104///
105/// assert_eq!(base, b"AAAABBBB");
106/// ```
107pub fn apply_eth1_votes(base: &mut Vec<u8>, delta: &ArchivedEth1DataVotesDiff) {
108 match delta {
109 ArchivedEth1DataVotesDiff::Append(appended_votes) => {
110 base.extend_from_slice(appended_votes.as_slice());
111 }
112 ArchivedEth1DataVotesDiff::ResetAndAppend(appended_votes) => {
113 base.clear();
114 base.extend_from_slice(appended_votes.as_slice());
115 }
116 }
117}