Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fill blockchain invalid blocks WIP #71

Merged
merged 3 commits into from
Dec 23, 2019
Merged
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
16 changes: 11 additions & 5 deletions retesteth/RPCSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct sessionInfo
};

void closeSession(const string& _threadID);
string const RPCSession::c_errorMiningString = "remote test_mineBlocks = false";

std::mutex g_socketMapMutex;
static std::map<std::string, sessionInfo> socketMap;
Expand Down Expand Up @@ -271,10 +272,11 @@ string RPCSession::eth_getCode(string const& _address, string const& _blockNumbe
return rpcCall("eth_getCode", { quote(_address), quote(_blockNumber) }).asString();
}

test::scheme_block RPCSession::eth_getBlockByNumber(string const& _blockNumber, bool _fullObjects)
test::scheme_block RPCSession::eth_getBlockByNumber(
BlockNumber const& _blockNumber, bool _fullObjects)
{
return test::scheme_block(
rpcCall("eth_getBlockByNumber", {quote(_blockNumber), _fullObjects ? "true" : "false"}));
return test::scheme_block(rpcCall("eth_getBlockByNumber",
{quote(_blockNumber.getBlockNumberAsString()), _fullObjects ? "true" : "false"}));
}

test::scheme_transactionReceipt RPCSession::eth_getTransactionReceipt(string const& _transactionHash)
Expand Down Expand Up @@ -369,12 +371,16 @@ void RPCSession::test_rewindToBlock(size_t _blockNr)
ETH_FAIL_REQUIRE_MESSAGE(rpcCall("test_rewindToBlock", { to_string(_blockNr) }) == true, "remote test_rewintToBlock = false");
}

string RPCSession::test_mineBlocks(int _number)
string RPCSession::test_mineBlocks(int _number, bool _canFail)
{
DataObject blockNumber = rpcCall("eth_blockNumber");
u256 startBlock = (blockNumber.type() == DataType::String) ? u256(blockNumber.asString()) :
blockNumber.asInt();
ETH_ERROR_REQUIRE_MESSAGE(rpcCall("test_mineBlocks", { to_string(_number) }, true) == true, "remote test_mineBlocks = false");

if (!_canFail)
ETH_ERROR_REQUIRE_MESSAGE(rpcCall("test_mineBlocks", { to_string(_number) }, true) == true, c_errorMiningString);
else
return c_errorMiningString;

// We auto-calibrate the time it takes to mine the transaction.
// It would be better to go without polling, but that would probably need a change to the test
Expand Down
15 changes: 12 additions & 3 deletions retesteth/RPCSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class RPCSession: public boost::noncopyable
test::scheme_transactionReceipt eth_getTransactionReceipt(std::string const& _transactionHash);
int eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber);
std::string eth_getCode(std::string const& _address, std::string const& _blockNumber);
test::scheme_block eth_getBlockByNumber(std::string const& _blockNumber, bool _fullObjects);
std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
test::scheme_block eth_getBlockByNumber(BlockNumber const& _blockNumber, bool _fullObjects);
std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber);
std::string eth_getStorageRoot(std::string const& _address, std::string const& _blockNumber);
std::string eth_getStorageAt(std::string const& _address, std::string const& _position, std::string const& _blockNumber);

Expand All @@ -52,7 +52,7 @@ class RPCSession: public boost::noncopyable
void test_setChainParams(std::string const& _config);
void test_rewindToBlock(size_t _blockNr);
void test_modifyTimestamp(unsigned long long _timestamp);
string test_mineBlocks(int _number);
string test_mineBlocks(int _number, bool _canFail = false);
void test_importRawBlock(std::string const& _blockRLP);

std::string sendRawRequest(std::string const& _request);
Expand All @@ -65,9 +65,18 @@ class RPCSession: public boost::noncopyable

/// Returns empty string if last RPC call had no errors, error string if there was an error
DataObject const& getLastRPCError() const { return m_lastRPCError; }
string const& getLastRPCErrorMessage() const
{
if (m_lastRPCError.type() != DataType::Null)
return m_lastRPCError.atKey("error").asString();
static const string empty;
return empty;
}
Socket::SocketType getSocketType() const { return m_socket.type(); }
std::string const& getSocketPath() const { return m_socket.path(); }

