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

Commit

Permalink
Unit tests for BLOCKHASH-refactoring-related code in Block & ExtVM cl…
Browse files Browse the repository at this point in the history
…asses
  • Loading branch information
gumb0 committed May 17, 2017
1 parent 2e09ff7 commit c4dd751
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 0 deletions.
2 changes: 2 additions & 0 deletions libethashseal/GenesisInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ using namespace dev;
#include "genesis/eip150Test.cpp"
#include "genesis/eip158Test.cpp"
#include "genesis/metropolisTest.cpp"
#include "genesis/metropolisTransitionTest.cpp"
#include "genesis/transitionnetTest.cpp"

std::string const& dev::eth::genesisInfo(Network _n)
Expand All @@ -45,6 +46,7 @@ std::string const& dev::eth::genesisInfo(Network _n)
case Network::EIP150Test: return c_genesisInfoEIP150Test;
case Network::EIP158Test: return c_genesisInfoEIP158Test;
case Network::MetropolisTest: return c_genesisInfoMetropolisTest;
case Network::MetropolisTransitionTest: return c_genesisInfoMetropolisTransitionTest;
default:
throw std::invalid_argument("Invalid network value");
}
Expand Down
1 change: 1 addition & 0 deletions libethashseal/GenesisInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum class Network
EIP150Test = 73, ///< Homestead + EIP150 Rules active from block 0 For BlockchainTests
EIP158Test = 74, ///< Homestead + EIP150 + EIP158 Rules active from block 0
MetropolisTest = 75, ///< All fork rules + Metropolis active from block 0
MetropolisTransitionTest = 76, ///< All fork rules + Metropolis active from block 2
Special = 0xff ///< Something else.
};

Expand Down
63 changes: 63 additions & 0 deletions libethashseal/genesis/metropolisTransitionTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../GenesisInfo.h"

static dev::h256 const c_genesisStateRootMetropolisTransitionTest;
static std::string const c_genesisInfoMetropolisTransitionTest = std::string() +
R"E(
{
"sealEngine": "NoProof",
"params": {
"accountStartNonce": "0x00",
"maximumExtraDataSize": "0x20",
"homsteadForkBlock": "0x00",
"daoHardforkBlock": "0xfffffffffffffff",
"EIP150ForkBlock": "0x00",
"EIP158ForkBlock": "0x00",
"metropolisForkBlock": "0x02",
"minGasLimit": "0x1388",
"maxGasLimit": "7fffffffffffffff",
"tieBreakingGas": false,
"gasLimitBoundDivisor": "0x0400",
"minimumDifficulty": "0x020000",
"difficultyBoundDivisor": "0x0800",
"durationLimit": "0x0d",
"blockReward": "0x4563918244F40000",
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
"networkID" : "0x1",
"chainID": "0x01",
"allowFutureBlocks" : true
},
"genesis": {
"nonce": "0x0000000000000042",
"difficulty": "0x400000000",
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"author": "0x0000000000000000000000000000000000000000",
"timestamp": "0x00",
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
"gasLimit": "0x1388"
},
"accounts": {
"0000000000000000000000000000000000000001": { "wei": "1", "precompiled": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
"0000000000000000000000000000000000000002": { "wei": "1", "precompiled": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
"0000000000000000000000000000000000000003": { "wei": "1", "precompiled": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
"0000000000000000000000000000000000000004": { "wei": "1", "precompiled": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
"0000000000000000000000000000000000000005": { "wei": "1", "precompiled": { "name": "modexp" } }
}
}
)E";
7 changes: 7 additions & 0 deletions test/tools/libtesteth/BlockChainHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,11 @@ class TestBlockChain
std::unique_ptr<TransientDirectory> m_tempDirBlockchain;
};

class NetworkSelector
{
public:
explicit NetworkSelector(Network _network) { TestBlockChain::s_sealEngineNetwork = _network; }
~NetworkSelector() { TestBlockChain::s_sealEngineNetwork = Network::FrontierTest; } // reset to default
};

}}
60 changes: 60 additions & 0 deletions test/unittests/libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,64 @@ BOOST_AUTO_TEST_CASE(bGetReceiptOverflow)
BOOST_CHECK_THROW(block.receipt(123), std::out_of_range);
}

class MetropolisTransitionTestFixture: public TestOutputHelper
{
public:
MetropolisTransitionTestFixture():
networkSelector(Network::MetropolisTransitionTest),
testBlockchain(TestBlockChain::defaultGenesisBlock()),
genesisBlock(testBlockchain.testGenesis()),
genesisDB(genesisBlock.state().db()),
blockchain(testBlockchain.interface())
{
TestBlock testBlock;
// block 1 - before Metropolis
testBlock.mine(testBlockchain);
testBlockchain.addBlock(testBlock);
block1hash = blockchain.currentHash();

// block 2 - first Metropolis block
testBlock.mine(testBlockchain);
testBlockchain.addBlock(testBlock);
block2hash = blockchain.currentHash();
}

NetworkSelector networkSelector;
TestBlockChain testBlockchain;
TestBlock const& genesisBlock;
OverlayDB const& genesisDB;
BlockChain const& blockchain;

h256 block1hash;
h256 block2hash;
};

