Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
jed
2012-06-13 16:55:38 -07:00
17 changed files with 170 additions and 126 deletions

View File

@@ -49,18 +49,12 @@
# 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0] # 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0]
# #
# [validation_seed]: # [validation_seed]:
# This is the seed used to generate the validation public/private key pair. # To perform validation, this section should contain either a validation seed or key.
# This representation has a checksum and is the recommended form for transmission. # The validation seed is used to generate the validation public/private key pair.
# # To obtain a validation seed, use the validation_create command.
# [validation_password]: # Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE
# This is the password used to generate the validation public/private key pair. # shfArahZT9Q9ckTf3s1psJ7C7qzVN
# 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
# #
[peer_ip] [peer_ip]
0.0.0.0 0.0.0.0

View File

@@ -18,8 +18,7 @@
#define SECTION_RPC_IP "rpc_ip" #define SECTION_RPC_IP "rpc_ip"
#define SECTION_RPC_PORT "rpc_port" #define SECTION_RPC_PORT "rpc_port"
#define SECTION_RPC_ALLOW_REMOTE "rpc_allow_remote" #define SECTION_RPC_ALLOW_REMOTE "rpc_allow_remote"
#define SECTION_VALIDATION_PASSWORD "validation_password" #define SECTION_VALIDATION_SEED "validation_seed"
#define SECTION_VALIDATION_KEY "validation_key"
#define SECTION_PEER_SSL_CIPHER_LIST "peer_ssl_cipher_list" #define SECTION_PEER_SSL_CIPHER_LIST "peer_ssl_cipher_list"
#define SECTION_PEER_SCAN_INTERVAL_MIN "peer_scan_interval_min" #define SECTION_PEER_SCAN_INTERVAL_MIN "peer_scan_interval_min"
#define SECTION_PEER_START_MAX "peer_start_max" #define SECTION_PEER_START_MAX "peer_start_max"
@@ -180,8 +179,8 @@ void Config::load()
if (sectionSingleB(secConfig, SECTION_RPC_ALLOW_REMOTE, strTemp)) if (sectionSingleB(secConfig, SECTION_RPC_ALLOW_REMOTE, strTemp))
RPC_ALLOW_REMOTE = boost::lexical_cast<bool>(strTemp); RPC_ALLOW_REMOTE = boost::lexical_cast<bool>(strTemp);
(void) sectionSingleB(secConfig, SECTION_VALIDATION_PASSWORD, VALIDATION_PASSWORD); if (sectionSingleB(secConfig, SECTION_VALIDATION_SEED, strTemp))
(void) sectionSingleB(secConfig, SECTION_VALIDATION_KEY, VALIDATION_KEY); VALIDATION_SEED.setFamilySeedGeneric(strTemp);
(void) sectionSingleB(secConfig, SECTION_PEER_SSL_CIPHER_LIST, PEER_SSL_CIPHER_LIST); (void) sectionSingleB(secConfig, SECTION_PEER_SSL_CIPHER_LIST, PEER_SSL_CIPHER_LIST);
if (sectionSingleB(secConfig, SECTION_PEER_SCAN_INTERVAL_MIN, strTemp)) if (sectionSingleB(secConfig, SECTION_PEER_SCAN_INTERVAL_MIN, strTemp))

View File

@@ -3,6 +3,7 @@
#include "types.h" #include "types.h"
#include "SerializedTypes.h" #include "SerializedTypes.h"
#include "NewcoinAddress.h"
#include <string> #include <string>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
@@ -78,8 +79,7 @@ public:
bool RPC_ALLOW_REMOTE; bool RPC_ALLOW_REMOTE;
// Validation // Validation
std::string VALIDATION_PASSWORD; NewcoinAddress VALIDATION_SEED;
std::string VALIDATION_KEY;
// Fees // Fees
uint64 FEE_DEFAULT; // Default fee. uint64 FEE_DEFAULT; // Default fee.

View File

