Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/FISCO-BCOS/FISCO-BCOS int…
Browse files Browse the repository at this point in the history
…o release-3.11.0
  • Loading branch information
bxq2011hust committed Aug 16, 2024
2 parents c6f8840 + 3bddba8 commit cb711ed
Show file tree
Hide file tree
Showing 19 changed files with 212 additions and 216 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/workflow-self-hosted-centos-upload.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ on:
branches:
- release-3.*
- feature-3.*
- bugfix-3.*
- master
release:
types: [ push ]
Expand Down Expand Up @@ -76,7 +77,7 @@ jobs:
. /opt/rh/rh-perl530/enable
export LIBCLANG_PATH=/opt/rh/llvm-toolset-7.0/root/lib64/
. /opt/rh/llvm-toolset-7.0/enable
cd build && cmake -DALLOCATOR=jemalloc -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DTESTS=ON -DWITH_LIGHTNODE=OFF -DWITH_CPPSDK=OFF -DWITH_TIKV=OFF -DWITH_TARS_SERVICES=OFF .. || cat *.log
cd build && cmake -DALLOCATOR=defalut -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake -DTESTS=ON -DWITH_LIGHTNODE=OFF -DWITH_CPPSDK=OFF -DWITH_TIKV=OFF -DWITH_TARS_SERVICES=OFF .. || cat *.log
make -j8
chmod +x ./fisco-bcos-air/fisco-bcos
./fisco-bcos-air/fisco-bcos -v
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,8 @@ FISCO BCOS(读作/ˈfɪskl bi:ˈkɒz/) 是一个稳定、高效、安全的
单链配置下,性能TPS可达10万+。全面支持国密算法、国产操作系统与国产CPU架构。包含区块流水线、可拔插共识机制、全方位并行计算、区块链文件系统、权限治理框架、分布式存储等特性。

