mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add missing tests for `gasleft()
,
blockhash()
tx.gasprice
and
block.gaslimit
`.
This commit is contained in:
parent
3dd31b704a
commit
06b7edfdcf
@ -85,6 +85,22 @@ std::pair<bool, string> ExecutionFramework::compareAndCreateMessage(
|
|||||||
return make_pair(false, message);
|
return make_pair(false, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u256 ExecutionFramework::gasLimit() const
|
||||||
|
{
|
||||||
|
auto latestBlock = m_rpc.eth_getBlockByNumber("latest", false);
|
||||||
|
return u256(latestBlock["gasLimit"].asString());
|
||||||
|
}
|
||||||
|
|
||||||
|
u256 ExecutionFramework::gasPrice() const
|
||||||
|
{
|
||||||
|
return u256(m_rpc.eth_gasPrice());
|
||||||
|
}
|
||||||
|
|
||||||
|
u256 ExecutionFramework::blockHash(u256 const& _blockNumber) const
|
||||||
|
{
|
||||||
|
return u256(m_rpc.eth_getBlockByNumber(toHex(_blockNumber, HexPrefix::Add), false)["hash"].asString());
|
||||||
|
}
|
||||||
|
|
||||||
void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
|
void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256 const& _value)
|
||||||
{
|
{
|
||||||
if (m_showMessages)
|
if (m_showMessages)
|
||||||
|
@ -194,6 +194,13 @@ public:
|
|||||||
return encodeArgs(u256(0x20), u256(_arg.size()), _arg);
|
return encodeArgs(u256(0x20), u256(_arg.size()), _arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u256 gasLimit() const;
|
||||||
|
u256 gasPrice() const;
|
||||||
|
u256 blockHash(u256 const& _blockNumber) const;
|
||||||
|
u256 const& blockNumber() const {
|
||||||
|
return m_blockNumber;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <class CppFunction, class... Args>
|
template <class CppFunction, class... Args>
|
||||||
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
|
auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments)
|
||||||
|
@ -207,6 +207,11 @@ string RPCSession::eth_getStorageRoot(string const& _address, string const& _blo
|
|||||||
return rpcCall("eth_getStorageRoot", { quote(address), quote(_blockNumber) }).asString();
|
return rpcCall("eth_getStorageRoot", { quote(address), quote(_blockNumber) }).asString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string RPCSession::eth_gasPrice()
|
||||||
|
{
|
||||||
|
return rpcCall("eth_gasPrice").asString();
|
||||||
|
}
|
||||||
|
|
||||||
void RPCSession::personal_unlockAccount(string const& _address, string const& _password, int _duration)
|
void RPCSession::personal_unlockAccount(string const& _address, string const& _password, int _duration)
|
||||||
{
|
{
|
||||||
BOOST_REQUIRE_MESSAGE(
|
BOOST_REQUIRE_MESSAGE(
|
||||||
|
@ -113,6 +113,7 @@ public:
|
|||||||
std::string eth_sendTransaction(std::string const& _transaction);
|
std::string eth_sendTransaction(std::string const& _transaction);
|
||||||
std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
|
std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
|
||||||
std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber);
|
std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber);
|
||||||
|
std::string eth_gasPrice();
|
||||||
std::string personal_newAccount(std::string const& _password);
|
std::string personal_newAccount(std::string const& _password);
|
||||||
void personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration);
|
void personal_unlockAccount(std::string const& _address, std::string const& _password, int _duration);
|
||||||
void test_setChainParams(std::vector<std::string> const& _accounts);
|
void test_setChainParams(std::vector<std::string> const& _accounts);
|
||||||
|
@ -2988,6 +2988,86 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic)
|
|||||||
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
|
BOOST_REQUIRE(callContractFunction("checkState()") == encodeArgs(false, 20 - 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(gasleft_decrease)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
uint v;
|
||||||
|
function f() public returns (bool) {
|
||||||
|
uint startGas = gasleft();
|
||||||
|
v++;
|
||||||
|
assert(startGas > gasleft());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function g() public returns (bool) {
|
||||||
|
uint startGas = gasleft();
|
||||||
|
assert(startGas > gasleft());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
ABI_CHECK(callContractFunction("f()"), encodeArgs(true));
|
||||||
|
ABI_CHECK(callContractFunction("g()"), encodeArgs(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(gaslimit)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f() public returns (uint) {
|
||||||
|
return block.gaslimit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
ABI_CHECK(callContractFunction("f()"), encodeArgs(gasLimit()));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(gasprice)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f() public returns (uint) {
|
||||||
|
return tx.gasprice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
ABI_CHECK(callContractFunction("f()"), encodeArgs(gasPrice()));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(blockhash)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
uint256 counter;
|
||||||
|
function g() public returns (bool) { counter++; return true; }
|
||||||
|
function f() public returns (bytes32[] memory r) {
|
||||||
|
r = new bytes32[](259);
|
||||||
|
for (uint i = 0; i < 259; i++)
|
||||||
|
r[i] = blockhash(block.number - 257 + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode);
|
||||||
|
// generate a sufficient amount of blocks
|
||||||
|
while (blockNumber() < u256(255))
|
||||||
|
ABI_CHECK(callContractFunction("g()"), encodeArgs(true));
|
||||||
|
|
||||||
|
vector<u256> hashes;
|
||||||
|
hashes.reserve(259);
|
||||||
|
// ``blockhash()`` is only valid for the last 256 blocks, otherwise zero
|
||||||
|
hashes.emplace_back(0);
|
||||||
|
for (u256 i = blockNumber() - u256(255); i <= blockNumber(); i++)
|
||||||
|
hashes.emplace_back(blockHash(i));
|
||||||
|
// the current block hash is not yet known at execution time and therefore zero
|
||||||
|
hashes.emplace_back(0);
|
||||||
|
// future block hashes are zero
|
||||||
|
hashes.emplace_back(0);
|
||||||
|
ABI_CHECK(callContractFunction("f()"), encodeDyn(hashes));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(value_complex)
|
BOOST_AUTO_TEST_CASE(value_complex)
|
||||||
{
|
{
|
||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
|
Loading…
Reference in New Issue
Block a user