From 97d3de6834c753930efe8b04479ac83f40c3a01c Mon Sep 17 00:00:00 2001 From: JimmyShi22 <417711026@qq.com> Date: Thu, 9 May 2024 14:56:27 +0800 Subject: [PATCH] bugfix_staticcall_noaddr_return & bugfix_support_transfer_receive_fallback --- .../src/executive/TransactionExecutive.cpp | 19 +++++++++++++-- .../extension/AccountPrecompiled.cpp | 23 ++++++++++++++++++- .../bcos-framework/ledger/Features.h | 6 ++++- .../unittests/interfaces/FeaturesTest.cpp | 2 ++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/bcos-executor/src/executive/TransactionExecutive.cpp b/bcos-executor/src/executive/TransactionExecutive.cpp index 7ab05dc09e..37436d9680 100644 --- a/bcos-executor/src/executive/TransactionExecutive.cpp +++ b/bcos-executor/src/executive/TransactionExecutive.cpp @@ -239,6 +239,18 @@ CallParameters::UniquePtr TransactionExecutive::execute(CallParameters::UniquePt callParameters->value > 0) { bool onlyTransfer = callParameters->data.empty(); + if (m_blockContext.features().get( + ledger::Features::Flag::bugfix_support_transfer_receive_fallback)) + { + // Note: To support receive fallback. + // Transfer from EOA or contract tx's data is empty. But we still need to executive as + // an normal transaction. + // If "to" is contract, go to contract's receive() fallback. + // If "to" is EOA, go to AccountPrecompiled receive() logic. + onlyTransfer = false; + } + + bool transferFromEVM = callParameters->seq != 0; int64_t requiredGas = transferFromEVM ? 0 : BALANCE_TRANSFER_GAS; auto currentContextAddress = callParameters->receiveAddress; @@ -1142,11 +1154,14 @@ CallParameters::UniquePtr TransactionExecutive::go( ) { // Note: to be the same as eth - // Just fix DMC: // if bugfix_call_noaddr_return is not set, callResult->evmStatus is still // default to EVMC_SUCCESS and serial mode is execute same as eth, but DMC is // using callResult->status, so we need to compat with DMC here - + if (m_blockContext.features().get( + ledger::Features::Flag::bugfix_staticcall_noaddr_return)) + { + callResult->data = bytes(); + } callResult->type = CallParameters::FINISHED; callResult->evmStatus = EVMC_SUCCESS; callResult->status = (int32_t)TransactionStatus::None; diff --git a/bcos-executor/src/precompiled/extension/AccountPrecompiled.cpp b/bcos-executor/src/precompiled/extension/AccountPrecompiled.cpp index e9bbb1e2e2..f1d1e48c00 100644 --- a/bcos-executor/src/precompiled/extension/AccountPrecompiled.cpp +++ b/bcos-executor/src/precompiled/extension/AccountPrecompiled.cpp @@ -33,6 +33,7 @@ const char* const AM_METHOD_GET_ACCOUNT_STATUS = "getAccountStatus()"; const char* const AM_METHOD_GET_ACCOUNT_BALANCE = "getAccountBalance()"; const char* const AM_METHOD_ADD_ACCOUNT_BALANCE = "addAccountBalance(uint256)"; const char* const AM_METHOD_SUB_ACCOUNT_BALANCE = "subAccountBalance(uint256)"; +const uint32_t AM_METHOD_RECEIVE_FALLBACK_SELECTOR = 1; AccountPrecompiled::AccountPrecompiled(crypto::Hash::Ptr hashImpl) : Precompiled(hashImpl) @@ -62,7 +63,18 @@ std::shared_ptr AccountPrecompiled::call( auto accountTableName = dynamicParams.at(0); // get user call actual params auto originParam = ref(param); - uint32_t func = getParamFunc(originParam); + uint32_t func; + if (originParam.size() == 0 && + blockContext.features().get( + ledger::Features::Flag::bugfix_support_transfer_receive_fallback)) + { + // Transfer to EOA operation, call receive() function + func = AM_METHOD_RECEIVE_FALLBACK_SELECTOR; + } + else + { + func = getParamFunc(originParam); + } bytesConstRef data = getParamData(originParam); auto table = _executive->storage().openTable(accountTableName); @@ -86,6 +98,15 @@ std::shared_ptr AccountPrecompiled::call( { subAccountBalance(accountTableName, _executive, data, _callParameters); } + else if (func == AM_METHOD_RECEIVE_FALLBACK_SELECTOR) + { + // Transfer to EOA operation + // receive() fallback logic + // Just return _callParameters, do noting + PRECOMPILED_LOG(TRACE) << LOG_BADGE("AccountPrecompiled") + << LOG_DESC("call receive() function. do nothing") + << LOG_KV("func", func); + } else { PRECOMPILED_LOG(INFO) << LOG_BADGE("AccountPrecompiled") diff --git a/bcos-framework/bcos-framework/ledger/Features.h b/bcos-framework/bcos-framework/ledger/Features.h index 11ff976a01..ac9347dfea 100644 --- a/bcos-framework/bcos-framework/ledger/Features.h +++ b/bcos-framework/bcos-framework/ledger/Features.h @@ -43,6 +43,8 @@ class Features bugfix_eip55_addr, bugfix_eoa_as_contract, bugfix_dmc_deploy_gas_used, + bugfix_staticcall_noaddr_return, + bugfix_support_transfer_receive_fallback, feature_dmc2serial, feature_sharding, feature_rpbft, @@ -156,7 +158,9 @@ class Features Flag::bugfix_sharding_call_in_child_executive, Flag::bugfix_internal_create_permission_denied}}, {protocol::BlockVersion::V3_7_3_VERSION, - {Flag::bugfix_eoa_as_contract, Flag::bugfix_dmc_deploy_gas_used}}}); + {Flag::bugfix_eoa_as_contract, Flag::bugfix_dmc_deploy_gas_used, + Flag::bugfix_staticcall_noaddr_return, + Flag::bugfix_support_transfer_receive_fallback}}}); for (const auto& upgradeFeatures : upgradeRoadmap) { if (((to < protocol::BlockVersion::V3_2_7_VERSION) && (to >= upgradeFeatures.to)) || diff --git a/bcos-framework/test/unittests/interfaces/FeaturesTest.cpp b/bcos-framework/test/unittests/interfaces/FeaturesTest.cpp index e6c9804209..781ac95e3e 100644 --- a/bcos-framework/test/unittests/interfaces/FeaturesTest.cpp +++ b/bcos-framework/test/unittests/interfaces/FeaturesTest.cpp @@ -143,6 +143,8 @@ BOOST_AUTO_TEST_CASE(feature) "bugfix_eip55_addr", "bugfix_eoa_as_contract", "bugfix_dmc_deploy_gas_used", + "bugfix_staticcall_noaddr_return", + "bugfix_support_transfer_receive_fallback", "feature_dmc2serial", "feature_sharding", "feature_rpbft",