mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Extract state printing to a separate class.
This commit is contained in:
parent
24f42c5541
commit
8023fdb537
@ -133,6 +133,10 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
|||||||
// Mainnet according to EIP-155
|
// Mainnet according to EIP-155
|
||||||
tx_context.chain_id = evmc::uint256be{1};
|
tx_context.chain_id = evmc::uint256be{1};
|
||||||
|
|
||||||
|
// Reserve space for recording calls.
|
||||||
|
if (!recorded_calls.capacity())
|
||||||
|
recorded_calls.reserve(max_recorded_calls);
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,9 +178,6 @@ void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _ben
|
|||||||
|
|
||||||
void EVMHost::recordCalls(evmc_message const& _message) noexcept
|
void EVMHost::recordCalls(evmc_message const& _message) noexcept
|
||||||
{
|
{
|
||||||
if (recorded_calls.empty())
|
|
||||||
recorded_calls.reserve(max_recorded_calls);
|
|
||||||
|
|
||||||
if (recorded_calls.size() < max_recorded_calls)
|
if (recorded_calls.size() < max_recorded_calls)
|
||||||
recorded_calls.emplace_back(_message);
|
recorded_calls.emplace_back(_message);
|
||||||
}
|
}
|
||||||
@ -786,7 +787,50 @@ StorageMap const& EVMHost::get_address_storage(evmc::address const& _addr)
|
|||||||
return accounts[_addr].storage;
|
return accounts[_addr].storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EVMHost::printCallRecords(std::ostringstream& _os) const noexcept
|
string EVMHostPrinter::state()
|
||||||
|
{
|
||||||
|
// Print state and execution trace.
|
||||||
|
if (host.account_exists(account))
|
||||||
|
{
|
||||||
|
storage();
|
||||||
|
balance();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
selfdestructRecords();
|
||||||
|
|
||||||
|
callRecords();
|
||||||
|
return stateStream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMHostPrinter::storage()
|
||||||
|
{
|
||||||
|
for (auto const& [slot, value]: host.get_address_storage(account))
|
||||||
|
if (host.get_storage(account, slot))
|
||||||
|
stateStream << host.convertFromEVMC(slot)
|
||||||
|
<< ": "
|
||||||
|
<< host.convertFromEVMC(value.value)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMHostPrinter::balance()
|
||||||
|
{
|
||||||
|
stateStream << "BALANCE "
|
||||||
|
<< host.convertFromEVMC(host.get_balance(account))
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMHostPrinter::selfdestructRecords()
|
||||||
|
{
|
||||||
|
for (auto const& record: host.recorded_selfdestructs)
|
||||||
|
stateStream << "SELFDESTRUCT"
|
||||||
|
<< " BENEFICIARY "
|
||||||
|
<< host.convertFromEVMC(record.beneficiary)
|
||||||
|
<< " BALANCE "
|
||||||
|
<< host.convertFromEVMC(record.balance)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EVMHostPrinter::callRecords()
|
||||||
{
|
{
|
||||||
static const auto callKind = [](evmc_call_kind _kind) -> string
|
static const auto callKind = [](evmc_call_kind _kind) -> string
|
||||||
{
|
{
|
||||||
@ -807,43 +851,9 @@ void EVMHost::printCallRecords(std::ostringstream& _os) const noexcept
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto const& record: recorded_calls)
|
for (auto const& record: host.recorded_calls)
|
||||||
_os << callKind(record.kind)
|
stateStream << callKind(record.kind)
|
||||||
<< " VALUE "
|
<< " VALUE "
|
||||||
<< convertFromEVMC(record.value)
|
<< host.convertFromEVMC(record.value)
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EVMHost::printSelfdestructRecords(ostringstream& _os) const noexcept
|
|
||||||
{
|
|
||||||
for (auto const& record: recorded_selfdestructs)
|
|
||||||
_os << "SELFDESTRUCT"
|
|
||||||
<< " BENEFICIARY "
|
|
||||||
<< convertFromEVMC(record.beneficiary)
|
|
||||||
<< " BALANCE "
|
|
||||||
<< convertFromEVMC(record.balance)
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EVMHost::printBalance(evmc::address const& _addr, ostringstream& _os) const noexcept
|
|
||||||
{
|
|
||||||
_os << "BALANCE " << convertFromEVMC(get_balance(_addr)) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
string EVMHost::dumpState(evmc::address _addr)
|
|
||||||
{
|
|
||||||
ostringstream stateStream;
|
|
||||||
|
|
||||||
// Print state and execution trace.
|
|
||||||
if (account_exists(_addr))
|
|
||||||
{
|
|
||||||
printStorageAt(_addr, stateStream);
|
|
||||||
printBalance(_addr, stateStream);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printSelfdestructRecords(stateStream);
|
|
||||||
|
|
||||||
printCallRecords(stateStream);
|
|
||||||
|
|
||||||
return stateStream.str();
|
|
||||||
}
|
|
||||||
|
@ -87,23 +87,11 @@ public:
|
|||||||
return m_vm.has_capability(capability);
|
return m_vm.has_capability(capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns the state as a string. State includes storage at and balance
|
|
||||||
/// of account at @param _addr and execution trace of the host post reset.
|
|
||||||
std::string dumpState(evmc::address _addr);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
evmc::address m_currentAddress = {};
|
evmc::address m_currentAddress = {};
|
||||||
|
|
||||||
/// Records calls made via @param _message.
|
/// Records calls made via @param _message.
|
||||||
void recordCalls(evmc_message const& _message) noexcept;
|
void recordCalls(evmc_message const& _message) noexcept;
|
||||||
/// Prints contents of storage at @param _addr to @param _os.
|
|
||||||
void printStorageAt(evmc::address const& _addr, std::ostringstream& _os);
|
|
||||||
/// Prints call summary to @param _os.
|
|
||||||
void printCallRecords(std::ostringstream& _os) const noexcept;
|
|
||||||
/// Print self destruct records to @param _os.
|
|
||||||
void printSelfdestructRecords(std::ostringstream& _os) const noexcept;
|
|
||||||
/// Print balance of @param _addr to @param _os.
|
|
||||||
void printBalance(evmc::address const& _addr, std::ostringstream& _os) const noexcept;
|
|
||||||
|
|
||||||
static evmc::result precompileECRecover(evmc_message const& _message) noexcept;
|
static evmc::result precompileECRecover(evmc_message const& _message) noexcept;
|
||||||
static evmc::result precompileSha256(evmc_message const& _message) noexcept;
|
static evmc::result precompileSha256(evmc_message const& _message) noexcept;
|
||||||
@ -125,5 +113,27 @@ private:
|
|||||||
evmc_revision m_evmRevision;
|
evmc_revision m_evmRevision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EVMHostPrinter
|
||||||
|
{
|
||||||
|
/// Constructs a host printer object for state at @param _address.
|
||||||
|
explicit EVMHostPrinter(EVMHost& _host, evmc::address _address):
|
||||||
|
host(_host),
|
||||||
|
account(_address)
|
||||||
|
{}
|
||||||
|
/// @returns state at account maintained by host.
|
||||||
|
std::string state();
|
||||||
|
/// Outputs storage at account to stateStream.
|
||||||
|
void storage();
|
||||||
|
/// Outputs call records for account to stateStream.
|
||||||
|
void callRecords();
|
||||||
|
/// Outputs balance of account to stateStream.
|
||||||
|
void balance();
|
||||||
|
/// Outputs self-destruct record for account to stateStream.
|
||||||
|
void selfdestructRecords();
|
||||||
|
|
||||||
|
std::ostringstream stateStream;
|
||||||
|
EVMHost& host;
|
||||||
|
evmc::address account;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
"Unoptimised call failed."
|
"Unoptimised call failed."
|
||||||
);
|
);
|
||||||
ostringstream unoptimizedState;
|
ostringstream unoptimizedState;
|
||||||
unoptimizedState << hostContext.dumpState(deployResult.create_address);
|
unoptimizedState << EVMHostPrinter{hostContext, deployResult.create_address}.state();
|
||||||
|
|
||||||
settings.runYulOptimiser = true;
|
settings.runYulOptimiser = true;
|
||||||
settings.optimizeStackAllocation = true;
|
settings.optimizeStackAllocation = true;
|
||||||
@ -160,7 +160,7 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
|||||||
"Optimised call failed."
|
"Optimised call failed."
|
||||||
);
|
);
|
||||||
ostringstream optimizedState;
|
ostringstream optimizedState;
|
||||||
optimizedState << hostContext.dumpState(deployResultOpt.create_address);
|
optimizedState << EVMHostPrinter{hostContext, deployResultOpt.create_address}.state();
|
||||||
|
|
||||||
int64_t constexpr tolerance = 1000;
|
int64_t constexpr tolerance = 1000;
|
||||||
if (callResult.gas_left > callResultOpt.gas_left)
|
if (callResult.gas_left > callResultOpt.gas_left)
|
||||||
|
Loading…
Reference in New Issue
Block a user