From 2a48091ff2cc98cda310912cf3a814f39d725180 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:10:19 +0800 Subject: [PATCH 01/58] add two parsing test cases related to overloaded functions --- test/SolidityParser.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 88b86e638..414ac5256 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -126,6 +126,31 @@ BOOST_AUTO_TEST_CASE(missing_argument_in_named_args) BOOST_CHECK_THROW(parseText(text), ParserError); } +BOOST_AUTO_TEST_CASE(two_exact_functions) +{ + char const* text = R"( + contract test { + function fun(uint a) returns(uint r) { return a; } + function fun(uint a) returns(uint r) { return a; } + } + )"; + // with support of overloaded functions, during parsing, + // we can't determine whether they match exactly, however + // it will throw DeclarationError in following stage. + BOOST_CHECK_NO_THROW(parseText(text)); +} + +BOOST_AUTO_TEST_CASE(overloaded_functions) +{ + char const* text = R"( + contract test { + function fun(uint a) returns(uint r) { return a; } + function fun(uint a, uint b) returns(uint r) { return a + b; } + } + )"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + BOOST_AUTO_TEST_CASE(function_natspec_documentation) { ASTPointer contract; From defd6cfa21b053d2cf24695ffae1c9c886fe57e6 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:11:59 +0800 Subject: [PATCH 02/58] mark an identifier as callable if its next token is '(' --- libsolidity/AST.h | 7 +++++-- libsolidity/Parser.cpp | 7 ++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index eab53153f..b21e505e9 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -1134,8 +1134,8 @@ public: class Identifier: public PrimaryExpression { public: - Identifier(SourceLocation const& _location, ASTPointer const& _name): - PrimaryExpression(_location), m_name(_name) {} + Identifier(SourceLocation const& _location, ASTPointer const& _name, bool _isCallable): + PrimaryExpression(_location), m_name(_name), m_isCallable(_isCallable) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; virtual void checkTypeRequirements() override; @@ -1151,6 +1151,8 @@ public: Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; } ContractDefinition const* getCurrentContract() const { return m_currentContract; } + bool isCallable() const { return m_isCallable; } + private: ASTPointer m_name; @@ -1159,6 +1161,7 @@ private: /// Stores a reference to the current contract. This is needed because types of base contracts /// change depending on the context. ContractDefinition const* m_currentContract = nullptr; + bool m_isCallable = false; }; /** diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 44d111591..cecf772da 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -837,9 +837,14 @@ ASTPointer Parser::parsePrimaryExpression() expression = nodeFactory.createNode(token, getLiteralAndAdvance()); break; case Token::Identifier: + { nodeFactory.markEndPosition(); - expression = nodeFactory.createNode(getLiteralAndAdvance()); + // if the next token is '(', this identifier looks like function call, + // it could be a contract, event etc. + bool isCallable = m_scanner->peekNextToken() == Token::LParen; + expression = nodeFactory.createNode(getLiteralAndAdvance(), isCallable); break; + } case Token::LParen: { m_scanner->next(); From 522f4288490d2955e47a3211b561d4a12fe58414 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:13:11 +0800 Subject: [PATCH 03/58] add end to end test cases related to overloaded functions --- test/SolidityEndToEndTest.cpp | 43 ++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index ae2417052..da5b29ad4 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3170,8 +3170,49 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap) BOOST_CHECK(callContractFunction("m_i()") == encodeArgs(4)); } +BOOST_AUTO_TEST_CASE(overloaded_function_call_resolve_to_first) +{ + char const* sourceCode = R"( + contract test { + function f(uint k) returns(uint d) { return k; } + function f(uint a, uint b) returns(uint d) { return a + b; } + function g() returns(uint d) { return f(3); } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(3)); +} -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_CASE(overloaded_function_call_resolve_to_second) +{ + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) returns(uint d) { return a + b; } + function f(uint k) returns(uint d) { return k; } + function g() returns(uint d) { return f(3, 7); } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(10)); +} + +BOOST_AUTO_TEST_CASE(overloaded_function_call_with_if_else) +{ + char const* sourceCode = R"( + contract test { + function f(uint a, uint b) returns(uint d) { return a + b; } + function f(uint k) returns(uint d) { return k; } + function g(bool flag) returns(uint d) { + if (flag) + return f(3); + else + return f(3, 7); + } + } + )"; + BOOST_CHECK(callContractFunction("g(bool)", true) == encodeArgs(3)); + BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); +} } } From f2da0e249caacba2ed407bfc957d568ad5d82752 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:15:27 +0800 Subject: [PATCH 04/58] enhance DeclarationContainer to use `std::set` so that it can handle overloaded function names --- libsolidity/DeclarationContainer.cpp | 29 +++++++++++++++++++++++----- libsolidity/DeclarationContainer.h | 6 +++--- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/libsolidity/DeclarationContainer.cpp b/libsolidity/DeclarationContainer.cpp index 2594d4281..226b9d680 100644 --- a/libsolidity/DeclarationContainer.cpp +++ b/libsolidity/DeclarationContainer.cpp @@ -22,6 +22,7 @@ #include #include +#include namespace dev { @@ -34,17 +35,35 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, if (name.empty()) return true; - if (!_update && (m_declarations.count(name) || m_invisibleDeclarations.count(name))) - return false; + if (!_update) + { + if (dynamic_cast(&_declaration)) + { + // other declarations must be FunctionDefinition, otherwise clash with other declarations. + for (auto&& declaration: m_declarations[_declaration.getName()]) + if (dynamic_cast(declaration) == nullptr) + return false; + } + else if (m_declarations.count(_declaration.getName()) != 0) + return false; + } + else + { + // update declaration + solAssert(dynamic_cast(&_declaration) == nullptr, "cannot be FunctionDefinition"); + + m_declarations[_declaration.getName()].clear(); + } if (_invisible) m_invisibleDeclarations.insert(name); else - m_declarations[name] = &_declaration; + m_declarations[_declaration.getName()].insert(&_declaration); + return true; } -Declaration const* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const +std::set DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const { solAssert(!_name.empty(), "Attempt to resolve empty name."); auto result = m_declarations.find(_name); @@ -52,7 +71,7 @@ Declaration const* DeclarationContainer::resolveName(ASTString const& _name, boo return result->second; if (_recursive && m_enclosingContainer) return m_enclosingContainer->resolveName(_name, true); - return nullptr; + return std::set({}); } } diff --git a/libsolidity/DeclarationContainer.h b/libsolidity/DeclarationContainer.h index f70881f5b..42784ec2a 100644 --- a/libsolidity/DeclarationContainer.h +++ b/libsolidity/DeclarationContainer.h @@ -48,14 +48,14 @@ public: /// @param _update if true, replaces a potential declaration that is already present /// @returns false if the name was already declared. bool registerDeclaration(Declaration const& _declaration, bool _invisible = false, bool _update = false); - Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const; + std::set resolveName(ASTString const& _name, bool _recursive = false) const; Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; } - std::map const& getDeclarations() const { return m_declarations; } + std::map> const& getDeclarations() const { return m_declarations; } private: Declaration const* m_enclosingDeclaration; DeclarationContainer const* m_enclosingContainer; - std::map m_declarations; + std::map> m_declarations; std::set m_invisibleDeclarations; }; From 0f2f0195bec48f771569d32e60812a779e4dba5d Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:20:11 +0800 Subject: [PATCH 05/58] fix test code due to API changes in DeclarationContainer --- test/SolidityExpressionCompiler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/SolidityExpressionCompiler.cpp b/test/SolidityExpressionCompiler.cpp index 7034085ef..fa01ce1c9 100644 --- a/test/SolidityExpressionCompiler.cpp +++ b/test/SolidityExpressionCompiler.cpp @@ -79,7 +79,9 @@ Declaration const& resolveDeclaration( // bracers are required, cause msvc couldnt handle this macro in for statement for (string const& namePart: _namespacedName) { - BOOST_REQUIRE(declaration = _resolver.resolveName(namePart, declaration)); + auto declarations = _resolver.resolveName(namePart, declaration); + BOOST_REQUIRE(!declarations.empty()); + BOOST_REQUIRE(declaration = *declarations.begin()); } BOOST_REQUIRE(declaration); return *declaration; From 774d677aaca7bd180095669a4e937134e2b79219 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sat, 28 Feb 2015 16:29:32 +0800 Subject: [PATCH 06/58] add test cases for functions in derived overload functions in base --- test/SolidityEndToEndTest.cpp | 24 ++++++++++++++++++++++++ test/SolidityNameAndTypeResolution.cpp | 8 ++++---- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index da5b29ad4..fcd59e5d1 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3214,6 +3214,30 @@ BOOST_AUTO_TEST_CASE(overloaded_function_call_with_if_else) BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); } +BOOST_AUTO_TEST_CASE(derived_overload_base_function_direct) +{ + char const* sourceCode = R"( + contract B { function f() returns(uint) { return 10; } } + contract C is B { function f(uint i) returns(uint) { return 2 * i; } } + )"; + compileAndRun(sourceCode, "C"); + BOOST_CHECK(callContractFunction("f(uint)", 1) == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(derived_overload_base_function_indirect) +{ + char const* sourceCode = R"( + contract A { function f(uint a) returns(uint) { return 2 * a; } } + contract B { function f() returns(uint) { return 10; } } + contract C is A, B { } + )"; + compileAndRun(sourceCode, "C"); + BOOST_CHECK(callContractFunction("f(uint)", 1) == encodeArgs(2)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(10)); +} + +BOOST_AUTO_TEST_SUITE_END() + } } } // end namespaces diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index c3a4a3377..d2ae3f739 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -424,23 +424,23 @@ BOOST_AUTO_TEST_CASE(cyclic_inheritance) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } -BOOST_AUTO_TEST_CASE(illegal_override_direct) +BOOST_AUTO_TEST_CASE(legal_override_direct) { char const* text = R"( contract B { function f() {} } contract C is B { function f(uint i) {} } )"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } -BOOST_AUTO_TEST_CASE(illegal_override_indirect) +BOOST_AUTO_TEST_CASE(legal_override_indirect) { char const* text = R"( contract A { function f(uint a) {} } contract B { function f() {} } contract C is A, B { } )"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } BOOST_AUTO_TEST_CASE(illegal_override_visibility) From 29ec4453b5429051932277c0c5bb25323893c93e Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 1 Mar 2015 11:33:38 +0800 Subject: [PATCH 07/58] add two overloaded function test cases --- test/SolidityEndToEndTest.cpp | 20 +++++++++++++------- test/SolidityNameAndTypeResolution.cpp | 25 +++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index fcd59e5d1..2beca7848 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3218,10 +3218,13 @@ BOOST_AUTO_TEST_CASE(derived_overload_base_function_direct) { char const* sourceCode = R"( contract B { function f() returns(uint) { return 10; } } - contract C is B { function f(uint i) returns(uint) { return 2 * i; } } + contract C is B { + function f(uint i) returns(uint) { return 2 * i; } + function g() returns(uint) { return f(1); } + } )"; - compileAndRun(sourceCode, "C"); - BOOST_CHECK(callContractFunction("f(uint)", 1) == encodeArgs(2)); + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(2)); } BOOST_AUTO_TEST_CASE(derived_overload_base_function_indirect) @@ -3229,11 +3232,14 @@ BOOST_AUTO_TEST_CASE(derived_overload_base_function_indirect) char const* sourceCode = R"( contract A { function f(uint a) returns(uint) { return 2 * a; } } contract B { function f() returns(uint) { return 10; } } - contract C is A, B { } + contract C is A, B { + function g() returns(uint) { return f(); } + function h() returns(uint) { return f(1); } + } )"; - compileAndRun(sourceCode, "C"); - BOOST_CHECK(callContractFunction("f(uint)", 1) == encodeArgs(2)); - BOOST_CHECK(callContractFunction("f()") == encodeArgs(10)); + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(10)); + BOOST_CHECK(callContractFunction("h()") == encodeArgs(2)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index d2ae3f739..d764019ef 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1287,6 +1287,31 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve) +{ + char const* sourceCode = R"( + contract test { + function f() returns(uint) { return 1; } + function f(uint a) returns(uint) { return a; } + function g() returns(uint) { return f(3, 5); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function) +{ + // literal 1 can be both converted to uint8 and uint8, so it's ambiguous. + char const* sourceCode = R"( + contract test { + function f(uint8 a) returns(uint) { return a; } + function f(uint a) returns(uint) { return 2*a; } + function g() returns(uint) { return f(1); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } From fcc31b7a7fe4405f22dbb937fbcb5e12ecfeae6a Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 1 Mar 2015 11:34:12 +0800 Subject: [PATCH 08/58] the contract interfaces should take overloaded function into consideration TODO: --- libsolidity/CompilerContext.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index ee8d3e00c..f787db7fc 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -106,8 +106,12 @@ eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(FunctionDefiniti solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); for (ContractDefinition const* contract: m_inheritanceHierarchy) for (ASTPointer const& function: contract->getDefinedFunctions()) - if (!function->isConstructor() && function->getName() == _function.getName()) + { + if (!function->isConstructor() && + dynamic_cast(*function->getType()).getCanonicalSignature() == + dynamic_cast(*_function.getType()).getCanonicalSignature()) return getFunctionEntryLabel(*function); + } solAssert(false, "Virtual function " + _function.getName() + " not found."); return m_asm.newTag(); // not reached } @@ -117,7 +121,7 @@ eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(string const& _nam auto it = getSuperContract(_base); for (; it != m_inheritanceHierarchy.end(); ++it) for (ASTPointer const& function: (*it)->getDefinedFunctions()) - if (!function->isConstructor() && function->getName() == _name) + if (!function->isConstructor() && function->getName() == _name) // TODO: add a test case for this! return getFunctionEntryLabel(*function); solAssert(false, "Super function " + _name + " not found."); return m_asm.newTag(); // not reached From 17f79a5c6ee1f769a53e333eb2f6ac175e22eda7 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 1 Mar 2015 11:34:39 +0800 Subject: [PATCH 09/58] implement overload resolution --- libsolidity/AST.cpp | 159 ++++++++++++++++++++++++++-- libsolidity/AST.h | 15 ++- libsolidity/CompilerContext.cpp | 4 +- libsolidity/ExpressionCompiler.cpp | 6 +- libsolidity/NameAndTypeResolver.cpp | 39 ++++--- libsolidity/NameAndTypeResolver.h | 4 +- libsolidity/Parser.cpp | 7 +- libsolidity/Types.h | 15 ++- 8 files changed, 210 insertions(+), 39 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 79b755e97..428c82f21 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -76,6 +76,15 @@ void ContractDefinition::checkTypeRequirements() for (ASTPointer const& function: getDefinedFunctions()) function->checkTypeRequirements(); + // check for duplicate declaration + set functions; + for (ASTPointer const& function: getDefinedFunctions()) + { + string signature = function->getCanonicalSignature(); + if (functions.count(signature)) + BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_comment("Duplicate functions are not allowed.")); + functions.insert(signature); + } for (ASTPointer const& variable: m_stateVariables) variable->checkTypeRequirements(); @@ -129,6 +138,7 @@ void ContractDefinition::checkIllegalOverrides() const // TODO unify this at a later point. for this we need to put the constness and the access specifier // into the types map functions; + set functionNames; map modifiers; // We search from derived to base, so the stored item causes the error. @@ -141,7 +151,8 @@ void ContractDefinition::checkIllegalOverrides() const string const& name = function->getName(); if (modifiers.count(name)) BOOST_THROW_EXCEPTION(modifiers[name]->createTypeError("Override changes function to modifier.")); - FunctionDefinition const*& override = functions[name]; + FunctionDefinition const*& override = functions[function->getCanonicalSignature()]; + functionNames.insert(name); if (!override) override = function.get(); else if (override->getVisibility() != function->getVisibility() || @@ -152,13 +163,13 @@ void ContractDefinition::checkIllegalOverrides() const for (ASTPointer const& modifier: contract->getFunctionModifiers()) { string const& name = modifier->getName(); - if (functions.count(name)) - BOOST_THROW_EXCEPTION(functions[name]->createTypeError("Override changes modifier to function.")); ModifierDefinition const*& override = modifiers[name]; if (!override) override = modifier.get(); else if (ModifierType(*override) != ModifierType(*modifier)) BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier signature.")); + if (functionNames.count(name)) + BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier to function.")); } } } @@ -185,16 +196,21 @@ vector, FunctionTypePointer>> const& ContractDefinition::getIn if (!m_interfaceFunctionList) { set functionsSeen; + set signaturesSeen; m_interfaceFunctionList.reset(new vector, FunctionTypePointer>>()); for (ContractDefinition const* contract: getLinearizedBaseContracts()) { for (ASTPointer const& f: contract->getDefinedFunctions()) - if (f->isPublic() && !f->isConstructor() && !f->getName().empty() && functionsSeen.count(f->getName()) == 0) + { + string functionSignature = f->getCanonicalSignature(); + if (f->isPublic() && !f->isConstructor() && !f->getName().empty() && signaturesSeen.count(functionSignature) == 0) { functionsSeen.insert(f->getName()); - FixedHash<4> hash(dev::sha3(f->getCanonicalSignature())); + signaturesSeen.insert(functionSignature); + FixedHash<4> hash(dev::sha3(functionSignature)); m_interfaceFunctionList->push_back(make_pair(hash, make_shared(*f, false))); } + } for (ASTPointer const& v: contract->getStateVariables()) if (v->isPublic() && functionsSeen.count(v->getName()) == 0) @@ -467,7 +483,43 @@ void Return::checkTypeRequirements() void VariableDeclarationStatement::checkTypeRequirements() { +<<<<<<< HEAD m_variable->checkTypeRequirements(); +======= + // Variables can be declared without type (with "var"), in which case the first assignment + // sets the type. + // Note that assignments before the first declaration are legal because of the special scoping + // rules inherited from JavaScript. + if (m_variable->getValue()) + { + if (m_variable->getType()) + { + std::cout << "getType() ok" << std::endl; + m_variable->getValue()->expectType(*m_variable->getType()); + } + else + { + // no type declared and no previous assignment, infer the type + std::cout << "here's where called...." << std::endl; + Identifier* identifier = dynamic_cast(m_variable->getValue().get()); + if (identifier) + identifier->checkTypeRequirementsFromVariableDeclaration(); + else + m_variable->getValue()->checkTypeRequirements(); + TypePointer type = m_variable->getValue()->getType(); + if (type->getCategory() == Type::Category::IntegerConstant) + { + auto intType = dynamic_pointer_cast(type)->getIntegerType(); + if (!intType) + BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString())); + type = intType; + } + else if (type->getCategory() == Type::Category::Void) + BOOST_THROW_EXCEPTION(m_variable->createTypeError("var cannot be void type")); + m_variable->setType(type); + } + } +>>>>>>> implement overload resolution } void Assignment::checkTypeRequirements() @@ -544,10 +596,16 @@ void BinaryOperation::checkTypeRequirements() void FunctionCall::checkTypeRequirements() { - m_expression->checkTypeRequirements(); + // we need to check arguments' type first as their info will be used by m_express(Identifier). for (ASTPointer const& argument: m_arguments) argument->checkTypeRequirements(); + auto identifier = dynamic_cast(m_expression.get()); + if (identifier) + identifier->checkTypeRequirementsWithFunctionCall(*this); + else + m_expression->checkTypeRequirements(); + Type const* expressionType = m_expression->getType().get(); if (isTypeConversion()) { @@ -617,6 +675,19 @@ void FunctionCall::checkTypeRequirements() else m_type = functionType->getReturnParameterTypes().front(); } + else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast(expressionType)) + { + // this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions. + overloadedTypes->m_identifier->overloadResolution(*this); + FunctionType const* functionType = dynamic_cast(overloadedTypes->m_identifier->getType().get()); + + // @todo actually the return type should be an anonymous struct, + // but we change it to the type of the first return value until we have structs + if (functionType->getReturnParameterTypes().empty()) + m_type = make_shared(); + else + m_type = functionType->getReturnParameterTypes().front(); + } else BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); } @@ -709,16 +780,92 @@ void IndexAccess::checkTypeRequirements() } } +void Identifier::checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall) +{ + solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); + + if (!m_referencedDeclaration) + overloadResolution(_functionCall); + + checkTypeRequirements(); +} + +void Identifier::checkTypeRequirementsFromVariableDeclaration() +{ + solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); + + if (!m_referencedDeclaration) + m_type = make_shared(m_overloadedDeclarations, this); + else + checkTypeRequirements(); + + m_isLValue = true; +} + void Identifier::checkTypeRequirements() { + // var x = f; TODO! solAssert(m_referencedDeclaration, "Identifier not resolved."); m_isLValue = m_referencedDeclaration->isLValue(); + if (m_isLValue) + std::cout << "Identifier: " << string(getName()) << " -> true" << std::endl; + else + std::cout << "Identifier: " << string(getName()) << " -> true" << std::endl; m_type = m_referencedDeclaration->getType(m_currentContract); if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined.")); } +void Identifier::overloadResolution(FunctionCall const& _functionCall) +{ + solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved."); + solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution."); + + bool resolved = false; + + std::vector> arguments = _functionCall.getArguments(); + std::vector> const& argumentNames = _functionCall.getNames(); + + if (argumentNames.empty()) + { + // positional arguments + std::vector possibles; + for (Declaration const* declaration: m_overloadedDeclarations) + { + TypePointer const& function = declaration->getType(); + auto const& functionType = dynamic_cast(*function); + TypePointers const& parameterTypes = functionType.getParameterTypes(); + + if (functionType.takesArbitraryParameters() || + (arguments.size() == parameterTypes.size() && + std::equal(arguments.cbegin(), arguments.cend(), parameterTypes.cbegin(), + [](ASTPointer const& argument, TypePointer const& parameterType) + { + return argument->getType()->isImplicitlyConvertibleTo(*parameterType); + }))) + possibles.push_back(declaration); + } + std::cout << "possibles: " << possibles.size() << std::endl; + if (possibles.empty()) + BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); + else if (std::none_of(possibles.cbegin() + 1, possibles.cend(), + [&possibles](Declaration const* declaration) + { + return declaration->getScope() == possibles.front()->getScope(); + })) + setReferencedDeclaration(*possibles.front()); + else + BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); + } + else + { + // named arguments + // TODO: don't support right now + // BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet.")); + } +} + void ElementaryTypeNameExpression::checkTypeRequirements() { m_type = make_shared(Type::fromElementaryTypeName(m_typeToken)); diff --git a/libsolidity/AST.h b/libsolidity/AST.h index b21e505e9..fa1d4a92e 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -1134,8 +1134,8 @@ public: class Identifier: public PrimaryExpression { public: - Identifier(SourceLocation const& _location, ASTPointer const& _name, bool _isCallable): - PrimaryExpression(_location), m_name(_name), m_isCallable(_isCallable) {} + Identifier(SourceLocation const& _location, ASTPointer const& _name): + PrimaryExpression(_location), m_name(_name) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; virtual void checkTypeRequirements() override; @@ -1151,9 +1151,15 @@ public: Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; } ContractDefinition const* getCurrentContract() const { return m_currentContract; } - bool isCallable() const { return m_isCallable; } + void setOverloadedDeclarations(std::set const& _declarations) { m_overloadedDeclarations = _declarations; } + std::set getOverloadedDeclarations() const { return m_overloadedDeclarations; } + void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall); + void checkTypeRequirementsFromVariableDeclaration(); + + void overloadResolution(FunctionCall const& _functionCall); private: + ASTPointer m_name; /// Declaration the name refers to. @@ -1161,7 +1167,8 @@ private: /// Stores a reference to the current contract. This is needed because types of base contracts /// change depending on the context. ContractDefinition const* m_currentContract = nullptr; - bool m_isCallable = false; + /// A set of overloaded declarations, right now only FunctionDefinition has overloaded declarations. + std::set m_overloadedDeclarations; }; /** diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index f787db7fc..b12e01923 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -108,8 +108,8 @@ eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(FunctionDefiniti for (ASTPointer const& function: contract->getDefinedFunctions()) { if (!function->isConstructor() && - dynamic_cast(*function->getType()).getCanonicalSignature() == - dynamic_cast(*_function.getType()).getCanonicalSignature()) + dynamic_cast(*function->getType(contract)).getCanonicalSignature() == + dynamic_cast(*_function.getType(contract)).getCanonicalSignature()) return getFunctionEntryLabel(*function); } solAssert(false, "Virtual function " + _function.getName() + " not found."); diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3d7a25311..5e5442ba3 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -822,7 +822,11 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) void ExpressionCompiler::endVisit(Identifier const& _identifier) { Declaration const* declaration = _identifier.getReferencedDeclaration(); - if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) + if (declaration == nullptr) + { + // no-op + } + else if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) { if (magicVar->getType()->getCategory() == Type::Category::Contract) // "this" or "super" diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index f6ee2f1d0..c787ae6b0 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -90,15 +90,15 @@ void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope."); } -Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const +std::set NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const { auto iterator = m_scopes.find(_scope); if (iterator == end(m_scopes)) - return nullptr; + return std::set({}); return iterator->second.resolveName(_name, false); } -Declaration const* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive) +std::set NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive) { return m_currentScope->resolveName(_name, _recursive); } @@ -108,13 +108,11 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) auto iterator = m_scopes.find(&_base); solAssert(iterator != end(m_scopes), ""); for (auto const& nameAndDeclaration: iterator->second.getDeclarations()) - { - Declaration const* declaration = nameAndDeclaration.second; - // Import if it was declared in the base, is not the constructor and is visible in derived classes - if (declaration->getScope() == &_base && declaration->getName() != _base.getName() && - declaration->isVisibleInDerivedContracts()) - m_currentScope->registerDeclaration(*declaration); - } + for (auto const& declaration: nameAndDeclaration.second) + // Import if it was declared in the base, is not the constructor and is visible in derived classes + if (declaration->getScope() == &_base && declaration->getName() != _base.getName() && + declaration->isVisibleInDerivedContracts()) + m_currentScope->registerDeclaration(*declaration); } void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const @@ -361,24 +359,31 @@ bool ReferencesResolver::visit(Mapping&) bool ReferencesResolver::visit(UserDefinedTypeName& _typeName) { - Declaration const* declaration = m_resolver.getNameFromCurrentScope(_typeName.getName()); - if (!declaration) + auto declarations = m_resolver.getNameFromCurrentScope(_typeName.getName()); + if (declarations.empty()) BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation()) << errinfo_comment("Undeclared identifier.")); - _typeName.setReferencedDeclaration(*declaration); + else if (declarations.size() > 1) + BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation()) + << errinfo_comment("Duplicate identifier.")); + else + _typeName.setReferencedDeclaration(**declarations.begin()); return false; } bool ReferencesResolver::visit(Identifier& _identifier) { - Declaration const* declaration = m_resolver.getNameFromCurrentScope(_identifier.getName()); - if (!declaration) + auto declarations = m_resolver.getNameFromCurrentScope(_identifier.getName()); + if (declarations.empty()) BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_identifier.getLocation()) << errinfo_comment("Undeclared identifier.")); - _identifier.setReferencedDeclaration(*declaration, m_currentContract); + else if (declarations.size() == 1) + _identifier.setReferencedDeclaration(**declarations.begin(), m_currentContract); + else + // Duplicate declaration will be checked in checkTypeRequirements() + _identifier.setOverloadedDeclarations(declarations); return false; } - } } diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index 63b8ab637..828776179 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -56,11 +56,11 @@ public: /// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted, /// the global scope is used (i.e. the one containing only the contract). /// @returns a pointer to the declaration on success or nullptr on failure. - Declaration const* resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const; + std::set resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const; /// Resolves a name in the "current" scope. Should only be called during the initial /// resolving phase. - Declaration const* getNameFromCurrentScope(ASTString const& _name, bool _recursive = true); + std::set getNameFromCurrentScope(ASTString const& _name, bool _recursive = true); private: void reset(); diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index cecf772da..44d111591 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -837,14 +837,9 @@ ASTPointer Parser::parsePrimaryExpression() expression = nodeFactory.createNode(token, getLiteralAndAdvance()); break; case Token::Identifier: - { nodeFactory.markEndPosition(); - // if the next token is '(', this identifier looks like function call, - // it could be a contract, event etc. - bool isCallable = m_scanner->peekNextToken() == Token::LParen; - expression = nodeFactory.createNode(getLiteralAndAdvance(), isCallable); + expression = nodeFactory.createNode(getLiteralAndAdvance()); break; - } case Token::LParen: { m_scanner->next(); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 6cef8d64a..5dd742ada 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -77,7 +77,7 @@ public: enum class Category { Integer, IntegerConstant, Bool, Real, Array, - String, Contract, Struct, Function, Enum, + String, Contract, Struct, Function, OverloadedFunctions, Enum, Mapping, Void, TypeType, Modifier, Magic }; @@ -524,6 +524,19 @@ private: Declaration const* m_declaration = nullptr; }; +class OverloadedFunctionType: public Type +{ +public: + explicit OverloadedFunctionType(std::set const& _overloadedDeclarations, Identifier* _identifier): + m_overloadedDeclarations(_overloadedDeclarations), m_identifier(_identifier) {} + virtual Category getCategory() const override { return Category::OverloadedFunctions; } + virtual std::string toString() const override { return "OverloadedFunctions"; } + +// private: + std::set m_overloadedDeclarations; + Identifier * m_identifier; +}; + /** * The type of a mapping, there is one distinct type per key/value type pair. */ From b441305234bbc7a2984791964fb3a538a2854dd5 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Thu, 5 Mar 2015 21:32:48 -0600 Subject: [PATCH 10/58] remove debug stuff --- libsolidity/AST.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 428c82f21..2aa57d7e3 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -493,14 +493,10 @@ void VariableDeclarationStatement::checkTypeRequirements() if (m_variable->getValue()) { if (m_variable->getType()) - { - std::cout << "getType() ok" << std::endl; m_variable->getValue()->expectType(*m_variable->getType()); - } else { // no type declared and no previous assignment, infer the type - std::cout << "here's where called...." << std::endl; Identifier* identifier = dynamic_cast(m_variable->getValue().get()); if (identifier) identifier->checkTypeRequirementsFromVariableDeclaration(); @@ -804,14 +800,9 @@ void Identifier::checkTypeRequirementsFromVariableDeclaration() void Identifier::checkTypeRequirements() { - // var x = f; TODO! solAssert(m_referencedDeclaration, "Identifier not resolved."); m_isLValue = m_referencedDeclaration->isLValue(); - if (m_isLValue) - std::cout << "Identifier: " << string(getName()) << " -> true" << std::endl; - else - std::cout << "Identifier: " << string(getName()) << " -> true" << std::endl; m_type = m_referencedDeclaration->getType(m_currentContract); if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined.")); @@ -846,7 +837,6 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall) }))) possibles.push_back(declaration); } - std::cout << "possibles: " << possibles.size() << std::endl; if (possibles.empty()) BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); else if (std::none_of(possibles.cbegin() + 1, possibles.cend(), @@ -859,11 +849,9 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall) BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); } else - { // named arguments // TODO: don't support right now - // BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet.")); - } + BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet.")); } void ElementaryTypeNameExpression::checkTypeRequirements() From eeaf97ae7f408261eac44a6085742451d30b1ac1 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Thu, 5 Mar 2015 21:37:51 -0600 Subject: [PATCH 11/58] add another var x = f; overloaded function test case --- test/SolidityEndToEndTest.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 2beca7848..dd34627ac 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3210,6 +3210,27 @@ BOOST_AUTO_TEST_CASE(overloaded_function_call_with_if_else) } } )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("g(bool)", true) == encodeArgs(3)); + BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); +} + +BOOST_AUTO_TEST_CASE(overloaded_function_with_var) +{ + char const* sourceCode = R"( + contract test { + function f(uint k) returns(uint d) { return k; } + function f(uint a, uint b) returns(uint d) { return a + b; } + function g(bool flag) returns(uint d) { + var x = f; + if (flag) + return x(3); + else + return x(3, 7); + } + } + )"; + compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("g(bool)", true) == encodeArgs(3)); BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); } From aa68913dd2325932a4ed35044987f590e63b1ab8 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Thu, 5 Mar 2015 23:02:35 -0600 Subject: [PATCH 12/58] make it work for var x = f; --- libsolidity/AST.cpp | 29 ++++++++++++++++++----------- libsolidity/AST.h | 2 +- libsolidity/ExpressionCompiler.cpp | 13 ++++++++----- libsolidity/Types.h | 9 +++++---- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 2aa57d7e3..2fd60f7b0 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -674,15 +674,23 @@ void FunctionCall::checkTypeRequirements() else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast(expressionType)) { // this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions. - overloadedTypes->m_identifier->overloadResolution(*this); - FunctionType const* functionType = dynamic_cast(overloadedTypes->m_identifier->getType().get()); + auto identifier = dynamic_cast(m_expression.get()); + solAssert(identifier, "only applies to 'var x = f;'"); + + Declaration const* function = overloadedTypes->getIdentifier()->overloadResolution(*this); + if (!function) + BOOST_THROW_EXCEPTION(createTypeError("Can't resolve declarations")); + + identifier->setReferencedDeclaration(*function); + identifier->checkTypeRequirements(); + + TypePointer type = identifier->getType(); + FunctionType const* functionType = dynamic_cast(type.get()); - // @todo actually the return type should be an anonymous struct, - // but we change it to the type of the first return value until we have structs if (functionType->getReturnParameterTypes().empty()) m_type = make_shared(); else - m_type = functionType->getReturnParameterTypes().front(); + m_type = functionType->getReturnParameterTypes().front(); } else BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); @@ -781,7 +789,7 @@ void Identifier::checkTypeRequirementsWithFunctionCall(FunctionCall const& _func solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); if (!m_referencedDeclaration) - overloadResolution(_functionCall); + setReferencedDeclaration(*overloadResolution(_functionCall)); checkTypeRequirements(); } @@ -791,7 +799,7 @@ void Identifier::checkTypeRequirementsFromVariableDeclaration() solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); if (!m_referencedDeclaration) - m_type = make_shared(m_overloadedDeclarations, this); + m_type = make_shared(this); else checkTypeRequirements(); @@ -808,13 +816,11 @@ void Identifier::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined.")); } -void Identifier::overloadResolution(FunctionCall const& _functionCall) +Declaration const* Identifier::overloadResolution(FunctionCall const& _functionCall) { solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved."); solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution."); - bool resolved = false; - std::vector> arguments = _functionCall.getArguments(); std::vector> const& argumentNames = _functionCall.getNames(); @@ -844,7 +850,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall) { return declaration->getScope() == possibles.front()->getScope(); })) - setReferencedDeclaration(*possibles.front()); + return possibles.front(); else BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); } @@ -852,6 +858,7 @@ void Identifier::overloadResolution(FunctionCall const& _functionCall) // named arguments // TODO: don't support right now BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet.")); + return nullptr; } void ElementaryTypeNameExpression::checkTypeRequirements() diff --git a/libsolidity/AST.h b/libsolidity/AST.h index fa1d4a92e..6cc7f742f 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -1157,7 +1157,7 @@ public: void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall); void checkTypeRequirementsFromVariableDeclaration(); - void overloadResolution(FunctionCall const& _functionCall); + Declaration const* overloadResolution(FunctionCall const& _functionCall); private: ASTPointer m_name; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 5e5442ba3..4be461b25 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -822,11 +822,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) void ExpressionCompiler::endVisit(Identifier const& _identifier) { Declaration const* declaration = _identifier.getReferencedDeclaration(); - if (declaration == nullptr) - { - // no-op - } - else if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) + if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) { if (magicVar->getType()->getCategory() == Type::Category::Contract) // "this" or "super" @@ -849,6 +845,13 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) { // no-op } + else if (declaration == nullptr && _identifier.getOverloadedDeclarations().size() > 1) + { + // var x = f; + declaration = *_identifier.getOverloadedDeclarations().begin(); + FunctionDefinition const* functionDef = dynamic_cast(declaration); + m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag(); + } else { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context.")); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 5dd742ada..b19f75406 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -527,13 +527,14 @@ private: class OverloadedFunctionType: public Type { public: - explicit OverloadedFunctionType(std::set const& _overloadedDeclarations, Identifier* _identifier): - m_overloadedDeclarations(_overloadedDeclarations), m_identifier(_identifier) {} + explicit OverloadedFunctionType(Identifier* _identifier): m_identifier(_identifier) {} + virtual Category getCategory() const override { return Category::OverloadedFunctions; } virtual std::string toString() const override { return "OverloadedFunctions"; } -// private: - std::set m_overloadedDeclarations; + Identifier* getIdentifier() const { return m_identifier; } + +private: Identifier * m_identifier; }; From 3eeac6a21b16837852b4ebb7c09169054878a5cb Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 8 Mar 2015 09:42:29 -0500 Subject: [PATCH 13/58] add the location of a duplicated function --- libsolidity/AST.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 2fd60f7b0..9d19b30c9 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -82,7 +82,8 @@ void ContractDefinition::checkTypeRequirements() { string signature = function->getCanonicalSignature(); if (functions.count(signature)) - BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_comment("Duplicate functions are not allowed.")); + BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(function->getLocation()) + << errinfo_comment("Duplicate functions are not allowed.")); functions.insert(signature); } From 19220b9fe5c78a5e68724c0def4f187955a5bc76 Mon Sep 17 00:00:00 2001 From: Lu Guanqun Date: Sun, 8 Mar 2015 17:26:36 -0500 Subject: [PATCH 14/58] fix rebase errors --- libsolidity/AST.cpp | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 9d19b30c9..09c03ef6e 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -356,7 +356,12 @@ void VariableDeclaration::checkTypeRequirements() else { // no type declared and no previous assignment, infer the type - m_value->checkTypeRequirements(); + Identifier* identifier = dynamic_cast(m_value.get()); + if (identifier) + identifier->checkTypeRequirementsFromVariableDeclaration(); + else + m_value->checkTypeRequirements(); + TypePointer type = m_value->getType(); if (type->getCategory() == Type::Category::IntegerConstant) { @@ -484,39 +489,7 @@ void Return::checkTypeRequirements() void VariableDeclarationStatement::checkTypeRequirements() { -<<<<<<< HEAD m_variable->checkTypeRequirements(); -======= - // Variables can be declared without type (with "var"), in which case the first assignment - // sets the type. - // Note that assignments before the first declaration are legal because of the special scoping - // rules inherited from JavaScript. - if (m_variable->getValue()) - { - if (m_variable->getType()) - m_variable->getValue()->expectType(*m_variable->getType()); - else - { - // no type declared and no previous assignment, infer the type - Identifier* identifier = dynamic_cast(m_variable->getValue().get()); - if (identifier) - identifier->checkTypeRequirementsFromVariableDeclaration(); - else - m_variable->getValue()->checkTypeRequirements(); - TypePointer type = m_variable->getValue()->getType(); - if (type->getCategory() == Type::Category::IntegerConstant) - { - auto intType = dynamic_pointer_cast(type)->getIntegerType(); - if (!intType) - BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString())); - type = intType; - } - else if (type->getCategory() == Type::Category::Void) - BOOST_THROW_EXCEPTION(m_variable->createTypeError("var cannot be void type")); - m_variable->setType(type); - } - } ->>>>>>> implement overload resolution } void Assignment::checkTypeRequirements() From 7f2ac996792ff43662b1f655a71a53f2281ae0d3 Mon Sep 17 00:00:00 2001 From: debris Date: Sat, 11 Apr 2015 19:53:45 +0200 Subject: [PATCH 15/58] fixed #1590, msvc build with cmake 3.2.1 --- CMakeLists.txt | 17 +++++++++++++---- test/CMakeLists.txt | 8 ++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 100ef9139..eb6dc9d46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,22 @@ # cmake global cmake_minimum_required(VERSION 2.8.12) + +project(ethereum) + +set(CMAKE_AUTOMOC ON) + +# link_directories interprate relative paths with respect to CMAKE_CURRENT_SOURCE_DIR +cmake_policy(SET CMP0015 NEW) + # let cmake autolink dependencies on windows # it's specified globally, cause qt libraries requires that on windows and they are also found globally cmake_policy(SET CMP0020 NEW) -project(ethereum) +# 3.1 and above +if ((${CMAKE_MAJOR_VERSION} GREATER 2) AND (${CMAKE_MINOR_VERSION} GREATER 0)) + # implicitly dereference variables (deprecated in 3.1) + cmake_policy(SET CMP0054 OLD) +endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -118,9 +130,6 @@ endfunction() ###################################################################################################### -set(CMAKE_AUTOMOC ON) -cmake_policy(SET CMP0015 NEW) - # Clear invalid option if ("${CMAKE_BUILD_TYPE}" STREQUAL "Release") if (PARANOID) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 90af5122e..1df4c7cc3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -34,10 +34,10 @@ endforeach(file) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) -add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) -add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp Stats.cpp) -add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) -add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp Stats.cpp) +add_executable(createRandomVMTest "./createRandomVMTest.cpp" "./vm.cpp" "./TestHelper.cpp" "./Stats.cpp") +add_executable(createRandomStateTest "./createRandomStateTest.cpp" "./TestHelper.cpp" "./Stats.cpp") +add_executable(checkRandomVMTest "./checkRandomVMTest.cpp" "./vm.cpp" "./TestHelper.cpp" "./Stats.cpp") +add_executable(checkRandomStateTest "./checkRandomStateTest.cpp" "./TestHelper.cpp" "./Stats.cpp") target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) From 0b36ca86d758b1be39c5db36e0398f436556a9e0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 15 Apr 2015 17:40:50 +0200 Subject: [PATCH 16/58] Fixed function overloads. Added tests, disallowed non-calling usage of non-unique function references. --- libsolidity/AST.cpp | 330 ++++++++++++++----------- libsolidity/AST.h | 63 +++-- libsolidity/Compiler.cpp | 6 +- libsolidity/CompilerContext.cpp | 42 ++-- libsolidity/CompilerContext.h | 11 +- libsolidity/DeclarationContainer.cpp | 29 ++- libsolidity/DeclarationContainer.h | 2 +- libsolidity/ExpressionCompiler.cpp | 46 ++-- libsolidity/LValue.cpp | 8 +- libsolidity/NameAndTypeResolver.cpp | 80 +++++- libsolidity/NameAndTypeResolver.h | 21 +- libsolidity/Types.cpp | 117 ++++++--- libsolidity/Types.h | 57 +++-- mix/CodeModel.cpp | 4 +- test/SolidityEndToEndTest.cpp | 154 +++++------- test/SolidityNameAndTypeResolution.cpp | 74 +++++- 16 files changed, 646 insertions(+), 398 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index ada4a01d1..1c1983d98 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -52,6 +52,7 @@ void ContractDefinition::checkTypeRequirements() for (ASTPointer const& baseSpecifier: getBaseContracts()) baseSpecifier->checkTypeRequirements(); + checkDuplicateFunctions(); checkIllegalOverrides(); checkAbstractFunctions(); @@ -82,20 +83,11 @@ void ContractDefinition::checkTypeRequirements() for (ASTPointer const& function: getDefinedFunctions()) function->checkTypeRequirements(); - // check for duplicate declaration - set functions; - for (ASTPointer const& function: getDefinedFunctions()) - { - string signature = function->getCanonicalSignature(); - if (functions.count(signature)) - BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(function->getLocation()) - << errinfo_comment("Duplicate functions are not allowed.")); - functions.insert(signature); - } for (ASTPointer const& variable: m_stateVariables) variable->checkTypeRequirements(); + checkExternalTypeClashes(); // check for hash collisions in function signatures set> hashes; for (auto const& it: getInterfaceFunctionList()) @@ -140,6 +132,33 @@ FunctionDefinition const* ContractDefinition::getFallbackFunction() const return nullptr; } +void ContractDefinition::checkDuplicateFunctions() const +{ + /// Checks that two functions with the same name defined in this contract have different + /// argument types and that there is at most one constructor. + map> functions; + for (ASTPointer const& function: getDefinedFunctions()) + functions[function->getName()].push_back(function.get()); + if (functions[getName()].size() > 1) + BOOST_THROW_EXCEPTION( + DeclarationError() << + errinfo_sourceLocation(getLocation()) << + errinfo_comment("More than one constructor defined.") + ); + for (auto const& it: functions) + { + vector const& overloads = it.second; + for (size_t i = 0; i < overloads.size(); ++i) + for (size_t j = i + 1; j < overloads.size(); ++j) + if (FunctionType(*overloads[i]).hasEqualArgumentTypes(FunctionType(*overloads[j]))) + BOOST_THROW_EXCEPTION( + DeclarationError() << + errinfo_sourceLocation(overloads[j]->getLocation()) << + errinfo_comment("Function with same name and arguments already defined.") + ); + } +} + void ContractDefinition::checkAbstractFunctions() { map functions; @@ -166,8 +185,7 @@ void ContractDefinition::checkIllegalOverrides() const { // TODO unify this at a later point. for this we need to put the constness and the access specifier // into the types - map functions; - set functionNames; + map> functions; map modifiers; // We search from derived to base, so the stored item causes the error. @@ -180,14 +198,21 @@ void ContractDefinition::checkIllegalOverrides() const string const& name = function->getName(); if (modifiers.count(name)) BOOST_THROW_EXCEPTION(modifiers[name]->createTypeError("Override changes function to modifier.")); - FunctionDefinition const*& override = functions[function->getCanonicalSignature()]; - functionNames.insert(name); - if (!override) - override = function.get(); - else if (override->getVisibility() != function->getVisibility() || - override->isDeclaredConst() != function->isDeclaredConst() || - FunctionType(*override) != FunctionType(*function)) - BOOST_THROW_EXCEPTION(override->createTypeError("Override changes extended function signature.")); + FunctionType functionType(*function); + // function should not change the return type + for (FunctionDefinition const* overriding: functions[name]) + { + FunctionType overridingType(*overriding); + if (!overridingType.hasEqualArgumentTypes(functionType)) + continue; + if ( + overriding->getVisibility() != function->getVisibility() || + overriding->isDeclaredConst() != function->isDeclaredConst() || + overridingType != functionType + ) + BOOST_THROW_EXCEPTION(overriding->createTypeError("Override changes extended function signature.")); + } + functions[name].push_back(function.get()); } for (ASTPointer const& modifier: contract->getFunctionModifiers()) { @@ -197,12 +222,43 @@ void ContractDefinition::checkIllegalOverrides() const override = modifier.get(); else if (ModifierType(*override) != ModifierType(*modifier)) BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier signature.")); - if (functionNames.count(name)) + if (!functions[name].empty()) BOOST_THROW_EXCEPTION(override->createTypeError("Override changes modifier to function.")); } } } +void ContractDefinition::checkExternalTypeClashes() const +{ + map>>> externalDeclarations; + for (ContractDefinition const* contract: getLinearizedBaseContracts()) + { + for (ASTPointer const& f: contract->getDefinedFunctions()) + if (f->isPartOfExternalInterface()) + { + auto functionType = make_shared(*f); + externalDeclarations[functionType->externalSignature(f->getName())].push_back( + make_pair(f.get(), functionType) + ); + } + for (ASTPointer const& v: contract->getStateVariables()) + if (v->isPartOfExternalInterface()) + { + auto functionType = make_shared(*v); + externalDeclarations[functionType->externalSignature(v->getName())].push_back( + make_pair(v.get(), functionType) + ); + } + } + for (auto const& it: externalDeclarations) + for (size_t i = 0; i < it.second.size(); ++i) + for (size_t j = i + 1; j < it.second.size(); ++j) + if (!it.second[i].second->hasEqualArgumentTypes(*it.second[j].second)) + BOOST_THROW_EXCEPTION(it.second[j].first->createTypeError( + "Function overload clash during conversion to external types for arguments." + )); +} + std::vector> const& ContractDefinition::getInterfaceEvents() const { if (!m_interfaceEvents) @@ -291,11 +347,11 @@ TypePointer EnumValue::getType(ContractDefinition const*) const void InheritanceSpecifier::checkTypeRequirements() { - m_baseName->checkTypeRequirements(); + m_baseName->checkTypeRequirements(nullptr); for (ASTPointer const& argument: m_arguments) - argument->checkTypeRequirements(); + argument->checkTypeRequirements(nullptr); - ContractDefinition const* base = dynamic_cast(m_baseName->getReferencedDeclaration()); + ContractDefinition const* base = dynamic_cast(&m_baseName->getReferencedDeclaration()); solAssert(base, "Base contract not available."); TypePointers parameterTypes = ContractType(*base).getConstructorType()->getParameterTypes(); if (parameterTypes.size() != m_arguments.size()) @@ -409,11 +465,7 @@ void VariableDeclaration::checkTypeRequirements() else { // no type declared and no previous assignment, infer the type - Identifier* identifier = dynamic_cast(m_value.get()); - if (identifier) - identifier->checkTypeRequirementsFromVariableDeclaration(); - else - m_value->checkTypeRequirements(); + m_value->checkTypeRequirements(nullptr); TypePointer type = m_value->getType(); if (type->getCategory() == Type::Category::IntegerConstant) @@ -452,11 +504,15 @@ void ModifierDefinition::checkTypeRequirements() void ModifierInvocation::checkTypeRequirements(vector> const& _bases) { - m_modifierName->checkTypeRequirements(); + TypePointers argumentTypes; for (ASTPointer const& argument: m_arguments) - argument->checkTypeRequirements(); + { + argument->checkTypeRequirements(nullptr); + argumentTypes.push_back(argument->getType()); + } + m_modifierName->checkTypeRequirements(&argumentTypes); - auto declaration = m_modifierName->getReferencedDeclaration(); + auto const* declaration = &m_modifierName->getReferencedDeclaration(); vector> emptyParameterList; vector> const* parameters = nullptr; if (auto modifier = dynamic_cast(declaration)) @@ -464,7 +520,7 @@ void ModifierInvocation::checkTypeRequirements(vectorgetName()->getReferencedDeclaration()) + if (declaration == &base->getName()->getReferencedDeclaration()) { if (auto referencedConstructor = dynamic_cast(*declaration).getConstructor()) parameters = &referencedConstructor->getParameters(); @@ -547,9 +603,9 @@ void VariableDeclarationStatement::checkTypeRequirements() m_variable->checkTypeRequirements(); } -void Assignment::checkTypeRequirements() +void Assignment::checkTypeRequirements(TypePointers const*) { - m_leftHandSide->checkTypeRequirements(); + m_leftHandSide->checkTypeRequirements(nullptr); m_leftHandSide->requireLValue(); if (m_leftHandSide->getType()->getCategory() == Type::Category::Mapping) BOOST_THROW_EXCEPTION(createTypeError("Mappings cannot be assigned to.")); @@ -559,7 +615,7 @@ void Assignment::checkTypeRequirements() else { // compound assignment - m_rightHandSide->checkTypeRequirements(); + m_rightHandSide->checkTypeRequirements(nullptr); TypePointer resultType = m_type->binaryOperatorResult(Token::AssignmentToBinaryOp(m_assigmentOperator), m_rightHandSide->getType()); if (!resultType || *resultType != *m_type) @@ -572,7 +628,7 @@ void Assignment::checkTypeRequirements() void ExpressionStatement::checkTypeRequirements() { - m_expression->checkTypeRequirements(); + m_expression->checkTypeRequirements(nullptr); if (m_expression->getType()->getCategory() == Type::Category::IntegerConstant) if (!dynamic_pointer_cast(m_expression->getType())->getIntegerType()) BOOST_THROW_EXCEPTION(m_expression->createTypeError("Invalid integer constant.")); @@ -580,7 +636,7 @@ void ExpressionStatement::checkTypeRequirements() void Expression::expectType(Type const& _expectedType) { - checkTypeRequirements(); + checkTypeRequirements(nullptr); Type const& type = *getType(); if (!type.isImplicitlyConvertibleTo(_expectedType)) BOOST_THROW_EXCEPTION(createTypeError("Type " + type.toString() + @@ -595,10 +651,10 @@ void Expression::requireLValue() m_lvalueRequested = true; } -void UnaryOperation::checkTypeRequirements() +void UnaryOperation::checkTypeRequirements(TypePointers const*) { // Inc, Dec, Add, Sub, Not, BitNot, Delete - m_subExpression->checkTypeRequirements(); + m_subExpression->checkTypeRequirements(nullptr); if (m_operator == Token::Value::Inc || m_operator == Token::Value::Dec || m_operator == Token::Value::Delete) m_subExpression->requireLValue(); m_type = m_subExpression->getType()->unaryOperatorResult(m_operator); @@ -606,10 +662,10 @@ void UnaryOperation::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Unary operator not compatible with type.")); } -void BinaryOperation::checkTypeRequirements() +void BinaryOperation::checkTypeRequirements(TypePointers const*) { - m_left->checkTypeRequirements(); - m_right->checkTypeRequirements(); + m_left->checkTypeRequirements(nullptr); + m_right->checkTypeRequirements(nullptr); m_commonType = m_left->getType()->binaryOperatorResult(m_operator, m_right->getType()); if (!m_commonType) BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) + @@ -619,17 +675,22 @@ void BinaryOperation::checkTypeRequirements() m_type = Token::isCompareOp(m_operator) ? make_shared() : m_commonType; } -void FunctionCall::checkTypeRequirements() +void FunctionCall::checkTypeRequirements(TypePointers const*) { - // we need to check arguments' type first as their info will be used by m_express(Identifier). + bool isPositionalCall = m_names.empty(); + + // we need to check arguments' type first as they will be forwarded to + // m_expression->checkTypeRequirements + TypePointers argumentTypes; for (ASTPointer const& argument: m_arguments) - argument->checkTypeRequirements(); + { + argument->checkTypeRequirements(nullptr); + // only store them for positional calls + if (isPositionalCall) + argumentTypes.push_back(argument->getType()); + } - auto identifier = dynamic_cast(m_expression.get()); - if (identifier) - identifier->checkTypeRequirementsWithFunctionCall(*this); - else - m_expression->checkTypeRequirements(); + m_expression->checkTypeRequirements(isPositionalCall ? &argumentTypes : nullptr); Type const* expressionType = m_expression->getType().get(); if (isTypeConversion()) @@ -639,7 +700,7 @@ void FunctionCall::checkTypeRequirements() // number of non-mapping members if (m_arguments.size() != 1) BOOST_THROW_EXCEPTION(createTypeError("More than one argument for explicit type conversion.")); - if (!m_names.empty()) + if (!isPositionalCall) BOOST_THROW_EXCEPTION(createTypeError("Type conversion cannot allow named arguments.")); if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType())) BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); @@ -654,8 +715,9 @@ void FunctionCall::checkTypeRequirements() if (!functionType->takesArbitraryParameters() && parameterTypes.size() != m_arguments.size()) BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call.")); - if (m_names.empty()) + if (isPositionalCall) { + // call by positional arguments for (size_t i = 0; i < m_arguments.size(); ++i) if (!functionType->takesArbitraryParameters() && !m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i])) @@ -663,6 +725,7 @@ void FunctionCall::checkTypeRequirements() } else { + // call by named arguments if (functionType->takesArbitraryParameters()) BOOST_THROW_EXCEPTION(createTypeError("Named arguments cannnot be used for functions " "that take arbitrary parameters.")); @@ -700,27 +763,6 @@ void FunctionCall::checkTypeRequirements() else m_type = functionType->getReturnParameterTypes().front(); } - else if (OverloadedFunctionType const* overloadedTypes = dynamic_cast(expressionType)) - { - // this only applies to "x(3)" where x is assigned by "var x = f;" where f is an overloaded functions. - auto identifier = dynamic_cast(m_expression.get()); - solAssert(identifier, "only applies to 'var x = f;'"); - - Declaration const* function = overloadedTypes->getIdentifier()->overloadResolution(*this); - if (!function) - BOOST_THROW_EXCEPTION(createTypeError("Can't resolve declarations")); - - identifier->setReferencedDeclaration(*function); - identifier->checkTypeRequirements(); - - TypePointer type = identifier->getType(); - FunctionType const* functionType = dynamic_cast(type.get()); - - if (functionType->getReturnParameterTypes().empty()) - m_type = make_shared(); - else - m_type = functionType->getReturnParameterTypes().front(); - } else BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); } @@ -730,10 +772,10 @@ bool FunctionCall::isTypeConversion() const return m_expression->getType()->getCategory() == Type::Category::TypeType; } -void NewExpression::checkTypeRequirements() +void NewExpression::checkTypeRequirements(TypePointers const*) { - m_contractName->checkTypeRequirements(); - m_contract = dynamic_cast(m_contractName->getReferencedDeclaration()); + m_contractName->checkTypeRequirements(nullptr); + m_contract = dynamic_cast(&m_contractName->getReferencedDeclaration()); if (!m_contract) BOOST_THROW_EXCEPTION(createTypeError("Identifier is not a contract.")); if (!m_contract->isFullyImplemented()) @@ -744,15 +786,37 @@ void NewExpression::checkTypeRequirements() FunctionType::Location::Creation); } -void MemberAccess::checkTypeRequirements() +void MemberAccess::checkTypeRequirements(TypePointers const* _argumentTypes) { - m_expression->checkTypeRequirements(); + m_expression->checkTypeRequirements(nullptr); Type const& type = *m_expression->getType(); - m_type = type.getMemberType(*m_memberName); - if (!m_type) - BOOST_THROW_EXCEPTION(createTypeError("Member \"" + *m_memberName + "\" not found or not " - "visible in " + type.toString())); - // This should probably move somewhere else. + + MemberList::MemberMap possibleMembers = type.getMembers().membersByName(*m_memberName); + if (possibleMembers.size() > 1 && _argumentTypes) + { + // do override resolution + for (auto it = possibleMembers.begin(); it != possibleMembers.end();) + if ( + it->type->getCategory() == Type::Category::Function && + !dynamic_cast(*it->type).canTakeArguments(*_argumentTypes) + ) + it = possibleMembers.erase(it); + else + ++it; + } + if (possibleMembers.size() == 0) + BOOST_THROW_EXCEPTION(createTypeError( + "Member \"" + *m_memberName + "\" not found or not visible " + "after argument-dependent lookup in " + type.toString() + )); + else if (possibleMembers.size() > 1) + BOOST_THROW_EXCEPTION(createTypeError( + "Member \"" + *m_memberName + "\" not unique " + "after argument-dependent lookup in " + type.toString() + )); + + m_referencedDeclaration = possibleMembers.front().declaration; + m_type = possibleMembers.front().type; if (type.getCategory() == Type::Category::Struct) m_isLValue = true; else if (type.getCategory() == Type::Category::Array) @@ -765,9 +829,9 @@ void MemberAccess::checkTypeRequirements() m_isLValue = false; } -void IndexAccess::checkTypeRequirements() +void IndexAccess::checkTypeRequirements(TypePointers const*) { - m_base->checkTypeRequirements(); + m_base->checkTypeRequirements(nullptr); switch (m_base->getType()->getCategory()) { case Type::Category::Array: @@ -800,7 +864,7 @@ void IndexAccess::checkTypeRequirements() m_type = make_shared(make_shared(ArrayType::Location::Memory, type.getActualType())); else { - m_index->checkTypeRequirements(); + m_index->checkTypeRequirements(nullptr); auto length = dynamic_cast(m_index->getType().get()); if (!length) BOOST_THROW_EXCEPTION(m_index->createTypeError("Integer constant expected.")); @@ -815,89 +879,57 @@ void IndexAccess::checkTypeRequirements() } } -void Identifier::checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall) -{ - solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); - - if (!m_referencedDeclaration) - setReferencedDeclaration(*overloadResolution(_functionCall)); - - checkTypeRequirements(); -} - -void Identifier::checkTypeRequirementsFromVariableDeclaration() +void Identifier::checkTypeRequirements(TypePointers const* _argumentTypes) { - solAssert(m_referencedDeclaration || !m_overloadedDeclarations.empty(), "Identifier not resolved."); - if (!m_referencedDeclaration) - m_type = make_shared(this); - else - checkTypeRequirements(); - - m_isLValue = true; -} - -void Identifier::checkTypeRequirements() -{ - solAssert(m_referencedDeclaration, "Identifier not resolved."); - + { + if (!_argumentTypes) + BOOST_THROW_EXCEPTION(createTypeError("Unable to determine overloaded type.")); + overloadResolution(*_argumentTypes); + } + solAssert(!!m_referencedDeclaration, "Referenced declaration is null after overload resolution."); m_isLValue = m_referencedDeclaration->isLValue(); m_type = m_referencedDeclaration->getType(m_currentContract); if (!m_type) BOOST_THROW_EXCEPTION(createTypeError("Declaration referenced before type could be determined.")); } -Declaration const* Identifier::overloadResolution(FunctionCall const& _functionCall) +Declaration const& Identifier::getReferencedDeclaration() const +{ + solAssert(!!m_referencedDeclaration, "Identifier not resolved."); + return *m_referencedDeclaration; +} + +void Identifier::overloadResolution(TypePointers const& _argumentTypes) { - solAssert(m_overloadedDeclarations.size() > 1, "FunctionIdentifier not resolved."); solAssert(!m_referencedDeclaration, "Referenced declaration should be null before overload resolution."); + solAssert(!m_overloadedDeclarations.empty(), "No candidates for overload resolution found."); - std::vector> arguments = _functionCall.getArguments(); - std::vector> const& argumentNames = _functionCall.getNames(); + std::vector possibles; + if (m_overloadedDeclarations.size() == 1) + m_referencedDeclaration = *m_overloadedDeclarations.begin(); - if (argumentNames.empty()) + for (Declaration const* declaration: m_overloadedDeclarations) { - // positional arguments - std::vector possibles; - for (Declaration const* declaration: m_overloadedDeclarations) - { - TypePointer const& function = declaration->getType(); - auto const& functionType = dynamic_cast(*function); - TypePointers const& parameterTypes = functionType.getParameterTypes(); - - if (functionType.takesArbitraryParameters() || - (arguments.size() == parameterTypes.size() && - std::equal(arguments.cbegin(), arguments.cend(), parameterTypes.cbegin(), - [](ASTPointer const& argument, TypePointer const& parameterType) - { - return argument->getType()->isImplicitlyConvertibleTo(*parameterType); - }))) - possibles.push_back(declaration); - } - if (possibles.empty()) - BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); - else if (std::none_of(possibles.cbegin() + 1, possibles.cend(), - [&possibles](Declaration const* declaration) - { - return declaration->getScope() == possibles.front()->getScope(); - })) - return possibles.front(); - else - BOOST_THROW_EXCEPTION(createTypeError("Can't resolve identifier")); + TypePointer const& function = declaration->getType(); + auto const* functionType = dynamic_cast(function.get()); + if (functionType && functionType->canTakeArguments(_argumentTypes)) + possibles.push_back(declaration); } + if (possibles.size() == 1) + m_referencedDeclaration = possibles.front(); + else if (possibles.empty()) + BOOST_THROW_EXCEPTION(createTypeError("No matching declaration found after argument-dependent lookup.")); else - // named arguments - // TODO: don't support right now - BOOST_THROW_EXCEPTION(createTypeError("Named arguments with overloaded functions are not supported yet.")); - return nullptr; + BOOST_THROW_EXCEPTION(createTypeError("No unique declaration found after argument-dependent lookup.")); } -void ElementaryTypeNameExpression::checkTypeRequirements() +void ElementaryTypeNameExpression::checkTypeRequirements(TypePointers const*) { m_type = make_shared(Type::fromElementaryTypeName(m_typeToken)); } -void Literal::checkTypeRequirements() +void Literal::checkTypeRequirements(TypePointers const*) { m_type = Type::forLiteral(*this); if (!m_type) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index fd50eb956..f0144c7ec 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -282,8 +282,14 @@ public: FunctionDefinition const* getFallbackFunction() const; private: + /// Checks that two functions defined in this contract with the same name have different + /// arguments and that there is at most one constructor. + void checkDuplicateFunctions() const; void checkIllegalOverrides() const; void checkAbstractFunctions(); + /// Checks that different functions with external visibility end up having different + /// external argument types (i.e. different signature). + void checkExternalTypeClashes() const; std::vector, FunctionTypePointer>> const& getInterfaceFunctionList() const; @@ -967,7 +973,10 @@ class Expression: public ASTNode { public: Expression(SourceLocation const& _location): ASTNode(_location) {} - virtual void checkTypeRequirements() = 0; + /// Performs type checking after which m_type should be set. + /// @arg _argumentTypes if set, provides the argument types for the case that this expression + /// is used in the context of a call, used for function overload resolution. + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) = 0; std::shared_ptr const& getType() const { return m_type; } bool isLValue() const { return m_isLValue; } @@ -1006,7 +1015,7 @@ public: } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Expression const& getLeftHandSide() const { return *m_leftHandSide; } Token::Value getAssignmentOperator() const { return m_assigmentOperator; } @@ -1034,7 +1043,7 @@ public: } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Token::Value getOperator() const { return m_operator; } bool isPrefixOperation() const { return m_isPrefix; } @@ -1061,7 +1070,7 @@ public: } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Expression const& getLeftExpression() const { return *m_left; } Expression const& getRightExpression() const { return *m_right; } @@ -1089,7 +1098,7 @@ public: Expression(_location), m_expression(_expression), m_arguments(_arguments), m_names(_names) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Expression const& getExpression() const { return *m_expression; } std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } @@ -1115,7 +1124,7 @@ public: Expression(_location), m_contractName(_contractName) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; /// Returns the referenced contract. Can only be called after type checking. ContractDefinition const* getContract() const { solAssert(m_contract, ""); return m_contract; } @@ -1139,11 +1148,18 @@ public: virtual void accept(ASTConstVisitor& _visitor) const override; Expression const& getExpression() const { return *m_expression; } ASTString const& getMemberName() const { return *m_memberName; } - virtual void checkTypeRequirements() override; + /// @returns the declaration referenced by this expression. Might return nullptr even if the + /// expression is valid, e.g. if the member does not correspond to an AST node. + Declaration const* referencedDeclaration() const { return m_referencedDeclaration; } + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; private: ASTPointer m_expression; ASTPointer m_memberName; + + /// Pointer to the referenced declaration, this is sometimes needed to resolve function over + /// loads in the type-checking phase. + Declaration const* m_referencedDeclaration = nullptr; }; /** @@ -1157,7 +1173,7 @@ public: Expression(_location), m_base(_base), m_index(_index) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Expression const& getBaseExpression() const { return *m_base; } Expression const* getIndexExpression() const { return m_index.get(); } @@ -1187,28 +1203,33 @@ public: PrimaryExpression(_location), m_name(_name) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; ASTString const& getName() const { return *m_name; } - void setReferencedDeclaration(Declaration const& _referencedDeclaration, - ContractDefinition const* _currentContract = nullptr) + void setReferencedDeclaration( + Declaration const& _referencedDeclaration, + ContractDefinition const* _currentContract = nullptr + ) { m_referencedDeclaration = &_referencedDeclaration; m_currentContract = _currentContract; } - Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; } - ContractDefinition const* getCurrentContract() const { return m_currentContract; } + Declaration const& getReferencedDeclaration() const; - void setOverloadedDeclarations(std::set const& _declarations) { m_overloadedDeclarations = _declarations; } - std::set getOverloadedDeclarations() const { return m_overloadedDeclarations; } + /// Stores a set of possible declarations referenced by this identifier. Has to be resolved + /// providing argument types using overloadResolution before the referenced declaration + /// is accessed. + void setOverloadedDeclarations(std::set const& _declarations) + { + m_overloadedDeclarations = _declarations; + } - void checkTypeRequirementsWithFunctionCall(FunctionCall const& _functionCall); - void checkTypeRequirementsFromVariableDeclaration(); + /// Tries to find exactly one of the possible referenced declarations provided the given + /// argument types in a call context. + void overloadResolution(TypePointers const& _argumentTypes); - Declaration const* overloadResolution(FunctionCall const& _functionCall); private: - ASTPointer m_name; /// Declaration the name refers to. @@ -1235,7 +1256,7 @@ public: } virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Token::Value getTypeToken() const { return m_typeToken; } @@ -1269,7 +1290,7 @@ public: PrimaryExpression(_location), m_token(_token), m_value(_value), m_subDenomination(_sub) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; - virtual void checkTypeRequirements() override; + virtual void checkTypeRequirements(TypePointers const* _argumentTypes) override; Token::Value getToken() const { return m_token; } /// @returns the non-parsed value of the literal diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 8e2634499..a8d0a5910 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -90,7 +90,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp for (auto const& modifier: constructor->getModifiers()) { auto baseContract = dynamic_cast( - modifier->getName()->getReferencedDeclaration()); + &modifier->getName()->getReferencedDeclaration()); if (baseContract) if (m_baseArguments.count(baseContract->getConstructor()) == 0) m_baseArguments[baseContract->getConstructor()] = &modifier->getArguments(); @@ -99,7 +99,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp for (ASTPointer const& base: contract->getBaseContracts()) { ContractDefinition const* baseContract = dynamic_cast( - base->getName()->getReferencedDeclaration()); + &base->getName()->getReferencedDeclaration()); solAssert(baseContract, ""); if (m_baseArguments.count(baseContract->getConstructor()) == 0) @@ -545,7 +545,7 @@ void Compiler::appendModifierOrFunctionCode() ASTPointer const& modifierInvocation = m_currentFunction->getModifiers()[m_modifierDepth]; // constructor call should be excluded - if (dynamic_cast(modifierInvocation->getName()->getReferencedDeclaration())) + if (dynamic_cast(&modifierInvocation->getName()->getReferencedDeclaration())) { ++m_modifierDepth; appendModifierOrFunctionCode(); diff --git a/libsolidity/CompilerContext.cpp b/libsolidity/CompilerContext.cpp index 0afda1367..f373fdfb0 100644 --- a/libsolidity/CompilerContext.cpp +++ b/libsolidity/CompilerContext.cpp @@ -102,27 +102,13 @@ eth::AssemblyItem CompilerContext::getFunctionEntryLabel(Declaration const& _dec eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel(FunctionDefinition const& _function) { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); - for (ContractDefinition const* contract: m_inheritanceHierarchy) - for (ASTPointer const& function: contract->getDefinedFunctions()) - { - if (!function->isConstructor() && - dynamic_cast(*function->getType(contract)).getCanonicalSignature() == - dynamic_cast(*_function.getType(contract)).getCanonicalSignature()) - return getFunctionEntryLabel(*function); - } - solAssert(false, "Virtual function " + _function.getName() + " not found."); - return m_asm.newTag(); // not reached + return getVirtualFunctionEntryLabel(_function, m_inheritanceHierarchy.begin()); } -eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(string const& _name, ContractDefinition const& _base) +eth::AssemblyItem CompilerContext::getSuperFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base) { - auto it = getSuperContract(_base); - for (; it != m_inheritanceHierarchy.end(); ++it) - for (ASTPointer const& function: (*it)->getDefinedFunctions()) - if (!function->isConstructor() && function->getName() == _name) // TODO: add a test case for this! - return getFunctionEntryLabel(*function); - solAssert(false, "Super function " + _name + " not found."); - return m_asm.newTag(); // not reached + solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); + return getVirtualFunctionEntryLabel(_function, getSuperContract(_base)); } FunctionDefinition const* CompilerContext::getNextConstructor(ContractDefinition const& _contract) const @@ -194,6 +180,26 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node) updateSourceLocation(); } +eth::AssemblyItem CompilerContext::getVirtualFunctionEntryLabel( + FunctionDefinition const& _function, + vector::const_iterator _searchStart +) +{ + string name = _function.getName(); + FunctionType functionType(_function); + auto it = _searchStart; + for (; it != m_inheritanceHierarchy.end(); ++it) + for (ASTPointer const& function: (*it)->getDefinedFunctions()) + if ( + function->getName() == name && + !function->isConstructor() && + FunctionType(*function).hasEqualArgumentTypes(functionType) + ) + return getFunctionEntryLabel(*function); + solAssert(false, "Super function " + name + " not found."); + return m_asm.newTag(); // not reached +} + vector::const_iterator CompilerContext::getSuperContract(ContractDefinition const& _contract) const { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); diff --git a/libsolidity/CompilerContext.h b/libsolidity/CompilerContext.h index 87f90d4c4..67dd3c94b 100644 --- a/libsolidity/CompilerContext.h +++ b/libsolidity/CompilerContext.h @@ -63,9 +63,9 @@ public: void setInheritanceHierarchy(std::vector const& _hierarchy) { m_inheritanceHierarchy = _hierarchy; } /// @returns the entry label of the given function and takes overrides into account. eth::AssemblyItem getVirtualFunctionEntryLabel(FunctionDefinition const& _function); - /// @returns the entry label of function with the given name from the most derived class just + /// @returns the entry label of a function that overrides the given declaration from the most derived class just /// above _base in the current inheritance hierarchy. - eth::AssemblyItem getSuperFunctionEntryLabel(std::string const& _name, ContractDefinition const& _base); + eth::AssemblyItem getSuperFunctionEntryLabel(FunctionDefinition const& _function, ContractDefinition const& _base); FunctionDefinition const* getNextConstructor(ContractDefinition const& _contract) const; /// @returns the set of functions for which we still need to generate code @@ -136,6 +136,13 @@ public: }; private: + /// @returns the entry label of the given function - searches the inheritance hierarchy + /// startig from the given point towards the base. + eth::AssemblyItem getVirtualFunctionEntryLabel( + FunctionDefinition const& _function, + std::vector::const_iterator _searchStart + ); + /// @returns an iterator to the contract directly above the given contract. std::vector::const_iterator getSuperContract(const ContractDefinition &_contract) const; /// Updates source location set in the assembly. void updateSourceLocation(); diff --git a/libsolidity/DeclarationContainer.cpp b/libsolidity/DeclarationContainer.cpp index 226b9d680..565f71dfd 100644 --- a/libsolidity/DeclarationContainer.cpp +++ b/libsolidity/DeclarationContainer.cpp @@ -35,30 +35,29 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, if (name.empty()) return true; - if (!_update) + if (_update) + { + solAssert(!dynamic_cast(&_declaration), "Attempt to update function definition."); + m_declarations[name].clear(); + m_invisibleDeclarations[name].clear(); + } + else { if (dynamic_cast(&_declaration)) { - // other declarations must be FunctionDefinition, otherwise clash with other declarations. - for (auto&& declaration: m_declarations[_declaration.getName()]) - if (dynamic_cast(declaration) == nullptr) + // check that all other declarations with the same name are functions + for (auto&& declaration: m_invisibleDeclarations[name] + m_declarations[name]) + if (!dynamic_cast(declaration)) return false; } - else if (m_declarations.count(_declaration.getName()) != 0) - return false; - } - else - { - // update declaration - solAssert(dynamic_cast(&_declaration) == nullptr, "cannot be FunctionDefinition"); - - m_declarations[_declaration.getName()].clear(); + else if (m_declarations.count(name) > 0 || m_invisibleDeclarations.count(name) > 0) + return false; } if (_invisible) - m_invisibleDeclarations.insert(name); + m_invisibleDeclarations[name].insert(&_declaration); else - m_declarations[_declaration.getName()].insert(&_declaration); + m_declarations[name].insert(&_declaration); return true; } diff --git a/libsolidity/DeclarationContainer.h b/libsolidity/DeclarationContainer.h index 42784ec2a..35a6ea077 100644 --- a/libsolidity/DeclarationContainer.h +++ b/libsolidity/DeclarationContainer.h @@ -56,7 +56,7 @@ private: Declaration const* m_enclosingDeclaration; DeclarationContainer const* m_enclosingContainer; std::map> m_declarations; - std::set m_invisibleDeclarations; + std::map> m_invisibleDeclarations; }; } diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3ca8de89e..8c8c3ee0d 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -601,13 +601,25 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) bool alsoSearchInteger = false; ContractType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); if (type.isSuper()) - m_context << m_context.getSuperFunctionEntryLabel(member, type.getContractDefinition()).pushTag(); + { + solAssert(!!_memberAccess.referencedDeclaration(), "Referenced declaration not resolved."); + m_context << m_context.getSuperFunctionEntryLabel( + dynamic_cast(*_memberAccess.referencedDeclaration()), + type.getContractDefinition() + ).pushTag(); + } else { // ordinary contract type - u256 identifier = type.getFunctionIdentifier(member); - if (identifier != Invalid256) + if (Declaration const* declaration = _memberAccess.referencedDeclaration()) { + u256 identifier; + if (auto const* variable = dynamic_cast(declaration)) + identifier = FunctionType(*variable).externalIdentifier(); + else if (auto const* function = dynamic_cast(declaration)) + identifier = FunctionType(*function).externalIdentifier(); + else + solAssert(false, "Contract member is neither variable nor function."); appendTypeConversion(type, IntegerType(0, IntegerType::Modifier::Address), true); m_context << identifier; } @@ -683,19 +695,16 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) case Type::Category::TypeType: { TypeType const& type = dynamic_cast(*_memberAccess.getExpression().getType()); - if (!type.getMembers().getMemberType(member)) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid member access to " + type.toString())); + solAssert( + !type.getMembers().membersByName(_memberAccess.getMemberName()).empty(), + "Invalid member access to " + type.toString() + ); - if (auto contractType = dynamic_cast(type.getActualType().get())) + if (dynamic_cast(type.getActualType().get())) { - ContractDefinition const& contract = contractType->getContractDefinition(); - for (ASTPointer const& function: contract.getDefinedFunctions()) - if (function->getName() == member) - { - m_context << m_context.getFunctionEntryLabel(*function).pushTag(); - return; - } - solAssert(false, "Function not found in member access."); + auto const* function = dynamic_cast(_memberAccess.referencedDeclaration()); + solAssert(!!function, "Function not found in member access"); + m_context << m_context.getFunctionEntryLabel(*function).pushTag(); } else if (auto enumType = dynamic_cast(type.getActualType().get())) m_context << enumType->getMemberValue(_memberAccess.getMemberName()); @@ -780,7 +789,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) void ExpressionCompiler::endVisit(Identifier const& _identifier) { CompilerContext::LocationSetter locationSetter(m_context, _identifier); - Declaration const* declaration = _identifier.getReferencedDeclaration(); + Declaration const* declaration = &_identifier.getReferencedDeclaration(); if (MagicVariableDeclaration const* magicVar = dynamic_cast(declaration)) { switch (magicVar->getType()->getCategory()) @@ -819,13 +828,6 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) { // no-op } - else if (declaration == nullptr && _identifier.getOverloadedDeclarations().size() > 1) - { - // var x = f; - declaration = *_identifier.getOverloadedDeclarations().begin(); - FunctionDefinition const* functionDef = dynamic_cast(declaration); - m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag(); - } else { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context.")); diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index 234072bce..fc990b0aa 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -177,10 +177,10 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc for (auto const& member: structType.getMembers()) { // assign each member that is not a mapping - TypePointer const& memberType = member.second; + TypePointer const& memberType = member.type; if (memberType->getCategory() == Type::Category::Mapping) continue; - pair const& offsets = structType.getStorageOffsetsOfMember(member.first); + pair const& offsets = structType.getStorageOffsetsOfMember(member.name); m_context << offsets.first << u256(offsets.second) << eth::Instruction::DUP6 << eth::Instruction::DUP3 @@ -230,10 +230,10 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const for (auto const& member: structType.getMembers()) { // zero each member that is not a mapping - TypePointer const& memberType = member.second; + TypePointer const& memberType = member.type; if (memberType->getCategory() == Type::Category::Mapping) continue; - pair const& offsets = structType.getStorageOffsetsOfMember(member.first); + pair const& offsets = structType.getStorageOffsetsOfMember(member.name); m_context << offsets.first << eth::Instruction::DUP3 << eth::Instruction::ADD << u256(offsets.second); diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index c787ae6b0..1c527b89c 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -53,8 +53,9 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) m_currentScope = &m_scopes[&_contract]; linearizeBaseContracts(_contract); + // we first import non-functions only as we do not yet know the argument types for (ContractDefinition const* base: _contract.getLinearizedBaseContracts()) - importInheritedScope(*base); + importInheritedScope(*base, false); // import non-functions for (ASTPointer const& structDef: _contract.getDefinedStructs()) ReferencesResolver resolver(*structDef, *this, &_contract, nullptr); @@ -64,6 +65,8 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) ReferencesResolver resolver(*variable, *this, &_contract, nullptr); for (ASTPointer const& event: _contract.getEvents()) ReferencesResolver resolver(*event, *this, &_contract, nullptr); + + // these can contain code, only resolve parameters for now for (ASTPointer const& modifier: _contract.getFunctionModifiers()) { m_currentScope = &m_scopes[modifier.get()]; @@ -75,6 +78,28 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) ReferencesResolver referencesResolver(*function, *this, &_contract, function->getReturnParameterList().get()); } + + m_currentScope = &m_scopes[&_contract]; + for (ContractDefinition const* base: _contract.getLinearizedBaseContracts()) + importInheritedScope(*base, true); // import functions + + // now resolve references inside the code + for (ASTPointer const& modifier: _contract.getFunctionModifiers()) + { + m_currentScope = &m_scopes[modifier.get()]; + ReferencesResolver resolver(*modifier, *this, &_contract, nullptr, true); + } + for (ASTPointer const& function: _contract.getDefinedFunctions()) + { + m_currentScope = &m_scopes[function.get()]; + ReferencesResolver referencesResolver( + *function, + *this, + &_contract, + function->getReturnParameterList().get(), + true + ); + } } void NameAndTypeResolver::checkTypeRequirements(ContractDefinition& _contract) @@ -90,7 +115,7 @@ void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) solAssert(_declaration.getScope() == nullptr, "Updated declaration outside global scope."); } -std::set NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const +set NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const { auto iterator = m_scopes.find(_scope); if (iterator == end(m_scopes)) @@ -98,21 +123,43 @@ std::set NameAndTypeResolver::resolveName(ASTString const& _ return iterator->second.resolveName(_name, false); } -std::set NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive) +set NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive) { return m_currentScope->resolveName(_name, _recursive); } -void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) +void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base, bool _importFunctions) { auto iterator = m_scopes.find(&_base); solAssert(iterator != end(m_scopes), ""); for (auto const& nameAndDeclaration: iterator->second.getDeclarations()) for (auto const& declaration: nameAndDeclaration.second) // Import if it was declared in the base, is not the constructor and is visible in derived classes - if (declaration->getScope() == &_base && declaration->getName() != _base.getName() && - declaration->isVisibleInDerivedContracts()) + if (declaration->getScope() == &_base && declaration->isVisibleInDerivedContracts()) + { + auto function = dynamic_cast(declaration); + if ((function == nullptr) == _importFunctions) + continue; + if (!!function) + { + FunctionType functionType(*function); + // only import if a function with the same arguments does not exist yet + bool functionWithEqualArgumentsFound = false; + for (auto knownDeclaration: m_currentScope->resolveName(nameAndDeclaration.first)) + { + auto knownFunction = dynamic_cast(knownDeclaration); + if (!knownFunction) + continue; // this is not legal, but will be caught later + if (!FunctionType(*knownFunction).hasEqualArgumentTypes(functionType)) + continue; + functionWithEqualArgumentsFound = true; + break; + } + if (functionWithEqualArgumentsFound) + continue; + } m_currentScope->registerDeclaration(*declaration); + } } void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) const @@ -123,8 +170,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) for (ASTPointer const& baseSpecifier: _contract.getBaseContracts()) { ASTPointer baseName = baseSpecifier->getName(); - ContractDefinition const* base = dynamic_cast( - baseName->getReferencedDeclaration()); + auto base = dynamic_cast(&baseName->getReferencedDeclaration()); if (!base) BOOST_THROW_EXCEPTION(baseName->createTypeError("Contract expected.")); // "push_front" has the effect that bases mentioned later can overwrite members of bases @@ -316,11 +362,19 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio enterNewSubScope(_declaration); } -ReferencesResolver::ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, - ContractDefinition const* _currentContract, - ParameterList const* _returnParameters, bool _allowLazyTypes): - m_resolver(_resolver), m_currentContract(_currentContract), - m_returnParameters(_returnParameters), m_allowLazyTypes(_allowLazyTypes) +ReferencesResolver::ReferencesResolver( + ASTNode& _root, + NameAndTypeResolver& _resolver, + ContractDefinition const* _currentContract, + ParameterList const* _returnParameters, + bool _resolveInsideCode, + bool _allowLazyTypes +): + m_resolver(_resolver), + m_currentContract(_currentContract), + m_returnParameters(_returnParameters), + m_resolveInsideCode(_resolveInsideCode), + m_allowLazyTypes(_allowLazyTypes) { _root.accept(*this); } diff --git a/libsolidity/NameAndTypeResolver.h b/libsolidity/NameAndTypeResolver.h index 828776179..6528bbef2 100644 --- a/libsolidity/NameAndTypeResolver.h +++ b/libsolidity/NameAndTypeResolver.h @@ -65,9 +65,10 @@ public: private: void reset(); - /// Imports all members declared directly in the given contract (i.e. does not import inherited - /// members) into the current scope if they are not present already. - void importInheritedScope(ContractDefinition const& _base); + /// Either imports all non-function members or all function members declared directly in the + /// given contract (i.e. does not import inherited members) into the current scope if they are + ///not present already. + void importInheritedScope(ContractDefinition const& _base, bool _importFunctions); /// Computes "C3-Linearization" of base contracts and stores it inside the contract. void linearizeBaseContracts(ContractDefinition& _contract) const; @@ -126,13 +127,18 @@ private: class ReferencesResolver: private ASTVisitor { public: - ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, - ContractDefinition const* _currentContract, - ParameterList const* _returnParameters, - bool _allowLazyTypes = true); + ReferencesResolver( + ASTNode& _root, + NameAndTypeResolver& _resolver, + ContractDefinition const* _currentContract, + ParameterList const* _returnParameters, + bool _resolveInsideCode = false, + bool _allowLazyTypes = true + ); private: virtual void endVisit(VariableDeclaration& _variable) override; + virtual bool visit(Block&) override { return m_resolveInsideCode; } virtual bool visit(Identifier& _identifier) override; virtual bool visit(UserDefinedTypeName& _typeName) override; virtual bool visit(Mapping&) override; @@ -141,6 +147,7 @@ private: NameAndTypeResolver& m_resolver; ContractDefinition const* m_currentContract; ParameterList const* m_returnParameters; + bool m_resolveInsideCode; bool m_allowLazyTypes; }; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 78649cc95..e35dc0b6f 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -92,13 +93,13 @@ std::pair const* MemberList::getMemberStorageOffset(string const { TypePointers memberTypes; memberTypes.reserve(m_memberTypes.size()); - for (auto const& nameAndType: m_memberTypes) - memberTypes.push_back(nameAndType.second); + for (auto const& member: m_memberTypes) + memberTypes.push_back(member.type); m_storageOffsets.reset(new StorageOffsets()); m_storageOffsets->computeOffsets(memberTypes); } for (size_t index = 0; index < m_memberTypes.size(); ++index) - if (m_memberTypes[index].first == _name) + if (m_memberTypes[index].name == _name) return m_storageOffsets->getOffset(index); return nullptr; } @@ -189,7 +190,7 @@ TypePointer Type::fromArrayTypeName(TypeName& _baseTypeName, Expression* _length if (_length) { if (!_length->getType()) - _length->checkTypeRequirements(); + _length->checkTypeRequirements(nullptr); auto const* length = dynamic_cast(_length->getType().get()); if (!length) BOOST_THROW_EXCEPTION(_length->createTypeError("Invalid array length.")); @@ -793,18 +794,46 @@ MemberList const& ContractType::getMembers() const if (!m_members) { // All address members and all interface functions - vector> members(IntegerType::AddressMemberList.begin(), - IntegerType::AddressMemberList.end()); + MemberList::MemberMap members( + IntegerType::AddressMemberList.begin(), + IntegerType::AddressMemberList.end() + ); if (m_super) { + // add the most derived of all functions which are visible in derived contracts for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts()) for (ASTPointer const& function: base->getDefinedFunctions()) - if (function->isVisibleInDerivedContracts()) - members.push_back(make_pair(function->getName(), make_shared(*function, true))); + { + if (!function->isVisibleInDerivedContracts()) + continue; + auto functionType = make_shared(*function, true); + bool functionWithEqualArgumentsFound = false; + for (auto const& member: members) + { + if (member.name != function->getName()) + continue; + auto memberType = dynamic_cast(member.type.get()); + solAssert(!!memberType, "Override changes type."); + if (!memberType->hasEqualArgumentTypes(*functionType)) + continue; + functionWithEqualArgumentsFound = true; + break; + } + if (!functionWithEqualArgumentsFound) + members.push_back(MemberList::Member( + function->getName(), + functionType, + function.get() + )); + } } else for (auto const& it: m_contract.getInterfaceFunctions()) - members.push_back(make_pair(it.second->getDeclaration().getName(), it.second)); + members.push_back(MemberList::Member( + it.second->getDeclaration().getName(), + it.second, + &it.second->getDeclaration() + )); m_members.reset(new MemberList(members)); } return *m_members; @@ -823,16 +852,6 @@ shared_ptr const& ContractType::getConstructorType() const return m_constructorType; } -u256 ContractType::getFunctionIdentifier(string const& _functionName) const -{ - auto interfaceFunctions = m_contract.getInterfaceFunctions(); - for (auto const& it: m_contract.getInterfaceFunctions()) - if (it.second->getDeclaration().getName() == _functionName) - return FixedHash<4>::Arith(it.first); - - return Invalid256; -} - vector> ContractType::getStateVariables() const { vector variables; @@ -873,8 +892,8 @@ u256 StructType::getStorageSize() const bool StructType::canLiveOutsideStorage() const { - for (pair const& member: getMembers()) - if (!member.second->canLiveOutsideStorage()) + for (auto const& member: getMembers()) + if (!member.type->canLiveOutsideStorage()) return false; return true; } @@ -891,7 +910,7 @@ MemberList const& StructType::getMembers() const { MemberList::MemberMap members; for (ASTPointer const& variable: m_struct.getMembers()) - members.push_back(make_pair(variable->getName(), variable->getType())); + members.push_back(MemberList::Member(variable->getName(), variable->getType(), variable.get())); m_members.reset(new MemberList(members)); } return *m_members; @@ -996,11 +1015,11 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): vector retParamNames; if (auto structType = dynamic_cast(returnType.get())) { - for (pair const& member: structType->getMembers()) - if (member.second->canLiveOutsideStorage()) + for (auto const& member: structType->getMembers()) + if (member.type->canLiveOutsideStorage()) { - retParamNames.push_back(member.first); - retParams.push_back(member.second); + retParamNames.push_back(member.name); + retParams.push_back(member.type); } } else @@ -1130,12 +1149,12 @@ MemberList const& FunctionType::getMembers() const case Location::Bare: if (!m_members) { - vector> members{ + MemberList::MemberMap members{ {"value", make_shared(parseElementaryTypeVector({"uint"}), TypePointers{copyAndSetGasOrValue(false, true)}, Location::SetValue, false, m_gasSet, m_valueSet)}}; if (m_location != Location::Creation) - members.push_back(make_pair("gas", make_shared( + members.push_back(MemberList::Member("gas", make_shared( parseElementaryTypeVector({"uint"}), TypePointers{copyAndSetGasOrValue(true, false)}, Location::SetGas, false, m_gasSet, m_valueSet))); @@ -1147,6 +1166,37 @@ MemberList const& FunctionType::getMembers() const } } +bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes) const +{ + TypePointers const& parameterTypes = getParameterTypes(); + if (takesArbitraryParameters()) + return true; + else if (_argumentTypes.size() != parameterTypes.size()) + return false; + else + return std::equal( + _argumentTypes.cbegin(), + _argumentTypes.cend(), + parameterTypes.cbegin(), + [](TypePointer const& argumentType, TypePointer const& parameterType) + { + return argumentType->isImplicitlyConvertibleTo(*parameterType); + } + ); +} + +bool FunctionType::hasEqualArgumentTypes(FunctionType const& _other) const +{ + if (m_parameterTypes.size() != _other.m_parameterTypes.size()) + return false; + return equal( + m_parameterTypes.cbegin(), + m_parameterTypes.cend(), + _other.m_parameterTypes.cbegin(), + [](TypePointer const& _a, TypePointer const& _b) -> bool { return *_a == *_b; } + ); +} + string FunctionType::externalSignature(std::string const& _name) const { std::string funcName = _name; @@ -1167,6 +1217,11 @@ string FunctionType::externalSignature(std::string const& _name) const return ret + ")"; } +u256 FunctionType::externalIdentifier() const +{ + return FixedHash<4>::Arith(FixedHash<4>(dev::sha3(externalSignature()))); +} + TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) { TypePointers pointers; @@ -1250,7 +1305,7 @@ MemberList const& TypeType::getMembers() const // We need to lazy-initialize it because of recursive references. if (!m_members) { - vector> members; + MemberList::MemberMap members; if (m_actualType->getCategory() == Category::Contract && m_currentContract != nullptr) { ContractDefinition const& contract = dynamic_cast(*m_actualType).getContractDefinition(); @@ -1259,14 +1314,14 @@ MemberList const& TypeType::getMembers() const // We are accessing the type of a base contract, so add all public and protected // members. Note that this does not add inherited functions on purpose. for (Declaration const* decl: contract.getInheritableMembers()) - members.push_back(make_pair(decl->getName(), decl->getType())); + members.push_back(MemberList::Member(decl->getName(), decl->getType(), decl)); } else if (m_actualType->getCategory() == Category::Enum) { EnumDefinition const& enumDef = dynamic_cast(*m_actualType).getEnumDefinition(); auto enumType = make_shared(enumDef); for (ASTPointer const& enumValue: enumDef.getMembers()) - members.push_back(make_pair(enumValue->getName(), enumType)); + members.push_back(MemberList::Member(enumValue->getName(), enumType)); } m_members.reset(new MemberList(members)); } diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 5fa09f690..446737faa 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -69,17 +69,43 @@ private: class MemberList { public: - using MemberMap = std::vector>; + struct Member + { + Member(std::string const& _name, TypePointer const& _type, Declaration const* _declaration = nullptr): + name(_name), + type(_type), + declaration(_declaration) + { + } + + std::string name; + TypePointer type; + Declaration const* declaration = nullptr; + }; + + using MemberMap = std::vector; MemberList() {} explicit MemberList(MemberMap const& _members): m_memberTypes(_members) {} MemberList& operator=(MemberList&& _other); TypePointer getMemberType(std::string const& _name) const { + TypePointer type; for (auto const& it: m_memberTypes) - if (it.first == _name) - return it.second; - return TypePointer(); + if (it.name == _name) + { + solAssert(!type, "Requested member type by non-unique name."); + type = it.type; + } + return type; + } + MemberMap membersByName(std::string const& _name) const + { + MemberMap members; + for (auto const& it: m_memberTypes) + if (it.name == _name) + members.push_back(it); + return members; } /// @returns the offset of the given member in storage slots and bytes inside a slot or /// a nullptr if the member is not part of storage. @@ -104,7 +130,7 @@ public: enum class Category { Integer, IntegerConstant, Bool, Real, Array, - FixedBytes, Contract, Struct, Function, OverloadedFunctions, Enum, + FixedBytes, Contract, Struct, Function, Enum, Mapping, Void, TypeType, Modifier, Magic }; @@ -554,11 +580,18 @@ public: virtual unsigned getSizeOnStack() const override; virtual MemberList const& getMembers() const override; + /// @returns true if this function can take the given argument types (possibly + /// after implicit conversion). + bool canTakeArguments(TypePointers const& _arguments) const; + bool hasEqualArgumentTypes(FunctionType const& _other) const; + Location const& getLocation() const { return m_location; } /// @returns the external signature of this function type given the function name /// If @a _name is not provided (empty string) then the @c m_declaration member of the /// function type is used std::string externalSignature(std::string const& _name = "") const; + /// @returns the external identifier of this function (the hash of the signature). + u256 externalIdentifier() const; Declaration const& getDeclaration() const { solAssert(m_declaration, "Requested declaration from a FunctionType that has none"); @@ -597,20 +630,6 @@ private: Declaration const* m_declaration = nullptr; }; -class OverloadedFunctionType: public Type -{ -public: - explicit OverloadedFunctionType(Identifier* _identifier): m_identifier(_identifier) {} - - virtual Category getCategory() const override { return Category::OverloadedFunctions; } - virtual std::string toString() const override { return "OverloadedFunctions"; } - - Identifier* getIdentifier() const { return m_identifier; } - -private: - Identifier * m_identifier; -}; - /** * The type of a mapping, there is one distinct type per key/value type pair. * Mappings always occupy their own storage slot, but do not actually use it. diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 3c4972fcf..6c54f4c02 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -397,8 +397,8 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) StructType const* s = dynamic_cast(_type); for(auto const& structMember: s->getMembers()) { - auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.first); - r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.first), nodeType(structMember.second.get()), slotAndOffset.first, slotAndOffset.second }); + auto slotAndOffset = s->getStorageOffsetsOfMember(structMember.name); + r.members.push_back(SolidityDeclaration { QString::fromStdString(structMember.name), nodeType(structMember.type.get()), slotAndOffset.first, slotAndOffset.second }); } } break; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 8218a2524..c18b3c562 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -304,7 +304,6 @@ BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr) BOOST_AUTO_TEST_CASE(calling_other_functions) { - // note that the index of a function is its index in the sorted sequence of functions char const* sourceCode = "contract collatz {\n" " function run(uint x) returns(uint y) {\n" " while ((y = x) > 1) {\n" @@ -1095,26 +1094,6 @@ BOOST_AUTO_TEST_CASE(now) BOOST_CHECK(callContractFunction("someInfo()") == encodeArgs(true)); } -BOOST_AUTO_TEST_CASE(function_types) -{ - char const* sourceCode = "contract test {\n" - " function a(bool selector) returns (uint b) {\n" - " var f = fun1;\n" - " if (selector) f = fun2;\n" - " return f(9);\n" - " }\n" - " function fun1(uint x) returns (uint b) {\n" - " return 11;\n" - " }\n" - " function fun2(uint x) returns (uint b) {\n" - " return 12;\n" - " }\n" - "}\n"; - compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("a(bool)", false) == encodeArgs(11)); - BOOST_CHECK(callContractFunction("a(bool)", true) == encodeArgs(12)); -} - BOOST_AUTO_TEST_CASE(type_conversions_cleanup) { // 22-byte integer converted to a contract (i.e. address, 20 bytes), converted to a 32 byte @@ -3571,6 +3550,61 @@ BOOST_AUTO_TEST_CASE(packed_storage_structs_bytes) BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); } +BOOST_AUTO_TEST_CASE(packed_storage_structs_delete) +{ + char const* sourceCode = R"( + contract C { + struct str { uint8 a; uint16 b; uint8 c; } + uint8 x; + uint16 y; + str data; + function test() returns (uint) { + x = 1; + y = 2; + data.a = 2; + data.b = 0xabcd; + data.c = 0xfa; + if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa) + return 2; + delete y; + delete data.b; + if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa) + return 3; + delete x; + delete data; + return 1; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); + BOOST_CHECK(m_state.storage(m_contractAddress).empty()); +} + +BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0) +{ + char const* sourceCode = R"( + contract C { + struct str { uint8 a; bytes0 b; uint8 c; } + uint8 a; + bytes0 x; + uint8 b; + str data; + function test() returns (bool) { + a = 2; + b = 3; + data.a = 4; + data.c = 5; + delete x; + delete data.b; + return a == 2 && b == 3 && data.a == 4 && data.c == 5; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); +} + BOOST_AUTO_TEST_CASE(overloaded_function_call_resolve_to_first) { char const* sourceCode = R"( @@ -3616,26 +3650,6 @@ BOOST_AUTO_TEST_CASE(overloaded_function_call_with_if_else) BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); } -BOOST_AUTO_TEST_CASE(overloaded_function_with_var) -{ - char const* sourceCode = R"( - contract test { - function f(uint k) returns(uint d) { return k; } - function f(uint a, uint b) returns(uint d) { return a + b; } - function g(bool flag) returns(uint d) { - var x = f; - if (flag) - return x(3); - else - return x(3, 7); - } - } - )"; - compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("g(bool)", true) == encodeArgs(3)); - BOOST_CHECK(callContractFunction("g(bool)", false) == encodeArgs(10)); -} - BOOST_AUTO_TEST_CASE(derived_overload_base_function_direct) { char const* sourceCode = R"( @@ -3664,59 +3678,19 @@ BOOST_AUTO_TEST_CASE(derived_overload_base_function_indirect) BOOST_CHECK(callContractFunction("h()") == encodeArgs(2)); } -BOOST_AUTO_TEST_CASE(packed_storage_structs_delete) +BOOST_AUTO_TEST_CASE(super_overload) { char const* sourceCode = R"( - contract C { - struct str { uint8 a; uint16 b; uint8 c; } - uint8 x; - uint16 y; - str data; - function test() returns (uint) { - x = 1; - y = 2; - data.a = 2; - data.b = 0xabcd; - data.c = 0xfa; - if (x != 1 || y != 2 || data.a != 2 || data.b != 0xabcd || data.c != 0xfa) - return 2; - delete y; - delete data.b; - if (x != 1 || y != 0 || data.a != 2 || data.b != 0 || data.c != 0xfa) - return 3; - delete x; - delete data; - return 1; - } - } - )"; - compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("test()") == encodeArgs(1)); - BOOST_CHECK(m_state.storage(m_contractAddress).empty()); -} - -BOOST_AUTO_TEST_CASE(packed_storage_structs_with_bytes0) -{ - char const* sourceCode = R"( - contract C { - struct str { uint8 a; bytes0 b; uint8 c; } - uint8 a; - bytes0 x; - uint8 b; - str data; - function test() returns (bool) { - a = 2; - b = 3; - data.a = 4; - data.c = 5; - delete x; - delete data.b; - return a == 2 && b == 3 && data.a == 4 && data.c == 5; - } + contract A { function f(uint a) returns(uint) { return 2 * a; } } + contract B { function f(bool b) returns(uint) { return 10; } } + contract C is A, B { + function g() returns(uint) { return super.f(true); } + function h() returns(uint) { return super.f(1); } } )"; - compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("test()") == encodeArgs(true)); + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(10)); + BOOST_CHECK(callContractFunction("h()") == encodeArgs(2)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 6bde9fd24..fd439fc84 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1637,7 +1637,7 @@ BOOST_AUTO_TEST_CASE(overloaded_function_cannot_resolve) BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function) { - // literal 1 can be both converted to uint8 and uint8, so it's ambiguous. + // literal 1 can be both converted to uint and uint8, so the call is ambiguous. char const* sourceCode = R"( contract test { function f(uint8 a) returns(uint) { return a; } @@ -1648,6 +1648,78 @@ BOOST_AUTO_TEST_CASE(ambiguous_overloaded_function) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(assignment_of_nonoverloaded_function) +{ + char const* sourceCode = R"( + contract test { + function f(uint a) returns(uint) { return 2 * a; } + function g() returns(uint) { var x = f; return x(7); } + } + )"; + ETH_TEST_REQUIRE_NO_THROW(parseTextAndResolveNames(sourceCode), "Type resolving failed"); +} + +BOOST_AUTO_TEST_CASE(assignment_of_overloaded_function) +{ + char const* sourceCode = R"( + contract test { + function f() returns(uint) { return 1; } + function f(uint a) returns(uint) { return 2 * a; } + function g() returns(uint) { var x = f; return x(7); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(external_types_clash) +{ + char const* sourceCode = R"( + contract base { + enum a { X } + function f(a) { } + } + contract test is base { + function f(uint8 a) { } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(override_changes_return_types) +{ + char const* sourceCode = R"( + contract base { + function f(uint a) returns (uint) { } + } + contract test is base { + function f(uint a) returns (uint8) { } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); +} + +BOOST_AUTO_TEST_CASE(multiple_constructors) +{ + char const* sourceCode = R"( + contract test { + function test(uint a) { } + function test() {} + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + +BOOST_AUTO_TEST_CASE(equal_overload) +{ + char const* sourceCode = R"( + contract test { + function test(uint a) returns (uint b) { } + function test(uint a) external {} + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), DeclarationError); +} + BOOST_AUTO_TEST_SUITE_END() } From a90c45a3ee4c937bac25b9dd4aace1160b9c3cc8 Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 16 Apr 2015 16:32:15 +0300 Subject: [PATCH 17/58] RLP length with first zeros --- libdevcore/RLP.cpp | 4 ++-- libdevcore/RLP.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index 994aac265..2a1c34030 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -149,7 +149,7 @@ unsigned RLP::length() const return n - c_rlpDataImmLenStart; else if (n < c_rlpListStart) { - if ((int)m_data.size() <= n - c_rlpDataIndLenZero) + if ((int)m_data.size() <= n - c_rlpDataIndLenZero || m_data[1] == 0) BOOST_THROW_EXCEPTION(BadRLP()); for (int i = 0; i < n - c_rlpDataIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; @@ -158,7 +158,7 @@ unsigned RLP::length() const return n - c_rlpListStart; else { - if ((int)m_data.size() <= n - c_rlpListIndLenZero) + if ((int)m_data.size() <= n - c_rlpListIndLenZero || m_data[1] == 0) BOOST_THROW_EXCEPTION(BadRLP()); for (int i = 0; i < n - c_rlpListIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h index caaf10b6a..7e765d395 100644 --- a/libdevcore/RLP.h +++ b/libdevcore/RLP.h @@ -303,7 +303,7 @@ private: /// Single-byte data payload. bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; } - /// @returns the bytes used to encode the length of the data. Valid for all types. + /// @returns the amount of bytes used to encode the length of the data. Valid for all types. unsigned lengthSize() const { if (isData() && m_data[0] > c_rlpDataIndLenZero) return m_data[0] - c_rlpDataIndLenZero; if (isList() && m_data[0] > c_rlpListIndLenZero) return m_data[0] - c_rlpListIndLenZero; return 0; } /// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data. From 989891d775dc7eacba641224190629fcb41be1e0 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 17 Apr 2015 12:17:51 +0200 Subject: [PATCH 18/58] add JSON test Conflicts: test/bcJS_API_TestFiller.json --- test/JSON_test.sol | 131 ++++++ test/bcJS_API_TestFiller.json | 247 ----------- test/bcRPC_API_TestFiller.json | 744 +++++++++++++++++++++++++++++++++ test/blockchain.cpp | 4 +- 4 files changed, 877 insertions(+), 249 deletions(-) create mode 100644 test/JSON_test.sol delete mode 100644 test/bcJS_API_TestFiller.json create mode 100644 test/bcRPC_API_TestFiller.json diff --git a/test/JSON_test.sol b/test/JSON_test.sol new file mode 100644 index 000000000..91d8734b3 --- /dev/null +++ b/test/JSON_test.sol @@ -0,0 +1,131 @@ + contract JSON_Test { + event Log0(uint value); + event Log0Anonym (uint value) anonymous; + event Log1(bool indexed aBool, uint value); + event Log1Anonym(bool indexed aBool, uint value) anonymous; + event Log2(bool indexed aBool, address indexed aAddress, uint value); + event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous; + event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value); + event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous; + event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value); + event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous; + + function JSON_Test() { + + } + + function setBool(bool _bool) { + myBool = _bool; + } + + function setInt8(int8 _int8) { + myInt8 = _int8; + } + + function setUint8(uint8 _uint8) { + myUint8 = _uint8; + } + + function setInt256(int256 _int256) { + myInt256 = _int256; + } + + function setUint256(uint256 _uint256) { + myUint256 = _uint256; + } + + function setAddress(address _address) { + myAddress = _address; + } + + //function setBytes0(bytes0 _bytes0) { + // myBytes0 = _bytes0; + //} + + function setBytes32(bytes32 _bytes32) { + myBytes32 = _bytes32; + } + + function getBool() returns (bool ret) { + return myBool; + } + + function getInt8() returns (int8 ret) { + return myInt8; + } + + function getUint8() returns (uint8 ret) { + return myUint8; + } + + function getInt256() returns (int256 ret) { + return myInt256; + } + + function getUint256() returns (uint256 ret) { + return myUint256; + } + + function getAddress() returns (address ret) { + return myAddress; + } + + //function getBytes0() returns (bytes0 ret) { + // return myBytes0; + //} + + function getBytes32() returns (bytes32 ret) { + return myBytes32; + } + + function fireEventLog0() { + Log0(42); + } + + function fireEventLog0Anonym() { + Log0Anonym(42); + } + + function fireEventLog1() { + Log1(true, 42); + } + + function fireEventLog1Anonym() { + Log1Anonym(true, 42); + } + + function fireEventLog2() { + Log2(true, msg.sender, 42); + } + + function fireEventLog2Anonym() { + Log2Anonym(true, msg.sender, 42); + } + + function fireEventLog3() { + Log3(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); + } + + function fireEventLog3Anonym() { + Log3Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 42); + } + + function fireEventLog4() { + Log4(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); + } + + function fireEventLog4Anonym() { + Log4Anonym(true, msg.sender, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, -23, 42); + } + + bool myBool; + int8 myInt8; + uint8 myUint8; + int256 myInt256; + uint256 myUint256; + address myAddress; + //bytes0 myBytes0; + bytes32 myBytes32; + +} + diff --git a/test/bcJS_API_TestFiller.json b/test/bcJS_API_TestFiller.json deleted file mode 100644 index fe7396e59..000000000 --- a/test/bcJS_API_TestFiller.json +++ /dev/null @@ -1,247 +0,0 @@ -{ - "JS_API_Tests" : { - "genesisBlockHeader" : { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty" : "131072", - "extraData" : "0x42", - "gasLimit" : "3141592", - "gasUsed" : "0", - "number" : "0", - "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", - "timestamp" : "0x54c98c81", - "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "nonce" : "0x0102030405060708", - "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "expect" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "70" - }, - "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { - "storage" : { - "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x01" : "0x42", - "0x02" : "0x23", - "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x04" : "0x01", - "0x05" : "0x55114a49" - } - } - }, - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "10000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - }, - "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { - "balance" : "100000", - "code" : "0x60003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b5056", - "nonce" : "0", - "storage" : { - "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x01" : "0x42", - "0x02" : "0x23", - "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x05" : "0x54c98c81" - } - } - }, - "blocks" : [ - { - "transactions" : [ - { - "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023", - "gasLimit" : "600000", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "", - "value" : "100000" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "1", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "0xfcfff16f", - "gasLimit" : "600000", - "gasPrice" : "1", - "nonce" : "2", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value" : "0x42" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "3", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - } - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "4", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "5", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "314159", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - } - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "6", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "7", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "8", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - } - ] - } -} diff --git a/test/bcRPC_API_TestFiller.json b/test/bcRPC_API_TestFiller.json new file mode 100644 index 000000000..00b3cc783 --- /dev/null +++ b/test/bcRPC_API_TestFiller.json @@ -0,0 +1,744 @@ +{ + "RPC_API_Test" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { + "balance" : "100000", + "code" : "0x60003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b5056", + "nonce" : "0", + "storage" : { + "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x01" : "0x42", + "0x02" : "0x23", + "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x05" : "0x54c98c81" + } + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023", + "gasLimit" : "600000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "100000" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "0xfcfff16f", + "gasLimit" : "600000", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "value" : "0x42" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "5", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "314159", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "6", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "7", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "8", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "create contract: c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "data" : "0x5b5b6106e0806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104b1565b60006000f35b610142610376565b8060005260206000f35b610157600435610301565b60006000f35b6101686004356102c9565b60006000f35b61017661041d565b8060005260206000f35b6101886103ae565b8060ff1660005260206000f35b61019d6103ee565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104a0565b60006000f35b6101d3610392565b8060000b60005260206000f35b6101e861042f565b60006000f35b6101f66103dc565b8060005260206000f35b6102086104fa565b60006000f35b6102196004356102e5565b60006000f35b61022761066e565b60006000f35b61023860043561031d565b60006000f35b61024661045f565b60006000f35b61025461046e565b60006000f35b610265600435610368565b60006000f35b61027660043561032b565b60006000f35b610287600435610339565b60006000f35b61029561058f565b60006000f35b6102a3610522565b60006000f35b6102b16103ca565b8060005260206000f35b6102c36105db565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff021916908302179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff16905061038f565b90565b6000600060019054906101000a900460ff1690506103ab565b90565b6000600060029054906101000a900460ff1690506103c7565b90565b600060016000505490506103d9565b90565b600060026000505490506103eb565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061041a565b90565b6000600460005054905061042c565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", + "gasLimit" : "3141592", + "gasPrice" : "1", + "nonce" : "9", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getBool", + "data" : "0x12a7b914", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "10", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getInt8", + "data" : "0x57cb2fc4", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "11", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getUint8", + "data" : "0x343a875d", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "12", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getInt256", + "data" : "0xf5b53e17", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "13", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getUint256", + "data" : "0x68895979", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "14", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getAddress", + "data" : "0x38cc4831", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "15", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getBytes32", + "data" : "0x1f903037", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "16", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setBool", + "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "17", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setBool", + "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "18", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setInt8", + "data" : "0x9a19a953000000000000000000000000000000000000000000000000fffffffffffffffa", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "19", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setUint8", + "data" : "0x1774e6460000000000000000000000000000000000000000000000000000000000000008", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "20", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setInt256", + "data" : "0xa53b1c1effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "21", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setUint256", + "data" : "0xd2282dc5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "22", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setAddress", + "data" : "0xe30081a0aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "23", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "setBytes32", + "data" : "0xc2b12a73aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "24", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getInt8", + "data" : "0x57cb2fc4", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "25", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getUint8", + "data" : "0x343a875d", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "26", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getInt256", + "data" : "0xf5b53e17", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "27", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getUint256", + "data" : "0x68895979", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "28", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getAddress", + "data" : "0x38cc4831", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "29", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "getBytes32", + "data" : "0x1f903037", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "30", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log0", + "data" : "0x65538c73", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "31", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log0a", + "data" : "0xa6780857", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "32", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log1", + "data" : "0xb61c0503", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "33", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log1a", + "data" : "0x4e7ad367", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "34", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log2", + "data" : "0x102accc1", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "35", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log2a", + "data" : "0x76bc21d9", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "36", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log3", + "data" : "0xf38b0600", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "37", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log3a", + "data" : "0xe8beef5b", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "38", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log4", + "data" : "0xfd408767", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "39", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "log4a", + "data" : "0x9dc2c8f5", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "40", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + } + ] + } +} diff --git a/test/blockchain.cpp b/test/blockchain.cpp index b144abe62..7fb425ed6 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -663,9 +663,9 @@ BOOST_AUTO_TEST_CASE(bcInvalidRLPTest) dev::test::executeTests("bcInvalidRLPTest", "/BlockTests", dev::test::doBlockchainTests); } -BOOST_AUTO_TEST_CASE(bcJS_API_Test) +BOOST_AUTO_TEST_CASE(bcRPC_API_Test) { - dev::test::executeTests("bcJS_API_Test", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcRPC_API_Test", "/BlockTests", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcValidBlockTest) From b415eb1fd2e3f8b21b8eae5c725f6036ce629895 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Tue, 14 Apr 2015 12:35:32 +0200 Subject: [PATCH 19/58] remove old contract --- test/bcRPC_API_TestFiller.json | 305 ++++++++------------------------- 1 file changed, 70 insertions(+), 235 deletions(-) diff --git a/test/bcRPC_API_TestFiller.json b/test/bcRPC_API_TestFiller.json index 00b3cc783..2938178c2 100644 --- a/test/bcRPC_API_TestFiller.json +++ b/test/bcRPC_API_TestFiller.json @@ -23,31 +23,20 @@ "nonce" : "0", "code" : "", "storage": {} - }, - "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { - "balance" : "100000", - "code" : "0x60003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b5056", - "nonce" : "0", - "storage" : { - "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x01" : "0x42", - "0x02" : "0x23", - "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "0x05" : "0x54c98c81" - } } }, "blocks" : [ { "transactions" : [ { - "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023", - "gasLimit" : "600000", + "data" : "create contract: 6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "data" : "0x5b5b6106e0806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104b1565b60006000f35b610142610376565b8060005260206000f35b610157600435610301565b60006000f35b6101686004356102c9565b60006000f35b61017661041d565b8060005260206000f35b6101886103ae565b8060ff1660005260206000f35b61019d6103ee565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104a0565b60006000f35b6101d3610392565b8060000b60005260206000f35b6101e861042f565b60006000f35b6101f66103dc565b8060005260206000f35b6102086104fa565b60006000f35b6102196004356102e5565b60006000f35b61022761066e565b60006000f35b61023860043561031d565b60006000f35b61024661045f565b60006000f35b61025461046e565b60006000f35b610265600435610368565b60006000f35b61027660043561032b565b60006000f35b610287600435610339565b60006000f35b61029561058f565b60006000f35b6102a3610522565b60006000f35b6102b16103ca565b8060005260206000f35b6102c36105db565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff021916908302179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff16905061038f565b90565b6000600060019054906101000a900460ff1690506103ab565b90565b6000600060029054906101000a900460ff1690506103c7565b90565b600060016000505490506103d9565b90565b600060026000505490506103eb565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061041a565b90565b6000600460005054905061042c565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", + "gasLimit" : "3141592", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "", - "value" : "100000" + "value" : "10" } ], "uncleHeaders" : [ @@ -56,12 +45,13 @@ { "transactions" : [ { - "data" : "", + "data" : "getBool", + "data" : "0x12a7b914", "gasLimit" : "314159", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -71,13 +61,14 @@ { "transactions" : [ { - "data" : "0xfcfff16f", - "gasLimit" : "600000", + "data" : "getInt8", + "data" : "0x57cb2fc4", + "gasLimit" : "314159", "gasPrice" : "1", "nonce" : "2", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "value" : "0x42" + "value" : "10" } ], "uncleHeaders" : [ @@ -86,12 +77,13 @@ { "transactions" : [ { - "data" : "", + "data" : "getUint8", + "data" : "0x343a875d", "gasLimit" : "314159", "gasPrice" : "1", "nonce" : "3", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -134,163 +126,6 @@ } ] }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "4", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "5", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "314159", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - } - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "6", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "7", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "8", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "create contract: c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", - "data" : "0x5b5b6106e0806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104b1565b60006000f35b610142610376565b8060005260206000f35b610157600435610301565b60006000f35b6101686004356102c9565b60006000f35b61017661041d565b8060005260206000f35b6101886103ae565b8060ff1660005260206000f35b61019d6103ee565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104a0565b60006000f35b6101d3610392565b8060000b60005260206000f35b6101e861042f565b60006000f35b6101f66103dc565b8060005260206000f35b6102086104fa565b60006000f35b6102196004356102e5565b60006000f35b61022761066e565b60006000f35b61023860043561031d565b60006000f35b61024661045f565b60006000f35b61025461046e565b60006000f35b610265600435610368565b60006000f35b61027660043561032b565b60006000f35b610287600435610339565b60006000f35b61029561058f565b60006000f35b6102a3610522565b60006000f35b6102b16103ca565b8060005260206000f35b6102c36105db565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff021916908302179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff16905061038f565b90565b6000600060019054906101000a900460ff1690506103ab565b90565b6000600060029054906101000a900460ff1690506103c7565b90565b600060016000505490506103d9565b90565b600060026000505490506103eb565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061041a565b90565b6000600460005054905061042c565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", - "gasLimit" : "3141592", - "gasPrice" : "1", - "nonce" : "9", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "getBool", - "data" : "0x12a7b914", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "10", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "getInt8", - "data" : "0x57cb2fc4", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "11", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, - { - "transactions" : [ - { - "data" : "getUint8", - "data" : "0x343a875d", - "gasLimit" : "314159", - "gasPrice" : "1", - "nonce" : "12", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", - "value" : "10" - } - ], - "uncleHeaders" : [ - ] - }, { "transactions" : [ { @@ -298,9 +133,9 @@ "data" : "0xf5b53e17", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "13", + "nonce" : "4", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -314,9 +149,9 @@ "data" : "0x68895979", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "14", + "nonce" : "5", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -330,9 +165,9 @@ "data" : "0x38cc4831", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "15", + "nonce" : "6", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -346,9 +181,9 @@ "data" : "0x1f903037", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "16", + "nonce" : "7", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -362,9 +197,9 @@ "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "17", + "nonce" : "8", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -378,9 +213,9 @@ "data" : "0x1e26fd330000000000000000000000000000000000000000000000000000000000000001", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "18", + "nonce" : "9", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -394,9 +229,9 @@ "data" : "0x9a19a953000000000000000000000000000000000000000000000000fffffffffffffffa", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "19", + "nonce" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -410,9 +245,9 @@ "data" : "0x1774e6460000000000000000000000000000000000000000000000000000000000000008", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "20", + "nonce" : "11", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -426,9 +261,9 @@ "data" : "0xa53b1c1effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "21", + "nonce" : "12", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -442,9 +277,9 @@ "data" : "0xd2282dc5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "22", + "nonce" : "13", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -458,9 +293,9 @@ "data" : "0xe30081a0aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "23", + "nonce" : "14", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -474,9 +309,9 @@ "data" : "0xc2b12a73aabbccffffffffffffffffffffffffffffffffffffffffffffffffffffffffee", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "24", + "nonce" : "15", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -490,9 +325,9 @@ "data" : "0x57cb2fc4", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "25", + "nonce" : "16", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -506,9 +341,9 @@ "data" : "0x343a875d", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "26", + "nonce" : "17", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -522,9 +357,9 @@ "data" : "0xf5b53e17", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "27", + "nonce" : "18", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -538,9 +373,9 @@ "data" : "0x68895979", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "28", + "nonce" : "19", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -554,9 +389,9 @@ "data" : "0x38cc4831", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "29", + "nonce" : "20", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -570,9 +405,9 @@ "data" : "0x1f903037", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "30", + "nonce" : "21", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -586,9 +421,9 @@ "data" : "0x65538c73", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "31", + "nonce" : "22", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -602,9 +437,9 @@ "data" : "0xa6780857", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "32", + "nonce" : "23", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -618,9 +453,9 @@ "data" : "0xb61c0503", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "33", + "nonce" : "24", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -634,9 +469,9 @@ "data" : "0x4e7ad367", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "34", + "nonce" : "25", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -650,9 +485,9 @@ "data" : "0x102accc1", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "35", + "nonce" : "26", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -666,9 +501,9 @@ "data" : "0x76bc21d9", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "36", + "nonce" : "27", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -682,9 +517,9 @@ "data" : "0xf38b0600", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "37", + "nonce" : "28", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -698,9 +533,9 @@ "data" : "0xe8beef5b", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "38", + "nonce" : "29", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -714,9 +549,9 @@ "data" : "0xfd408767", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "39", + "nonce" : "30", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], @@ -730,9 +565,9 @@ "data" : "0x9dc2c8f5", "gasLimit" : "314159", "gasPrice" : "1", - "nonce" : "40", + "nonce" : "31", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "c73a4c080ed74d5cad62e58d32dd8e5f0d78fe24", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", "value" : "10" } ], From 70873c6d145a697cf3e7ffbfef79297faf154cb3 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Wed, 15 Apr 2015 09:25:46 +0200 Subject: [PATCH 20/58] update JSON_test.sol --- test/JSON_test.sol | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/JSON_test.sol b/test/JSON_test.sol index 91d8734b3..5cb7a48af 100644 --- a/test/JSON_test.sol +++ b/test/JSON_test.sol @@ -1,14 +1,14 @@ contract JSON_Test { event Log0(uint value); - event Log0Anonym (uint value) anonymous; + event Log0Anonym (uint value) ; event Log1(bool indexed aBool, uint value); - event Log1Anonym(bool indexed aBool, uint value) anonymous; + event Log1Anonym(bool indexed aBool, uint value) ; event Log2(bool indexed aBool, address indexed aAddress, uint value); - event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous; + event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) ; event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value); - event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous; + event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) ; event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value); - event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous; + event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) ; function JSON_Test() { @@ -38,9 +38,9 @@ myAddress = _address; } - //function setBytes0(bytes0 _bytes0) { - // myBytes0 = _bytes0; - //} + function setBytes0(bytes0 _bytes0) { + myBytes0 = _bytes0; + } function setBytes32(bytes32 _bytes32) { myBytes32 = _bytes32; @@ -70,9 +70,9 @@ return myAddress; } - //function getBytes0() returns (bytes0 ret) { - // return myBytes0; - //} + function getBytes0() returns (bytes0 ret) { + return myBytes0; + } function getBytes32() returns (bytes32 ret) { return myBytes32; @@ -124,7 +124,7 @@ int256 myInt256; uint256 myUint256; address myAddress; - //bytes0 myBytes0; + bytes0 myBytes0; bytes32 myBytes32; } From e396efd3be2269d40328f6fefbdc21c638b88a50 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 17 Apr 2015 12:19:12 +0200 Subject: [PATCH 21/58] add sleep 1 second to avoid invalid blocks due to same timestamp during creation Conflicts: test/blockchain.cpp --- test/bcRPC_API_TestFiller.json | 2 +- test/blockchain.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/bcRPC_API_TestFiller.json b/test/bcRPC_API_TestFiller.json index 2938178c2..781bd5e7d 100644 --- a/test/bcRPC_API_TestFiller.json +++ b/test/bcRPC_API_TestFiller.json @@ -226,7 +226,7 @@ "transactions" : [ { "data" : "setInt8", - "data" : "0x9a19a953000000000000000000000000000000000000000000000000fffffffffffffffa", + "data" : "0x9a19a953fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa", "gasLimit" : "314159", "gasPrice" : "1", "nonce" : "10", diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 7fb425ed6..8854a9705 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -289,6 +289,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) state = stateTemp; //revert state as if it was before executing this block } blArray.push_back(blObj); + sleep(1); } //for blocks if (o.count("expect") > 0) From fa50ff051f25f27b746f7a3f66e65685c24cdfbd Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 16 Apr 2015 15:16:39 +0200 Subject: [PATCH 22/58] style --- test/JSON_test.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/JSON_test.sol b/test/JSON_test.sol index 5cb7a48af..2c67fc2e5 100644 --- a/test/JSON_test.sol +++ b/test/JSON_test.sol @@ -11,7 +11,6 @@ event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) ; function JSON_Test() { - } function setBool(bool _bool) { @@ -125,7 +124,6 @@ uint256 myUint256; address myAddress; bytes0 myBytes0; - bytes32 myBytes32; - + bytes32 myBytes32; } From a84cdc08cf3f0b7a2bd2ccc434e238517df622ef Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 17 Apr 2015 14:51:01 +0200 Subject: [PATCH 23/58] retrigger build --- test/blockchain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 8854a9705..8d8a67632 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -695,4 +695,3 @@ BOOST_AUTO_TEST_CASE(userDefinedFile) } BOOST_AUTO_TEST_SUITE_END() - From cf02b5f64b8444e2b71f237921a148a7f2f2f2b6 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 17 Apr 2015 15:08:42 +0200 Subject: [PATCH 24/58] use this_thread::sleep_for instead of sleep --- test/blockchain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 8d8a67632..c525832dc 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -289,7 +289,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) state = stateTemp; //revert state as if it was before executing this block } blArray.push_back(blObj); - sleep(1); + this_thread::sleep_for(chrono::seconds(1)); } //for blocks if (o.count("expect") > 0) From b87032736ee518d104d81f18aeea6b6eeab47acf Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 17 Apr 2015 16:39:51 +0200 Subject: [PATCH 25/58] update test after solidity fix --- test/JSON_test.sol | 23 +++++++---------------- test/bcRPC_API_TestFiller.json | 2 +- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/test/JSON_test.sol b/test/JSON_test.sol index 2c67fc2e5..ffd7cdc40 100644 --- a/test/JSON_test.sol +++ b/test/JSON_test.sol @@ -1,14 +1,14 @@ contract JSON_Test { - event Log0(uint value); - event Log0Anonym (uint value) ; + event Log0(uint value) ; + event Log0Anonym (uint value) anonymous; event Log1(bool indexed aBool, uint value); - event Log1Anonym(bool indexed aBool, uint value) ; + event Log1Anonym(bool indexed aBool, uint value) anonymous; event Log2(bool indexed aBool, address indexed aAddress, uint value); - event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) ; + event Log2Anonym(bool indexed aBool, address indexed aAddress, uint value) anonymous; event Log3(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value); - event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) ; + event Log3Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, uint value) anonymous; event Log4(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value); - event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) ; + event Log4Anonym(bool indexed aBool, address indexed aAddress, bytes32 indexed aBytes32, int8 aInt8, uint value) anonymous; function JSON_Test() { } @@ -36,11 +36,7 @@ function setAddress(address _address) { myAddress = _address; } - - function setBytes0(bytes0 _bytes0) { - myBytes0 = _bytes0; - } - + function setBytes32(bytes32 _bytes32) { myBytes32 = _bytes32; } @@ -69,10 +65,6 @@ return myAddress; } - function getBytes0() returns (bytes0 ret) { - return myBytes0; - } - function getBytes32() returns (bytes32 ret) { return myBytes32; } @@ -123,7 +115,6 @@ int256 myInt256; uint256 myUint256; address myAddress; - bytes0 myBytes0; bytes32 myBytes32; } diff --git a/test/bcRPC_API_TestFiller.json b/test/bcRPC_API_TestFiller.json index 781bd5e7d..b31f1fa48 100644 --- a/test/bcRPC_API_TestFiller.json +++ b/test/bcRPC_API_TestFiller.json @@ -30,7 +30,7 @@ "transactions" : [ { "data" : "create contract: 6295ee1b4f6dd65047762f924ecd367c17eabf8f", - "data" : "0x5b5b6106e0806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104b1565b60006000f35b610142610376565b8060005260206000f35b610157600435610301565b60006000f35b6101686004356102c9565b60006000f35b61017661041d565b8060005260206000f35b6101886103ae565b8060ff1660005260206000f35b61019d6103ee565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104a0565b60006000f35b6101d3610392565b8060000b60005260206000f35b6101e861042f565b60006000f35b6101f66103dc565b8060005260206000f35b6102086104fa565b60006000f35b6102196004356102e5565b60006000f35b61022761066e565b60006000f35b61023860043561031d565b60006000f35b61024661045f565b60006000f35b61025461046e565b60006000f35b610265600435610368565b60006000f35b61027660043561032b565b60006000f35b610287600435610339565b60006000f35b61029561058f565b60006000f35b6102a3610522565b60006000f35b6102b16103ca565b8060005260206000f35b6102c36105db565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff021916908302179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff16905061038f565b90565b6000600060019054906101000a900460ff1690506103ab565b90565b6000600060029054906101000a900460ff1690506103c7565b90565b600060016000505490506103d9565b90565b600060026000505490506103eb565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061041a565b90565b6000600460005054905061042c565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", + "data" : "0x5b5b610705806100106000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063102accc11461012c57806312a7b9141461013a5780631774e6461461014c5780631e26fd331461015d5780631f9030371461016e578063343a875d1461018057806338cc4831146101955780634e7ad367146101bd57806357cb2fc4146101cb57806365538c73146101e057806368895979146101ee57806376bc21d9146102005780639a19a9531461020e5780639dc2c8f51461021f578063a53b1c1e1461022d578063a67808571461023e578063b61c05031461024c578063c2b12a731461025a578063d2282dc51461026b578063e30081a01461027c578063e8beef5b1461028d578063f38b06001461029b578063f5b53e17146102a9578063fd408767146102bb57005b6101346104d6565b60006000f35b61014261039b565b8060005260206000f35b610157600435610326565b60006000f35b6101686004356102c9565b60006000f35b610176610442565b8060005260206000f35b6101886103d3565b8060ff1660005260206000f35b61019d610413565b8073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b6101c56104c5565b60006000f35b6101d36103b7565b8060000b60005260206000f35b6101e8610454565b60006000f35b6101f6610401565b8060005260206000f35b61020861051f565b60006000f35b6102196004356102e5565b60006000f35b610227610693565b60006000f35b610238600435610342565b60006000f35b610246610484565b60006000f35b610254610493565b60006000f35b61026560043561038d565b60006000f35b610276600435610350565b60006000f35b61028760043561035e565b60006000f35b6102956105b4565b60006000f35b6102a3610547565b60006000f35b6102b16103ef565b8060005260206000f35b6102c3610600565b60006000f35b80600060006101000a81548160ff021916908302179055505b50565b80600060016101000a81548160ff02191690837f01000000000000000000000000000000000000000000000000000000000000009081020402179055505b50565b80600060026101000a81548160ff021916908302179055505b50565b806001600050819055505b50565b806002600050819055505b50565b80600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908302179055505b50565b806004600050819055505b50565b6000600060009054906101000a900460ff1690506103b4565b90565b6000600060019054906101000a900460000b90506103d0565b90565b6000600060029054906101000a900460ff1690506103ec565b90565b600060016000505490506103fe565b90565b60006002600050549050610410565b90565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061043f565b90565b60006004600050549050610451565b90565b7f65c9ac8011e286e89d02a269890f41d67ca2cc597b2c76c7c69321ff492be5806000602a81526020016000a15b565b6000602a81526020016000a05b565b60017f81933b308056e7e85668661dcd102b1f22795b4431f9cf4625794f381c271c6b6000602a81526020016000a25b565b60016000602a81526020016000a15b565b3373ffffffffffffffffffffffffffffffffffffffff1660017f0e216b62efbb97e751a2ce09f607048751720397ecfb9eef1e48a6644948985b6000602a81526020016000a35b565b3373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a25b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017f317b31292193c2a4f561cc40a95ea0d97a2733f14af6d6d59522473e1f3ae65f6000602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660016000602a81526020016000a35b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff1660017fd5f0a30e4be0c6be577a71eceb7464245a796a7e6a55c0d971837b250de05f4e60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a45b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6001023373ffffffffffffffffffffffffffffffffffffffff16600160007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe98152602001602a81526020016000a35b56", "gasLimit" : "3141592", "gasPrice" : "1", "nonce" : "0", From e1caebe33115ebd2b9af946841d119d4d0a7c760 Mon Sep 17 00:00:00 2001 From: winsvega Date: Mon, 20 Apr 2015 11:27:11 +0300 Subject: [PATCH 26/58] first zeros in rlp m_data overflow percautions --- libdevcore/RLP.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index 2a1c34030..bceafd2b4 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -149,8 +149,11 @@ unsigned RLP::length() const return n - c_rlpDataImmLenStart; else if (n < c_rlpListStart) { - if ((int)m_data.size() <= n - c_rlpDataIndLenZero || m_data[1] == 0) + if ((int)m_data.size() <= n - c_rlpDataIndLenZero) BOOST_THROW_EXCEPTION(BadRLP()); + if ((int)m_data.size() > 1) + if (m_data[1] == 0) + BOOST_THROW_EXCEPTION(BadRLP()); for (int i = 0; i < n - c_rlpDataIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; } @@ -158,8 +161,11 @@ unsigned RLP::length() const return n - c_rlpListStart; else { - if ((int)m_data.size() <= n - c_rlpListIndLenZero || m_data[1] == 0) + if ((int)m_data.size() <= n - c_rlpListIndLenZero) BOOST_THROW_EXCEPTION(BadRLP()); + if ((int)m_data.size() > 1) + if (m_data[1] == 0) + BOOST_THROW_EXCEPTION(BadRLP()); for (int i = 0; i < n - c_rlpListIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; } From 4e4fc4d11cb20549e38ca90c2e0056f3d9a7d84e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 11:10:19 +0200 Subject: [PATCH 27/58] Fixes for reimporting. --- libethereum/BlockChain.cpp | 14 +++++++++----- libethereum/BlockChain.h | 4 ++-- libethereum/State.cpp | 8 ++++---- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 2e089dd3b..4e3349a31 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -218,7 +218,11 @@ void BlockChain::rebuild(std::string const& _path, std::functionPut(m_writeOptions, toSlice(m_lastBlockHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[m_lastBlockHash].rlp())); + + h256 lastHash = m_lastBlockHash; boost::timer t; for (unsigned d = 1; d < originalNumber; ++d) { @@ -240,7 +244,7 @@ void BlockChain::rebuild(std::string const& _path, std::function (u256)time(0)) { - clog(BlockChainNote) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")"; + clog(BlockChainChat) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")"; // Block has a timestamp in the future. This is no good. BOOST_THROW_EXCEPTION(FutureTime()); } - clog(BlockChainNote) << "Attempting import of " << bi.hash().abridged() << "..."; + clog(BlockChainChat) << "Attempting import of " << bi.hash().abridged() << "..."; #if ETH_TIMED_IMPORTS preliminaryChecks = t.elapsed(); @@ -609,7 +613,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import } else { - clog(BlockChainNote) << " Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << ")"; + clog(BlockChainChat) << " Imported but not best (oTD:" << details(last).totalDifficulty << " > TD:" << td << ")"; } #if ETH_TIMED_IMPORTS diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 70a9f93db..8061487d7 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -56,8 +56,8 @@ struct AlreadyHaveBlock: virtual Exception {}; struct UnknownParent: virtual Exception {}; struct FutureTime: virtual Exception {}; -struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 7; }; -struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 4; }; +struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 5; }; +struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 3; }; struct BlockChainWarn: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 1; }; struct BlockChainDebug: public LogChannel { static const char* name() { return "#B#"; } static const int verbosity = 0; }; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 19cec8614..598dac37d 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -663,7 +663,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement uncle.verifyParent(uncleParent); nonces.insert(uncle.nonce); - tdIncrease += uncle.difficulty; +// tdIncrease += uncle.difficulty; rewarded.push_back(uncle); } @@ -704,15 +704,15 @@ void State::cleanup(bool _fullCommit) paranoia("immediately before database commit", true); // Commit the new trie to disk. - cnote << "Committing to disk: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); + clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); m_db.commit(); - cnote << "Committed: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); + clog(StateTrace) << "Committed: stateRoot" << m_currentBlock.stateRoot.abridged() << "=" << rootHash().abridged() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); paranoia("immediately after database commit", true); m_previousBlock = m_currentBlock; m_currentBlock.populateFromParent(m_previousBlock); - cdebug << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash().abridged(); + clog(StateTrace) << "finalising enactment. current -> previous, hash is" << m_previousBlock.hash().abridged(); } else m_db.rollback(); From 30e42521b5a11e93e9581faf90ae82dc43651947 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 11:10:51 +0200 Subject: [PATCH 28/58] Minor protocol version bump to force rebuilding DB. --- libethcore/Common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index a0ceb389e..56120471b 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -34,7 +34,7 @@ namespace eth { const unsigned c_protocolVersion = 60; -const unsigned c_minorProtocolVersion = 0; +const unsigned c_minorProtocolVersion = 1; const unsigned c_databaseBaseVersion = 9; #if ETH_FATDB const unsigned c_databaseVersionModifier = 1; From a1e0ea0df3f063bc7b85ef1990e45ecf5d5a5b81 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 20 Apr 2015 11:37:21 +0200 Subject: [PATCH 29/58] fix hex encoding blockheader and use tmp directories for stateDB --- test/blockchain.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 92912938e..73d4eb255 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -52,8 +52,10 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) BOOST_REQUIRE(o.count("pre")); ImportTest importer(o["pre"].get_obj()); - State state(OverlayDB(), BaseState::Empty, biGenesisBlock.coinbaseAddress); - State stateTemp(OverlayDB(), BaseState::Empty, biGenesisBlock.coinbaseAddress); + TransientDirectory td_stateDB; + TransientDirectory td_stateDB_tmp; + State state(OverlayDB(State::openDB(td_stateDB.path())), BaseState::Empty, biGenesisBlock.coinbaseAddress); + State stateTemp(OverlayDB(State::openDB(td_stateDB_tmp.path())), BaseState::Empty, biGenesisBlock.coinbaseAddress); importer.importState(o["pre"].get_obj(), state); o["pre"] = fillJsonWithState(state); state.commit(); @@ -626,11 +628,11 @@ void writeBlockHeaderToJson(mObject& _o, BlockInfo const& _bi) _o["transactionsTrie"] = toString(_bi.transactionsRoot); _o["receiptTrie"] = toString(_bi.receiptsRoot); _o["bloom"] = toString(_bi.logBloom); - _o["difficulty"] = "0x" + toHex(toCompactBigEndian(_bi.difficulty), 1); - _o["number"] = "0x" + toHex(toCompactBigEndian(_bi.number), 1); - _o["gasLimit"] = "0x" + toHex(toCompactBigEndian(_bi.gasLimit), 1); - _o["gasUsed"] = "0x" + toHex(toCompactBigEndian(_bi.gasUsed), 1); - _o["timestamp"] = "0x" + toHex(toCompactBigEndian(_bi.timestamp), 1); + _o["difficulty"] = "0x" + toHex(toCompactBigEndian(_bi.difficulty, 1)); + _o["number"] = "0x" + toHex(toCompactBigEndian(_bi.number, 1)); + _o["gasLimit"] = "0x" + toHex(toCompactBigEndian(_bi.gasLimit, 1)); + _o["gasUsed"] = "0x" + toHex(toCompactBigEndian(_bi.gasUsed, 1)); + _o["timestamp"] = "0x" + toHex(toCompactBigEndian(_bi.timestamp, 1)); _o["extraData"] ="0x" + toHex(_bi.extraData); _o["mixHash"] = toString(_bi.mixHash); _o["nonce"] = toString(_bi.nonce); From 8328220471475b2733a9f4a2cc4c3710ee2d7d5c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 11:49:37 +0200 Subject: [PATCH 30/58] Fixes for reimporting, make block availability atomic. --- alethzero/MainWin.cpp | 2 +- libethcore/EthashAux.cpp | 6 +++--- libethereum/BlockChain.cpp | 38 +++++++++++++++++++++++++++----------- libethereum/BlockChain.h | 3 ++- 4 files changed, 33 insertions(+), 16 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 270996a30..3ec5febd2 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -164,7 +164,7 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->chainStatus); statusBar()->addPermanentWidget(ui->blockCount); - ui->blockCount->setText(QString("PV%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); + ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 68c5f3057..750d80082 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -75,11 +75,11 @@ h256 EthashAux::seedHash(unsigned _number) n = get()->m_seedHashes.size() - 1; } get()->m_seedHashes.resize(epoch + 1); - cdebug << "Searching for seedHash of epoch " << epoch; +// cdebug << "Searching for seedHash of epoch " << epoch; for (; n <= epoch; ++n, ret = sha3(ret)) { get()->m_seedHashes[n] = ret; - cdebug << "Epoch" << n << "is" << ret.abridged(); +// cdebug << "Epoch" << n << "is" << ret.abridged(); } } return get()->m_seedHashes[epoch]; @@ -95,7 +95,7 @@ ethash_params EthashAux::params(h256 const& _seedHash) } catch (...) { - cdebug << "Searching for seedHash " << _seedHash.abridged(); +// cdebug << "Searching for seedHash " << _seedHash.abridged(); for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {} if (epoch == 2048) { diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 4e3349a31..6705349f4 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -167,6 +167,7 @@ void BlockChain::open(std::string const& _path, WithExisting _we) std::string l; m_extrasDB->Get(m_readOptions, ldb::Slice("best"), &l); m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); + m_lastBlockNumber = number(m_lastBlockHash); cnote << "Opened blockchain DB. Latest: " << currentHash(); } @@ -177,6 +178,7 @@ void BlockChain::close() delete m_extrasDB; delete m_blocksDB; m_lastBlockHash = m_genesisHash; + m_lastBlockNumber = 0; m_details.clear(); m_blocks.clear(); } @@ -191,8 +193,7 @@ void BlockChain::rebuild(std::string const& _path, std::functionPut(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32)); // Most of the time these two will be equal - only when we're doing a chain revert will they not be if (common != last) @@ -601,6 +597,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import m_extrasDB->Put(m_writeOptions, toSlice(h, ExtraTransactionAddress), (ldb::Slice)dev::ref(m_transactionAddresses[h].rlp())); } + // FINALLY! change our best hash. + { + WriteGuard l(x_lastBlockHash); + m_lastBlockHash = bi.hash(); + m_lastBlockNumber = (unsigned)bi.number; + m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&(bi.hash()), 32)); + } + clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << toString(route); noteCanonChanged(); @@ -960,14 +964,26 @@ bool BlockChain::isKnown(h256 const& _hash) const { if (_hash == m_genesisHash) return true; + { ReadGuard l(x_blocks); - if (m_blocks.count(_hash)) - return true; + auto it = m_blocks.find(_hash); + if (it != m_blocks.end()) + { + noteUsed(_hash); + BlockInfo bi(it->second, CheckNothing, _hash); + return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber + } } + string d; m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); - return !!d.size(); + + if (!d.size()) + return false; + + BlockInfo bi(bytesConstRef(&d), CheckNothing, _hash); + return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber } bytes BlockChain::block(h256 const& _hash) const diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 8061487d7..be5b931ee 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -185,7 +185,7 @@ public: /// Get a number for the given hash (or the most recent mined if none given). Thread-safe. unsigned number(h256 const& _hash) const { return details(_hash).number; } - unsigned number() const { return number(currentHash()); } + unsigned number() const { return m_lastBlockNumber; } /// Get a given block (RLP format). Thread-safe. h256 currentHash() const { ReadGuard l(x_lastBlockHash); return m_lastBlockHash; } @@ -315,6 +315,7 @@ private: /// Hash of the last (valid) block on the longest chain. mutable boost::shared_mutex x_lastBlockHash; h256 m_lastBlockHash; + unsigned m_lastBlockNumber = 0; /// Genesis block info. h256 m_genesisHash; From 86804fedf1b81e2136b07e9f3d896f7cd6d80a6a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 12:22:35 +0200 Subject: [PATCH 31/58] Fix deadlock. --- libethereum/BlockChain.cpp | 22 +++++++++++----------- libp2p/NodeTable.cpp | 6 +++--- libp2p/RLPxHandshake.cpp | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 6705349f4..6a483a228 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -965,24 +965,24 @@ bool BlockChain::isKnown(h256 const& _hash) const if (_hash == m_genesisHash) return true; + BlockInfo bi; + { ReadGuard l(x_blocks); auto it = m_blocks.find(_hash); if (it != m_blocks.end()) - { - noteUsed(_hash); - BlockInfo bi(it->second, CheckNothing, _hash); - return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber - } + bi = BlockInfo(it->second, CheckNothing, _hash); } - string d; - m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); - - if (!d.size()) - return false; + if (!bi) + { + string d; + m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); + if (!d.size()) + return false; + bi = BlockInfo(bytesConstRef(&d), CheckNothing, _hash); + } - BlockInfo bi(bytesConstRef(&d), CheckNothing, _hash); return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber } diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 1f48d52b7..e65c6660b 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -382,7 +382,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes // h256 + Signature + type + RLP (smallest possible packet is empty neighbours packet which is 3 bytes) if (_packet.size() < h256::size + Signature::size + 1 + 3) { - clog(NodeTableWarn) << "Invalid message size from " << _from.address().to_string() << ":" << _from.port(); + clog(NodeTableTriviaSummary) << "Invalid message size from " << _from.address().to_string() << ":" << _from.port(); return; } @@ -390,7 +390,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes h256 hashSigned(sha3(hashedBytes)); if (!_packet.cropped(0, h256::size).contentsEqual(hashSigned.asBytes())) { - clog(NodeTableWarn) << "Invalid message hash from " << _from.address().to_string() << ":" << _from.port(); + clog(NodeTableTriviaSummary) << "Invalid message hash from " << _from.address().to_string() << ":" << _from.port(); return; } @@ -402,7 +402,7 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes Public nodeid(dev::recover(*(Signature const*)sigBytes.data(), sha3(signedBytes))); if (!nodeid) { - clog(NodeTableWarn) << "Invalid message signature from " << _from.address().to_string() << ":" << _from.port(); + clog(NodeTableTriviaSummary) << "Invalid message signature from " << _from.address().to_string() << ":" << _from.port(); return; } diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index bb9af2ef7..fbf0d9fdf 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -249,7 +249,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) bytesRef frame(&m_handshakeInBuffer); if (!m_io->authAndDecryptFrame(frame)) { - clog(NetWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: decrypt failed"; + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: decrypt failed"; m_nextState = Error; transition(); return; @@ -258,13 +258,13 @@ void RLPXHandshake::transition(boost::system::error_code _ech) PacketType packetType = (PacketType)(frame[0] == 0x80 ? 0x0 : frame[0]); if (packetType != 0) { - clog(NetWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: invalid packet type"; + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: invalid packet type"; m_nextState = Error; transition(); return; } - clog(NetNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session."; + clog(NetTriviaSummary) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame: success. starting session."; RLP rlp(frame.cropped(1), RLP::ThrowOnFail | RLP::FailIfTooSmall); m_host->startPeerSession(m_remote, rlp, m_io, m_socket->remoteEndpoint()); } From 67f1cb513b7e076cd434a79e1233dfc654d1435e Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 20 Apr 2015 12:33:41 +0200 Subject: [PATCH 32/58] BigNumber object available to web preview --- mix/qml/WebPreview.qml | 2 +- mix/qml/html/WebContainer.html | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 6db727e3b..1e76366da 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -186,7 +186,7 @@ Item { if (documentName === urlInput.text.replace(httpServer.url + "/", "")) { //root page, inject deployment script - content = "\n" + content; + content = "\n" + content; _request.setResponseContentType("text/html"); } _request.setResponse(content); diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index 30e203bed..9c458a4c7 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -21,6 +21,7 @@ updateContracts = function(contracts) { if (window.web3) { window.web3.reset(); window.contracts = {}; + window.BigNumber = require('bignumber.js'); for (var c in contracts) { var contractProto = window.web3.eth.contract(contracts[c].interface); var contract = new contractProto(contracts[c].address); From 6b0a6e1043beccf6f41d3f40694dee1e10c5b7b8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 13:16:58 +0200 Subject: [PATCH 33/58] Inject block data in AZ. --- alethzero/Main.ui | 6 ++++++ alethzero/MainWin.cpp | 19 +++++++++++++++++++ alethzero/MainWin.h | 1 + 3 files changed, 26 insertions(+) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 8e48793c9..1fd9669e9 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -176,6 +176,7 @@ + @@ -1685,6 +1686,11 @@ font-size: 14pt Retry Unknown Parent Blocks + + + In&ject Block + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 3ec5febd2..64fca6a05 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1448,6 +1448,25 @@ void Main::on_inject_triggered() } } +void Main::on_injectBlock_triggered() +{ + QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex"); + try + { + bytes b = fromHex(s.toStdString(), WhenError::Throw); + ethereum()->injectBlock(b); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "block rejected"; + } +} + void Main::on_blocks_currentItemChanged() { ui->info->clear(); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index a8579ed01..1a53ec62b 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -159,6 +159,7 @@ private slots: void on_killBlockchain_triggered(); void on_clearPending_triggered(); void on_inject_triggered(); + void on_injectBlock_triggered(); void on_forceMining_triggered(); void on_usePrivate_triggered(); void on_turboMining_triggered(); From 9aab3ea20826cf6936bd52f4767652f1bb45263f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 13:56:35 +0200 Subject: [PATCH 34/58] Extra diagnostics. --- libethereum/BlockChain.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 6a483a228..4d28cae7f 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -406,7 +406,10 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import auto pdata = pd.rlp(); clog(BlockChainDebug) << "Details is returning false despite block known:" << RLP(pdata); auto parentBlock = block(bi.parentHash); - clog(BlockChainDebug) << "Block:" << RLP(parentBlock); + clog(BlockChainDebug) << "isKnown:" << isKnown(bi.parentHash); + clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << bi.number; + clog(BlockChainDebug) << "Block:" << BlockInfo(parentBlock); + clog(BlockChainDebug) << "RLP:" << RLP(parentBlock); clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; exit(-1); } From a02aab8c34d9c16ab6665ae71c0a1574dd57db8b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 14:47:13 +0200 Subject: [PATCH 35/58] Synchronisation safety for details/blocks in BlockChain. Avoid situation where block isKnown before details available. --- libethereum/BlockChain.cpp | 41 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 4d28cae7f..8dec48e96 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -485,14 +485,15 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import #endif { + ReadGuard l1(x_blocks); ReadGuard l2(x_details); ReadGuard l4(x_receipts); ReadGuard l5(x_logBlooms); - m_blocksDB->Put(m_writeOptions, toSlice(bi.hash()), (ldb::Slice)ref(_block)); m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.hash()].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(m_logBlooms[bi.hash()].rlp())); m_extrasDB->Put(m_writeOptions, toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(m_receipts[bi.hash()].rlp())); + m_blocksDB->Put(m_writeOptions, toSlice(bi.hash()), (ldb::Slice)ref(_block)); } #if ETH_TIMED_IMPORTS @@ -968,25 +969,23 @@ bool BlockChain::isKnown(h256 const& _hash) const if (_hash == m_genesisHash) return true; - BlockInfo bi; - - { - ReadGuard l(x_blocks); - auto it = m_blocks.find(_hash); - if (it != m_blocks.end()) - bi = BlockInfo(it->second, CheckNothing, _hash); - } - - if (!bi) - { - string d; - m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); - if (!d.size()) - return false; - bi = BlockInfo(bytesConstRef(&d), CheckNothing, _hash); - } - - return bi.number <= m_lastBlockNumber; // TODO: m_lastBlockNumber + ETH_READ_GUARDED(x_blocks) + if (!m_blocks.count(_hash)) + { + string d; + m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); + if (d.empty()) + return false; + } + ETH_READ_GUARDED(x_details) + if (!m_details.count(_hash)) + { + string d; + m_extrasDB->Get(m_readOptions, toSlice(_hash, ExtraDetails), &d); + if (d.empty()) + return false; + } + return true; } bytes BlockChain::block(h256 const& _hash) const @@ -1004,7 +1003,7 @@ bytes BlockChain::block(h256 const& _hash) const string d; m_blocksDB->Get(m_readOptions, toSlice(_hash), &d); - if (!d.size()) + if (d.empty()) { cwarn << "Couldn't find requested block:" << _hash.abridged(); return bytes(); From ed5b2a5da6da5175ff68292ad31a514675947f0c Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 20 Apr 2015 14:54:55 +0200 Subject: [PATCH 36/58] Made font size adjustable Switched to inkpot colour scheme --- mix/qml/CodeEditorView.qml | 31 +++++++++++++++++ mix/qml/WebCodeEditor.qml | 9 +++++ mix/qml/html/cm/inkpot.css | 65 ++++++++++++++++++++++++++++++++++++ mix/qml/html/codeeditor.html | 3 +- mix/qml/html/codeeditor.js | 9 ++++- mix/web.qrc | 1 + 6 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 mix/qml/html/cm/inkpot.css diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 7c4ef066f..956b71915 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -3,6 +3,7 @@ import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Dialogs 1.1 +import Qt.labs.settings 1.0 Item { id: codeEditorView @@ -74,6 +75,7 @@ Item { } editor.document = document; editor.sourceName = document.documentId; + editor.setFontSize(editorSettings.fontSize); editor.setText(data, document.syntaxMode); editor.changeGeneration(); } @@ -158,6 +160,15 @@ Item { } } + function setFontSize(size) + { + if (size <= 10 || size >= 48) + return; + editorSettings.fontSize = size; + for (var i = 0; i < editors.count; i++) + editors.itemAt(i).item.setFontSize(size); + } + Component.onCompleted: projectModel.codeEditor = codeEditorView; Connections { @@ -317,4 +328,24 @@ Item { ListModel { id: editorListModel } + + + Action { + id: increaseFontSize + text: qsTr("Increase Font Size") + shortcut: "Ctrl+=" + onTriggered: setFontSize(editorSettings.fontSize + 1) + } + + Action { + id: decreaseFontSize + text: qsTr("Decrease Font Size") + shortcut: "Ctrl+-" + onTriggered: setFontSize(editorSettings.fontSize - 1) + } + + Settings { + id: editorSettings + property int fontSize: 12; + } } diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 7c4a18492..9a9a3bea7 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -19,6 +19,7 @@ Item { property var currentBreakpoints: [] property string sourceName property var document + property int fontSize: 0 function setText(text, mode) { currentText = text; @@ -76,6 +77,13 @@ Item { editorBrowser.runJavaScript("goToCompilationError()", function(result) {}); } + function setFontSize(size) { + fontSize = size; + if (initialized && editorBrowser) + editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); + } + + Clipboard { id: clipboard @@ -108,6 +116,7 @@ Item { { if (!loading && editorBrowser) { initialized = true; + setFontSize(fontSize); setText(currentText, currentMode); runJavaScript("getTextChanged()", function(result) { }); pollTimer.running = true; diff --git a/mix/qml/html/cm/inkpot.css b/mix/qml/html/cm/inkpot.css new file mode 100644 index 000000000..c6863e624 --- /dev/null +++ b/mix/qml/html/cm/inkpot.css @@ -0,0 +1,65 @@ +/* +Inkpot theme for code-mirror +https://github.com/ciaranm/inkpot +*/ + +/* Color scheme for code-mirror */ + +.cm-s-inkpot.CodeMirror { + color: #cfbfad; + text-shadow: #1e1e27 0 1px; + background-color: #1e1e27; + line-height: 1.45em; + color-profile: sRGB; + rendering-intent: auto; +} + +.cm-s-inkpot .CodeMirror-gutters { background: #2e2e2e; border-right: 0px solid #aaa; } +.cm-s-inkpot .CodeMirror-linenumber { color: #8b8bcd; } +.cm-s-inkpot .CodeMirror-cursor { border-left: 1px solid white !important; } + +.cm-s-inkpot span.cm-comment { color: #cd8b00; } +.cm-s-inkpot span.cm-def { color: #cfbfad; font-weight:bold; } +.cm-s-inkpot span.cm-keyword { color: #808bed; } +.cm-s-inkpot span.cm-builtin { color: #cfbfad; } +.cm-s-inkpot span.cm-variable { color: #cfbfad; } +.cm-s-inkpot span.cm-string { color: #ffcd8b; } +.cm-s-inkpot span.cm-number { color: #f0ad6d; } +.cm-s-inkpot span.cm-atom { color: #cb6ecb; } +.cm-s-inkpot span.cm-variable-2 { color: #ffb8ff; } + +.cm-s-inkpot span.cm-meta { color: #409090; } +.cm-s-inkpot span.cm-qualifier { color: #808bed; } +.cm-s-inkpot span.cm-tag { color: #808bed; } +.cm-s-inkpot span.cm-attribute { color: #FF5555; } +.cm-s-inkpot span.cm-error { color: #f00; } + +.cm-s-inkpot .cm-bracket { color: #cb4b16; } +.cm-s-inkpot .CodeMirror-matchingbracket { color: #859900; } +.cm-s-inkpot .CodeMirror-nonmatchingbracket { color: #dc322f; } + +.cm-s-inkpot .CodeMirror-selected { background: #4e4e8f !important; } +span.CodeMirror-selectedtext { color: #ffffff !important; } + + +/* Code execution */ +.CodeMirror-exechighlight { + border-bottom: double 1px #94A2A2; +} + + +/* Error annotation */ +.CodeMirror-errorannotation { + border-bottom: 1px solid #DD3330; + margin-bottom: 4px; +} + +.CodeMirror-errorannotation-context { + font-family: monospace; + color: #EEE9D5; + background: #b58900; + padding: 2px; + text-shadow: none !important; + border-top: solid 2px #063742; +} + diff --git a/mix/qml/html/codeeditor.html b/mix/qml/html/codeeditor.html index c9d4ff96a..f368404fe 100644 --- a/mix/qml/html/codeeditor.html +++ b/mix/qml/html/codeeditor.html @@ -1,7 +1,8 @@ - + + diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index 501e0bd57..e8504fee0 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -9,7 +9,7 @@ var editor = CodeMirror(document.body, { }); var ternServer; -editor.setOption("theme", "solarized dark"); +editor.setOption("theme", "inkpot"); editor.setOption("indentUnit", 4); editor.setOption("indentWithTabs", true); editor.setOption("fullScreen", true); @@ -194,4 +194,11 @@ goToCompilationError = function() editor.setCursor(annotation.line, annotation.column) } +setFontSize = function(size) +{ + editor.getWrapperElement().style["font-size"] = size + "px"; + editor.refresh(); +} + editor.setOption("extraKeys", extraKeys); + diff --git a/mix/web.qrc b/mix/web.qrc index 6870411c5..a34fd0b67 100644 --- a/mix/web.qrc +++ b/mix/web.qrc @@ -32,6 +32,7 @@ qml/html/cm/show-hint.js qml/html/cm/signal.js qml/html/cm/solarized.css + qml/html/cm/inkpot.css qml/html/cm/solidity.js qml/html/cm/solidityToken.js qml/html/cm/tern.js From e4ee14bfad1a54da854ecc0f533ba66dce408de2 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 20 Apr 2015 14:57:49 +0200 Subject: [PATCH 37/58] style --- mix/qml/CodeEditorView.qml | 4 +--- mix/qml/WebCodeEditor.qml | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index 956b71915..e4d62ed81 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -160,8 +160,7 @@ Item { } } - function setFontSize(size) - { + function setFontSize(size) { if (size <= 10 || size >= 48) return; editorSettings.fontSize = size; @@ -329,7 +328,6 @@ Item { id: editorListModel } - Action { id: increaseFontSize text: qsTr("Increase Font Size") diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 9a9a3bea7..38f2327b1 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -83,7 +83,6 @@ Item { editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); } - Clipboard { id: clipboard From 46182cd82f55679cfa6e4146217feb047af15b20 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 20 Apr 2015 14:57:56 +0200 Subject: [PATCH 38/58] Styling. --- libsolidity/DeclarationContainer.cpp | 14 +++++--------- libsolidity/NameAndTypeResolver.cpp | 18 ++++++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/libsolidity/DeclarationContainer.cpp b/libsolidity/DeclarationContainer.cpp index 565f71dfd..5f8d24e34 100644 --- a/libsolidity/DeclarationContainer.cpp +++ b/libsolidity/DeclarationContainer.cpp @@ -24,10 +24,9 @@ #include #include -namespace dev -{ -namespace solidity -{ +using namespace std; +using namespace dev; +using namespace dev::solidity; bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update) { @@ -62,7 +61,7 @@ bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, return true; } -std::set DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const +set DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const { solAssert(!_name.empty(), "Attempt to resolve empty name."); auto result = m_declarations.find(_name); @@ -70,8 +69,5 @@ std::set DeclarationContainer::resolveName(ASTString const& return result->second; if (_recursive && m_enclosingContainer) return m_enclosingContainer->resolveName(_name, true); - return std::set({}); -} - -} + return set({}); } diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index 1c527b89c..a286934a9 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -31,7 +31,7 @@ namespace dev namespace solidity { -NameAndTypeResolver::NameAndTypeResolver(std::vector const& _globals) +NameAndTypeResolver::NameAndTypeResolver(vector const& _globals) { for (Declaration const* declaration: _globals) m_scopes[nullptr].registerDeclaration(*declaration); @@ -119,7 +119,7 @@ set NameAndTypeResolver::resolveName(ASTString const& _name, { auto iterator = m_scopes.find(_scope); if (iterator == end(m_scopes)) - return std::set({}); + return set({}); return iterator->second.resolveName(_name, false); } @@ -415,11 +415,17 @@ bool ReferencesResolver::visit(UserDefinedTypeName& _typeName) { auto declarations = m_resolver.getNameFromCurrentScope(_typeName.getName()); if (declarations.empty()) - BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation()) - << errinfo_comment("Undeclared identifier.")); + BOOST_THROW_EXCEPTION( + DeclarationError() << + errinfo_sourceLocation(_typeName.getLocation()) << + errinfo_comment("Undeclared identifier.") + ); else if (declarations.size() > 1) - BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation()) - << errinfo_comment("Duplicate identifier.")); + BOOST_THROW_EXCEPTION( + DeclarationError() << + errinfo_sourceLocation(_typeName.getLocation()) << + errinfo_comment("Duplicate identifier.") + ); else _typeName.setReferencedDeclaration(**declarations.begin()); return false; From 53da2881e95d3fb40220386cf2dec7de8e5991ae Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 17:58:10 +0200 Subject: [PATCH 39/58] Fix for mining, possibly. --- libethereum/Client.cpp | 9 --------- libethereum/State.h | 42 ++++++++++++++++++++---------------------- mix/MixClient.cpp | 2 +- 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 7ab4a99f4..b39a15e22 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -205,20 +205,11 @@ void Client::startedWorking() // TODO: currently it contains keys for *all* blocks. Make it remove old ones. cdebug << "startedWorking()"; - cdebug << m_bc.number() << m_bc.currentHash(); - cdebug << "Pre:" << m_preMine.info(); - cdebug << "Post:" << m_postMine.info(); - cdebug << "Pre:" << m_preMine.info().headerHash(WithoutNonce) << "; Post:" << m_postMine.info().headerHash(WithoutNonce); - ETH_WRITE_GUARDED(x_preMine) m_preMine.sync(m_bc); ETH_WRITE_GUARDED(x_postMine) ETH_READ_GUARDED(x_preMine) m_postMine = m_preMine; - - cdebug << "Pre:" << m_preMine.info(); - cdebug << "Post:" << m_postMine.info(); - cdebug << "Pre:" << m_preMine.info().headerHash(WithoutNonce) << "; Post:" << m_postMine.info().headerHash(WithoutNonce); } void Client::doneWorking() diff --git a/libethereum/State.h b/libethereum/State.h index 28b005243..1b36cbceb 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -161,15 +161,18 @@ public: /// This may be called multiple times and without issue. void commitToMine(BlockChain const& _bc); + /// @returns true iff commitToMine() has been called without any subsequest transactions added &c. + bool isCommittedToMine() const { return m_committedToMine; } + /// Pass in a solution to the proof-of-work. - /// @returns true iff the given nonce is a proof-of-work for this State's block. + /// @returns true iff we were previously committed to mining. template bool completeMine(typename PoW::Solution const& _result) { - PoW::assignResult(_result, m_currentBlock); + if (!m_committedToMine) + return false; - // if (!m_pow.verify(m_currentBlock)) - // return false; + PoW::assignResult(_result, m_currentBlock); cnote << "Completed" << m_currentBlock.headerHash(WithoutNonce).abridged() << m_currentBlock.nonce.abridged() << m_currentBlock.difficulty << PoW::verify(m_currentBlock); @@ -178,24 +181,6 @@ public: return true; } - /** Commit to DB and build the final block if the previous call to mine()'s result is completion. - * Typically looks like: - * @code - * while (notYetMined) - * { - * // lock - * commitToMine(_blockChain); // will call uncommitToMine if a repeat. - * // unlock - * MineInfo info; - * for (info.completed = false; !info.completed; info = mine()) {} - * } - * // lock - * completeMine(); - * // unlock - * @endcode - */ - void completeMine(); - /// Get the complete current block, including valid nonce. /// Only valid after mine() returns true. bytes const& blockData() const { return m_currentBytes; } @@ -327,6 +312,19 @@ public: void resetCurrent(); private: + /** Commit to DB and build the final block if the previous call to mine()'s result is completion. + * Typically looks like: + * @code + * while (notYetMined) + * { + * // lock + * commitToMine(_blockChain); // will call uncommitToMine if a repeat. + * completeMine(); + * // unlock + * @endcode + */ + void completeMine(); + /// Undo the changes to the state for committing to mine. void uncommitToMine(); diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 35d7dc413..b95dc5cf3 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -250,7 +250,7 @@ void MixClient::mine() { WriteGuard l(x_state); m_state.commitToMine(bc()); - m_state.completeMine(); + m_state.completeMine(Ethash::Solution()); bc().import(m_state.blockData(), m_stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce); /* GenericFarm f; From d2931fc1a6b7d2408f4a207193d620d93558550c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 18:02:44 +0200 Subject: [PATCH 40/58] Fix #1690. --- libdevcore/CommonIO.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libdevcore/CommonIO.h b/libdevcore/CommonIO.h index 478383b25..80334fa31 100644 --- a/libdevcore/CommonIO.h +++ b/libdevcore/CommonIO.h @@ -77,7 +77,11 @@ template inline std::ostream& operator<<(std::ostream& _out, template inline std::ostream& operator<<(std::ostream& _out, std::multimap const& _e); template _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p); +#ifdef _WIN32 +template inline std::string toString(std::chrono::time_point const& _e, std::string _format = "%Y-%m-%d %H:%M:%S") +#else template inline std::string toString(std::chrono::time_point const& _e, std::string _format = "%F %T") +#endif { unsigned long milliSecondsSinceEpoch = std::chrono::duration_cast(_e.time_since_epoch()).count(); auto const durationSinceEpoch = std::chrono::milliseconds(milliSecondsSinceEpoch); From 6f7d34f1961fe291aad2e48549862d3fdaa641d8 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 19:40:55 +0200 Subject: [PATCH 41/58] Terminal colour codes. --- libdevcore/Log.h | 7 +- libdevcore/Terminal.h | 157 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 libdevcore/Terminal.h diff --git a/libdevcore/Log.h b/libdevcore/Log.h index 812ec0886..f3d9942c9 100644 --- a/libdevcore/Log.h +++ b/libdevcore/Log.h @@ -28,6 +28,7 @@ #include #include "vector_ref.h" #include "CommonIO.h" +#include "Terminal.h" namespace dev { @@ -77,9 +78,9 @@ std::string getThreadName(); struct LogChannel { static const char* name() { return " "; } static const int verbosity = 1; }; struct LeftChannel: public LogChannel { static const char* name() { return "<<<"; } }; struct RightChannel: public LogChannel { static const char* name() { return ">>>"; } }; -struct WarnChannel: public LogChannel { static const char* name() { return "!!!"; } static const int verbosity = 0; }; +struct WarnChannel: public LogChannel { static const char* name() { return EthWhiteOn EthBlackB "!!!" EthReset; } static const int verbosity = 0; }; struct NoteChannel: public LogChannel { static const char* name() { return "***"; } }; -struct DebugChannel: public LogChannel { static const char* name() { return "---"; } static const int verbosity = 0; }; +struct DebugChannel: public LogChannel { static const char* name() { return EthWhiteB "---" EthReset; } static const int verbosity = 0; }; /// Logging class, iostream-like, that can be shifted to. template @@ -98,7 +99,7 @@ public: char buf[24]; if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) buf[0] = '\0'; // empty if case strftime fails - m_sstr << Id::name() << " [ " << buf << " | " << getThreadName() << ThreadContext::join(" | ") << (_term ? " ] " : ""); + m_sstr << Id::name() << EthBlue " [ " EthBlueI << buf << EthBlue " | " EthCyan << getThreadName() << ThreadContext::join(EthBlue " | " EthPurple) << (_term ? EthBlue " ] " : "") << EthReset; } } diff --git a/libdevcore/Terminal.h b/libdevcore/Terminal.h new file mode 100644 index 000000000..ce6fe898a --- /dev/null +++ b/libdevcore/Terminal.h @@ -0,0 +1,157 @@ +#pragma once + +namespace dev +{ +namespace con +{ + +#ifdef _WIN32 + +#define EthReset "" // Text Reset + +// Regular Colors +#define EthBlack "" // Black +#define EthRed "" // Red +#define EthGreen "" // Green +#define EthYellow "" // Yellow +#define EthBlue "" // Blue +#define EthPurple "" // Purple +#define EthCyan "" // Cyan +#define EthWhite "" // White + +// Bold +#define EthBlackB "" // Black +#define EthRedB "" // Red +#define EthGreenB "" // Green +#define EthYellowB "" // Yellow +#define EthBlueB "" // Blue +#define EthPurpleB "" // Purple +#define EthCyanB "" // Cyan +#define EthWhiteB "" // White + +// Underline +#define EthBlackU "" // Black +#define EthRedU "" // Red +#define EthGreenU "" // Green +#define EthYellowU "" // Yellow +#define EthBlueU "" // Blue +#define EthPurpleU "" // Purple +#define EthCyanU "" // Cyan +#define EthWhiteU "" // White + +// Background +#define EthBlackOn "" // Black +#define EthRedOn "" // Red +#define EthGreenOn "" // Green +#define EthYellowOn "" // Yellow +#define EthBlueOn "" // Blue +#define EthPurpleOn "" // Purple +#define EthCyanOn "" // Cyan +#define EthWhiteOn "" // White + +// High Intensity +#define EthCoal "" // Black +#define EthRedI "" // Red +#define EthGreenI "" // Green +#define EthYellowI "" // Yellow +#define EthBlueI "" // Blue +#define EthPurpleI "" // Purple +#define EthCyanI "" // Cyan +#define EthWhiteI "" // White + +// Bold High Intensity +#define EthBlackBI "" // Black +#define EthRedBI "" // Red +#define EthGreenBI "" // Green +#define EthYellowBI "" // Yellow +#define EthBlueBI "" // Blue +#define EthPurpleBI "" // Purple +#define EthCyanBI "" // Cyan +#define EthWhiteBI "" // White + +// High Intensity backgrounds +#define EthBlackOnI "" // Black +#define EthRedOnI "" // Red +#define EthGreenOnI "" // Green +#define EthYellowOnI "" // Yellow +#define EthBlueOnI "" // Blue +#define EthPurpleOnI "" // Purple +#define EthCyanOnI "" // Cyan +#define EthWhiteOnI "" // White + +#else + +#define EthReset "\x1b[0m" // Text Reset + +// Regular Colors +#define EthBlack "\x1b[30m" // Black +#define EthCoal "\x1b[90m" // Black +#define EthGray "\x1b[37m" // White +#define EthWhite "\x1b[97m" // White +#define EthRed "\x1b[31m" // Red +#define EthGreen "\x1b[32m" // Green +#define EthYellow "\x1b[33m" // Yellow +#define EthBlue "\x1b[34m" // Blue +#define EthPurple "\x1b[35m" // Purple +#define EthCyan "\x1b[36m" // Cyan +// High Intensity +#define EthRedI "\x1b[91m" // Red +#define EthGreenI "\x1b[92m" // Green +#define EthYellowI "\x1b[93m" // Yellow +#define EthBlueI "\x1b[94m" // Blue +#define EthPurpleI "\x1b[95m" // Purple +#define EthCyanI "\x1b[96m" // Cyan + +// Bold +#define EthBlackB "\x1b[1;30m" // Black +#define EthCoalB "\x1b[1;90m" // Black +#define EthGrayB "\x1b[1;37m" // White +#define EthWhiteB "\x1b[1;97m" // White +#define EthRedB "\x1b[1;31m" // Red +#define EthGreenB "\x1b[1;32m" // Green +#define EthYellowB "\x1b[1;33m" // Yellow +#define EthBlueB "\x1b[1;34m" // Blue +#define EthPurpleB "\x1b[1;35m" // Purple +#define EthCyanB "\x1b[1;36m" // Cyan +// Bold High Intensity +#define EthRedBI "\x1b[1;91m" // Red +#define EthGreenBI "\x1b[1;92m" // Green +#define EthYellowBI "\x1b[1;93m" // Yellow +#define EthBlueBI "\x1b[1;94m" // Blue +#define EthPurpleBI "\x1b[1;95m" // Purple +#define EthCyanBI "\x1b[1;96m" // Cyan + +// Background +#define EthBlackOn "\x1b[40m" // Black +#define EthCoalOn "\x1b[100m" // Black +#define EthGrayOn "\x1b[47m" // White +#define EthWhiteOn "\x1b[107m" // White +#define EthRedOn "\x1b[41m" // Red +#define EthGreenOn "\x1b[42m" // Green +#define EthYellowOn "\x1b[43m" // Yellow +#define EthBlueOn "\x1b[44m" // Blue +#define EthPurpleOn "\x1b[45m" // Purple +#define EthCyanOn "\x1b[46m" // Cyan +// High Intensity backgrounds +#define EthRedOnI "\x1b[101m" // Red +#define EthGreenOnI "\x1b[102m" // Green +#define EthYellowOnI "\x1b[103m" // Yellow +#define EthBlueOnI "\x1b[104m" // Blue +#define EthPurpleOnI "\x1b[105m" // Purple +#define EthCyanOnI "\x1b[106m" // Cyan + +// Underline +#define EthBlackU "\x1b[4;30m" // Black +#define EthRedU "\x1b[4;31m" // Red +#define EthGreenU "\x1b[4;32m" // Green +#define EthYellowU "\x1b[4;33m" // Yellow +#define EthBlueU "\x1b[4;34m" // Blue +#define EthPurpleU "\x1b[4;35m" // Purple +#define EthCyanU "\x1b[4;36m" // Cyan +#define EthWhiteU "\x1b[4;37m" // White + +#endif + +} + +} From 338e5bd0887a4b02d6e94ca30bf2cfcb00c530e0 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 20 Apr 2015 22:48:53 +0200 Subject: [PATCH 42/58] Restructure test folders --- {test => libdevcrypto}/trie.cpp | 0 {test => libp2p}/net.cpp | 0 libtestutils/Common.cpp | 6 + libtestutils/Common.h | 1 + test/CMakeLists.txt | 89 +-- test/TestHelper.cpp | 10 +- test/TestHelper.h | 3 +- test/{ => deprecated}/fork.cpp | 0 test/{ => deprecated}/kademlia.cpp | 0 test/{ => deprecated}/main.cpp | 0 test/{ => deprecated}/txTest.cpp | 0 test/fuzzTesting/CMakeLists.txt | 31 + .../checkRandomStateTest.cpp | 2 +- test/{ => fuzzTesting}/checkRandomVMTest.cpp | 3 +- .../createRandomStateTest.cpp | 4 +- test/{ => fuzzTesting}/createRandomVMTest.cpp | 2 +- test/libdevcore/CMakeLists.txt | 5 + test/{ => libdevcore}/rlp.cpp | 4 +- test/libdevcrypto/CMakeLists.txt | 5 + test/{ => libdevcrypto}/MemTrie.cpp | 0 test/{ => libdevcrypto}/MemTrie.h | 0 test/{ => libdevcrypto}/TrieHash.cpp | 0 test/{ => libdevcrypto}/TrieHash.h | 0 test/{ => libdevcrypto}/crypto.cpp | 0 test/{ => libdevcrypto}/hexPrefix.cpp | 4 +- test/libdevcrypto/trie.cpp | 553 ++++++++++++++++ test/libethcore/CMakeLists.txt | 5 + test/{ => libethcore}/commonjs.cpp | 0 test/{ => libethcore}/dagger.cpp | 4 +- .../bcInvalidHeaderTestFiller.json | 0 .../bcJS_API_TestFiller.json | 0 .../bcUncleHeaderValiditiyFiller.json | 0 .../BlockTestsFiller}/bcUncleTestFiller.json | 0 .../bcValidBlockTestFiller.json | 0 test/libethereum/CMakeLists.txt | 5 + test/{ => libethereum}/ClientBase.cpp | 2 +- .../StateTestsFiller}/ManyFunctions.sol | 0 .../ManyFunctionsGenerator.py | 0 .../stBlockHashTestFiller.json | 0 .../stCallCreateCallCodeTestFiller.json | 0 .../StateTestsFiller}/stExampleFiller.json | 0 .../stInitCodeTestFiller.json | 0 .../StateTestsFiller}/stLogTestsFiller.json | 0 .../stMemoryStressTestFiller.json | 0 .../StateTestsFiller}/stMemoryTestFiller.json | 0 .../stPreCompiledContractsFiller.json | 0 .../stQuadraticComplexityTestFiller.json | 0 .../stRecursiveCreateFiller.json | 0 .../StateTestsFiller}/stRefundTestFiller.json | 0 .../stSolidityTestFiller.json | 0 .../stSpecialTestFiller.json | 0 .../stSystemOperationsTestFiller.json | 0 .../stTransactionTestFiller.json | 0 .../tt10mbDataFieldFiller.json | 0 .../ttTransactionTestFiller.json | 0 test/{ => libethereum}/blockchain.cpp | 16 +- test/{ => libethereum}/genesis.cpp | 4 +- test/{ => libethereum}/state.cpp | 34 +- test/{ => libethereum}/stateOriginal.cpp | 2 +- test/{ => libethereum}/transaction.cpp | 8 +- test/libevm/CMakeLists.txt | 5 + .../VMTestsFiller/performanceTester.sol} | 0 .../vmArithmeticTestFiller.json | 0 .../vmBitwiseLogicOperationTestFiller.json | 0 .../VMTestsFiller}/vmBlockInfoTestFiller.json | 0 .../vmEnvironmentalInfoTestFiller.json | 0 .../vmIOandFlowOperationsTestFiller.json | 0 .../VMTestsFiller}/vmLogTestFiller.json | 0 .../vmPerformanceTestFiller.json | 0 .../vmPushDupSwapTestFiller.json | 0 .../VMTestsFiller}/vmSha3TestFiller.json | 0 .../vmSystemOperationsTestFiller.json | 0 .../VMTestsFiller}/vmtestsFiller.json | 0 test/{ => libevm}/vm.cpp | 28 +- test/{ => libevm}/vm.h | 2 +- test/{ => libevmcore}/Assembly.cpp | 0 test/libevmcore/CMakeLists.txt | 5 + test/libnatspec/CMakeLists.txt | 5 + test/{ => libnatspec}/natspec.cpp | 0 test/libp2p/CMakeLists.txt | 5 + test/libp2p/net.cpp | 372 +++++++++++ test/{ => libp2p}/peer.cpp | 0 test/{ => libp2p}/rlpx.cpp | 0 test/libsolidity/CMakeLists.txt | 5 + test/{ => libsolidity}/SolidityABIJSON.cpp | 2 +- test/{ => libsolidity}/SolidityCompiler.cpp | 0 .../SolidityEndToEndTest.cpp | 2 +- .../SolidityExpressionCompiler.cpp | 2 +- test/{ => libsolidity}/SolidityInterface.cpp | 2 +- .../SolidityNameAndTypeResolution.cpp | 2 +- .../{ => libsolidity}/SolidityNatspecJSON.cpp | 2 +- test/{ => libsolidity}/SolidityOptimizer.cpp | 2 +- test/{ => libsolidity}/SolidityParser.cpp | 2 +- test/{ => libsolidity}/SolidityScanner.cpp | 0 test/{ => libsolidity}/SolidityTypes.cpp | 0 .../solidityExecutionFramework.h | 2 +- test/{ => libweb3jsonrpc}/AccountHolder.cpp | 0 test/libweb3jsonrpc/CMakeLists.txt | 5 + test/{ => libweb3jsonrpc}/jsonrpc.cpp | 4 +- test/libweb3jsonrpc/webthreestubclient.h | 596 ++++++++++++++++++ test/libwhisper/CMakeLists.txt | 5 + test/{ => libwhisper}/whisperTopic.cpp | 0 test/randomTestFiller.json | 29 - 103 files changed, 1741 insertions(+), 145 deletions(-) rename {test => libdevcrypto}/trie.cpp (100%) rename {test => libp2p}/net.cpp (100%) rename test/{ => deprecated}/fork.cpp (100%) rename test/{ => deprecated}/kademlia.cpp (100%) rename test/{ => deprecated}/main.cpp (100%) rename test/{ => deprecated}/txTest.cpp (100%) create mode 100644 test/fuzzTesting/CMakeLists.txt rename test/{ => fuzzTesting}/checkRandomStateTest.cpp (99%) rename test/{ => fuzzTesting}/checkRandomVMTest.cpp (99%) rename test/{ => fuzzTesting}/createRandomStateTest.cpp (99%) rename test/{ => fuzzTesting}/createRandomVMTest.cpp (99%) create mode 100644 test/libdevcore/CMakeLists.txt rename test/{ => libdevcore}/rlp.cpp (98%) create mode 100644 test/libdevcrypto/CMakeLists.txt rename test/{ => libdevcrypto}/MemTrie.cpp (100%) rename test/{ => libdevcrypto}/MemTrie.h (100%) rename test/{ => libdevcrypto}/TrieHash.cpp (100%) rename test/{ => libdevcrypto}/TrieHash.h (100%) rename test/{ => libdevcrypto}/crypto.cpp (100%) rename test/{ => libdevcrypto}/hexPrefix.cpp (96%) create mode 100644 test/libdevcrypto/trie.cpp create mode 100644 test/libethcore/CMakeLists.txt rename test/{ => libethcore}/commonjs.cpp (100%) rename test/{ => libethcore}/dagger.cpp (97%) rename test/{ => libethereum/BlockTestsFiller}/bcInvalidHeaderTestFiller.json (100%) rename test/{ => libethereum/BlockTestsFiller}/bcJS_API_TestFiller.json (100%) rename test/{ => libethereum/BlockTestsFiller}/bcUncleHeaderValiditiyFiller.json (100%) rename test/{ => libethereum/BlockTestsFiller}/bcUncleTestFiller.json (100%) rename test/{ => libethereum/BlockTestsFiller}/bcValidBlockTestFiller.json (100%) create mode 100644 test/libethereum/CMakeLists.txt rename test/{ => libethereum}/ClientBase.cpp (99%) rename test/{ => libethereum/StateTestsFiller}/ManyFunctions.sol (100%) rename test/{ => libethereum/StateTestsFiller}/ManyFunctionsGenerator.py (100%) rename test/{ => libethereum/StateTestsFiller}/stBlockHashTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stCallCreateCallCodeTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stExampleFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stInitCodeTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stLogTestsFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stMemoryStressTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stMemoryTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stPreCompiledContractsFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stQuadraticComplexityTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stRecursiveCreateFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stRefundTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stSolidityTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stSpecialTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stSystemOperationsTestFiller.json (100%) rename test/{ => libethereum/StateTestsFiller}/stTransactionTestFiller.json (100%) rename test/{ => libethereum/TransactionTestsFiller}/tt10mbDataFieldFiller.json (100%) rename test/{ => libethereum/TransactionTestsFiller}/ttTransactionTestFiller.json (100%) rename test/{ => libethereum}/blockchain.cpp (96%) rename test/{ => libethereum}/genesis.cpp (97%) rename test/{ => libethereum}/state.cpp (77%) rename test/{ => libethereum}/stateOriginal.cpp (98%) rename test/{ => libethereum}/transaction.cpp (96%) create mode 100644 test/libevm/CMakeLists.txt rename test/{PerformaceTester.sol => libevm/VMTestsFiller/performanceTester.sol} (100%) rename test/{ => libevm/VMTestsFiller}/vmArithmeticTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmBitwiseLogicOperationTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmBlockInfoTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmEnvironmentalInfoTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmIOandFlowOperationsTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmLogTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmPerformanceTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmPushDupSwapTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmSha3TestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmSystemOperationsTestFiller.json (100%) rename test/{ => libevm/VMTestsFiller}/vmtestsFiller.json (100%) rename test/{ => libevm}/vm.cpp (90%) rename test/{ => libevm}/vm.h (99%) rename test/{ => libevmcore}/Assembly.cpp (100%) create mode 100644 test/libevmcore/CMakeLists.txt create mode 100644 test/libnatspec/CMakeLists.txt rename test/{ => libnatspec}/natspec.cpp (100%) create mode 100644 test/libp2p/CMakeLists.txt create mode 100644 test/libp2p/net.cpp rename test/{ => libp2p}/peer.cpp (100%) rename test/{ => libp2p}/rlpx.cpp (100%) create mode 100644 test/libsolidity/CMakeLists.txt rename test/{ => libsolidity}/SolidityABIJSON.cpp (99%) rename test/{ => libsolidity}/SolidityCompiler.cpp (100%) rename test/{ => libsolidity}/SolidityEndToEndTest.cpp (99%) rename test/{ => libsolidity}/SolidityExpressionCompiler.cpp (99%) rename test/{ => libsolidity}/SolidityInterface.cpp (99%) rename test/{ => libsolidity}/SolidityNameAndTypeResolution.cpp (99%) rename test/{ => libsolidity}/SolidityNatspecJSON.cpp (99%) rename test/{ => libsolidity}/SolidityOptimizer.cpp (99%) rename test/{ => libsolidity}/SolidityParser.cpp (99%) rename test/{ => libsolidity}/SolidityScanner.cpp (100%) rename test/{ => libsolidity}/SolidityTypes.cpp (100%) rename test/{ => libsolidity}/solidityExecutionFramework.h (99%) rename test/{ => libweb3jsonrpc}/AccountHolder.cpp (100%) create mode 100644 test/libweb3jsonrpc/CMakeLists.txt rename test/{ => libweb3jsonrpc}/jsonrpc.cpp (99%) create mode 100644 test/libweb3jsonrpc/webthreestubclient.h create mode 100644 test/libwhisper/CMakeLists.txt rename test/{ => libwhisper}/whisperTopic.cpp (100%) delete mode 100644 test/randomTestFiller.json diff --git a/test/trie.cpp b/libdevcrypto/trie.cpp similarity index 100% rename from test/trie.cpp rename to libdevcrypto/trie.cpp diff --git a/test/net.cpp b/libp2p/net.cpp similarity index 100% rename from test/net.cpp rename to libp2p/net.cpp diff --git a/libtestutils/Common.cpp b/libtestutils/Common.cpp index 86f96f667..6bc9d2c15 100644 --- a/libtestutils/Common.cpp +++ b/libtestutils/Common.cpp @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -71,6 +72,11 @@ std::string dev::test::toTestFilePath(std::string const& _filename) return getTestPath() + "/" + _filename + ".json"; } +std::string dev::test::getFolder(std::string const& _line) +{ + return boost::filesystem::path(_line).parent_path().string(); +} + std::string dev::test::getRandomPath() { std::stringstream stream; diff --git a/libtestutils/Common.h b/libtestutils/Common.h index 4757a3b7a..33acd36f1 100644 --- a/libtestutils/Common.h +++ b/libtestutils/Common.h @@ -37,6 +37,7 @@ std::string getTestPath(); int randomNumber(); Json::Value loadJsonFromFile(std::string const& _path); std::string toTestFilePath(std::string const& _filename); +std::string getFolder(std::string const& _line); std::string getRandomPath(); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 90af5122e..bbb351232 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,10 +1,42 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) -list(REMOVE_ITEM SRC_LIST "./createRandomVMTest.cpp") -list(REMOVE_ITEM SRC_LIST "./createRandomStateTest.cpp") -list(REMOVE_ITEM SRC_LIST "./checkRandomVMTest.cpp") -list(REMOVE_ITEM SRC_LIST "./checkRandomStateTest.cpp") + +macro (add_sources) + file (RELATIVE_PATH _relPath "${CMAKE_SOURCE_DIR}/test" "${CMAKE_CURRENT_SOURCE_DIR}") + foreach (_src ${ARGN}) + if (_relPath) + list (APPEND SRC "${_relPath}/${_src}") + else() + list (APPEND SRC "${_src}") + endif() + endforeach() + if (_relPath) + # propagate SRCS to parent directory + set (SRC ${SRC} PARENT_SCOPE) + endif() +endmacro() + +#add_sources(boostTest.cpp) + +add_subdirectory(fuzzTesting) +add_subdirectory(libdevcore) +add_subdirectory(libdevcrypto) +add_subdirectory(libethcore) +add_subdirectory(libethereum) +add_subdirectory(libevm) +add_subdirectory(libevmcore) +add_subdirectory(libnatspec) +add_subdirectory(libp2p) +add_subdirectory(libsolidity) +add_subdirectory(libweb3jsonrpc) +add_subdirectory(libwhisper) + +message(STATUS "${SRC}") +message("AHA") + +set(SRC_LIST ${SRC_LIST} ${SRC}) +message(STATUS "${SRC_LIST}") if (NOT JSONRPC) list(REMOVE_ITEM SRC_LIST "./AccountHolder.cpp") @@ -17,27 +49,23 @@ include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) # search for test names and create ctest tests -enable_testing() -foreach(file ${SRC_LIST}) - file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE)") - set(TestSuite "DEFAULT") - foreach(test_raw ${test_list_raw}) - string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) - if(test MATCHES "^SUITE .*") - string(SUBSTRING ${test} 6 -1 TestSuite) - elseif(test MATCHES "^CASE .*") - string(SUBSTRING ${test} 5 -1 TestCase) - add_test(NAME ${TestSuite}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth -t ${TestSuite}/${TestCase}) - endif(test MATCHES "^SUITE .*") - endforeach(test_raw) -endforeach(file) +#enable_testing() +#foreach(file ${SRC_LIST}) +# file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE)") +# set(TestSuite "DEFAULT") +# foreach(test_raw ${test_list_raw}) +# string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) +# if(test MATCHES "^SUITE .*") +# string(SUBSTRING ${test} 6 -1 TestSuite) +# elseif(test MATCHES "^CASE .*") +# string(SUBSTRING ${test} 5 -1 TestCase) +# add_test(NAME ${TestSuite}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth -t ${TestSuite}/${TestCase}) +# endif(test MATCHES "^SUITE .*") +# endforeach(test_raw) +#endforeach(file) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) -add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) -add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp Stats.cpp) -add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) -add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp Stats.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) @@ -57,23 +85,6 @@ if (JSONRPC) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() -target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(createRandomVMTest ethereum) -target_link_libraries(createRandomVMTest ethcore) -target_link_libraries(createRandomVMTest testutils) -target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(createRandomStateTest ethereum) -target_link_libraries(createRandomStateTest ethcore) -target_link_libraries(createRandomStateTest testutils) -target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(checkRandomVMTest ethereum) -target_link_libraries(checkRandomVMTest ethcore) -target_link_libraries(checkRandomVMTest testutils) -target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(checkRandomStateTest ethereum) -target_link_libraries(checkRandomStateTest ethcore) -target_link_libraries(checkRandomStateTest testutils) - enable_testing() set(CTEST_OUTPUT_ON_FAILURE TRUE) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ed844e961..3d0856829 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -23,9 +23,6 @@ #include #include - -#include - #include #include #include @@ -592,7 +589,7 @@ void userDefinedTest(string testTypeFlag, std::function doTests) +void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests) { string testPath = getTestPath(); testPath += _testPathAppendix; @@ -605,11 +602,12 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun try { cnote << "Populating tests..."; + cout << "boost::filesystem::current_path(): " << boost::filesystem::current_path().string() << endl; json_spirit::mValue v; boost::filesystem::path p(__FILE__); boost::filesystem::path dir = p.parent_path(); - string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty."); + string s = asString(dev::contents(_pathToFiller.string() + "/" + _name + "Filler.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + _pathToFiller.string() + "/" + _name + "Filler.json is empty."); json_spirit::read_string(s, v); doTests(v, true); writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); diff --git a/test/TestHelper.h b/test/TestHelper.h index 36a84ecdb..bf4cdc16e 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -24,6 +24,7 @@ #include #include +#include #include "JsonSpiritHeaders.h" #include @@ -155,7 +156,7 @@ void checkStorage(std::map _expectedStore, std::map _res void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs); void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates); -void executeTests(const std::string& _name, const std::string& _testPathAppendix, std::function doTests); +void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests); void userDefinedTest(std::string testTypeFlag, std::function doTests); RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj); eth::LastHashes lastHashes(u256 _currentBlockNumber); diff --git a/test/fork.cpp b/test/deprecated/fork.cpp similarity index 100% rename from test/fork.cpp rename to test/deprecated/fork.cpp diff --git a/test/kademlia.cpp b/test/deprecated/kademlia.cpp similarity index 100% rename from test/kademlia.cpp rename to test/deprecated/kademlia.cpp diff --git a/test/main.cpp b/test/deprecated/main.cpp similarity index 100% rename from test/main.cpp rename to test/deprecated/main.cpp diff --git a/test/txTest.cpp b/test/deprecated/txTest.cpp similarity index 100% rename from test/txTest.cpp rename to test/deprecated/txTest.cpp diff --git a/test/fuzzTesting/CMakeLists.txt b/test/fuzzTesting/CMakeLists.txt new file mode 100644 index 000000000..1aa5cff84 --- /dev/null +++ b/test/fuzzTesting/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_policy(SET CMP0015 NEW) + +file(GLOB HEADERS "*.h") +include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) +include_directories(BEFORE ..) +include_directories(BEFORE ../..) +include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${CRYPTOPP_INCLUDE_DIRS}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) + +add_executable(createRandomVMTest createRandomVMTest.cpp ../libevm/vm.cpp ../TestHelper.cpp ../Stats.cpp) +add_executable(createRandomStateTest createRandomStateTest.cpp ../TestHelper.cpp ../Stats.cpp) +add_executable(checkRandomVMTest checkRandomVMTest.cpp ../libevm/vm.cpp ../TestHelper.cpp ../Stats.cpp) +add_executable(checkRandomStateTest checkRandomStateTest.cpp ../TestHelper.cpp ../Stats.cpp) + +target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(createRandomVMTest ethereum) +target_link_libraries(createRandomVMTest ethcore) +target_link_libraries(createRandomVMTest testutils) +target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(createRandomStateTest ethereum) +target_link_libraries(createRandomStateTest ethcore) +target_link_libraries(createRandomStateTest testutils) +target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(checkRandomVMTest ethereum) +target_link_libraries(checkRandomVMTest ethcore) +target_link_libraries(checkRandomVMTest testutils) +target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(checkRandomStateTest ethereum) +target_link_libraries(checkRandomStateTest ethcore) +target_link_libraries(checkRandomStateTest testutils) diff --git a/test/checkRandomStateTest.cpp b/test/fuzzTesting/checkRandomStateTest.cpp similarity index 99% rename from test/checkRandomStateTest.cpp rename to test/fuzzTesting/checkRandomStateTest.cpp index 49aca852f..260f9e004 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/fuzzTesting/checkRandomStateTest.cpp @@ -26,7 +26,7 @@ #include #include #include "TestHelper.h" -#include "vm.h" +#include "../libevm/vm.h" #pragma GCC diagnostic ignored "-Wunused-parameter" using namespace std; diff --git a/test/checkRandomVMTest.cpp b/test/fuzzTesting/checkRandomVMTest.cpp similarity index 99% rename from test/checkRandomVMTest.cpp rename to test/fuzzTesting/checkRandomVMTest.cpp index a40922577..bb55dcffa 100644 --- a/test/checkRandomVMTest.cpp +++ b/test/fuzzTesting/checkRandomVMTest.cpp @@ -25,7 +25,8 @@ #include #include #include -#include "vm.h" +#include "../libevm/vm.h" + #pragma GCC diagnostic ignored "-Wunused-parameter" using namespace std; diff --git a/test/createRandomStateTest.cpp b/test/fuzzTesting/createRandomStateTest.cpp similarity index 99% rename from test/createRandomStateTest.cpp rename to test/fuzzTesting/createRandomStateTest.cpp index 5758598b9..6e42934bc 100644 --- a/test/createRandomStateTest.cpp +++ b/test/fuzzTesting/createRandomStateTest.cpp @@ -35,8 +35,8 @@ #include #include #include -#include "TestHelper.h" -#include "vm.h" +#include "../TestHelper.h" +#include "../libevm/vm.h" using namespace std; using namespace json_spirit; diff --git a/test/createRandomVMTest.cpp b/test/fuzzTesting/createRandomVMTest.cpp similarity index 99% rename from test/createRandomVMTest.cpp rename to test/fuzzTesting/createRandomVMTest.cpp index de81099fe..abb4e184b 100644 --- a/test/createRandomVMTest.cpp +++ b/test/fuzzTesting/createRandomVMTest.cpp @@ -35,7 +35,7 @@ #include #include #include -#include "vm.h" +#include "../libevm/vm.h" using namespace std; using namespace json_spirit; diff --git a/test/libdevcore/CMakeLists.txt b/test/libdevcore/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libdevcore/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/rlp.cpp b/test/libdevcore/rlp.cpp similarity index 98% rename from test/rlp.cpp rename to test/libdevcore/rlp.cpp index 9062b54f4..41362d569 100644 --- a/test/rlp.cpp +++ b/test/libdevcore/rlp.cpp @@ -30,8 +30,8 @@ #include #include #include -#include "JsonSpiritHeaders.h" -#include "TestHelper.h" +#include "../JsonSpiritHeaders.h" +#include "../TestHelper.h" using namespace std; using namespace dev; diff --git a/test/libdevcrypto/CMakeLists.txt b/test/libdevcrypto/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libdevcrypto/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/MemTrie.cpp b/test/libdevcrypto/MemTrie.cpp similarity index 100% rename from test/MemTrie.cpp rename to test/libdevcrypto/MemTrie.cpp diff --git a/test/MemTrie.h b/test/libdevcrypto/MemTrie.h similarity index 100% rename from test/MemTrie.h rename to test/libdevcrypto/MemTrie.h diff --git a/test/TrieHash.cpp b/test/libdevcrypto/TrieHash.cpp similarity index 100% rename from test/TrieHash.cpp rename to test/libdevcrypto/TrieHash.cpp diff --git a/test/TrieHash.h b/test/libdevcrypto/TrieHash.h similarity index 100% rename from test/TrieHash.h rename to test/libdevcrypto/TrieHash.h diff --git a/test/crypto.cpp b/test/libdevcrypto/crypto.cpp similarity index 100% rename from test/crypto.cpp rename to test/libdevcrypto/crypto.cpp diff --git a/test/hexPrefix.cpp b/test/libdevcrypto/hexPrefix.cpp similarity index 96% rename from test/hexPrefix.cpp rename to test/libdevcrypto/hexPrefix.cpp index da294ba5b..c72f24535 100644 --- a/test/hexPrefix.cpp +++ b/test/libdevcrypto/hexPrefix.cpp @@ -24,11 +24,11 @@ #include -#include "JsonSpiritHeaders.h" +#include "../JsonSpiritHeaders.h" #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace dev; diff --git a/test/libdevcrypto/trie.cpp b/test/libdevcrypto/trie.cpp new file mode 100644 index 000000000..0e7125624 --- /dev/null +++ b/test/libdevcrypto/trie.cpp @@ -0,0 +1,553 @@ +/* + 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 . +*/ +/** @file trie.cpp + * @author Gav Wood + * @date 2014 + * Trie test functions. + */ + +#include +#include + +#include + +#include "../JsonSpiritHeaders.h" +#include +#include +#include "TrieHash.h" +#include "MemTrie.h" +#include "../TestHelper.h" + +using namespace std; +using namespace dev; + +namespace js = json_spirit; + +namespace dev +{ +namespace test +{ + +static unsigned fac(unsigned _i) +{ + return _i > 2 ? _i * fac(_i - 1) : _i; +} + +} +} + +using dev::operator <<; + +BOOST_AUTO_TEST_SUITE(TrieTests) + +BOOST_AUTO_TEST_CASE(fat_trie) +{ + h256 r; + MemoryDB fm; + { + FatGenericTrieDB ft(&fm); + ft.init(); + ft.insert(h256("69", h256::FromHex, h256::AlignRight).ref(), h256("414243", h256::FromHex, h256::AlignRight).ref()); + for (auto i: ft) + cnote << i.first << i.second; + r = ft.root(); + } + { + FatGenericTrieDB ft(&fm); + ft.setRoot(r); + for (auto i: ft) + cnote << i.first << i.second; + } +} + +BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test) +{ + string testPath = test::getTestPath(); + + testPath += "/TrieTests"; + + cnote << "Testing Secure Trie..."; + js::mValue v; + string s = asString(contents(testPath + "/hex_encoded_securetrie_test.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'hex_encoded_securetrie_test.json' is empty. Have you cloned the 'tests' repo branch develop?"); + js::read_string(s, v); + for (auto& i: v.get_obj()) + { + cnote << i.first; + js::mObject& o = i.second.get_obj(); + vector> ss; + for (auto i: o["in"].get_obj()) + { + ss.push_back(make_pair(i.first, i.second.get_str())); + if (!ss.back().first.find("0x")) + ss.back().first = asString(fromHex(ss.back().first.substr(2))); + if (!ss.back().second.find("0x")) + ss.back().second = asString(fromHex(ss.back().second.substr(2))); + } + for (unsigned j = 0; j < min(1000000000u, dev::test::fac((unsigned)ss.size())); ++j) + { + next_permutation(ss.begin(), ss.end()); + MemoryDB m; + GenericTrieDB t(&m); + MemoryDB hm; + HashedGenericTrieDB ht(&hm); + MemoryDB fm; + FatGenericTrieDB ft(&fm); + t.init(); + ht.init(); + ft.init(); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + for (auto const& k: ss) + { + t.insert(k.first, k.second); + ht.insert(k.first, k.second); + ft.insert(k.first, k.second); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + { + BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); + BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); + BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); + } + BOOST_CHECK_EQUAL(ht.root(), ft.root()); + } + BOOST_REQUIRE(!o["root"].is_null()); + BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ht.root().asArray())); + BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ft.root().asArray())); + } + } +} + +BOOST_AUTO_TEST_CASE(trie_test_anyorder) +{ + string testPath = test::getTestPath(); + + testPath += "/TrieTests"; + + cnote << "Testing Trie..."; + js::mValue v; + string s = asString(contents(testPath + "/trieanyorder.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trieanyorder.json' is empty. Have you cloned the 'tests' repo branch develop?"); + js::read_string(s, v); + for (auto& i: v.get_obj()) + { + cnote << i.first; + js::mObject& o = i.second.get_obj(); + vector> ss; + for (auto i: o["in"].get_obj()) + { + ss.push_back(make_pair(i.first, i.second.get_str())); + if (!ss.back().first.find("0x")) + ss.back().first = asString(fromHex(ss.back().first.substr(2))); + if (!ss.back().second.find("0x")) + ss.back().second = asString(fromHex(ss.back().second.substr(2))); + } + for (unsigned j = 0; j < min(1000u, dev::test::fac((unsigned)ss.size())); ++j) + { + next_permutation(ss.begin(), ss.end()); + MemoryDB m; + GenericTrieDB t(&m); + MemoryDB hm; + HashedGenericTrieDB ht(&hm); + MemoryDB fm; + FatGenericTrieDB ft(&fm); + t.init(); + ht.init(); + ft.init(); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + for (auto const& k: ss) + { + t.insert(k.first, k.second); + ht.insert(k.first, k.second); + ft.insert(k.first, k.second); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + { + BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); + BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); + BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); + } + BOOST_CHECK_EQUAL(ht.root(), ft.root()); + } + BOOST_REQUIRE(!o["root"].is_null()); + BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); + BOOST_CHECK_EQUAL(ht.root(), ft.root()); + } + } +} + +BOOST_AUTO_TEST_CASE(trie_tests_ordered) +{ + string testPath = test::getTestPath(); + + testPath += "/TrieTests"; + + cnote << "Testing Trie..."; + js::mValue v; + string s = asString(contents(testPath + "/trietest.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trietest.json' is empty. Have you cloned the 'tests' repo branch develop?"); + js::read_string(s, v); + + for (auto& i: v.get_obj()) + { + cnote << i.first; + js::mObject& o = i.second.get_obj(); + vector> ss; + vector keysToBeDeleted; + for (auto& i: o["in"].get_array()) + { + vector values; + for (auto& s: i.get_array()) + { + if (s.type() == json_spirit::str_type) + values.push_back(s.get_str()); + else if (s.type() == json_spirit::null_type) + { + // mark entry for deletion + values.push_back(""); + if (!values[0].find("0x")) + values[0] = asString(fromHex(values[0].substr(2))); + keysToBeDeleted.push_back(values[0]); + } + else + BOOST_FAIL("Bad type (expected string)"); + } + + BOOST_REQUIRE(values.size() == 2); + ss.push_back(make_pair(values[0], values[1])); + if (!ss.back().first.find("0x")) + ss.back().first = asString(fromHex(ss.back().first.substr(2))); + if (!ss.back().second.find("0x")) + ss.back().second = asString(fromHex(ss.back().second.substr(2))); + } + + MemoryDB m; + GenericTrieDB t(&m); + MemoryDB hm; + HashedGenericTrieDB ht(&hm); + MemoryDB fm; + FatGenericTrieDB ft(&fm); + t.init(); + ht.init(); + ft.init(); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + + for (auto const& k: ss) + { + if (find(keysToBeDeleted.begin(), keysToBeDeleted.end(), k.first) != keysToBeDeleted.end() && k.second.empty()) + t.remove(k.first), ht.remove(k.first), ft.remove(k.first); + else + t.insert(k.first, k.second), ht.insert(k.first, k.second), ft.insert(k.first, k.second); + BOOST_REQUIRE(t.check(true)); + BOOST_REQUIRE(ht.check(true)); + BOOST_REQUIRE(ft.check(true)); + for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + { + BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); + BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); + BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); + } + BOOST_CHECK_EQUAL(ht.root(), ft.root()); + } + + BOOST_REQUIRE(!o["root"].is_null()); + BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); + } +} + +inline h256 stringMapHash256(StringMap const& _s) +{ + return hash256(_s); +} + +BOOST_AUTO_TEST_CASE(moreTrieTests) +{ + cnote << "Testing Trie more..."; +#if 0 + // More tests... + { + MemoryDB m; + GenericTrieDB t(&m); + t.init(); // initialise as empty tree. + cout << t; + cout << m; + cout << t.root() << endl; + cout << hash256(StringMap()) << endl; + + t.insert(string("tesz"), string("test")); + cout << t; + cout << m; + cout << t.root() << endl; + cout << stringMapHash256({{"test", "test"}}) << endl; + + t.insert(string("tesa"), string("testy")); + cout << t; + cout << m; + cout << t.root() << endl; + cout << stringMapHash256({{"test", "test"}, {"te", "testy"}}) << endl; + cout << t.at(string("test")) << endl; + cout << t.at(string("te")) << endl; + cout << t.at(string("t")) << endl; + + t.remove(string("te")); + cout << m; + cout << t.root() << endl; + cout << stringMapHash256({{"test", "test"}}) << endl; + + t.remove(string("test")); + cout << m; + cout << t.root() << endl; + cout << hash256(StringMap()) << endl; + } + { + MemoryDB m; + GenericTrieDB t(&m); + t.init(); // initialise as empty tree. + t.insert(string("a"), string("A")); + t.insert(string("b"), string("B")); + cout << t; + cout << m; + cout << t.root() << endl; + cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl; + cout << RLP(rlp256({{"b", "B"}, {"a", "A"}})) << endl; + } + { + MemTrie t; + t.insert("dog", "puppy"); + cout << hex << t.hash256() << endl; + cout << RLP(t.rlp()) << endl; + } + { + MemTrie t; + t.insert("bed", "d"); + t.insert("be", "e"); + cout << hex << t.hash256() << endl; + cout << RLP(t.rlp()) << endl; + } + { + cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl; + MemTrie t; + t.insert("dog", "puppy"); + t.insert("doe", "reindeer"); + cout << hex << t.hash256() << endl; + cout << RLP(t.rlp()) << endl; + cout << toHex(t.rlp()) << endl; + } +#endif + { + MemoryDB m; + GenericTrieDB d(&m); + d.init(); // initialise as empty tree. + MemTrie t; + StringMap s; + + auto add = [&](char const* a, char const* b) + { + d.insert(string(a), string(b)); + t.insert(a, b); + s[a] = b; + + /*cout << endl << "-------------------------------" << endl; + cout << a << " -> " << b << endl; + cout << d; + cout << m; + cout << d.root() << endl; + cout << hash256(s) << endl;*/ + + BOOST_REQUIRE(d.check(true)); + BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); + BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); + for (auto const& i: s) + { + (void)i; + BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); + BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); + } + }; + + auto remove = [&](char const* a) + { + s.erase(a); + t.remove(a); + d.remove(string(a)); + + /*cout << endl << "-------------------------------" << endl; + cout << "X " << a << endl; + cout << d; + cout << m; + cout << d.root() << endl; + cout << hash256(s) << endl;*/ + + BOOST_REQUIRE(d.check(true)); + BOOST_REQUIRE(t.at(a).empty()); + BOOST_REQUIRE(d.at(string(a)).empty()); + BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); + BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); + for (auto const& i: s) + { + (void)i; + BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); + BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); + } + }; + + add("dogglesworth", "cat"); + add("doe", "reindeer"); + remove("dogglesworth"); + add("horse", "stallion"); + add("do", "verb"); + add("doge", "coin"); + remove("horse"); + remove("do"); + remove("doge"); + remove("doe"); + } +} + +BOOST_AUTO_TEST_CASE(trieLowerBound) +{ + cnote << "Stress-testing Trie.lower_bound..."; + if (0) + { + MemoryDB dm; + EnforceRefs e(dm, true); + GenericTrieDB d(&dm); + d.init(); // initialise as empty tree. + for (int a = 0; a < 20; ++a) + { + StringMap m; + for (int i = 0; i < 50; ++i) + { + auto k = randomWord(); + auto v = toString(i); + m[k] = v; + d.insert(k, v); + } + + for (auto i: d) + { + auto it = d.lower_bound(i.first); + for (auto iit = d.begin(); iit != d.end(); ++iit) + if ((*iit).first.toString() >= i.first.toString()) + { + BOOST_REQUIRE(it == iit); + break; + } + } + for (unsigned i = 0; i < 100; ++i) + { + auto k = randomWord(); + auto it = d.lower_bound(k); + for (auto iit = d.begin(); iit != d.end(); ++iit) + if ((*iit).first.toString() >= k) + { + BOOST_REQUIRE(it == iit); + break; + } + } + + } + } +} + +BOOST_AUTO_TEST_CASE(trieStess) +{ + cnote << "Stress-testing Trie..."; + if (0) + { + MemoryDB m; + MemoryDB dm; + EnforceRefs e(dm, true); + GenericTrieDB d(&dm); + d.init(); // initialise as empty tree. + MemTrie t; + BOOST_REQUIRE(d.check(true)); + for (int a = 0; a < 20; ++a) + { + StringMap m; + for (int i = 0; i < 50; ++i) + { + auto k = randomWord(); + auto v = toString(i); + m[k] = v; + t.insert(k, v); + d.insert(k, v); + BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); + BOOST_REQUIRE_EQUAL(hash256(m), d.root()); + BOOST_REQUIRE(d.check(true)); + } + while (!m.empty()) + { + auto k = m.begin()->first; + auto v = m.begin()->second; + d.remove(k); + t.remove(k); + m.erase(k); + if (!d.check(true)) + { + // cwarn << m; + for (auto i: d) + cwarn << i.first.toString() << i.second.toString(); + + MemoryDB dm2; + EnforceRefs e2(dm2, true); + GenericTrieDB d2(&dm2); + d2.init(); // initialise as empty tree. + for (auto i: d) + d2.insert(i.first, i.second); + + cwarn << "Good:" << d2.root(); +// for (auto i: dm2.get()) +// cwarn << i.first.abridged() << ": " << RLP(i.second); + d2.debugStructure(cerr); + cwarn << "Broken:" << d.root(); // Leaves an extension -> extension (3c1... -> 742...) +// for (auto i: dm.get()) +// cwarn << i.first.abridged() << ": " << RLP(i.second); + d.debugStructure(cerr); + + d2.insert(k, v); + cwarn << "Pres:" << d2.root(); +// for (auto i: dm2.get()) +// cwarn << i.first.abridged() << ": " << RLP(i.second); + d2.debugStructure(cerr); + g_logVerbosity = 99; + d2.remove(k); + g_logVerbosity = 4; + + cwarn << "Good?" << d2.root(); + } + BOOST_REQUIRE(d.check(true)); + BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); + BOOST_REQUIRE_EQUAL(hash256(m), d.root()); + } + } + } +} + +BOOST_AUTO_TEST_SUITE_END() + + diff --git a/test/libethcore/CMakeLists.txt b/test/libethcore/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libethcore/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/commonjs.cpp b/test/libethcore/commonjs.cpp similarity index 100% rename from test/commonjs.cpp rename to test/libethcore/commonjs.cpp diff --git a/test/dagger.cpp b/test/libethcore/dagger.cpp similarity index 97% rename from test/dagger.cpp rename to test/libethcore/dagger.cpp index cb8908d32..119780346 100644 --- a/test/dagger.cpp +++ b/test/libethcore/dagger.cpp @@ -22,12 +22,12 @@ #include #include -#include "JsonSpiritHeaders.h" +#include "../JsonSpiritHeaders.h" #include #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace dev; diff --git a/test/bcInvalidHeaderTestFiller.json b/test/libethereum/BlockTestsFiller/bcInvalidHeaderTestFiller.json similarity index 100% rename from test/bcInvalidHeaderTestFiller.json rename to test/libethereum/BlockTestsFiller/bcInvalidHeaderTestFiller.json diff --git a/test/bcJS_API_TestFiller.json b/test/libethereum/BlockTestsFiller/bcJS_API_TestFiller.json similarity index 100% rename from test/bcJS_API_TestFiller.json rename to test/libethereum/BlockTestsFiller/bcJS_API_TestFiller.json diff --git a/test/bcUncleHeaderValiditiyFiller.json b/test/libethereum/BlockTestsFiller/bcUncleHeaderValiditiyFiller.json similarity index 100% rename from test/bcUncleHeaderValiditiyFiller.json rename to test/libethereum/BlockTestsFiller/bcUncleHeaderValiditiyFiller.json diff --git a/test/bcUncleTestFiller.json b/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json similarity index 100% rename from test/bcUncleTestFiller.json rename to test/libethereum/BlockTestsFiller/bcUncleTestFiller.json diff --git a/test/bcValidBlockTestFiller.json b/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json similarity index 100% rename from test/bcValidBlockTestFiller.json rename to test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json diff --git a/test/libethereum/CMakeLists.txt b/test/libethereum/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libethereum/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/ClientBase.cpp b/test/libethereum/ClientBase.cpp similarity index 99% rename from test/ClientBase.cpp rename to test/libethereum/ClientBase.cpp index 7597b6612..9ee93779e 100644 --- a/test/ClientBase.cpp +++ b/test/libethereum/ClientBase.cpp @@ -21,7 +21,7 @@ #include #include -#include "TestUtils.h" +#include "../TestUtils.h" using namespace std; using namespace dev; diff --git a/test/ManyFunctions.sol b/test/libethereum/StateTestsFiller/ManyFunctions.sol similarity index 100% rename from test/ManyFunctions.sol rename to test/libethereum/StateTestsFiller/ManyFunctions.sol diff --git a/test/ManyFunctionsGenerator.py b/test/libethereum/StateTestsFiller/ManyFunctionsGenerator.py similarity index 100% rename from test/ManyFunctionsGenerator.py rename to test/libethereum/StateTestsFiller/ManyFunctionsGenerator.py diff --git a/test/stBlockHashTestFiller.json b/test/libethereum/StateTestsFiller/stBlockHashTestFiller.json similarity index 100% rename from test/stBlockHashTestFiller.json rename to test/libethereum/StateTestsFiller/stBlockHashTestFiller.json diff --git a/test/stCallCreateCallCodeTestFiller.json b/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json similarity index 100% rename from test/stCallCreateCallCodeTestFiller.json rename to test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json diff --git a/test/stExampleFiller.json b/test/libethereum/StateTestsFiller/stExampleFiller.json similarity index 100% rename from test/stExampleFiller.json rename to test/libethereum/StateTestsFiller/stExampleFiller.json diff --git a/test/stInitCodeTestFiller.json b/test/libethereum/StateTestsFiller/stInitCodeTestFiller.json similarity index 100% rename from test/stInitCodeTestFiller.json rename to test/libethereum/StateTestsFiller/stInitCodeTestFiller.json diff --git a/test/stLogTestsFiller.json b/test/libethereum/StateTestsFiller/stLogTestsFiller.json similarity index 100% rename from test/stLogTestsFiller.json rename to test/libethereum/StateTestsFiller/stLogTestsFiller.json diff --git a/test/stMemoryStressTestFiller.json b/test/libethereum/StateTestsFiller/stMemoryStressTestFiller.json similarity index 100% rename from test/stMemoryStressTestFiller.json rename to test/libethereum/StateTestsFiller/stMemoryStressTestFiller.json diff --git a/test/stMemoryTestFiller.json b/test/libethereum/StateTestsFiller/stMemoryTestFiller.json similarity index 100% rename from test/stMemoryTestFiller.json rename to test/libethereum/StateTestsFiller/stMemoryTestFiller.json diff --git a/test/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json similarity index 100% rename from test/stPreCompiledContractsFiller.json rename to test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json diff --git a/test/stQuadraticComplexityTestFiller.json b/test/libethereum/StateTestsFiller/stQuadraticComplexityTestFiller.json similarity index 100% rename from test/stQuadraticComplexityTestFiller.json rename to test/libethereum/StateTestsFiller/stQuadraticComplexityTestFiller.json diff --git a/test/stRecursiveCreateFiller.json b/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json similarity index 100% rename from test/stRecursiveCreateFiller.json rename to test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json diff --git a/test/stRefundTestFiller.json b/test/libethereum/StateTestsFiller/stRefundTestFiller.json similarity index 100% rename from test/stRefundTestFiller.json rename to test/libethereum/StateTestsFiller/stRefundTestFiller.json diff --git a/test/stSolidityTestFiller.json b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json similarity index 100% rename from test/stSolidityTestFiller.json rename to test/libethereum/StateTestsFiller/stSolidityTestFiller.json diff --git a/test/stSpecialTestFiller.json b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json similarity index 100% rename from test/stSpecialTestFiller.json rename to test/libethereum/StateTestsFiller/stSpecialTestFiller.json diff --git a/test/stSystemOperationsTestFiller.json b/test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json similarity index 100% rename from test/stSystemOperationsTestFiller.json rename to test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json diff --git a/test/stTransactionTestFiller.json b/test/libethereum/StateTestsFiller/stTransactionTestFiller.json similarity index 100% rename from test/stTransactionTestFiller.json rename to test/libethereum/StateTestsFiller/stTransactionTestFiller.json diff --git a/test/tt10mbDataFieldFiller.json b/test/libethereum/TransactionTestsFiller/tt10mbDataFieldFiller.json similarity index 100% rename from test/tt10mbDataFieldFiller.json rename to test/libethereum/TransactionTestsFiller/tt10mbDataFieldFiller.json diff --git a/test/ttTransactionTestFiller.json b/test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json similarity index 100% rename from test/ttTransactionTestFiller.json rename to test/libethereum/TransactionTestsFiller/ttTransactionTestFiller.json diff --git a/test/blockchain.cpp b/test/libethereum/blockchain.cpp similarity index 96% rename from test/blockchain.cpp rename to test/libethereum/blockchain.cpp index ec8fb7539..92f3c8623 100644 --- a/test/blockchain.cpp +++ b/test/libethereum/blockchain.cpp @@ -24,7 +24,7 @@ #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace json_spirit; @@ -655,37 +655,37 @@ BOOST_AUTO_TEST_SUITE(BlockChainTests) BOOST_AUTO_TEST_CASE(bcForkBlockTest) { - dev::test::executeTests("bcForkBlockTest", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcForkBlockTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcInvalidRLPTest) { - dev::test::executeTests("bcInvalidRLPTest", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcInvalidRLPTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcJS_API_Test) { - dev::test::executeTests("bcJS_API_Test", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcJS_API_Test", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcValidBlockTest) { - dev::test::executeTests("bcValidBlockTest", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcValidBlockTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcInvalidHeaderTest) { - dev::test::executeTests("bcInvalidHeaderTest", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcInvalidHeaderTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcUncleTest) { - dev::test::executeTests("bcUncleTest", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcUncleTest", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(bcUncleHeaderValiditiy) { - dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockTests", dev::test::doBlockchainTests); + dev::test::executeTests("bcUncleHeaderValiditiy", "/BlockTests",dev::test::getFolder(__FILE__) + "/BlockTestsFiller", dev::test::doBlockchainTests); } BOOST_AUTO_TEST_CASE(userDefinedFile) diff --git a/test/genesis.cpp b/test/libethereum/genesis.cpp similarity index 97% rename from test/genesis.cpp rename to test/libethereum/genesis.cpp index 5ac3ea2a8..4633a0617 100644 --- a/test/genesis.cpp +++ b/test/libethereum/genesis.cpp @@ -25,10 +25,10 @@ #include -#include "JsonSpiritHeaders.h" +#include "../JsonSpiritHeaders.h" #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace dev; diff --git a/test/state.cpp b/test/libethereum/state.cpp similarity index 77% rename from test/state.cpp rename to test/libethereum/state.cpp index 65f333538..e6811d972 100644 --- a/test/state.cpp +++ b/test/libethereum/state.cpp @@ -23,14 +23,14 @@ #include #include -#include "JsonSpiritHeaders.h" +#include "../JsonSpiritHeaders.h" #include #include #include #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace json_spirit; @@ -106,79 +106,79 @@ BOOST_AUTO_TEST_SUITE(StateTests) BOOST_AUTO_TEST_CASE(stExample) { - dev::test::executeTests("stExample", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stExample", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stSystemOperationsTest) { - dev::test::executeTests("stSystemOperationsTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stSystemOperationsTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stCallCreateCallCodeTest) { - dev::test::executeTests("stCallCreateCallCodeTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stCallCreateCallCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stPreCompiledContracts) { - dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stLogTests) { - dev::test::executeTests("stLogTests", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stRecursiveCreate) { - dev::test::executeTests("stRecursiveCreate", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stRecursiveCreate", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stInitCodeTest) { - dev::test::executeTests("stInitCodeTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stInitCodeTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stTransactionTest) { - dev::test::executeTests("stTransactionTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stTransactionTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stSpecialTest) { - dev::test::executeTests("stSpecialTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stSpecialTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stRefundTest) { - dev::test::executeTests("stRefundTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stRefundTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stBlockHashTest) { - dev::test::executeTests("stBlockHashTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stBlockHashTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest) { if (test::Options::get().quadratic) - dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stQuadraticComplexityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stMemoryStressTest) { if (test::Options::get().memory) - dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stMemoryStressTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stSolidityTest) { - dev::test::executeTests("stSolidityTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stSolidityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } BOOST_AUTO_TEST_CASE(stMemoryTest) { - dev::test::executeTests("stMemoryTest", "/StateTests", dev::test::doStateTests); + dev::test::executeTests("stMemoryTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } diff --git a/test/stateOriginal.cpp b/test/libethereum/stateOriginal.cpp similarity index 98% rename from test/stateOriginal.cpp rename to test/libethereum/stateOriginal.cpp index 7f3371484..82d6288d6 100644 --- a/test/stateOriginal.cpp +++ b/test/libethereum/stateOriginal.cpp @@ -27,7 +27,7 @@ #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace dev; using namespace dev::eth; diff --git a/test/transaction.cpp b/test/libethereum/transaction.cpp similarity index 96% rename from test/transaction.cpp rename to test/libethereum/transaction.cpp index 78a1ac7f7..1a4716725 100644 --- a/test/transaction.cpp +++ b/test/libethereum/transaction.cpp @@ -20,7 +20,7 @@ * Transaaction test functions. */ -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; using namespace json_spirit; @@ -137,12 +137,12 @@ BOOST_AUTO_TEST_SUITE(TransactionTests) BOOST_AUTO_TEST_CASE(ttTransactionTest) { - dev::test::executeTests("ttTransactionTest", "/TransactionTests", dev::test::doTransactionTests); + dev::test::executeTests("ttTransactionTest", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); } BOOST_AUTO_TEST_CASE(ttWrongRLPTransaction) { - dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests", dev::test::doTransactionTests); + dev::test::executeTests("ttWrongRLPTransaction", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); } BOOST_AUTO_TEST_CASE(tt10mbDataField) @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(tt10mbDataField) { auto start = chrono::steady_clock::now(); - dev::test::executeTests("tt10mbDataField", "/TransactionTests", dev::test::doTransactionTests); + dev::test::executeTests("tt10mbDataField", "/TransactionTests",dev::test::getFolder(__FILE__) + "/TransactionTestsFiller", dev::test::doTransactionTests); auto end = chrono::steady_clock::now(); auto duration(chrono::duration_cast(end - start)); diff --git a/test/libevm/CMakeLists.txt b/test/libevm/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libevm/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/PerformaceTester.sol b/test/libevm/VMTestsFiller/performanceTester.sol similarity index 100% rename from test/PerformaceTester.sol rename to test/libevm/VMTestsFiller/performanceTester.sol diff --git a/test/vmArithmeticTestFiller.json b/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json similarity index 100% rename from test/vmArithmeticTestFiller.json rename to test/libevm/VMTestsFiller/vmArithmeticTestFiller.json diff --git a/test/vmBitwiseLogicOperationTestFiller.json b/test/libevm/VMTestsFiller/vmBitwiseLogicOperationTestFiller.json similarity index 100% rename from test/vmBitwiseLogicOperationTestFiller.json rename to test/libevm/VMTestsFiller/vmBitwiseLogicOperationTestFiller.json diff --git a/test/vmBlockInfoTestFiller.json b/test/libevm/VMTestsFiller/vmBlockInfoTestFiller.json similarity index 100% rename from test/vmBlockInfoTestFiller.json rename to test/libevm/VMTestsFiller/vmBlockInfoTestFiller.json diff --git a/test/vmEnvironmentalInfoTestFiller.json b/test/libevm/VMTestsFiller/vmEnvironmentalInfoTestFiller.json similarity index 100% rename from test/vmEnvironmentalInfoTestFiller.json rename to test/libevm/VMTestsFiller/vmEnvironmentalInfoTestFiller.json diff --git a/test/vmIOandFlowOperationsTestFiller.json b/test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json similarity index 100% rename from test/vmIOandFlowOperationsTestFiller.json rename to test/libevm/VMTestsFiller/vmIOandFlowOperationsTestFiller.json diff --git a/test/vmLogTestFiller.json b/test/libevm/VMTestsFiller/vmLogTestFiller.json similarity index 100% rename from test/vmLogTestFiller.json rename to test/libevm/VMTestsFiller/vmLogTestFiller.json diff --git a/test/vmPerformanceTestFiller.json b/test/libevm/VMTestsFiller/vmPerformanceTestFiller.json similarity index 100% rename from test/vmPerformanceTestFiller.json rename to test/libevm/VMTestsFiller/vmPerformanceTestFiller.json diff --git a/test/vmPushDupSwapTestFiller.json b/test/libevm/VMTestsFiller/vmPushDupSwapTestFiller.json similarity index 100% rename from test/vmPushDupSwapTestFiller.json rename to test/libevm/VMTestsFiller/vmPushDupSwapTestFiller.json diff --git a/test/vmSha3TestFiller.json b/test/libevm/VMTestsFiller/vmSha3TestFiller.json similarity index 100% rename from test/vmSha3TestFiller.json rename to test/libevm/VMTestsFiller/vmSha3TestFiller.json diff --git a/test/vmSystemOperationsTestFiller.json b/test/libevm/VMTestsFiller/vmSystemOperationsTestFiller.json similarity index 100% rename from test/vmSystemOperationsTestFiller.json rename to test/libevm/VMTestsFiller/vmSystemOperationsTestFiller.json diff --git a/test/vmtestsFiller.json b/test/libevm/VMTestsFiller/vmtestsFiller.json similarity index 100% rename from test/vmtestsFiller.json rename to test/libevm/VMTestsFiller/vmtestsFiller.json diff --git a/test/vm.cpp b/test/libevm/vm.cpp similarity index 90% rename from test/vm.cpp rename to test/libevm/vm.cpp index 9e21972f1..d0eb532a7 100644 --- a/test/vm.cpp +++ b/test/libevm/vm.cpp @@ -450,76 +450,76 @@ BOOST_AUTO_TEST_SUITE(VMTests) BOOST_AUTO_TEST_CASE(vmtests) { - dev::test::executeTests("vmtests", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmtests", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmArithmeticTest) { - dev::test::executeTests("vmArithmeticTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmArithmeticTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmBitwiseLogicOperationTest) { - dev::test::executeTests("vmBitwiseLogicOperationTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmBitwiseLogicOperationTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmSha3Test) { - dev::test::executeTests("vmSha3Test", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmSha3Test", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmEnvironmentalInfoTest) { - dev::test::executeTests("vmEnvironmentalInfoTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmEnvironmentalInfoTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmBlockInfoTest) { - dev::test::executeTests("vmBlockInfoTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmBlockInfoTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmIOandFlowOperationsTest) { - dev::test::executeTests("vmIOandFlowOperationsTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmIOandFlowOperationsTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmPushDupSwapTest) { - dev::test::executeTests("vmPushDupSwapTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmPushDupSwapTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmLogTest) { - dev::test::executeTests("vmLogTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmLogTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmSystemOperationsTest) { - dev::test::executeTests("vmSystemOperationsTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmSystemOperationsTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmPerformanceTest) { if (test::Options::get().performance) - dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmPerformanceTest", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) { if (test::Options::get().inputLimits) - dev::test::executeTests("vmInputLimits1", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmInputLimits1", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmInputLimitsTest2) { if (test::Options::get().inputLimits) - dev::test::executeTests("vmInputLimits2", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmInputLimits2", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmInputLimitsLightTest) { if (test::Options::get().inputLimits) - dev::test::executeTests("vmInputLimitsLight", "/VMTests", dev::test::doVMTests); + dev::test::executeTests("vmInputLimitsLight", "/VMTests",dev::test::getFolder(__FILE__) + "/VMTestsFiller", dev::test::doVMTests); } BOOST_AUTO_TEST_CASE(vmRandom) diff --git a/test/vm.h b/test/libevm/vm.h similarity index 99% rename from test/vm.h rename to test/libevm/vm.h index 1c0190b69..2bfc68d56 100644 --- a/test/vm.h +++ b/test/libevm/vm.h @@ -38,7 +38,7 @@ along with cpp-ethereum. If not, see . #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" namespace dev { namespace test { diff --git a/test/Assembly.cpp b/test/libevmcore/Assembly.cpp similarity index 100% rename from test/Assembly.cpp rename to test/libevmcore/Assembly.cpp diff --git a/test/libevmcore/CMakeLists.txt b/test/libevmcore/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libevmcore/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/libnatspec/CMakeLists.txt b/test/libnatspec/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libnatspec/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/natspec.cpp b/test/libnatspec/natspec.cpp similarity index 100% rename from test/natspec.cpp rename to test/libnatspec/natspec.cpp diff --git a/test/libp2p/CMakeLists.txt b/test/libp2p/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libp2p/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/libp2p/net.cpp b/test/libp2p/net.cpp new file mode 100644 index 000000000..9a5dbb32f --- /dev/null +++ b/test/libp2p/net.cpp @@ -0,0 +1,372 @@ +/* + 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 . +*/ +/** @file net.cpp + * @author Alex Leverington + * @date 2014 + */ + +#include + +#include +#include +#include +#include +#include +using namespace std; +using namespace dev; +using namespace dev::p2p; +namespace ba = boost::asio; +namespace bi = ba::ip; + +struct NetFixture +{ + NetFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = true; } + ~NetFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = false; } +}; + +BOOST_FIXTURE_TEST_SUITE(net, NetFixture) + +/** + * Only used for testing. Not useful beyond tests. + */ +class TestHost: public Worker +{ +public: + TestHost(): Worker("test",0), m_io() {}; + virtual ~TestHost() { m_io.stop(); stopWorking(); } + void start() { startWorking(); } + void doWork() { m_io.run(); } + void doneWorking() { m_io.reset(); m_io.poll(); m_io.reset(); } + +protected: + ba::io_service m_io; +}; + +struct TestNodeTable: public NodeTable +{ + /// Constructor + TestNodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _addr, uint16_t _port = 30300): NodeTable(_io, _alias, NodeIPEndpoint(_addr, _port, _port)) {} + + static std::vector> createTestNodes(unsigned _count) + { + std::vector> ret; + asserts(_count < 1000); + static uint16_t s_basePort = 30500; + + ret.clear(); + for (unsigned i = 0; i < _count; i++) + { + KeyPair k = KeyPair::create(); + ret.push_back(make_pair(k,s_basePort+i)); + } + + return std::move(ret); + } + + void pingTestNodes(std::vector> const& _testNodes) + { + bi::address ourIp = bi::address::from_string("127.0.0.1"); + for (auto& n: _testNodes) + { + ping(bi::udp::endpoint(ourIp, n.second)); + this_thread::sleep_for(chrono::milliseconds(2)); + } + } + + void populateTestNodes(std::vector> const& _testNodes, size_t _count = 0) + { + if (!_count) + _count = _testNodes.size(); + + bi::address ourIp = bi::address::from_string("127.0.0.1"); + for (auto& n: _testNodes) + if (_count--) + { + // manually add node for test + { + Guard ln(x_nodes); + shared_ptr node(new NodeEntry(m_node, n.first.pub(), NodeIPEndpoint(ourIp, n.second, n.second))); + node->pending = false; + m_nodes[node->id] = node; + } + noteActiveNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); + } + else + break; + } + + void reset() + { + Guard l(x_state); + for (auto& n: m_state) n.nodes.clear(); + } +}; + +/** + * Only used for testing. Not useful beyond tests. + */ +struct TestNodeTableHost: public TestHost +{ + TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias, bi::address::from_string("127.0.0.1"))), testNodes(TestNodeTable::createTestNodes(_count)) {}; + ~TestNodeTableHost() { m_io.stop(); stopWorking(); } + + void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first, bi::address::from_string("127.0.0.1"),n.second)); } + + void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); } + + void populateAll(size_t _count = 0) { for (auto& t: nodeTables) t->populateTestNodes(testNodes, _count); } + + void populate(size_t _count = 0) { nodeTable->populateTestNodes(testNodes, _count); } + + KeyPair m_alias; + shared_ptr nodeTable; + std::vector> testNodes; // keypair and port + std::vector> nodeTables; +}; + +class TestUDPSocket: UDPSocketEvents, public TestHost +{ +public: + TestUDPSocket(): m_socket(new UDPSocket(m_io, *this, 30300)) {} + + void onDisconnected(UDPSocketFace*) {}; + void onReceived(UDPSocketFace*, bi::udp::endpoint const&, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } + + shared_ptr> m_socket; + + bool success = false; +}; + +BOOST_AUTO_TEST_CASE(requestTimeout) +{ + using TimePoint = std::chrono::steady_clock::time_point; + using RequestTimeout = std::pair; + + std::chrono::milliseconds timeout(300); + std::list timeouts; + + NodeId nodeA(sha3("a")); + NodeId nodeB(sha3("b")); + timeouts.push_back(make_pair(nodeA, chrono::steady_clock::now())); + this_thread::sleep_for(std::chrono::milliseconds(100)); + timeouts.push_back(make_pair(nodeB, chrono::steady_clock::now())); + this_thread::sleep_for(std::chrono::milliseconds(210)); + + bool nodeAtriggered = false; + bool nodeBtriggered = false; + timeouts.remove_if([&](RequestTimeout const& t) + { + auto now = chrono::steady_clock::now(); + auto diff = now - t.second; + if (t.first == nodeA && diff < timeout) + nodeAtriggered = true; + if (t.first == nodeB && diff < timeout) + nodeBtriggered = true; + return (t.first == nodeA || t.first == nodeB); + }); + + BOOST_REQUIRE(nodeAtriggered == false); + BOOST_REQUIRE(nodeBtriggered == true); + BOOST_REQUIRE(timeouts.size() == 0); +} + +BOOST_AUTO_TEST_CASE(isIPAddressType) +{ + string wildcard = "0.0.0.0"; + BOOST_REQUIRE(bi::address::from_string(wildcard).is_unspecified()); + + string empty = ""; + BOOST_REQUIRE_THROW(bi::address::from_string(empty).is_unspecified(), std::exception); + + string publicAddress192 = "192.169.0.0"; + BOOST_REQUIRE(isPublicAddress(publicAddress192)); + BOOST_REQUIRE(!isPrivateAddress(publicAddress192)); + BOOST_REQUIRE(!isLocalHostAddress(publicAddress192)); + + string publicAddress172 = "172.32.0.0"; + BOOST_REQUIRE(isPublicAddress(publicAddress172)); + BOOST_REQUIRE(!isPrivateAddress(publicAddress172)); + BOOST_REQUIRE(!isLocalHostAddress(publicAddress172)); + + string privateAddress192 = "192.168.1.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress192)); + BOOST_REQUIRE(!isPublicAddress(privateAddress192)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress192)); + + string privateAddress172 = "172.16.0.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress172)); + BOOST_REQUIRE(!isPublicAddress(privateAddress172)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress172)); + + string privateAddress10 = "10.0.0.0"; + BOOST_REQUIRE(isPrivateAddress(privateAddress10)); + BOOST_REQUIRE(!isPublicAddress(privateAddress10)); + BOOST_REQUIRE(!isLocalHostAddress(privateAddress10)); +} + +BOOST_AUTO_TEST_CASE(v2PingNodePacket) +{ + // test old versino of pingNode packet w/new + RLPStream s; + s.appendList(3); s << "1.1.1.1" << 30303 << std::chrono::duration_cast((std::chrono::system_clock::now() + chrono::seconds(60)).time_since_epoch()).count(); + + PingNode p((bi::udp::endpoint())); + BOOST_REQUIRE_NO_THROW(p = PingNode::fromBytesConstRef(bi::udp::endpoint(), bytesConstRef(&s.out()))); + BOOST_REQUIRE(p.version == 2); +} + +BOOST_AUTO_TEST_CASE(neighboursPacketLength) +{ + KeyPair k = KeyPair::create(); + std::vector> testNodes(TestNodeTable::createTestNodes(16)); + bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); + + // hash(32), signature(65), overhead: packet(2), type(1), nodeList(2), ts(9), + static unsigned const nlimit = (1280 - 111) / 87; + for (unsigned offset = 0; offset < testNodes.size(); offset += nlimit) + { + Neighbours out(to); + + auto limit = nlimit ? std::min(testNodes.size(), (size_t)(offset + nlimit)) : testNodes.size(); + for (auto i = offset; i < limit; i++) + { + Neighbours::Node node; + node.ipAddress = boost::asio::ip::address::from_string("200.200.200.200").to_string(); + node.udpPort = testNodes[i].second; + node.node = testNodes[i].first.pub(); + out.nodes.push_back(node); + } + + out.sign(k.sec()); + BOOST_REQUIRE_LE(out.data.size(), 1280); + } +} + +BOOST_AUTO_TEST_CASE(test_neighbours_packet) +{ + KeyPair k = KeyPair::create(); + std::vector> testNodes(TestNodeTable::createTestNodes(16)); + bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); + + Neighbours out(to); + for (auto n: testNodes) + { + Neighbours::Node node; + node.ipAddress = boost::asio::ip::address::from_string("127.0.0.1").to_string(); + node.udpPort = n.second; + node.node = n.first.pub(); + out.nodes.push_back(node); + } + out.sign(k.sec()); + + bytesConstRef packet(out.data.data(), out.data.size()); + bytesConstRef rlpBytes(packet.cropped(h256::size + Signature::size + 1)); + Neighbours in = Neighbours::fromBytesConstRef(to, rlpBytes); + int count = 0; + for (auto n: in.nodes) + { + BOOST_REQUIRE_EQUAL(testNodes[count].second, n.udpPort); + BOOST_REQUIRE_EQUAL(testNodes[count].first.pub(), n.node); + BOOST_REQUIRE_EQUAL(sha3(testNodes[count].first.pub()), sha3(n.node)); + count++; + } +} + +BOOST_AUTO_TEST_CASE(test_findnode_neighbours) +{ + // Executing findNode should result in a list which is serialized + // into Neighbours packet. Neighbours packet should then be deserialized + // into the same list of nearest nodes. +} + +BOOST_AUTO_TEST_CASE(test_windows_template) +{ + bi::udp::endpoint ep; + PingNode p(ep); +} + +BOOST_AUTO_TEST_CASE(kademlia) +{ + // Not yet a 'real' test. + TestNodeTableHost node(8); + node.start(); + node.nodeTable->discover(); // ideally, joining with empty node table logs warning we can check for + node.setup(); + node.populate(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + node.populateAll(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + auto nodes = node.nodeTable->nodes(); + nodes.sort(); + + node.nodeTable->reset(); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + node.populate(1); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + node.nodeTable->discover(); + this_thread::sleep_for(chrono::milliseconds(2000)); + clog << "NodeTable:\n" << *node.nodeTable.get() << endl; + + BOOST_REQUIRE_EQUAL(node.nodeTable->count(), 8); + + auto netNodes = node.nodeTable->nodes(); + netNodes.sort(); + +} + +BOOST_AUTO_TEST_CASE(test_udp_once) +{ + UDPDatagram d(bi::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300), bytes({65,65,65,65})); + TestUDPSocket a; a.m_socket->connect(); a.start(); + a.m_socket->send(d); + this_thread::sleep_for(chrono::seconds(1)); + BOOST_REQUIRE_EQUAL(true, a.success); +} + +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(netTypes) + +BOOST_AUTO_TEST_CASE(unspecifiedNode) +{ + Node n = UnspecifiedNode; + BOOST_REQUIRE(!n); + + Node node(Public(sha3("0")), NodeIPEndpoint(bi::address(), 0, 0)); + BOOST_REQUIRE(node); + BOOST_REQUIRE(n != node); + + Node nodeEq(Public(sha3("0")), NodeIPEndpoint(bi::address(), 0, 0)); + BOOST_REQUIRE_EQUAL(node, nodeEq); +} + +BOOST_AUTO_TEST_CASE(nodeTableReturnsUnspecifiedNode) +{ + ba::io_service io; + NodeTable t(io, KeyPair::create(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), 30303, 30303)); + if (Node n = t.node(NodeId())) + BOOST_REQUIRE(false); + else + BOOST_REQUIRE(n == UnspecifiedNode); +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/test/peer.cpp b/test/libp2p/peer.cpp similarity index 100% rename from test/peer.cpp rename to test/libp2p/peer.cpp diff --git a/test/rlpx.cpp b/test/libp2p/rlpx.cpp similarity index 100% rename from test/rlpx.cpp rename to test/libp2p/rlpx.cpp diff --git a/test/libsolidity/CMakeLists.txt b/test/libsolidity/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libsolidity/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp similarity index 99% rename from test/SolidityABIJSON.cpp rename to test/libsolidity/SolidityABIJSON.cpp index bbe5fd8c4..b0633cca1 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -21,7 +21,7 @@ */ #if ETH_SOLIDITY -#include "TestHelper.h" +#include "../TestHelper.h" #include #include #include diff --git a/test/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp similarity index 100% rename from test/SolidityCompiler.cpp rename to test/libsolidity/SolidityCompiler.cpp diff --git a/test/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp similarity index 99% rename from test/SolidityEndToEndTest.cpp rename to test/libsolidity/SolidityEndToEndTest.cpp index 3764949d9..c345f5204 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include using namespace std; diff --git a/test/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp similarity index 99% rename from test/SolidityExpressionCompiler.cpp rename to test/libsolidity/SolidityExpressionCompiler.cpp index b748d887d..505cac991 100644 --- a/test/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -31,7 +31,7 @@ #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; diff --git a/test/SolidityInterface.cpp b/test/libsolidity/SolidityInterface.cpp similarity index 99% rename from test/SolidityInterface.cpp rename to test/libsolidity/SolidityInterface.cpp index c836f0fa7..ab6cb9029 100644 --- a/test/SolidityInterface.cpp +++ b/test/libsolidity/SolidityInterface.cpp @@ -22,7 +22,7 @@ #if ETH_SOLIDITY -#include "TestHelper.h" +#include "../TestHelper.h" #include #include diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp similarity index 99% rename from test/SolidityNameAndTypeResolution.cpp rename to test/libsolidity/SolidityNameAndTypeResolution.cpp index c1a274b0c..917ea0007 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -31,7 +31,7 @@ #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; diff --git a/test/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp similarity index 99% rename from test/SolidityNatspecJSON.cpp rename to test/libsolidity/SolidityNatspecJSON.cpp index 28d657357..99adcf199 100644 --- a/test/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -22,7 +22,7 @@ #if ETH_SOLIDITY -#include "TestHelper.h" +#include "../TestHelper.h" #include #include #include diff --git a/test/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp similarity index 99% rename from test/SolidityOptimizer.cpp rename to test/libsolidity/SolidityOptimizer.cpp index f57380acd..8ab1de8f1 100644 --- a/test/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp similarity index 99% rename from test/SolidityParser.cpp rename to test/libsolidity/SolidityParser.cpp index 7cd8efce1..7baa12921 100644 --- a/test/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -28,7 +28,7 @@ #include #include #include -#include "TestHelper.h" +#include "../TestHelper.h" using namespace std; diff --git a/test/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp similarity index 100% rename from test/SolidityScanner.cpp rename to test/libsolidity/SolidityScanner.cpp diff --git a/test/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp similarity index 100% rename from test/SolidityTypes.cpp rename to test/libsolidity/SolidityTypes.cpp diff --git a/test/solidityExecutionFramework.h b/test/libsolidity/solidityExecutionFramework.h similarity index 99% rename from test/solidityExecutionFramework.h rename to test/libsolidity/solidityExecutionFramework.h index 2134d424d..f76465f23 100644 --- a/test/solidityExecutionFramework.h +++ b/test/libsolidity/solidityExecutionFramework.h @@ -24,7 +24,7 @@ #include #include -#include "TestHelper.h" +#include "../TestHelper.h" #include #include #include diff --git a/test/AccountHolder.cpp b/test/libweb3jsonrpc/AccountHolder.cpp similarity index 100% rename from test/AccountHolder.cpp rename to test/libweb3jsonrpc/AccountHolder.cpp diff --git a/test/libweb3jsonrpc/CMakeLists.txt b/test/libweb3jsonrpc/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libweb3jsonrpc/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/jsonrpc.cpp b/test/libweb3jsonrpc/jsonrpc.cpp similarity index 99% rename from test/jsonrpc.cpp rename to test/libweb3jsonrpc/jsonrpc.cpp index eaa9edc45..f3e702653 100644 --- a/test/jsonrpc.cpp +++ b/test/libweb3jsonrpc/jsonrpc.cpp @@ -34,8 +34,8 @@ #include #include #include -#include "JsonSpiritHeaders.h" -#include "TestHelper.h" +#include "../JsonSpiritHeaders.h" +#include "../TestHelper.h" #include "webthreestubclient.h" BOOST_AUTO_TEST_SUITE(jsonrpc) diff --git a/test/libweb3jsonrpc/webthreestubclient.h b/test/libweb3jsonrpc/webthreestubclient.h new file mode 100644 index 000000000..fd71bfb5d --- /dev/null +++ b/test/libweb3jsonrpc/webthreestubclient.h @@ -0,0 +1,596 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ +#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ + +#include + +class WebThreeStubClient : public jsonrpc::Client +{ + public: + WebThreeStubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} + + std::string web3_sha3(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("web3_sha3",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string web3_clientVersion() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("web3_clientVersion",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string net_version() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_version",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string net_peerCount() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_peerCount",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool net_listening() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_listening",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_protocolVersion() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_protocolVersion",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_hashrate() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_hashrate",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_coinbase() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_coinbase",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_mining() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_mining",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_gasPrice() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_gasPrice",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_accounts() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_accounts",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_blockNumber() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_blockNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBalance(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBalance",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_getStorageAt",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionCount",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBlockTransactionCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getBlockTransactionCountByHash",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getUncleCountByBlockHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getUncleCountByBlockHash",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getCode",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_sendTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_sendTransaction",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_call(const Json::Value& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_call",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_flush() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_flush",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getBlockByHash(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBlockByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBlockByNumber",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getTransactionByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionByBlockHashAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionByBlockNumberAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getUncleByBlockHashAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getUncleByBlockNumberAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getCompilers() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getCompilers",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileLLL(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileLLL",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileSerpent(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileSerpent",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileSolidity(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileSolidity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_newFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_newBlockFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_uninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getFilterChanges",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getFilterLogs(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getFilterLogs",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getLogs(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getLogs",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getWork",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_submitWork",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_register",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_unregister(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_unregister",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_fetchQueuedTransactions(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_fetchQueuedTransactions",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("db_put",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("db_get",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_post",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newIdentity() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("shh_newIdentity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_hasIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_hasIdentity",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("shh_newGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("shh_addToGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_newFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_uninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value shh_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_getFilterChanges",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value shh_getMessages(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_getMessages",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } +}; + +#endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ diff --git a/test/libwhisper/CMakeLists.txt b/test/libwhisper/CMakeLists.txt new file mode 100644 index 000000000..3ceda13b0 --- /dev/null +++ b/test/libwhisper/CMakeLists.txt @@ -0,0 +1,5 @@ +cmake_policy(SET CMP0015 NEW) + +aux_source_directory(. SRCS) + +add_sources(${SRCS}) diff --git a/test/whisperTopic.cpp b/test/libwhisper/whisperTopic.cpp similarity index 100% rename from test/whisperTopic.cpp rename to test/libwhisper/whisperTopic.cpp diff --git a/test/randomTestFiller.json b/test/randomTestFiller.json deleted file mode 100644 index 0712cc40f..000000000 --- a/test/randomTestFiller.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "randomVMtest": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "1000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "pre" : { - "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "random", - "storage": {} - } - }, - "exec" : { - "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", - "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", - "value" : "1000000000000000000", - "data" : "", - "gasPrice" : "100000000000000", - "gas" : "10000" - } - } -} From 63010e146af786fb91060f9beafae1ef8815a458 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 20 Apr 2015 23:17:19 +0200 Subject: [PATCH 43/58] fixes --- libdevcrypto/trie.cpp | 553 ---------------------------------------- libp2p/net.cpp | 372 --------------------------- libtestutils/Common.cpp | 4 +- libtestutils/Common.h | 2 +- test/CMakeLists.txt | 36 ++- test/TestHelper.cpp | 2 - 6 files changed, 18 insertions(+), 951 deletions(-) delete mode 100644 libdevcrypto/trie.cpp delete mode 100644 libp2p/net.cpp diff --git a/libdevcrypto/trie.cpp b/libdevcrypto/trie.cpp deleted file mode 100644 index 9e59dd316..000000000 --- a/libdevcrypto/trie.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* - 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 . -*/ -/** @file trie.cpp - * @author Gav Wood - * @date 2014 - * Trie test functions. - */ - -#include -#include - -#include - -#include "JsonSpiritHeaders.h" -#include -#include -#include "TrieHash.h" -#include "MemTrie.h" -#include "TestHelper.h" - -using namespace std; -using namespace dev; - -namespace js = json_spirit; - -namespace dev -{ -namespace test -{ - -static unsigned fac(unsigned _i) -{ - return _i > 2 ? _i * fac(_i - 1) : _i; -} - -} -} - -using dev::operator <<; - -BOOST_AUTO_TEST_SUITE(TrieTests) - -BOOST_AUTO_TEST_CASE(fat_trie) -{ - h256 r; - MemoryDB fm; - { - FatGenericTrieDB ft(&fm); - ft.init(); - ft.insert(h256("69", h256::FromHex, h256::AlignRight).ref(), h256("414243", h256::FromHex, h256::AlignRight).ref()); - for (auto i: ft) - cnote << i.first << i.second; - r = ft.root(); - } - { - FatGenericTrieDB ft(&fm); - ft.setRoot(r); - for (auto i: ft) - cnote << i.first << i.second; - } -} - -BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test) -{ - string testPath = test::getTestPath(); - - testPath += "/TrieTests"; - - cnote << "Testing Secure Trie..."; - js::mValue v; - string s = asString(contents(testPath + "/hex_encoded_securetrie_test.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'hex_encoded_securetrie_test.json' is empty. Have you cloned the 'tests' repo branch develop?"); - js::read_string(s, v); - for (auto& i: v.get_obj()) - { - cnote << i.first; - js::mObject& o = i.second.get_obj(); - vector> ss; - for (auto i: o["in"].get_obj()) - { - ss.push_back(make_pair(i.first, i.second.get_str())); - if (!ss.back().first.find("0x")) - ss.back().first = asString(fromHex(ss.back().first.substr(2))); - if (!ss.back().second.find("0x")) - ss.back().second = asString(fromHex(ss.back().second.substr(2))); - } - for (unsigned j = 0; j < min(1000000000u, dev::test::fac((unsigned)ss.size())); ++j) - { - next_permutation(ss.begin(), ss.end()); - MemoryDB m; - GenericTrieDB t(&m); - MemoryDB hm; - HashedGenericTrieDB ht(&hm); - MemoryDB fm; - FatGenericTrieDB ft(&fm); - t.init(); - ht.init(); - ft.init(); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - for (auto const& k: ss) - { - t.insert(k.first, k.second); - ht.insert(k.first, k.second); - ft.insert(k.first, k.second); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) - { - BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); - BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); - BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); - } - BOOST_CHECK_EQUAL(ht.root(), ft.root()); - } - BOOST_REQUIRE(!o["root"].is_null()); - BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ht.root().asArray())); - BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(ft.root().asArray())); - } - } -} - -BOOST_AUTO_TEST_CASE(trie_test_anyorder) -{ - string testPath = test::getTestPath(); - - testPath += "/TrieTests"; - - cnote << "Testing Trie..."; - js::mValue v; - string s = asString(contents(testPath + "/trieanyorder.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trieanyorder.json' is empty. Have you cloned the 'tests' repo branch develop?"); - js::read_string(s, v); - for (auto& i: v.get_obj()) - { - cnote << i.first; - js::mObject& o = i.second.get_obj(); - vector> ss; - for (auto i: o["in"].get_obj()) - { - ss.push_back(make_pair(i.first, i.second.get_str())); - if (!ss.back().first.find("0x")) - ss.back().first = asString(fromHex(ss.back().first.substr(2))); - if (!ss.back().second.find("0x")) - ss.back().second = asString(fromHex(ss.back().second.substr(2))); - } - for (unsigned j = 0; j < min(1000u, dev::test::fac((unsigned)ss.size())); ++j) - { - next_permutation(ss.begin(), ss.end()); - MemoryDB m; - GenericTrieDB t(&m); - MemoryDB hm; - HashedGenericTrieDB ht(&hm); - MemoryDB fm; - FatGenericTrieDB ft(&fm); - t.init(); - ht.init(); - ft.init(); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - for (auto const& k: ss) - { - t.insert(k.first, k.second); - ht.insert(k.first, k.second); - ft.insert(k.first, k.second); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) - { - BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); - BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); - BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); - } - BOOST_CHECK_EQUAL(ht.root(), ft.root()); - } - BOOST_REQUIRE(!o["root"].is_null()); - BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); - BOOST_CHECK_EQUAL(ht.root(), ft.root()); - } - } -} - -BOOST_AUTO_TEST_CASE(trie_tests_ordered) -{ - string testPath = test::getTestPath(); - - testPath += "/TrieTests"; - - cnote << "Testing Trie..."; - js::mValue v; - string s = asString(contents(testPath + "/trietest.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of 'trietest.json' is empty. Have you cloned the 'tests' repo branch develop?"); - js::read_string(s, v); - - for (auto& i: v.get_obj()) - { - cnote << i.first; - js::mObject& o = i.second.get_obj(); - vector> ss; - vector keysToBeDeleted; - for (auto& i: o["in"].get_array()) - { - vector values; - for (auto& s: i.get_array()) - { - if (s.type() == json_spirit::str_type) - values.push_back(s.get_str()); - else if (s.type() == json_spirit::null_type) - { - // mark entry for deletion - values.push_back(""); - if (!values[0].find("0x")) - values[0] = asString(fromHex(values[0].substr(2))); - keysToBeDeleted.push_back(values[0]); - } - else - BOOST_FAIL("Bad type (expected string)"); - } - - BOOST_REQUIRE(values.size() == 2); - ss.push_back(make_pair(values[0], values[1])); - if (!ss.back().first.find("0x")) - ss.back().first = asString(fromHex(ss.back().first.substr(2))); - if (!ss.back().second.find("0x")) - ss.back().second = asString(fromHex(ss.back().second.substr(2))); - } - - MemoryDB m; - GenericTrieDB t(&m); - MemoryDB hm; - HashedGenericTrieDB ht(&hm); - MemoryDB fm; - FatGenericTrieDB ft(&fm); - t.init(); - ht.init(); - ft.init(); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - - for (auto const& k: ss) - { - if (find(keysToBeDeleted.begin(), keysToBeDeleted.end(), k.first) != keysToBeDeleted.end() && k.second.empty()) - t.remove(k.first), ht.remove(k.first), ft.remove(k.first); - else - t.insert(k.first, k.second), ht.insert(k.first, k.second), ft.insert(k.first, k.second); - BOOST_REQUIRE(t.check(true)); - BOOST_REQUIRE(ht.check(true)); - BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) - { - BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); - BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); - BOOST_REQUIRE((*i).second.toBytes() == (*j).second.toBytes()); - } - BOOST_CHECK_EQUAL(ht.root(), ft.root()); - } - - BOOST_REQUIRE(!o["root"].is_null()); - BOOST_CHECK_EQUAL(o["root"].get_str(), "0x" + toHex(t.root().asArray())); - } -} - -inline h256 stringMapHash256(StringMap const& _s) -{ - return hash256(_s); -} - -BOOST_AUTO_TEST_CASE(moreTrieTests) -{ - cnote << "Testing Trie more..."; -#if 0 - // More tests... - { - MemoryDB m; - GenericTrieDB t(&m); - t.init(); // initialise as empty tree. - cout << t; - cout << m; - cout << t.root() << endl; - cout << hash256(StringMap()) << endl; - - t.insert(string("tesz"), string("test")); - cout << t; - cout << m; - cout << t.root() << endl; - cout << stringMapHash256({{"test", "test"}}) << endl; - - t.insert(string("tesa"), string("testy")); - cout << t; - cout << m; - cout << t.root() << endl; - cout << stringMapHash256({{"test", "test"}, {"te", "testy"}}) << endl; - cout << t.at(string("test")) << endl; - cout << t.at(string("te")) << endl; - cout << t.at(string("t")) << endl; - - t.remove(string("te")); - cout << m; - cout << t.root() << endl; - cout << stringMapHash256({{"test", "test"}}) << endl; - - t.remove(string("test")); - cout << m; - cout << t.root() << endl; - cout << hash256(StringMap()) << endl; - } - { - MemoryDB m; - GenericTrieDB t(&m); - t.init(); // initialise as empty tree. - t.insert(string("a"), string("A")); - t.insert(string("b"), string("B")); - cout << t; - cout << m; - cout << t.root() << endl; - cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl; - cout << RLP(rlp256({{"b", "B"}, {"a", "A"}})) << endl; - } - { - MemTrie t; - t.insert("dog", "puppy"); - cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; - } - { - MemTrie t; - t.insert("bed", "d"); - t.insert("be", "e"); - cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; - } - { - cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl; - MemTrie t; - t.insert("dog", "puppy"); - t.insert("doe", "reindeer"); - cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; - cout << toHex(t.rlp()) << endl; - } -#endif - { - MemoryDB m; - GenericTrieDB d(&m); - d.init(); // initialise as empty tree. - MemTrie t; - StringMap s; - - auto add = [&](char const* a, char const* b) - { - d.insert(string(a), string(b)); - t.insert(a, b); - s[a] = b; - - /*cout << endl << "-------------------------------" << endl; - cout << a << " -> " << b << endl; - cout << d; - cout << m; - cout << d.root() << endl; - cout << hash256(s) << endl;*/ - - BOOST_REQUIRE(d.check(true)); - BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); - BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); - for (auto const& i: s) - { - (void)i; - BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); - BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); - } - }; - - auto remove = [&](char const* a) - { - s.erase(a); - t.remove(a); - d.remove(string(a)); - - /*cout << endl << "-------------------------------" << endl; - cout << "X " << a << endl; - cout << d; - cout << m; - cout << d.root() << endl; - cout << hash256(s) << endl;*/ - - BOOST_REQUIRE(d.check(true)); - BOOST_REQUIRE(t.at(a).empty()); - BOOST_REQUIRE(d.at(string(a)).empty()); - BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); - BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); - for (auto const& i: s) - { - (void)i; - BOOST_REQUIRE_EQUAL(t.at(i.first), i.second); - BOOST_REQUIRE_EQUAL(d.at(i.first), i.second); - } - }; - - add("dogglesworth", "cat"); - add("doe", "reindeer"); - remove("dogglesworth"); - add("horse", "stallion"); - add("do", "verb"); - add("doge", "coin"); - remove("horse"); - remove("do"); - remove("doge"); - remove("doe"); - } -} - -BOOST_AUTO_TEST_CASE(trieLowerBound) -{ - cnote << "Stress-testing Trie.lower_bound..."; - if (0) - { - MemoryDB dm; - EnforceRefs e(dm, true); - GenericTrieDB d(&dm); - d.init(); // initialise as empty tree. - for (int a = 0; a < 20; ++a) - { - StringMap m; - for (int i = 0; i < 50; ++i) - { - auto k = randomWord(); - auto v = toString(i); - m[k] = v; - d.insert(k, v); - } - - for (auto i: d) - { - auto it = d.lower_bound(i.first); - for (auto iit = d.begin(); iit != d.end(); ++iit) - if ((*iit).first.toString() >= i.first.toString()) - { - BOOST_REQUIRE(it == iit); - break; - } - } - for (unsigned i = 0; i < 100; ++i) - { - auto k = randomWord(); - auto it = d.lower_bound(k); - for (auto iit = d.begin(); iit != d.end(); ++iit) - if ((*iit).first.toString() >= k) - { - BOOST_REQUIRE(it == iit); - break; - } - } - - } - } -} - -BOOST_AUTO_TEST_CASE(trieStess) -{ - cnote << "Stress-testing Trie..."; - if (0) - { - MemoryDB m; - MemoryDB dm; - EnforceRefs e(dm, true); - GenericTrieDB d(&dm); - d.init(); // initialise as empty tree. - MemTrie t; - BOOST_REQUIRE(d.check(true)); - for (int a = 0; a < 20; ++a) - { - StringMap m; - for (int i = 0; i < 50; ++i) - { - auto k = randomWord(); - auto v = toString(i); - m[k] = v; - t.insert(k, v); - d.insert(k, v); - BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); - BOOST_REQUIRE_EQUAL(hash256(m), d.root()); - BOOST_REQUIRE(d.check(true)); - } - while (!m.empty()) - { - auto k = m.begin()->first; - auto v = m.begin()->second; - d.remove(k); - t.remove(k); - m.erase(k); - if (!d.check(true)) - { - // cwarn << m; - for (auto i: d) - cwarn << i.first.toString() << i.second.toString(); - - MemoryDB dm2; - EnforceRefs e2(dm2, true); - GenericTrieDB d2(&dm2); - d2.init(); // initialise as empty tree. - for (auto i: d) - d2.insert(i.first, i.second); - - cwarn << "Good:" << d2.root(); -// for (auto i: dm2.get()) -// cwarn << i.first.abridged() << ": " << RLP(i.second); - d2.debugStructure(cerr); - cwarn << "Broken:" << d.root(); // Leaves an extension -> extension (3c1... -> 742...) -// for (auto i: dm.get()) -// cwarn << i.first.abridged() << ": " << RLP(i.second); - d.debugStructure(cerr); - - d2.insert(k, v); - cwarn << "Pres:" << d2.root(); -// for (auto i: dm2.get()) -// cwarn << i.first.abridged() << ": " << RLP(i.second); - d2.debugStructure(cerr); - g_logVerbosity = 99; - d2.remove(k); - g_logVerbosity = 4; - - cwarn << "Good?" << d2.root(); - } - BOOST_REQUIRE(d.check(true)); - BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); - BOOST_REQUIRE_EQUAL(hash256(m), d.root()); - } - } - } -} - -BOOST_AUTO_TEST_SUITE_END() - - diff --git a/libp2p/net.cpp b/libp2p/net.cpp deleted file mode 100644 index 9a5dbb32f..000000000 --- a/libp2p/net.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/* - 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 . -*/ -/** @file net.cpp - * @author Alex Leverington - * @date 2014 - */ - -#include - -#include -#include -#include -#include -#include -using namespace std; -using namespace dev; -using namespace dev::p2p; -namespace ba = boost::asio; -namespace bi = ba::ip; - -struct NetFixture -{ - NetFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = true; } - ~NetFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = false; } -}; - -BOOST_FIXTURE_TEST_SUITE(net, NetFixture) - -/** - * Only used for testing. Not useful beyond tests. - */ -class TestHost: public Worker -{ -public: - TestHost(): Worker("test",0), m_io() {}; - virtual ~TestHost() { m_io.stop(); stopWorking(); } - void start() { startWorking(); } - void doWork() { m_io.run(); } - void doneWorking() { m_io.reset(); m_io.poll(); m_io.reset(); } - -protected: - ba::io_service m_io; -}; - -struct TestNodeTable: public NodeTable -{ - /// Constructor - TestNodeTable(ba::io_service& _io, KeyPair _alias, bi::address const& _addr, uint16_t _port = 30300): NodeTable(_io, _alias, NodeIPEndpoint(_addr, _port, _port)) {} - - static std::vector> createTestNodes(unsigned _count) - { - std::vector> ret; - asserts(_count < 1000); - static uint16_t s_basePort = 30500; - - ret.clear(); - for (unsigned i = 0; i < _count; i++) - { - KeyPair k = KeyPair::create(); - ret.push_back(make_pair(k,s_basePort+i)); - } - - return std::move(ret); - } - - void pingTestNodes(std::vector> const& _testNodes) - { - bi::address ourIp = bi::address::from_string("127.0.0.1"); - for (auto& n: _testNodes) - { - ping(bi::udp::endpoint(ourIp, n.second)); - this_thread::sleep_for(chrono::milliseconds(2)); - } - } - - void populateTestNodes(std::vector> const& _testNodes, size_t _count = 0) - { - if (!_count) - _count = _testNodes.size(); - - bi::address ourIp = bi::address::from_string("127.0.0.1"); - for (auto& n: _testNodes) - if (_count--) - { - // manually add node for test - { - Guard ln(x_nodes); - shared_ptr node(new NodeEntry(m_node, n.first.pub(), NodeIPEndpoint(ourIp, n.second, n.second))); - node->pending = false; - m_nodes[node->id] = node; - } - noteActiveNode(n.first.pub(), bi::udp::endpoint(ourIp, n.second)); - } - else - break; - } - - void reset() - { - Guard l(x_state); - for (auto& n: m_state) n.nodes.clear(); - } -}; - -/** - * Only used for testing. Not useful beyond tests. - */ -struct TestNodeTableHost: public TestHost -{ - TestNodeTableHost(unsigned _count = 8): m_alias(KeyPair::create()), nodeTable(new TestNodeTable(m_io, m_alias, bi::address::from_string("127.0.0.1"))), testNodes(TestNodeTable::createTestNodes(_count)) {}; - ~TestNodeTableHost() { m_io.stop(); stopWorking(); } - - void setup() { for (auto n: testNodes) nodeTables.push_back(make_shared(m_io,n.first, bi::address::from_string("127.0.0.1"),n.second)); } - - void pingAll() { for (auto& t: nodeTables) t->pingTestNodes(testNodes); } - - void populateAll(size_t _count = 0) { for (auto& t: nodeTables) t->populateTestNodes(testNodes, _count); } - - void populate(size_t _count = 0) { nodeTable->populateTestNodes(testNodes, _count); } - - KeyPair m_alias; - shared_ptr nodeTable; - std::vector> testNodes; // keypair and port - std::vector> nodeTables; -}; - -class TestUDPSocket: UDPSocketEvents, public TestHost -{ -public: - TestUDPSocket(): m_socket(new UDPSocket(m_io, *this, 30300)) {} - - void onDisconnected(UDPSocketFace*) {}; - void onReceived(UDPSocketFace*, bi::udp::endpoint const&, bytesConstRef _packet) { if (_packet.toString() == "AAAA") success = true; } - - shared_ptr> m_socket; - - bool success = false; -}; - -BOOST_AUTO_TEST_CASE(requestTimeout) -{ - using TimePoint = std::chrono::steady_clock::time_point; - using RequestTimeout = std::pair; - - std::chrono::milliseconds timeout(300); - std::list timeouts; - - NodeId nodeA(sha3("a")); - NodeId nodeB(sha3("b")); - timeouts.push_back(make_pair(nodeA, chrono::steady_clock::now())); - this_thread::sleep_for(std::chrono::milliseconds(100)); - timeouts.push_back(make_pair(nodeB, chrono::steady_clock::now())); - this_thread::sleep_for(std::chrono::milliseconds(210)); - - bool nodeAtriggered = false; - bool nodeBtriggered = false; - timeouts.remove_if([&](RequestTimeout const& t) - { - auto now = chrono::steady_clock::now(); - auto diff = now - t.second; - if (t.first == nodeA && diff < timeout) - nodeAtriggered = true; - if (t.first == nodeB && diff < timeout) - nodeBtriggered = true; - return (t.first == nodeA || t.first == nodeB); - }); - - BOOST_REQUIRE(nodeAtriggered == false); - BOOST_REQUIRE(nodeBtriggered == true); - BOOST_REQUIRE(timeouts.size() == 0); -} - -BOOST_AUTO_TEST_CASE(isIPAddressType) -{ - string wildcard = "0.0.0.0"; - BOOST_REQUIRE(bi::address::from_string(wildcard).is_unspecified()); - - string empty = ""; - BOOST_REQUIRE_THROW(bi::address::from_string(empty).is_unspecified(), std::exception); - - string publicAddress192 = "192.169.0.0"; - BOOST_REQUIRE(isPublicAddress(publicAddress192)); - BOOST_REQUIRE(!isPrivateAddress(publicAddress192)); - BOOST_REQUIRE(!isLocalHostAddress(publicAddress192)); - - string publicAddress172 = "172.32.0.0"; - BOOST_REQUIRE(isPublicAddress(publicAddress172)); - BOOST_REQUIRE(!isPrivateAddress(publicAddress172)); - BOOST_REQUIRE(!isLocalHostAddress(publicAddress172)); - - string privateAddress192 = "192.168.1.0"; - BOOST_REQUIRE(isPrivateAddress(privateAddress192)); - BOOST_REQUIRE(!isPublicAddress(privateAddress192)); - BOOST_REQUIRE(!isLocalHostAddress(privateAddress192)); - - string privateAddress172 = "172.16.0.0"; - BOOST_REQUIRE(isPrivateAddress(privateAddress172)); - BOOST_REQUIRE(!isPublicAddress(privateAddress172)); - BOOST_REQUIRE(!isLocalHostAddress(privateAddress172)); - - string privateAddress10 = "10.0.0.0"; - BOOST_REQUIRE(isPrivateAddress(privateAddress10)); - BOOST_REQUIRE(!isPublicAddress(privateAddress10)); - BOOST_REQUIRE(!isLocalHostAddress(privateAddress10)); -} - -BOOST_AUTO_TEST_CASE(v2PingNodePacket) -{ - // test old versino of pingNode packet w/new - RLPStream s; - s.appendList(3); s << "1.1.1.1" << 30303 << std::chrono::duration_cast((std::chrono::system_clock::now() + chrono::seconds(60)).time_since_epoch()).count(); - - PingNode p((bi::udp::endpoint())); - BOOST_REQUIRE_NO_THROW(p = PingNode::fromBytesConstRef(bi::udp::endpoint(), bytesConstRef(&s.out()))); - BOOST_REQUIRE(p.version == 2); -} - -BOOST_AUTO_TEST_CASE(neighboursPacketLength) -{ - KeyPair k = KeyPair::create(); - std::vector> testNodes(TestNodeTable::createTestNodes(16)); - bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); - - // hash(32), signature(65), overhead: packet(2), type(1), nodeList(2), ts(9), - static unsigned const nlimit = (1280 - 111) / 87; - for (unsigned offset = 0; offset < testNodes.size(); offset += nlimit) - { - Neighbours out(to); - - auto limit = nlimit ? std::min(testNodes.size(), (size_t)(offset + nlimit)) : testNodes.size(); - for (auto i = offset; i < limit; i++) - { - Neighbours::Node node; - node.ipAddress = boost::asio::ip::address::from_string("200.200.200.200").to_string(); - node.udpPort = testNodes[i].second; - node.node = testNodes[i].first.pub(); - out.nodes.push_back(node); - } - - out.sign(k.sec()); - BOOST_REQUIRE_LE(out.data.size(), 1280); - } -} - -BOOST_AUTO_TEST_CASE(test_neighbours_packet) -{ - KeyPair k = KeyPair::create(); - std::vector> testNodes(TestNodeTable::createTestNodes(16)); - bi::udp::endpoint to(boost::asio::ip::address::from_string("127.0.0.1"), 30000); - - Neighbours out(to); - for (auto n: testNodes) - { - Neighbours::Node node; - node.ipAddress = boost::asio::ip::address::from_string("127.0.0.1").to_string(); - node.udpPort = n.second; - node.node = n.first.pub(); - out.nodes.push_back(node); - } - out.sign(k.sec()); - - bytesConstRef packet(out.data.data(), out.data.size()); - bytesConstRef rlpBytes(packet.cropped(h256::size + Signature::size + 1)); - Neighbours in = Neighbours::fromBytesConstRef(to, rlpBytes); - int count = 0; - for (auto n: in.nodes) - { - BOOST_REQUIRE_EQUAL(testNodes[count].second, n.udpPort); - BOOST_REQUIRE_EQUAL(testNodes[count].first.pub(), n.node); - BOOST_REQUIRE_EQUAL(sha3(testNodes[count].first.pub()), sha3(n.node)); - count++; - } -} - -BOOST_AUTO_TEST_CASE(test_findnode_neighbours) -{ - // Executing findNode should result in a list which is serialized - // into Neighbours packet. Neighbours packet should then be deserialized - // into the same list of nearest nodes. -} - -BOOST_AUTO_TEST_CASE(test_windows_template) -{ - bi::udp::endpoint ep; - PingNode p(ep); -} - -BOOST_AUTO_TEST_CASE(kademlia) -{ - // Not yet a 'real' test. - TestNodeTableHost node(8); - node.start(); - node.nodeTable->discover(); // ideally, joining with empty node table logs warning we can check for - node.setup(); - node.populate(); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - - node.populateAll(); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - - auto nodes = node.nodeTable->nodes(); - nodes.sort(); - - node.nodeTable->reset(); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - - node.populate(1); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - - node.nodeTable->discover(); - this_thread::sleep_for(chrono::milliseconds(2000)); - clog << "NodeTable:\n" << *node.nodeTable.get() << endl; - - BOOST_REQUIRE_EQUAL(node.nodeTable->count(), 8); - - auto netNodes = node.nodeTable->nodes(); - netNodes.sort(); - -} - -BOOST_AUTO_TEST_CASE(test_udp_once) -{ - UDPDatagram d(bi::udp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 30300), bytes({65,65,65,65})); - TestUDPSocket a; a.m_socket->connect(); a.start(); - a.m_socket->send(d); - this_thread::sleep_for(chrono::seconds(1)); - BOOST_REQUIRE_EQUAL(true, a.success); -} - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_AUTO_TEST_SUITE(netTypes) - -BOOST_AUTO_TEST_CASE(unspecifiedNode) -{ - Node n = UnspecifiedNode; - BOOST_REQUIRE(!n); - - Node node(Public(sha3("0")), NodeIPEndpoint(bi::address(), 0, 0)); - BOOST_REQUIRE(node); - BOOST_REQUIRE(n != node); - - Node nodeEq(Public(sha3("0")), NodeIPEndpoint(bi::address(), 0, 0)); - BOOST_REQUIRE_EQUAL(node, nodeEq); -} - -BOOST_AUTO_TEST_CASE(nodeTableReturnsUnspecifiedNode) -{ - ba::io_service io; - NodeTable t(io, KeyPair::create(), NodeIPEndpoint(bi::address::from_string("127.0.0.1"), 30303, 30303)); - if (Node n = t.node(NodeId())) - BOOST_REQUIRE(false); - else - BOOST_REQUIRE(n == UnspecifiedNode); -} - -BOOST_AUTO_TEST_SUITE_END() - diff --git a/libtestutils/Common.cpp b/libtestutils/Common.cpp index 6bc9d2c15..284598220 100644 --- a/libtestutils/Common.cpp +++ b/libtestutils/Common.cpp @@ -72,9 +72,9 @@ std::string dev::test::toTestFilePath(std::string const& _filename) return getTestPath() + "/" + _filename + ".json"; } -std::string dev::test::getFolder(std::string const& _line) +std::string dev::test::getFolder(std::string const& _file) { - return boost::filesystem::path(_line).parent_path().string(); + return boost::filesystem::path(_file).parent_path().string(); } std::string dev::test::getRandomPath() diff --git a/libtestutils/Common.h b/libtestutils/Common.h index 33acd36f1..e7a01531f 100644 --- a/libtestutils/Common.h +++ b/libtestutils/Common.h @@ -37,7 +37,7 @@ std::string getTestPath(); int randomNumber(); Json::Value loadJsonFromFile(std::string const& _path); std::string toTestFilePath(std::string const& _filename); -std::string getFolder(std::string const& _line); +std::string getFolder(std::string const& _file); std::string getRandomPath(); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bbb351232..b46ab06e5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,8 +17,6 @@ macro (add_sources) endif() endmacro() -#add_sources(boostTest.cpp) - add_subdirectory(fuzzTesting) add_subdirectory(libdevcore) add_subdirectory(libdevcrypto) @@ -32,14 +30,10 @@ add_subdirectory(libsolidity) add_subdirectory(libweb3jsonrpc) add_subdirectory(libwhisper) -message(STATUS "${SRC}") -message("AHA") - set(SRC_LIST ${SRC_LIST} ${SRC}) -message(STATUS "${SRC_LIST}") if (NOT JSONRPC) - list(REMOVE_ITEM SRC_LIST "./AccountHolder.cpp") + list(REMOVE_ITEM SRC_LIST "libweb3jsonrpc/./AccountHolder.cpp") endif() include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) @@ -49,20 +43,20 @@ include_directories(${CRYPTOPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) # search for test names and create ctest tests -#enable_testing() -#foreach(file ${SRC_LIST}) -# file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE)") -# set(TestSuite "DEFAULT") -# foreach(test_raw ${test_list_raw}) -# string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) -# if(test MATCHES "^SUITE .*") -# string(SUBSTRING ${test} 6 -1 TestSuite) -# elseif(test MATCHES "^CASE .*") -# string(SUBSTRING ${test} 5 -1 TestCase) -# add_test(NAME ${TestSuite}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth -t ${TestSuite}/${TestCase}) -# endif(test MATCHES "^SUITE .*") -# endforeach(test_raw) -#endforeach(file) +enable_testing() +foreach(file ${SRC_LIST}) + file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${file} test_list_raw REGEX "BOOST_.*TEST_(SUITE|CASE)") + set(TestSuite "DEFAULT") + foreach(test_raw ${test_list_raw}) + string(REGEX REPLACE ".*TEST_(SUITE|CASE)\\(([^ ,\\)]*).*" "\\1 \\2" test ${test_raw}) + if(test MATCHES "^SUITE .*") + string(SUBSTRING ${test} 6 -1 TestSuite) + elseif(test MATCHES "^CASE .*") + string(SUBSTRING ${test} 5 -1 TestCase) + add_test(NAME ${TestSuite}/${TestCase} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth -t ${TestSuite}/${TestCase}) + endif(test MATCHES "^SUITE .*") + endforeach(test_raw) +endforeach(file) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 3d0856829..1419afde5 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -602,10 +602,8 @@ void executeTests(const string& _name, const string& _testPathAppendix, const bo try { cnote << "Populating tests..."; - cout << "boost::filesystem::current_path(): " << boost::filesystem::current_path().string() << endl; json_spirit::mValue v; boost::filesystem::path p(__FILE__); - boost::filesystem::path dir = p.parent_path(); string s = asString(dev::contents(_pathToFiller.string() + "/" + _name + "Filler.json")); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + _pathToFiller.string() + "/" + _name + "Filler.json is empty."); json_spirit::read_string(s, v); From a8e4f115ab6084c2815fe687b5e18b0b50f203a6 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Mon, 20 Apr 2015 23:21:50 +0200 Subject: [PATCH 44/58] properly mv webthreestubclient.h --- test/webthreestubclient.h | 596 -------------------------------------- 1 file changed, 596 deletions(-) delete mode 100644 test/webthreestubclient.h diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h deleted file mode 100644 index fd71bfb5d..000000000 --- a/test/webthreestubclient.h +++ /dev/null @@ -1,596 +0,0 @@ -/** - * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! - */ - -#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ -#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ - -#include - -class WebThreeStubClient : public jsonrpc::Client -{ - public: - WebThreeStubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} - - std::string web3_sha3(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("web3_sha3",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string web3_clientVersion() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("web3_clientVersion",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string net_version() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_version",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string net_peerCount() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_peerCount",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool net_listening() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_listening",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_protocolVersion() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_protocolVersion",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_hashrate() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_hashrate",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_coinbase() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_coinbase",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_mining() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_mining",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_gasPrice() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_gasPrice",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_accounts() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_accounts",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_blockNumber() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_blockNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBalance(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBalance",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("eth_getStorageAt",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionCount",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBlockTransactionCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getBlockTransactionCountByHash",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getUncleCountByBlockHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getUncleCountByBlockHash",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getCode",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_sendTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_sendTransaction",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_call(const Json::Value& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_call",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_flush() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_flush",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getBlockByHash(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBlockByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBlockByNumber",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getTransactionByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionByBlockHashAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionByBlockNumberAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getUncleByBlockHashAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getUncleByBlockNumberAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getCompilers() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_getCompilers",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileLLL(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileLLL",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileSerpent(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileSerpent",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileSolidity(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileSolidity",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_newFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_newBlockFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_uninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getFilterChanges",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getFilterLogs(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getFilterLogs",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getLogs(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getLogs",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_getWork",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("eth_submitWork",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_register",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_unregister(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_unregister",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_fetchQueuedTransactions(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_fetchQueuedTransactions",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("db_put",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("db_get",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_post",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newIdentity() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("shh_newIdentity",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_hasIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_hasIdentity",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("shh_newGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("shh_addToGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_newFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_uninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value shh_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_getFilterChanges",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value shh_getMessages(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_getMessages",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } -}; - -#endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ From 6aff7a03b1cc7106e1cae74fb30f3eaa16dbb869 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 20 Apr 2015 23:32:42 +0200 Subject: [PATCH 45/58] More colourful logging. --- alethzero/MainWin.cpp | 7 ++- eth/main.cpp | 66 +++++++++++++++++++++++ libdevcore/Log.cpp | 25 +++++++++ libdevcore/Log.h | 40 ++++++-------- libdevcore/Terminal.h | 110 ++++++++++++++++++-------------------- libethereum/Executive.cpp | 4 +- libp2p/Session.cpp | 9 ++-- test/vm.cpp | 4 +- 8 files changed, 177 insertions(+), 88 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 64fca6a05..eb2431f10 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -116,6 +116,11 @@ QString contentsOfQResource(string const& res) Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b"); //Address c_nameReg = Address("ddd1cea741d548f90d86fb87a3ae6492e18c03a1"); +static QString filterOutTerminal(QString _s) +{ + return _s.replace(QRegExp("\x1b\\[(\\d;)?\\d+m"), ""); +} + Main::Main(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main), @@ -130,7 +135,7 @@ Main::Main(QWidget *parent) : { simpleDebugOut(s, c); m_logLock.lock(); - m_logHistory.append(QString::fromStdString(s) + "\n"); + m_logHistory.append(filterOutTerminal(QString::fromStdString(s)) + "\n"); m_logChanged = true; m_logLock.unlock(); // ui->log->addItem(QString::fromStdString(s)); diff --git a/eth/main.cpp b/eth/main.cpp index 0344e66d6..4ce42e47e 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -405,6 +405,72 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) int main(int argc, char** argv) { + cout << "\x1b[30mEthBlack\x1b[0m" << endl; + cout << "\x1b[90mEthCoal\x1b[0m" << endl; + cout << "\x1b[37mEthGray\x1b[0m" << endl; + cout << "\x1b[97mEthWhite\x1b[0m" << endl; + cout << "\x1b[31mEthRed\x1b[0m" << endl; + cout << "\x1b[32mEthGreen\x1b[0m" << endl; + cout << "\x1b[33mEthYellow\x1b[0m" << endl; + cout << "\x1b[34mEthBlue\x1b[0m" << endl; + cout << "\x1b[35mEthPurple\x1b[0m" << endl; + cout << "\x1b[36mEthCyan\x1b[0m" << endl; + // High Intensity + cout << "\x1b[91mEthRedI\x1b[0m" << endl; + cout << "\x1b[92mEthLime\x1b[0m" << endl; + cout << "\x1b[93mEthYellowI\x1b[0m" << endl; + cout << "\x1b[94mEthBlueI\x1b[0m" << endl; + cout << "\x1b[95mEthPurpleI\x1b[0m" << endl; + cout << "\x1b[96mEthCyanI\x1b[0m" << endl; + + // Bold + cout << "\x1b[1;30mEthBlackB\x1b[0m" << endl; + cout << "\x1b[1;90mEthCoalB\x1b[0m" << endl; + cout << "\x1b[1;37mEthGrayB\x1b[0m" << endl; + cout << "\x1b[1;97mEthWhiteB\x1b[0m" << endl; + cout << "\x1b[1;31mEthRedB\x1b[0m" << endl; + cout << "\x1b[1;32mEthGreenB\x1b[0m" << endl; + cout << "\x1b[1;33mEthYellowB\x1b[0m" << endl; + cout << "\x1b[1;34mEthBlueB\x1b[0m" << endl; + cout << "\x1b[1;35mEthPurpleB\x1b[0m" << endl; + cout << "\x1b[1;36mEthCyanB\x1b[0m" << endl; + // Bold High Intensity + cout << "\x1b[1;91mEthRedBI\x1b[0m" << endl; + cout << "\x1b[1;92mEthGreenBI\x1b[0m" << endl; + cout << "\x1b[1;93mEthYellowBI\x1b[0m" << endl; + cout << "\x1b[1;94mEthBlueBI\x1b[0m" << endl; + cout << "\x1b[1;95mEthPurpleBI\x1b[0m" << endl; + cout << "\x1b[1;96mEthCyanBI\x1b[0m" << endl; + + // Background + cout << "\x1b[40mEthBlackOn\x1b[0m" << endl; + cout << "\x1b[100mEthCoalOn\x1b[0m" << endl; + cout << "\x1b[47mEthGrayOn\x1b[0m" << endl; + cout << "\x1b[107mEthWhiteOn\x1b[0m" << endl; + cout << "\x1b[41mEthRedOn\x1b[0m" << endl; + cout << "\x1b[42mEthGreenOn\x1b[0m" << endl; + cout << "\x1b[43mEthYellowOn\x1b[0m" << endl; + cout << "\x1b[44mEthBlueOn\x1b[0m" << endl; + cout << "\x1b[45mEthPurpleOn\x1b[0m" << endl; + cout << "\x1b[46mEthCyanOn\x1b[0m" << endl; + // High Intensity backgrounds + cout << "\x1b[101mEthRedOnI\x1b[0m" << endl; + cout << "\x1b[102mEthGreenOnI\x1b[0m" << endl; + cout << "\x1b[103mEthYellowOnI\x1b[0m" << endl; + cout << "\x1b[104mEthBlueOnI\x1b[0m" << endl; + cout << "\x1b[105mEthPurpleOnI\x1b[0m" << endl; + cout << "\x1b[106mEthCyanOnI\x1b[0m" << endl; + + // Underline + cout << "\x1b[4;30mEthBlackU\x1b[0m" << endl; + cout << "\x1b[4;31mEthRedU\x1b[0m" << endl; + cout << "\x1b[4;32mEthGreenU\x1b[0m" << endl; + cout << "\x1b[4;33mEthYellowU\x1b[0m" << endl; + cout << "\x1b[4;34mEthBlueU\x1b[0m" << endl; + cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl; + cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl; + cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl; + // Init defaults Defaults::get(); diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index 0edc3e039..3123fdf58 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -28,10 +28,35 @@ using namespace std; using namespace dev; +//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»» + // Logging int dev::g_logVerbosity = 5; map dev::g_logOverride; +const char* LogChannel::name() { return EthGray "···" EthReset; } +const char* LeftChannel::name() { return EthNavy "◀▬▬" EthReset; } +const char* RightChannel::name() { return EthGreen "▬▬▶" EthReset; } +const char* WarnChannel::name() { return EthOnRed EthBlackBold "✘✘✘" EthReset; } +const char* NoteChannel::name() { return EthGreen " ✔ " EthReset; } +const char* DebugChannel::name() { return EthWhite " ◆ " EthReset; } + +LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v) +{ + auto it = g_logOverride.find(_info); + if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && (int)_v <= g_logVerbosity)) + { + time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + char buf[24]; + if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) + buf[0] = '\0'; // empty if case strftime fails + static char const* c_begin = EthWhite " [ " EthReset EthCoalBold; + static char const* c_sep = EthReset EthWhite " | " EthReset EthCoalBold; + static char const* c_end = EthReset EthWhite " ] " EthReset; + m_sstr << _id << c_begin << buf << c_sep << getThreadName() << ThreadContext::join(c_sep) << c_end; + } +} + /// Associate a name with each thread for nice logging. struct ThreadLocalLogName { diff --git a/libdevcore/Log.h b/libdevcore/Log.h index f3d9942c9..c8924724b 100644 --- a/libdevcore/Log.h +++ b/libdevcore/Log.h @@ -75,42 +75,36 @@ std::string getThreadName(); /// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ). /// Channels should inherit from LogChannel and define name() and verbosity. -struct LogChannel { static const char* name() { return " "; } static const int verbosity = 1; }; -struct LeftChannel: public LogChannel { static const char* name() { return "<<<"; } }; -struct RightChannel: public LogChannel { static const char* name() { return ">>>"; } }; -struct WarnChannel: public LogChannel { static const char* name() { return EthWhiteOn EthBlackB "!!!" EthReset; } static const int verbosity = 0; }; -struct NoteChannel: public LogChannel { static const char* name() { return "***"; } }; -struct DebugChannel: public LogChannel { static const char* name() { return EthWhiteB "---" EthReset; } static const int verbosity = 0; }; +struct LogChannel { static const char* name(); static const int verbosity = 1; }; +struct LeftChannel: public LogChannel { static const char* name(); }; +struct RightChannel: public LogChannel { static const char* name(); }; +struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct NoteChannel: public LogChannel { static const char* name(); }; +struct DebugChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; + +class LogOutputStreamBase +{ +public: + LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v); + +protected: + std::stringstream m_sstr; ///< The accrued log entry. +}; /// Logging class, iostream-like, that can be shifted to. template -class LogOutputStream +class LogOutputStream: private LogOutputStreamBase { public: /// Construct a new object. /// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character. - LogOutputStream(bool _term = true) - { - std::type_info const* i = &typeid(Id); - auto it = g_logOverride.find(i); - if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && Id::verbosity <= g_logVerbosity)) - { - time_t rawTime = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - char buf[24]; - if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) - buf[0] = '\0'; // empty if case strftime fails - m_sstr << Id::name() << EthBlue " [ " EthBlueI << buf << EthBlue " | " EthCyan << getThreadName() << ThreadContext::join(EthBlue " | " EthPurple) << (_term ? EthBlue " ] " : "") << EthReset; - } - } + LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity) {} /// Destructor. Posts the accrued log entry to the g_logPost function. ~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(m_sstr.str(), Id::name()); } /// Shift arbitrary data to the log. Spaces will be added between items as required. template LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; m_sstr << _t; } return *this; } - -private: - std::stringstream m_sstr; ///< The accrued log entry. }; // Simple cout-like stream objects for accessing common log channels. diff --git a/libdevcore/Terminal.h b/libdevcore/Terminal.h index ce6fe898a..f4e31e7e4 100644 --- a/libdevcore/Terminal.h +++ b/libdevcore/Terminal.h @@ -52,7 +52,7 @@ namespace con // High Intensity #define EthCoal "" // Black #define EthRedI "" // Red -#define EthGreenI "" // Green +#define EthLime "" // Green #define EthYellowI "" // Yellow #define EthBlueI "" // Blue #define EthPurpleI "" // Purple @@ -88,67 +88,63 @@ namespace con #define EthCoal "\x1b[90m" // Black #define EthGray "\x1b[37m" // White #define EthWhite "\x1b[97m" // White -#define EthRed "\x1b[31m" // Red +#define EthMaroon "\x1b[31m" // Red +#define EthRed "\x1b[91m" // Red #define EthGreen "\x1b[32m" // Green -#define EthYellow "\x1b[33m" // Yellow -#define EthBlue "\x1b[34m" // Blue -#define EthPurple "\x1b[35m" // Purple -#define EthCyan "\x1b[36m" // Cyan -// High Intensity -#define EthRedI "\x1b[91m" // Red -#define EthGreenI "\x1b[92m" // Green -#define EthYellowI "\x1b[93m" // Yellow -#define EthBlueI "\x1b[94m" // Blue -#define EthPurpleI "\x1b[95m" // Purple -#define EthCyanI "\x1b[96m" // Cyan - -// Bold -#define EthBlackB "\x1b[1;30m" // Black -#define EthCoalB "\x1b[1;90m" // Black -#define EthGrayB "\x1b[1;37m" // White -#define EthWhiteB "\x1b[1;97m" // White -#define EthRedB "\x1b[1;31m" // Red -#define EthGreenB "\x1b[1;32m" // Green -#define EthYellowB "\x1b[1;33m" // Yellow -#define EthBlueB "\x1b[1;34m" // Blue -#define EthPurpleB "\x1b[1;35m" // Purple -#define EthCyanB "\x1b[1;36m" // Cyan -// Bold High Intensity -#define EthRedBI "\x1b[1;91m" // Red -#define EthGreenBI "\x1b[1;92m" // Green -#define EthYellowBI "\x1b[1;93m" // Yellow -#define EthBlueBI "\x1b[1;94m" // Blue -#define EthPurpleBI "\x1b[1;95m" // Purple -#define EthCyanBI "\x1b[1;96m" // Cyan +#define EthLime "\x1b[92m" // Green +#define EthOrange "\x1b[33m" // Yellow +#define EthYellow "\x1b[93m" // Yellow +#define EthNavy "\x1b[34m" // Blue +#define EthBlue "\x1b[94m" // Blue +#define EthViolet "\x1b[35m" // Purple +#define EthPurple "\x1b[95m" // Purple +#define EthTeal "\x1b[36m" // Cyan +#define EthCyan "\x1b[96m" // Cyan + +#define EthBlackBold "\x1b[1;30m" // Black +#define EthCoalBold "\x1b[1;90m" // Black +#define EthGrayBold "\x1b[1;37m" // White +#define EthWhiteBold "\x1b[1;97m" // White +#define EthMaroonBold "\x1b[1;31m" // Red +#define EthRedBold "\x1b[1;91m" // Red +#define EthGreenBold "\x1b[1;32m" // Green +#define EthLimeBold "\x1b[1;92m" // Green +#define EthOrangeBold "\x1b[1;33m" // Yellow +#define EthYellowBold "\x1b[1;93m" // Yellow +#define EthNavyBold "\x1b[1;34m" // Blue +#define EthBlueBold "\x1b[1;94m" // Blue +#define EthVioletBold "\x1b[1;35m" // Purple +#define EthPurpleBold "\x1b[1;95m" // Purple +#define EthTealBold "\x1b[1;36m" // Cyan +#define EthCyanBold "\x1b[1;96m" // Cyan // Background -#define EthBlackOn "\x1b[40m" // Black -#define EthCoalOn "\x1b[100m" // Black -#define EthGrayOn "\x1b[47m" // White -#define EthWhiteOn "\x1b[107m" // White -#define EthRedOn "\x1b[41m" // Red -#define EthGreenOn "\x1b[42m" // Green -#define EthYellowOn "\x1b[43m" // Yellow -#define EthBlueOn "\x1b[44m" // Blue -#define EthPurpleOn "\x1b[45m" // Purple -#define EthCyanOn "\x1b[46m" // Cyan -// High Intensity backgrounds -#define EthRedOnI "\x1b[101m" // Red -#define EthGreenOnI "\x1b[102m" // Green -#define EthYellowOnI "\x1b[103m" // Yellow -#define EthBlueOnI "\x1b[104m" // Blue -#define EthPurpleOnI "\x1b[105m" // Purple -#define EthCyanOnI "\x1b[106m" // Cyan +#define EthOnBlack "\x1b[40m" // Black +#define EthOnCoal "\x1b[100m" // Black +#define EthOnGray "\x1b[47m" // White +#define EthOnWhite "\x1b[107m" // White +#define EthOnMaroon "\x1b[41m" // Red +#define EthOnRed "\x1b[101m" // Red +#define EthOnGreen "\x1b[42m" // Green +#define EthOnLime "\x1b[102m" // Green +#define EthOnOrange "\x1b[43m" // Yellow +#define EthOnYellow "\x1b[103m" // Yellow +#define EthOnNavy "\x1b[44m" // Blue +#define EthOnBlue "\x1b[104m" // Blue +#define EthOnViolet "\x1b[45m" // Purple +#define EthOnPurple "\x1b[105m" // Purple +#define EthOnTeal "\x1b[46m" // Cyan +#define EthOnCyan "\x1b[106m" // Cyan // Underline -#define EthBlackU "\x1b[4;30m" // Black -#define EthRedU "\x1b[4;31m" // Red -#define EthGreenU "\x1b[4;32m" // Green -#define EthYellowU "\x1b[4;33m" // Yellow -#define EthBlueU "\x1b[4;34m" // Blue -#define EthPurpleU "\x1b[4;35m" // Purple -#define EthCyanU "\x1b[4;36m" // Cyan -#define EthWhiteU "\x1b[4;37m" // White +#define EthBlackUnder "\x1b[4;30m" // Black +#define EthGrayUnder "\x1b[4;37m" // White +#define EthMaroonUnder "\x1b[4;31m" // Red +#define EthGreenUnder "\x1b[4;32m" // Green +#define EthOrangeUnder "\x1b[4;33m" // Yellow +#define EthNavyUnder "\x1b[4;34m" // Blue +#define EthVioletUnder "\x1b[4;35m" // Purple +#define EthTealUnder "\x1b[4;36m" // Cyan #endif diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index d4ad0ef1d..f66059ace 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -199,8 +199,8 @@ OnOpFunc Executive::simpleTrace() o << " STORAGE" << endl; for (auto const& i: ext.state().storage(ext.myAddress)) o << showbase << hex << i.first << ": " << i.second << endl; - dev::LogOutputStream(true) << o.str(); - dev::LogOutputStream(false) << " | " << dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << dec << vm.gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32" << " ]"; + dev::LogOutputStream() << o.str(); + dev::LogOutputStream() << " < " << dec << ext.depth << " : " << ext.myAddress << " : #" << steps << " : " << hex << setw(4) << setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " : " << dec << vm.gas() << " : -" << dec << gasCost << " : " << newMemSize << "x32" << " >"; }; } diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index cd4bccbf0..61de42791 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -48,7 +48,8 @@ Session::Session(Host* _s, RLPXFrameIO* _io, std::shared_ptr const& _n, Pe Session::~Session() { - ThreadContext tc(info().id.abridged() + " | " + info().clientVersion); + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); clog(NetMessageSummary) << "Closing peer session :-("; m_peer->m_lastConnected = m_peer->m_lastAttempted - chrono::seconds(1); @@ -323,7 +324,8 @@ void Session::write() auto self(shared_from_this()); ba::async_write(m_socket, ba::buffer(bytes), [this, self](boost::system::error_code ec, std::size_t /*length*/) { - ThreadContext tc(info().id.abridged() + " | " + info().clientVersion); + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); // must check queue, as write callback can occur following dropped() if (ec) { @@ -397,7 +399,8 @@ void Session::doRead() auto self(shared_from_this()); ba::async_read(m_socket, boost::asio::buffer(m_data, h256::size), [this,self](boost::system::error_code ec, std::size_t length) { - ThreadContext tc(info().id.abridged() + " | " + info().clientVersion); + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); if (ec && ec.category() != boost::asio::error::get_misc_category() && ec.value() != boost::asio::error::eof) { clog(NetWarn) << "Error reading: " << ec.message(); diff --git a/test/vm.cpp b/test/vm.cpp index 9e21972f1..2f654b375 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -261,8 +261,8 @@ eth::OnOpFunc FakeExtVM::simpleTrace() for (auto const& i: std::get<2>(ext.addresses.find(ext.myAddress)->second)) o << std::showbase << std::hex << i.first << ": " << i.second << std::endl; - dev::LogOutputStream(true) << o.str(); - dev::LogOutputStream(false) << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; + dev::LogOutputStream() << o.str(); + dev::LogOutputStream() << " | " << std::dec << ext.depth << " | " << ext.myAddress << " | #" << steps << " | " << std::hex << std::setw(4) << std::setfill('0') << vm.curPC() << " : " << instructionInfo(inst).name << " | " << std::dec << vm.gas() << " | -" << std::dec << gasCost << " | " << newMemSize << "x32" << " ]"; /*creates json stack trace*/ if (eth::VMTraceChannel::verbosity <= g_logVerbosity) From dad9a32d3394e2c0ff0c1147aac416ad8f1fe8f9 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 21 Apr 2015 01:10:38 +0200 Subject: [PATCH 46/58] Better logging. --- CMakeLists.txt | 6 +++--- exp/main.cpp | 9 ++++++++- libdevcore/Log.cpp | 23 ++++++++++++----------- libdevcrypto/MemoryDB.cpp | 3 +++ libdevcrypto/MemoryDB.h | 4 ++-- libdevcrypto/TrieDB.cpp | 2 ++ libdevcrypto/TrieDB.h | 2 +- libethereum/BlockChain.cpp | 5 +++++ libethereum/BlockChain.h | 8 ++++---- libethereum/BlockQueue.cpp | 2 ++ libethereum/BlockQueue.h | 2 +- libethereum/Client.cpp | 5 +++++ libethereum/Client.h | 8 ++++---- libethereum/ClientBase.cpp | 5 +++++ libethereum/ClientBase.h | 8 ++++---- libethereum/Executive.cpp | 2 ++ libethereum/Executive.h | 2 +- libethereum/State.cpp | 5 +++++ libethereum/State.h | 8 ++++---- libethereum/TransactionQueue.cpp | 2 ++ libethereum/TransactionQueue.h | 2 +- libp2p/Common.cpp | 14 ++++++++++++++ libp2p/Common.h | 22 +++++++++++----------- libp2p/NodeTable.cpp | 14 ++++++++++++++ libp2p/NodeTable.h | 26 +++++++++++++------------- libp2p/RLPxHandshake.cpp | 2 +- libp2p/Session.cpp | 3 ++- libtestutils/Common.cpp | 2 ++ libtestutils/Common.h | 2 +- 29 files changed, 134 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18d6a911a..0e8a25942 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,11 +242,11 @@ if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x") set(CMAKE_BUILD_TYPE "Release") endif () -# Default TARGET_PLATFORM to ${CMAKE_SYSTEM} +# Default TARGET_PLATFORM to ${CMAKE_SYSTEM_NAME} # change this once we support cross compiling -set(TARGET_PLATFORM CACHE STRING ${CMAKE_SYSTEM}) +set(TARGET_PLATFORM CACHE STRING ${CMAKE_SYSTEM_NAME}) if ("x${TARGET_PLATFORM}" STREQUAL "x") - set(TARGET_PLATFORM ${CMAKE_SYSTEM}) + set(TARGET_PLATFORM ${CMAKE_SYSTEM_NAME}) endif () include(EthDependencies) diff --git a/exp/main.cpp b/exp/main.cpp index 20f287f43..366c5b2ff 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -22,7 +22,14 @@ #if ETH_ETHASHCL #define __CL_ENABLE_EXCEPTIONS #define CL_USE_DEPRECATED_OPENCL_2_0_APIS -#include "libethash-cl/cl.hpp" +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#include +#pragma clang diagnostic pop +#else +#include +#endif #endif #include #include diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index 3123fdf58..c4cacad26 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -28,18 +28,18 @@ using namespace std; using namespace dev; -//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»» +//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙ // Logging int dev::g_logVerbosity = 5; map dev::g_logOverride; -const char* LogChannel::name() { return EthGray "···" EthReset; } -const char* LeftChannel::name() { return EthNavy "◀▬▬" EthReset; } -const char* RightChannel::name() { return EthGreen "▬▬▶" EthReset; } -const char* WarnChannel::name() { return EthOnRed EthBlackBold "✘✘✘" EthReset; } -const char* NoteChannel::name() { return EthGreen " ✔ " EthReset; } -const char* DebugChannel::name() { return EthWhite " ◆ " EthReset; } +const char* LogChannel::name() { return EthGray "···"; } +const char* LeftChannel::name() { return EthNavy "◀▬▬"; } +const char* RightChannel::name() { return EthGreen "▬▬▶"; } +const char* WarnChannel::name() { return EthOnRed EthBlackBold " ✘"; } +const char* NoteChannel::name() { return EthBlue " ℹ"; } +const char* DebugChannel::name() { return EthWhite " ◇"; } LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v) { @@ -50,10 +50,11 @@ LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* char buf[24]; if (strftime(buf, 24, "%X", localtime(&rawTime)) == 0) buf[0] = '\0'; // empty if case strftime fails - static char const* c_begin = EthWhite " [ " EthReset EthCoalBold; - static char const* c_sep = EthReset EthWhite " | " EthReset EthCoalBold; - static char const* c_end = EthReset EthWhite " ] " EthReset; - m_sstr << _id << c_begin << buf << c_sep << getThreadName() << ThreadContext::join(c_sep) << c_end; + static char const* c_begin = " " EthViolet; + static char const* c_sep1 = EthReset EthBlack "|" EthNavy; + static char const* c_sep2 = EthReset EthBlack "|" EthTeal; + static char const* c_end = EthReset " "; + m_sstr << _id << c_begin << buf << c_sep1 << getThreadName() << ThreadContext::join(c_sep2) << c_end; } } diff --git a/libdevcrypto/MemoryDB.cpp b/libdevcrypto/MemoryDB.cpp index 56b77ddee..ab74173c4 100644 --- a/libdevcrypto/MemoryDB.cpp +++ b/libdevcrypto/MemoryDB.cpp @@ -27,6 +27,9 @@ using namespace dev; namespace dev { +const char* DBChannel::name() { return "TDB"; } +const char* DBWarn::name() { return "TDB"; } + std::map MemoryDB::get() const { if (!m_enforceRefs) diff --git a/libdevcrypto/MemoryDB.h b/libdevcrypto/MemoryDB.h index 7858126f8..58b1339a5 100644 --- a/libdevcrypto/MemoryDB.h +++ b/libdevcrypto/MemoryDB.h @@ -31,8 +31,8 @@ namespace dev { -struct DBChannel: public LogChannel { static const char* name() { return "TDB"; } static const int verbosity = 18; }; -struct DBWarn: public LogChannel { static const char* name() { return "TDB"; } static const int verbosity = 1; }; +struct DBChannel: public LogChannel { static const char* name(); static const int verbosity = 18; }; +struct DBWarn: public LogChannel { static const char* name(); static const int verbosity = 1; }; #define dbdebug clog(DBChannel) #define dbwarn clog(DBWarn) diff --git a/libdevcrypto/TrieDB.cpp b/libdevcrypto/TrieDB.cpp index 6f476c14b..6f84a3e29 100644 --- a/libdevcrypto/TrieDB.cpp +++ b/libdevcrypto/TrieDB.cpp @@ -26,3 +26,5 @@ using namespace dev; h256 const dev::c_shaNull = sha3(rlp("")); h256 const dev::EmptyTrie = c_shaNull; + +const char* TrieDBChannel::name() { return "-T-"; } diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h index f645f15fa..68a2c248d 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcrypto/TrieDB.h @@ -40,7 +40,7 @@ namespace ldb = leveldb; namespace dev { -struct TrieDBChannel: public LogChannel { static const char* name() { return "-T-"; } static const int verbosity = 17; }; +struct TrieDBChannel: public LogChannel { static const char* name(); static const int verbosity = 17; }; #define tdebug clog(TrieDBChannel) struct InvalidTrie: virtual dev::Exception {}; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 8dec48e96..8bba5ff1b 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -48,6 +48,11 @@ namespace js = json_spirit; #define ETH_CATCH 1 #define ETH_TIMED_IMPORTS 0 +const char* BlockChainDebug::name() { return EthBlue "☍" EthWhite " ◇"; } +const char* BlockChainWarn::name() { return EthBlue "☍" EthOnRed EthBlackBold " ✘"; } +const char* BlockChainNote::name() { return EthBlue "☍" EthBlue " ℹ"; } +const char* BlockChainChat::name() { return EthBlue "☍" EthWhite " ◌"; } + std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc) { string cmp = toBigEndianString(_bc.currentHash()); diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index be5b931ee..e40d928f9 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -56,10 +56,10 @@ struct AlreadyHaveBlock: virtual Exception {}; struct UnknownParent: virtual Exception {}; struct FutureTime: virtual Exception {}; -struct BlockChainChat: public LogChannel { static const char* name() { return "-B-"; } static const int verbosity = 5; }; -struct BlockChainNote: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 3; }; -struct BlockChainWarn: public LogChannel { static const char* name() { return "=B="; } static const int verbosity = 1; }; -struct BlockChainDebug: public LogChannel { static const char* name() { return "#B#"; } static const int verbosity = 0; }; +struct BlockChainChat: public LogChannel { static const char* name(); static const int verbosity = 5; }; +struct BlockChainNote: public LogChannel { static const char* name(); static const int verbosity = 3; }; +struct BlockChainWarn: public LogChannel { static const char* name(); static const int verbosity = 1; }; +struct BlockChainDebug: public LogChannel { static const char* name(); static const int verbosity = 0; }; // TODO: Move all this Genesis stuff into Genesis.h/.cpp std::map const& genesisState(); diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index 4fd63aa86..b056dc74f 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -29,6 +29,8 @@ using namespace std; using namespace dev; using namespace dev::eth; +const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; } + ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs) { // Check if we already know this block. diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h index 1932b2f66..adcc6ab39 100644 --- a/libethereum/BlockQueue.h +++ b/libethereum/BlockQueue.h @@ -35,7 +35,7 @@ namespace eth class BlockChain; -struct BlockQueueChannel: public LogChannel { static const char* name() { return "[]Q"; } static const int verbosity = 4; }; +struct BlockQueueChannel: public LogChannel { static const char* name(); static const int verbosity = 4; }; #define cblockq dev::LogOutputStream() struct BlockQueueStatus diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index b39a15e22..b9ddcdbaa 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -124,6 +124,11 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r) return _out; } +const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; } +const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; } +const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; } +const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; } + Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): Worker("eth"), m_vc(_dbPath), diff --git a/libethereum/Client.h b/libethereum/Client.h index b1cfaf4ac..d4c55ef55 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -92,10 +92,10 @@ private: std::array m_octiles; }; -struct ClientNote: public LogChannel { static const char* name() { return "*C*"; } static const int verbosity = 2; }; -struct ClientChat: public LogChannel { static const char* name() { return "=C="; } static const int verbosity = 4; }; -struct ClientTrace: public LogChannel { static const char* name() { return "-C-"; } static const int verbosity = 7; }; -struct ClientDetail: public LogChannel { static const char* name() { return " C "; } static const int verbosity = 14; }; +struct ClientNote: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct ClientChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct ClientTrace: public LogChannel { static const char* name(); static const int verbosity = 7; }; +struct ClientDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; struct ActivityReport { diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 5ac9f44d9..6092879b9 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -31,6 +31,11 @@ using namespace std; using namespace dev; using namespace dev::eth; +const char* WatchChannel::name() { return EthBlue "ℹ" EthWhite " "; } +const char* WorkInChannel::name() { return EthOrange "⚒" EthGreen "▬▶"; } +const char* WorkOutChannel::name() { return EthOrange "⚒" EthNavy "◀▬"; } +const char* WorkChannel::name() { return EthOrange "⚒" EthWhite " "; } + State ClientBase::asOf(BlockNumber _h) const { if (_h == PendingBlock) diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 629791b31..531318736 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -60,11 +60,11 @@ struct ClientWatch mutable std::chrono::system_clock::time_point lastPoll = std::chrono::system_clock::now(); }; -struct WatchChannel: public LogChannel { static const char* name() { return "(o)"; } static const int verbosity = 7; }; +struct WatchChannel: public LogChannel { static const char* name(); static const int verbosity = 7; }; #define cwatch LogOutputStream() -struct WorkInChannel: public LogChannel { static const char* name() { return ">W>"; } static const int verbosity = 16; }; -struct WorkOutChannel: public LogChannel { static const char* name() { return "() #define cworkin LogOutputStream() #define cworkout LogOutputStream() diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index f66059ace..2d8dbdc16 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -31,6 +31,8 @@ using namespace std; using namespace dev; using namespace dev::eth; +const char* VMTraceChannel::name() { return "EVM"; } + Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level): m_s(_s), m_lastHashes(_bc.lastHashes((unsigned)_s.info().number - 1)), diff --git a/libethereum/Executive.h b/libethereum/Executive.h index c55341cb8..8903fd464 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -35,7 +35,7 @@ class BlockChain; class ExtVM; struct Manifest; -struct VMTraceChannel: public LogChannel { static const char* name() { return "EVM"; } static const int verbosity = 11; }; +struct VMTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 11; }; /** * @brief Message-call/contract-creation executor; useful for executing transactions. diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 598dac37d..ea2834cc1 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -47,6 +47,11 @@ using namespace dev::eth; static const u256 c_blockReward = 1500 * finney; +const char* StateSafeExceptions::name() { return EthViolet "⚙" EthBlue " ℹ"; } +const char* StateDetail::name() { return EthViolet "⚙" EthWhite " ◌"; } +const char* StateTrace::name() { return EthViolet "⚙" EthGray " ◎"; } +const char* StateChat::name() { return EthViolet "⚙" EthWhite " ◌"; } + OverlayDB State::openDB(std::string _path, WithExisting _we) { if (_path.empty()) diff --git a/libethereum/State.h b/libethereum/State.h index 1b36cbceb..85ca30649 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -50,10 +50,10 @@ namespace eth class BlockChain; class State; -struct StateChat: public LogChannel { static const char* name() { return "-S-"; } static const int verbosity = 4; }; -struct StateTrace: public LogChannel { static const char* name() { return "=S="; } static const int verbosity = 7; }; -struct StateDetail: public LogChannel { static const char* name() { return "/S/"; } static const int verbosity = 14; }; -struct StateSafeExceptions: public LogChannel { static const char* name() { return "(S)"; } static const int verbosity = 21; }; +struct StateChat: public LogChannel { static const char* name(); static const int verbosity = 4; }; +struct StateTrace: public LogChannel { static const char* name(); static const int verbosity = 7; }; +struct StateDetail: public LogChannel { static const char* name(); static const int verbosity = 14; }; +struct StateSafeExceptions: public LogChannel { static const char* name(); static const int verbosity = 21; }; enum class BaseState { diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index c23fd8db4..a4eb5cee8 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -28,6 +28,8 @@ using namespace std; using namespace dev; using namespace dev::eth; +const char* TransactionQueueChannel::name() { return EthCyan "┉┅▶"; } + ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallback const& _cb, IfDropped _ik) { // Check if we already know this transaction. diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index e2d1c3aee..3858949cc 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -35,7 +35,7 @@ namespace eth class BlockChain; -struct TransactionQueueChannel: public LogChannel { static const char* name() { return "->Q"; } static const int verbosity = 4; }; +struct TransactionQueueChannel: public LogChannel { static const char* name(); static const int verbosity = 4; }; #define ctxq dev::LogOutputStream() enum class IfDropped { Ignore, Retry }; diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index 7206ec835..1853679cf 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -32,6 +32,20 @@ const dev::p2p::Node dev::p2p::UnspecifiedNode = dev::p2p::Node(NodeId(), Unspec bool dev::p2p::NodeIPEndpoint::test_allowLocal = false; +//⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙━┅┉▬ + +const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; } +const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; } +const char* NetNote::name() { return EthYellow "⧎" EthBlue " ℹ"; } +const char* NetConnect::name() { return EthYellow "⧎" EthYellow " ▢"; } +const char* NetMessageSummary::name() { return EthYellow "⧎" EthWhite " ◌"; } +const char* NetMessageDetail::name() { return EthYellow "⧎" EthGray " ○"; } +const char* NetTriviaSummary::name() { return EthYellow "⧎" EthGray " ◎"; } +const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; } +const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; } +const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; } +const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; } + bool p2p::isPublicAddress(std::string const& _addressToCheck) { return _addressToCheck.empty() ? false : isPublicAddress(bi::address::from_string(_addressToCheck)); diff --git a/libp2p/Common.h b/libp2p/Common.h index 691ef7fb3..378064e7d 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -75,17 +75,17 @@ struct NetworkStartRequired: virtual dev::Exception {}; struct InvalidPublicIPAddress: virtual dev::Exception {}; struct InvalidHostIPAddress: virtual dev::Exception {}; -struct NetWarn: public LogChannel { static const char* name() { return "!N!"; } static const int verbosity = 0; }; -struct NetNote: public LogChannel { static const char* name() { return "*N*"; } static const int verbosity = 1; }; -struct NetImpolite: public LogChannel { static const char* name() { return "#!*"; } static const int verbosity = 1; }; -struct NetMessageSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 2; }; -struct NetConnect: public LogChannel { static const char* name() { return "+N+"; } static const int verbosity = 10; }; -struct NetMessageDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 5; }; -struct NetTriviaSummary: public LogChannel { static const char* name() { return "-N-"; } static const int verbosity = 10; }; -struct NetTriviaDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 11; }; -struct NetAllDetail: public LogChannel { static const char* name() { return "=N="; } static const int verbosity = 13; }; -struct NetRight: public LogChannel { static const char* name() { return ">N>"; } static const int verbosity = 14; }; -struct NetLeft: public LogChannel { static const char* name() { return ">P"; } +const char* NodeTableIngress::name() { return "< void interpretRLP(bytesConstRef _bytes) { RLP r(_bytes); for (auto n: r[0]) nodes.push_back(Node(n)); ts = r[1].toInt(); } }; -struct NodeTableWarn: public LogChannel { static const char* name() { return "!P!"; } static const int verbosity = 0; }; -struct NodeTableNote: public LogChannel { static const char* name() { return "*P*"; } static const int verbosity = 1; }; -struct NodeTableMessageSummary: public LogChannel { static const char* name() { return "-P-"; } static const int verbosity = 2; }; -struct NodeTableMessageDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 5; }; -struct NodeTableConnect: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; }; -struct NodeTableEvent: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; }; -struct NodeTableTimer: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; }; -struct NodeTableUpdate: public LogChannel { static const char* name() { return "+P+"; } static const int verbosity = 10; }; -struct NodeTableTriviaSummary: public LogChannel { static const char* name() { return "-P-"; } static const int verbosity = 10; }; -struct NodeTableTriviaDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 11; }; -struct NodeTableAllDetail: public LogChannel { static const char* name() { return "=P="; } static const int verbosity = 13; }; -struct NodeTableEgress: public LogChannel { static const char* name() { return ">>P"; } static const int verbosity = 14; }; -struct NodeTableIngress: public LogChannel { static const char* name() { return "<remoteEndpoint().address().is_unspecified()) - clog(NetWarn) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; + clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; cancel(); } }); diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 61de42791..363953a20 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -436,7 +436,8 @@ void Session::doRead() auto tlen = frameSize + ((16 - (frameSize % 16)) % 16) + h128::size; ba::async_read(m_socket, boost::asio::buffer(m_data, tlen), [this, self, headerRLP, frameSize, tlen](boost::system::error_code ec, std::size_t length) { - ThreadContext tc(info().id.abridged() + " | " + info().clientVersion); + ThreadContext tc(info().id.abridged()); + ThreadContext tc2(info().clientVersion); if (ec && ec.category() != boost::asio::error::get_misc_category() && ec.value() != boost::asio::error::eof) { clog(NetWarn) << "Error reading: " << ec.message(); diff --git a/libtestutils/Common.cpp b/libtestutils/Common.cpp index 86f96f667..3c1350a99 100644 --- a/libtestutils/Common.cpp +++ b/libtestutils/Common.cpp @@ -29,6 +29,8 @@ using namespace std; using namespace dev; using namespace dev::test; +const char* TestChannel::name() { return "TST"; } + std::string dev::test::getTestPath() { string testPath; diff --git a/libtestutils/Common.h b/libtestutils/Common.h index 4757a3b7a..f7f786323 100644 --- a/libtestutils/Common.h +++ b/libtestutils/Common.h @@ -30,7 +30,7 @@ namespace dev namespace test { -struct TestChannel: public LogChannel { static const char* name() { return "TEST"; } }; +struct TestChannel: public LogChannel { static const char* name(); }; #define ctest dev::LogOutputStream() std::string getTestPath(); From 8b6cb1e23c4d37a7c3cc82cb9fb8551cb58a3891 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 21 Apr 2015 01:14:45 +0200 Subject: [PATCH 47/58] Version bump and client rename. --- eth/main.cpp | 2 +- libdevcore/Common.cpp | 2 +- neth/main.cpp | 2 +- test/libweb3jsonrpc/jsonrpc.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 4ce42e47e..da8943e46 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -926,7 +926,7 @@ int main(int argc, char** argv) VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); - std::string clientImplString = "Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""); + std::string clientImplString = "++eth/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""); dev::WebThreeDirect web3( clientImplString, dbPath, diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 1f0d188fa..f27637dec 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.9.12"; +char const* Version = "0.9.13"; } diff --git a/neth/main.cpp b/neth/main.cpp index 31df2ffcb..4e83f64bc 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -542,7 +542,7 @@ int main(int argc, char** argv) VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); - std::string clientImplString = "NEthereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""); + std::string clientImplString = "N++eth/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) + (jit ? "/JIT" : ""); dev::WebThreeDirect web3( clientImplString, dbPath, diff --git a/test/libweb3jsonrpc/jsonrpc.cpp b/test/libweb3jsonrpc/jsonrpc.cpp index f3e702653..97ba17ccf 100644 --- a/test/libweb3jsonrpc/jsonrpc.cpp +++ b/test/libweb3jsonrpc/jsonrpc.cpp @@ -59,7 +59,7 @@ struct Setup setup = true; dev::p2p::NetworkPreferences nprefs(30303, std::string(), false); - web3 = new WebThreeDirect("Ethereum(++) tests", "", true, {"eth", "shh"}, nprefs); + web3 = new WebThreeDirect("++eth tests", "", true, {"eth", "shh"}, nprefs); web3->setIdealPeerCount(5); web3->ethereum()->setForceMining(true); From 50d78468f012b8f4b72066b5b17ba9a32cceae68 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 21 Apr 2015 08:25:45 +0200 Subject: [PATCH 48/58] policy CMP0054 set to new --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77180e56f..b3773861e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ cmake_policy(SET CMP0020 NEW) # 3.1 and above if ((${CMAKE_MAJOR_VERSION} GREATER 2) AND (${CMAKE_MINOR_VERSION} GREATER 0)) # implicitly dereference variables (deprecated in 3.1) - cmake_policy(SET CMP0054 OLD) + cmake_policy(SET CMP0054 NEW) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") From 6f1bfcb23230bd2e340d407260f3b83f216c6bc9 Mon Sep 17 00:00:00 2001 From: Jan Willem Penterman Date: Tue, 21 Apr 2015 10:34:07 +0200 Subject: [PATCH 49/58] added some missing "color" definitions and uisng basic charset for logger "icons" --- libdevcore/Log.cpp | 9 +++ libdevcore/Terminal.h | 131 ++++++++++++++++++++---------------------- 2 files changed, 72 insertions(+), 68 deletions(-) diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index c4cacad26..5515fd8da 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -34,12 +34,21 @@ using namespace dev; int dev::g_logVerbosity = 5; map dev::g_logOverride; +#ifdef _WIN32 +const char* LogChannel::name() { return EthGray "..."; } +const char* LeftChannel::name() { return EthNavy "<--"; } +const char* RightChannel::name() { return EthGreen "-->"; } +const char* WarnChannel::name() { return EthOnRed EthBlackBold " X"; } +const char* NoteChannel::name() { return EthBlue " i"; } +const char* DebugChannel::name() { return EthWhite " D"; } +#else const char* LogChannel::name() { return EthGray "···"; } const char* LeftChannel::name() { return EthNavy "◀▬▬"; } const char* RightChannel::name() { return EthGreen "▬▬▶"; } const char* WarnChannel::name() { return EthOnRed EthBlackBold " ✘"; } const char* NoteChannel::name() { return EthBlue " ℹ"; } const char* DebugChannel::name() { return EthWhite " ◇"; } +#endif LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v) { diff --git a/libdevcore/Terminal.h b/libdevcore/Terminal.h index f4e31e7e4..a30a527f2 100644 --- a/libdevcore/Terminal.h +++ b/libdevcore/Terminal.h @@ -9,75 +9,70 @@ namespace con #define EthReset "" // Text Reset -// Regular Colors -#define EthBlack "" // Black -#define EthRed "" // Red -#define EthGreen "" // Green -#define EthYellow "" // Yellow -#define EthBlue "" // Blue -#define EthPurple "" // Purple -#define EthCyan "" // Cyan -#define EthWhite "" // White - -// Bold -#define EthBlackB "" // Black -#define EthRedB "" // Red -#define EthGreenB "" // Green -#define EthYellowB "" // Yellow -#define EthBlueB "" // Blue -#define EthPurpleB "" // Purple -#define EthCyanB "" // Cyan -#define EthWhiteB "" // White - -// Underline -#define EthBlackU "" // Black -#define EthRedU "" // Red -#define EthGreenU "" // Green -#define EthYellowU "" // Yellow -#define EthBlueU "" // Blue -#define EthPurpleU "" // Purple -#define EthCyanU "" // Cyan -#define EthWhiteU "" // White +#define EthReset "" // Text Reset -// Background -#define EthBlackOn "" // Black -#define EthRedOn "" // Red -#define EthGreenOn "" // Green -#define EthYellowOn "" // Yellow -#define EthBlueOn "" // Blue -#define EthPurpleOn "" // Purple -#define EthCyanOn "" // Cyan -#define EthWhiteOn "" // White - -// High Intensity -#define EthCoal "" // Black -#define EthRedI "" // Red -#define EthLime "" // Green -#define EthYellowI "" // Yellow -#define EthBlueI "" // Blue -#define EthPurpleI "" // Purple -#define EthCyanI "" // Cyan -#define EthWhiteI "" // White - -// Bold High Intensity -#define EthBlackBI "" // Black -#define EthRedBI "" // Red -#define EthGreenBI "" // Green -#define EthYellowBI "" // Yellow -#define EthBlueBI "" // Blue -#define EthPurpleBI "" // Purple -#define EthCyanBI "" // Cyan -#define EthWhiteBI "" // White - -// High Intensity backgrounds -#define EthBlackOnI "" // Black -#define EthRedOnI "" // Red -#define EthGreenOnI "" // Green -#define EthYellowOnI "" // Yellow -#define EthBlueOnI "" // Blue -#define EthPurpleOnI "" // Purple -#define EthCyanOnI "" // Cyan -#define EthWhiteOnI "" // White + // Regular Colors +#define EthBlack "" // Black +#define EthCoal "" // Black +#define EthGray "" // White +#define EthWhite "" // White +#define EthMaroon "" // Red +#define EthRed "" // Red +#define EthGreen "" // Green +#define EthLime "" // Green +#define EthOrange "" // Yellow +#define EthYellow "" // Yellow +#define EthNavy "" // Blue +#define EthBlue "" // Blue +#define EthViolet "" // Purple +#define EthPurple "" // Purple +#define EthTeal "" // Cyan +#define EthCyan "" // Cyan + +#define EthBlackBold "" // Black +#define EthCoalBold "" // Black +#define EthGrayBold "" // White +#define EthWhiteBold "" // White +#define EthMaroonBold "" // Red +#define EthRedBold "" // Red +#define EthGreenBold "" // Green +#define EthLimeBold "" // Green +#define EthOrangeBold "" // Yellow +#define EthYellowBold "" // Yellow +#define EthNavyBold "" // Blue +#define EthBlueBold "" // Blue +#define EthVioletBold "" // Purple +#define EthPurpleBold "" // Purple +#define EthTealBold "" // Cyan +#define EthCyanBold "" // Cyan + + // Background +#define EthOnBlack "" // Black +#define EthOnCoal "" // Black +#define EthOnGray "" // White +#define EthOnWhite "" // White +#define EthOnMaroon "" // Red +#define EthOnRed "" // Red +#define EthOnGreen "" // Green +#define EthOnLime "" // Green +#define EthOnOrange "" // Yellow +#define EthOnYellow "" // Yellow +#define EthOnNavy "" // Blue +#define EthOnBlue "" // Blue +#define EthOnViolet "" // Purple +#define EthOnPurple "" // Purple +#define EthOnTeal "" // Cyan +#define EthOnCyan "" // Cyan + + // Underline +#define EthBlackUnder "" // Black +#define EthGrayUnder "" // White +#define EthMaroonUnder "" // Red +#define EthGreenUnder "" // Green +#define EthOrangeUnder "" // Yellow +#define EthNavyUnder "" // Blue +#define EthVioletUnder "" // Purple +#define EthTealUnder "" // Cyan #else From aa9583a14b8c545793f4ace95ec2161a767e2c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 21 Apr 2015 10:37:47 +0200 Subject: [PATCH 50/58] testeth: Handle command line options for user defined tests --- test/TestHelper.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ed844e961..92d38c008 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -542,6 +542,8 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e void userDefinedTest(string testTypeFlag, std::function doTests) { + Options::get(); // parse command line options, e.g. to enable JIT + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) { string arg = boost::unit_test::framework::master_test_suite().argv[i]; From 69db1c7181249a2b70fd39f8f5185166dc192815 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 21 Apr 2015 11:45:33 +0200 Subject: [PATCH 51/58] Removed (and added) some #ifs (but removed more than I added). --- alethzero/CMakeLists.txt | 4 +++- alethzero/Transact.cpp | 6 ++++++ test/CMakeLists.txt | 11 +++++------ test/libethereum/state.cpp | 2 ++ test/libevmcore/CMakeLists.txt | 5 ----- test/{libevmcore => libsolidity}/Assembly.cpp | 4 ---- test/libsolidity/SolidityABIJSON.cpp | 3 --- test/libsolidity/SolidityCompiler.cpp | 4 ---- test/libsolidity/SolidityEndToEndTest.cpp | 4 ---- test/libsolidity/SolidityExpressionCompiler.cpp | 4 ---- test/libsolidity/SolidityInterface.cpp | 4 ---- test/libsolidity/SolidityNameAndTypeResolution.cpp | 4 ---- test/libsolidity/SolidityNatspecJSON.cpp | 4 ---- test/libsolidity/SolidityOptimizer.cpp | 4 ---- test/libsolidity/SolidityParser.cpp | 4 ---- test/libsolidity/SolidityScanner.cpp | 4 ---- test/libsolidity/SolidityTypes.cpp | 4 ---- 17 files changed, 16 insertions(+), 59 deletions(-) delete mode 100644 test/libevmcore/CMakeLists.txt rename test/{libevmcore => libsolidity}/Assembly.cpp (99%) diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index fb134a82d..d9e8dff6f 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -51,7 +51,9 @@ target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} lll) -target_link_libraries(${EXECUTABLE} solidity) +if (SOLIDITY) + target_link_libraries(${EXECUTABLE} solidity) +endif () target_link_libraries(${EXECUTABLE} evmcore) target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} web3jsonrpc) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 1ebdf9e23..d3e5650bf 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -168,6 +168,7 @@ static std::string toString(TransactionException _te) } } +#if ETH_SOLIDITY static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, string const& _contractName) { string ret = ""; @@ -182,6 +183,7 @@ static string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, s } return ret; } +#endif static tuple, bytes, string> userInputToCode(string const& _user, bool _opt) { @@ -197,6 +199,7 @@ static tuple, bytes, string> userInputToCode(string const& _user, boost::replace_all_copy(u, " ", ""); data = fromHex(u); } +#if ETH_SOLIDITY else if (sourceIsSolidity(_user)) { dev::solidity::CompilerStack compiler(true); @@ -220,6 +223,7 @@ static tuple, bytes, string> userInputToCode(string const& _user, errors.push_back("Solidity: Uncaught exception"); } } +#endif #if ETH_SERPENT else if (sourceIsSerpent(_user)) { @@ -394,6 +398,7 @@ void Transact::on_send_clicked() // If execution is a contract creation, add Natspec to // a local Natspec LEVELDB ethereum()->submitTransaction(s, value(), m_data, ui->gas->value(), gasPrice()); +#if ETH_SOLIDITY string src = ui->data->toPlainText().toStdString(); if (sourceIsSolidity(src)) try @@ -407,6 +412,7 @@ void Transact::on_send_clicked() } } catch (...) {} +#endif } else ethereum()->submitTransaction(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice()); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b46ab06e5..a97bb86fc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -23,19 +23,18 @@ add_subdirectory(libdevcrypto) add_subdirectory(libethcore) add_subdirectory(libethereum) add_subdirectory(libevm) -add_subdirectory(libevmcore) add_subdirectory(libnatspec) add_subdirectory(libp2p) -add_subdirectory(libsolidity) +if (SOLIDITY) + add_subdirectory(libsolidity) +endif () +if (JSONRPC) add_subdirectory(libweb3jsonrpc) +endif () add_subdirectory(libwhisper) set(SRC_LIST ${SRC_LIST} ${SRC}) -if (NOT JSONRPC) - list(REMOVE_ITEM SRC_LIST "libweb3jsonrpc/./AccountHolder.cpp") -endif() - include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(BEFORE ..) include_directories(${Boost_INCLUDE_DIRS}) diff --git a/test/libethereum/state.cpp b/test/libethereum/state.cpp index e6811d972..670ed0330 100644 --- a/test/libethereum/state.cpp +++ b/test/libethereum/state.cpp @@ -171,10 +171,12 @@ BOOST_AUTO_TEST_CASE(stMemoryStressTest) dev::test::executeTests("stMemoryStressTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } +#if ETH_SOLIDITY BOOST_AUTO_TEST_CASE(stSolidityTest) { dev::test::executeTests("stSolidityTest", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } +#endif BOOST_AUTO_TEST_CASE(stMemoryTest) { diff --git a/test/libevmcore/CMakeLists.txt b/test/libevmcore/CMakeLists.txt deleted file mode 100644 index 3ceda13b0..000000000 --- a/test/libevmcore/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -cmake_policy(SET CMP0015 NEW) - -aux_source_directory(. SRCS) - -add_sources(${SRCS}) diff --git a/test/libevmcore/Assembly.cpp b/test/libsolidity/Assembly.cpp similarity index 99% rename from test/libevmcore/Assembly.cpp rename to test/libsolidity/Assembly.cpp index fab260a9d..8dcee7fb5 100644 --- a/test/libevmcore/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -20,8 +20,6 @@ * Unit tests for Assembly Items from evmcore/Assembly.h */ -#if ETH_SOLIDITY - #include #include #include @@ -120,5 +118,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp index b0633cca1..f0e54a940 100644 --- a/test/libsolidity/SolidityABIJSON.cpp +++ b/test/libsolidity/SolidityABIJSON.cpp @@ -19,7 +19,6 @@ * @date 2014 * Unit tests for the solidity compiler JSON Interface output. */ -#if ETH_SOLIDITY #include "../TestHelper.h" #include @@ -501,5 +500,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } - -#endif diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp index bb16c88cd..7b0ceedb6 100644 --- a/test/libsolidity/SolidityCompiler.cpp +++ b/test/libsolidity/SolidityCompiler.cpp @@ -20,8 +20,6 @@ * Unit tests for the solidity compiler. */ -#if ETH_SOLIDITY - #include #include #include @@ -193,5 +191,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c345f5204..db58c3441 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -21,8 +21,6 @@ * Unit tests for the solidity expression compiler, testing the behaviour of the code. */ -#if ETH_SOLIDITY - #include #include #include @@ -3704,5 +3702,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp index 505cac991..613b0b1f7 100644 --- a/test/libsolidity/SolidityExpressionCompiler.cpp +++ b/test/libsolidity/SolidityExpressionCompiler.cpp @@ -20,8 +20,6 @@ * Unit tests for the solidity expression compiler. */ -#if ETH_SOLIDITY - #include #include @@ -491,5 +489,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityInterface.cpp b/test/libsolidity/SolidityInterface.cpp index ab6cb9029..c8f74e3aa 100644 --- a/test/libsolidity/SolidityInterface.cpp +++ b/test/libsolidity/SolidityInterface.cpp @@ -20,8 +20,6 @@ * Unit tests for generating source interfaces for Solidity contracts. */ -#if ETH_SOLIDITY - #include "../TestHelper.h" #include #include @@ -149,5 +147,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } - -#endif diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 917ea0007..076ea595b 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -20,8 +20,6 @@ * Unit tests for the name and type resolution of the solidity parser. */ -#if ETH_SOLIDITY - #include #include @@ -1671,5 +1669,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp index 99adcf199..d2c1ec186 100644 --- a/test/libsolidity/SolidityNatspecJSON.cpp +++ b/test/libsolidity/SolidityNatspecJSON.cpp @@ -20,8 +20,6 @@ * Unit tests for the solidity compiler JSON Interface output. */ -#if ETH_SOLIDITY - #include "../TestHelper.h" #include #include @@ -539,5 +537,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } - -#endif diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 8ab1de8f1..af9b51467 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -20,8 +20,6 @@ * Tests for the Solidity optimizer. */ -#if ETH_SOLIDITY - #include #include #include @@ -816,5 +814,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 7baa12921..ad17c40a6 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -20,8 +20,6 @@ * Unit tests for the solidity parser. */ -#if ETH_SOLIDITY - #include #include #include @@ -855,5 +853,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityScanner.cpp b/test/libsolidity/SolidityScanner.cpp index 20b946ee0..8d3e53929 100644 --- a/test/libsolidity/SolidityScanner.cpp +++ b/test/libsolidity/SolidityScanner.cpp @@ -20,8 +20,6 @@ * Unit tests for the solidity scanner. */ -#if ETH_SOLIDITY - #include #include @@ -288,5 +286,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } // end namespaces - -#endif diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp index da8b48303..6b6306479 100644 --- a/test/libsolidity/SolidityTypes.cpp +++ b/test/libsolidity/SolidityTypes.cpp @@ -20,8 +20,6 @@ * Unit tests for the type system of Solidity. */ -#if ETH_SOLIDITY - #include #include @@ -93,5 +91,3 @@ BOOST_AUTO_TEST_SUITE_END() } } } - -#endif From c4ad72f29211ea07043c3c290a86cb7055ac5731 Mon Sep 17 00:00:00 2001 From: Jan Willem Penterman Date: Tue, 21 Apr 2015 12:54:32 +0200 Subject: [PATCH 52/58] removed special characters from Net Log messages (Win only) --- libp2p/Common.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index 1853679cf..f4394b146 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -34,6 +34,19 @@ bool dev::p2p::NodeIPEndpoint::test_allowLocal = false; //⊳⊲◀▶■▣▢□▷◁▧▨▩▲◆◉◈◇◎●◍◌○◼☑☒☎☢☣☰☀♽♥♠✩✭❓✔✓✖✕✘✓✔✅⚒⚡⦸⬌∅⁕«««»»»⚙━┅┉▬ +#ifdef _WIN32 +const char* NetWarn::name() { return EthYellow "N" EthRed " X"; } +const char* NetImpolite::name() { return EthYellow "N" EthRed " !"; } +const char* NetNote::name() { return EthYellow "N" EthBlue " i"; } +const char* NetConnect::name() { return EthYellow "N" EthYellow " C"; } +const char* NetMessageSummary::name() { return EthYellow "N" EthWhite " ."; } +const char* NetMessageDetail::name() { return EthYellow "N" EthGray " o"; } +const char* NetTriviaSummary::name() { return EthYellow "N" EthGray " O"; } +const char* NetTriviaDetail::name() { return EthYellow "N" EthCoal " 0"; } +const char* NetAllDetail::name() { return EthYellow "N" EthCoal " A"; } +const char* NetRight::name() { return EthYellow "N" EthGreen "->"; } +const char* NetLeft::name() { return EthYellow "N" EthNavy "<-"; } +#else const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; } const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; } const char* NetNote::name() { return EthYellow "⧎" EthBlue " ℹ"; } @@ -45,6 +58,7 @@ const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; } const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; } const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; } const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; } +#endif bool p2p::isPublicAddress(std::string const& _addressToCheck) { From 7386869de60855429fa2587b2ad51b0cee9ab9d2 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 20 Apr 2015 14:09:41 +0200 Subject: [PATCH 53/58] Fixed byte alignment for return type of ripemd160 built-in contract. --- libsolidity/ExpressionCompiler.cpp | 8 +++++++- test/libsolidity/SolidityEndToEndTest.cpp | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 7ea71a7a4..02f22593a 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -1066,7 +1066,13 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio m_context << eth::Instruction::POP; m_context << eth::Instruction::POP; // pop contract address - if (firstType) + if (_functionType.getLocation() == FunctionType::Location::RIPEMD160) + { + // fix: built-in contract returns right-aligned data + CompilerUtils(m_context).loadFromMemory(0, IntegerType(160), false, true); + appendTypeConversion(IntegerType(160), FixedBytesType(20)); + } + else if (firstType) CompilerUtils(m_context).loadFromMemory(0, *firstType, false, true); } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c345f5204..1d437ee5f 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1499,7 +1499,7 @@ BOOST_AUTO_TEST_CASE(ripemd) { h256 ret; dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32)); - return u256(ret) >> (256 - 160); + return u256(ret); }; testSolidityAgainstCpp("a(bytes32)", f, u256(4)); testSolidityAgainstCpp("a(bytes32)", f, u256(5)); @@ -1814,7 +1814,7 @@ BOOST_AUTO_TEST_CASE(gas_for_builtin) )"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes()); - BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), true)); + BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc000000000000000000000000"), true)); } BOOST_AUTO_TEST_CASE(value_complex) From ea5e343e4d33d22da7d2763a01954a0eaaa6bdbd Mon Sep 17 00:00:00 2001 From: Jan Willem Penterman Date: Tue, 21 Apr 2015 14:42:14 +0200 Subject: [PATCH 54/58] more ascii art for windows logging --- libethereum/BlockChain.cpp | 7 +++++++ libethereum/BlockQueue.cpp | 4 ++++ libethereum/Client.cpp | 7 +++++++ 3 files changed, 18 insertions(+) diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 8bba5ff1b..b1c519858 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -48,10 +48,17 @@ namespace js = json_spirit; #define ETH_CATCH 1 #define ETH_TIMED_IMPORTS 0 +#ifdef _WIN32 +const char* BlockChainDebug::name() { return EthBlue "8" EthWhite " <>"; } +const char* BlockChainWarn::name() { return EthBlue "8" EthOnRed EthBlackBold " X"; } +const char* BlockChainNote::name() { return EthBlue "8" EthBlue " i"; } +const char* BlockChainChat::name() { return EthBlue "8" EthWhite " o"; } +#else const char* BlockChainDebug::name() { return EthBlue "☍" EthWhite " ◇"; } const char* BlockChainWarn::name() { return EthBlue "☍" EthOnRed EthBlackBold " ✘"; } const char* BlockChainNote::name() { return EthBlue "☍" EthBlue " ℹ"; } const char* BlockChainChat::name() { return EthBlue "☍" EthWhite " ◌"; } +#endif std::ostream& dev::eth::operator<<(std::ostream& _out, BlockChain const& _bc) { diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index b056dc74f..0c40521e2 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -29,7 +29,11 @@ using namespace std; using namespace dev; using namespace dev::eth; +#ifdef _WIN32 +const char* BlockQueueChannel::name() { return EthOrange "[]->"; } +#else const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; } +#endif ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs) { diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index b9ddcdbaa..cbd650c75 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -124,10 +124,17 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r) return _out; } +#ifdef _WIN32 +const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; } +const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; } +const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; } +const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; } +#else const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; } const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; } const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; } const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; } +#endif Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): Worker("eth"), From 3146a7aeb75b91d78d7a3027ec3812e8346cdb9b Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 21 Apr 2015 13:35:38 +0200 Subject: [PATCH 55/58] Fix for Contract and Enum types as external function arguments. --- libsolidity/AST.h | 11 ++++----- libsolidity/Types.cpp | 8 +++---- libsolidity/Types.h | 29 +++++++++++++++++++---- test/libsolidity/SolidityEndToEndTest.cpp | 19 +++++++++++++++ 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index 0c133ff1a..a75bdf7dc 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -143,8 +143,8 @@ public: ASTString const& getName() const { return *m_name; } Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; } bool isPublic() const { return getVisibility() >= Visibility::Public; } - bool isVisibleInContract() const { return getVisibility() != Visibility::External; } - virtual bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; } + virtual bool isVisibleInContract() const { return getVisibility() != Visibility::External; } + bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; } /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope. /// Available only after name and type resolution step. @@ -156,7 +156,7 @@ public: /// contract types. virtual TypePointer getType(ContractDefinition const* m_currentContract = nullptr) const = 0; virtual bool isLValue() const { return false; } - virtual bool isPartOfExternalInterface() const { return false; }; + virtual bool isPartOfExternalInterface() const { return false; } protected: virtual Visibility getDefaultVisibility() const { return Visibility::Public; } @@ -437,10 +437,9 @@ public: ASTPointer const& getReturnParameterList() const { return m_returnParameters; } Block const& getBody() const { return *m_body; } - virtual bool isVisibleInDerivedContracts() const override + virtual bool isVisibleInContract() const override { - return !isConstructor() && !getName().empty() && isVisibleInContract() && - getVisibility() >= Visibility::Internal; + return Declaration::isVisibleInContract() && !isConstructor() && !getName().empty(); } virtual TypePointer getType(ContractDefinition const*) const override; virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstructor && !getName().empty(); } diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index bfde7187a..eb24a4629 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -1109,7 +1109,7 @@ unsigned FunctionType::getSizeOnStack() const return size; } -TypePointer FunctionType::externalType() const +FunctionTypePointer FunctionType::externalFunctionType() const { TypePointers paramTypes; TypePointers retParamTypes; @@ -1117,13 +1117,13 @@ TypePointer FunctionType::externalType() const for (auto type: m_parameterTypes) { if (!type->externalType()) - return TypePointer(); + return FunctionTypePointer(); paramTypes.push_back(type->externalType()); } for (auto type: m_returnParameterTypes) { if (!type->externalType()) - return TypePointer(); + return FunctionTypePointer(); retParamTypes.push_back(type->externalType()); } return make_shared(paramTypes, retParamTypes, m_location, m_arbitraryParameters); @@ -1168,7 +1168,7 @@ string FunctionType::externalSignature(std::string const& _name) const } string ret = funcName + "("; - TypePointers externalParameterTypes = dynamic_cast(*externalType()).getParameterTypes(); + TypePointers externalParameterTypes = externalFunctionType()->getParameterTypes(); for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it) { solAssert(!!(*it), "Parameter should have external type"); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index e6d32d175..493fde545 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -404,12 +404,20 @@ public: virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(Type const& _other) const override; + virtual unsigned getCalldataEncodedSize(bool _padded = true) const override + { + return externalType()->getCalldataEncodedSize(_padded); + } virtual unsigned getStorageBytes() const override { return 20; } + virtual bool canLiveOutsideStorage() const override { return true; } virtual bool isValueType() const override { return true; } virtual std::string toString() const override; virtual MemberList const& getMembers() const override; - virtual TypePointer externalType() const override { return std::make_shared(160, IntegerType::Modifier::Address); } + virtual TypePointer externalType() const override + { + return std::make_shared(160, IntegerType::Modifier::Address); + } bool isSuper() const { return m_super; } ContractDefinition const& getContractDefinition() const { return m_contract; } @@ -472,13 +480,21 @@ public: explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; virtual bool operator==(Type const& _other) const override; + virtual unsigned getCalldataEncodedSize(bool _padded = true) const override + { + return externalType()->getCalldataEncodedSize(_padded); + } virtual unsigned getSizeOnStack() const override { return 1; } virtual unsigned getStorageBytes() const override; + virtual bool canLiveOutsideStorage() const override { return true; } virtual std::string toString() const override; virtual bool isValueType() const override { return true; } virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - virtual TypePointer externalType() const override { return std::make_shared(8 * int(getStorageBytes())); } + virtual TypePointer externalType() const override + { + return std::make_shared(8 * int(getStorageBytes())); + } EnumDefinition const& getEnumDefinition() const { return m_enum; } /// @returns the value that the string has in the Enum @@ -512,9 +528,12 @@ public: virtual Category getCategory() const override { return Category::Function; } - /// @returns TypePointer of a new FunctionType object. All input/return parameters are an appropriate external types of input/return parameters of current function. - /// Returns an empty shared pointer if one of the input/return parameters does not have an externaltype. - virtual TypePointer externalType() const override; + /// @returns TypePointer of a new FunctionType object. All input/return parameters are an + /// appropriate external types of input/return parameters of current function. + /// Returns an empty shared pointer if one of the input/return parameters does not have an + /// external type. + virtual FunctionTypePointer externalFunctionType() const; + virtual TypePointer externalType() const override { return externalFunctionType(); } explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true); explicit FunctionType(VariableDeclaration const& _varDecl); diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index c345f5204..f01e4c851 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -3699,6 +3699,25 @@ BOOST_AUTO_TEST_CASE(packed_storage_signed) BOOST_CHECK( callContractFunction("test()") == encodeArgs(u256(-2), u256(4), u256(-112), u256(0))); } +BOOST_AUTO_TEST_CASE(external_types_in_calls) +{ + char const* sourceCode = R"( + contract C1 { C1 public bla; function C1(C1 x) { bla = x; } } + contract C { + function test() returns (C1 x, C1 y) { + C1 c = new C1(C1(9)); + x = c.bla(); + y = this.t1(C1(7)); + } + function t1(C1 a) returns (C1) { return a; } + function() returns (C1) { return C1(9); } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(9), u256(7))); + BOOST_CHECK(callContractFunction("nonexisting") == encodeArgs(u256(9))); +} + BOOST_AUTO_TEST_SUITE_END() } From e2c147f6887a3db0d6333a9507962dc55dc91ee0 Mon Sep 17 00:00:00 2001 From: Jan Willem Penterman Date: Tue, 21 Apr 2015 17:00:02 +0200 Subject: [PATCH 56/58] multiple gpu support (and option to use less than maximum cpu threads) --- eth/main.cpp | 38 ++++++++++++++++++++++++-------- libethash-cl/ethash_cl_miner.cpp | 21 ++++++++++++++++++ libethash-cl/ethash_cl_miner.h | 2 ++ libethcore/Ethash.cpp | 10 ++++++++- libethcore/Ethash.h | 14 +++++++----- 5 files changed, 70 insertions(+), 15 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index da8943e46..eabcc2a4d 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -136,6 +136,7 @@ void help() << " -G,--opencl When mining use the GPU via OpenCL." << endl << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-device When mining using -G/--opencl use OpenCL device n (default: 0)." << endl + << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl << "Client networking:" << endl << " --client-name Add a name to your client's version string (default: blank)." << endl << " -b,--bootstrap Connect to the default Ethereum peerserver." << endl @@ -481,7 +482,8 @@ int main(int argc, char** argv) /// Mining options MinerType minerType = MinerType::CPU; unsigned openclPlatform = 0; - unsigned openclDevice = 0; + unsigned openclDevice = 0; + unsigned miningThreads = UINT_MAX; /// File name for import/export. string filename; @@ -601,12 +603,12 @@ int main(int argc, char** argv) else if (arg == "--opencl-platform" && i + 1 < argc) try { openclPlatform= stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } else if (arg == "--opencl-device" && i + 1 < argc) try { openclDevice = stol(argv[++i]); @@ -850,6 +852,17 @@ int main(int argc, char** argv) return -1; } } + else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) + { + try { + miningThreads = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; + } + } else if (arg == "-b" || arg == "--bootstrap") bootstrap = true; else if (arg == "-f" || arg == "--force-mining") @@ -905,9 +918,16 @@ int main(int argc, char** argv) if (sessionSecret) sigKey = KeyPair(sessionSecret); - ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); - ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); + + if (minerType == MinerType::CPU) { + ProofOfWork::CPUMiner::setNumInstances(miningThreads); + } + else if (minerType == MinerType::GPU) { + ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); + ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); + ProofOfWork::GPUMiner::setNumInstances(miningThreads); + } // Two codepaths is necessary since named block require database, but numbered // blocks are superuseful to have when database is already open in another process. if (mode == OperationMode::DAGInit && !(initDAG == LatestBlock || initDAG == PendingBlock)) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 53eabe349..891d3f97d 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -85,6 +85,27 @@ std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _devic return "{ \"platform\": \"" + platforms[platform_num].getInfo() + "\", \"device\": \"" + device.getInfo() + "\", \"version\": \"" + device_version + "\" }"; } +unsigned ethash_cl_miner::get_num_devices(unsigned _platformId) +{ + std::vector platforms; + cl::Platform::get(&platforms); + if (platforms.empty()) + { + debugf("No OpenCL platforms found.\n"); + return 0; + } + + std::vector devices; + unsigned platform_num = std::min(_platformId, platforms.size() - 1); + platforms[platform_num].getDevices(CL_DEVICE_TYPE_ALL, &devices); + if (devices.empty()) + { + debugf("No OpenCL devices found.\n"); + return 0; + } + return devices.size(); +} + void ethash_cl_miner::finish() { if (m_queue()) diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index 3046f037b..21635df91 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -33,6 +33,8 @@ public: bool init(ethash_params const& params, std::function _fillDAG, unsigned workgroup_size = 64, unsigned _platformId = 0, unsigned _deviceId = 0); static std::string platform_info(unsigned _platformId = 0, unsigned _deviceId = 0); + static unsigned get_num_devices(unsigned _platformId = 0); + void finish(); void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 7ff35fd2b..91ba00710 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -264,10 +264,12 @@ private: unsigned Ethash::GPUMiner::s_platformId = 0; unsigned Ethash::GPUMiner::s_deviceId = 0; +unsigned Ethash::GPUMiner::s_numInstances = 1; +unsigned Ethash::CPUMiner::s_numInstances = 1; Ethash::GPUMiner::GPUMiner(ConstructionInfo const& _ci): Miner(_ci), - Worker("gpuminer"), + Worker("gpuminer" + toString(index())), m_hook(new EthashCLHook(this)) { } @@ -308,6 +310,7 @@ void Ethash::GPUMiner::workLoop() auto p = EthashAux::params(m_minerSeed); auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); }; + unsigned device = instances() > 0 ? index() : s_deviceId; m_miner->init(p, cb, 32, s_platformId, s_deviceId); } @@ -331,6 +334,11 @@ std::string Ethash::GPUMiner::platformInfo() return ethash_cl_miner::platform_info(s_platformId, s_deviceId); } +unsigned Ethash::GPUMiner::getNumDevices() +{ + return ethash_cl_miner::get_num_devices(s_platformId); +} + #endif } diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 2bbe7d649..9a66e9865 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -78,17 +78,18 @@ public: static bool preVerify(BlockInfo const& _header); static WorkPackage package(BlockInfo const& _header); static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } + class CPUMiner: public Miner, Worker { public: CPUMiner(ConstructionInfo const& _ci): Miner(_ci), Worker("miner" + toString(index())) {} - static unsigned instances() { return std::thread::hardware_concurrency(); } + static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } static std::string platformInfo(); static void setDefaultPlatform(unsigned) {} static void setDefaultDevice(unsigned) {} - + static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, std::thread::hardware_concurrency()); } protected: void kickOff() override { @@ -100,7 +101,7 @@ public: private: void workLoop() override; - static unsigned s_deviceId; + static unsigned s_numInstances; }; #if ETH_ETHASHCL || !ETH_TRUE @@ -112,11 +113,13 @@ public: GPUMiner(ConstructionInfo const& _ci); ~GPUMiner(); - static unsigned instances() { return 1; } + static unsigned instances() { return s_numInstances > 0 ? s_numInstances : 1; } static std::string platformInfo(); + static unsigned getNumDevices(); static void setDefaultPlatform(unsigned _id) { s_platformId = _id; } static void setDefaultDevice(unsigned _id) { s_deviceId = _id; } - + static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } + protected: void kickOff() override; void pause() override; @@ -133,6 +136,7 @@ public: h256 m_minerSeed; ///< Last seed in m_miner static unsigned s_platformId; static unsigned s_deviceId; + static unsigned s_numInstances; }; #else using GPUMiner = CPUMiner; From 55b9038d6f24ebaef2273e0ab70c8b97cf7ca639 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 21 Apr 2015 17:22:46 +0200 Subject: [PATCH 57/58] More awesome logging stuff. --- alethzero/NatspecHandler.cpp | 2 +- eth/main.cpp | 6 +- libdevcore/Log.cpp | 4 +- libdevcore/Log.h | 111 ++++++++++++++++++++++++++++++++--- libdevcrypto/MemoryDB.cpp | 10 ++-- libdevcrypto/OverlayDB.cpp | 2 +- libdevcrypto/TrieDB.h | 12 ++-- libethcore/EthashAux.cpp | 6 +- libethereum/BlockChain.cpp | 28 +++------ libethereum/BlockQueue.cpp | 4 +- libethereum/Client.cpp | 16 +++-- libevmcore/Assembly.cpp | 2 +- libp2p/Network.cpp | 2 +- libp2p/NodeTable.cpp | 2 +- 14 files changed, 152 insertions(+), 55 deletions(-) diff --git a/alethzero/NatspecHandler.cpp b/alethzero/NatspecHandler.cpp index 27cf00341..ffab6db58 100644 --- a/alethzero/NatspecHandler.cpp +++ b/alethzero/NatspecHandler.cpp @@ -51,7 +51,7 @@ NatspecHandler::~NatspecHandler() void NatspecHandler::add(dev::h256 const& _contractHash, string const& _doc) { m_db->Put(m_writeOptions, _contractHash.ref(), _doc); - cdebug << "Registering NatSpec: " << _contractHash.abridged() << _doc; + cdebug << "Registering NatSpec: " << _contractHash << _doc; } string NatspecHandler::retrieve(dev::h256 const& _contractHash) const diff --git a/eth/main.cpp b/eth/main.cpp index da8943e46..b51a76142 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -370,7 +370,7 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) for (unsigned i = 0; !completed; ++i) { if (current) - cnote << "Mining on PoWhash" << current.headerHash.abridged() << ": " << f.miningProgress(); + cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); else cnote << "Getting work package..."; Json::Value v = rpc.eth_getWork(); @@ -380,12 +380,12 @@ void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) current.headerHash = hh; current.seedHash = h256(v[1].asString()); current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight); - cnote << "Got work package:" << current.headerHash.abridged() << " < " << current.boundary; + cnote << "Got work package:" << current.headerHash << " < " << current.boundary; f.setWork(current); } this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); } - cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash.abridged() << "," << solution.mixHash.abridged() << "] to" << _remote << "..."; + cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "..."; bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash)); if (ok) clog(HappyChannel) << "Submitted and accepted."; diff --git a/libdevcore/Log.cpp b/libdevcore/Log.cpp index c4cacad26..c71b28001 100644 --- a/libdevcore/Log.cpp +++ b/libdevcore/Log.cpp @@ -41,7 +41,9 @@ const char* WarnChannel::name() { return EthOnRed EthBlackBold " ✘"; } const char* NoteChannel::name() { return EthBlue " ℹ"; } const char* DebugChannel::name() { return EthWhite " ◇"; } -LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v) +LogOutputStreamBase::LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing): + m_autospacing(_autospacing), + m_verbosity(_v) { auto it = g_logOverride.find(_info); if ((it != g_logOverride.end() && it->second == true) || (it == g_logOverride.end() && (int)_v <= g_logVerbosity)) diff --git a/libdevcore/Log.h b/libdevcore/Log.h index c8924724b..71c2b3450 100644 --- a/libdevcore/Log.h +++ b/libdevcore/Log.h @@ -26,8 +26,12 @@ #include #include #include +#include #include "vector_ref.h" +#include "Common.h" #include "CommonIO.h" +#include "CommonData.h" +#include "FixedHash.h" #include "Terminal.h" namespace dev @@ -76,35 +80,128 @@ std::string getThreadName(); /// The default logging channels. Each has an associated verbosity and three-letter prefix (name() ). /// Channels should inherit from LogChannel and define name() and verbosity. struct LogChannel { static const char* name(); static const int verbosity = 1; }; -struct LeftChannel: public LogChannel { static const char* name(); }; +struct LeftChannel: public LogChannel { static const char* name(); }; struct RightChannel: public LogChannel { static const char* name(); }; -struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; -struct NoteChannel: public LogChannel { static const char* name(); }; +struct WarnChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; +struct NoteChannel: public LogChannel { static const char* name(); }; struct DebugChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; +enum LogTag +{ + None, + url, + error +}; + class LogOutputStreamBase { public: - LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v); + LogOutputStreamBase(char const* _id, std::type_info const* _info, unsigned _v, bool _autospacing); + + void comment(std::string const& _t) + { + switch (m_logTag) + { + case url: m_sstr << EthNavyUnder; break; + case error: m_sstr << EthRedBold; break; + default:; + } + m_sstr << _t << EthReset; + m_logTag = None; + } + + void append(unsigned long _t) { m_sstr << EthBlue << _t << EthReset; } + void append(long _t) { m_sstr << EthBlue << _t << EthReset; } + void append(unsigned int _t) { m_sstr << EthBlue << _t << EthReset; } + void append(int _t) { m_sstr << EthBlue << _t << EthReset; } + void append(bigint const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(u256 const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(u160 const& _t) { m_sstr << EthNavy << _t << EthReset; } + void append(double _t) { m_sstr << EthBlue << _t << EthReset; } + template void append(FixedHash const& _t) { m_sstr << EthTeal "#" << _t.abridged() << EthReset; } + void append(h160 const& _t) { m_sstr << EthRed "@" << _t.abridged() << EthReset; } + void append(h256 const& _t) { m_sstr << EthCyan "#" << _t.abridged() << EthReset; } + void append(h512 const& _t) { m_sstr << EthTeal "##" << _t.abridged() << EthReset; } + void append(std::string const& _t) { m_sstr << EthGreen "\"" + _t + "\"" EthReset; } + void append(bytes const& _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; } + void append(bytesConstRef _t) { m_sstr << EthYellow "%" << toHex(_t) << EthReset; } + template void append(std::vector const& _t) + { + m_sstr << EthWhite "[" EthReset; + int n = 0; + for (auto const& i: _t) + { + m_sstr << (n++ ? EthWhite ", " EthReset : ""); + append(i); + } + m_sstr << EthWhite "]" EthReset; + } + template void append(std::set const& _t) + { + m_sstr << EthYellow "{" EthReset; + int n = 0; + for (auto const& i: _t) + { + m_sstr << (n++ ? EthYellow ", " EthReset : ""); + append(i); + } + m_sstr << EthYellow "}" EthReset; + } + template void append(std::map const& _t) + { + m_sstr << EthLime "{" EthReset; + int n = 0; + for (auto const& i: _t) + { + m_sstr << (n++ ? EthLime ", " EthReset : ""); + append(i.first); + m_sstr << (n++ ? EthLime ": " EthReset : ""); + append(i.second); + } + m_sstr << EthLime "}" EthReset; + } + template void append(std::pair const& _t) + { + m_sstr << EthPurple "(" EthReset; + append(_t.first); + m_sstr << EthPurple ", " EthReset; + append(_t.second); + m_sstr << EthPurple ")" EthReset; + } + template void append(T const& _t) + { + m_sstr << toString(_t); + } + template void append(boost::asio::ip::tcp::endpoint const& _t) + { + m_sstr << EthNavyUnder "tcp://" << _t << EthReset; + } protected: + bool m_autospacing = false; + unsigned m_verbosity = 0; std::stringstream m_sstr; ///< The accrued log entry. + LogTag m_logTag; }; /// Logging class, iostream-like, that can be shifted to. template -class LogOutputStream: private LogOutputStreamBase +class LogOutputStream: LogOutputStreamBase { public: /// Construct a new object. /// If _term is true the the prefix info is terminated with a ']' character; if not it ends only with a '|' character. - LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity) {} + LogOutputStream(): LogOutputStreamBase(Id::name(), &typeid(Id), Id::verbosity, _AutoSpacing) {} /// Destructor. Posts the accrued log entry to the g_logPost function. ~LogOutputStream() { if (Id::verbosity <= g_logVerbosity) g_logPost(m_sstr.str(), Id::name()); } + LogOutputStream& operator<<(std::string const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; comment(_t); } return *this; } + + LogOutputStream& operator<<(LogTag _t) { m_logTag = _t; return *this; } + /// Shift arbitrary data to the log. Spaces will be added between items as required. - template LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; m_sstr << _t; } return *this; } + template LogOutputStream& operator<<(T const& _t) { if (Id::verbosity <= g_logVerbosity) { if (_AutoSpacing && m_sstr.str().size() && m_sstr.str().back() != ' ') m_sstr << " "; append(_t); } return *this; } }; // Simple cout-like stream objects for accessing common log channels. diff --git a/libdevcrypto/MemoryDB.cpp b/libdevcrypto/MemoryDB.cpp index ab74173c4..a207bb7d6 100644 --- a/libdevcrypto/MemoryDB.cpp +++ b/libdevcrypto/MemoryDB.cpp @@ -49,7 +49,7 @@ std::string MemoryDB::lookup(h256 _h) const if (!m_enforceRefs || (m_refCount.count(it->first) && m_refCount.at(it->first))) return it->second; // else if (m_enforceRefs && m_refCount.count(it->first) && !m_refCount.at(it->first)) -// cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h.abridged(); +// cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h; } return std::string(); } @@ -67,7 +67,7 @@ void MemoryDB::insert(h256 _h, bytesConstRef _v) m_over[_h] = _v.toString(); m_refCount[_h]++; #if ETH_PARANOIA - dbdebug << "INST" << _h.abridged() << "=>" << m_refCount[_h]; + dbdebug << "INST" << _h << "=>" << m_refCount[_h]; #endif } @@ -82,15 +82,15 @@ bool MemoryDB::kill(h256 _h) { // If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously // used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*. - dbdebug << "NOKILL-WAS" << _h.abridged(); + dbdebug << "NOKILL-WAS" << _h; return false; } - dbdebug << "KILL" << _h.abridged() << "=>" << m_refCount[_h]; + dbdebug << "KILL" << _h << "=>" << m_refCount[_h]; return true; } else { - dbdebug << "NOKILL" << _h.abridged(); + dbdebug << "NOKILL" << _h; return false; } #else diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp index 5f8aea667..91f73ad49 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -103,7 +103,7 @@ void OverlayDB::kill(h256 _h) if (m_db) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); if (ret.empty()) - cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h.abridged(); + cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h; } #else MemoryDB::kill(_h); diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h index 68a2c248d..a707c30f0 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcrypto/TrieDB.h @@ -120,14 +120,14 @@ public: if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out)) { if (_out) - (*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2 ") << sha3(_r.data()).abridged() << ": " << _r << "\n"; + (*_out) << std::string(_indent * 2, ' ') << (_wasExt ? "!2 " : "2 ") << sha3(_r.data()) << ": " << _r << "\n"; if (!isLeaf(_r)) // don't go down leaves descendEntry(_r[1], _keyMask, true, _out, _indent + 1); } else if (_r.isList() && _r.itemCount() == 17) { if (_out) - (*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()).abridged() << ": " << _r << "\n"; + (*_out) << std::string(_indent * 2, ' ') << "17 " << sha3(_r.data()) << ": " << _r << "\n"; for (unsigned i = 0; i < 16; ++i) if (!_r[i].isEmpty()) // 16 branches are allowed to be empty descendEntry(_r[i], _keyMask, false, _out, _indent + 1); @@ -779,7 +779,7 @@ template std::string GenericTrieDB::atAux(RLP const& _here, Nibbl template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSlice _k, bytesConstRef _v, bool _inLine) { #if ETH_PARANOIA - tdebug << "mergeAt " << _orig << _k << sha3(_orig.data()).abridged(); + tdebug << "mergeAt " << _orig << _k << sha3(_orig.data()); #endif // The caller will make sure that the bytes are inserted properly. @@ -854,7 +854,7 @@ template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSli template void GenericTrieDB::mergeAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k, bytesConstRef _v) { #if ETH_PARANOIA - tdebug << "mergeAtAux " << _orig << _k << sha3(_orig.data()).abridged() << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash().abridged() : std::string()); + tdebug << "mergeAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash() : std::string()); #endif RLP r = _orig; @@ -902,7 +902,7 @@ template std::string GenericTrieDB::deref(RLP const& _n) const template bytes GenericTrieDB::deleteAt(RLP const& _orig, NibbleSlice _k) { #if ETH_PARANOIA - tdebug << "deleteAt " << _orig << _k << sha3(_orig.data()).abridged(); + tdebug << "deleteAt " << _orig << _k << sha3(_orig.data()); #endif // The caller will make sure that the bytes are inserted properly. @@ -1009,7 +1009,7 @@ template bytes GenericTrieDB::deleteAt(RLP const& _orig, NibbleSl template bool GenericTrieDB::deleteAtAux(RLPStream& _out, RLP const& _orig, NibbleSlice _k) { #if ETH_PARANOIA - tdebug << "deleteAtAux " << _orig << _k << sha3(_orig.data()).abridged() << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash().abridged() : std::string()); + tdebug << "deleteAtAux " << _orig << _k << sha3(_orig.data()) << ((_orig.isData() && _orig.size() <= 32) ? _orig.toHash() : std::string()); #endif bytes b = _orig.isEmpty() ? bytes() : deleteAt(_orig.isList() ? _orig : RLP(node(_orig.toHash())), _k); diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 750d80082..44064cde6 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -79,7 +79,7 @@ h256 EthashAux::seedHash(unsigned _number) for (; n <= epoch; ++n, ret = sha3(ret)) { get()->m_seedHashes[n] = ret; -// cdebug << "Epoch" << n << "is" << ret.abridged(); +// cdebug << "Epoch" << n << "is" << ret; } } return get()->m_seedHashes[epoch]; @@ -95,12 +95,12 @@ ethash_params EthashAux::params(h256 const& _seedHash) } catch (...) { -// cdebug << "Searching for seedHash " << _seedHash.abridged(); +// cdebug << "Searching for seedHash " << _seedHash; for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {} if (epoch == 2048) { std::ostringstream error; - error << "apparent block number for " << _seedHash.abridged() << " is too high; max is " << (ETHASH_EPOCH_LENGTH * 2048); + error << "apparent block number for " << _seedHash << " is too high; max is " << (ETHASH_EPOCH_LENGTH * 2048); throw std::invalid_argument(error.str()); } } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 8bba5ff1b..46e4b9adf 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -247,7 +247,7 @@ void BlockChain::rebuild(std::string const& _path, std::function parent is" << bi.parentHash.abridged() << "; expected" << lastHash.abridged() << "#" << (d - 1); + cwarn << "DISJOINT CHAIN DETECTED; " << bi.hash() << "#" << d << " -> parent is" << bi.parentHash << "; expected" << lastHash << "#" << (d - 1); return; } lastHash = bi.hash(); @@ -280,16 +280,6 @@ bool contains(T const& _t, V const& _v) return false; } -inline string toString(h256s const& _bs) -{ - ostringstream out; - out << "[ "; - for (auto i: _bs) - out << i.abridged() << ", "; - out << "]"; - return out.str(); -} - LastHashes BlockChain::lastHashes(unsigned _n) const { Guard l(x_lastLastHashes); @@ -323,14 +313,14 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st } catch (dev::eth::UnknownParent) { - cwarn << "ODD: Import queue contains block with unknown parent." << boost::current_exception_diagnostic_information(); + cwarn << "ODD: Import queue contains block with unknown parent." << error << boost::current_exception_diagnostic_information(); // NOTE: don't reimport since the queue should guarantee everything in the right order. // Can't continue - chain bad. badBlocks.push_back(BlockInfo::headerHash(block)); } catch (Exception const& _e) { - cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << diagnostic_information(_e); + cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << error << diagnostic_information(_e); // NOTE: don't reimport since the queue should guarantee everything in the right order. // Can't continue - chain bad. badBlocks.push_back(BlockInfo::headerHash(block)); @@ -427,7 +417,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import BOOST_THROW_EXCEPTION(FutureTime()); } - clog(BlockChainChat) << "Attempting import of " << bi.hash().abridged() << "..."; + clog(BlockChainChat) << "Attempting import of " << bi.hash() << "..."; #if ETH_TIMED_IMPORTS preliminaryChecks = t.elapsed(); @@ -704,7 +694,7 @@ void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end) tuple BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const { -// cdebug << "treeRoute" << _from.abridged() << "..." << _to.abridged(); +// cdebug << "treeRoute" << _from << "..." << _to; if (!_from || !_to) return make_tuple(h256s(), h256(), 0); h256s ret; @@ -719,7 +709,7 @@ tuple BlockChain::treeRoute(h256 const& _from, h256 const ret.push_back(from); from = details(from).parent; fn--; -// cdebug << "from:" << fn << _from.abridged(); +// cdebug << "from:" << fn << _from; } h256 to = _to; while (fn < tn) @@ -728,7 +718,7 @@ tuple BlockChain::treeRoute(h256 const& _from, h256 const back.push_back(to); to = details(to).parent; tn--; -// cdebug << "to:" << tn << _to.abridged(); +// cdebug << "to:" << tn << _to; } for (;; from = details(from).parent, to = details(to).parent) { @@ -738,7 +728,7 @@ tuple BlockChain::treeRoute(h256 const& _from, h256 const back.push_back(to); fn--; tn--; -// cdebug << "from:" << fn << _from.abridged() << "; to:" << tn << _to.abridged(); +// cdebug << "from:" << fn << _from << "; to:" << tn << _to; if (from == to) break; if (!from) @@ -1010,7 +1000,7 @@ bytes BlockChain::block(h256 const& _hash) const if (d.empty()) { - cwarn << "Couldn't find requested block:" << _hash.abridged(); + cwarn << "Couldn't find requested block:" << _hash; return bytes(); } diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index b056dc74f..63df3f9fb 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -36,7 +36,7 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo // Check if we already know this block. h256 h = BlockInfo::headerHash(_block); - cblockq << "Queuing block" << h.abridged() << "for import..."; + cblockq << "Queuing block" << h << "for import..."; UpgradableGuard l(m_lock); @@ -95,7 +95,7 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo else if (!m_readySet.count(bi.parentHash) && !m_drainingSet.count(bi.parentHash) && !_bc.isKnown(bi.parentHash)) { // We don't know the parent (yet) - queue it up for later. It'll get resent to us if we find out about its ancestry later on. - cblockq << "OK - queued as unknown parent:" << bi.parentHash.abridged(); + cblockq << "OK - queued as unknown parent:" << bi.parentHash; m_unknown.insert(make_pair(bi.parentHash, make_pair(h, _block.toBytes()))); m_unknownSet.insert(h); diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index b9ddcdbaa..00d4ca021 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -291,7 +291,15 @@ static string filtersToString(T const& _fs) ret << "{"; unsigned i = 0; for (h256 const& f: _fs) - ret << (i++ ? ", " : "") << (f == PendingChangedFilter ? "pending" : f == ChainChangedFilter ? "chain" : f.abridged()); + { + ret << (i++ ? ", " : ""); + if (f == PendingChangedFilter) + ret << url << "pending"; + else if (f == ChainChangedFilter) + ret << url << "chain"; + else + ret << f; + } ret << "}"; return ret.str(); } @@ -475,7 +483,7 @@ void Client::onChainChanged(ImportRoute const& _ir) // insert transactions that we are declaring the dead part of the chain for (auto const& h: _ir.second) { - clog(ClientNote) << "Dead block:" << h.abridged(); + clog(ClientNote) << "Dead block:" << h; for (auto const& t: m_bc.transactions(h)) { clog(ClientNote) << "Resubmitting transaction " << Transaction(t, CheckTransaction::None); @@ -486,10 +494,10 @@ void Client::onChainChanged(ImportRoute const& _ir) // remove transactions from m_tq nicely rather than relying on out of date nonce later on. for (auto const& h: _ir.first) { - clog(ClientChat) << "Live block:" << h.abridged(); + clog(ClientChat) << "Live block:" << h; for (auto const& th: m_bc.transactionHashes(h)) { - clog(ClientNote) << "Safely dropping transaction " << th.abridged(); + clog(ClientNote) << "Safely dropping transaction " << th; m_tq.drop(th); } } diff --git a/libevmcore/Assembly.cpp b/libevmcore/Assembly.cpp index ae8567e2a..eac946230 100644 --- a/libevmcore/Assembly.cpp +++ b/libevmcore/Assembly.cpp @@ -311,7 +311,7 @@ Assembly& Assembly::optimise(bool _enable) unsigned total = 0; for (unsigned count = 1; count > 0; total += count) { - copt << *this; + copt << toString(*this); count = 0; copt << "Performing control flow analysis..."; diff --git a/libp2p/Network.cpp b/libp2p/Network.cpp index 5702fbce7..1c780c5e9 100644 --- a/libp2p/Network.cpp +++ b/libp2p/Network.cpp @@ -228,7 +228,7 @@ bi::tcp::endpoint Network::resolveHost(string const& _addr) bi::tcp::resolver r(s_resolverIoService); auto it = r.resolve({split[0], toString(port)}, ec); if (ec) - clog(NetWarn) << "Error resolving host address " << _addr << ":" << ec.message(); + clog(NetWarn) << "Error resolving host address..." << url << _addr << ":" << error << ec.message(); else ep = *it; } diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 35db7fbac..4f81e42b9 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -87,7 +87,7 @@ shared_ptr NodeTable::addNode(Node const& _node) // we handle when tcp endpoint is 0 below if (_node.endpoint.address.to_string() == "0.0.0.0") { - clog(NodeTableWarn) << "addNode Failed. Invalid UDP address 0.0.0.0 for" << _node.id.abridged(); + clog(NodeTableWarn) << "addNode Failed. Invalid UDP address" << url << "0.0.0.0" << "for" << _node.id; return move(shared_ptr()); } From 6da67f1581b100435724fac7edbc679a17e735da Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Tue, 21 Apr 2015 17:26:54 +0200 Subject: [PATCH 58/58] Fix style. Fix device id. --- eth/main.cpp | 11 ++++++----- libethcore/Ethash.cpp | 5 +++-- libethereum/BlockQueue.cpp | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/eth/main.cpp b/eth/main.cpp index 9839ba4f2..2d79f4954 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -482,7 +482,7 @@ int main(int argc, char** argv) /// Mining options MinerType minerType = MinerType::CPU; unsigned openclPlatform = 0; - unsigned openclDevice = 0; + unsigned openclDevice = 0; unsigned miningThreads = UINT_MAX; /// File name for import/export. @@ -602,7 +602,7 @@ int main(int argc, char** argv) } else if (arg == "--opencl-platform" && i + 1 < argc) try { - openclPlatform= stol(argv[++i]); + openclPlatform = stol(argv[++i]); } catch (...) { @@ -920,14 +920,15 @@ int main(int argc, char** argv) - if (minerType == MinerType::CPU) { + if (minerType == MinerType::CPU) ProofOfWork::CPUMiner::setNumInstances(miningThreads); - } - else if (minerType == MinerType::GPU) { + else if (minerType == MinerType::GPU) + { ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); ProofOfWork::GPUMiner::setNumInstances(miningThreads); } + // Two codepaths is necessary since named block require database, but numbered // blocks are superuseful to have when database is already open in another process. if (mode == OperationMode::DAGInit && !(initDAG == LatestBlock || initDAG == PendingBlock)) diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 91ba00710..c40ce2625 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -121,6 +121,8 @@ bool Ethash::verify(BlockInfo const& _header) return slow; } +unsigned Ethash::CPUMiner::s_numInstances = 1; + void Ethash::CPUMiner::workLoop() { auto tid = std::this_thread::get_id(); @@ -265,7 +267,6 @@ private: unsigned Ethash::GPUMiner::s_platformId = 0; unsigned Ethash::GPUMiner::s_deviceId = 0; unsigned Ethash::GPUMiner::s_numInstances = 1; -unsigned Ethash::CPUMiner::s_numInstances = 1; Ethash::GPUMiner::GPUMiner(ConstructionInfo const& _ci): Miner(_ci), @@ -311,7 +312,7 @@ void Ethash::GPUMiner::workLoop() auto p = EthashAux::params(m_minerSeed); auto cb = [&](void* d) { EthashAux::full(m_minerSeed, bytesRef((byte*)d, p.full_size)); }; unsigned device = instances() > 0 ? index() : s_deviceId; - m_miner->init(p, cb, 32, s_platformId, s_deviceId); + m_miner->init(p, cb, 32, s_platformId, device); } uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index f8a07bd99..44ddda637 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -30,7 +30,7 @@ using namespace dev; using namespace dev::eth; #ifdef _WIN32 -const char* BlockQueueChannel::name() { return EthOrange "[]->"; } +const char* BlockQueueChannel::name() { return EthOrange "[]>"; } #else const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; } #endif