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

LastHashes refactoring #4126

Merged
merged 1 commit into from
Jun 21, 2017
Merged

LastHashes refactoring #4126

merged 1 commit into from
Jun 21, 2017

Conversation

gumb0
Copy link
Member

@gumb0 gumb0 commented Jun 8, 2017

Follow-up to #4066
Resolves #4084

Refactoring basically replaces LastHashes vector constructed by Blockchain class and passed to Executive when we need to execute some VM code with LastBlockHashesFace interface provided by BlockChain class.
The new interface constructs exactly the same vector, and the behavior before Metropolis is not changed.

After Metropolis BLOCKHASH doesn't access this interface (performs a call to contract instead) and this way we avoid constructing unnecessary hash vector.

@gumb0 gumb0 force-pushed the lasthashes-refactoring2 branch 3 times, most recently from bbe1350 to 555050f Compare June 8, 2017 16:34
@@ -1,5 +1,7 @@
#pragma once

#include "db.h"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This vector_ref.h file uses DEV_LDB macro defined in db.h
This came up after reordering of #include's in another file

@@ -45,7 +45,7 @@ class Ethash: public SealEngineBase

StringHashMap jsInfo(BlockHeader const& _bi) const override;
void verify(Strictness _s, BlockHeader const& _bi, BlockHeader const& _parent, bytesConstRef _block) const override;
void verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, EnvInfo const& _env) const override;
void verifyTransaction(ImportRequirements::value _ir, TransactionBase const& _t, BlockHeader const& _header, u256 const& _startGasUsed) const override;
Copy link
Member Author

@gumb0 gumb0 Jun 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this change is that I find it weird that transaction validation depends on EnvInfo which describes an enviroment for VM execution.
Also EnvInfo now contains a pointer to LastBlockHashesFace, which shouldn't have to do with transation validation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy to see these dependencies go.

@codecov-io
Copy link

codecov-io commented Jun 8, 2017

Codecov Report

Merging #4126 into develop will increase coverage by 0.21%.
The diff coverage is 76.99%.

@@             Coverage Diff             @@
##           develop    #4126      +/-   ##
===========================================
+ Coverage    66.94%   67.16%   +0.21%     
===========================================
  Files          299      301       +2     
  Lines        23138    23126      -12     
===========================================
+ Hits         15490    15532      +42     
+ Misses        7648     7594      -54
Impacted Files Coverage Δ
libethereum/Block.h 60.86% <ø> (ø) ⬆️
test/tools/jsontests/vm.h 100% <ø> (ø) ⬆️
libethcore/SealEngine.h 75% <ø> (ø) ⬆️
libethereum/Client.h 68.42% <ø> (ø) ⬆️
test/tools/libtesteth/ImportTest.h 100% <ø> (ø) ⬆️
libethereum/State.h 95.12% <ø> (ø) ⬆️
libethereum/Client.cpp 25.4% <ø> (+0.84%) ⬆️
libethashseal/Ethash.h 42.85% <ø> (ø) ⬆️
libethereum/Interface.h 16.66% <ø> (ø) ⬆️
libethereum/Executive.h 66.66% <ø> (ø) ⬆️
... and 30 more

@@ -100,10 +100,6 @@ class Client: public ClientBase, protected Worker
/// Queues a block for import.
ImportResult queueBlock(bytes const& _block, bool _isSafe = false);

using Interface::call; // to remove warning about hiding virtual function
/// Makes the given call. Nothing is recorded into the state. This cheats by creating a null address and endowing it with a lot of ETH.
ExecutionResult call(Address _dest, bytes const& _data = bytes(), u256 _gas = 125000, u256 _value = 0, u256 _gasPrice = 1 * ether, Address const& _from = Address());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not used

@@ -95,13 +95,6 @@ class Interface
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _blockNumber, _ff); }
ExecutionResult call(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, FudgeFactor _ff = FudgeFactor::Strict) { return call(toAddress(_secret), _value, _dest, _data, _gas, _gasPrice, _ff); }

/// Does the given creation. Nothing is recorded into the state.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These were not used

@gumb0 gumb0 added this to the Metropolis milestone Jun 9, 2017
@@ -313,7 +313,7 @@ int main(int argc, char** argv)

