mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #7886 from ethereum/develop
Merge develop into develop_060
This commit is contained in:
commit
f2790cc5e0
@ -9,7 +9,7 @@ version: 2.1
|
||||
parameters:
|
||||
docker-image-rev:
|
||||
type: string
|
||||
default: "2"
|
||||
default: "3"
|
||||
|
||||
defaults:
|
||||
|
||||
|
@ -62,7 +62,7 @@ RUN git clone --recursive -b boost-1.69.0 https://github.com/boostorg/boost.git
|
||||
rm -rf /usr/src/boost
|
||||
|
||||
# Z3
|
||||
RUN git clone --depth 1 -b z3-4.8.6 https://github.com/Z3Prover/z3.git \
|
||||
RUN git clone --depth 1 -b z3-4.8.7 https://github.com/Z3Prover/z3.git \
|
||||
/usr/src/z3; \
|
||||
cd /usr/src/z3; \
|
||||
python scripts/mk_make.py --prefix=/usr ; \
|
||||
|
@ -43,13 +43,13 @@ then
|
||||
./scripts/install_obsolete_jsoncpp_1_7_4.sh
|
||||
|
||||
# z3
|
||||
wget https://github.com/Z3Prover/z3/releases/download/z3-4.8.6/z3-4.8.6-x64-osx-10.14.6.zip
|
||||
unzip z3-4.8.6-x64-osx-10.14.6.zip
|
||||
rm -f z3-4.8.6-x64-osx-10.14.6.zip
|
||||
cp z3-4.8.6-x64-osx-10.14.6/bin/libz3.a /usr/local/lib
|
||||
cp z3-4.8.6-x64-osx-10.14.6/bin/z3 /usr/local/bin
|
||||
cp z3-4.8.6-x64-osx-10.14.6/include/* /usr/local/include
|
||||
rm -rf z3-4.8.6-x64-osx-10.14.6
|
||||
wget https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-osx-10.14.6.zip
|
||||
unzip z3-4.8.7-x64-osx-10.14.6.zip
|
||||
rm -f z3-4.8.7-x64-osx-10.14.6.zip
|
||||
cp z3-4.8.7-x64-osx-10.14.6/bin/libz3.a /usr/local/lib
|
||||
cp z3-4.8.7-x64-osx-10.14.6/bin/z3 /usr/local/bin
|
||||
cp z3-4.8.7-x64-osx-10.14.6/include/* /usr/local/include
|
||||
rm -rf z3-4.8.7-x64-osx-10.14.6
|
||||
|
||||
# evmone
|
||||
wget https://github.com/ethereum/evmone/releases/download/v0.3.0/evmone-0.3.0-darwin-x86_64.tar.gz
|
||||
|
@ -98,33 +98,25 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
evmc::address address{};
|
||||
address.bytes[19] = precompiledAddress;
|
||||
// 1wei
|
||||
m_state.accounts[address].balance.bytes[31] = 1;
|
||||
accounts[address].balance.bytes[31] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
evmc_storage_status EVMHost::set_storage(const evmc::address& _addr, const evmc::bytes32& _key, const evmc::bytes32& _value) noexcept
|
||||
{
|
||||
evmc::bytes32 previousValue = m_state.accounts[_addr].storage[_key];
|
||||
m_state.accounts[_addr].storage[_key] = _value;
|
||||
|
||||
// TODO EVMC_STORAGE_MODIFIED_AGAIN should be also used
|
||||
if (previousValue == _value)
|
||||
return EVMC_STORAGE_UNCHANGED;
|
||||
else if (previousValue == evmc::bytes32{})
|
||||
return EVMC_STORAGE_ADDED;
|
||||
else if (_value == evmc::bytes32{})
|
||||
return EVMC_STORAGE_DELETED;
|
||||
else
|
||||
return EVMC_STORAGE_MODIFIED;
|
||||
|
||||
// TODO: support short literals in EVMC and use them here
|
||||
tx_context.block_difficulty = convertToEVMC(u256("200000000"));
|
||||
tx_context.block_gas_limit = 20000000;
|
||||
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
|
||||
tx_context.tx_gas_price = convertToEVMC(u256("3000000000"));
|
||||
tx_context.tx_origin = 0x9292929292929292929292929292929292929292_address;
|
||||
// Mainnet according to EIP-155
|
||||
tx_context.chain_id = convertToEVMC(u256(1));
|
||||
}
|
||||
|
||||
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
||||
{
|
||||
// TODO actual selfdestruct is even more complicated.
|
||||
evmc::uint256be balance = m_state.accounts[_addr].balance;
|
||||
m_state.accounts.erase(_addr);
|
||||
m_state.accounts[_beneficiary].balance = balance;
|
||||
evmc::uint256be balance = accounts[_addr].balance;
|
||||
accounts.erase(_addr);
|
||||
accounts[_beneficiary].balance = balance;
|
||||
}
|
||||
|
||||
evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
@ -146,12 +138,12 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
return precompileALTBN128PairingProduct(_message);
|
||||
|
||||
State stateBackup = m_state;
|
||||
auto const stateBackup = accounts;
|
||||
|
||||
u256 value{convertFromEVMC(_message.value)};
|
||||
Account& sender = m_state.accounts[_message.sender];
|
||||
auto& sender = accounts[_message.sender];
|
||||
|
||||
bytes code;
|
||||
evmc::bytes code;
|
||||
|
||||
evmc_message message = _message;
|
||||
if (message.depth == 0)
|
||||
@ -163,7 +155,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
{
|
||||
evmc::result result({});
|
||||
result.status_code = EVMC_OUT_OF_GAS;
|
||||
m_state = stateBackup;
|
||||
accounts = stateBackup;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -177,23 +169,23 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
asBytes(to_string(sender.nonce++))
|
||||
));
|
||||
message.destination = convertToEVMC(createAddress);
|
||||
code = bytes(message.input_data, message.input_data + message.input_size);
|
||||
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
|
||||
}
|
||||
else if (message.kind == EVMC_DELEGATECALL)
|
||||
{
|
||||
code = m_state.accounts[message.destination].code;
|
||||
code = accounts[message.destination].code;
|
||||
message.destination = m_currentAddress;
|
||||
}
|
||||
else if (message.kind == EVMC_CALLCODE)
|
||||
{
|
||||
code = m_state.accounts[message.destination].code;
|
||||
code = accounts[message.destination].code;
|
||||
message.destination = m_currentAddress;
|
||||
}
|
||||
else
|
||||
code = m_state.accounts[message.destination].code;
|
||||
code = accounts[message.destination].code;
|
||||
//TODO CREATE2
|
||||
|
||||
Account& destination = m_state.accounts[message.destination];
|
||||
auto& destination = accounts[message.destination];
|
||||
|
||||
if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)
|
||||
{
|
||||
@ -218,55 +210,22 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
else
|
||||
{
|
||||
result.create_address = message.destination;
|
||||
destination.code = bytes(result.output_data, result.output_data + result.output_size);
|
||||
destination.codeHash = convertToEVMC(keccak256(destination.code));
|
||||
destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size);
|
||||
destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size}));
|
||||
}
|
||||
}
|
||||
|
||||
if (result.status_code != EVMC_SUCCESS)
|
||||
m_state = stateBackup;
|
||||
accounts = stateBackup;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
evmc_tx_context EVMHost::get_tx_context() const noexcept
|
||||
{
|
||||
evmc_tx_context ctx = {};
|
||||
ctx.block_timestamp = m_state.timestamp;
|
||||
ctx.block_number = m_state.blockNumber;
|
||||
ctx.block_coinbase = m_coinbase;
|
||||
// TODO: support short literals in EVMC and use them here
|
||||
ctx.block_difficulty = convertToEVMC(u256("200000000"));
|
||||
ctx.block_gas_limit = 20000000;
|
||||
ctx.tx_gas_price = convertToEVMC(u256("3000000000"));
|
||||
ctx.tx_origin = 0x9292929292929292929292929292929292929292_address;
|
||||
// Mainnet according to EIP-155
|
||||
ctx.chain_id = convertToEVMC(u256(1));
|
||||
return ctx;
|
||||
}
|
||||
|
||||
evmc::bytes32 EVMHost::get_block_hash(int64_t _number) const noexcept
|
||||
{
|
||||
return convertToEVMC(u256("0x3737373737373737373737373737373737373737373737373737373737373737") + _number);
|
||||
}
|
||||
|
||||
void EVMHost::emit_log(
|
||||
evmc::address const& _addr,
|
||||
uint8_t const* _data,
|
||||
size_t _dataSize,
|
||||
evmc::bytes32 const _topics[],
|
||||
size_t _topicsCount
|
||||
) noexcept
|
||||
{
|
||||
LogEntry entry;
|
||||
entry.address = convertFromEVMC(_addr);
|
||||
for (size_t i = 0; i < _topicsCount; ++i)
|
||||
entry.topics.emplace_back(convertFromEVMC(_topics[i]));
|
||||
entry.data = bytes(_data, _data + _dataSize);
|
||||
m_state.logs.emplace_back(std::move(entry));
|
||||
}
|
||||
|
||||
|
||||
Address EVMHost::convertFromEVMC(evmc::address const& _addr)
|
||||
{
|
||||
return Address(bytes(begin(_addr.bytes), end(_addr.bytes)));
|
||||
|
127
test/EVMHost.h
127
test/EVMHost.h
@ -21,6 +21,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <test/evmc/mocked_host.hpp>
|
||||
#include <test/evmc/evmc.hpp>
|
||||
#include <test/evmc/evmc.h>
|
||||
|
||||
@ -34,9 +35,12 @@ namespace test
|
||||
{
|
||||
using Address = h160;
|
||||
|
||||
class EVMHost: public evmc::Host
|
||||
class EVMHost: public evmc::MockedHost
|
||||
{
|
||||
public:
|
||||
using MockedHost::get_code_size;
|
||||
using MockedHost::get_balance;
|
||||
|
||||
/// Tries to dynamically load libevmone. @returns nullptr on failure.
|
||||
/// The path has to be provided for the first successful run and will be ignored
|
||||
/// afterwards.
|
||||
@ -44,134 +48,33 @@ public:
|
||||
|
||||
explicit EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm = getVM());
|
||||
|
||||
struct Account
|
||||
{
|
||||
evmc::uint256be balance = {};
|
||||
size_t nonce = 0;
|
||||
bytes code;
|
||||
evmc::bytes32 codeHash = {};
|
||||
std::map<evmc::bytes32, evmc::bytes32> storage;
|
||||
};
|
||||
|
||||
struct LogEntry
|
||||
{
|
||||
Address address;
|
||||
std::vector<h256> topics;
|
||||
bytes data;
|
||||
};
|
||||
|
||||
struct State
|
||||
{
|
||||
size_t blockNumber;
|
||||
uint64_t timestamp;
|
||||
std::map<evmc::address, Account> accounts;
|
||||
std::vector<LogEntry> logs;
|
||||
};
|
||||
|
||||
Account const* account(evmc::address const& _address) const
|
||||
{
|
||||
auto it = m_state.accounts.find(_address);
|
||||
return it == m_state.accounts.end() ? nullptr : &it->second;
|
||||
}
|
||||
|
||||
Account* account(evmc::address const& _address)
|
||||
{
|
||||
auto it = m_state.accounts.find(_address);
|
||||
return it == m_state.accounts.end() ? nullptr : &it->second;
|
||||
}
|
||||
|
||||
void reset() { m_state = State{}; m_currentAddress = {}; }
|
||||
void reset() { accounts.clear(); m_currentAddress = {}; }
|
||||
void newBlock()
|
||||
{
|
||||
m_state.blockNumber++;
|
||||
m_state.timestamp += 15;
|
||||
m_state.logs.clear();
|
||||
tx_context.block_number++;
|
||||
tx_context.block_timestamp += 15;
|
||||
recorded_logs.clear();
|
||||
}
|
||||
|
||||
bool account_exists(evmc::address const& _addr) const noexcept final
|
||||
{
|
||||
return account(_addr) != nullptr;
|
||||
return evmc::MockedHost::account_exists(_addr);
|
||||
}
|
||||
|
||||
evmc::bytes32 get_storage(evmc::address const& _addr, evmc::bytes32 const& _key) const noexcept final
|
||||
{
|
||||
if (auto* acc = account(_addr))
|
||||
{
|
||||
auto it = acc->storage.find(_key);
|
||||
if (it != acc->storage.end())
|
||||
return it->second;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
void selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;
|
||||
|
||||
evmc_storage_status set_storage(
|
||||
evmc::address const& _addr,
|
||||
evmc::bytes32 const& _key,
|
||||
evmc::bytes32 const& _value
|
||||
) noexcept;
|
||||
evmc::result call(evmc_message const& _message) noexcept final;
|
||||
|
||||
evmc::uint256be get_balance(evmc::address const& _addr) const noexcept final
|
||||
{
|
||||
if (Account const* acc = account(_addr))
|
||||
return acc->balance;
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t get_code_size(evmc::address const& _addr) const noexcept final
|
||||
{
|
||||
if (Account const* acc = account(_addr))
|
||||
return acc->code.size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
evmc::bytes32 get_code_hash(evmc::address const& _addr) const noexcept final
|
||||
{
|
||||
if (Account const* acc = account(_addr))
|
||||
return acc->codeHash;
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t copy_code(
|
||||
evmc::address const& _addr,
|
||||
size_t _codeOffset,
|
||||
uint8_t* _bufferData,
|
||||
size_t _bufferSize
|
||||
) const noexcept final
|
||||
{
|
||||
size_t i = 0;
|
||||
if (Account const* acc = account(_addr))
|
||||
for (; i < _bufferSize && _codeOffset + i < acc->code.size(); i++)
|
||||
_bufferData[i] = acc->code[_codeOffset + i];
|
||||
return i;
|
||||
}
|
||||
|
||||
void selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept;
|
||||
|
||||
evmc::result call(evmc_message const& _message) noexcept;
|
||||
|
||||
evmc_tx_context get_tx_context() const noexcept;
|
||||
|
||||
evmc::bytes32 get_block_hash(int64_t number) const noexcept;
|
||||
|
||||
void emit_log(
|
||||
evmc::address const& _addr,
|
||||
uint8_t const* _data,
|
||||
size_t _dataSize,
|
||||
evmc::bytes32 const _topics[],
|
||||
size_t _topicsCount
|
||||
) noexcept;
|
||||
evmc::bytes32 get_block_hash(int64_t number) const noexcept final;
|
||||
|
||||
static Address convertFromEVMC(evmc::address const& _addr);
|
||||
static evmc::address convertToEVMC(Address const& _addr);
|
||||
static h256 convertFromEVMC(evmc::bytes32 const& _data);
|
||||
static evmc::bytes32 convertToEVMC(h256 const& _data);
|
||||
|
||||
|
||||
State m_state;
|
||||
evmc::address m_currentAddress = {};
|
||||
evmc::address m_coinbase = convertToEVMC(Address("0x7878787878787878787878787878787878787878"));
|
||||
|
||||
private:
|
||||
evmc::address m_currentAddress = {};
|
||||
|
||||
static evmc::result precompileECRecover(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileSha256(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileRipeMD160(evmc_message const& _message) noexcept;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <test/EVMHost.h>
|
||||
|
||||
#include <test/evmc/evmc.hpp>
|
||||
#include <test/evmc/loader.h>
|
||||
|
||||
#include <libdevcore/CommonIO.h>
|
||||
|
||||
@ -56,7 +55,7 @@ ExecutionFramework::ExecutionFramework(langutil::EVMVersion _evmVersion):
|
||||
m_evmHost->reset();
|
||||
|
||||
for (size_t i = 0; i < 10; i++)
|
||||
m_evmHost->m_state.accounts[EVMHost::convertToEVMC(account(i))].balance =
|
||||
m_evmHost->accounts[EVMHost::convertToEVMC(account(i))].balance =
|
||||
EVMHost::convertToEVMC(u256(1) << 100);
|
||||
|
||||
}
|
||||
@ -89,12 +88,12 @@ std::pair<bool, string> ExecutionFramework::compareAndCreateMessage(
|
||||
|
||||
u256 ExecutionFramework::gasLimit() const
|
||||
{
|
||||
return {m_evmHost->get_tx_context().block_gas_limit};
|
||||
return {m_evmHost->tx_context.block_gas_limit};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::gasPrice() const
|
||||
{
|
||||
return {EVMHost::convertFromEVMC(m_evmHost->get_tx_context().tx_gas_price)};
|
||||
return {EVMHost::convertFromEVMC(m_evmHost->tx_context.tx_gas_price)};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::blockHash(u256 const& _number) const
|
||||
@ -104,7 +103,7 @@ u256 ExecutionFramework::blockHash(u256 const& _number) const
|
||||
|
||||
u256 ExecutionFramework::blockNumber() const
|
||||
{
|
||||
return m_evmHost->m_state.blockNumber;
|
||||
return m_evmHost->tx_context.block_number;
|
||||
}
|
||||
|
||||
void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
|
||||
@ -178,7 +177,7 @@ void ExecutionFramework::sendEther(Address const& _addr, u256 const& _amount)
|
||||
|
||||
size_t ExecutionFramework::currentTimestamp()
|
||||
{
|
||||
return m_evmHost->get_tx_context().block_timestamp;
|
||||
return m_evmHost->tx_context.block_timestamp;
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::blockTimestamp(u256 _block)
|
||||
@ -201,27 +200,30 @@ bool ExecutionFramework::addressHasCode(Address const& _addr)
|
||||
|
||||
size_t ExecutionFramework::numLogs() const
|
||||
{
|
||||
return m_evmHost->m_state.logs.size();
|
||||
return m_evmHost->recorded_logs.size();
|
||||
}
|
||||
|
||||
size_t ExecutionFramework::numLogTopics(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).topics.size();
|
||||
return m_evmHost->recorded_logs.at(_logIdx).topics.size();
|
||||
}
|
||||
|
||||
h256 ExecutionFramework::logTopic(size_t _logIdx, size_t _topicIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).topics.at(_topicIdx);
|
||||
return EVMHost::convertFromEVMC(m_evmHost->recorded_logs.at(_logIdx).topics.at(_topicIdx));
|
||||
}
|
||||
|
||||
Address ExecutionFramework::logAddress(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).address;
|
||||
return EVMHost::convertFromEVMC(m_evmHost->recorded_logs.at(_logIdx).creator);
|
||||
}
|
||||
|
||||
bytes const& ExecutionFramework::logData(size_t _logIdx) const
|
||||
bytes ExecutionFramework::logData(size_t _logIdx) const
|
||||
{
|
||||
return m_evmHost->m_state.logs.at(_logIdx).data;
|
||||
const auto& data = m_evmHost->recorded_logs.at(_logIdx).data;
|
||||
// TODO: Return a copy of log data, because this is expected from REQUIRE_LOG_DATA(),
|
||||
// but reference type like string_view would be preferable.
|
||||
return {data.begin(), data.end()};
|
||||
}
|
||||
|
||||
u256 ExecutionFramework::balanceAt(Address const& _addr)
|
||||
@ -231,10 +233,11 @@ u256 ExecutionFramework::balanceAt(Address const& _addr)
|
||||
|
||||
bool ExecutionFramework::storageEmpty(Address const& _addr)
|
||||
{
|
||||
if (EVMHost::Account const* acc = m_evmHost->account(EVMHost::convertToEVMC(_addr)))
|
||||
const auto it = m_evmHost->accounts.find(EVMHost::convertToEVMC(_addr));
|
||||
if (it != m_evmHost->accounts.end())
|
||||
{
|
||||
for (auto const& entry: acc->storage)
|
||||
if (!(entry.second == evmc::bytes32{}))
|
||||
for (auto const& entry: it->second.storage)
|
||||
if (!(entry.second.value == evmc::bytes32{}))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -267,7 +267,7 @@ protected:
|
||||
size_t numLogTopics(size_t _logIdx) const;
|
||||
h256 logTopic(size_t _logIdx, size_t _topicIdx) const;
|
||||
Address logAddress(size_t _logIdx) const;
|
||||
bytes const& logData(size_t _logIdx) const;
|
||||
bytes logData(size_t _logIdx) const;
|
||||
|
||||
langutil::EVMVersion m_evmVersion;
|
||||
solidity::RevertStrings m_revertStrings = solidity::RevertStrings::Default;
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev::test;
|
||||
@ -280,8 +279,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
size_t const m_biddingTime = size_t(7 * 24 * 3600);
|
||||
size_t const m_renewalInterval = size_t(365 * 24 * 3600);
|
||||
int64_t const m_biddingTime = 7 * 24 * 3600;
|
||||
};
|
||||
|
||||
}
|
||||
@ -417,7 +415,7 @@ BOOST_AUTO_TEST_CASE(auction_simple)
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// "wait" until auction end
|
||||
|
||||
m_evmHost->m_state.timestamp += m_biddingTime + 10;
|
||||
m_evmHost->tx_context.block_timestamp += m_biddingTime + 10;
|
||||
// trigger auction again
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), m_sender);
|
||||
@ -429,7 +427,7 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
string name = "x";
|
||||
|
||||
unsigned startTime = 0x776347e2;
|
||||
m_evmHost->m_state.timestamp = startTime;
|
||||
m_evmHost->tx_context.block_timestamp = startTime;
|
||||
|
||||
RegistrarInterface registrar(*this);
|
||||
// initiate auction
|
||||
@ -437,19 +435,19 @@ BOOST_AUTO_TEST_CASE(auction_bidding)
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// overbid self
|
||||
m_evmHost->m_state.timestamp = startTime + m_biddingTime - 10;
|
||||
m_evmHost->tx_context.block_timestamp = startTime + m_biddingTime - 10;
|
||||
registrar.setNextValue(12);
|
||||
registrar.reserve(name);
|
||||
// another bid by someone else
|
||||
sendEther(account(1), 10 * ether);
|
||||
m_sender = account(1);
|
||||
m_evmHost->m_state.timestamp = startTime + 2 * m_biddingTime - 50;
|
||||
m_evmHost->tx_context.block_timestamp = startTime + 2 * m_biddingTime - 50;
|
||||
registrar.setNextValue(13);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), 0);
|
||||
// end auction by first bidder (which is not highest) trying to overbid again (too late)
|
||||
m_sender = account(0);
|
||||
m_evmHost->m_state.timestamp = startTime + 4 * m_biddingTime;
|
||||
m_evmHost->tx_context.block_timestamp = startTime + 4 * m_biddingTime;
|
||||
registrar.setNextValue(20);
|
||||
registrar.reserve(name);
|
||||
BOOST_CHECK_EQUAL(registrar.owner(name), account(1));
|
||||
|
@ -1115,7 +1115,7 @@ BOOST_AUTO_TEST_CASE(blockchain)
|
||||
}
|
||||
}
|
||||
)";
|
||||
m_evmHost->m_coinbase = EVMHost::convertToEVMC(Address("0x1212121212121212121212121212121212121212"));
|
||||
m_evmHost->tx_context.block_coinbase = EVMHost::convertToEVMC(Address("0x1212121212121212121212121212121212121212"));
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
m_evmHost->newBlock();
|
||||
|
@ -1,19 +0,0 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract Simple {
|
||||
uint[] a;
|
||||
function f(uint n) public {
|
||||
uint i;
|
||||
while (i < n)
|
||||
{
|
||||
a[i] = i;
|
||||
++i;
|
||||
}
|
||||
require(n > 1);
|
||||
// Assertion is safe but current solver version cannot solve it.
|
||||
// Keep test for next solver release.
|
||||
assert(a[n-1] > a[n-2]);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (273-296): Assertion violation happens here
|
@ -0,0 +1,26 @@
|
||||
pragma experimental SMTChecker;
|
||||
|
||||
contract LoopFor2 {
|
||||
uint[] b;
|
||||
uint[] c;
|
||||
|
||||
function testUnboundedForLoop(uint n) public {
|
||||
b[0] = 900;
|
||||
uint[] storage a = b;
|
||||
require(n > 0 && n < 100);
|
||||
uint i;
|
||||
while (i < n) {
|
||||
b[i] = i + 1;
|
||||
c[i] = b[i];
|
||||
++i;
|
||||
}
|
||||
// Fails as false positive.
|
||||
assert(b[0] == c[0]);
|
||||
assert(a[0] == 900);
|
||||
assert(b[0] == 900);
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// Warning: (296-316): Assertion violation happens here
|
||||
// Warning: (320-339): Assertion violation happens here
|
||||
// Warning: (343-362): Assertion violation happens here
|
Loading…
Reference in New Issue
Block a user