From c26d60579add9d3c82d4fda8e0cf87c1bc9ed682 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 15:48:14 -0700 Subject: [PATCH 1/6] Change config to use single entry for validation. --- newcoind.cfg | 18 ++++++------------ src/Config.cpp | 7 +++---- src/Config.h | 4 ++-- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/newcoind.cfg b/newcoind.cfg index 44810f175f..e34c6b2490 100644 --- a/newcoind.cfg +++ b/newcoind.cfg @@ -49,18 +49,12 @@ # 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0] # # [validation_seed]: -# This is the seed used to generate the validation public/private key pair. -# This representation has a checksum and is the recommended form for transmission. -# -# [validation_password]: -# This is the password used to generate the validation public/private key pair. -# This representation is the form for providing a pass phrase. -# -# [validation_key]: -# To perform validation, either this section or the [validation_password] section must be provided. -# This representation is the form for human memorization (RFC 1751). -# -# Example: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE +# To perform validation, this section should contain either a validation seed or key. +# The validation seed is used to generate the validation public/private key pair. +# To obtain a validation seed, use the validation_create command. +# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE +# shfArahZT9Q9ckTf3s1psJ7C7qzVN + # [peer_ip] 0.0.0.0 diff --git a/src/Config.cpp b/src/Config.cpp index f7bd74751c..44a12f6a50 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -18,8 +18,7 @@ #define SECTION_RPC_IP "rpc_ip" #define SECTION_RPC_PORT "rpc_port" #define SECTION_RPC_ALLOW_REMOTE "rpc_allow_remote" -#define SECTION_VALIDATION_PASSWORD "validation_password" -#define SECTION_VALIDATION_KEY "validation_key" +#define SECTION_VALIDATION_SEED "validation_seed" #define SECTION_PEER_SSL_CIPHER_LIST "peer_ssl_cipher_list" #define SECTION_PEER_SCAN_INTERVAL_MIN "peer_scan_interval_min" #define SECTION_PEER_START_MAX "peer_start_max" @@ -180,8 +179,8 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_RPC_ALLOW_REMOTE, strTemp)) RPC_ALLOW_REMOTE = boost::lexical_cast(strTemp); - (void) sectionSingleB(secConfig, SECTION_VALIDATION_PASSWORD, VALIDATION_PASSWORD); - (void) sectionSingleB(secConfig, SECTION_VALIDATION_KEY, VALIDATION_KEY); + if (sectionSingleB(secConfig, SECTION_VALIDATION_SEED, strTemp)) + VALIDATION_SEED.setFamilySeedGeneric(strTemp); (void) sectionSingleB(secConfig, SECTION_PEER_SSL_CIPHER_LIST, PEER_SSL_CIPHER_LIST); if (sectionSingleB(secConfig, SECTION_PEER_SCAN_INTERVAL_MIN, strTemp)) diff --git a/src/Config.h b/src/Config.h index 7b754d4a37..4ef20c81b9 100644 --- a/src/Config.h +++ b/src/Config.h @@ -3,6 +3,7 @@ #include "types.h" #include "SerializedTypes.h" +#include "NewcoinAddress.h" #include #include @@ -78,8 +79,7 @@ public: bool RPC_ALLOW_REMOTE; // Validation - std::string VALIDATION_PASSWORD; - std::string VALIDATION_KEY; + NewcoinAddress VALIDATION_SEED; // Fees uint64 FEE_DEFAULT; // Default fee. From 2866c6e46d36670043a5bcd3f3650f8b797c0145 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 15:49:35 -0700 Subject: [PATCH 2/6] Add support for hashing uint160. --- src/SHAMap.cpp | 11 +++++++++++ src/SHAMap.h | 1 + 2 files changed, 12 insertions(+) diff --git a/src/SHAMap.cpp b/src/SHAMap.cpp index c84eec80e0..ac600171e5 100644 --- a/src/SHAMap.cpp +++ b/src/SHAMap.cpp @@ -18,16 +18,27 @@ std::size_t hash_value(const SHAMapNode& mn) { std::size_t seed = theApp->getNonceST(); + boost::hash_combine(seed, mn.getDepth()); + return mn.getNodeID().hash_combine(seed); } std::size_t hash_value(const uint256& u) { std::size_t seed = theApp->getNonceST(); + return u.hash_combine(seed); } +std::size_t hash_value(const uint160& u) +{ + std::size_t seed = theApp->getNonceST(); + + return u.hash_combine(seed); +} + + SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying) { root = boost::make_shared(mSeq, SHAMapNode(0, uint256())); diff --git a/src/SHAMap.h b/src/SHAMap.h index b9090c963d..0588096c7a 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -78,6 +78,7 @@ public: extern std::size_t hash_value(const SHAMapNode& mn); extern std::size_t hash_value(const uint256& u); +extern std::size_t hash_value(const uint160& u); class SHAMapItem { // an item stored in a SHAMap From 5aaeef3a5050e1abe7606d8d060ee9f36d891f60 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 15:50:21 -0700 Subject: [PATCH 3/6] Add getNodeID to NewcoinAddress. --- src/NewcoinAddress.cpp | 62 ++++++++++++++++++------------------------ src/NewcoinAddress.h | 12 ++++---- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/NewcoinAddress.cpp b/src/NewcoinAddress.cpp index f31036963e..d80e9254f4 100644 --- a/src/NewcoinAddress.cpp +++ b/src/NewcoinAddress.cpp @@ -58,7 +58,7 @@ void NewcoinAddress::clear() // NodePublic // -NewcoinAddress NewcoinAddress::createNodePublic(NewcoinAddress& naSeed) +NewcoinAddress NewcoinAddress::createNodePublic(const NewcoinAddress& naSeed) { CKey ckSeed(naSeed.getFamilySeed()); NewcoinAddress naNew; @@ -69,6 +69,29 @@ NewcoinAddress NewcoinAddress::createNodePublic(NewcoinAddress& naSeed) return naNew; } +NewcoinAddress NewcoinAddress::createNodePublic(const std::vector& vPublic) +{ + NewcoinAddress naNew; + + naNew.setNodePublic(vPublic); + + return naNew; +} + +uint160 NewcoinAddress::getNodeID() const +{ + switch (nVersion) { + case VER_NONE: + throw std::runtime_error("unset source"); + + case VER_NODE_PUBLIC: + // Note, we are encoding the left. + return Hash160(vchData); + + default: + throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion))); + } +} const std::vector& NewcoinAddress::getNodePublic() const { switch (nVersion) { @@ -136,7 +159,7 @@ bool NewcoinAddress::verifyNodePublic(const uint256& hash, const std::string& st // NodePrivate // -NewcoinAddress NewcoinAddress::createNodePrivate(NewcoinAddress& naSeed) +NewcoinAddress NewcoinAddress::createNodePrivate(const NewcoinAddress& naSeed) { uint256 uPrivKey; NewcoinAddress naNew; @@ -229,7 +252,7 @@ uint160 NewcoinAddress::getAccountID() const return uint160(vchData); case VER_ACCOUNT_PUBLIC: - // Note, we are encoding the left or right. + // Note, we are encoding the left. return Hash160(vchData); default: @@ -595,13 +618,6 @@ void NewcoinAddress::setFamilyGenerator(const std::vector& vPubli SetData(VER_FAMILY_GENERATOR, vPublic); } -#if 0 -void NewcoinAddress::setFamilyGenerator(const NewcoinAddress& seed) -{ - seed.seedInfo(this, 0); -} -#endif - NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSeed) { CKey ckSeed(naSeed.getFamilySeed()); @@ -616,21 +632,6 @@ NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSee // Family Seed // -#if 0 -// --> dstGenerator: Set the public generator from our seed. -void NewcoinAddress::seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const -{ - CKey pubkey = CKey(getFamilySeed()); - - if (dstGenerator) { - dstGenerator->setFamilyGenerator(pubkey.GetPubKey()); - } - - if (dstPrivateKey) - *dstPrivateKey = pubkey.GetSecretBN(); -} -#endif - uint128 NewcoinAddress::getFamilySeed() const { switch (nVersion) { @@ -645,17 +646,6 @@ uint128 NewcoinAddress::getFamilySeed() const } } -#if 0 -BIGNUM* NewcoinAddress::getFamilyPrivateKey() const -{ - BIGNUM* ret; - - seedInfo(0, &ret); - - return ret; -} -#endif - std::string NewcoinAddress::humanFamilySeed1751() const { switch (nVersion) { diff --git a/src/NewcoinAddress.h b/src/NewcoinAddress.h index 284e35c680..be0938d939 100644 --- a/src/NewcoinAddress.h +++ b/src/NewcoinAddress.h @@ -7,6 +7,7 @@ // // Used to hold addresses and parse and produce human formats. // +// XXX This needs to be reworked to store data in uint160 and uint256. Conversion to CBase58Data should happen as needed. class NewcoinAddress : public CBase58Data { private: @@ -21,8 +22,6 @@ private: VER_FAMILY_SEED = 33, } VersionEncoding; -// void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const; - public: NewcoinAddress(); @@ -31,8 +30,9 @@ public: void clear(); // - // Node Public + // Node Public - Also used for Validators // + uint160 getNodeID() const; const std::vector& getNodePublic() const; std::string humanNodePublic() const; @@ -42,7 +42,8 @@ public: bool verifyNodePublic(const uint256& hash, const std::vector& vchSig) const; bool verifyNodePublic(const uint256& hash, const std::string& strSig) const; - static NewcoinAddress createNodePublic(NewcoinAddress& naSeed); + static NewcoinAddress createNodePublic(const NewcoinAddress& naSeed); + static NewcoinAddress createNodePublic(const std::vector& vPublic); // // Node Private @@ -57,7 +58,7 @@ public: void setNodePrivate(uint256 hash256); void signNodePrivate(const uint256& hash, std::vector& vchSig) const; - static NewcoinAddress createNodePrivate(NewcoinAddress& naSeed); + static NewcoinAddress createNodePrivate(const NewcoinAddress& naSeed); // // Accounts IDs @@ -159,7 +160,6 @@ public: // Family Seeds // Clients must disallow reconizable entries from being seeds. uint128 getFamilySeed() const; - // BIGNUM* getFamilyPrivateKey() const; std::string humanFamilySeed() const; std::string humanFamilySeed1751() const; From 368e5a0accb90104ed12c792bb52cfe6291e1d57 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 15:51:30 -0700 Subject: [PATCH 4/6] Have consensus use the config for validation and use uint160 for peerIDs. --- src/LedgerConsensus.cpp | 24 +++++++++++------------ src/LedgerConsensus.h | 8 ++++---- src/LedgerProposal.cpp | 38 +++++++++++++++++++++++++----------- src/LedgerProposal.h | 21 ++++++++++++-------- src/SerializedValidation.cpp | 18 ++++++++++------- src/SerializedValidation.h | 3 ++- 6 files changed, 69 insertions(+), 43 deletions(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 58385ca93e..bf17cd74a9 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -118,10 +118,10 @@ bool TransactionAcquire::takeNodes(const std::list& nodeIDs, } } -void LCTransaction::setVote(const uint256& peer, bool votesYes) +void LCTransaction::setVote(const uint160& peer, bool votesYes) { - std::pair::iterator, bool> res = - mVotes.insert(std::make_pair(peer, votesYes)); + std::pair::iterator, bool> res = + mVotes.insert(std::make_pair(peer, votesYes)); if (res.second) { // new vote @@ -182,14 +182,13 @@ LedgerConsensus::LedgerConsensus(Ledger::pointer previousLedger, uint32 closeTim void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger) { - CKey::pointer nodePrivKey = boost::make_shared(); - nodePrivKey->MakeNewKey(); // FIXME + // XXX Don't even start if no VALIDATION_SEED. SHAMap::pointer initialSet = initialLedger->peekTransactionMap()->snapShot(false); uint256 txSet = initialSet->getHash(); assert (initialLedger->getParentHash() == mPreviousLedger->getHash()); - mOurPosition = boost::make_shared(nodePrivKey, initialLedger->getParentHash(), txSet); + mOurPosition = boost::make_shared(theConfig.VALIDATION_SEED, initialLedger->getParentHash(), txSet); mapComplete(txSet, initialSet); propose(std::vector(), std::vector()); } @@ -234,8 +233,8 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map) mComplete[map->getHash()] = map; // Adjust tracking for each peer that takes this position - std::vector peers; - for (boost::unordered_map::iterator it = mPeerPositions.begin(), + std::vector peers; + for (boost::unordered_map::iterator it = mPeerPositions.begin(), end = mPeerPositions.end(); it != end; ++it) { if (it->second->getCurrentHash() == map->getHash()) @@ -256,13 +255,13 @@ void LedgerConsensus::sendHaveTxSet(const uint256& hash, bool direct) theApp->getConnectionPool().relayMessage(NULL, packet); } -void LedgerConsensus::adjustCount(SHAMap::pointer map, const std::vector& peers) +void LedgerConsensus::adjustCount(SHAMap::pointer map, const std::vector& peers) { // Adjust the counts on all disputed transactions based on the set of peers taking this position for (boost::unordered_map::iterator it = mDisputes.begin(), end = mDisputes.end(); it != end; ++it) { bool setHas = map->hasItem(it->second->getTransactionID()); - for(std::vector::const_iterator pit = peers.begin(), pend = peers.end(); pit != pend; ++pit) + for(std::vector::const_iterator pit = peers.begin(), pend = peers.end(); pit != pend; ++pit) it->second->setVote(*pit, setHas); } } @@ -489,7 +488,7 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec LCTransaction::pointer txn = boost::make_shared(txID, tx, ourPosition); mDisputes[txID] = txn; - for (boost::unordered_map::iterator pit = mPeerPositions.begin(), + for (boost::unordered_map::iterator pit = mPeerPositions.begin(), pend = mPeerPositions.end(); pit != pend; ++pit) { boost::unordered_map::const_iterator cit = @@ -719,7 +718,7 @@ void LedgerConsensus::accept(SHAMap::pointer set) } #endif - SerializedValidation v(newLCLHash, mOurPosition->peekKey(), true); + SerializedValidation v(newLCLHash, mOurPosition->peekSeed(), true); std::vector validation = v.getSigned(); newcoin::TMValidation val; val.set_validation(&validation[0], validation.size()); @@ -732,3 +731,4 @@ void LedgerConsensus::endConsensus() { theApp->getOPs().endConsensus(); } +// vim:ts=4 diff --git a/src/LedgerConsensus.h b/src/LedgerConsensus.h index 5595435f5a..3f3f422dee 100644 --- a/src/LedgerConsensus.h +++ b/src/LedgerConsensus.h @@ -48,7 +48,7 @@ protected: int mYays, mNays; bool mOurPosition; std::vector transaction; - boost::unordered_map mVotes; + boost::unordered_map mVotes; public: typedef boost::shared_ptr pointer; @@ -60,7 +60,7 @@ public: bool getOurPosition() const { return mOurPosition; } const std::vector& peekTransaction() { return transaction; } - void setVote(const uint256& peer, bool votesYes); + void setVote(const uint160& peer, bool votesYes); bool updatePosition(int timePassed); int getAgreeLevel(); @@ -86,7 +86,7 @@ protected: LedgerProposal::pointer mOurPosition; // Convergence tracking, trusted peers indexed by hash of public key - boost::unordered_map mPeerPositions; + boost::unordered_map mPeerPositions; // Transaction Sets, indexed by hash of transaction tree boost::unordered_map mComplete; @@ -107,7 +107,7 @@ protected: SHAMap::pointer find(const uint256& hash); void addDisputedTransaction(const uint256&, const std::vector& transaction); - void adjustCount(SHAMap::pointer map, const std::vector& peers); + void adjustCount(SHAMap::pointer map, const std::vector& peers); void propose(const std::vector& addedTx, const std::vector& removedTx); void addPosition(LedgerProposal&, bool ours); diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp index 8efbc256ce..94cd3d4e28 100644 --- a/src/LedgerProposal.cpp +++ b/src/LedgerProposal.cpp @@ -7,34 +7,44 @@ #include "Application.h" LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, const std::string& pubKey) : - mPreviousLedger(pLgr), mCurrentHash(tx), mProposeSeq(seq), mKey(boost::make_shared()) + mPreviousLedger(pLgr), mCurrentHash(tx), mProposeSeq(seq) { - if (!mKey->SetPubKey(pubKey)) - throw std::runtime_error("Invalid public key in proposal"); - mPreviousLedger = theApp->getMasterLedger().getClosedLedger()->getHash(); - mPeerID = Serializer::getSHA512Half(mKey->GetPubKey()); + // XXX Make caller give us a vuc for pubkey. + + mPublicKey.setNodePublic(strCopy(pubKey)); + // XXX Validate key. + // if (!mKey->SetPubKey(pubKey)) + // throw std::runtime_error("Invalid public key in proposal"); + + mPreviousLedger = theApp->getMasterLedger().getClosedLedger()->getHash(); + mPeerID = mPublicKey.getNodeID(); } -LedgerProposal::LedgerProposal(CKey::pointer mPrivateKey, const uint256& prevLgr, const uint256& position) : - mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0), mKey(mPrivateKey) +LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLgr, const uint256& position) : + mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0) { - mPeerID = Serializer::getSHA512Half(mKey->GetPubKey()); + mSeed = naSeed; + mPublicKey = NewcoinAddress::createNodePublic(naSeed); + mPrivateKey = NewcoinAddress::createNodePrivate(naSeed); + mPeerID = mPublicKey.getNodeID(); } uint256 LedgerProposal::getSigningHash() const { Serializer s(72); + s.add32(sProposeMagic); s.add32(mProposeSeq); s.add256(mPreviousLedger); s.add256(mCurrentHash); + return s.getSHA512Half(); } bool LedgerProposal::checkSign(const std::string& signature) { - return mKey->Verify(getSigningHash(), signature); + return mPublicKey.verifyNodePublic(getSigningHash(), signature); } void LedgerProposal::changePosition(const uint256& newPosition) @@ -46,7 +56,13 @@ void LedgerProposal::changePosition(const uint256& newPosition) std::vector LedgerProposal::sign(void) { std::vector ret; - if (!mKey->Sign(getSigningHash(), ret)) - throw std::runtime_error("unable to sign proposal"); + + mPrivateKey.signNodePrivate(getSigningHash(), ret); + // XXX If this can fail, find out sooner. + // if (!mPrivateKey.signNodePrivate(getSigningHash(), ret)) + // throw std::runtime_error("unable to sign proposal"); + return ret; } + +// vim:ts=4 diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index daeda453aa..50a5e40123 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -5,17 +5,20 @@ #include -#include "uint256.h" -#include "key.h" +#include "NewcoinAddress.h" #include "Serializer.h" class LedgerProposal { protected: - uint256 mPeerID, mPreviousLedger, mCurrentHash; + uint256 mPreviousLedger, mCurrentHash; uint32 mProposeSeq; - CKey::pointer mKey; + + uint160 mPeerID; + NewcoinAddress mPublicKey; // Peer + NewcoinAddress mPrivateKey; // Our's + NewcoinAddress mSeed; // Our's static const uint32 sProposeMagic = 0x50525000; // PRP @@ -27,20 +30,22 @@ public: LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose, const std::string& pubKey); // our first proposal - LedgerProposal(CKey::pointer privateKey, const uint256& prevLedger, const uint256& position); + LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLedger, const uint256& position); uint256 getSigningHash() const; bool checkSign(const std::string& signature); - const uint256& getPeerID() const { return mPeerID; } + const uint160& getPeerID() const { return mPeerID; } const uint256& getCurrentHash() const { return mCurrentHash; } const uint256& getPrevLedger() const { return mPreviousLedger; } uint32 getProposeSeq() const { return mProposeSeq; } - CKey::pointer peekKey() { return mKey; } - std::vector getPubKey() const { return mKey->GetPubKey(); } + const NewcoinAddress& peekSeed() const { return mSeed; } + std::vector getPubKey() const { return mPublicKey.getNodePublic(); } std::vector sign(); void changePosition(const uint256& newPosition); }; #endif + +// vim:ts=4 diff --git a/src/SerializedValidation.cpp b/src/SerializedValidation.cpp index 47c4633c32..a6c8e8c040 100644 --- a/src/SerializedValidation.cpp +++ b/src/SerializedValidation.cpp @@ -18,22 +18,26 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi if (!isValid()) throw std::runtime_error("Invalid validation"); } -SerializedValidation::SerializedValidation(const uint256& ledgerHash, CKey::pointer nodeKey, bool isFull) +SerializedValidation::SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull) : STObject(sValidationFormat), mSignature("Signature") { setValueFieldH256(sfLedgerHash, ledgerHash); - setValueFieldVL(sfSigningKey, nodeKey->GetPubKey()); + setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic()); if (!isFull) setFlag(sFullFlag); - if (!nodeKey->Sign(getSigningHash(), mSignature.peekValue())) - throw std::runtime_error("Unable to sign validation"); + NewcoinAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue()); + // XXX Check if this can fail. + // if (!NewcoinAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue())) + // throw std::runtime_error("Unable to sign validation"); } uint256 SerializedValidation::getSigningHash() const { Serializer s; + s.add32(sValidationMagic); add(s); + return s.getSHA512Half(); } @@ -46,9 +50,9 @@ bool SerializedValidation::isValid() const { try { - CKey pubKey; - return pubKey.SetPubKey(getValueFieldVL(sfSigningKey)) && - pubKey.Verify(getSigningHash(), mSignature.peekValue()); + NewcoinAddress naPublicKey = NewcoinAddress::createNodePublic(getValueFieldVL(sfSigningKey)); + + return naPublicKey.isValid() && naPublicKey.verifyNodePublic(getSigningHash(), mSignature.peekValue()); } catch (...) { diff --git a/src/SerializedValidation.h b/src/SerializedValidation.h index 8eefc9f18f..594504c874 100644 --- a/src/SerializedValidation.h +++ b/src/SerializedValidation.h @@ -2,6 +2,7 @@ #define __VALIDATION__ #include "SerializedObject.h" +#include "NewcoinAddress.h" class SerializedValidation : public STObject { @@ -19,7 +20,7 @@ public: SerializedValidation(SerializerIterator& sit, bool checkSignature = true); SerializedValidation(const Serializer& s, bool checkSignature = true); - SerializedValidation(const uint256& ledgerHash, CKey::pointer nodeKey, bool isFull); + SerializedValidation(const uint256& ledgerHash, const NewcoinAddress& naSeed, bool isFull); uint256 getLedgerHash() const; NewcoinAddress getSignerPublic() const; From bec2891800951bebe8a1095198b27f4e58875817 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 16:44:57 -0700 Subject: [PATCH 5/6] Add RPC command validation_seed. --- src/RPCServer.cpp | 52 +++++++++++++++++++++++++++++++---------------- src/RPCServer.h | 3 ++- src/main.cpp | 1 + 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 1e06ce82e0..4d90800d14 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1479,40 +1479,55 @@ Json::Value RPCServer::doUnlAdd(Json::Value& params) return "invalid params"; } -// validation_create -// validation_create -// validation_create -// validation_create +// validation_create [||] // // NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command // shell history file (e.g. .bash_history) and it may be leaked via the process status command (i.e. ps). -Json::Value RPCServer::doValidatorCreate(Json::Value& params) { - NewcoinAddress familySeed; +Json::Value RPCServer::doValidationCreate(Json::Value& params) { + NewcoinAddress naSeed; + Json::Value obj(Json::objectValue); if (params.empty()) { std::cerr << "Creating random validation seed." << std::endl; - familySeed.setFamilySeedRandom(); // Get a random seed. + naSeed.setFamilySeedRandom(); // Get a random seed. } - else if (!familySeed.setFamilySeedGeneric(params[0u].asString())) + else if (!naSeed.setFamilySeedGeneric(params[0u].asString())) { return RPCError(rpcBAD_SEED); } - // Derive generator from seed. - NewcoinAddress familyGenerator = NewcoinAddress::createGeneratorPublic(familySeed); - NewcoinAddress nodePublicKey = NewcoinAddress::createNodePublic(familySeed); - NewcoinAddress nodePrivateKey = NewcoinAddress::createNodePrivate(familySeed); + obj["validation_public_key"] = NewcoinAddress::createNodePublic(naSeed).humanNodePublic(); + obj["validation_seed"] = naSeed.humanFamilySeed(); + obj["validation_key"] = naSeed.humanFamilySeed1751(); - // Paranoia - assert(1 == familySeed.setFamilySeed1751(familySeed.humanFamilySeed1751())); + return obj; +} +// validation_seed [||] +// +// NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command +// shell history file (e.g. .bash_history) and it may be leaked via the process status command (i.e. ps). +Json::Value RPCServer::doValidationSeed(Json::Value& params) { Json::Value obj(Json::objectValue); - obj["validation_public_key"] = nodePublicKey.humanNodePublic(); - obj["validation_seed"] = familySeed.humanFamilySeed(); - obj["validation_key"] = familySeed.humanFamilySeed1751(); + if (params.empty()) + { + std::cerr << "Unset validation seed." << std::endl; + + theConfig.VALIDATION_SEED.clear(); + } + else if (!theConfig.VALIDATION_SEED.setFamilySeedGeneric(params[0u].asString())) + { + return RPCError(rpcBAD_SEED); + } + else + { + obj["validation_public_key"] = NewcoinAddress::createNodePublic(theConfig.VALIDATION_SEED).humanNodePublic(); + obj["validation_seed"] = theConfig.VALIDATION_SEED.humanFamilySeed(); + obj["validation_key"] = theConfig.VALIDATION_SEED.humanFamilySeed1751(); + } return obj; } @@ -2045,7 +2060,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params { "unl_reset", &RPCServer::doUnlReset, 0, 0, }, { "unl_score", &RPCServer::doUnlScore, 0, 0, }, - { "validation_create", &RPCServer::doValidatorCreate, 0, 1, }, + { "validation_create", &RPCServer::doValidationCreate, 0, 1, }, + { "validation_seed", &RPCServer::doValidationSeed, 0, 1, }, { "wallet_accounts", &RPCServer::doWalletAccounts, 1, 1, optCurrent }, { "wallet_add", &RPCServer::doWalletAdd, 3, 5, optCurrent }, diff --git a/src/RPCServer.h b/src/RPCServer.h index 8eea5c60b2..4a3c6ece99 100644 --- a/src/RPCServer.h +++ b/src/RPCServer.h @@ -138,7 +138,8 @@ private: Json::Value doUnlReset(Json::Value& params); Json::Value doUnlScore(Json::Value& params); - Json::Value doValidatorCreate(Json::Value& params); + Json::Value doValidationCreate(Json::Value& params); + Json::Value doValidationSeed(Json::Value& params); Json::Value doWalletAccounts(Json::Value& params); Json::Value doWalletAdd(Json::Value& params); diff --git a/src/main.cpp b/src/main.cpp index 24f989988f..7c1ee53746 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -63,6 +63,7 @@ void printHelp(const po::options_description& desc) cout << " unl_list" << endl; cout << " unl_reset" << endl; cout << " validation_create [||]" << endl; + cout << " validation_seed [||]" << endl; cout << " wallet_add [] []" << endl; cout << " wallet_accounts " << endl; cout << " wallet_claim [] []" << endl; From ab9cc7f70c9c6bfed185fa310fafff4097043bf0 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 13 Jun 2012 16:53:09 -0700 Subject: [PATCH 6/6] Check UNL before processing validation. --- src/LedgerProposal.cpp | 6 ++---- src/LedgerProposal.h | 2 +- src/NetworkOPs.cpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/LedgerProposal.cpp b/src/LedgerProposal.cpp index 94cd3d4e28..b386e599c1 100644 --- a/src/LedgerProposal.cpp +++ b/src/LedgerProposal.cpp @@ -6,12 +6,10 @@ #include "key.h" #include "Application.h" -LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, const std::string& pubKey) : +LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& tx, const NewcoinAddress& naPeerPublic) : mPreviousLedger(pLgr), mCurrentHash(tx), mProposeSeq(seq) { - // XXX Make caller give us a vuc for pubkey. - - mPublicKey.setNodePublic(strCopy(pubKey)); + mPublicKey = naPeerPublic; // XXX Validate key. // if (!mKey->SetPubKey(pubKey)) // throw std::runtime_error("Invalid public key in proposal"); diff --git a/src/LedgerProposal.h b/src/LedgerProposal.h index 50a5e40123..52ab4091e9 100644 --- a/src/LedgerProposal.h +++ b/src/LedgerProposal.h @@ -27,7 +27,7 @@ public: typedef boost::shared_ptr pointer; // proposal from peer - LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose, const std::string& pubKey); + LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose, const NewcoinAddress& naPeerPublic); // our first proposal LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLedger, const uint256& position); diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index db14bbf94c..1492f69c70 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -456,9 +456,14 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger) return mConsensus->startup(); } +// <-- bool: true to relay bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, const std::string& pubKey, const std::string& signature) { + // XXX Validate key. + // XXX Take a vuc for pubkey. + NewcoinAddress naPeerPublic = NewcoinAddress::createNodePublic(strCopy(pubKey)); + if (mMode != omFULL) // FIXME: Should we relay? { Log(lsWARNING) << "Received proposal when not full: " << mMode; @@ -474,7 +479,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, if (!consensus) return false; LedgerProposal::pointer proposal = - boost::make_shared(consensus->getLCL(), proposeSeq, proposeHash, pubKey); + boost::make_shared(consensus->getLCL(), proposeSeq, proposeHash, naPeerPublic); if (!proposal->checkSign(signature)) { // Note that if the LCL is different, the signature check will fail Log(lsWARNING) << "Ledger proposal fails signature check"; @@ -482,7 +487,9 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, } // Is this node on our UNL? - // WRITEME + // XXX Is this right? + if (!theApp->getUNL().nodeInUNL(naPeerPublic)) + return true; return consensus->peerPosition(proposal); }