@@ -118,10 +118,10 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
} }
} }
void LCTransaction::setVote(const uint256& peer, bool votesYes) void LCTransaction::setVote(const uint160& peer, bool votesYes)
{ {
std::pair<boost::unordered_map<uint256, bool>::iterator, bool> res = std::pair<boost::unordered_map<uint160, bool>::iterator, bool> res =
mVotes.insert(std::make_pair<uint256, bool>(peer, votesYes)); mVotes.insert(std::make_pair<uint160, bool>(peer, votesYes));
if (res.second) if (res.second)
{ // new vote { // new vote
@@ -182,14 +182,13 @@ LedgerConsensus::LedgerConsensus(Ledger::pointer previousLedger, uint32 closeTim
void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger) void LedgerConsensus::takeInitialPosition(Ledger::pointer initialLedger)
{ {
CKey::pointer nodePrivKey = boost::make_shared<CKey>(); // XXX Don't even start if no VALIDATION_SEED.
nodePrivKey->MakeNewKey(); // FIXME
SHAMap::pointer initialSet = initialLedger->peekTransactionMap()->snapShot(false); SHAMap::pointer initialSet = initialLedger->peekTransactionMap()->snapShot(false);
uint256 txSet = initialSet->getHash(); uint256 txSet = initialSet->getHash();
assert (initialLedger->getParentHash() == mPreviousLedger->getHash()); assert (initialLedger->getParentHash() == mPreviousLedger->getHash());
mOurPosition = boost::make_shared<LedgerProposal>(nodePrivKey, initialLedger->getParentHash(), txSet); mOurPosition = boost::make_shared<LedgerProposal>(theConfig.VALIDATION_SEED, initialLedger->getParentHash(), txSet);
mapComplete(txSet, initialSet); mapComplete(txSet, initialSet);
propose(std::vector<uint256>(), std::vector<uint256>()); propose(std::vector<uint256>(), std::vector<uint256>());
} }
@@ -234,8 +233,8 @@ void LedgerConsensus::mapComplete(const uint256& hash, SHAMap::pointer map)
mComplete[map->getHash()] = map; mComplete[map->getHash()] = map;
// Adjust tracking for each peer that takes this position // Adjust tracking for each peer that takes this position
std::vector<uint256> peers; std::vector<uint160> peers;
for (boost::unordered_map<uint256, LedgerProposal::pointer>::iterator it = mPeerPositions.begin(), for (boost::unordered_map<uint160, LedgerProposal::pointer>::iterator it = mPeerPositions.begin(),
end = mPeerPositions.end(); it != end; ++it) end = mPeerPositions.end(); it != end; ++it)
{ {
if (it->second->getCurrentHash() == map->getHash()) if (it->second->getCurrentHash() == map->getHash())
@@ -256,13 +255,13 @@ void LedgerConsensus::sendHaveTxSet(const uint256& hash, bool direct)
theApp->getConnectionPool().relayMessage(NULL, packet); theApp->getConnectionPool().relayMessage(NULL, packet);
} }
void LedgerConsensus::adjustCount(SHAMap::pointer map, const std::vector<uint256>& peers) void LedgerConsensus::adjustCount(SHAMap::pointer map, const std::vector<uint160>& peers)
{ // Adjust the counts on all disputed transactions based on the set of peers taking this position { // Adjust the counts on all disputed transactions based on the set of peers taking this position
for (boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.begin(), end = mDisputes.end(); for (boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.begin(), end = mDisputes.end();
it != end; ++it) it != end; ++it)
{ {
bool setHas = map->hasItem(it->second->getTransactionID()); bool setHas = map->hasItem(it->second->getTransactionID());
for(std::vector<uint256>::const_iterator pit = peers.begin(), pend = peers.end(); pit != pend; ++pit) for(std::vector<uint160>::const_iterator pit = peers.begin(), pend = peers.end(); pit != pend; ++pit)
it->second->setVote(*pit, setHas); it->second->setVote(*pit, setHas);
} }
} }
@@ -489,7 +488,7 @@ void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vec
LCTransaction::pointer txn = boost::make_shared<LCTransaction>(txID, tx, ourPosition); LCTransaction::pointer txn = boost::make_shared<LCTransaction>(txID, tx, ourPosition);
mDisputes[txID] = txn; mDisputes[txID] = txn;
for (boost::unordered_map<uint256, LedgerProposal::pointer>::iterator pit = mPeerPositions.begin(), for (boost::unordered_map<uint160, LedgerProposal::pointer>::iterator pit = mPeerPositions.begin(),
pend = mPeerPositions.end(); pit != pend; ++pit) pend = mPeerPositions.end(); pit != pend; ++pit)
{ {
boost::unordered_map<uint256, SHAMap::pointer>::const_iterator cit = boost::unordered_map<uint256, SHAMap::pointer>::const_iterator cit =
@@ -719,7 +718,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
} }
#endif #endif
SerializedValidation v(newLCLHash, mOurPosition->peekKey(), true); SerializedValidation v(newLCLHash, mOurPosition->peekSeed(), true);
std::vector<unsigned char> validation = v.getSigned(); std::vector<unsigned char> validation = v.getSigned();
newcoin::TMValidation val; newcoin::TMValidation val;
val.set_validation(&validation[0], validation.size()); val.set_validation(&validation[0], validation.size());
@@ -732,3 +731,4 @@ void LedgerConsensus::endConsensus()
{ {
theApp->getOPs().endConsensus(); theApp->getOPs().endConsensus();
} }
// vim:ts=4

View File

@@ -48,7 +48,7 @@ protected:
int mYays, mNays; int mYays, mNays;
bool mOurPosition; bool mOurPosition;
std::vector<unsigned char> transaction; std::vector<unsigned char> transaction;
boost::unordered_map<uint256, bool> mVotes; boost::unordered_map<uint160, bool> mVotes;
public: public:
typedef boost::shared_ptr<LCTransaction> pointer; typedef boost::shared_ptr<LCTransaction> pointer;
@@ -60,7 +60,7 @@ public:
bool getOurPosition() const { return mOurPosition; } bool getOurPosition() const { return mOurPosition; }
const std::vector<unsigned char>& peekTransaction() { return transaction; } const std::vector<unsigned char>& peekTransaction() { return transaction; }
void setVote(const uint256& peer, bool votesYes); void setVote(const uint160& peer, bool votesYes);
bool updatePosition(int timePassed); bool updatePosition(int timePassed);
int getAgreeLevel(); int getAgreeLevel();
@@ -86,7 +86,7 @@ protected:
LedgerProposal::pointer mOurPosition; LedgerProposal::pointer mOurPosition;
// Convergence tracking, trusted peers indexed by hash of public key // Convergence tracking, trusted peers indexed by hash of public key
boost::unordered_map<uint256, LedgerProposal::pointer> mPeerPositions; boost::unordered_map<uint160, LedgerProposal::pointer> mPeerPositions;
// Transaction Sets, indexed by hash of transaction tree // Transaction Sets, indexed by hash of transaction tree
boost::unordered_map<uint256, SHAMap::pointer> mComplete; boost::unordered_map<uint256, SHAMap::pointer> mComplete;
@@ -107,7 +107,7 @@ protected:
SHAMap::pointer find(const uint256& hash); SHAMap::pointer find(const uint256& hash);
void addDisputedTransaction(const uint256&, const std::vector<unsigned char>& transaction); void addDisputedTransaction(const uint256&, const std::vector<unsigned char>& transaction);
void adjustCount(SHAMap::pointer map, const std::vector<uint256>& peers); void adjustCount(SHAMap::pointer map, const std::vector<uint160>& peers);
void propose(const std::vector<uint256>& addedTx, const std::vector<uint256>& removedTx); void propose(const std::vector<uint256>& addedTx, const std::vector<uint256>& removedTx);
void addPosition(LedgerProposal&, bool ours); void addPosition(LedgerProposal&, bool ours);

View File

@@ -6,35 +6,43 @@
#include "key.h" #include "key.h"
#include "Application.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), mKey(boost::make_shared<CKey>()) mPreviousLedger(pLgr), mCurrentHash(tx), mProposeSeq(seq)
{ {
if (!mKey->SetPubKey(pubKey)) mPublicKey = naPeerPublic;
throw std::runtime_error("Invalid public key in proposal"); // XXX Validate key.
// if (!mKey->SetPubKey(pubKey))
// throw std::runtime_error("Invalid public key in proposal");
mPreviousLedger = theApp->getMasterLedger().getClosedLedger()->getHash(); mPreviousLedger = theApp->getMasterLedger().getClosedLedger()->getHash();
mPeerID = Serializer::getSHA512Half(mKey->GetPubKey()); mPeerID = mPublicKey.getNodeID();
} }
LedgerProposal::LedgerProposal(CKey::pointer mPrivateKey, const uint256& prevLgr, const uint256& position) : LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLgr, const uint256& position) :
mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0), mKey(mPrivateKey) 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 uint256 LedgerProposal::getSigningHash() const
{ {
Serializer s(72); Serializer s(72);
s.add32(sProposeMagic); s.add32(sProposeMagic);
s.add32(mProposeSeq); s.add32(mProposeSeq);
s.add256(mPreviousLedger); s.add256(mPreviousLedger);
s.add256(mCurrentHash); s.add256(mCurrentHash);
return s.getSHA512Half(); return s.getSHA512Half();
} }
bool LedgerProposal::checkSign(const std::string& signature) bool LedgerProposal::checkSign(const std::string& signature)
{ {
return mKey->Verify(getSigningHash(), signature); return mPublicKey.verifyNodePublic(getSigningHash(), signature);
} }
void LedgerProposal::changePosition(const uint256& newPosition) void LedgerProposal::changePosition(const uint256& newPosition)
@@ -46,7 +54,13 @@ void LedgerProposal::changePosition(const uint256& newPosition)
std::vector<unsigned char> LedgerProposal::sign(void) std::vector<unsigned char> LedgerProposal::sign(void)
{ {
std::vector<unsigned char> ret; std::vector<unsigned char> 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; return ret;
} }
// vim:ts=4

