diff --git a/bcos-executor/src/executive/CoroutineTransactionExecutive.cpp b/bcos-executor/src/executive/CoroutineTransactionExecutive.cpp index c38b31bf2c..9031f9ced0 100644 --- a/bcos-executor/src/executive/CoroutineTransactionExecutive.cpp +++ b/bcos-executor/src/executive/CoroutineTransactionExecutive.cpp @@ -32,7 +32,7 @@ CallParameters::UniquePtr CoroutineTransactionExecutive::start(CallParameters::U m_exchangeMessage = execute(std::move(callParameters)); - if (m_blockContext.features().get(ledger::Features::Flag::bugfix_dmc_revert)) + if (m_blockContext.lock()->features().get(ledger::Features::Flag::bugfix_dmc_revert)) { m_exchangeMessage = waitingFinish(std::move(m_exchangeMessage)); } @@ -92,27 +92,37 @@ CallParameters::UniquePtr CoroutineTransactionExecutive::externalCall( // When resume, exchangeMessage set to output auto output = std::move(m_exchangeMessage); - if (output->delegateCall && output->type != CallParameters::FINISHED) + if (m_blockContext.lock()->features().get(ledger::Features::Flag::bugfix_call_noaddr_return)) { - output->data = bytes(); - if (m_blockContext.lock()->features().get( - ledger::Features::Flag::bugfix_call_noaddr_return)) + if (output->delegateCall && + output->status == (int32_t)bcos::protocol::TransactionStatus::CallAddressError) { // This is eth's bug, but we still need to compat with it :) // https://docs.soliditylang.org/en/v0.8.17/control-structures.html#error-handling-assert-require-revert-and-exceptions + output->data = bytes(); output->type = CallParameters::FINISHED; output->status = (int32_t)bcos::protocol::TransactionStatus::None; output->evmStatus = EVMC_SUCCESS; + + EXECUTIVE_LOG(DEBUG) << "Could not getCode during DMC externalCall, but return success" + << LOG_KV("codeAddress", output->codeAddress) + << LOG_KV("status", output->status) + << LOG_KV("evmStatus", output->evmStatus); } - else + } + else + { + if (output->delegateCall && output->type != CallParameters::FINISHED) { + output->data = bytes(); output->status = (int32_t)bcos::protocol::TransactionStatus::RevertInstruction; output->evmStatus = EVMC_REVERT; + + EXECUTIVE_LOG(DEBUG) << "Could not getCode during DMC externalCall" + << LOG_KV("codeAddress", output->codeAddress) + << LOG_KV("status", output->status) + << LOG_KV("evmStatus", output->evmStatus); } - EXECUTIVE_LOG(DEBUG) << "Could not getCode during DMC externalCall" - << LOG_KV("codeAddress", output->codeAddress) - << LOG_KV("status", output->status) - << LOG_KV("evmStatus", output->evmStatus); } // After coroutine switch, set the recoder diff --git a/bcos-scheduler/src/DmcExecutor.cpp b/bcos-scheduler/src/DmcExecutor.cpp index 1412c310b3..05d47f46e6 100644 --- a/bcos-scheduler/src/DmcExecutor.cpp +++ b/bcos-scheduler/src/DmcExecutor.cpp @@ -1,6 +1,7 @@ #include "DmcExecutor.h" #include "bcos-crypto/bcos-crypto/ChecksumAddress.h" #include "bcos-framework/executor/ExecuteError.h" +#include #include @@ -384,6 +385,7 @@ DmcExecutor::MessageHint DmcExecutor::handleExecutiveMessage(ExecutiveState::Ptr << "Could not getCode() from correspond executor during delegateCall: " << message->toString(); message->setType(protocol::ExecutionMessage::REVERT); + message->setStatus((int32_t)protocol::TransactionStatus::CallAddressError); message->setCreate(false); message->setKeyLocks({}); return MessageHint::NEED_PREPARE; @@ -455,10 +457,6 @@ DmcExecutor::MessageHint DmcExecutor::handleExecutiveMessageV2(ExecutiveState::P { if (executiveState->message->data().toBytes() == bcos::protocol::GET_CODE_INPUT_BYTES) { - auto newSeq = executiveState->currentSeq++; - executiveState->callStack.push(newSeq); - executiveState->message->setSeq(newSeq); - // getCode DMC_LOG(DEBUG) << "Get external code in scheduler" << LOG_KV("codeAddress", executiveState->message->delegateCallAddress()); @@ -468,6 +466,9 @@ DmcExecutor::MessageHint DmcExecutor::handleExecutiveMessageV2(ExecutiveState::P << LOG_KV("codeSize", code.size()); executiveState->message->setData(code); executiveState->message->setType(protocol::ExecutionMessage::PRE_FINISH); + + executiveState->isRevertStackMessage = true; + return MessageHint::NEED_PREPARE; } @@ -494,6 +495,7 @@ DmcExecutor::MessageHint DmcExecutor::handleExecutiveMessageV2(ExecutiveState::P << "Could not getCode() from correspond executor during delegateCall: " << message->toString(); message->setType(protocol::ExecutionMessage::REVERT); + message->setStatus((int32_t)protocol::TransactionStatus::CallAddressError); message->setCreate(false); message->setKeyLocks({}); @@ -510,6 +512,13 @@ DmcExecutor::MessageHint DmcExecutor::handleExecutiveMessageV2(ExecutiveState::P // Return type, pop stack case protocol::ExecutionMessage::PRE_FINISH: { + if (executiveState->isRevertStackMessage) + { + // handle schedule in message + executiveState->isRevertStackMessage = false; + return MessageHint::NEED_SEND; + } + // update my key locks in m_keyLocks m_keyLocks->batchAcquireKeyLock( message->from(), message->keyLocks(), message->contextID(), message->seq());