Skip to content

Commit

Permalink
sync PR FISCO-BCOS#4019
Browse files Browse the repository at this point in the history
  • Loading branch information
JimmyShi22 committed Nov 10, 2023
1 parent 8c3924d commit 2b2910d
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 30 deletions.
7 changes: 4 additions & 3 deletions bcos-crypto/bcos-crypto/ChecksumAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,13 @@ inline std::string newEVMAddress(
inline std::string newEVMAddress(bcos::crypto::Hash::Ptr _hashImpl, const std::string_view& _sender,
bytesConstRef _init, u256 const& _salt)
{
auto hash =
_hashImpl->hash(bytes{0xff} + _sender + toBigEndian(_salt) + _hashImpl->hash(_init));
auto hash = _hashImpl->hash(
bytes{0xff} + (_sender.starts_with("0x") ? fromHexWithPrefix(_sender) : fromHex(_sender)) +
toBigEndian(_salt) + _hashImpl->hash(_init));

std::string hexAddress;
hexAddress.reserve(40);
boost::algorithm::hex(hash.data(), hash.data() + 20, std::back_inserter(hexAddress));
boost::algorithm::hex(hash.data() + 12, hash.data() + 32, std::back_inserter(hexAddress));

toAddress(hexAddress, _hashImpl);

Expand Down
8 changes: 0 additions & 8 deletions bcos-executor/src/executor/TransactionExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -972,14 +972,6 @@ void TransactionExecutor::executeTransactionsInternal(std::string contractAddres
}
});

if (isStaticCall)
{
EXECUTOR_NAME_LOG(FATAL)
<< "executeTransactionsInternal() only handle non static transactions but "
"receive static call";
assert(false);
}

auto prepareT = utcTime() - startT;
startT = utcTime();

Expand Down
11 changes: 11 additions & 0 deletions bcos-executor/src/vm/DelegateHostContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ DelegateHostContext::DelegateHostContext(CallParameters::UniquePtr callParameter
}
setCode(getCallParameters()->delegateCallCode);
m_delegateCallSender = getCallParameters()->delegateCallSender;
m_thisAddress = getCallParameters()->receiveAddress;
}

std::optional<storage::Entry> DelegateHostContext::code()
Expand All @@ -35,6 +36,16 @@ h256 DelegateHostContext::codeHash()
return m_codeHash;
}

std::string_view DelegateHostContext::myAddress() const
{
if (this->features().get(ledger::Features::Flag::bugfix_evm_create2_delegatecall_staticcall_codecopy))
{
return m_thisAddress;
}

return HostContext::myAddress();
}

std::string_view DelegateHostContext::caller() const
{
return m_delegateCallSender;
Expand Down
2 changes: 2 additions & 0 deletions bcos-executor/src/vm/DelegateHostContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ class DelegateHostContext : public HostContext
bool setCode(bytes code) override;
h256 codeHash() override;

std::string_view myAddress() const override;
std::string_view caller() const override;

private:
storage::Entry m_code;
h256 m_codeHash;
std::string m_thisAddress;
std::string m_delegateCallSender;
};

