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

parse different versions of genesis config #4973

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion libethcore/ChainOperationParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ PrecompiledContract::PrecompiledContract(

ChainOperationParams::ChainOperationParams():
m_blockReward("0x4563918244F40000"),
m_allowRewardOverwrite(true),
minGasLimit(0x1388),
maxGasLimit("0x7fffffffffffffff"),
gasLimitBoundDivisor(0x0400),
Expand Down Expand Up @@ -73,7 +74,7 @@ EVMSchedule const& ChainOperationParams::scheduleForBlockNumber(u256 const& _blo

u256 ChainOperationParams::blockReward(EVMSchedule const& _schedule) const
{
if (_schedule.blockRewardOverwrite)
if (_schedule.blockRewardOverwrite && m_allowRewardOverwrite)
return *_schedule.blockRewardOverwrite;
else
return m_blockReward;
Expand Down
3 changes: 3 additions & 0 deletions libethcore/ChainOperationParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,13 @@ struct ChainOperationParams
/// General chain params.
private:
u256 m_blockReward;
bool m_allowRewardOverwrite; //allow overwrite of the block reward that is set in genesis.json
Copy link
Member

Choose a reason for hiding this comment

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

Why do you need this hack?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

without this, Byzantium blockreward is reset to non zero value even if I want to run Byzantium tests with 0 mining reward that I set in chain params.

Copy link
Member

Choose a reason for hiding this comment

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

You're not running Byzantium rules then. Maybe create another config similar to Byzantium but without block reward?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well then I do not run any rules then. because I use 0 block reward for all tests with NoProof
the issue is that Byzantium set is overwriting the block reward and I dont have any means to prevent it from config.

Copy link
Member

Choose a reason for hiding this comment

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

You need to create new EVMSchedule in EVMSchedule.h, add it to ChainOperationParams::scheduleForBlockNumber(), then use new param like "byzantiumTestForkBlock" in actual chain config

Copy link
Contributor Author

Choose a reason for hiding this comment

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

isn't it too much just for the test purpose?

Copy link
Member

Choose a reason for hiding this comment

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

Well ad-hoc hacking lower-level data structures and mechanisms just for the test purpose seems too much to me

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it is not really a hack. its an option to set mining reward in genesis config

Copy link
Member

Choose a reason for hiding this comment

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

To make it work you could also try just overriding NoProof::blockReward() and always returning 0 from there.

Copy link
Member

Choose a reason for hiding this comment

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

Though I wouldn't fully support such change, because it makes NoProof engine further away from real network mechanics and for unit tests I would like it to stay closer. But if you'd made another engine just for your tests like NoProofZeroRewards that would be fine I guess.


public:
EVMSchedule const& scheduleForBlockNumber(u256 const& _blockNumber) const;
u256 blockReward(EVMSchedule const& _schedule) const;
void setBlockReward(u256 const& _newBlockReward);
void setBlockRewardOvewrite(bool _ovewrite) { m_allowRewardOverwrite = _ovewrite; }
u256 maximumExtraDataSize = 1024;
u256 accountStartNonce = 0;
bool tieBreakingGas = true;
Expand Down
2 changes: 2 additions & 0 deletions libethcore/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ DEV_SIMPLE_EXCEPTION(InvalidTransactionReceiptFormat);
DEV_SIMPLE_EXCEPTION(TransactionReceiptVersionError);
DEV_SIMPLE_EXCEPTION(BlockNotFound);
DEV_SIMPLE_EXCEPTION(UnknownParent);
DEV_SIMPLE_EXCEPTION(MissingField);
DEV_SIMPLE_EXCEPTION(UnknownConfig);
DEV_SIMPLE_EXCEPTION(AddressAlreadyUsed);

DEV_SIMPLE_EXCEPTION(DatabaseAlreadyOpen);
Expand Down
69 changes: 69 additions & 0 deletions libethereum/ChainParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <libethcore/SealEngine.h>
#include <libethcore/BlockHeader.h>
#include <libethcore/Precompiled.h>
#include <libethashseal/GenesisInfo.h>
#include "GenesisInfo.h"
#include "State.h"
#include "Account.h"
Expand Down Expand Up @@ -90,6 +91,9 @@ set<string> const c_knownParamNames = {c_minGasLimit, c_maxGasLimit, c_gasLimitB
c_durationLimit, c_chainID, c_networkID, c_allowFutureBlocks};
} // anonymous namespace

/// parse simple genesis format into cpp genesis format
js::mObject prepareFromGeneralConfig(js::mObject const& _config);

ChainParams ChainParams::loadConfig(
string const& _json, h256 const& _stateRoot, const boost::filesystem::path& _configPath) const
{
Expand All @@ -98,6 +102,13 @@ ChainParams ChainParams::loadConfig(
json_spirit::read_string_or_throw(_json, val);
js::mObject obj = val.get_obj();

if (obj.count("version") && u256(obj.at("version").get_str()) == 1)
{
obj = prepareFromGeneralConfig(obj);
cp.setBlockRewardOvewrite(
false); // do not allow hardcode block reward overwrite (Byzantium)
}

validateFieldNames(obj, c_knownChainConfigFields);

cp.sealEngineName = obj[c_sealEngine].get_str();
Expand Down Expand Up @@ -281,3 +292,61 @@ bytes ChainParams::genesisBlock() const
block.appendRaw(RLPEmptyList);
return block.out();
}

void checkFieldExist(js::mObject const& _config, string const& _field)
{
if (!_config.count(_field))
BOOST_THROW_EXCEPTION(
MissingField() << errinfo_comment("Missing field '" + _field + "' in genesis config"));
}

js::mObject prepareFromGeneralConfig(js::mObject const& _config)
{
checkFieldExist(_config, c_params);
checkFieldExist(_config, "state");
checkFieldExist(_config, c_genesis);
js::mObject params = _config.at(c_params).get_obj();
checkFieldExist(params, "forkRules");
string forkRules = params.at("forkRules").get_str();
Network rules;
if (forkRules == "Frontier")
rules = Network::FrontierTest;
else if (forkRules == "Homestead")
rules = Network::HomesteadTest;
else if (forkRules == "EIP150")
rules = Network::EIP150Test;
else if (forkRules == "EIP158")
rules = Network::EIP158Test;
else if (forkRules == "Byzantium")
rules = Network::ByzantiumTest;
else if (forkRules == "Constantinople")
rules = Network::ConstantinopleTest;
else
BOOST_THROW_EXCEPTION(
UnknownConfig() << errinfo_comment("Unrecognized network config: '" + forkRules + "'"));
js::mValue v;
js::read_string(genesisInfo(rules), v);
js::mObject& obj = v.get_obj();

checkFieldExist(params, c_blockReward);
js::mObject& originalParams = obj[c_params].get_obj();
originalParams[c_blockReward] = params[c_blockReward];

// overwrite with general config
obj[c_sealEngine] = params.at("miningMethod");

// copy account configuration
for (auto const account : _config.at("state").get_obj())
obj[c_accounts].get_obj().emplace(account);

// overwrite genesis configuration
js::mObject& cppGenesis = obj[c_genesis].get_obj();
js::mObject const& genGenesis = _config.at(c_genesis).get_obj();

// Overwrite genesis fields
// Minimum fields from state tests
cppGenesis[c_author] = genGenesis.at("coinbase");
cppGenesis[c_gasLimit] = genGenesis.at(c_gasLimit);
cppGenesis[c_timestamp] = genGenesis.at(c_timestamp);
return v.get_obj();
}