Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
More unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Jul 2, 2019
1 parent 75f488a commit 23b85b5
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 2 deletions.
3 changes: 3 additions & 0 deletions libethereum/Executive.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ class Executive
/// Revert all changes made to the state by this execution.
void revert();

/// Used only in tests
ExtVM const& extVM() const { return *m_ext; }

private:
/// @returns false iff go() must be called (and thus a VM execution in required).
bool createWithAddressFromNonceAndSender(Address const& _sender, u256 const& _endowment,
Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ set(unittest_sources
unittests/libethcore/CommonJS.cpp
unittests/libethcore/KeyManager.cpp

unittests/libethereum/ExecutiveTest.cpp
unittests/libethereum/ValidationSchemes.cpp

unittests/libp2p/capability.cpp
Expand Down
148 changes: 148 additions & 0 deletions test/unittests/libethereum/ExecutiveTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Aleth: Ethereum C++ client, tools and libraries.
// Copyright 2019 Aleth Authors.
// Licensed under the GNU General Public License, Version 3.

#include <libethashseal/Ethash.h>
#include <libethashseal/GenesisInfo.h>
#include <libethereum/ChainParams.h>
#include <libethereum/Executive.h>
#include <libethereum/ExtVM.h>
#include <libethereum/State.h>
#include <test/tools/libtestutils/TestLastBlockHashes.h>
#include <gtest/gtest.h>

using namespace dev;
using namespace dev::eth;
using namespace dev::test;

class ExecutiveTest : public testing::Test
{
public:
ExecutiveTest()
{
ethash.setChainParams(ChainParams{genesisInfo(eth::Network::IstanbulTransitionTest)});
}

Ethash ethash;
BlockHeader blockHeader;
TestLastBlockHashes lastBlockHashes{{}};
State state{0};

Address receiveAddress{"0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"};
Address txSender{"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
u256 txValue;
u256 gasPrice;
bytesConstRef txData{};
u256 gas = 1000000;
bytes code = {1, 2, 3, 4};
};

TEST_F(ExecutiveTest, callUsesAccountVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(receiveAddress);
u256 version = 1;
state.setCode(receiveAddress, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);

bool done = executive.call(receiveAddress, txSender, txValue, gasPrice, txData, gas);

EXPECT_FALSE(done);
EXPECT_EQ(executive.extVM().version, version);
}

TEST_F(ExecutiveTest, createUsesLatestForkVersion)
{
// block in Istanbul fork
blockHeader.setNumber(10);

EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

Executive executive(state, envInfo, ethash);

bool done = executive.create(txSender, txValue, gasPrice, gas, ref(code), txSender);

EXPECT_FALSE(done);
EXPECT_EQ(executive.extVM().version, IstanbulSchedule.version);
}

TEST_F(ExecutiveTest, createOpcodeUsesParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);

bool done = executive.createOpcode(txSender, txValue, gasPrice, gas, ref(code), txSender);

EXPECT_FALSE(done);
EXPECT_EQ(executive.extVM().version, version);
}

TEST_F(ExecutiveTest, create2OpcodeUsesParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);

bool done = executive.create2Opcode(txSender, txValue, gasPrice, gas, ref(code), txSender, 0);

EXPECT_FALSE(done);
EXPECT_EQ(executive.extVM().version, version);
}

TEST_F(ExecutiveTest, emptyInitCodeSetsParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);

bytes initCode;
bool done = executive.createOpcode(txSender, txValue, gasPrice, gas, ref(initCode), txSender);

EXPECT_TRUE(done);
EXPECT_FALSE(state.addressHasCode(executive.newAddress()));
EXPECT_EQ(state.version(executive.newAddress()), version);
}

TEST_F(ExecutiveTest, createdContractHasParentVersion)
{
EnvInfo envInfo(blockHeader, lastBlockHashes, 0);

state.createContract(txSender);
u256 version = 1;
state.setCode(txSender, bytes{code}, version);
state.commit(State::CommitBehaviour::RemoveEmptyAccounts);

Executive executive(state, envInfo, ethash);

// mstore(0, 0x60)
// return(0, 0x20)
bytes initCode = fromHex("606060005260206000f3");

bool done = executive.createOpcode(txSender, txValue, gasPrice, gas, ref(initCode), txSender);
EXPECT_FALSE(done);

done = executive.go();
EXPECT_TRUE(done);

EXPECT_TRUE(state.addressHasCode(executive.newAddress()));
EXPECT_EQ(state.version(executive.newAddress()), version);
}
24 changes: 22 additions & 2 deletions test/unittests/libethereum/StateUnitTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ BOOST_AUTO_TEST_CASE(RollbackSetCode)
s.setCode(addr, {std::begin(codeData), std::end(codeData)}, version);
s.rollback(savepoint);

BOOST_CHECK(!s.addressHasCode(addr));
BOOST_CHECK(!s.accountNonemptyAndExisting(addr));
BOOST_CHECK(!s.addressInUse(addr));
BOOST_CHECK(s.version(addr) == 0);

// only state root exists in DB
BOOST_CHECK_EQUAL(s.db().keys().size(), 1);
}

BOOST_AUTO_TEST_CASE(CodeVersionZero)
Expand All @@ -85,6 +88,23 @@ BOOST_AUTO_TEST_CASE(CodeVersionZero)
BOOST_CHECK_EQUAL(s.version(addr), version);
}

BOOST_AUTO_TEST_CASE(SetEmptyCodeNonZeroVersion)
{
Address addr{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
State s{0};
s.createContract(addr);
s.setNonce(addr, 1);
u256 version = 123;
s.setCode(addr, {}, version);
s.commit(State::CommitBehaviour::RemoveEmptyAccounts);

BOOST_CHECK(!s.addressHasCode(addr));
BOOST_CHECK_EQUAL(s.version(addr), version);

// empty code is not saved to DB
BOOST_CHECK(!s.db().exists(EmptySHA3));
}

class AddressRangeTestFixture : public TestOutputHelperFixture
{
public:
Expand Down

0 comments on commit 23b85b5

Please sign in to comment.