Skip to content
This repository has been archived by the owner on Nov 18, 2021. It is now read-only.

Commit

Permalink
Initial BLS Beacon (#1284)
Browse files Browse the repository at this point in the history
  • Loading branch information
ejfitzgerald committed Jun 29, 2019
1 parent 2f88722 commit e12b040
Show file tree
Hide file tree
Showing 43 changed files with 2,721 additions and 73 deletions.
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@
[submodule "vendor/spdlog"]
path = vendor/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "vendor/mcl"]
path = vendor/mcl
url = https://github.com/herumi/mcl.git
[submodule "vendor/bls"]
path = vendor/bls
url = https://github.com/herumi/bls.git
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ features. Fetch.AI will be delivering regular updates.
* MacOS Darwin 10.13x and higher (64bit)
* Ubuntu 18.04 (x86_64)

(We plan to support all major platforms in the future)
(We plan to support all major platforms in the future).

## Getting Started

Expand Down
2 changes: 1 addition & 1 deletion apps/constellation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ add_executable(constellation
health_check_http_module.hpp
logging_http_module.hpp
main.cpp)
target_link_libraries(constellation PRIVATE fetch-ledger fetch-miner)
target_link_libraries(constellation PRIVATE fetch-ledger fetch-miner fetch-dkg)
target_include_directories(constellation PRIVATE ${FETCH_ROOT_DIR}/libs/python/include)
40 changes: 38 additions & 2 deletions apps/constellation/constellation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "ledger/chaincode/contract_http_interface.hpp"
#include "ledger/dag/dag_interface.hpp"

#include "dkg/dkg_service.hpp"
#include "ledger/consensus/naive_entropy_generator.hpp"
#include "ledger/consensus/stake_snapshot.hpp"
#include "ledger/execution_manager.hpp"
Expand Down Expand Up @@ -58,6 +59,7 @@ using fetch::network::Uri;
using fetch::network::Peer;
using fetch::ledger::Address;
using fetch::ledger::GenesisFileCreator;
using fetch::muddle::MuddleEndpoint;

using ExecutorPtr = std::shared_ptr<Executor>;

Expand All @@ -67,6 +69,7 @@ namespace {
using LaneIndex = fetch::ledger::LaneIdentity::lane_type;
using StakeManagerPtr = std::shared_ptr<ledger::StakeManager>;
using EntropyPtr = std::unique_ptr<ledger::EntropyGeneratorInterface>;
using DkgServicePtr = std::unique_ptr<dkg::DkgService>;
using ConstByteArray = byte_array::ConstByteArray;

static const std::size_t HTTP_THREADS{4};
Expand Down Expand Up @@ -163,6 +166,21 @@ StakeManagerPtr CreateStakeManager(bool enabled, ledger::EntropyGeneratorInterfa
return mgr;
}

DkgServicePtr CreateDkgService(Constellation::Config const &cfg, ConstByteArray address,
MuddleEndpoint &endpoint)
{
DkgServicePtr dkg{};

if (cfg.proof_of_stake && !cfg.beacon_address.empty())
{
crypto::bls::Init();

dkg = std::make_unique<dkg::DkgService>(endpoint, address, cfg.beacon_address);
}

return dkg;
}

} // namespace