static string const c_errorMiningString;

private:
explicit RPCSession(Socket::SocketType _type, std::string const& _path);
static void runNewInstanceOfAClient(std::string const& _threadID, ClientConfig const& _config);
Expand Down
2 changes: 1 addition & 1 deletion retesteth/TestSuite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ void TestSuite::executeTest(string const& _testFolder, fs::path const& _testFile
}
catch (std::exception const& _ex)
{
ETH_STDERROR_MESSAGE("ERROR OCCURED FILLING TESTS: " + string(_ex.what()));
ETH_MARK_ERROR("ERROR OCCURED FILLING TESTS: " + string(_ex.what()));
RPCSession::sessionEnd(TestOutputHelper::getThreadID(), RPCSession::SessionStatus::HasFinished);
wasErrors = true;
}
Expand Down
90 changes: 85 additions & 5 deletions retesteth/configs/ClientConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,26 @@ string default_config = R"({
"EIP158ToByzantiumAt5",
"HomesteadToDaoAt5",
"ByzantiumToConstantinopleFixAt5"
]
],
"exceptions" : {
"ExtraDataTooBig" : "extra-data too long",
"InvalidDifficulty" : "invalid difficulty",
"InvalidGasLimit" : "invalid gasLimit:",
"TooMuchGasUsed" : "invalid gasUsed:",
"InvalidNumber" : "invalid block number",
"InvalidTimestamp" : "timestamp equals parent's",
"InvalidLogBloom" : "invalid bloom (remote:",
"InvalidStateRoot" : "invalid merkle root (remote:",
"InvalidGasLimit2" : "invalid gas limit:",
"InvalidGasUsed" : "invalid gas used (remote:",
"InvalidBlockMixHash" : "invalid mix digest",
"InvalidBlockNonce" : "",
"UnknownParent" : "unknown ancestor",
"UnknownParent2" : "unknown ancestor",
"InvalidReceiptsStateRoot" : "invalid receipt root hash (remote:",
"InvalidTransactionsRoot" : "transaction root hash mismatch: have",
"InvalidUnclesHash" : "uncle root hash mismatch: have"
}
})";

string besu_config = R"({
Expand All @@ -68,7 +87,11 @@ string besu_config = R"({
"EIP158ToByzantiumAt5",
"HomesteadToDaoAt5",
"ByzantiumToConstantinopleFixAt5"
]
],
"exceptions" : {
"ExtraDataTooBig" : "extra-data too long",
"InvalidDifficulty" : "invalid difficulty"
}
})";

string alethTCP_config = R"({
Expand All @@ -94,7 +117,26 @@ string alethTCP_config = R"({
"EIP158ToByzantiumAt5",
"HomesteadToDaoAt5",
"ByzantiumToConstantinopleFixAt5"
]
],
"exceptions" : {
"ExtraDataTooBig" : "ExtraData too big",
"InvalidDifficulty" : "Invalid Difficulty",
"InvalidGasLimit" : "Invalid Block GasLimit",
"TooMuchGasUsed" : "Too much gas used",
"InvalidNumber" : "Invalid number",
"InvalidTimestamp" : "Invalid timestamp",
"InvalidLogBloom" : "Invalid log bloom",
"InvalidStateRoot" : "Invalid state root",
"InvalidGasLimit2" : "Invalid Block GasLimit",
"InvalidGasUsed" : "Invalid gas used",
"InvalidBlockMixHash" : "Invalid block nonce",
"InvalidBlockNonce" : "Invalid block nonce"
"UnknownParent" : "UnknownParent",
"UnknownParent2" : "Invalid parent hash",
"InvalidReceiptsStateRoot" : "Invalid receipts state root",
"InvalidTransactionsRoot" : "Invalid transactions root",
"InvalidUnclesHash" : "Invalid uncles hash"
}
})";