Expand Down
18 changes: 16 additions & 2 deletions bcos-executor/src/vm/EVMHostInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,24 @@ evmc_bytes32 getCodeHash(evmc_host_context* _context, const evmc_address* _addr)
* @param _bufferSize : code size to copy
* @return size_t : return copied code size(in byte)
*/
size_t copyCode(evmc_host_context* _context, const evmc_address*, size_t, uint8_t* _bufferData,
size_t _bufferSize)
size_t copyCode(evmc_host_context* _context, const evmc_address* _addr, size_t _codeOffset,
uint8_t* _bufferData, size_t _bufferSize)
{
auto& hostContext = static_cast<HostContext&>(*_context);
if (hostContext.features().get(ledger::Features::Flag::bugfix_evm_create2_delegatecall_staticcall_codecopy))
{
auto addr = fromEvmC(*_addr);
bytes const& code = hostContext.codeAt(addr);

// Handle "big offset" edge case.
if (_codeOffset >= code.size())
return 0;

size_t maxToCopy = code.size() - _codeOffset;
size_t numToCopy = std::min(maxToCopy, _bufferSize);
std::copy_n(&code[_codeOffset], numToCopy, _bufferData);
return numToCopy;
}

hostContext.setCode(bytes((bcos::byte*)_bufferData, (bcos::byte*)_bufferData + _bufferSize));
return _bufferSize;
Expand Down
14 changes: 14 additions & 0 deletions bcos-executor/src/vm/HostContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ evmc_result HostContext::externalRequest(const evmc_message* _msg)
{
case EVMC_CREATE2:
request->createSalt = fromEvmC(_msg->create2_salt);
if (features().get(ledger::Features::Flag::bugfix_evm_create2_delegatecall_staticcall_codecopy))
{
request->data.assign(_msg->input_data, _msg->input_data + _msg->input_size);
request->create = true;
}
break;
case EVMC_CALL:
if (blockContext.isWasm())
Expand Down Expand Up @@ -209,6 +214,15 @@ evmc_result HostContext::externalRequest(const evmc_message* _msg)

request->staticCall = m_callParameters->staticCall;

if (features().get(ledger::Features::Flag::bugfix_evm_create2_delegatecall_staticcall_codecopy))
{
// EVM STATICCALL opcode support
if (_msg->flags & EVMC_STATIC)
{
request->staticCall = true;
}
}

auto response = m_executive->externalCall(std::move(request));

// Convert CallParameters to evmc_resultx
Expand Down
8 changes: 7 additions & 1 deletion bcos-executor/src/vm/HostContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class HostContext : public evmc_host_context
void log(h256s&& _topics, bytesConstRef _data);

/// ------ get interfaces related to HostContext------
std::string_view myAddress() const;
virtual std::string_view myAddress() const;
virtual std::string_view caller() const { return m_callParameters->senderAddress; }
std::string_view origin() const { return m_callParameters->origin; }
std::string_view codeAddress() const { return m_callParameters->codeAddress; }
Expand Down Expand Up @@ -160,6 +160,12 @@ class HostContext : public evmc_host_context

bool isWasm();

bcos::bytes codeAt(const std::string_view& address) { return externalCodeRequest(address); }
const bcos::ledger::Features& features() const
{
return m_executive->blockContext().lock()->features();
}

protected:
const CallParameters::UniquePtr& getCallParameters() const { return m_callParameters; }
virtual bcos::bytes externalCodeRequest(const std::string_view& address);
Expand Down
2 changes: 2 additions & 0 deletions bcos-framework/bcos-framework/ledger/Features.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Features
{
bugfix_revert, // https://github.com/FISCO-BCOS/FISCO-BCOS/issues/3629
bugfix_statestorage_hash,
bugfix_evm_create2_delegatecall_staticcall_codecopy,
feature_dmc2serial,
feature_sharding,
feature_rpbft,
Expand Down Expand Up @@ -119,6 +120,7 @@ class Features
if (version >= protocol::BlockVersion::V3_2_4_VERSION)
{
set(Flag::bugfix_statestorage_hash);
set(Flag::bugfix_evm_create2_delegatecall_staticcall_codecopy);
}
setToShardingDefault(version);
}
Expand Down
18 changes: 10 additions & 8 deletions bcos-framework/test/unittests/interfaces/FeaturesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,18 @@ BOOST_AUTO_TEST_CASE(feature)
BOOST_CHECK_EQUAL(features7.get("feature_balance_policy1"), true);

auto keys = Features::featureKeys();
BOOST_CHECK_EQUAL(keys.size(), 9);

BOOST_CHECK_EQUAL(keys.size(), 10);
BOOST_CHECK_EQUAL(keys[0], "bugfix_revert");
BOOST_CHECK_EQUAL(keys[1], "bugfix_statestorage_hash");
BOOST_CHECK_EQUAL(keys[2], "feature_dmc2serial");
BOOST_CHECK_EQUAL(keys[3], "feature_sharding");
BOOST_CHECK_EQUAL(keys[4], "feature_rpbft");
BOOST_CHECK_EQUAL(keys[5], "feature_paillier");
BOOST_CHECK_EQUAL(keys[6], "feature_balance");
BOOST_CHECK_EQUAL(keys[7], "feature_balance_precompiled");
BOOST_CHECK_EQUAL(keys[8], "feature_balance_policy1");
BOOST_CHECK_EQUAL(keys[2], "bugfix_evm_create2_delegatecall_staticcall_codecopy");
BOOST_CHECK_EQUAL(keys[3], "feature_dmc2serial");
BOOST_CHECK_EQUAL(keys[4], "feature_sharding");
BOOST_CHECK_EQUAL(keys[5], "feature_rpbft");
BOOST_CHECK_EQUAL(keys[6], "feature_paillier");
BOOST_CHECK_EQUAL(keys[7], "feature_balance");
BOOST_CHECK_EQUAL(keys[8], "feature_balance_precompiled");
BOOST_CHECK_EQUAL(keys[9], "feature_balance_policy1");
}

BOOST_AUTO_TEST_SUITE_END()
2 changes: 1 addition & 1 deletion bcos-scheduler/src/BlockExecutive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1514,7 +1514,7 @@ DmcExecutor::Ptr BlockExecutive::buildDmcExecutor(const std::string& name,
bcos::executor::ParallelTransactionExecutorInterface::Ptr executor)
{
auto dmcExecutor = std::make_shared<DmcExecutor>(name, contractAddress, m_block, executor,
m_keyLocks, m_scheduler->m_hashImpl, m_dmcRecorder);
m_keyLocks, m_scheduler->m_hashImpl, m_dmcRecorder, isCall());
return dmcExecutor;
}

