diff options
Diffstat (limited to 'draft-summermatter-set-union.xml')
-rw-r--r-- | draft-summermatter-set-union.xml | 160 |
1 files changed, 96 insertions, 64 deletions
diff --git a/draft-summermatter-set-union.xml b/draft-summermatter-set-union.xml index 003cbce..50dcad0 100644 --- a/draft-summermatter-set-union.xml +++ b/draft-summermatter-set-union.xml | |||
@@ -2000,6 +2000,8 @@ FUNCTION decide_operation_mode(avg_element_size, | |||
2000 | est_local_set_diff | 2000 | est_local_set_diff |
2001 | est_remote_set_diff, | 2001 | est_remote_set_diff, |
2002 | rtt_tradeoff) | 2002 | rtt_tradeoff) |
2003 | |||
2004 | # If a set size is zero always do full sync | ||
2003 | IF (0 == remote_set_size) | 2005 | IF (0 == remote_set_size) |
2004 | RETURN FULL_SYNC_LOCAL_SENDING_FIRST | 2006 | RETURN FULL_SYNC_LOCAL_SENDING_FIRST |
2005 | IF END | 2007 | IF END |
@@ -2007,56 +2009,66 @@ FUNCTION decide_operation_mode(avg_element_size, | |||
2007 | RETURN FULL_SYNC_REMOTE_SENDING_FIRST | 2009 | RETURN FULL_SYNC_REMOTE_SENDING_FIRST |
2008 | IF END | 2010 | IF END |
2009 | 2011 | ||
2012 | # Estimate required transferred bytes when doing a full synchronisation | ||
2013 | # and transmitting local set first. | ||
2010 | estimated_total_diff = est_set_diff_remote + est_local_set_diff | 2014 | estimated_total_diff = est_set_diff_remote + est_local_set_diff |
2011 | 2015 | total_elements_local_send = est_remote_set_diff + local_set_size | |
2012 | total_elements_to_send_local_send_first = est_remote_set_diff + local_set_size | 2016 | total_bytes_local_send = (avg_element_size * total_elements_local_send) |
2013 | 2017 | + (total_elements_local_send * sizeof(ELEMENT_MSG_HEADER)) | |
2014 | total_bytes_full_local_send_first = (avg_element_size * total_elements_to_send_local_send_first) | 2018 | + (sizeof(FULL_DONE_MSG_HEADER) * 2) |
2015 | + (total_elements_to_send_local_send_first * sizeof(ELEMENT_MSG_HEADER)) | 2019 | + RTT_MIN_FULL * rtt_tradeoff |
2016 | + (sizeof(FULL_DONE_MSG_HEADER) * 2) | 2020 | |
2017 | + RTT_MIN_FULL * rtt_tradeoff | 2021 | # Estimate required transferred bytes when doing a full synchronisation |
2018 | 2022 | # and transmitting remote set first. | |
2019 | total_elements_to_send_remote_send_first = est_local_set_diff + remote_set_size | 2023 | total_elements_remote_send = est_local_set_diff + remote_set_size |
2020 | 2024 | total_bytes_remote_send = (avg_element_size * total_elements_remote_send) | |
2021 | total_bytes_full_remote_send_first = (avg_element_size * total_elements_to_send_remote_send_first) | 2025 | + ( total_elements_remote_send * sizeof(ELEMENT_MSG_HEADER)) |
2022 | + ( total_elements_to_send_remote_send_first * sizeof(ELEMENT_MSG_HEADER)) | 2026 | + (sizeof(FULL_DONE_MSG_HEADER) * 2) |
2023 | + (sizeof(FULL_DONE_MSG_HEADER) * 2) | 2027 | + (RTT_MIN_FULL + 0.5) * rtt_tradeoff |
2024 | + (RTT_MIN_FULL + 0.5) * rtt_tradeoff | 2028 | + sizeof(REQUEST_FULL_MSG) |
2025 | + sizeof(REQUEST_FULL_MSG) | 2029 | |
2026 | 2030 | # Estimate required transferred bytes when doing a differential synchronisation | |
2031 | |||
2032 | # Estimate messages required to transfer IBF | ||
2027 | ibf_bucket_count = estimated_total_diff * IBF_BUCKET_NUMBER_FACTOR | 2033 | ibf_bucket_count = estimated_total_diff * IBF_BUCKET_NUMBER_FACTOR |
2028 | |||
2029 | IF (ibf_bucket_count <= IBF_MIN_SIZE) | 2034 | IF (ibf_bucket_count <= IBF_MIN_SIZE) |
2030 | ibf_bucket_count = IBF_MIN_SIZE | 2035 | ibf_bucket_count = IBF_MIN_SIZE |
2031 | END IF | 2036 | END IF |
2032 | |||
2033 | ibf_message_count = ceil ( ibf_bucket_count / MAX_BUCKETS_PER_MESSAGE) | 2037 | ibf_message_count = ceil ( ibf_bucket_count / MAX_BUCKETS_PER_MESSAGE) |
2034 | 2038 | ||
2039 | # Estimate average counter length with variable counter | ||
2035 | estimated_counter_size = MIN ( | 2040 | estimated_counter_size = MIN ( |
2036 | 2 * LOG2(local_set_size / ibf_bucket_count), | 2041 | 2 * LOG2(local_set_size / ibf_bucket_count), |
2037 | LOG2(local_set_size) | 2042 | LOG2(local_set_size) |
2038 | ) | 2043 | ) |
2039 | counter_bytes = estimated_counter_size / 8 | 2044 | counter_bytes = estimated_counter_size / 8 |
2040 | 2045 | ||
2046 | # Sum up all messages required to do differential synchronisation | ||
2041 | ibf_bytes = sizeof(IBF_MESSAGE) * ibf_message_count * 1.2 | 2047 | ibf_bytes = sizeof(IBF_MESSAGE) * ibf_message_count * 1.2 |
2042 | + ibf_bucket_count * sizeof(IBF_KEY) * 1.2 | 2048 | + ibf_bucket_count * sizeof(IBF_KEY) * 1.2 |
2043 | + ibf_bucket_count * sizeof(IBF_KEYHASH) * 1.2 | 2049 | + ibf_bucket_count * sizeof(IBF_KEYHASH) * 1.2 |
2044 | + ibf_bucket_count * counter_bytes * 1.2 | 2050 | + ibf_bucket_count * counter_bytes * 1.2 |
2045 | 2051 | ||
2046 | element_size = (avg_element_size + sizeof(ELEMENT_MSG_HEADER)) * estimated_total_diff | ||
2047 | done_size = sizeof(DONE_HEADER) | 2052 | done_size = sizeof(DONE_HEADER) |
2048 | inquery_size = (sizeof(IBF_KEY) + sizeof(INQUERY_MSG_HEADER)) * estimated_total_diff | 2053 | element_size = (avg_element_size + sizeof(ELEMENT_MSG_HEADER)) |
2049 | demand_size = (sizeof(HASHCODE) + sizeof(DEMAND_MSG_HEADER)) * estimated_total_diff | 2054 | * estimated_total_diff |
2050 | offer_size = (sizeof(HASHCODE) + sizeof(OFFER_MSG_HEADER)) * estimated_total_diff | 2055 | inquery_size = (sizeof(IBF_KEY) + sizeof(INQUERY_MSG_HEADER)) |
2056 | * estimated_total_diff | ||
2057 | demand_size = (sizeof(HASHCODE) + sizeof(DEMAND_MSG_HEADER)) | ||
2058 | * estimated_total_diff | ||
2059 | offer_size = (sizeof(HASHCODE) + sizeof(OFFER_MSG_HEADER)) | ||
2060 | * estimated_total_diff | ||
2051 | 2061 | ||
2052 | total_bytes_diff = (element_size + done_size + inquery_size | 2062 | total_bytes_diff = (element_size + done_size + inquery_size |
2053 | + demand_size + offer_size + ibf_bytes) | 2063 | + demand_size + offer_size + ibf_bytes) |
2054 | + DIFFERENTIAL_RTT_MEAN * rtt_tradeoff | 2064 | + DIFFERENTIAL_RTT_MEAN * rtt_tradeoff |
2065 | |||
2066 | # Decide for a optimal mode of operation | ||
2055 | 2067 | ||
2056 | full_min = MIN (total_bytes_full_local_send_first, | 2068 | full_min = MIN (total_bytes_local_send, |
2057 | total_bytes_full_local_send_first) | 2069 | total_bytes_local_send) |
2058 | IF (full_min < total_bytes_diff) | 2070 | IF (full_min < total_bytes_diff) |
2059 | IF (total_bytes_full_remote_send_first > total_bytes_full_local_send_first) | 2071 | IF (total_bytes_remote_send > total_bytes_local_send) |
2060 | RETURN FULL_SYNC_LOCAL_SENDING_FIRST | 2072 | RETURN FULL_SYNC_LOCAL_SENDING_FIRST |
2061 | ELSE | 2073 | ELSE |
2062 | RETURN FULL_SYNC_REMOTE_SENDING_FIRST | 2074 | RETURN FULL_SYNC_REMOTE_SENDING_FIRST |
@@ -2128,18 +2140,18 @@ FUNCTION END | |||
2128 | Since the optimal number of bytes a counter in the IBF contains is very variable and varies | 2140 | Since the optimal number of bytes a counter in the IBF contains is very variable and varies |
2129 | due to different parameters. Details are described in the BSC thesis | 2141 | due to different parameters. Details are described in the BSC thesis |
2130 | by Summermatter <xref target="byzantine_fault_tolerant_set_reconciliation" format="default"/>. | 2142 | by Summermatter <xref target="byzantine_fault_tolerant_set_reconciliation" format="default"/>. |
2131 | Therefore a compression algorithm has been implemented, which always creates the IBF counter in optimal size. | 2143 | Therefore a packing algorithm has been implemented, which always creates the IBF counter in optimal size. |
2132 | and thus minimizes the bandwidth needed to transmit the IBF. | 2144 | and thus minimizes the bandwidth needed to transmit the IBF. |
2133 | </t> | 2145 | </t> |
2134 | <t> | 2146 | <t> |
2135 | A simple algorithm is used for the compression. In a first step it is determined, which is the largest counter | 2147 | A simple algorithm is used for the packing. In a first step it is determined, which is the largest counter |
2136 | and how many bits are needed to store it. In a second step for every counter of every bucket, the counter | 2148 | and how many bits are needed to store it. In a second step for every counter of every bucket, the counter |
2137 | is stored in the bit length, determined in the first step and these are concatenated. | 2149 | is stored in the bit length, determined in the first step and these are concatenated. |
2138 | </t> | 2150 | </t> |
2139 | <t> | 2151 | <t> |
2140 | Three individual functions are used for this purpose. The first one is a function that iterates over each bucket of | 2152 | Three individual functions are used for this purpose. The first one is a function that iterates over each bucket of |
2141 | the IBF to get the maximum counter in the IBF. As second it needs | 2153 | the IBF to get the maximum counter in the IBF. As second it needs |
2142 | a function that compresses the counter of the IBF and thirdly a function that decompresses the counter. | 2154 | a function that pack the counter of the IBF and thirdly a function that unpack the counter. |
2143 | </t> | 2155 | </t> |
2144 | <figure anchor="performance_counter_variable_size_code"> | 2156 | <figure anchor="performance_counter_variable_size_code"> |
2145 | <artwork name="" type="" align="left" alt=""><![CDATA[ | 2157 | <artwork name="" type="" align="left" alt=""><![CDATA[ |
@@ -2155,14 +2167,16 @@ FUNCTION ibf_get_max_counter(ibf) | |||
2155 | IF bucket.counter > max_counter | 2167 | IF bucket.counter > max_counter |
2156 | max_counter = bucket.counter | 2168 | max_counter = bucket.counter |
2157 | 2169 | ||
2158 | RETURN CEILING( log2 ( max_counter ) ) # next bigger discrete number of the binary logarithm of the max counter | 2170 | # next bigger discrete number of the binary logarithm of the max counter |
2171 | RETURN CEILING( log2 ( max_counter ) ) | ||
2159 | 2172 | ||
2160 | # INPUTS: | 2173 | # INPUTS: |
2161 | # ibf: The IBF | 2174 | # ibf: The IBF |
2162 | # offset: The offset which defines the starting point from which bucket the compress operation starts | 2175 | # offset: The offset which defines the starting point from which bucket the |
2163 | # count: The number of buckets in the array that will be compressed | 2176 | # pack operation starts |
2177 | # count: The number of buckets in the array that will be packed | ||
2164 | # OUTPUTS: | 2178 | # OUTPUTS: |
2165 | # returns: A byte array of compressed counters to send over the network | 2179 | # returns: A byte array of packed counters to send over the network |
2166 | 2180 | ||
2167 | FUNCTION pack_counter(ibf, offset, count) | 2181 | FUNCTION pack_counter(ibf, offset, count) |
2168 | counter_bytes = ibf_get_max_counter(ibf) | 2182 | counter_bytes = ibf_get_max_counter(ibf) |
@@ -2206,7 +2220,7 @@ FUNCTION pack_counter(ibf, offset, count) | |||
2206 | byte_ctr++ | 2220 | byte_ctr++ |
2207 | NEXT_BUCKET | 2221 | NEXT_BUCKET |
2208 | 2222 | ||
2209 | # Write the last partial compressed byte to the buffer | 2223 | # Write the last partial packed byte to the buffer |
2210 | buffer[byte_ctr] = store << (8 - store_bits) | 2224 | buffer[byte_ctr] = store << (8 - store_bits) |
2211 | byte_ctr++ | 2225 | byte_ctr++ |
2212 | 2226 | ||
@@ -2214,10 +2228,13 @@ FUNCTION pack_counter(ibf, offset, count) | |||
2214 | 2228 | ||
2215 | # INPUTS: | 2229 | # INPUTS: |
2216 | # ibf: The IBF | 2230 | # ibf: The IBF |
2217 | # offset: The offset which defines the starting point from which bucket the compress operation starts | 2231 | # offset: The offset which defines the starting point from which bucket |
2218 | # count: The number of buckets in the array that will be compressed | 2232 | the packed operation starts |
2219 | # counter_bit_length: The bit length of the counter can be found in the ibf message in the ibf_counter_bit_length field | 2233 | # count: The number of buckets in the array that will be packed |
2220 | # packed_data: A byte array which contains the data packed with the pack_counter function | 2234 | # counter_bit_length: The bit length of the counter can be found in the |
2235 | ibf message in the ibf_counter_bit_length field | ||
2236 | # packed_data: A byte array which contains the data packed with the pack_counter | ||
2237 | function | ||
2221 | # OUTPUTS: | 2238 | # OUTPUTS: |
2222 | # returns: Nothing because the unpacked counter is saved directly into the IBF | 2239 | # returns: Nothing because the unpacked counter is saved directly into the IBF |
2223 | 2240 | ||
@@ -2675,7 +2692,7 @@ FUNCTION END | |||
2675 | # rd: Number of duplicated elements received | 2692 | # rd: Number of duplicated elements received |
2676 | # rf: Number of fresh elements received | 2693 | # rf: Number of fresh elements received |
2677 | # Output: | 2694 | # Output: |
2678 | # Returns TRUE if full syncronisation is plausible and FALSE otherwise | 2695 | # Returns TRUE if full synchronisation is plausible and FALSE otherwise |
2679 | 2696 | ||
2680 | FUNCTION full_sync_plausibility_check (state,rs,lis,rd,rf) | 2697 | FUNCTION full_sync_plausibility_check (state,rs,lis,rd,rf) |
2681 | security_level_lb = 1 / SECURITY_LEVEL | 2698 | security_level_lb = 1 / SECURITY_LEVEL |
@@ -2900,8 +2917,8 @@ FUNCTION END | |||
2900 | which means within the byzantine boundaries described in section <xref target="security_generic_functions_check_byzantine_boundaries" format="title" />. | 2917 | which means within the byzantine boundaries described in section <xref target="security_generic_functions_check_byzantine_boundaries" format="title" />. |
2901 | </t> | 2918 | </t> |
2902 | <t> | 2919 | <t> |
2903 | In case of compressed strata estimators the decompression algorithm needs to | 2920 | In case of compressed strata estimators the unpacking algorithm needs to |
2904 | be protected against decompression memory corruption (memory overflow). | 2921 | be protected against unpacking memory corruption (memory overflow). |
2905 | </t> | 2922 | </t> |
2906 | </dd> | 2923 | </dd> |
2907 | </dl> | 2924 | </dl> |
@@ -3014,19 +3031,25 @@ FUNCTION END | |||
3014 | Name | Value | Description | 3031 | Name | Value | Description |
3015 | ----------------------------+------------+-------------------------- | 3032 | ----------------------------+------------+-------------------------- |
3016 | SE_STRATA_COUNT | 32 | Number of IBFs in a strata estimator | 3033 | SE_STRATA_COUNT | 32 | Number of IBFs in a strata estimator |
3017 | IBF_HASH_NUM* | 3 | Number of times an element is hashed to an IBF | 3034 | IBF_HASH_NUM* | 3 | Number of times an element is hashed to an |
3018 | IBF_FACTOR* | 2 | The factor by which the size of the IBF is increased | 3035 | IBF |
3019 | in case of decoding failure or initially from the | 3036 | IBF_FACTOR* | 2 | The factor by which the size of the IBF is |
3020 | set difference | 3037 | increased in case of decoding failure or |
3021 | MAX_BUCKETS_PER_MESSAGE | 1120 | Maximum bucket of an IBF that are transmitted in single message | 3038 | initially from the set difference |
3039 | MAX_BUCKETS_PER_MESSAGE | 1120 | Maximum bucket of an IBF that are | ||
3040 | transmitted in single message | ||
3022 | IBF_MIN_SIZE* | 37 | Minimal number of buckets in an IBF | 3041 | IBF_MIN_SIZE* | 37 | Minimal number of buckets in an IBF |
3023 | DIFFERENTIAL_RTT_MEAN* | 3.65145 | The average RTT that is needed for a differential synchronisation | 3042 | DIFFERENTIAL_RTT_MEAN* | 3.65145 | The average RTT that is needed for a |
3024 | SECURITY_LEVEL* | 2^80 | Security level for probabilistic security algorithms | 3043 | differential synchronisation |
3025 | PROBABILITY_FOR_NEW_ROUND* | 0.15 | The probability for a IBF decoding failure in the differential | 3044 | SECURITY_LEVEL* | 2^80 | Security level for probabilistic security |
3026 | synchronisation mode | 3045 | algorithms |
3027 | DIFFERENTIAL_RTT_MEAN* | 3.65145 | The average RTT that is needed for a differential synchronisation | 3046 | PROBABILITY_FOR_NEW_ROUND* | 0.15 | The probability for a IBF decoding failure |
3047 | in the differential synchronisation mode | ||
3048 | DIFFERENTIAL_RTT_MEAN* | 3.65145 | The average RTT that is needed for a | ||
3049 | differential synchronisation | ||
3028 | MAX_IBF_SIZE | 1048576 | Maximal number of buckets in an IBF | 3050 | MAX_IBF_SIZE | 1048576 | Maximal number of buckets in an IBF |
3029 | AVG_BYTE_SIZE_SE* | 4221 | Average byte size of a single strata estimator | 3051 | AVG_BYTE_SIZE_SE* | 4221 | Average byte size of a single strata |
3052 | estimator | ||
3030 | VALID_NUMBER_SE* | [1,2,4,8] | Valid number of SE in | 3053 | VALID_NUMBER_SE* | [1,2,4,8] | Valid number of SE in |
3031 | 3054 | ||
3032 | ]]></artwork> | 3055 | ]]></artwork> |
@@ -3043,20 +3066,29 @@ VALID_NUMBER_SE* | [1,2,4,8] | Valid number of SE in | |||
3043 | <artwork name="" type="" align="left" alt=""><![CDATA[ | 3066 | <artwork name="" type="" align="left" alt=""><![CDATA[ |
3044 | Type | Name | References | Description | 3067 | Type | Name | References | Description |
3045 | --------+----------------------------+------------+-------------------------- | 3068 | --------+----------------------------+------------+-------------------------- |
3046 | 559 | SETU_P2P_REQUEST_FULL | [This.I-D] | Request the full set of the other peer | 3069 | 559 | SETU_P2P_REQUEST_FULL | [This.I-D] | Request the full set of the other |
3047 | 710 | SETU_P2P_SEND_FULL | [This.I-D] | Signals to send the full set to the other peer | 3070 | peer |
3048 | 560 | SETU_P2P_DEMAND | [This.I-D] | Demand the whole element from the other peer, given only the hash code. | 3071 | 710 | SETU_P2P_SEND_FULL | [This.I-D] | Signals to send the full set to the |
3049 | 561 | SETU_P2P_INQUIRY | [This.I-D] | Tell the other peer to send a list of hashes that match an IBF key. | 3072 | other peer |
3050 | 562 | SETU_P2P_OFFER | [This.I-D] | Tell the other peer which hashes match a given IBF key. | 3073 | 560 | SETU_P2P_DEMAND | [This.I-D] | Demand the whole element from the |
3051 | 563 | SETU_P2P_OPERATION_REQUEST | [This.I-D] | Request a set union operation from a remote peer. | 3074 | other peer, given only the hash |
3075 | code. | ||
3076 | 561 | SETU_P2P_INQUIRY | [This.I-D] | Tell the other peer to send a list | ||
3077 | of hashes that match an IBF key. | ||
3078 | 562 | SETU_P2P_OFFER | [This.I-D] | Tell the other peer which hashes | ||
3079 | match a given IBF key. | ||
3080 | 563 | SETU_P2P_OPERATION_REQUEST | [This.I-D] | Request a set union operation from | ||
3081 | a remote peer. | ||
3052 | 564 | SETU_P2P_SE | [This.I-D] | Strata Estimator uncompressed | 3082 | 564 | SETU_P2P_SE | [This.I-D] | Strata Estimator uncompressed |
3053 | 565 | SETU_P2P_IBF | [This.I-D] | Invertible Bloom Filter slices. | 3083 | 565 | SETU_P2P_IBF | [This.I-D] | Invertible Bloom Filter slices. |
3054 | 566 | SETU_P2P_ELEMENTS | [This.I-D] | Actual set elements. | 3084 | 566 | SETU_P2P_ELEMENTS | [This.I-D] | Actual set elements. |
3055 | 567 | SETU_P2P_IBF_LAST | [This.I-D] | Invertible Bloom Filter Last Slice. | 3085 | 567 | SETU_P2P_IBF_LAST | [This.I-D] | Invertible Bloom Filter Last Slice. |
3056 | 568 | SETU_P2P_DONE | [This.I-D] | Set operation is done. | 3086 | 568 | SETU_P2P_DONE | [This.I-D] | Set operation is done. |
3057 | 569 | SETU_P2P_SEC | [This.I-D] | Strata Estimator compressed | 3087 | 569 | SETU_P2P_SEC | [This.I-D] | Strata Estimator compressed |
3058 | 570 | SETU_P2P_FULL_DONE | [This.I-D] | All elements in full synchronisation mode have been sent is done. | 3088 | 570 | SETU_P2P_FULL_DONE | [This.I-D] | All elements in full synchronisation |
3059 | 571 | SETU_P2P_FULL_ELEMENT | [This.I-D] | Send an actual element in full synchronisation mode. | 3089 | mode have been sent is done. |
3090 | 571 | SETU_P2P_FULL_ELEMENT | [This.I-D] | Send an actual element in full | ||
3091 | synchronisation mode. | ||
3060 | 3092 | ||
3061 | ]]></artwork> | 3093 | ]]></artwork> |
3062 | </figure> | 3094 | </figure> |