Skip to content

Commit

Permalink
Set features on startup from config.genesis (FISCO-BCOS#4046)
Browse files Browse the repository at this point in the history
  • Loading branch information
morebtcg authored Nov 15, 2023
1 parent 5d9163d commit 14089e4
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 275 deletions.
16 changes: 15 additions & 1 deletion bcos-framework/bcos-framework/ledger/GenesisConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,18 @@ namespace bcos::ledger
struct FeatureSet
{
Features::Flag flag{};
protocol::BlockNumber enableNumber{};
int enable{};
};

struct Alloc
{
using State = std::pair<std::string, std::string>;

std::string address;
u256 nonce;
u256 balance;
std::string code;
std::vector<State> storage;
};

class GenesisConfig
Expand Down Expand Up @@ -68,6 +79,9 @@ class GenesisConfig
// rpbft config
int64_t m_epochSealerNum = 4;
int64_t m_epochBlockNum = 1000;

std::vector<FeatureSet> m_features;
std::vector<Alloc> m_allocs;

}; // namespace genesisConfig
} // namespace bcos::ledger
1 change: 1 addition & 0 deletions bcos-framework/bcos-framework/ledger/LedgerTypeDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ constexpr static std::string_view SYS_KEY_TOTAL_FAILED_TRANSACTION =
"total_failed_transaction_count";

// sys table name
constexpr static std::string_view SYS_TABLES{"s_tables"};
constexpr static std::string_view SYS_CONSENSUS{"s_consensus"};
constexpr static std::string_view SYS_CONFIG{"s_config"};
constexpr static std::string_view SYS_CURRENT_STATE{"s_current_state"};
Expand Down
13 changes: 11 additions & 2 deletions bcos-framework/bcos-framework/storage/Entry.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class Entry
std::shared_ptr<std::vector<unsigned char>>, std::shared_ptr<std::vector<char>>>;

Entry() = default;
explicit Entry(auto input) { set(std::move(input)); }

Entry(const Entry&) = default;
Entry(Entry&&) noexcept = default;
bcos::storage::Entry& operator=(const Entry&) = default;
Expand Down Expand Up @@ -81,14 +83,14 @@ class Entry

template <typename In, typename OutputArchive = boost::archive::binary_oarchive,
int flag = ARCHIVE_FLAG>
void setObject(const In& in)
void setObject(const In& input)
{
std::string value;
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> outputStream(
value);
OutputArchive archive(outputStream, flag);

archive << in;
archive << input;
outputStream.flush();

setField(0, std::move(value));
Expand Down Expand Up @@ -162,6 +164,13 @@ class Entry

m_status = MODIFIED;
}
template <EntryBufferInput T>
void set(std::shared_ptr<T> value)
{
m_size = value->size();
m_value = std::move(value);
m_status = MODIFIED;
}

template <typename T>
void setPointer(std::shared_ptr<T>&& value)
Expand Down
32 changes: 28 additions & 4 deletions bcos-ledger/src/libledger/Ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ using namespace bcos::protocol;
using namespace bcos::storage;
using namespace bcos::crypto;
using namespace bcos::tool;

using namespace std::string_view_literals;

void Ledger::asyncPreStoreBlockTxs(bcos::protocol::TransactionsPtr _blockTxs,
bcos::protocol::Block::ConstPtr block, std::function<void(Error::UniquePtr&&)> _callback)
Expand Down Expand Up @@ -1595,6 +1595,32 @@ void Ledger::getReceiptProof(protocol::TransactionReceipt::Ptr _receipt,
});
}

static task::Task<void> setGenesisFeatures(RANGES::input_range auto const& featureSets,
const ledger::Features existsFeatures, auto& storage)
{
ledger::Features features = existsFeatures;
for (auto&& featureSet : featureSets)
{
if (featureSet.enable > 0)
{
features.set(featureSet.flag);
}
}
co_await features.writeToStorage(storage, 0);
}

#if 0
static task::Task<void> setAlloc(RANGES::input_range auto const& allocs, auto& storage)
{
for (auto&& alloc : allocs)
{
co_await storage2::writeOne(
storage, std::make_tuple(SYS_TABLES, alloc.address), storage::Entry("value"sv));
}
co_return;
}
#endif