/**
Expand Down Expand Up @@ -199,6 +217,7 @@ Constellation::Constellation(CertificatePtr certificate, Config config)
cfg_.log2_num_lanes))
, lane_control_(internal_muddle_.AsEndpoint(), shard_cfgs_, cfg_.log2_num_lanes)
, dag_{GenerateDAG(cfg_.features.IsEnabled("synergetic"), "dag_db_", true, certificate)}
, dkg_{CreateDkgService(cfg_, certificate->identity().identifier(), muddle_.AsEndpoint())}
, entropy_{CreateEntropy()}
, stake_{CreateStakeManager(cfg_.proof_of_stake, *entropy_)}
, execution_manager_{std::make_shared<ExecutionManager>(
Expand Down Expand Up @@ -271,6 +290,12 @@ Constellation::Constellation(CertificatePtr certificate, Config config)
{
http_.AddModule(*module);
}

// If we are using the DKG service we need to update the default entropy engine for PoS
if (dkg_)
{
stake_->UpdateEntropy(*dkg_);
}
}

/**
Expand Down Expand Up @@ -360,7 +385,7 @@ void Constellation::Run(UriList const &initial_peers, core::WeakRunnable bootstr
{
FETCH_LOG_INFO(LOGGING_NAME, "Loading from genesis save file.");

GenesisFileCreator creator(block_coordinator_, *storage_, stake_.get());
GenesisFileCreator creator(block_coordinator_, *storage_, stake_.get(), dkg_.get());
creator.LoadFile(SNAPSHOT_FILENAME);

FETCH_LOG_INFO(LOGGING_NAME, "Loaded from genesis save file.");
Expand Down Expand Up @@ -393,10 +418,21 @@ void Constellation::Run(UriList const &initial_peers, core::WeakRunnable bootstr
// Step 2. Main monitor loop
//---------------------------------------------------------------
bool start_up_in_progress{true};
bool dkg_attached{false};

// monitor loop
while (active_)
{
// wait for at least one connected peer
if (!muddle_.AsEndpoint().GetDirectlyConnectedPeers().empty())
{
if (dkg_ && !dkg_attached)
{
reactor_.Attach(dkg_->GetWeakRunnable());
dkg_attached = true;
}
}

// determine the status of the main chain server
bool const is_in_sync = main_chain_service_->IsSynced() && block_coordinator_.IsSynced();

Expand Down Expand Up @@ -440,7 +476,7 @@ void Constellation::Run(UriList const &initial_peers, core::WeakRunnable bootstr
{
FETCH_LOG_INFO(LOGGING_NAME, "Creating genesis save file.");

GenesisFileCreator creator(block_coordinator_, *storage_, stake_.get());
GenesisFileCreator creator(block_coordinator_, *storage_, stake_.get(), dkg_.get());
creator.CreateFile(SNAPSHOT_FILENAME);
}

Expand Down
48 changes: 28 additions & 20 deletions apps/constellation/constellation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@
#include <vector>

namespace fetch {
namespace dkg {

class DkgService;
}

/**
* Top level container for all components that are required to run a ledger instance
Expand All @@ -66,31 +70,33 @@ class Constellation : public ledger::BlockSinkInterface
using Manifest = network::Manifest;
using NetworkMode = ledger::MainChainRpcService::Mode;
using FeatureFlags = core::FeatureFlags;
using ConstByteArray = byte_array::ConstByteArray;

static constexpr uint32_t DEFAULT_BLOCK_DIFFICULTY = 6;

struct Config
{
Manifest manifest{};
uint32_t log2_num_lanes{0};
uint32_t num_slices{0};
uint32_t num_executors{0};
std::string interface_address{};
std::string db_prefix{};
uint32_t processor_threads{0};
uint32_t verification_threads{0};
uint32_t max_peers{0};
uint32_t transient_peers{0};
uint32_t block_interval_ms{0};
uint32_t block_difficulty{DEFAULT_BLOCK_DIFFICULTY};
uint32_t peers_update_cycle_ms{0};
bool disable_signing{false};
bool sign_broadcasts{false};
bool dump_state_file{false};
bool load_state_file{false};
bool proof_of_stake{false};
NetworkMode network_mode{NetworkMode::PUBLIC_NETWORK};
FeatureFlags features{};
Manifest manifest{};
uint32_t log2_num_lanes{0};
uint32_t num_slices{0};
uint32_t num_executors{0};
std::string interface_address{};
std::string db_prefix{};
uint32_t processor_threads{0};
uint32_t verification_threads{0};
uint32_t max_peers{0};
uint32_t transient_peers{0};
uint32_t block_interval_ms{0};
uint32_t block_difficulty{DEFAULT_BLOCK_DIFFICULTY};
uint32_t peers_update_cycle_ms{0};
bool disable_signing{false};
bool sign_broadcasts{false};
bool dump_state_file{false};
bool load_state_file{false};
bool proof_of_stake{false};
NetworkMode network_mode{NetworkMode::PUBLIC_NETWORK};
ConstByteArray beacon_address{};
FeatureFlags features{};

uint32_t num_lanes() const
{
Expand Down Expand Up @@ -138,6 +144,7 @@ class Constellation : public ledger::BlockSinkInterface
using NaiveSynergeticMiner = ledger::NaiveSynergeticMiner;
using StakeManagerPtr = std::shared_ptr<ledger::StakeManager>;
using EntropyPtr = std::unique_ptr<ledger::EntropyGeneratorInterface>;
using DkgServicePtr = std::shared_ptr<dkg::DkgService>;

using ShardConfigs = ledger::ShardConfigs;
using TxStatusCache = ledger::TransactionStatusCache;
Expand Down Expand Up @@ -178,6 +185,7 @@ class Constellation : public ledger::BlockSinkInterface

/// @name Staking
/// @{
DkgServicePtr dkg_; ///< The DKG system
EntropyPtr entropy_; ///< The entropy system
StakeManagerPtr stake_; ///< The stake system
/// @}
Expand Down
9 changes: 9 additions & 0 deletions apps/constellation/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ struct CommandLineArguments
std::string config_path;
std::string raw_peers;
std::string experimental_features;
std::string beacon_address;
ManifestPtr manifest;
uint32_t num_lanes{0};

Expand Down Expand Up @@ -268,6 +269,7 @@ struct CommandLineArguments
p.add(private_flag, "private-network", "Run node as part of a private network (disables bootstrap). Incompatible with -standalone", false);
p.add(experimental_features, "experimental", "Enable selected experimental features", std::string{});
p.add(args.cfg.proof_of_stake, "pos", "Enable proof of stake features", false);
p.add(beacon_address, "beacon", "The base64 encoded address of the beacon", std::string{});
// clang-format on

// parse the args
Expand Down Expand Up @@ -303,11 +305,18 @@ struct CommandLineArguments
UpdateConfigFromEnvironment(private_flag, "CONSTELLATION_PRIVATE_NETWORK");
UpdateConfigFromEnvironment(experimental_features, "CONSTELLATION_EXPERIMENTAL");
UpdateConfigFromEnvironment(args.cfg.proof_of_stake, "CONSTELLATION_POS");
UpdateConfigFromEnvironment(beacon_address, "CONSTELLATION_BEACON_ADDRESS");
// clang-format on

// parse the feature flags (if they exist)
args.cfg.features.Parse(experimental_features);

// beacon address
if (!beacon_address.empty())
{
args.cfg.beacon_address = fetch::byte_array::FromBase64(beacon_address);
}

// update the peers
args.SetPeers(raw_peers);

Expand Down
31 changes: 31 additions & 0 deletions cmake/BuildTargets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,37 @@ function (configure_vendor_targets)
# Google Test
add_subdirectory(${FETCH_ROOT_VENDOR_DIR}/googletest)

# MCL
set(USE_GMP OFF CACHE BOOL "use gmp" FORCE)
set(USE_OPENSSL OFF CACHE BOOL "use openssl" FORCE)
# TODO: Work out how to get this to work with the already found version of OpenSSL

add_subdirectory(${FETCH_ROOT_VENDOR_DIR}/mcl)
target_include_directories(mcl INTERFACE ${FETCH_ROOT_VENDOR_DIR}/mcl/include)
target_compile_definitions(mcl
INTERFACE
-DMCL_USE_VINT
-DMCL_VINT_FIXED_BUFFER)

add_library(vendor-mcl INTERFACE)
target_link_libraries(vendor-mcl INTERFACE mcl)
target_compile_definitions(vendor-mcl INTERFACE -DMCLBN_FP_UNIT_SIZE=4)

# BLS
add_library(libbls-internal STATIC ${FETCH_ROOT_VENDOR_DIR}/bls/src/bls_c256.cpp
${FETCH_ROOT_VENDOR_DIR}/bls/src/bls_c384.cpp
${FETCH_ROOT_VENDOR_DIR}/bls/src/bls_c384_256.cpp)
target_link_libraries(libbls-internal PUBLIC mcl)
target_include_directories(libbls-internal PUBLIC ${FETCH_ROOT_VENDOR_DIR}/bls/include)
target_compile_definitions(libbls-internal
PUBLIC
-DMCL_USE_VINT
-DMCL_VINT_FIXED_BUFFER)

add_library(vendor-bls INTERFACE)
target_link_libraries(vendor-bls INTERFACE libbls-internal)
target_compile_definitions(vendor-bls INTERFACE -DMCLBN_FP_UNIT_SIZE=4)

# Google Benchmark Do not build the google benchmark library tests
if (FETCH_ENABLE_BENCHMARKS)
set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Suppress google benchmark default tests" FORCE)
Expand Down
111 changes: 111 additions & 0 deletions libs/core/include/core/containers/mapping.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#pragma once
//------------------------------------------------------------------------------
//
// Copyright 2018-2019 Fetch.AI Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//------------------------------------------------------------------------------

#include <type_traits>
#include <unordered_map>

namespace fetch {
namespace core {

template <typename Key, typename Value>
class Mapping
{
public:
// Construction / Destruction
Mapping() = default;
Mapping(Mapping const &) = default;
Mapping(Mapping &&) noexcept = default;
~Mapping() = default;

bool Lookup(Key const &key, Value &value);
bool Lookup(Value const &value, Key &key);
void Update(Key const &key, Value const &value);

// Operators
Mapping &operator=(Mapping const &) = default;
Mapping &operator=(Mapping &&) noexcept = default;

private:
using ForwardIndex = std::unordered_map<Key, Value>;
using ReverseIndex = std::unordered_map<Value, Key>;

ForwardIndex forward_index_;
ReverseIndex reverse_index_;

static_assert(!std::is_same<Key, Value>::value, "");
};

template <typename K, typename V>
bool Mapping<K, V>::Lookup(K const &key, V &value)
{
bool success{false};

auto const it = forward_index_.find(key);
if (it != forward_index_.end())
{
value = it->second;
success = true;
}

return success;
}

template <typename K, typename V>
bool Mapping<K, V>::Lookup(V const &value, K &key)
{
bool success{false};

auto const it = reverse_index_.find(value);
if (it != reverse_index_.end())
{
key = it->second;
success = true;
}

return success;
}

template <typename K, typename V>
void Mapping<K, V>::Update(K const &key, V const &value)
{
// update the forward map
auto const forward_it = forward_index_.find(key);
if (forward_it == forward_index_.end())
{
forward_index_.emplace(key, value);
}
else
{
forward_it->second = value;
}

// update the reverse map
auto const reverse_it = reverse_index_.find(value);
if (reverse_it == reverse_index_.end())
{
reverse_index_.emplace(value, key);
}
else
{
reverse_it->second = key;
}
}

} // namespace core
} // namespace fetch
Loading

0 comments on commit e12b040

Please sign in to comment.