Skip to content

Commit

Permalink
Add bugfix_policy1_emptyto and recover java_sdk_demo ci test (#4785)
Browse files Browse the repository at this point in the history
  • Loading branch information
morebtcg authored Jan 6, 2025
1 parent 4ba2683 commit 00e41d3
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 174 deletions.
1 change: 1 addition & 0 deletions bcos-framework/bcos-framework/ledger/Features.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Features
bugfix_set_row_with_dirty_flag,
bugfix_rpbft_vrf_blocknumber_input,
bugfix_delete_account_code,
bugfix_policy1_emptyto,
feature_dmc2serial,
feature_sharding,
feature_rpbft,
Expand Down
1 change: 1 addition & 0 deletions bcos-framework/test/unittests/interfaces/FeaturesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ BOOST_AUTO_TEST_CASE(feature)
"bugfix_set_row_with_dirty_flag",
"bugfix_rpbft_vrf_blocknumber_input",
"bugfix_delete_account_code",
"bugfix_policy1_emptyto",
"feature_dmc2serial",
"feature_sharding",
"feature_rpbft",
Expand Down
8 changes: 8 additions & 0 deletions bcos-scheduler/src/BlockExecutive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,10 @@ void BlockExecutive::onTxFinish(bcos::protocol::ExecutionMessage::UniquePtr outp
<< ", gasUsed: " << receipt->gasUsed()
<< ", version: " << receipt->version()
<< ", status: " << receipt->status();
if (c_fileLogLevel == LogLevel::TRACE)
{
SCHEDULER_LOG(TRACE) << receipt->toString();
}
m_executiveResults[output->contextID() - m_startContextID].receipt = std::move(receipt);
break;
}
Expand All @@ -1634,6 +1638,10 @@ void BlockExecutive::onTxFinish(bcos::protocol::ExecutionMessage::UniquePtr outp
<< ", version: " << receipt->version()
<< ", status: " << receipt->status()
<< ", effectiveGasPrice: " << receipt->effectiveGasPrice();
if (c_fileLogLevel == LogLevel::TRACE)
{
SCHEDULER_LOG(TRACE) << receipt->toString();
}
m_executiveResults[output->contextID() - m_startContextID].receipt = std::move(receipt);
break;
}
Expand Down
45 changes: 26 additions & 19 deletions tools/.ci/ci_check_air.sh
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ if [[ -n "${1}" ]]; then
console_branch=${1}
fi

# non-sm test
non-sm test
LOG_INFO "======== check non-sm case ========"
init ""
expand_node ""
Expand All @@ -186,13 +186,13 @@ if [[ ${?} == "0" ]]; then
echo "java_sdk_integrationTest error"
exit 1
fi
#bash ${current_path}/.ci/java_sdk_demo_ci_test.sh ${console_branch} "false" "${current_path}/nodes/127.0.0.1"
#if [[ ${?} == "0" ]]; then
# LOG_INFO "java_sdk_demo_ci_test success"
# else
# echo "java_sdk_demo_ci_test error"
# exit 1
#fi
bash ${current_path}/.ci/java_sdk_demo_ci_test.sh ${console_branch} "false" "${current_path}/nodes/127.0.0.1"
if [[ ${?} == "0" ]]; then
LOG_INFO "java_sdk_demo_ci_test success"
else
echo "java_sdk_demo_ci_test error"
exit 1
fi
LOG_INFO "======== check non-sm success ========"

LOG_INFO "======== clear node after non-sm test ========"
Expand All @@ -217,13 +217,13 @@ if [[ ${?} == "0" ]]; then
echo "java_sdk_integrationTest error"
exit 1
fi
#bash ${current_path}/.ci/java_sdk_demo_ci_test.sh ${console_branch} "true" "${current_path}/nodes/127.0.0.1"
#if [[ ${?} == "0" ]]; then
# LOG_INFO "java_sdk_demo_ci_test success"
# else
# echo "java_sdk_demo_ci_test error"
# exit 1
#fi
bash ${current_path}/.ci/java_sdk_demo_ci_test.sh ${console_branch} "true" "${current_path}/nodes/127.0.0.1"
if [[ ${?} == "0" ]]; then
LOG_INFO "java_sdk_demo_ci_test success"
else
echo "java_sdk_demo_ci_test error"
exit 1
fi

LOG_INFO "======== check sm case success ========"
clear_node
Expand All @@ -232,22 +232,29 @@ LOG_INFO "======== clear node after sm test success ========"
# baseline暂时不支持balance precompiled,故不测试java_sdk_demo_ci_test
# baseline does not support balance precompiled temporarily, so java_sdk_demo_ci_test is not tested
LOG_INFO "======== check baseline cases ========"
init_baseline "-s"
expand_node "-s"
bash ${current_path}/.ci/console_ci_test.sh ${console_branch} "true" "${current_path}/nodes/127.0.0.1"
init_baseline ""
expand_node ""
bash ${current_path}/.ci/console_ci_test.sh ${console_branch} "false" "${current_path}/nodes/127.0.0.1"
if [[ ${?} == "0" ]]; then
LOG_INFO "console_integrationTest success"
else
echo "console_integrationTest error"
exit 1
fi
bash ${current_path}/.ci/java_sdk_ci_test.sh ${console_branch} "true" "${current_path}/nodes/127.0.0.1"
bash ${current_path}/.ci/java_sdk_ci_test.sh ${console_branch} "false" "${current_path}/nodes/127.0.0.1"
if [[ ${?} == "0" ]]; then
LOG_INFO "java_sdk_integrationTest success"
else
echo "java_sdk_integrationTest error"
exit 1
fi
# bash ${current_path}/.ci/java_sdk_demo_ci_test.sh ${console_branch} "false" "${current_path}/nodes/127.0.0.1"
# if [[ ${?} == "0" ]]; then
# LOG_INFO "java_sdk_demo_ci_test success"
# else
# echo "java_sdk_demo_ci_test error"
# exit 1
# fi
stop_node
LOG_INFO "======== check baseline cases success ========"
clear_node
Expand Down
1 change: 0 additions & 1 deletion transaction-executor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ add_library(transaction-executor
bcos-transaction-executor/EVMCResult.cpp
bcos-transaction-executor/vm/VMInstance.cpp
bcos-transaction-executor/precompiled/PrecompiledManager.cpp
bcos-transaction-executor/precompiled/PrecompiledImpl.cpp
bcos-transaction-executor/vm/HostContext.cpp
bcos-transaction-executor/TransactionExecutorImpl.cpp
)
Expand Down
112 changes: 109 additions & 3 deletions transaction-executor/bcos-transaction-executor/EVMCResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

#include "EVMCResult.h"
#include "bcos-codec/abi/ContractABICodec.h"
#include "bcos-protocol/TransactionStatus.h"
#include "bcos-utilities/Exceptions.h"
#include <evmc/evmc.h>
#include <boost/throw_exception.hpp>
#include <cstdint>
#include <memory>

struct UnknownEVMCStatus : public bcos::Exception
{
};

static void cleanEVMCResult(evmc_result& from)
{
Expand All @@ -11,12 +20,21 @@ static void cleanEVMCResult(evmc_result& from)
from.output_size = 0;
}

bcos::transaction_executor::EVMCResult::EVMCResult(evmc_result&& from) : evmc_result(from)
bcos::transaction_executor::EVMCResult::EVMCResult(evmc_result&& from)
: evmc_result(from), status{evmcStatusToTransactionStatus(from.status_code)}
{
cleanEVMCResult(from);
}

bcos::transaction_executor::EVMCResult::EVMCResult(
evmc_result&& from, protocol::TransactionStatus _status)
: evmc_result(from), status(_status)
{
cleanEVMCResult(from);
}

bcos::transaction_executor::EVMCResult::EVMCResult(EVMCResult&& from) noexcept : evmc_result(from)
bcos::transaction_executor::EVMCResult::EVMCResult(EVMCResult&& from) noexcept
: evmc_result(from), status{from.status}
{
cleanEVMCResult(from);
}
Expand Down Expand Up @@ -64,7 +82,95 @@ bcos::protocol::TransactionStatus bcos::transaction_executor::evmcStatusToTransa
return protocol::TransactionStatus::OutOfStack;
case EVMC_STACK_UNDERFLOW:
return protocol::TransactionStatus::StackUnderflow;
case EVMC_INVALID_INSTRUCTION:
case EVMC_UNDEFINED_INSTRUCTION:
return protocol::TransactionStatus::BadInstruction;
default:
return protocol::TransactionStatus::RevertInstruction;
BOOST_THROW_EXCEPTION(UnknownEVMCStatus{});
}
}