// sync method, to be split
// FIXME: too long
bool Ledger::buildGenesisBlock(
Expand Down Expand Up @@ -1750,7 +1776,6 @@ bool Ledger::buildGenesisBlock(
}
}


createFileSystemTables(genesis.m_compatibilityVersion);
auto txLimit = genesis.m_txCountLimit;
LEDGER_LOG(INFO) << LOG_DESC("Commit the genesis block") << LOG_KV("txLimit", txLimit)
Expand Down Expand Up @@ -1839,6 +1864,7 @@ bool Ledger::buildGenesisBlock(
notifyRotateEntry.setObject(SystemConfigEntry("0", 0));
sysTable->setRow(INTERNAL_SYSTEM_KEY_NOTIFY_ROTATE, std::move(notifyRotateEntry));
}
task::syncWait(setGenesisFeatures(genesis.m_features, features, *m_storage));

// consensus leader period
Entry leaderPeriodEntry;
Expand Down Expand Up @@ -1964,8 +1990,6 @@ bool Ledger::buildGenesisBlock(
Entry archivedNumber;
archivedNumber.importFields({"0"});
stateTable->setRow(SYS_KEY_ARCHIVED_NUMBER, std::move(archivedNumber));

task::syncWait(features.writeToStorage(*m_storage, 0));
return true;
}

Expand Down
1 change: 1 addition & 0 deletions bcos-ledger/src/libledger/Ledger.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* @date 2021-04-13
*/
#pragma once
#include "bcos-framework/ledger/Features.h"
#include "bcos-framework/ledger/GenesisConfig.h"
#include "bcos-framework/ledger/LedgerInterface.h"
#include "bcos-framework/ledger/LedgerTypeDef.h"
Expand Down
4 changes: 2 additions & 2 deletions bcos-tool/bcos-tool/NodeConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,7 @@ void bcos::tool::NodeConfig::loadGenesisFeatures(boost::property_tree::ptree con
auto flag = it.first;
auto enableNumber = it.second.get_value<bool>();
m_genesisConfig.m_features.emplace_back(ledger::FeatureSet{
.flag = ledger::Features::string2Flag(flag), .enableNumber = enableNumber});
.flag = ledger::Features::string2Flag(flag), .enable = enableNumber});
}
}
}
Expand Down Expand Up @@ -1063,7 +1063,7 @@ std::string bcos::tool::generateGenesisData(
ss << "[features]" << '\n';
for (const auto& feature : genesisConfig.m_features)
{
ss << feature.flag << ":" << feature.enableNumber << '\n';
ss << feature.flag << ":" << feature.enable << '\n';
}
}