## 版本信息
-
稳定版本(生产环境使用):v3.2.7,版本内容可参考[《FISCO-BCOS v3.2.7版本说明》](https://github.com/FISCO-BCOS/FISCO-BCOS/releases/tag/v3.2.7)
-
最新版本(用户体验新特性):v3.9.0,版本内容可参考 [《FISCO-BCOS v3.9.0版本说明》](https://github.com/FISCO-BCOS/FISCO-BCOS/releases/tag/v3.9.0)
- 稳定版本(生产环境使用):v3.7.3,版本内容可参考[《FISCO-BCOS v3.7.3版本说明》](https://github.com/FISCO-BCOS/FISCO-BCOS/releases/tag/v3.7.3)
- 最新版本(用户体验新特性):v3.10.0,版本内容可参考 [《FISCO-BCOS v3.10.0版本说明》](https://github.com/FISCO-BCOS/FISCO-BCOS/releases/tag/v3.10.0)

## 系统概述
FISCO BCOS系统架构包括基础层、核心层、服务层、用户层和接入层提供稳定、安全的区块链底层服务。中间件层通过可视化界面,简化了用户管理区块链系统的流程。右侧配套相关开发、运维、安全控制的组件,辅助应用落地过程中不同角色的需要;同时,提供隐私保护和跨链相关的技术组件,满足不同场景的应用诉求。
Expand Down
11 changes: 6 additions & 5 deletions bcos-executor/src/executor/TransactionExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2054,9 +2054,12 @@ void TransactionExecutor::getCode(
// asyncGetRow key should not be empty
auto codeKey = codeHash.empty() ? ACCOUNT_CODE : codeHash;
// try to get abi from SYS_CODE_BINARY first
ledger::Features features;
task::syncWait(features.readFromStorage(*stateStorage, m_lastCommittedBlockNumber));
stateStorage->asyncGetRow(bcos::ledger::SYS_CODE_BINARY, codeKey,
[this, contractTableName, callback = std::move(callback),
getCodeFromContractTable = std::move(getCodeFromContractTable)](
getCodeFromContractTable = std::move(getCodeFromContractTable),
features = std::move(features)](
Error::UniquePtr error, std::optional<Entry> entry) {
if (!m_isRunning)
{
Expand All @@ -2083,11 +2086,9 @@ void TransactionExecutor::getCode(
}

auto code = entry->getField(0);
if ((m_blockContext->features().get(
ledger::Features::Flag::bugfix_eoa_as_contract) &&
if ((features.get(ledger::Features::Flag::bugfix_eoa_as_contract) &&
bcos::precompiled::isDynamicPrecompiledAccountCode(code)) ||
(m_blockContext->features().get(
ledger::Features::Flag::bugfix_eoa_match_failed) &&
(features.get(ledger::Features::Flag::bugfix_eoa_match_failed) &&
bcos::precompiled::matchDynamicAccountCode(code)))
{
EXECUTOR_NAME_LOG(DEBUG) << "Get eoa code success, return empty code to evm";
Expand Down
5 changes: 3 additions & 2 deletions bcos-executor/src/precompiled/common/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,14 @@ inline std::string getDynamicPrecompiledCodeString(

inline bool matchDynamicAccountCode(std::string_view code)
{
return code.starts_with(getDynamicPrecompiledCodeString(ACCOUNT_ADDRESS, ""));
auto const prefix = getDynamicPrecompiledCodeString(ACCOUNT_ADDRESS, "");
return code.starts_with(prefix);
}

// ERROR: this method match account precompiled in wrong logic, use matchDynamicAccountCode instead.
inline bool isDynamicPrecompiledAccountCode(const std::string_view& _code)
{
return std::string_view(getDynamicPrecompiledCodeString(ACCOUNT_ADDRESS, "")) == _code;
return getDynamicPrecompiledCodeString(ACCOUNT_ADDRESS, "") == _code;
}

inline std::string trimHexPrefix(const std::string& _hex)
Expand Down
1 change: 1 addition & 0 deletions bcos-executor/src/vm/gas_meter/Metric.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace bcos
{
namespace wasm
{
using bcos::wasm::Instruction;
InstructionTable GetInstructionTable()
{
auto defaultInstructionTable = InstructionTable{};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once

#include "../protocol/Block.h"
#include "../protocol/BlockHeader.h"
#include "../protocol/TransactionReceipt.h"
#include "bcos-task/Task.h"
#include "bcos-task/Trait.h"
#include "bcos-utilities/Ranges.h"

namespace bcos::transaction_scheduler
{
Expand Down
4 changes: 4 additions & 0 deletions bcos-rpc/bcos-rpc/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ using namespace bcos::rpc;
std::tuple<protocol::BlockNumber, bool> bcos::rpc::getBlockNumberByTag(
protocol::BlockNumber latest, std::string_view blockTag)
{
if (blockTag.data() == nullptr || blockTag.empty())
{
return std::make_tuple(latest, true);
}
if (blockTag == EarliestBlock)
{
return std::make_tuple(0, false);
Expand Down
79 changes: 39 additions & 40 deletions bcos-rpc/bcos-rpc/web3jsonrpc/endpoints/EthEndpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <bcos-rpc/web3jsonrpc/utils/Common.h>
#include <bcos-rpc/web3jsonrpc/utils/util.h>
#include <bcos-tars-protocol/protocol/TransactionImpl.h>
#include <variant>

using namespace bcos;
using namespace bcos::rpc;
Expand Down Expand Up @@ -348,35 +349,35 @@ task::Task<void> EthEndpoint::getCode(const Json::Value& request, Json::Value& r
struct Awaitable
{
bcos::scheduler::SchedulerInterface::Ptr m_scheduler;
std::string m_address;
std::string& m_address;
std::variant<Error::Ptr, bcos::bytes> m_result{};
constexpr static bool await_ready() noexcept { return false; }
void await_suspend(std::coroutine_handle<> handle) noexcept
{
m_scheduler->getCode(m_address, [this, handle](auto&& error, auto&& code) {
if (error)
{
m_result.emplace<Error::Ptr>(std::move(error));
m_result.emplace<Error::Ptr>(std::forward<decltype(error)>(error));
}
else
{
m_result.emplace<bcos::bytes>(std::move(code));
m_result.emplace<bcos::bytes>(std::forward<decltype(code)>(code));
}
handle.resume();
});
}
bcos::bytes await_resume() noexcept
bcos::bytes await_resume()
{
if (std::holds_alternative<Error::Ptr>(m_result))
{
BOOST_THROW_EXCEPTION(*std::get<Error::Ptr>(m_result));
}
return std::move(std::get<bcos::bytes>(m_result));
return std::get<bcos::bytes>(m_result);
}
};
auto const code = co_await Awaitable{
.m_scheduler = scheduler,
.m_address = std::move(addressStr),
.m_address = addressStr,
};
Json::Value result = toHexStringWithPrefix(code);
buildJsonContent(result, response);
Expand Down Expand Up @@ -475,70 +476,68 @@ task::Task<void> EthEndpoint::call(const Json::Value& request, Json::Value& resp
BOOST_THROW_EXCEPTION(
JsonRpcException(JsonRpcError::InternalError, "Scheduler not available!"));
}
auto [valid, call] = decodeCallRequest(request[0u]);
auto [valid, call] = decodeCallRequest(request[0U]);
if (!valid)
{
BOOST_THROW_EXCEPTION(JsonRpcException(InvalidParams, "Invalid call request!"));
}
auto const blockTag = toView(request[1u]);
auto const blockTag = toView(request[1U]);
auto [blockNumber, _] = co_await getBlockNumberByTag(blockTag);
if (c_fileLogLevel == TRACE)
{
WEB3_LOG(TRACE) << LOG_DESC("eth_call") << LOG_KV("call", call)
<< LOG_KV("blockTag", blockTag) << LOG_KV("blockNumber", blockNumber);
}
auto&& tx = call.takeToTransaction(m_nodeService->blockFactory()->transactionFactory());
// TODO: ignore params blockNumber here, use it after historical data is available

// MOVE it into a new file
auto tx = call.takeToTransaction(m_nodeService->blockFactory()->transactionFactory());
struct Awaitable
{
bcos::scheduler::SchedulerInterface& m_scheduler;
bcos::protocol::Transaction::Ptr m_tx;
std::variant<Error::Ptr, protocol::TransactionReceipt::Ptr> m_result{};
bcos::protocol::Transaction::Ptr& m_tx;
Error::Ptr m_error;
Json::Value& m_response;

constexpr static bool await_ready() noexcept { return false; }
void await_suspend(std::coroutine_handle<> handle) noexcept
void await_suspend(std::coroutine_handle<> handle)
{
m_scheduler.call(m_tx, [this, handle](Error::Ptr&& error, auto&& result) {
if (error)
{
m_result.emplace<Error::Ptr>(std::move(error));
m_error = std::move(error);
}
else
{
m_result.emplace<protocol::TransactionReceipt::Ptr>(std::move(result));
auto output = toHexStringWithPrefix(result->output());
if (result->status() == static_cast<int32_t>(protocol::TransactionStatus::None))
{
m_response["jsonrpc"] = "2.0";
m_response["result"] = output;
}
else
{
// https://docs.infura.io/api/networks/ethereum/json-rpc-methods/eth_call#returns
Json::Value jsonResult = Json::objectValue;
jsonResult["code"] = result->status();
jsonResult["message"] = result->message();
jsonResult["data"] = output;
m_response["jsonrpc"] = "2.0";
m_response["error"] = std::move(jsonResult);
}
}

handle.resume();
});
}
protocol::TransactionReceipt::Ptr await_resume() noexcept
void await_resume()
{
if (std::holds_alternative<Error::Ptr>(m_result))
if (m_error)
{
BOOST_THROW_EXCEPTION(*std::get<Error::Ptr>(m_result));
BOOST_THROW_EXCEPTION(*m_error);
}
return std::move(std::get<protocol::TransactionReceipt::Ptr>(m_result));
}
};
auto const result = co_await Awaitable{.m_scheduler = *scheduler, .m_tx = std::move(tx)};

auto output = toHexStringWithPrefix(result->output());
if (result->status() == static_cast<int32_t>(protocol::TransactionStatus::None))
{
response["jsonrpc"] = "2.0";
response["result"] = std::move(output);
}
else
{
// https://docs.infura.io/api/networks/ethereum/json-rpc-methods/eth_call#returns
Json::Value jsonResult = Json::objectValue;
jsonResult["code"] = result->status();
jsonResult["message"] = result->message();
jsonResult["data"] = std::move(output);
response["jsonrpc"] = "2.0";
response["error"] = std::move(jsonResult);
}
co_return;
Awaitable awaitable{
.m_scheduler = *scheduler, .m_tx = tx, .m_error = {}, .m_response = response};
co_await awaitable;
}
task::Task<void> EthEndpoint::estimateGas(const Json::Value& request, Json::Value& response)
{
Expand Down
2 changes: 1 addition & 1 deletion bcos-rpc/bcos-rpc/web3jsonrpc/model/BlockResponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace bcos::rpc
result["totalDifficulty"] = "0x0";
result["extraData"] = toHexStringWithPrefix(block->blockHeader()->extraData());
result["size"] = "0xffff";
result["gasLimit"] = toQuantity(3000000000ull);
result["gasLimit"] = toQuantity(30000000ull);
result["gasUsed"] = toQuantity((uint64_t)block->blockHeader()->gasUsed());
result["timestamp"] = toQuantity(block->blockHeader()->timestamp());
if (fullTxs)
Expand Down
26 changes: 10 additions & 16 deletions bcos-security/bcos-security/DataEncryption.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,12 @@ std::shared_ptr<bytes> DataEncryption::decryptContents(const std::shared_ptr<byt
if (m_compatibilityVersion >=
static_cast<uint32_t>(bcos::protocol::BlockVersion::V3_3_VERSION))
{
random_bytes_engine rbe;
std::vector<unsigned char> ivData(16);
std::generate(std::begin(ivData), std::end(ivData), std::ref(rbe));

size_t const offsetIv = encFileBytes.size() - 16;
size_t const cipherDataSize = encFileBytes.size() - 16;
decFileBytesBase64Ptr = m_symmetricEncrypt->symmetricDecrypt(
(const unsigned char*)encFileBytes.data(), encFileBytes.size(),
(const unsigned char*)m_dataKey.data(), m_dataKey.size(), ivData.data(), 16);
decFileBytesBase64Ptr->insert(
decFileBytesBase64Ptr->end(), ivData.begin(), ivData.end());
reinterpret_cast<const unsigned char*>(encFileBytes.data()), cipherDataSize,
reinterpret_cast<const unsigned char*>(m_dataKey.data()), m_dataKey.size(),
reinterpret_cast<const unsigned char*>(encFileBytes.data() + offsetIv), 16);
}
else
{
Expand Down Expand Up @@ -143,15 +140,12 @@ std::shared_ptr<bytes> DataEncryption::decryptFile(const std::string& filename)
if (m_compatibilityVersion >=
static_cast<uint32_t>(bcos::protocol::BlockVersion::V3_3_VERSION))
{
random_bytes_engine rbe;
std::vector<unsigned char> ivData(16);
std::generate(std::begin(ivData), std::end(ivData), std::ref(rbe));

size_t const offsetIv = encFileBytes.size() - 16;
size_t const cipherDataSize = encFileBytes.size() - 16;
decFileBytesBase64Ptr = m_symmetricEncrypt->symmetricDecrypt(
(const unsigned char*)encFileBytes.data(), encFileBytes.size(),
(const unsigned char*)m_dataKey.data(), m_dataKey.size(), ivData.data(), 16);
decFileBytesBase64Ptr->insert(
decFileBytesBase64Ptr->end(), ivData.begin(), ivData.end());
reinterpret_cast<const unsigned char*>(encFileBytes.data()), cipherDataSize,
reinterpret_cast<const unsigned char*>(m_dataKey.data()), m_dataKey.size(),
reinterpret_cast<const unsigned char*>(encFileBytes.data() + offsetIv), 16);
}
else
{
Expand Down
22 changes: 13 additions & 9 deletions bcos-table/src/LegacyStorageWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "bcos-utilities/Error.h"
#include <boost/throw_exception.hpp>
#include <exception>
#include <functional>
#include <iterator>
#include <stdexcept>

Expand All @@ -19,10 +20,10 @@ template <class Storage>
class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface
{
private:
Storage* m_storage;
std::reference_wrapper<Storage> m_storage;

public:
explicit LegacyStorageWrapper(Storage& m_storage) : m_storage(std::addressof(m_storage)) {}
explicit LegacyStorageWrapper(Storage& m_storage) : m_storage(m_storage) {}

void asyncGetPrimaryKeys(std::string_view table,
const std::optional<storage::Condition const>& condition,
Expand All @@ -35,7 +36,7 @@ class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface

size_t index = 0;
auto [start, count] = condition->getLimit();
auto range = co_await storage2::range(*self->m_storage);
auto range = co_await storage2::range(self->m_storage.get());
while (auto keyValue = co_await range.next())
{
auto&& [key, value] = *keyValue;
Expand Down Expand Up @@ -80,7 +81,7 @@ class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface
try
{
auto value = co_await storage2::readOne(
*self->m_storage, transaction_executor::StateKeyView{table, key});
self->m_storage.get(), transaction_executor::StateKeyView{table, key});
callback(nullptr, std::move(value));
}
catch (std::exception& e)
Expand All @@ -105,7 +106,7 @@ class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface
return transaction_executor::StateKeyView{
table, std::forward<decltype(key)>(key)};
}) | RANGES::to<std::vector>();
auto values = co_await storage2::readSome(*self->m_storage, stateKeys);
auto values = co_await storage2::readSome(self->m_storage.get(), stateKeys);

std::vector<std::optional<storage::Entry>> vectorValues(
std::make_move_iterator(values.begin()), std::make_move_iterator(values.end()));
Expand All @@ -128,11 +129,11 @@ class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface
if (entry.status() == storage::Entry::Status::DELETED)
{
co_await storage2::removeOne(
*self->m_storage, transaction_executor::StateKeyView(table, key));
self->m_storage.get(), transaction_executor::StateKeyView(table, key));
}
else
{
co_await storage2::writeOne(*self->m_storage,
co_await storage2::writeOne(self->m_storage,
transaction_executor::StateKey(table, key), std::move(entry));
}
callback(nullptr);
Expand All @@ -157,7 +158,7 @@ class LegacyStorageWrapper : public virtual bcos::storage::StorageInterface
decltype(values)& values) -> task::Task<Error::Ptr> {
try
{
co_await storage2::writeSome(*self->m_storage,
co_await storage2::writeSome(self->m_storage.get(),
keys | RANGES::views::transform([&](std::string_view key) {
return transaction_executor::StateKey{tableName, key};
}),
Expand Down Expand Up @@ -195,7 +196,10 @@ class LegacyStateStorageWrapper : public virtual storage::StateStorageInterface,

void rollback(const storage::Recoder& recoder) override
{
BOOST_THROW_EXCEPTION(std::runtime_error("Unimplemented!"));
// 不要抛出异常,会导致TransactionExecutive::revert()后续的transientStateStorage->rollback无法执行
// Do not throw an exception that will cause Tra::Revert () to follow the Trancintztat
// Stolag-> Rohrbak not to be executed
// BOOST_THROW_EXCEPTION(std::runtime_error("Unimplemented!"));
}

crypto::HashType hash(
Expand Down
Loading

0 comments on commit cb711ed

Please sign in to comment.