View File

@@ -5,17 +5,20 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include "uint256.h" #include "NewcoinAddress.h"
#include "key.h"
#include "Serializer.h" #include "Serializer.h"
class LedgerProposal class LedgerProposal
{ {
protected: protected:
uint256 mPeerID, mPreviousLedger, mCurrentHash; uint256 mPreviousLedger, mCurrentHash;
uint32 mProposeSeq; uint32 mProposeSeq;
CKey::pointer mKey;
uint160 mPeerID;
NewcoinAddress mPublicKey; // Peer
NewcoinAddress mPrivateKey; // Our's
NewcoinAddress mSeed; // Our's
static const uint32 sProposeMagic = 0x50525000; // PRP static const uint32 sProposeMagic = 0x50525000; // PRP
@@ -24,23 +27,25 @@ public:
typedef boost::shared_ptr<LedgerProposal> pointer; typedef boost::shared_ptr<LedgerProposal> pointer;
// proposal from peer // 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 // 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; uint256 getSigningHash() const;
bool checkSign(const std::string& signature); 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& getCurrentHash() const { return mCurrentHash; }
const uint256& getPrevLedger() const { return mPreviousLedger; } const uint256& getPrevLedger() const { return mPreviousLedger; }
uint32 getProposeSeq() const { return mProposeSeq; } uint32 getProposeSeq() const { return mProposeSeq; }
CKey::pointer peekKey() { return mKey; } const NewcoinAddress& peekSeed() const { return mSeed; }
std::vector<unsigned char> getPubKey() const { return mKey->GetPubKey(); } std::vector<unsigned char> getPubKey() const { return mPublicKey.getNodePublic(); }
std::vector<unsigned char> sign(); std::vector<unsigned char> sign();
void changePosition(const uint256& newPosition); void changePosition(const uint256& newPosition);
}; };
#endif #endif
// vim:ts=4