Expand Down
2 changes: 1 addition & 1 deletion bcos-scheduler/src/DmcExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ void DmcExecutor::go(std::function<void(bcos::Error::UniquePtr, Status)> callbac
// record all send message for debug
m_dmcRecorder->recordSends(m_contractAddress, *messages);

if (messages->size() == 1 && (*messages)[0]->staticCall())
if (isCall())
{
DMC_LOG(TRACE) << "send call request, address:" << m_contractAddress
<< LOG_KV("executor", m_name) << LOG_KV("to", (*messages)[0]->to())
Expand Down
8 changes: 6 additions & 2 deletions bcos-scheduler/src/DmcExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@ class DmcExecutor : public std::enable_shared_from_this<DmcExecutor>
DmcExecutor(std::string name, std::string contractAddress, bcos::protocol::Block::Ptr block,
bcos::executor::ParallelTransactionExecutorInterface::Ptr executor,
GraphKeyLocks::Ptr keyLocks, bcos::crypto::Hash::Ptr hashImpl,
DmcStepRecorder::Ptr dmcRecorder)
DmcStepRecorder::Ptr dmcRecorder, bool isCall)
: m_name(name),
m_contractAddress(contractAddress),
m_block(block),
m_executor(executor),
m_keyLocks(keyLocks),
m_hashImpl(hashImpl),
m_dmcRecorder(dmcRecorder)
m_dmcRecorder(dmcRecorder),
m_isCall(isCall)
{}

virtual ~DmcExecutor() = default;
Expand Down Expand Up @@ -142,6 +143,7 @@ class DmcExecutor : public std::enable_shared_from_this<DmcExecutor>
callback);

void handleCreateMessage(protocol::ExecutionMessage::UniquePtr& message, int64_t currentSeq);
void setIsCall(bool isCall) { m_isCall = isCall; }

protected:
MessageHint handleExecutiveMessage(ExecutiveState::Ptr executive);
Expand All @@ -153,6 +155,7 @@ class DmcExecutor : public std::enable_shared_from_this<DmcExecutor>
std::string newEVMAddress(int64_t blockNumber, int64_t contextID, int64_t seq);
std::string newEVMAddress(
const std::string_view& _sender, bytesConstRef _init, u256 const& _salt);
bool isCall() { return m_isCall; }

protected:
std::string m_name;
Expand All @@ -164,6 +167,7 @@ class DmcExecutor : public std::enable_shared_from_this<DmcExecutor>
DmcStepRecorder::Ptr m_dmcRecorder;
ExecutivePool m_executivePool;
bool m_hasContractTableChanged = false;
bool m_isCall;


mutable SharedMutex x_concurrentLock;
Expand Down
9 changes: 5 additions & 4 deletions bcos-scheduler/test/testDmcExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(stateSwitchTest)
block->setBlockHeader(blockHeader);
// block = fakeBlock(cryptoSuite, blockFactory, 1, 1, 1);
auto dmcExecutor = std::make_shared<DmcExecutor>(
"DmcExecutor1", "0xaabbccdd", block, executor1, keyLocks, hashImpl, dmcRecorder);
"DmcExecutor1", "0xaabbccdd", block, executor1, keyLocks, hashImpl, dmcRecorder, false);

dmcExecutor->setSchedulerOutHandler(
[this, &dmcFlagStruct](bcos::scheduler::ExecutiveState::Ptr executiveState) {
Expand All @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(stateSwitchTest)
blockHeader->calculateHash(*hashImpl);
block->setBlockHeader(blockHeader);
auto dmcExecutor2 = std::make_shared<DmcExecutor>(
"DmcExecutor2", to, block, executor1, keyLocks, hashImpl, dmcRecorder);
"DmcExecutor2", to, block, executor1, keyLocks, hashImpl, dmcRecorder, false);
dmcExecutor2->scheduleIn(executiveState);
});

Expand Down Expand Up @@ -226,6 +226,7 @@ BOOST_AUTO_TEST_CASE(stateSwitchTest)


// call
dmcExecutor->setIsCall(true);
auto callMessage = createMessage(4, 0, 1, "0xaabbccdd", true);
dmcExecutor->submit(std::move(callMessage), false);
dmcExecutor->prepare();
Expand Down Expand Up @@ -253,7 +254,7 @@ BOOST_AUTO_TEST_CASE(keyLocksTest)
block->setBlockHeader(blockHeader);
// block = fakeBlock(cryptoSuite, blockFactory, 1, 1, 1);
auto dmcExecutor = std::make_shared<DmcExecutor>(
"DmcExecutor1", "0xaabbccdd", block, executor1, keyLocks, hashImpl, dmcRecorder);
"DmcExecutor1", "0xaabbccdd", block, executor1, keyLocks, hashImpl, dmcRecorder, false);

dmcExecutor->setSchedulerOutHandler(
[this, &dmcFlagStruct](bcos::scheduler::ExecutiveState::Ptr executiveState) {
Expand All @@ -266,7 +267,7 @@ BOOST_AUTO_TEST_CASE(keyLocksTest)
blockHeader->calculateHash(*blockFactory->cryptoSuite()->hashImpl());
block->setBlockHeader(blockHeader);
auto dmcExecutor2 = std::make_shared<DmcExecutor>(
"DmcExecutor2", to, block, executor1, keyLocks, hashImpl, dmcRecorder);
"DmcExecutor2", to, block, executor1, keyLocks, hashImpl, dmcRecorder, false);
dmcExecutor2->scheduleIn(executiveState);
});

Expand Down

0 comments on commit 2b2910d

Please sign in to comment.