string alethIPCDebug_config = R"({
Expand All @@ -117,7 +159,26 @@ string alethIPCDebug_config = R"({
"EIP158ToByzantiumAt5",
"HomesteadToDaoAt5",
"ByzantiumToConstantinopleFixAt5"
]
],
"exceptions" : {
"ExtraDataTooBig" : "ExtraData too big",
"InvalidDifficulty" : "Invalid Difficulty",
"InvalidGasLimit" : "Invalid Block GasLimit",
"TooMuchGasUsed" : "Too much gas used",
"InvalidNumber" : "Invalid number",
"InvalidTimestamp" : "Invalid timestamp",
"InvalidLogBloom" : "Invalid log bloom",
"InvalidStateRoot" : "Invalid state root",
"InvalidGasLimit2" : "Invalid Block GasLimit",
"InvalidGasUsed" : "Invalid gas used",
"InvalidBlockMixHash" : "Invalid block nonce",
"InvalidBlockNonce" : "Invalid block nonce"
"UnknownParent" : "UnknownParent",
"UnknownParent2" : "Invalid parent hash",
"InvalidReceiptsStateRoot" : "Invalid receipts state root",
"InvalidTransactionsRoot" : "Invalid transactions root",
"InvalidUnclesHash" : "Invalid uncles hash"
}
})";


Expand All @@ -141,7 +202,26 @@ string aleth_config = R"({
"EIP158ToByzantiumAt5",
"HomesteadToDaoAt5",
"ByzantiumToConstantinopleFixAt5"
]
],
"exceptions" : {
"ExtraDataTooBig" : "ExtraData too big",
"InvalidDifficulty" : "Invalid Difficulty",
"InvalidGasLimit" : "Invalid Block GasLimit",
"TooMuchGasUsed" : "Too much gas used",
"InvalidNumber" : "Invalid number",
"InvalidTimestamp" : "Invalid timestamp",
"InvalidLogBloom" : "Invalid log bloom",
"InvalidStateRoot" : "Invalid state root",
"InvalidGasLimit2" : "Invalid Block GasLimit",
"InvalidGasUsed" : "Invalid gas used",
"InvalidBlockMixHash" : "Invalid block nonce",
"InvalidBlockNonce" : "Invalid block nonce"
"UnknownParent" : "UnknownParent",
"UnknownParent2" : "Invalid parent hash",
"InvalidReceiptsStateRoot" : "Invalid receipts state root",
"InvalidTransactionsRoot" : "Invalid transactions root",
"InvalidUnclesHash" : "Invalid uncles hash"
}
})";

string aleth_config_sh = R"(
Expand Down
22 changes: 16 additions & 6 deletions retesteth/configs/ClientConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,18 @@ class ClientConfig : public object
{
m_configFilePath = _clientConfigPath;
requireJsonFields(_obj, "ClientConfig (" + m_configFilePath.string() + ")",
{
{"name", {DataType::String}},
{"socketType", {DataType::String}},
{{"name", {DataType::String}}, {"socketType", {DataType::String}},
{"socketAddress", {DataType::String, DataType::Array}},
{"forks", {DataType::Array}},
{"additionalForks", {DataType::Array}},
},
{"forks", {DataType::Array}}, {"additionalForks", {DataType::Array}},
{"exceptions", {DataType::Object}}},
true);

for (auto const& name : m_data.atKey("forks").getSubObjects())
m_networks.push_back(name.asString());
for (auto const& name : m_data.atKey("additionalForks").getSubObjects())
m_additional_networks.push_back(name.asString());
for (auto const& except : m_data.atKey("exceptions").getSubObjects())
m_exceptions[except.getKey()] = except.asString();

std::string const& socketTypeStr = _obj.atKey("socketType").asString();
if (socketTypeStr == "ipc")
Expand Down Expand Up @@ -96,6 +95,16 @@ class ClientConfig : public object
"\"path to .ipc socket\"], [tcp, \"address:port\"]");
}