std::tuple<bcos::protocol::TransactionStatus, bcos::bytes>
bcos::transaction_executor::evmcStatusToErrorMessage(
const bcos::crypto::Hash& hashImpl, evmc_status_code status)
{
using namespace std::string_literals;
bcos::bytes output;

switch (status)
{
case EVMC_SUCCESS:
return {bcos::protocol::TransactionStatus::None, {}};
case EVMC_REVERT:
return {bcos::protocol::TransactionStatus::RevertInstruction, {}};
case EVMC_OUT_OF_GAS:
return {bcos::protocol::TransactionStatus::OutOfGas,
bcos::transaction_executor::writeErrInfoToOutput(hashImpl, "Execution out of gas."s)};
case EVMC_INSUFFICIENT_BALANCE:
return {bcos::protocol::TransactionStatus::NotEnoughCash, {}};
case EVMC_STACK_OVERFLOW:
return {bcos::protocol::TransactionStatus::OutOfStack,
bcos::transaction_executor::writeErrInfoToOutput(
hashImpl, "Execution stack overflow."s)};
case EVMC_STACK_UNDERFLOW:
return {bcos::protocol::TransactionStatus::StackUnderflow,
bcos::transaction_executor::writeErrInfoToOutput(
hashImpl, "Execution needs more items on EVM stack."s)};
case EVMC_INVALID_INSTRUCTION:
case EVMC_UNDEFINED_INSTRUCTION:
return {bcos::protocol::TransactionStatus::BadInstruction,
bcos::transaction_executor::writeErrInfoToOutput(
hashImpl, "Execution invalid/undefined opcode."s)};
case EVMC_BAD_JUMP_DESTINATION:
return {bcos::protocol::TransactionStatus::BadJumpDestination,
bcos::transaction_executor::writeErrInfoToOutput(
hashImpl, "Execution has violated the jump destination restrictions."s)};
case EVMC_INVALID_MEMORY_ACCESS:
return {bcos::protocol::TransactionStatus::StackUnderflow,
bcos::transaction_executor::writeErrInfoToOutput(
hashImpl, "Execution tried to read outside memory bounds."s)};
case EVMC_STATIC_MODE_VIOLATION:
return {bcos::protocol::TransactionStatus::Unknown,
bcos::transaction_executor::writeErrInfoToOutput(hashImpl,
"Execution tried to execute an operation which is restricted in static mode."s)};
case EVMC_INTERNAL_ERROR:
default:
return {bcos::protocol::TransactionStatus::Unknown, {}};
};
}