Expand Down
128 changes: 66 additions & 62 deletions libtask/bcos-task/TBBWait.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,86 +9,90 @@
namespace bcos::task::tbb
{

template <class Task>
auto syncWait(Task&& task) -> AwaitableReturnType<std::remove_cvref_t<Task>>
requires IsAwaitable<Task> && std::is_rvalue_reference_v<decltype(task)>
struct SyncWait
{
using ReturnType = AwaitableReturnType<std::remove_cvref_t<Task>>;
using ReturnTypeWrap = std::conditional_t<std::is_reference_v<ReturnType>,
std::add_pointer_t<ReturnType>, ReturnType>;
using ReturnVariant = std::conditional_t<std::is_void_v<ReturnType>,
std::variant<std::monostate, std::exception_ptr>,
std::variant<std::monostate, ReturnTypeWrap, std::exception_ptr>>;
template <class Task>
auto operator()(Task&& task) const -> AwaitableReturnType<std::remove_cvref_t<Task>>
requires IsAwaitable<Task> && std::is_rvalue_reference_v<decltype(task)>
{
using ReturnType = AwaitableReturnType<std::remove_cvref_t<Task>>;
using ReturnTypeWrap = std::conditional_t<std::is_reference_v<ReturnType>,
std::add_pointer_t<ReturnType>, ReturnType>;
using ReturnVariant = std::conditional_t<std::is_void_v<ReturnType>,
std::variant<std::monostate, std::exception_ptr>,
std::variant<std::monostate, ReturnTypeWrap, std::exception_ptr>>;

ReturnVariant result;
boost::atomic_flag finished{};
boost::atomic<oneapi::tbb::task::suspend_point> suspendPoint{};
ReturnVariant result;
boost::atomic_flag finished{};
boost::atomic<oneapi::tbb::task::suspend_point> suspendPoint{};

auto waitTask =
[](Task&& task, decltype(result)& result, boost::atomic_flag& finished,
boost::atomic<oneapi::tbb::task::suspend_point>& suspendPoint) -> task::Task<void> {
try
{
if constexpr (std::is_void_v<ReturnType>)
auto waitTask =
[](Task&& task, decltype(result)& result, boost::atomic_flag& finished,
boost::atomic<oneapi::tbb::task::suspend_point>& suspendPoint) -> task::Task<void> {
try
{
co_await task;
}
else
{
if constexpr (std::is_reference_v<ReturnType>)
if constexpr (std::is_void_v<ReturnType>)
{
decltype(auto) ref = co_await task;
result = std::addressof(ref);
co_await task;
}
else
{
result = co_await task;
if constexpr (std::is_reference_v<ReturnType>)
{
decltype(auto) ref = co_await task;
result = std::addressof(ref);
}
else
{
result = co_await task;
}
}
}
}
catch (...)
{
result = std::current_exception();
}
catch (...)
{
result = std::current_exception();
}

if (finished.test_and_set())
{
// finished已经被设置,说明外部已经suspend了,此处要获取spsendPoint并resume
// finished has been set, which means that the external has been suspended, here you
// need to get spsendPoint and resume
suspendPoint.wait({});
oneapi::tbb::task::resume(suspendPoint.load());
}
}(std::forward<Task>(task), result, finished, suspendPoint);
waitTask.start();

if (finished.test_and_set())
if (!finished.test_and_set())
{
// finished已经被设置,说明外部已经suspend了,此处要获取spsendPoint并resume
// finished has been set, which means that the external has been suspended, here you
// need to get spsendPoint and resume
suspendPoint.wait({});
oneapi::tbb::task::resume(suspendPoint.load());
// finished第一次被设置,说明task还在执行中,suspend并等待task来执行resume
// finished is set for the first time, indicating that the task is still being executed,
// suspending and waiting for the task to execute resume
oneapi::tbb::task::suspend([&](oneapi::tbb::task::suspend_point tag) {
suspendPoint.store(tag);
suspendPoint.notify_one();
});
}
}(std::forward<Task>(task), result, finished, suspendPoint);
waitTask.start();

if (!finished.test_and_set())
{
// finished第一次被设置,说明task还在执行中,suspend并等待task来执行resume
// finished is set for the first time, indicating that the task is still being executed,
// suspending and waiting for the task to execute resume
oneapi::tbb::task::suspend([&](oneapi::tbb::task::suspend_point tag) {
suspendPoint.store(tag);
suspendPoint.notify_one();
});
}

if (std::holds_alternative<std::exception_ptr>(result))
{
std::rethrow_exception(std::get<std::exception_ptr>(result));
}

if constexpr (!std::is_void_v<ReturnType>)
{
if constexpr (std::is_reference_v<ReturnType>)
if (std::holds_alternative<std::exception_ptr>(result))
{
return *(std::get<ReturnTypeWrap>(result));
std::rethrow_exception(std::get<std::exception_ptr>(result));
}
else

if constexpr (!std::is_void_v<ReturnType>)
{
return std::move(std::get<ReturnTypeWrap>(result));
if constexpr (std::is_reference_v<ReturnType>)
{
return *(std::get<ReturnTypeWrap>(result));
}
else
{
return std::move(std::get<ReturnTypeWrap>(result));
}
}
}
}
};
constexpr inline static SyncWait syncWait{};

} // namespace bcos::task::tbb
Loading

0 comments on commit 14089e4

Please sign in to comment.