std::string const& getExceptionString(string const& _exceptionName) const
{
if (m_exceptions.count(_exceptionName))
return m_exceptions.at(_exceptionName);
ETH_ERROR_MESSAGE("Config::getExceptionString '" + _exceptionName +
"' not found in client config `exceptions` section! (" +
getConfigFilePath().c_str() + ")");
static string const notfound = "";
return notfound;
}
fs::path const& getConfigFilePath() const { return m_configFilePath; }
fs::path const& getCorrectMiningRewardConfigFilePath() const { return m_configCorrectMiningRewardFilePath; }
fs::path const& getShellPath() const { return m_shellPath; }
Expand Down Expand Up @@ -138,6 +147,7 @@ class ClientConfig : public object
std::vector<string> m_networks; ///< Allowed forks as network name
std::vector<string> m_additional_networks; ///< Allowed forks as network name
std::map<string, DataObject> m_genesisTemplate; ///< Template For test_setChainParams
std::map<string, string> m_exceptions; ///< Exception Translation
DataObject m_correctReward; ///< Correct mining reward info for StateTests->BlockchainTests
};
} // namespace test
45 changes: 19 additions & 26 deletions retesteth/ethObjects/blockchainTest/scheme_blockchainTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ using namespace test;

scheme_blockchainTestBase::fieldChecker::fieldChecker(DataObject const& _test)
{
requireJsonFields(_test, "blockchainTest " + _test.getKey(),
requireJsonFields(_test, "blockchainTestBase " + _test.getKey(),
{{"_info", {{DataType::Object}, jsonField::Optional}},
{"blocks", {{DataType::Array}, jsonField::Required}},
{"expect", {{DataType::Array}, jsonField::Optional}},
Expand All @@ -17,13 +17,12 @@ scheme_blockchainTestBase::fieldChecker::fieldChecker(DataObject const& _test)
{"postState", {{DataType::Object}, jsonField::Optional}},
{"postStateHash", {{DataType::String}, jsonField::Optional}},
{"pre", {{DataType::Object}, jsonField::Required}},
{"sealEngine", {{DataType::String}, jsonField::Optional}}
});
{"sealEngine", {{DataType::String}, jsonField::Optional}}});
}

scheme_blockchainTest::fieldChecker::fieldChecker(DataObject const& _test)
{
requireJsonFields(_test, "blockchainTest " + _test.getKey(),
requireJsonFields(_test, "blockchainTest" + _test.getKey(),
{{"_info", {{DataType::Object}, jsonField::Required}},
{"blocks", {{DataType::Array}, jsonField::Required}},
{"genesisBlockHeader", {{DataType::Object}, jsonField::Required}},
Expand All @@ -33,8 +32,7 @@ scheme_blockchainTest::fieldChecker::fieldChecker(DataObject const& _test)
{"postState", {{DataType::Object}, jsonField::Optional}},
{"postStateHash", {{DataType::String}, jsonField::Optional}},
{"pre", {{DataType::Object}, jsonField::Required}},
{"sealEngine", {{DataType::String}, jsonField::Optional}}
});
{"sealEngine", {{DataType::String}, jsonField::Optional}}});
}