BOOST_FIXTURE_TEST_SUITE(MetropolisBlockSuite, MetropolisTransitionTestFixture)

BOOST_AUTO_TEST_CASE(bBlockhashContractIsCreated)
{
Block block = blockchain.genesisBlock(genesisDB);
BOOST_CHECK(!block.state().addressHasCode(Address(0xf0)));

block.sync(blockchain);
BOOST_REQUIRE(block.state().addressHasCode(Address(0xf0)));
}

BOOST_AUTO_TEST_CASE(bBlockhashContractIsUpdated)
{
Block block = blockchain.genesisBlock(genesisDB);
block.sync(blockchain, block1hash); // sync to the beginning of block 2

h256 storageRoot2 = block.state().storageRoot(Address(0xf0));
BOOST_CHECK(storageRoot2 != EmptyTrie);

block.sync(blockchain); // sync to the beginning of block 3
h256 storageRoot3 = block.state().storageRoot(Address(0xf0));
BOOST_CHECK(storageRoot3 != EmptyTrie);

BOOST_REQUIRE(storageRoot2 != storageRoot3);
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()
111 changes: 111 additions & 0 deletions test/unittests/libethereum/ExtVMTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file ExtVMTest.cpp
*/

#include <test/tools/libtesteth/TestHelper.h>
#include <test/tools/libtesteth/BlockChainHelper.h>

#include <libethereum/Block.h>
#include <libethereum/ExtVM.h>

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

class ExtVMTestFixture: public TestOutputHelper
{
public:
ExtVMTestFixture():
networkSelector(Network::MetropolisTransitionTest),
testBlockchain(TestBlockChain::defaultGenesisBlock()),
genesisBlock(testBlockchain.testGenesis()),
genesisDB(genesisBlock.state().db()),
blockchain(testBlockchain.interface())
{
TestBlock testBlock;
// block 1 - before Metropolis
testBlock.mine(testBlockchain);
testBlockchain.addBlock(testBlock);

// block 2 - first Metropolis block
testBlock.mine(testBlockchain);
testBlockchain.addBlock(testBlock);
}

NetworkSelector networkSelector;
TestBlockChain testBlockchain;
TestBlock const& genesisBlock;
OverlayDB const& genesisDB;
BlockChain const& blockchain;
};

BOOST_FIXTURE_TEST_SUITE(ExtVmSuite, ExtVMTestFixture)

BOOST_AUTO_TEST_CASE(BlockhashOutOfBoundsRetunsZero)
{
Block block = blockchain.genesisBlock(genesisDB);
block.sync(blockchain);

EnvInfo envInfo(block.info(), {}, 0);
Address addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
ExtVM extVM(block.mutableState(), envInfo, *blockchain.sealEngine(), addr, addr, addr, 0, 0, bytesConstRef(), bytesConstRef(), h256());

BOOST_CHECK_EQUAL(extVM.blockHash(100), h256());
}

BOOST_AUTO_TEST_CASE(BlockhashBeforeMetropolisReliesOnLastHashes)
{
Block block = blockchain.genesisBlock(genesisDB);
block.sync(blockchain);

LastHashes lastHashes{ h256("0xaaabbbccc"), h256("0xdddeeefff")};
EnvInfo envInfo(block.info(), lastHashes, 0);
Address addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
ExtVM extVM(block.mutableState(), envInfo, *blockchain.sealEngine(), addr, addr, addr, 0, 0, bytesConstRef(), bytesConstRef(), h256());
h256 hash = extVM.blockHash(1);
BOOST_REQUIRE_EQUAL(hash, lastHashes[0]);
}

BOOST_AUTO_TEST_CASE(BlockhashDoesntNeedLastHashesInMetropolis)
{
// BLOCKHASH starts to work through the call to a contract 256 block after Metro fork block
TestBlock testBlock;
for (int i = 0; i < 256; ++i)
{
testBlock.mine(testBlockchain);
testBlockchain.addBlock(testBlock);
}

Block block = blockchain.genesisBlock(genesisDB);
block.sync(blockchain);

LastHashes lastHashes{};
EnvInfo envInfo(block.info(), lastHashes, 0);
Address addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b");
ExtVM extVM(block.mutableState(), envInfo, *blockchain.sealEngine(), addr, addr, addr, 0, 0, bytesConstRef(), bytesConstRef(), h256());

// older than 256 not available
BOOST_CHECK_EQUAL(extVM.blockHash(1), h256());

h256 hash = extVM.blockHash(200);
BOOST_REQUIRE_EQUAL(hash, blockchain.numberHash(200));
}


BOOST_AUTO_TEST_SUITE_END()

0 comments on commit c4dd751

Please sign in to comment.