View File

@@ -456,9 +456,14 @@ int NetworkOPs::beginConsensus(Ledger::pointer closingLedger)
return mConsensus->startup(); return mConsensus->startup();
} }
// <-- bool: true to relay
bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash, bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash,
const std::string& pubKey, const std::string& signature) 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? if (mMode != omFULL) // FIXME: Should we relay?
{ {
Log(lsWARNING) << "Received proposal when not full: " << mMode; Log(lsWARNING) << "Received proposal when not full: " << mMode;
@@ -474,7 +479,7 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash,
if (!consensus) return false; if (!consensus) return false;
LedgerProposal::pointer proposal = LedgerProposal::pointer proposal =
boost::make_shared<LedgerProposal>(consensus->getLCL(), proposeSeq, proposeHash, pubKey); boost::make_shared<LedgerProposal>(consensus->getLCL(), proposeSeq, proposeHash, naPeerPublic);
if (!proposal->checkSign(signature)) if (!proposal->checkSign(signature))
{ // Note that if the LCL is different, the signature check will fail { // Note that if the LCL is different, the signature check will fail
Log(lsWARNING) << "Ledger proposal fails signature check"; 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? // Is this node on our UNL?
// WRITEME // XXX Is this right?
if (!theApp->getUNL().nodeInUNL(naPeerPublic))
return true;
return consensus->peerPosition(proposal); return consensus->peerPosition(proposal);
} }

View File

@@ -58,7 +58,7 @@ void NewcoinAddress::clear()
// NodePublic // NodePublic
// //
NewcoinAddress NewcoinAddress::createNodePublic(NewcoinAddress& naSeed) NewcoinAddress NewcoinAddress::createNodePublic(const NewcoinAddress& naSeed)
{ {
CKey ckSeed(naSeed.getFamilySeed()); CKey ckSeed(naSeed.getFamilySeed());
NewcoinAddress naNew; NewcoinAddress naNew;
@@ -69,6 +69,29 @@ NewcoinAddress NewcoinAddress::createNodePublic(NewcoinAddress& naSeed)
return naNew; return naNew;
} }
NewcoinAddress NewcoinAddress::createNodePublic(const std::vector<unsigned char>& 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<unsigned char>& NewcoinAddress::getNodePublic() const const std::vector<unsigned char>& NewcoinAddress::getNodePublic() const
{ {
switch (nVersion) { switch (nVersion) {
@@ -136,7 +159,7 @@ bool NewcoinAddress::verifyNodePublic(const uint256& hash, const std::string& st
// NodePrivate // NodePrivate
// //
NewcoinAddress NewcoinAddress::createNodePrivate(NewcoinAddress& naSeed) NewcoinAddress NewcoinAddress::createNodePrivate(const NewcoinAddress& naSeed)
{ {
uint256 uPrivKey; uint256 uPrivKey;
NewcoinAddress naNew; NewcoinAddress naNew;
@@ -229,7 +252,7 @@ uint160 NewcoinAddress::getAccountID() const
return uint160(vchData); return uint160(vchData);
case VER_ACCOUNT_PUBLIC: case VER_ACCOUNT_PUBLIC:
// Note, we are encoding the left or right. // Note, we are encoding the left.
return Hash160(vchData); return Hash160(vchData);
default: default:
@@ -595,13 +618,6 @@ void NewcoinAddress::setFamilyGenerator(const std::vector<unsigned char>& vPubli
SetData(VER_FAMILY_GENERATOR, vPublic); SetData(VER_FAMILY_GENERATOR, vPublic);
} }
#if 0
void NewcoinAddress::setFamilyGenerator(const NewcoinAddress& seed)
{
seed.seedInfo(this, 0);
}
#endif
NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSeed) NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSeed)
{ {
CKey ckSeed(naSeed.getFamilySeed()); CKey ckSeed(naSeed.getFamilySeed());
@@ -616,21 +632,6 @@ NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSee
// Family Seed // 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 uint128 NewcoinAddress::getFamilySeed() const
{ {
switch (nVersion) { 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 std::string NewcoinAddress::humanFamilySeed1751() const
{ {
switch (nVersion) { switch (nVersion) {

View File

@@ -7,6 +7,7 @@
// //
// Used to hold addresses and parse and produce human formats. // 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 class NewcoinAddress : public CBase58Data
{ {
private: private:
@@ -21,8 +22,6 @@ private:
VER_FAMILY_SEED = 33, VER_FAMILY_SEED = 33,
} VersionEncoding; } VersionEncoding;
// void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const;
public: public:
NewcoinAddress(); NewcoinAddress();
@@ -31,8 +30,9 @@ public:
void clear(); void clear();
// //
// Node Public // Node Public - Also used for Validators
// //
uint160 getNodeID() const;
const std::vector<unsigned char>& getNodePublic() const; const std::vector<unsigned char>& getNodePublic() const;
std::string humanNodePublic() const; std::string humanNodePublic() const;
@@ -42,7 +42,8 @@ public:
bool verifyNodePublic(const uint256& hash, const std::vector<unsigned char>& vchSig) const; bool verifyNodePublic(const uint256& hash, const std::vector<unsigned char>& vchSig) const;
bool verifyNodePublic(const uint256& hash, const std::string& strSig) 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<unsigned char>& vPublic);
// //
// Node Private // Node Private
@@ -57,7 +58,7 @@ public:
void setNodePrivate(uint256 hash256); void setNodePrivate(uint256 hash256);
void signNodePrivate(const uint256& hash, std::vector<unsigned char>& vchSig) const; void signNodePrivate(const uint256& hash, std::vector<unsigned char>& vchSig) const;
static NewcoinAddress createNodePrivate(NewcoinAddress& naSeed); static NewcoinAddress createNodePrivate(const NewcoinAddress& naSeed);
// //
// Accounts IDs // Accounts IDs
@@ -159,7 +160,6 @@ public:
// Family Seeds // Family Seeds
// Clients must disallow reconizable entries from being seeds. // Clients must disallow reconizable entries from being seeds.
uint128 getFamilySeed() const; uint128 getFamilySeed() const;
// BIGNUM* getFamilyPrivateKey() const;
std::string humanFamilySeed() const; std::string humanFamilySeed() const;
std::string humanFamilySeed1751() const; std::string humanFamilySeed1751() const;

View File

@@ -1479,40 +1479,55 @@ Json::Value RPCServer::doUnlAdd(Json::Value& params)
return "invalid params"; return "invalid params";
} }
// validation_create // validation_create [<pass_phrase>|<seed>|<seed_key>]
// validation_create <pass_phrase>
// validation_create <seed>
// validation_create <seed_key>
// //
// NOTE: It is poor security to specify secret information on the command line. This information might be saved in the command // 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). // 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) { Json::Value RPCServer::doValidationCreate(Json::Value& params) {
NewcoinAddress familySeed; NewcoinAddress naSeed;
Json::Value obj(Json::objectValue);
if (params.empty()) if (params.empty())
{ {
std::cerr << "Creating random validation seed." << std::endl; 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); return RPCError(rpcBAD_SEED);
} }
// Derive generator from seed. obj["validation_public_key"] = NewcoinAddress::createNodePublic(naSeed).humanNodePublic();
NewcoinAddress familyGenerator = NewcoinAddress::createGeneratorPublic(familySeed); obj["validation_seed"] = naSeed.humanFamilySeed();
NewcoinAddress nodePublicKey = NewcoinAddress::createNodePublic(familySeed); obj["validation_key"] = naSeed.humanFamilySeed1751();
NewcoinAddress nodePrivateKey = NewcoinAddress::createNodePrivate(familySeed);
// Paranoia return obj;
assert(1 == familySeed.setFamilySeed1751(familySeed.humanFamilySeed1751())); }
// validation_seed [<pass_phrase>|<seed>|<seed_key>]
//
// 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); Json::Value obj(Json::objectValue);
obj["validation_public_key"] = nodePublicKey.humanNodePublic(); if (params.empty())
obj["validation_seed"] = familySeed.humanFamilySeed(); {
obj["validation_key"] = familySeed.humanFamilySeed1751(); 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; return obj;
} }
@@ -2045,7 +2060,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
{ "unl_reset", &RPCServer::doUnlReset, 0, 0, }, { "unl_reset", &RPCServer::doUnlReset, 0, 0, },
{ "unl_score", &RPCServer::doUnlScore, 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_accounts", &RPCServer::doWalletAccounts, 1, 1, optCurrent },
{ "wallet_add", &RPCServer::doWalletAdd, 3, 5, optCurrent }, { "wallet_add", &RPCServer::doWalletAdd, 3, 5, optCurrent },

View File

@@ -138,7 +138,8 @@ private:
Json::Value doUnlReset(Json::Value& params); Json::Value doUnlReset(Json::Value& params);
Json::Value doUnlScore(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 doWalletAccounts(Json::Value& params);
Json::Value doWalletAdd(Json::Value& params); Json::Value doWalletAdd(Json::Value& params);

View File

@@ -18,16 +18,27 @@
std::size_t hash_value(const SHAMapNode& mn) std::size_t hash_value(const SHAMapNode& mn)
{ {
std::size_t seed = theApp->getNonceST(); std::size_t seed = theApp->getNonceST();
boost::hash_combine(seed, mn.getDepth()); boost::hash_combine(seed, mn.getDepth());
return mn.getNodeID().hash_combine(seed); return mn.getNodeID().hash_combine(seed);
} }
std::size_t hash_value(const uint256& u) std::size_t hash_value(const uint256& u)
{ {
std::size_t seed = theApp->getNonceST(); std::size_t seed = theApp->getNonceST();
return u.hash_combine(seed); 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) SHAMap::SHAMap(uint32 seq) : mSeq(seq), mState(Modifying)
{ {
root = boost::make_shared<SHAMapTreeNode>(mSeq, SHAMapNode(0, uint256())); root = boost::make_shared<SHAMapTreeNode>(mSeq, SHAMapNode(0, uint256()));

View File

@@ -78,6 +78,7 @@ public:
extern std::size_t hash_value(const SHAMapNode& mn); 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 uint256& u);
extern std::size_t hash_value(const uint160& u);
class SHAMapItem class SHAMapItem
{ // an item stored in a SHAMap { // an item stored in a SHAMap

View File

@@ -18,22 +18,26 @@ SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSi
if (!isValid()) throw std::runtime_error("Invalid validation"); 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") : STObject(sValidationFormat), mSignature("Signature")
{ {
setValueFieldH256(sfLedgerHash, ledgerHash); setValueFieldH256(sfLedgerHash, ledgerHash);
setValueFieldVL(sfSigningKey, nodeKey->GetPubKey()); setValueFieldVL(sfSigningKey, NewcoinAddress::createNodePublic(naSeed).getNodePublic());
if (!isFull) setFlag(sFullFlag); if (!isFull) setFlag(sFullFlag);
if (!nodeKey->Sign(getSigningHash(), mSignature.peekValue())) NewcoinAddress::createNodePrivate(naSeed).signNodePrivate(getSigningHash(), mSignature.peekValue());
throw std::runtime_error("Unable to sign validation"); // 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 uint256 SerializedValidation::getSigningHash() const
{ {
Serializer s; Serializer s;
s.add32(sValidationMagic); s.add32(sValidationMagic);
add(s); add(s);
return s.getSHA512Half(); return s.getSHA512Half();
} }
@@ -46,9 +50,9 @@ bool SerializedValidation::isValid() const
{ {
try try
{ {
CKey pubKey; NewcoinAddress naPublicKey = NewcoinAddress::createNodePublic(getValueFieldVL(sfSigningKey));
return pubKey.SetPubKey(getValueFieldVL(sfSigningKey)) &&
pubKey.Verify(getSigningHash(), mSignature.peekValue()); return naPublicKey.isValid() && naPublicKey.verifyNodePublic(getSigningHash(), mSignature.peekValue());
} }
catch (...) catch (...)
{ {

View File

@@ -2,6 +2,7 @@
#define __VALIDATION__ #define __VALIDATION__
#include "SerializedObject.h" #include "SerializedObject.h"
#include "NewcoinAddress.h"
class SerializedValidation : public STObject class SerializedValidation : public STObject
{ {
@@ -19,7 +20,7 @@ public:
SerializedValidation(SerializerIterator& sit, bool checkSignature = true); SerializedValidation(SerializerIterator& sit, bool checkSignature = true);
SerializedValidation(const Serializer& s, 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; uint256 getLedgerHash() const;
NewcoinAddress getSignerPublic() const; NewcoinAddress getSignerPublic() const;

View File

@@ -63,6 +63,7 @@ void printHelp(const po::options_description& desc)
cout << " unl_list" << endl; cout << " unl_list" << endl;
cout << " unl_reset" << endl; cout << " unl_reset" << endl;
cout << " validation_create [<seed>|<pass_phrase>|<key>]" << endl; cout << " validation_create [<seed>|<pass_phrase>|<key>]" << endl;
cout << " validation_seed [<seed>|<pass_phrase>|<key>]" << endl;
cout << " wallet_add <regular_seed> <paying_account> <master_seed> [<initial_funds>] [<account_annotation>]" << endl; cout << " wallet_add <regular_seed> <paying_account> <master_seed> [<initial_funds>] [<account_annotation>]" << endl;
cout << " wallet_accounts <seed>" << endl; cout << " wallet_accounts <seed>" << endl;
cout << " wallet_claim <master_seed> <regular_seed> [<source_tag>] [<account_annotation>]" << endl; cout << " wallet_claim <master_seed> <regular_seed> [<source_tag>] [<account_annotation>]" << endl;