bcos::transaction_executor::EVMCResult bcos::transaction_executor::makeErrorEVMCResult(
crypto::Hash const& hashImpl, protocol::TransactionStatus status, evmc_status_code evmStatus,
int64_t gas, const std::string& errorInfo)
{
bytes errorBytes;
if (!errorInfo.empty())
{
errorBytes = writeErrInfoToOutput(hashImpl, errorInfo);
}
else
{
auto [_, errorMessage] = evmcStatusToErrorMessage(hashImpl, evmStatus);
errorBytes.swap(errorMessage);
}

std::unique_ptr<uint8_t[]> output;
size_t outputSize = 0;
if (!errorBytes.empty())
{
output = std::make_unique_for_overwrite<uint8_t[]>(errorBytes.size());
outputSize = errorBytes.size();
std::uninitialized_copy(errorBytes.begin(), errorBytes.end(), output.get());
}

return EVMCResult{
evmc_result{.status_code = evmStatus,
.gas_left = gas,
.gas_refund = 0,
.output_data = output.release(),
.output_size = outputSize,
.release = +[](const struct evmc_result* result) { delete[] result->output_data; },
.create_address = {},
.padding = {}},
status};
}
14 changes: 12 additions & 2 deletions transaction-executor/bcos-transaction-executor/EVMCResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,26 @@

namespace bcos::transaction_executor
{
bytes writeErrInfoToOutput(const crypto::Hash& hashImpl, std::string const& errInfo);
protocol::TransactionStatus evmcStatusToTransactionStatus(evmc_status_code status);
class EVMCResult : public evmc_result
{
public:
explicit EVMCResult(evmc_result&& from);
EVMCResult(evmc_result&& from, protocol::TransactionStatus _status);
EVMCResult(const EVMCResult&) = delete;
EVMCResult(EVMCResult&& from) noexcept;
EVMCResult& operator=(const EVMCResult&) = delete;
EVMCResult& operator=(EVMCResult&& from) noexcept;
~EVMCResult() noexcept;

protocol::TransactionStatus status;
};

bytes writeErrInfoToOutput(const crypto::Hash& hashImpl, std::string const& errInfo);

protocol::TransactionStatus evmcStatusToTransactionStatus(evmc_status_code status);
std::tuple<bcos::protocol::TransactionStatus, bcos::bytes> evmcStatusToErrorMessage(
const bcos::crypto::Hash& hashImpl, evmc_status_code status);

EVMCResult makeErrorEVMCResult(crypto::Hash const& hashImpl, protocol::TransactionStatus status,
evmc_status_code evmStatus, int64_t gas, const std::string& errorInfo);
} // namespace bcos::transaction_executor
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#include "bcos-framework/protocol/TransactionReceiptFactory.h"
#include "bcos-framework/transaction-executor/TransactionExecutor.h"
#include "bcos-task/Wait.h"
#include "bcos-utilities/DataConvertUtility.h"
#include "precompiled/PrecompiledManager.h"
#include "vm/HostContext.h"
#include <evmc/evmc.h>
Expand Down Expand Up @@ -128,11 +127,22 @@ class TransactionExecutorImpl
evmcResult.create_address.bytes + sizeof(evmcResult.create_address.bytes),
std::back_inserter(newContractAddress));
}
bcos::bytesConstRef output{evmcResult.output_data, evmcResult.output_size};