scheme_blockchainTestBase::scheme_blockchainTestBase(DataObject const& _test)
Expand All @@ -59,48 +57,39 @@ scheme_blockchainTest::scheme_blockchainTest(DataObject const& _test)
// Valid block json description
if (blockSection.count("blockHeader"))
{
requireJsonFields(blockSection, "blockchainTest " + _test.getKey(),
{ {"blockHeader", {{DataType::Object}, jsonField::Required}},
requireJsonFields(blockSection, "blockchainTestValidblock " + _test.getKey(),
{{"blockHeader", {{DataType::Object}, jsonField::Required}},
{"rlp", {{DataType::String}, jsonField::Required}},
{"transactions", {{DataType::Array}, jsonField::Required}},
{"uncleHeaders", {{DataType::Array}, jsonField::Optional}},
{"blocknumber", {{DataType::String}, jsonField::Optional}},
{"chainname", {{DataType::String}, jsonField::Optional}},
{"chainnetwork", {{DataType::String}, jsonField::Optional}}
});
{"chainnetwork", {{DataType::String}, jsonField::Optional}}});
scheme_blockHeader(blockSection.atKey("blockHeader"));
for (auto const& trSection: blockSection.atKey("transactions").getSubObjects())
m_transactions.push_back(scheme_transaction(trSection));
}
else
{
// Invalid block json description
requireJsonFields(blockSection, "blockchainTest " + _test.getKey(),
{ {"blockHeader", {{DataType::Object}, jsonField::Optional}},
requireJsonFields(blockSection, "blockchainTestInvalidblock " + _test.getKey(),
{{"blockHeader", {{DataType::Object}, jsonField::Optional}},
{"rlp", {{DataType::String}, jsonField::Required}},
{"transactions", {{DataType::Array}, jsonField::Optional}},
{"uncleHeaders", {{DataType::Array}, jsonField::Optional}},
{"blocknumber", {{DataType::String}, jsonField::Optional}},
{"chainname", {{DataType::String}, jsonField::Optional}},
{"chainnetwork", {{DataType::String}, jsonField::Optional}},
{"expectExceptionByzantium", {{DataType::String}, jsonField::Optional}},
{"expectExceptionConstantinople", {{DataType::String}, jsonField::Optional}},
{"expectExceptionConstantinopleFix", {{DataType::String}, jsonField::Optional}},
{"expectExceptionEIP150", {{DataType::String}, jsonField::Optional}},
{"expectExceptionEIP158", {{DataType::String}, jsonField::Optional}},
{"expectExceptionFrontier", {{DataType::String}, jsonField::Optional}},
{"expectExceptionHomestead", {{DataType::String}, jsonField::Optional}},
{"expectExceptionIstanbul", {{DataType::String}, jsonField::Optional}},
{"expectExceptionALL", {{DataType::String}, jsonField::Optional}}
});
{"expectException", {{DataType::String}, jsonField::Optional}},
{"chainnetwork", {{DataType::String}, jsonField::Optional}}});
}

m_blockRLPs.push_back(blockSection.atKey("rlp").asString());
}
makeAllFieldsHex(m_data);
}

DataObject scheme_blockchainTestBase::getGenesisForRPC(string const& _network) const
DataObject scheme_blockchainTestBase::getGenesisForRPC(
string const& _network, string const& _sealEngine) const
{
string net = (_network.empty() ? getData().atKey("network").asString() : _network);
DataObject genesis = prepareGenesisParams(net, m_sealEngine);
Expand All @@ -109,10 +98,14 @@ DataObject scheme_blockchainTestBase::getGenesisForRPC(string const& _network) c
data["author"] = m_genesisHeader.getData().atKey("coinbase");
data["difficulty"] = m_genesisHeader.getData().atKey("difficulty");
data["gasLimit"] = m_genesisHeader.getData().atKey("gasLimit");
data["nonce"] = m_genesisHeader.getData().atKey("nonce");
data["nonce"] = (_sealEngine == "NoProof") ? DataObject("0x0000000000000000") :
m_genesisHeader.getData().atKey("nonce");
data["extraData"] = m_genesisHeader.getData().atKey("extraData");
data["timestamp"] = m_genesisHeader.getData().atKey("timestamp");
data["mixHash"] = m_genesisHeader.getData().atKey("mixHash");
data["mixHash"] =
(_sealEngine == "NoProof") ?
DataObject("0x0000000000000000000000000000000000000000000000000000000000000000") :
m_genesisHeader.getData().atKey("mixHash");
object::makeAllFieldsHex(data);

genesis["genesis"] = data;
Expand Down
3 changes: 2 additions & 1 deletion retesteth/ethObjects/blockchainTest/scheme_blockchainTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class scheme_blockchainTestBase : public object
{
public:
scheme_blockchainTestBase(DataObject const& _test);
DataObject getGenesisForRPC(string const& _network = string()) const;
DataObject getGenesisForRPC(
string const& _network = string(), string const& _sealEngine = "NoProof") const;
scheme_state const& getPre() const { return m_pre; };

private:
Expand Down
Loading