if (mode == Mode::Statistics)
{
cout << "Gas used: " << res.gasUsed << " (+" << t.baseGasRequired(se->evmSchedule(envInfo)) << " for transaction, -" << res.gasRefunded << " refunded)" << endl;
cout << "Gas used: " << res.gasUsed << " (+" << t.baseGasRequired(se->evmSchedule(envInfo.number())) << " for transaction, -" << res.gasRefunded << " refunded)" << endl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will this affect VMTests ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely not, this change is just giving evmSchedule the only thing it needs - block number instead of the whole EnvInfo

Copy link
Contributor

@winsvega winsvega left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tests work fine

@@ -75,7 +75,7 @@ class SealEngineFace
ChainOperationParams const& chainParams() const { return m_params; }
void setChainParams(ChainOperationParams const& _params) { m_params = _params; }
SealEngineFace* withChainParams(ChainOperationParams const& _params) { setChainParams(_params); return this; }
virtual EVMSchedule const& evmSchedule(EnvInfo const&) const = 0;
virtual EVMSchedule const& evmSchedule(u256 const&) const = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name the parameter?

@@ -105,7 +105,7 @@ class SealEngineBase: public SealEngineFace
m_onSealGenerated(ret.out());
}
void onSealGenerated(std::function<void(bytes const&)> const& _f) override { m_onSealGenerated = _f; }
EVMSchedule const& evmSchedule(EnvInfo const&) const override;
EVMSchedule const& evmSchedule(u256 const&) const override;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name the parameter?

@@ -228,30 +227,32 @@ class EnvInfo
{
public:
EnvInfo() {}
EnvInfo(BlockHeader const& _current, LastHashes const& _lh = LastHashes(), u256 const& _gasUsed = u256()):
EnvInfo(BlockHeader const& _current, std::shared_ptr<LastBlockHashesFace const> _lh, u256 const& _gasUsed):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't to figure out the reason this is the shared_ptr.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to get rid of it and pass LastBlockHashesFace const& around, but I gave up because some test code need setting & resetting this interface into EnvInfo (calling EnvInfo::setLastHashes())

Copy link
Member Author

@gumb0 gumb0 Jun 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code to be exact: https:/ethereum/cpp-ethereum/pull/4126/files#diff-e01cd53eebd917cc35354ffc7719d8adR295

Probably there's a way to change this test code somehow... modifying EnvInfo is a weird thing to do in general

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the shared_ptr here either, but can't tell you how to fix it.

void setLastHashes(LastHashes&& _lh) { m_lastHashes = _lh; }

void setLastHashes(std::shared_ptr<LastBlockHashesFace const> _lh) { m_lastHashes = _lh; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spurious space.

@chfast
Copy link
Member

chfast commented Jun 14, 2017

I like the direction it is going. And I also want less dependencies on test framework. Just can we use unique PTR instead?

@gumb0
Copy link
Member Author

gumb0 commented Jun 14, 2017

@chfast Hm, making it unique_ptr means we'll construct the new instance of this LastBlockHashes implementation (https:/ethereum/cpp-ethereum/pull/4126/files#diff-4bd28474d53dacc284d9432a1a785c10R128) on every tx execution. Which kind of defeats the purpose of caching the returned hashes vector in LastBlockHashes::m_lastHashes

@gumb0
Copy link
Member Author

gumb0 commented Jun 14, 2017

I'm trying to replace shared_ptr<LastBlockHashesFace const> with LastBlockHashesFace const&.
If it doesn't work out, I'll go with unique_ptr

If it does work out, it probably better should go into separate PR

@gumb0 gumb0 force-pushed the lasthashes-refactoring2 branch 3 times, most recently from 0a4d215 to 778418e Compare June 15, 2017 15:46
@@ -274,6 +283,8 @@ int main(int argc, char** argv)
state.addBalance(sender, value);

unique_ptr<SealEngineFace> se(ChainParams(genesisInfo(networkName)).createSealEngine());
LastBlockHashes lastBlockHashes;
EnvInfo const envInfo(blockHeader, lastBlockHashes, 0);
Copy link
Member Author

@gumb0 gumb0 Jun 15, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like previously ethvm tool didn't work for the code containing BLOCKHASH. Now any BLOCKHASH will return 0

@gumb0 gumb0 force-pushed the lasthashes-refactoring2 branch 4 times, most recently from 6e75183 to f3e90f5 Compare June 20, 2017 13:48
@gumb0
Copy link
Member Author

gumb0 commented Jun 20, 2017

I've replaced shared_ptr<LastBlockHashes const> with LastBlockHashes const& and made EnvInfo struct immutable (now when test code needs to set a new last hashes, it recreates EnvInfo)

Tests are green now, please review the changes @chfast @gcolvin @pirapira @winsvega
(I somehow messed up making it a separate commit and it's all now in one forced-pushed commit, sorry)

h256s precedingHashes(h256 const& _mostRecentHash) const override
{
Guard l(m_lastHashesMutex);
if (m_lastHashes.empty() || m_lastHashes.back() != _mostRecentHash)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean front instead of back?

In a following line I see m_lastHashes[0] = _mostRecentHash.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, looks like it was incorrect in the original code, nice catch!

LastHashes BlockChain::lastHashes(h256 const& _parent) const
{
Guard l(x_lastLastHashes);
if (m_lastLastHashes.empty() || m_lastLastHashes.back() != _parent)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the back is inherited from here.

@gumb0 gumb0 merged commit d06c3be into develop Jun 21, 2017
@gumb0 gumb0 deleted the lasthashes-refactoring2 branch June 21, 2017 11:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants