diff --git a/libdevcore/JsonUtils.cpp b/libdevcore/JsonUtils.cpp index 0ff9e8707eb..692b73a5fb7 100644 --- a/libdevcore/JsonUtils.cpp +++ b/libdevcore/JsonUtils.cpp @@ -15,11 +15,12 @@ along with cpp-ethereum. If not, see . */ -#include #include +#include +#include +#include #include #include -#include void dev::validateFieldNames(json_spirit::mObject const& _obj, std::set const& _allowedFields) { @@ -56,7 +57,7 @@ std::string dev::jsonTypeAsString(json_spirit::Value_type _type) } void dev::requireJsonFields(json_spirit::mObject const& _o, std::string const& _config, - std::map const& _validationMap) + std::map const& _validationMap) { // check for unexpected fiedls for (auto const& field : _o) @@ -74,40 +75,37 @@ void dev::requireJsonFields(json_spirit::mObject const& _o, std::string const& _ // check field types with validation map for (auto const vmap : _validationMap) { + auto const& expectedFieldName = vmap.first; + auto const& expectedFieldPresence = vmap.second.second; // check that all required fields are in the object - if (!_o.count(vmap.first)) + if (!_o.count(expectedFieldName)) { - if (vmap.second.second == jsonField::Required) + if (expectedFieldPresence == JsonFieldPresence::Required) { std::string const comment = - "Expected field '" + vmap.first + "' not found in config: " + _config; + "Expected field '" + expectedFieldName + "' not found in config: " + _config; std::cerr << comment << "\n" << json_spirit::write_string((json_spirit::mValue)_o, true) << "\n"; BOOST_THROW_EXCEPTION(MissingField() << errinfo_comment(comment)); } - else if (vmap.second.second == jsonField::Optional) + else if (expectedFieldPresence == JsonFieldPresence::Optional) continue; } // check that field type is one of allowed field types - bool matched = false; - for (auto const& type : vmap.second.first) - { - if (_o.at(vmap.first).type() == type) - matched = true; - } + auto const& expectedFieldTypes = vmap.second.first; + bool matched = expectedFieldTypes.count(_o.at(expectedFieldName).type()); if (matched == false) { - std::string sTypes; - for (auto const& type : vmap.second.first) - { - if (sTypes.size()) - sTypes += ", or "; - sTypes += jsonTypeAsString(type); - } - std::string const comment = - "Field '" + vmap.first + "' expected to be " + sTypes + ", but set to " + - jsonTypeAsString(_o.at(vmap.first).type()) + " in " + _config; + std::vector types; + for (auto const& type : expectedFieldTypes) + types.push_back(jsonTypeAsString(type)); + std::string sTypes = boost::algorithm::join(types, " or "); + + std::string const comment = "Field '" + expectedFieldName + "' is expected to be " + + sTypes + ", but is set to " + + jsonTypeAsString(_o.at(expectedFieldName).type()) + " in " + + _config; std::cerr << comment << "\n" << json_spirit::write_string((json_spirit::mValue)_o, true) << "\n"; BOOST_THROW_EXCEPTION(WrongFieldType() << errinfo_comment(comment)); diff --git a/libdevcore/JsonUtils.h b/libdevcore/JsonUtils.h index 9f2db0b6359..26a9da8039a 100644 --- a/libdevcore/JsonUtils.h +++ b/libdevcore/JsonUtils.h @@ -28,21 +28,21 @@ void validateFieldNames(json_spirit::mObject const& _obj, std::set // Converts json value type to string std::string jsonTypeAsString(json_spirit::Value_type _type); -enum jsonField +enum class JsonFieldPresence { Required, Optional }; -using jsonTypeSet = std::set; -using jsonType = std::pair; -//! Check the json object with validation map that reuires certain field of certain type to be -//! present in json -/*! - \param _o a json object to check - \param _configName a string with json object name. Will apper in error message. - \param _validationMap a map with json objects that would be checked. "objName" -> {js::str_type, +using JsonTypeSet = std::set; +using JsonFieldOptions = std::pair; +/// Check the json object with validation map that reuires certain field of certain type to be +/// present in json +/** + @param _o a json object to check + @param _configName a string with json object name. Will apper in error message. + @param _validationMap a map with json objects that would be checked. "objName" -> {js::str_type, jsonField::Required} */ void requireJsonFields(json_spirit::mObject const& _o, std::string const& _configName, - std::map const& _validationMap); + std::map const& _validationMap); } diff --git a/libethereum/Account.cpp b/libethereum/Account.cpp index 4b80144370d..76b1c3fe419 100644 --- a/libethereum/Account.cpp +++ b/libethereum/Account.cpp @@ -54,22 +54,22 @@ uint64_t toUnsigned(js::mValue const& _v) } } -PrecompiledContract createPrecompiledContract(js::mObject& _precompiled) +PrecompiledContract createPrecompiledContract(js::mObject const& _precompiled) { - auto n = _precompiled["name"].get_str(); - try + auto n = _precompiled.at("name").get_str(); + try { u256 startingBlock = 0; if (_precompiled.count("startingBlock")) - startingBlock = u256(_precompiled["startingBlock"].get_str()); + startingBlock = u256(_precompiled.at("startingBlock").get_str()); - if (!_precompiled.count("linear")) + if (!_precompiled.count("linear")) return PrecompiledContract(PrecompiledRegistrar::pricer(n), PrecompiledRegistrar::executor(n), startingBlock); - auto l = _precompiled["linear"].get_obj(); - unsigned base = toUnsigned(l["base"]); - unsigned word = toUnsigned(l["word"]); - return PrecompiledContract(base, word, PrecompiledRegistrar::executor(n), startingBlock); + auto const& l = _precompiled.at("linear").get_obj(); + unsigned base = toUnsigned(l.at("base")); + unsigned word = toUnsigned(l.at("word")); + return PrecompiledContract(base, word, PrecompiledRegistrar::executor(n), startingBlock); } catch (PricerNotFound const&) { @@ -99,35 +99,36 @@ AccountMap dev::eth::jsonToAccountMap(std::string const& _json, u256 const& _def js::mValue val; json_spirit::read_string_or_throw(_json, val); - js::mObject o = val.get_obj(); - for (auto const& account: o) - { + + for (auto const& account : val.get_obj()) + { Address a(fromHex(account.first)); // FIXME: Do not copy every account object. - auto o = account.second.get_obj(); - validateAccountMapObj(o); + auto const& accountMapJson = account.second.get_obj(); + validateAccountMapObj(accountMapJson); - bool haveBalance = (o.count(c_wei) || o.count(c_finney) || o.count(c_balance)); - bool haveNonce = o.count(c_nonce); - bool haveCode = o.count(c_code) || o.count(c_codeFromFile); - bool haveStorage = o.count(c_storage); - bool shouldNotExists = o.count(c_shouldnotexist); + bool haveBalance = (accountMapJson.count(c_wei) || accountMapJson.count(c_finney) || + accountMapJson.count(c_balance)); + bool haveNonce = accountMapJson.count(c_nonce); + bool haveCode = accountMapJson.count(c_code) || accountMapJson.count(c_codeFromFile); + bool haveStorage = accountMapJson.count(c_storage); + bool shouldNotExists = accountMapJson.count(c_shouldnotexist); - if (haveStorage || haveCode || haveNonce || haveBalance) + if (haveStorage || haveCode || haveNonce || haveBalance) { u256 balance = 0; - if (o.count(c_wei)) - balance = u256Safe(o[c_wei].get_str()); - else if (o.count(c_finney)) - balance = u256Safe(o[c_finney].get_str()) * finney; - else if (o.count(c_balance)) - balance = u256Safe(o[c_balance].get_str()); + if (accountMapJson.count(c_wei)) + balance = u256Safe(accountMapJson.at(c_wei).get_str()); + else if (accountMapJson.count(c_finney)) + balance = u256Safe(accountMapJson.at(c_finney).get_str()) * finney; + else if (accountMapJson.count(c_balance)) + balance = u256Safe(accountMapJson.at(c_balance).get_str()); - u256 nonce = haveNonce ? u256Safe(o[c_nonce].get_str()) : _defaultNonce; + u256 nonce = haveNonce ? u256Safe(accountMapJson.at(c_nonce).get_str()) : _defaultNonce; ret[a] = Account(nonce, balance); - auto codeIt = o.find(c_code); - if (codeIt != o.end()) + auto codeIt = accountMapJson.find(c_code); + if (codeIt != accountMapJson.end()) { auto& codeObj = codeIt->second; if (codeObj.type() == json_spirit::str_type) @@ -144,8 +145,8 @@ AccountMap dev::eth::jsonToAccountMap(std::string const& _json, u256 const& _def << "! Code field needs to be a string"; } - auto codePathIt = o.find(c_codeFromFile); - if (codePathIt != o.end()) + auto codePathIt = accountMapJson.find(c_codeFromFile); + if (codePathIt != accountMapJson.end()) { auto& codePathObj = codePathIt->second; if (codePathObj.type() == json_spirit::str_type) @@ -166,8 +167,8 @@ AccountMap dev::eth::jsonToAccountMap(std::string const& _json, u256 const& _def if (haveStorage) - for (pair const& j: o[c_storage].get_obj()) - ret[a].setStorage(u256(j.first), u256(j.second.get_str())); + for (pair const& j : accountMapJson.at(c_storage).get_obj()) + ret[a].setStorage(u256(j.first), u256(j.second.get_str())); } if (o_mask) @@ -177,10 +178,10 @@ AccountMap dev::eth::jsonToAccountMap(std::string const& _json, u256 const& _def ret[a] = Account(0, 0); } - if (o_precompiled && o.count(c_precompiled)) - { - js::mObject p = o[c_precompiled].get_obj(); - o_precompiled->insert(make_pair(a, createPrecompiledContract(p))); + if (o_precompiled && accountMapJson.count(c_precompiled)) + { + js::mObject p = accountMapJson.at(c_precompiled).get_obj(); + o_precompiled->insert(make_pair(a, createPrecompiledContract(p))); } } diff --git a/libethereum/ChainParams.cpp b/libethereum/ChainParams.cpp index 2e6580d1dcf..7a0987d1eee 100644 --- a/libethereum/ChainParams.cpp +++ b/libethereum/ChainParams.cpp @@ -20,17 +20,18 @@ */ #include "ChainParams.h" +#include "Account.h" +#include "GenesisInfo.h" +#include "State.h" +#include "ValidationSchemes.h" #include +#include #include #include -#include -#include #include #include -#include "ValidationSchemes.h" -#include "GenesisInfo.h" -#include "State.h" -#include "Account.h" +#include + using namespace std; using namespace dev; using namespace eth; @@ -58,8 +59,8 @@ ChainParams ChainParams::loadConfig( { ChainParams cp(*this); js::mValue val; - json_spirit::read_string_or_throw(_json, val); - js::mObject obj = val.get_obj(); + js::read_string_or_throw(_json, val); + js::mObject obj = val.get_obj(); validateConfigJson(obj); cp.sealEngineName = obj[c_sealEngine].get_str(); @@ -96,16 +97,16 @@ ChainParams ChainParams::loadConfig( cp.allowFutureBlocks = params.count(c_allowFutureBlocks); // genesis - string genesisStr = json_spirit::write_string(obj[c_genesis], false); - cp = cp.loadGenesis(genesisStr, _stateRoot); + string genesisStr = js::write_string(obj[c_genesis], false); + cp = cp.loadGenesis(genesisStr, _stateRoot); // genesis state - string genesisStateStr = json_spirit::write_string(obj[c_accounts], false); + string genesisStateStr = js::write_string(obj[c_accounts], false); cp.genesisState = jsonToAccountMap( genesisStateStr, cp.accountStartNonce, nullptr, &cp.precompiled, _configPath); // Strict account check - json_spirit::read_string_or_throw(genesisStateStr, val); + js::read_string_or_throw(genesisStateStr, val); for (auto const& account: val.get_obj()) validateAccountObj(account.second.get_obj()); @@ -119,8 +120,8 @@ ChainParams ChainParams::loadGenesis(string const& _json, h256 const& _stateRoot ChainParams cp(*this); js::mValue val; - json_spirit::read_string(_json, val); - js::mObject genesis = val.get_obj(); + js::read_string(_json, val); + js::mObject genesis = val.get_obj(); cp.parentHash = h256(0); // required by the YP cp.author = genesis.count(c_coinbase) ? h160(genesis[c_coinbase].get_str()) : h160(genesis[c_author].get_str()); diff --git a/libethereum/ValidationSchemes.cpp b/libethereum/ValidationSchemes.cpp index 1ede262e0a9..ec1c286c2cb 100644 --- a/libethereum/ValidationSchemes.cpp +++ b/libethereum/ValidationSchemes.cpp @@ -14,18 +14,19 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -#include -#include #include "ValidationSchemes.h" +#include +#include using namespace std; -using namespace dev; namespace js = json_spirit; -namespace dev { -namespace eth { -namespace validation { - +namespace dev +{ +namespace eth +{ +namespace validation +{ string const c_sealEngine = "sealEngine"; string const c_params = "params"; string const c_genesis = "genesis"; @@ -73,20 +74,20 @@ string const c_allowFutureBlocks = "allowFutureBlocks"; void validateConfigJson(js::mObject const& _obj) { requireJsonFields(_obj, "ChainParams::loadConfig", - {{c_sealEngine, {{json_spirit::str_type}, jsonField::Required}}, - {c_params, {{json_spirit::obj_type}, jsonField::Required}}, - {c_genesis, {{json_spirit::obj_type}, jsonField::Required}}, - {c_accounts, {{json_spirit::obj_type}, jsonField::Required}}}); + {{c_sealEngine, {{js::str_type}, JsonFieldPresence::Required}}, + {c_params, {{js::obj_type}, JsonFieldPresence::Required}}, + {c_genesis, {{js::obj_type}, JsonFieldPresence::Required}}, + {c_accounts, {{js::obj_type}, JsonFieldPresence::Required}}}); requireJsonFields(_obj.at(c_genesis).get_obj(), "ChainParams::loadConfig::genesis", - {{c_author, {{json_spirit::str_type}, jsonField::Required}}, - {c_nonce, {{json_spirit::str_type}, jsonField::Required}}, - {c_gasLimit, {{json_spirit::str_type}, jsonField::Required}}, - {c_timestamp, {{json_spirit::str_type}, jsonField::Required}}, - {c_difficulty, {{json_spirit::str_type}, jsonField::Required}}, - {c_extraData, {{json_spirit::str_type}, jsonField::Required}}, - {c_mixHash, {{json_spirit::str_type}, jsonField::Required}}, - {c_parentHash, {{json_spirit::str_type}, jsonField::Optional}}}); + {{c_author, {{js::str_type}, JsonFieldPresence::Required}}, + {c_nonce, {{js::str_type}, JsonFieldPresence::Required}}, + {c_gasLimit, {{js::str_type}, JsonFieldPresence::Required}}, + {c_timestamp, {{js::str_type}, JsonFieldPresence::Required}}, + {c_difficulty, {{js::str_type}, JsonFieldPresence::Required}}, + {c_extraData, {{js::str_type}, JsonFieldPresence::Required}}, + {c_mixHash, {{js::str_type}, JsonFieldPresence::Required}}, + {c_parentHash, {{js::str_type}, JsonFieldPresence::Optional}}}); js::mObject const& accounts = _obj.at(c_accounts).get_obj(); for (auto const& acc : accounts) @@ -97,13 +98,13 @@ void validateAccountMapObj(js::mObject const& _obj) { // A map object with possibly defined fields requireJsonFields(_obj, "validateAccountMapObj", - {{c_storage, {{json_spirit::obj_type}, jsonField::Optional}}, - {c_balance, {{json_spirit::str_type}, jsonField::Optional}}, - {c_nonce, {{json_spirit::str_type}, jsonField::Optional}}, - {c_code, {{json_spirit::str_type}, jsonField::Optional}}, - {c_precompiled, {{json_spirit::obj_type}, jsonField::Optional}}, - {c_shouldnotexist, {{json_spirit::str_type}, jsonField::Optional}}, - {c_wei, {{json_spirit::str_type}, jsonField::Optional}}}); + {{c_storage, {{js::obj_type}, JsonFieldPresence::Optional}}, + {c_balance, {{js::str_type}, JsonFieldPresence::Optional}}, + {c_nonce, {{js::str_type}, JsonFieldPresence::Optional}}, + {c_code, {{js::str_type}, JsonFieldPresence::Optional}}, + {c_precompiled, {{js::obj_type}, JsonFieldPresence::Optional}}, + {c_shouldnotexist, {{js::str_type}, JsonFieldPresence::Optional}}, + {c_wei, {{js::str_type}, JsonFieldPresence::Optional}}}); } void validateAccountObj(js::mObject const& _obj) @@ -112,28 +113,29 @@ void validateAccountObj(js::mObject const& _obj) { // A precompiled contract requireJsonFields(_obj, "validateAccountObj", - {{c_precompiled, {{json_spirit::obj_type}, jsonField::Required}}, - {c_wei, {{json_spirit::str_type}, jsonField::Optional}}}); + {{c_precompiled, {{js::obj_type}, JsonFieldPresence::Required}}, + {c_wei, {{js::str_type}, JsonFieldPresence::Optional}}}); } else if (_obj.size() == 1) { // A genesis account with only balance set if (_obj.count(c_balance)) requireJsonFields(_obj, "validateAccountObj", - {{c_balance, {{json_spirit::str_type}, jsonField::Required}}}); + {{c_balance, {{js::str_type}, JsonFieldPresence::Required}}}); else requireJsonFields(_obj, "validateAccountObj", - {{c_wei, {{json_spirit::str_type}, jsonField::Required}}}); + {{c_wei, {{js::str_type}, JsonFieldPresence::Required}}}); } else { // A standart account with all fields requireJsonFields(_obj, "validateAccountObj", - {{c_code, {{json_spirit::str_type}, jsonField::Required}}, - {c_nonce, {{json_spirit::str_type}, jsonField::Required}}, - {c_storage, {{json_spirit::obj_type}, jsonField::Required}}, - {c_balance, {{json_spirit::str_type}, jsonField::Required}}}); + {{c_code, {{js::str_type}, JsonFieldPresence::Required}}, + {c_nonce, {{js::str_type}, JsonFieldPresence::Required}}, + {c_storage, {{js::obj_type}, JsonFieldPresence::Required}}, + {c_balance, {{js::str_type}, JsonFieldPresence::Required}}}); } } - -}}} +} +} +} diff --git a/libethereum/ValidationSchemes.h b/libethereum/ValidationSchemes.h index 02d26bd3559..07da9eff89c 100644 --- a/libethereum/ValidationSchemes.h +++ b/libethereum/ValidationSchemes.h @@ -14,17 +14,16 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file ValidationSchemes.h - * @date 2018 - */ -#include #include +#include -namespace dev { -namespace eth { -namespace validation { - +namespace dev +{ +namespace eth +{ +namespace validation +{ extern std::string const c_sealEngine; extern std::string const c_params; extern std::string const c_genesis; @@ -77,6 +76,6 @@ void validateAccountObj(json_spirit::mObject const& _o); // Validate account Map json object. Map indicates which fields are set void validateAccountMapObj(json_spirit::mObject const& _o); - - -}}} +} +} +}