From 3d0aa49b9e92ae7edc09109142e874e769ebef6b Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Fri, 23 Jun 2023 10:36:33 +0200 Subject: [PATCH 1/6] Added optimal number of committees and sizes function --- carnot/committee_sizes.py | 66 +++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +- 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 carnot/committee_sizes.py diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py new file mode 100644 index 0000000..bccfd7f --- /dev/null +++ b/carnot/committee_sizes.py @@ -0,0 +1,66 @@ +import math +from scipy.stats import binom + + +CARNOT_ADVERSARY_THRESHOLD_PER_COMMITTEE: float = 1/3 +CARNOT_NETWORK_ADVERSARY_THRESHOLD: float = 1 / 4 + + +def compute_optimal_number_of_committees_and_committee_size( + number_of_nodes: int, + failure_threshold: float, + adversaries_threshold_per_committee: float, + network_adversary_threshold: float +): + assert failure_threshold > 0 + # N is the number of nodes, delta is the failure prob. which can be tolerated, + # A is the fraction of a committee (typical value is 1/3) and P + # is the fraction of adversarial nodes (typical value is 1/4). + number_of_committees = 1 + committee_size = number_of_nodes + remainder = 0 + current_probability = 0.0 + odd_committee = 0 + while current_probability < failure_threshold: + previous_number_of_committees = number_of_committees + previous_committee_size = committee_size + previous_remainder = remainder + previous_probability = current_probability + odd_committee = odd_committee + 1 + number_of_committees = 2 * odd_committee + 1 + committee_size = number_of_nodes // number_of_committees + remainder = number_of_nodes % number_of_committees + if 0 < remainder: + committee_size_probability = binom.cdf( + math.floor(adversaries_threshold_per_committee * committee_size), + committee_size, + network_adversary_threshold + ) + committee_size_plus_one_probability = binom.cdf( + math.floor(adversaries_threshold_per_committee * (committee_size + 1)), + committee_size + 1, + network_adversary_threshold + ) + current_probability = 1 - committee_size_probability ** (number_of_committees - remainder) * committee_size_plus_one_probability ** remainder + else: + committee_size_probability = binom.cdf( + math.floor(adversaries_threshold_per_committee * committee_size), + committee_size, + network_adversary_threshold + ) + current_probability = 1 - committee_size_probability ** number_of_committees + # return number of committees, K_1, committee size, n_1, number of committees + # with size n_1+1, r_1 and prob. of failure, Prob_1. + return previous_number_of_committees, previous_committee_size, previous_remainder, previous_probability + + +if __name__ == "__main__": + failure_threshold = 0.01 + print( + compute_optimal_number_of_committees_and_committee_size( + 600, + failure_threshold, + CARNOT_ADVERSARY_THRESHOLD_PER_COMMITTEE, + CARNOT_NETWORK_ADVERSARY_THRESHOLD + ) + ) diff --git a/requirements.txt b/requirements.txt index 058bb11..4ea0792 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -blspy~=1.0.16 \ No newline at end of file +blspy~=1.0.16 +scipy~=1.10.1 \ No newline at end of file From 7528506b212d6b6165ca700c5cd37aa70b87bf19 Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Fri, 23 Jun 2023 11:05:15 +0200 Subject: [PATCH 2/6] Remove main --- carnot/committee_sizes.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py index bccfd7f..884d85f 100644 --- a/carnot/committee_sizes.py +++ b/carnot/committee_sizes.py @@ -52,15 +52,3 @@ def compute_optimal_number_of_committees_and_committee_size( # return number of committees, K_1, committee size, n_1, number of committees # with size n_1+1, r_1 and prob. of failure, Prob_1. return previous_number_of_committees, previous_committee_size, previous_remainder, previous_probability - - -if __name__ == "__main__": - failure_threshold = 0.01 - print( - compute_optimal_number_of_committees_and_committee_size( - 600, - failure_threshold, - CARNOT_ADVERSARY_THRESHOLD_PER_COMMITTEE, - CARNOT_NETWORK_ADVERSARY_THRESHOLD - ) - ) From 18c8407edb9688b5a2737919f17afad926a86bbd Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Tue, 27 Jun 2023 13:12:06 +0200 Subject: [PATCH 3/6] Extract common scope code snippet --- carnot/committee_sizes.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py index 884d85f..f312179 100644 --- a/carnot/committee_sizes.py +++ b/carnot/committee_sizes.py @@ -30,12 +30,13 @@ def compute_optimal_number_of_committees_and_committee_size( number_of_committees = 2 * odd_committee + 1 committee_size = number_of_nodes // number_of_committees remainder = number_of_nodes % number_of_committees + + committee_size_probability = binom.cdf( + math.floor(adversaries_threshold_per_committee * committee_size), + committee_size, + network_adversary_threshold + ) if 0 < remainder: - committee_size_probability = binom.cdf( - math.floor(adversaries_threshold_per_committee * committee_size), - committee_size, - network_adversary_threshold - ) committee_size_plus_one_probability = binom.cdf( math.floor(adversaries_threshold_per_committee * (committee_size + 1)), committee_size + 1, @@ -43,11 +44,6 @@ def compute_optimal_number_of_committees_and_committee_size( ) current_probability = 1 - committee_size_probability ** (number_of_committees - remainder) * committee_size_plus_one_probability ** remainder else: - committee_size_probability = binom.cdf( - math.floor(adversaries_threshold_per_committee * committee_size), - committee_size, - network_adversary_threshold - ) current_probability = 1 - committee_size_probability ** number_of_committees # return number of committees, K_1, committee size, n_1, number of committees # with size n_1+1, r_1 and prob. of failure, Prob_1. From 143c009e8e75992f5f95e2ecd46dad2c2a6009b0 Mon Sep 17 00:00:00 2001 From: danielsanchezq Date: Tue, 27 Jun 2023 14:10:39 +0200 Subject: [PATCH 4/6] Fmt --- carnot/committee_sizes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py index f312179..5bbc4fe 100644 --- a/carnot/committee_sizes.py +++ b/carnot/committee_sizes.py @@ -42,7 +42,10 @@ def compute_optimal_number_of_committees_and_committee_size( committee_size + 1, network_adversary_threshold ) - current_probability = 1 - committee_size_probability ** (number_of_committees - remainder) * committee_size_plus_one_probability ** remainder + current_probability = ( + 1 - committee_size_probability ** (number_of_committees - remainder) + * committee_size_plus_one_probability ** remainder + ) else: current_probability = 1 - committee_size_probability ** number_of_committees # return number of committees, K_1, committee size, n_1, number of committees From 8e059377159cb506fc9eae73c09a722b211f24fd Mon Sep 17 00:00:00 2001 From: Alexander Mozeika <106667936+AMozeika@users.noreply.github.com> Date: Tue, 27 Jun 2023 14:10:35 +0100 Subject: [PATCH 5/6] Edited comments --- carnot/committee_sizes.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py index 5bbc4fe..4a27f82 100644 --- a/carnot/committee_sizes.py +++ b/carnot/committee_sizes.py @@ -13,9 +13,10 @@ def compute_optimal_number_of_committees_and_committee_size( network_adversary_threshold: float ): assert failure_threshold > 0 - # N is the number of nodes, delta is the failure prob. which can be tolerated, - # A is the fraction of a committee (typical value is 1/3) and P - # is the fraction of adversarial nodes (typical value is 1/4). + # number_of_nodes is the number of nodes in the network + # failure_threshold is the prob. of failure which can be tolerated + # adversaries_threshold_per_committee is the fraction Byzantine modes in a committee + # network_adversary_threshold is the fraction of Byzantine nodes in the network number_of_committees = 1 committee_size = number_of_nodes remainder = 0 @@ -48,6 +49,6 @@ def compute_optimal_number_of_committees_and_committee_size( ) else: current_probability = 1 - committee_size_probability ** number_of_committees - # return number of committees, K_1, committee size, n_1, number of committees - # with size n_1+1, r_1 and prob. of failure, Prob_1. + # return the number_of_committees, committee_size, remainder and current_probability + # computed at the previous iteration. return previous_number_of_committees, previous_committee_size, previous_remainder, previous_probability From 90ab66a4dccddbbbfc12419a8599290bcba714fa Mon Sep 17 00:00:00 2001 From: Alexander Mozeika <106667936+AMozeika@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:14:15 +0100 Subject: [PATCH 6/6] Added algorithm description --- carnot/committee_sizes.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/carnot/committee_sizes.py b/carnot/committee_sizes.py index 4a27f82..e0e6fac 100644 --- a/carnot/committee_sizes.py +++ b/carnot/committee_sizes.py @@ -1,3 +1,14 @@ +""" +This algorithm given the number_of_nodes in the network, fraction of Byzantine nodes in the network, network_adversary_threshold, +fraction of Byzantine modes in a committee, adversaries_threshold_per_committee, and the probability of failure_threshold which can be tolerated computes the maximum number_of_committees and committee_size. + +The algorithm computes the current_probability for the number_of_nodes=committee_size*number_of_committees+remainder nodes where the committee_size and committee_size+1 number of nodes are assigned, respectively, to the number_of_committees-remainder and remainder number of committees. + +Initially, all number_of_nodes are in one committee, and in subsequent iterations, the number_of_committees is increased by two until the current_probability <= failure_threshold. When the latter condition is violated then the algorithm stops and outputs the number_of_committees, committee_size, remainder and current_probability. + +A more detailed description of the algorithm, and of its mathematical aspects, is provided in the "Carnot paper" available at https://www.notion.so/Nomos-Specification-419bfb7a939648e9b3894a90d188c3be?pvs=4 +""" + import math from scipy.stats import binom @@ -15,7 +26,7 @@ def compute_optimal_number_of_committees_and_committee_size( assert failure_threshold > 0 # number_of_nodes is the number of nodes in the network # failure_threshold is the prob. of failure which can be tolerated - # adversaries_threshold_per_committee is the fraction Byzantine modes in a committee + # adversaries_threshold_per_committee is the fraction of Byzantine modes in a committee # network_adversary_threshold is the fraction of Byzantine nodes in the network number_of_committees = 1 committee_size = number_of_nodes