if (evmcResult.status_code != 0)
{
TRANSACTION_EXECUTOR_LOG(DEBUG) << "Transaction revert: " << evmcResult.status_code;

auto [_, errorMessage] = evmcStatusToErrorMessage(
*executeContext.m_executor.get().m_hashImpl, evmcResult.status_code);
if (!errorMessage.empty())
{
auto output = std::make_unique<uint8_t[]>(errorMessage.size());
std::uninitialized_copy(errorMessage.begin(), errorMessage.end(), output.get());
evmcResult.output_data = output.release();
evmcResult.output_size = errorMessage.size();
evmcResult.release =
+[](const struct evmc_result* result) { delete[] result->output_data; };
}
}

auto gasUsed = executeContext.m_gasLimit - evmcResult.gas_left;
Expand All @@ -149,6 +159,7 @@ class TransactionExecutorImpl
TRANSACTION_EXECUTOR_LOG(ERROR) << "Insufficient balance: " << senderBalance
<< ", balanceUsed: " << balanceUsed;
evmcResult.status_code = EVMC_INSUFFICIENT_BALANCE;
evmcResult.status = protocol::TransactionStatus::NotEnoughCash;
co_await rollback(
executeContext.m_rollbackableStorage, executeContext.m_startSavepoint);
}
Expand All @@ -158,23 +169,23 @@ class TransactionExecutorImpl
}
}

auto receiptStatus =
static_cast<int32_t>(evmcStatusToTransactionStatus(evmcResult.status_code));
auto receiptStatus = static_cast<int32_t>(evmcResult.status);
auto const& logEntries = executeContext.m_hostContext.logs();
auto transactionVersion = static_cast<bcos::protocol::TransactionVersion>(
executeContext.m_transaction.get().version());
protocol::TransactionReceipt::Ptr receipt;
switch (transactionVersion)
switch (auto transactionVersion = static_cast<bcos::protocol::TransactionVersion>(
executeContext.m_transaction.get().version()))
{
case bcos::protocol::TransactionVersion::V0_VERSION:
receipt = executeContext.m_executor.get().m_receiptFactory.get().createReceipt(gasUsed,
std::move(newContractAddress), logEntries, receiptStatus, output,
std::move(newContractAddress), logEntries, receiptStatus,
{evmcResult.output_data, evmcResult.output_size},
executeContext.m_blockHeader.get().number());
break;
case bcos::protocol::TransactionVersion::V1_VERSION:
case bcos::protocol::TransactionVersion::V2_VERSION:
receipt = executeContext.m_executor.get().m_receiptFactory.get().createReceipt2(gasUsed,
std::move(newContractAddress), logEntries, receiptStatus, output,
std::move(newContractAddress), logEntries, receiptStatus,
{evmcResult.output_data, evmcResult.output_size},
executeContext.m_blockHeader.get().number(), "", transactionVersion);
break;
default:
Expand All @@ -186,12 +197,7 @@ class TransactionExecutorImpl
if (c_fileLogLevel <= LogLevel::TRACE)
{
TRANSACTION_EXECUTOR_LOG(TRACE)
<< "Execte transaction finished" << ", gasUsed: " << receipt->gasUsed()
<< ", newContractAddress: " << receipt->contractAddress()
<< ", logEntries: " << receipt->logEntries().size()
<< ", status: " << receipt->status() << ", output: " << toHex(receipt->output())
<< ", blockNumber: " << receipt->blockNumber() << ", receipt: " << receipt->hash()
<< ", version: " << receipt->version();
<< "Execte transaction finished: " << receipt->toString();
}

co_return receipt; // 完成第三步 Complete the third step
Expand Down
Loading

0 comments on commit 00e41d3

Please sign in to comment.