From 1a20295e163e606c949a95a2839decce47e2a330 Mon Sep 17 00:00:00 2001 From: Stefan Thomas Date: Tue, 23 Oct 2012 17:52:18 +0200 Subject: [PATCH 1/6] Remove tx invalid assertion - exception should be enough. Jed's words, not mine. ;) --- src/SerializedTransaction.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index dbe3ffbf20..a7c26357a1 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -25,7 +25,6 @@ SerializedTransaction::SerializedTransaction(const STObject& object) : STObject( throw std::runtime_error("invalid transaction type"); if (!setType(mFormat->elements)) { - assert(false); throw std::runtime_error("transaction not valid"); } } From 67c87a9d13dbbe3eb95e205d91d4cf74937416e0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Oct 2012 11:05:17 -0700 Subject: [PATCH 2/6] Add a few test vectors. --- src/DeterministicKeys.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/DeterministicKeys.cpp b/src/DeterministicKeys.cpp index 2c5241a58b..ce2a9cd7f5 100644 --- a/src/DeterministicKeys.cpp +++ b/src/DeterministicKeys.cpp @@ -9,7 +9,10 @@ // Functions to add CKey support for deterministic EC keys +#include + #include "Serializer.h" +#include "Log.h" // <-- seed uint128 CKey::PassPhraseToKey(const std::string& passPhrase) @@ -304,4 +307,34 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey(const NewcoinAddress& pubGen, cons return pkey; } +BOOST_AUTO_TEST_SUITE(DeterministicKeys_test) + +BOOST_AUTO_TEST_CASE(DeterminsticKeys_test1) +{ + Log(lsDEBUG) << "Beginning deterministic key test"; + + uint128 seed1, seed2; + seed1.SetHex("71ED064155FFADFA38782C5E0158CB26"); + seed2.SetHex("CF0C3BE4485961858C4198515AE5B965"); + CKey root1(seed1), root2(seed2); + + uint256 priv1, priv2; + root1.GetPrivateKeyU(priv1); + root2.GetPrivateKeyU(priv2); + + if (priv1.GetHex() != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8") + BOOST_FAIL("Incorrect private key for generator"); + if (priv2.GetHex() != "98BC2EACB26EB021D1A6293C044D88BA2F0B6729A2772DEEBF2E21A263C1740B") + BOOST_FAIL("Incorrect private key for generator"); + + NewcoinAddress nSeed; + nSeed.setSeed(seed1); + if (nSeed.humanSeed() != "shHM53KPZ87Gwdqarm1bAmPeXg8Tn") + BOOST_FAIL("Incorrect human seed"); + if (nSeed.humanSeed1751() != "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH") + BOOST_FAIL("Incorrect 1751 seed"); +} + +BOOST_AUTO_TEST_SUITE_END(); + // vim:ts=4 From 756e628f93313a379b20a879630fa7590ec60ace Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Oct 2012 11:22:37 -0700 Subject: [PATCH 3/6] Add an STObject::operator== that is sensible. --- src/SerializedObject.cpp | 37 ++++++++++++++++++++++++++++++++++++- src/SerializedObject.h | 3 +++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index d6bce836cb..e69fd32d66 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -792,6 +792,42 @@ Json::Value STObject::getJson(int options) const return ret; } +bool STObject::operator==(const STObject& obj) const +{ // This is not particularly efficient, and only compares data elements with binary representations + int matches = 0; + BOOST_FOREACH(const SerializedType& t, mData) + if ((t.getSType() != STI_NOTPRESENT) && t.getFName().isBinary()) + { // each present field must have a matching field + bool match = false; + BOOST_FOREACH(const SerializedType& t2, obj.mData) + if (t.getFName() == t2.getFName()) + { + if (t2 != t) + return false; + match = true; + ++matches; + break; + } + if (!match) + { + Log(lsTRACE) << "STObject::operator==: no match for " << t.getFName().getName(); + return false; + } + } + + int fields = 0; + BOOST_FOREACH(const SerializedType& t2, obj.mData) + if ((t2.getSType() != STI_NOTPRESENT) && t2.getFName().isBinary()) + ++fields; + + if (fields != matches) + { + Log(lsTRACE) << "STObject::operator==: " << fields << " fields, " << matches << " matches"; + return false; + } + return true; +} + Json::Value STVector256::getJson(int options) const { Json::Value ret(Json::arrayValue); @@ -1246,7 +1282,6 @@ BOOST_AUTO_TEST_CASE( FieldManipulation_test ) if (object1.getFieldVL(sfTestVL) != j) BOOST_FAIL("STObject error"); if (object3.getFieldVL(sfTestVL) != j) BOOST_FAIL("STObject error"); } - } BOOST_AUTO_TEST_SUITE_END(); diff --git a/src/SerializedObject.h b/src/SerializedObject.h index 0c94259174..e1f7b0021d 100644 --- a/src/SerializedObject.h +++ b/src/SerializedObject.h @@ -148,6 +148,9 @@ public: { return makeDefaultObject(STI_NOTPRESENT, name); } static std::auto_ptr makeDefaultObject(SField::ref name) { return makeDefaultObject(name.fieldType, name); } + + bool operator==(const STObject& o) const; + bool operator!=(const STObject& o) const { return ! (*this == o); } }; class STArray : public SerializedType From bb4cc37e5845a816cd56b01fb9930b55ce2e0673 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Oct 2012 11:22:56 -0700 Subject: [PATCH 4/6] Remove chatty debug. --- src/Amount.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Amount.cpp b/src/Amount.cpp index 8abd8bbfc4..2280d70326 100644 --- a/src/Amount.cpp +++ b/src/Amount.cpp @@ -166,8 +166,6 @@ STAmount::STAmount(SField::ref n, const Json::Value& v) } else throw std::runtime_error("invalid amount type"); - - cLog(lsTRACE) << "Parsed: " << this->getJson(0); } std::string STAmount::createHumanCurrency(const uint160& uCurrency) From 61de7a974613555508b14bc21ce45e63d4e94737 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Oct 2012 11:23:09 -0700 Subject: [PATCH 5/6] Clean up this unit test. --- src/SerializedTransaction.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/SerializedTransaction.cpp b/src/SerializedTransaction.cpp index a7c26357a1..53f35ba098 100644 --- a/src/SerializedTransaction.cpp +++ b/src/SerializedTransaction.cpp @@ -202,8 +202,8 @@ BOOST_AUTO_TEST_CASE( STrans_test ) NewcoinAddress seed; seed.setSeedRandom(); NewcoinAddress generator = NewcoinAddress::createGeneratorPublic(seed); - NewcoinAddress publicAcct = NewcoinAddress::createAccountPublic(generator, 1); - NewcoinAddress privateAcct = NewcoinAddress::createAccountPrivate(generator, seed, 1); + NewcoinAddress publicAcct = NewcoinAddress::createAccountPublic(generator, 1); + NewcoinAddress privateAcct = NewcoinAddress::createAccountPrivate(generator, seed, 1); SerializedTransaction j(ttCLAIM); j.setSourceAccount(publicAcct); @@ -223,10 +223,15 @@ BOOST_AUTO_TEST_CASE( STrans_test ) Log(lsFATAL) << copy.getJson(0); BOOST_FAIL("Transaction fails serialize/deserialize test"); } - Log(lsINFO) << "ORIG: " << j.getJson(0); std::auto_ptr new_obj = STObject::parseJson(j.getJson(0), sfGeneric); if (new_obj.get() == NULL) BOOST_FAIL("Unable to build object from json"); - Log(lsINFO) << "BUILT " << new_obj->getJson(0); + + if (STObject(j) != *new_obj) + { + Log(lsINFO) << "ORIG: " << j.getJson(0); + Log(lsINFO) << "BUILT " << new_obj->getJson(0); + BOOST_FAIL("Built a different transaction"); + } } BOOST_AUTO_TEST_SUITE_END(); From 6da5d508a77de9dc1c4f92475313a460043685f0 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 23 Oct 2012 11:49:16 -0700 Subject: [PATCH 6/6] Improve the warning messages when STObject::setType fails. --- src/SerializedObject.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/SerializedObject.cpp b/src/SerializedObject.cpp index e69fd32d66..0742dcbfe7 100644 --- a/src/SerializedObject.cpp +++ b/src/SerializedObject.cpp @@ -164,7 +164,8 @@ bool STObject::setType(const std::vector &type) { if (elem->flags != SOE_OPTIONAL) { - cLog(lsWARNING) << "setType !valid missing " << elem->e_field.fieldName; + cLog(lsWARNING) << "setType( " << getFName().getName() << ") invalid missing " + << elem->e_field.fieldName; valid = false; } newData.push_back(makeNonPresentObject(elem->e_field)); @@ -178,7 +179,8 @@ bool STObject::setType(const std::vector &type) { if (!t.getFName().isDiscardable()) { - cLog(lsWARNING) << "setType !valid leftover: " << t.getFName().getName(); + cLog(lsWARNING) << "setType( " << getFName().getName() << ") invalid leftover " + << t.getFName().getName(); valid = false; } }