diff --git a/include/nil/blueprint/comparison/comparison.hpp b/include/nil/blueprint/comparison/comparison.hpp index f9a4c822..fc6703e5 100644 --- a/include/nil/blueprint/comparison/comparison.hpp +++ b/include/nil/blueprint/comparison/comparison.hpp @@ -41,14 +41,14 @@ namespace nil { template typename crypto3::zk::snark::plonk_variable - handle_comparison_component( + handle_comparison_component( llvm::CmpInst::Predicate p, const typename crypto3::zk::snark::plonk_variable &x, const typename crypto3::zk::snark::plonk_variable &y, std::size_t Bitness, circuit> &bp, assignment> - &assignment, + &assignment, std::uint32_t start_row, std::size_t &public_input_idx) { diff --git a/include/nil/blueprint/component_manifest_utilities.hpp b/include/nil/blueprint/component_manifest_utilities.hpp new file mode 100644 index 00000000..c281069e --- /dev/null +++ b/include/nil/blueprint/component_manifest_utilities.hpp @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Kokoshnikov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_COMPONENT_MANIFEST_UTILITIES_HPP +#define CRYPTO3_ASSIGNER_COMPONENT_MANIFEST_UTILITIES_HPP + +#include +#include +#include + +#include + +namespace nil { + namespace blueprint { + namespace detail { + + struct FlexibleParameters { + std::vector witness; + + FlexibleParameters(std::uint32_t witness_amount) { + witness.resize(witness_amount); + std::iota(witness.begin(), witness.end(), 0); // fill 0, 1, ... + } + }; + + template + struct CompilerRestrictions { + inline static compiler_manifest common_restriction_manifest = compiler_manifest(ArithmetizationParams::witness_columns, + std::numeric_limits::max() - 1, + std::numeric_limits::max(), true); + }; + + template + struct ManifestReader { + inline static typename ComponentType::manifest_type manifest = + CompilerRestrictions::common_restriction_manifest.intersect(ComponentType::get_manifest()); + + template + static std::vector > + get_witness(Args... args) { + ASSERT(manifest.is_satisfiable()); + auto witness_amount_ptr = manifest.witness_amount; + std::vector > values; + for (auto it = witness_amount_ptr->begin(); + it != witness_amount_ptr->end(); it++) { + const auto witness_amount = *it; + values.emplace_back(witness_amount, + ComponentType::get_rows_amount(witness_amount, + args...)); + } + ASSERT(values.size() > 0); + return values; + } + + static typename ComponentType::component_type::constant_container_type + get_constants() { + typename ComponentType::component_type::constant_container_type constants; + std::iota(constants.begin(), constants.end(), 0); // fill 0, 1, ... + return constants; + } + + static typename ComponentType::component_type::public_input_container_type + get_public_inputs() { + typename ComponentType::component_type::public_input_container_type public_inputs; + std::iota(public_inputs.begin(), public_inputs.end(), 0); // fill 0, 1, ... + return public_inputs; + } + }; + } // namespace detail + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_COMPONENT_MANIFEST_UTILITIES_HPP \ No newline at end of file diff --git a/include/nil/blueprint/curves/addition.hpp b/include/nil/blueprint/curves/addition.hpp index ecfb9471..901a97b6 100644 --- a/include/nil/blueprint/curves/addition.hpp +++ b/include/nil/blueprint/curves/addition.hpp @@ -45,6 +45,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -66,7 +67,8 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = components::unified_addition; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); struct var_ec_point { var X; @@ -102,7 +104,8 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = components::complete_addition>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); using non_native_policy_type = basic_non_native_policy; diff --git a/include/nil/blueprint/curves/multiplication.hpp b/include/nil/blueprint/curves/multiplication.hpp index 8b69f55e..a9ae2317 100644 --- a/include/nil/blueprint/curves/multiplication.hpp +++ b/include/nil/blueprint/curves/multiplication.hpp @@ -45,6 +45,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -67,7 +68,8 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = components::curve_element_variable_base_scalar_mul< ArithmetizationType,CurveType>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, {0}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); struct var_ec_point { var X; @@ -104,7 +106,8 @@ namespace nil { using ArithmetizationType = crypto3::zk::snark::plonk_constraint_system; using component_type = components::variable_base_multiplication>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0, 253)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs(), 253, nil::blueprint::components::bit_shift_mode::RIGHT); using non_native_policy_type = basic_non_native_policy; diff --git a/include/nil/blueprint/fields/addition.hpp b/include/nil/blueprint/fields/addition.hpp index eb94ca27..725e1903 100644 --- a/include/nil/blueprint/fields/addition.hpp +++ b/include/nil/blueprint/fields/addition.hpp @@ -45,6 +45,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -67,7 +68,8 @@ namespace nil { using component_type = components::addition< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); var x = variables[operand0]; var y = variables[operand1]; @@ -94,7 +96,8 @@ namespace nil { using component_type = components::addition< crypto3::zk::snark::plonk_constraint_system, OperatingFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); std::vector operand0_vars = vectors[operand0]; std::vector operand1_vars = vectors[operand1]; diff --git a/include/nil/blueprint/fields/division.hpp b/include/nil/blueprint/fields/division.hpp index 80c84d28..f1cd49f8 100644 --- a/include/nil/blueprint/fields/division.hpp +++ b/include/nil/blueprint/fields/division.hpp @@ -44,6 +44,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -66,7 +67,8 @@ namespace nil { using component_type = components::division< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2, 3}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); var x = variables[operand0]; var y = variables[operand1]; diff --git a/include/nil/blueprint/fields/multiplication.hpp b/include/nil/blueprint/fields/multiplication.hpp index cfdb3fa0..594b76ec 100644 --- a/include/nil/blueprint/fields/multiplication.hpp +++ b/include/nil/blueprint/fields/multiplication.hpp @@ -45,6 +45,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -67,7 +68,8 @@ namespace nil { using component_type = components::multiplication< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); var x = variables[operand0]; var y = variables[operand1]; @@ -94,7 +96,8 @@ namespace nil { using component_type = components::multiplication< crypto3::zk::snark::plonk_constraint_system, OperatingFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); std::vector operand0_vars = vectors[operand0]; std::vector operand1_vars = vectors[operand1]; diff --git a/include/nil/blueprint/fields/subtraction.hpp b/include/nil/blueprint/fields/subtraction.hpp index ac3955f7..76b552f5 100644 --- a/include/nil/blueprint/fields/subtraction.hpp +++ b/include/nil/blueprint/fields/subtraction.hpp @@ -45,6 +45,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -67,7 +68,8 @@ namespace nil { using component_type = components::subtraction< crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); var x = variables[operand0]; var y = variables[operand1]; @@ -94,7 +96,8 @@ namespace nil { using component_type = components::subtraction< crypto3::zk::snark::plonk_constraint_system, OperatingFieldType, basic_non_native_policy>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {}, {}); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs()); std::vector operand0_vars = vectors[operand0]; std::vector operand1_vars = vectors[operand1]; diff --git a/include/nil/blueprint/hashes/sha2_256.hpp b/include/nil/blueprint/hashes/sha2_256.hpp index 776f260b..246cb65c 100644 --- a/include/nil/blueprint/hashes/sha2_256.hpp +++ b/include/nil/blueprint/hashes/sha2_256.hpp @@ -42,6 +42,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -67,7 +68,10 @@ namespace nil { typename component_type::input_type instance_input = {input_block_vars}; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {}); + const auto p = detail::PolicyManager::get_parameters(detail::ManifestReader::get_witness(0)); + + component_type component_instance(p.witness, detail::ManifestReader::get_constants(), + detail::ManifestReader::get_public_inputs()); components::generate_circuit(component_instance, bp, assignmnt, instance_input, start_row); diff --git a/include/nil/blueprint/hashes/sha2_512.hpp b/include/nil/blueprint/hashes/sha2_512.hpp index 2c2b4a26..0c12dd99 100644 --- a/include/nil/blueprint/hashes/sha2_512.hpp +++ b/include/nil/blueprint/hashes/sha2_512.hpp @@ -43,6 +43,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -77,8 +78,10 @@ namespace nil { typename sha2_512_component_type::input_type sha2_512_instance_input = {R, A, {{input_vars[16], input_vars[17], input_vars[18], input_vars[19]}}}; - - sha2_512_component_type sha2_512_component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {}); + const auto p_sha2_512 = detail::PolicyManager::get_parameters(detail::ManifestReader::get_witness(0)); + sha2_512_component_type sha2_512_component_instance(p_sha2_512.witness, + detail::ManifestReader::get_constants(), + detail::ManifestReader::get_public_inputs()); components::generate_circuit(sha2_512_component_instance, bp, assignmnt, sha2_512_instance_input, start_row); @@ -89,7 +92,11 @@ namespace nil { crypto3::zk::snark::plonk_constraint_system, BlueprintFieldType, basic_non_native_policy>; - reduction_component_type reduction_component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {}); + const auto p = detail::PolicyManager::get_parameters(detail::ManifestReader::get_witness(0)); + + reduction_component_type reduction_component_instance(p.witness, + detail::ManifestReader::get_constants(), + detail::ManifestReader::get_public_inputs()); start_row = assignmnt.allocated_rows(); diff --git a/include/nil/blueprint/integers/bit_de_composition.hpp b/include/nil/blueprint/integers/bit_de_composition.hpp index ba6e2fc9..1e23e071 100644 --- a/include/nil/blueprint/integers/bit_de_composition.hpp +++ b/include/nil/blueprint/integers/bit_de_composition.hpp @@ -37,6 +37,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -68,9 +69,8 @@ namespace nil { using component_type = nil::blueprint::components::bit_decomposition< crypto3::zk::snark::plonk_constraint_system>; - - component_type component_instance = component_type({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {0}, - BitsAmount, Mode); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0, BitsAmount)); + component_type component_instance = component_type(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs(), BitsAmount, Mode); components::generate_circuit(component_instance, bp, assignment, {component_input}, start_row); return components::generate_assignments(component_instance, assignment, {component_input}, start_row); @@ -104,9 +104,8 @@ namespace nil { bool is_msb = bool(typename BlueprintFieldType::integral_type(var_value(assignment, sig_bit_var).data)); mode Mode = is_msb ? mode::MSB : mode::LSB; - - component_type component_instance = component_type({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {0}, - 128, true, Mode); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0, 128, true)); + component_type component_instance = component_type(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs(), 128, true, Mode); components::generate_circuit(component_instance, bp, assignment, {component_input}, start_row); return components::generate_assignments(component_instance, assignment, {component_input}, start_row); diff --git a/include/nil/blueprint/integers/bit_shift.hpp b/include/nil/blueprint/integers/bit_shift.hpp index b8768bbc..501ccf76 100644 --- a/include/nil/blueprint/integers/bit_shift.hpp +++ b/include/nil/blueprint/integers/bit_shift.hpp @@ -36,6 +36,8 @@ #include #include +#include + namespace nil { namespace blueprint { @@ -67,8 +69,9 @@ namespace nil { using nil::blueprint::components::bit_shift_mode; + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0, Bitness, Shift, left_or_right)); - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {0}, Bitness, Shift, left_or_right); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs(), Bitness, Shift, left_or_right); components::generate_circuit(component_instance, bp, assignment, {x}, start_row); @@ -87,8 +90,6 @@ namespace nil { std::uint32_t start_row, typename nil::blueprint::components::bit_shift_mode left_or_right) { - using non_native_policy_type = basic_non_native_policy; - llvm::Value *operand0 = inst->getOperand(0); llvm::Value *operand1 = inst->getOperand(1); diff --git a/include/nil/blueprint/integers/division_remainder.hpp b/include/nil/blueprint/integers/division_remainder.hpp index 359e23fb..01137e39 100644 --- a/include/nil/blueprint/integers/division_remainder.hpp +++ b/include/nil/blueprint/integers/division_remainder.hpp @@ -36,6 +36,7 @@ #include #include +#include namespace nil { namespace blueprint { @@ -56,10 +57,10 @@ namespace nil { std::uint32_t start_row) { using var = crypto3::zk::snark::plonk_variable; - using component_type = components::division_remainder< crypto3::zk::snark::plonk_constraint_system>; - component_type component_instance({0, 1, 2, 3, 4, 5, 6, 7, 8}, {0}, {0}, Bitness, true); + const auto p = PolicyManager::get_parameters(ManifestReader::get_witness(0, Bitness, true)); + component_type component_instance(p.witness, ManifestReader::get_constants(), ManifestReader::get_public_inputs(), Bitness, true); var x = variables[operand0]; var y = variables[operand1]; diff --git a/include/nil/blueprint/parser.hpp b/include/nil/blueprint/parser.hpp index 909f7b45..c30cd0ba 100644 --- a/include/nil/blueprint/parser.hpp +++ b/include/nil/blueprint/parser.hpp @@ -81,16 +81,19 @@ #include #include +#include + namespace nil { namespace blueprint { template struct parser { - parser(long stack_size, bool detailed_logging) : stack_memory(stack_size) { + parser(long stack_size, bool detailed_logging, const std::string &kind = "") : stack_memory(stack_size) { if (detailed_logging) { log.set_level(logger::level::DEBUG); } + detail::PolicyManager::set_policy(kind); } using ArithmetizationType = diff --git a/include/nil/blueprint/policy/default_policy.hpp b/include/nil/blueprint/policy/default_policy.hpp new file mode 100644 index 00000000..0dea1cdb --- /dev/null +++ b/include/nil/blueprint/policy/default_policy.hpp @@ -0,0 +1,48 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Kokoshnikov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_DEFAULT_POLICY_HPP +#define CRYPTO3_ASSIGNER_DEFAULT_POLICY_HPP + +#include + +#include + +namespace nil { + namespace blueprint { + namespace detail { + struct DefaultPolicy: public Policy { + FlexibleParameters get_parameters(const std::vector>& witness_variants) const override { + const auto witness_amount = *std::min_element(witness_variants.begin(), witness_variants.end(), + [](const std::pair& a, + const std::pair& b) { + return a.second < b.second;}); + return FlexibleParameters(witness_amount.first); + } + }; + } // namespace detail + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_DEFAULT_POLICY_HPP diff --git a/include/nil/blueprint/policy/policy.hpp b/include/nil/blueprint/policy/policy.hpp new file mode 100644 index 00000000..951b805d --- /dev/null +++ b/include/nil/blueprint/policy/policy.hpp @@ -0,0 +1,43 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Kokoshnikov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_POLICY_HPP +#define CRYPTO3_ASSIGNER_POLICY_HPP + +#include + +#include + +namespace nil { + namespace blueprint { + namespace detail { + struct Policy { + virtual FlexibleParameters get_parameters(const std::vector>& witness_variants) const = 0; + }; + } // namespace detail + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_POLICY_HPP diff --git a/include/nil/blueprint/policy/policy_manager.hpp b/include/nil/blueprint/policy/policy_manager.hpp new file mode 100644 index 00000000..ee518b1f --- /dev/null +++ b/include/nil/blueprint/policy/policy_manager.hpp @@ -0,0 +1,76 @@ +//---------------------------------------------------------------------------// +// Copyright (c) 2023 Alexey Kokoshnikov +// +// MIT License +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//---------------------------------------------------------------------------// + +#ifndef CRYPTO3_ASSIGNER_POLICY_MANAGER_HPP +#define CRYPTO3_ASSIGNER_POLICY_MANAGER_HPP + +#include +#include + +#include + +namespace nil { + namespace blueprint { + namespace detail { + + enum class policy_kind { + DEFAULT + }; + + struct PolicyManager { + static FlexibleParameters get_parameters(const std::vector > &witness_variants) { + if (!policy) { + policy.reset(new DefaultPolicy()); + } + return policy->get_parameters(witness_variants); + } + + static void set_policy(policy_kind kind) { + switch (kind) { + case policy_kind::DEFAULT: + default: { + policy.reset(new DefaultPolicy()); + } + } + } + + static void set_policy(const std::string &kind_str) { + const auto it = policy_kind_map.find(kind_str); + if (it != policy_kind_map.end()) { + set_policy(it->second); + } + } + private: + inline static std::shared_ptr policy = nullptr; + + inline static const std::map policy_kind_map = { + {"default", policy_kind::DEFAULT} + }; + }; + } // namespace detail + } // namespace blueprint +} // namespace nil + +#endif // CRYPTO3_ASSIGNER_POLICY_MANAGER_HPP