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

Conflicts:
	src/UniqueNodeList.cpp
This commit is contained in:
jed
2012-06-18 14:47:15 -07:00
9 changed files with 123 additions and 52 deletions

View File

@@ -31,7 +31,14 @@
# Note: $XDG_CONFIG_HOME defaults to $HOME/.config
# $XDG_DATA_HOME defaults to $HOME/.local/share
#
# [validators_site]:
# Specifies where to find validators.txt for UNL boostrapping and RPC command unl_network.
# During alpha testing, this defaults to: redstem.com
#
# Example: newcoin.org
#
# [unl_default]:
# XXX This should be called: [validators_file]
# Specifies how to bootstrap the UNL list. The UNL list is based on a
# validators.txt file and is maintained in the databases. When newcoind
# starts up, if the databases are missing or are obsolete due to an upgrade
@@ -48,6 +55,16 @@
# Examples: C:/home/johndoe/newcoin/validators.txt
# /home/johndoe/newcoin/validators.txt
#
# [validators]:
# List of nodes to accept as validators speficied by public key or domain.
#
# For domains, newcoind will probe for https web servers at the specied
# domain in the following order: newcoin.DOMAIN, www.DOMAIN, DOMAIN
#
# Examples: redstem.com
# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe
#
# [peer_ip]:
# IP address or domain to bind to allow external connections from peers.
# Defaults to not allow external connections from peers.
@@ -104,4 +121,4 @@
snTBDmrhUK3znvF8AaQURLm4UCkbS
[unl_default]
validators.txt
validators.txt

View File

@@ -1,14 +1,11 @@
#include "Config.h"
#include "ParseSection.h"
#include "utils.h"
#include <boost/lexical_cast.hpp>
#include <fstream>
#include <iostream>
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg
#define SECTION_ACCOUNT_PROBE_MAX "account_probe_max"
#define SECTION_FEE_ACCOUNT_CREATE "fee_account_create"
#define SECTION_FEE_DEFAULT "fee_default"
@@ -28,6 +25,8 @@
#define SECTION_VALIDATION_SEED "validation_seed"
#define SECTION_WEBSOCKET_IP "websocket_ip"
#define SECTION_WEBSOCKET_PORT "websocket_port"
#define SECTION_VALIDATORS "validators"
#define SECTION_VALIDATORS_SITE "validators_site"
// Fees are in XNB.
#define DEFAULT_FEE_ACCOUNT_CREATE 1000
@@ -143,6 +142,8 @@ void Config::setup(const std::string& strConf)
ACCOUNT_PROBE_MAX = 10;
VALIDATORS_SITE = DEFAULT_VALIDATORS_SITE;
load();
}
@@ -170,6 +171,17 @@ void Config::load()
section secConfig = ParseSection(strConfigFile, true);
std::string strTemp;
section::mapped_type* smtTmp;
smtTmp = sectionEntries(secConfig, SECTION_VALIDATORS);
if (smtTmp)
{
VALIDATORS = *smtTmp;
sectionEntriesPrint(&VALIDATORS, SECTION_VALIDATORS);
}
(void) sectionSingleB(secConfig, SECTION_VALIDATORS_SITE, VALIDATORS_SITE);
(void) sectionSingleB(secConfig, SECTION_PEER_IP, PEER_IP);
if (sectionSingleB(secConfig, SECTION_PEER_PORT, strTemp))

View File

@@ -2,14 +2,14 @@
#define __CONFIG__
#include "types.h"
#include "SerializedTypes.h"
#include "NewcoinAddress.h"
#include "ParseSection.h"
#include "SerializedTypes.h"
#include <string>
#include <boost/filesystem.hpp>
#define SYSTEM_NAME "newcoin"
#define VALIDATORS_SITE "redstem.com"
#define SYSTEM_CURRENCY_CODE "XNS"
#define SYSTEM_CURRENCY_PRECISION 6
@@ -18,6 +18,9 @@
#define SYSTEM_CURRENCY_PARTS 1000000ull // 10^SYSTEM_CURRENCY_PRECISION
#define SYSTEM_CURRENCY_START (SYSTEM_CURRENCY_GIFT*SYSTEM_CURRENCY_USERS*SYSTEM_CURRENCY_PARTS)
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg
#define DEFAULT_VALIDATORS_SITE "redstem.com"
#define VALIDATORS_FILE_NAME "validators.txt"
const int SYSTEM_PEER_PORT = 6561;
@@ -46,6 +49,9 @@ public:
boost::filesystem::path DATA_DIR;
boost::filesystem::path UNL_DEFAULT;
std::string VALIDATORS_SITE; // Where to find validators.txt on the Internet.
std::vector<std::string> VALIDATORS; // Validators from newcoind.cfg
// Network parameters
int NETWORK_START_TIME; // The Unix time we start ledger 0
int TRANSACTION_FEE_BASE;

View File

@@ -227,7 +227,6 @@ void LedgerConsensus::createDisputes(SHAMap::pointer m1, SHAMap::pointer m2)
m1->compare(m2, differences, 16384);
for(SHAMap::SHAMapDiff::iterator pos = differences.begin(), end = differences.end(); pos != end; ++pos)
{ // create disputed transactions (from the ledger that has them)
Log(lsTRACE) << "Transaction now in dispute: " << pos->first.GetHex();
if (pos->second.first)
{
assert(!pos->second.second);
@@ -521,7 +520,7 @@ void LedgerConsensus::propose(const std::vector<uint256>& added, const std::vect
void LedgerConsensus::addDisputedTransaction(const uint256& txID, const std::vector<unsigned char>& tx)
{
Log(lsTRACE) << "Transacstion " << txID.GetHex() << " is disputed";
Log(lsTRACE) << "Transaction " << txID.GetHex() << " is disputed";
boost::unordered_map<uint256, LCTransaction::pointer>::iterator it = mDisputes.find(txID);
if (it != mDisputes.end()) return;
@@ -649,7 +648,6 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTran
else
{
Log(lsINFO) << " hard fail";
assert(!ledger->hasTransaction(txn->getTransactionID()));
}
#ifndef TRUST_NETWORK
}

View File

@@ -1,4 +1,5 @@
#include "ParseSection.h"
#include "utils.h"
#include <iostream>
#include <boost/algorithm/string.hpp>
@@ -32,6 +33,8 @@ section ParseSection(const std::string& strInput, const bool bTrim)
if (strValue.empty() || strValue[0] == '#')
{
// Blank line or comment, do nothing.
nothing();
}
else if (strValue[0] == '[' && strValue[strValue.length()-1] == ']') {
// New section.
@@ -41,29 +44,37 @@ section ParseSection(const std::string& strInput, const bool bTrim)
}
else
{
// Another line in a section.
// Another line for section.
if (bTrim)
boost::algorithm::trim(strValue);
secResult[strSection].push_back(strValue);
if (!strValue.empty())
secResult[strSection].push_back(strValue);
}
}
return secResult;
}
void PrintSection(section secInput)
void sectionEntriesPrint(std::vector<std::string>* vspEntries, const std::string& strSection)
{
std::cerr << "[" << strSection << "]" << std::endl;
if (vspEntries)
{
BOOST_FOREACH(std::string& strValue, *vspEntries)
{
std::cerr << strValue << std::endl;
}
}
}
void sectionPrint(section secInput)
{
std::cerr << "PrintSection>" << std::endl;
BOOST_FOREACH(section::value_type& pairSection, secInput)
{
std::cerr << "[" << pairSection.first << "]" << std::endl;
BOOST_FOREACH(std::string& value, pairSection.second)
{
std::cerr << value << std::endl;
}
sectionEntriesPrint(&pairSection.second, pairSection.first);
}
std::cerr << "PrintSection<" << std::endl;
}
section::mapped_type* sectionEntries(section& secSource, const std::string& strSection)

View File

@@ -8,7 +8,8 @@
typedef std::map<const std::string, std::vector<std::string> > section;
section ParseSection(const std::string& strInput, const bool bTrim);
void PrintSection(section secInput);
void sectionPrint(section secInput);
void sectionEntriesPrint(std::vector<std::string>* vspEntries, const std::string& strSection);
bool sectionSingleB(section& secSource, const std::string& strSection, std::string& strValue);
int sectionCount(section& secSource, const std::string& strSection);
section::mapped_type* sectionEntries(section& secSource, const std::string& strSection);

View File

@@ -1926,7 +1926,7 @@ Json::Value RPCServer::doUnlList(Json::Value& params)
// Populate the UNL from a local validators.txt file.
Json::Value RPCServer::doUnlLoad(Json::Value& params)
{
if (!theApp->getUNL().nodeLoad())
if (theConfig.UNL_DEFAULT.empty() || !theApp->getUNL().nodeLoad(theConfig.UNL_DEFAULT))
{
return RPCError(rpcLOAD_FAILED);
}

View File

@@ -692,10 +692,11 @@ void UniqueNodeList::processIps(const std::string& strSite, const NewcoinAddress
// --> strValidatorsSrc: source details for display
// --> naNodePublic: remote source public key - not valid for local
// --> vsWhy: reason for adding validator to SeedDomains or SeedNodes.
void UniqueNodeList::processValidators(const std::string& strSite, const std::string& strValidatorsSrc, const NewcoinAddress& naNodePublic, validatorSource vsWhy, section::mapped_type* pmtVecStrValidators)
int UniqueNodeList::processValidators(const std::string& strSite, const std::string& strValidatorsSrc, const NewcoinAddress& naNodePublic, validatorSource vsWhy, section::mapped_type* pmtVecStrValidators)
{
Database* db = theApp->getWalletDB()->getDB();
std::string strNodePublic = naNodePublic.isValid() ? naNodePublic.humanNodePublic() : "local";
std::string strNodePublic = naNodePublic.isValid() ? naNodePublic.humanNodePublic() : strValidatorsSrc;
int iValues = 0;
std::cerr
<< str(boost::format("Validator: '%s' : '%s' : processing %d validators.")
@@ -718,7 +719,6 @@ void UniqueNodeList::processValidators(const std::string& strSite, const std::st
vstrValues.reserve(MIN(pmtVecStrValidators->size(), REFERRAL_VALIDATORS_MAX));
int iValues = 0;
BOOST_FOREACH(std::string strReferral, *pmtVecStrValidators)
{
if (iValues == REFERRAL_VALIDATORS_MAX)
@@ -734,7 +734,7 @@ void UniqueNodeList::processValidators(const std::string& strSite, const std::st
if (!boost::regex_match(strReferral, smMatch, reReferral))
{
std::cerr
<< str(boost::format("Validator: '%s' ["SECTION_VALIDATORS"]: rejecting '%s'")
<< str(boost::format("Validator: '%s' ["SECTION_VALIDATORS"]: rejecting line: '%s'")
% strSite % strReferral)
<< std::endl;
}
@@ -744,7 +744,7 @@ void UniqueNodeList::processValidators(const std::string& strSite, const std::st
std::string strComment = smMatch[2];
NewcoinAddress naValidator;
// std::cerr << str(boost::format("Validator: '%s' : '%s'") % strRefered % strComment) << std::endl;
std::cerr << str(boost::format("Validator='%s', Comment='%s'") % strRefered % strComment) << std::endl;
if (naValidator.setNodePublic(strRefered))
{
@@ -781,6 +781,8 @@ void UniqueNodeList::processValidators(const std::string& strSite, const std::st
}
fetchDirty();
return iValues;
}
// Given a section with IPs, parse and persist it for a validator.
@@ -823,7 +825,7 @@ void UniqueNodeList::getIpsUrl(const NewcoinAddress& naNodePublic, section secSi
}
}
// Given a section with validators, parse and persist it.
// After fetching a newcoin.txt from a web site, given a section with validators, parse and persist it.
void UniqueNodeList::responseValidators(const std::string& strValidatorsUrl, const NewcoinAddress& naNodePublic, section secSite, const std::string& strSite, const boost::system::error_code& err, const std::string strValidatorsFile)
{
if (!err)
@@ -1137,10 +1139,11 @@ int UniqueNodeList::iSourceScore(validatorSource vsWhy)
int iScore = 0;
switch (vsWhy) {
case vsConfig: iScore = 1500; break;
case vsManual: iScore = 1500; break;
case vsReferral: iScore = 0; break;
case vsValidator: iScore = 1000; break;
case vsWeb: iScore = 200; break;
case vsReferral: iScore = 0; break;
default:
throw std::runtime_error("Internal error: bad validatorSource.");
}
@@ -1485,34 +1488,34 @@ Json::Value UniqueNodeList::getUnlJson()
return ret;
}
bool UniqueNodeList::nodeLoad()
bool UniqueNodeList::nodeLoad(boost::filesystem::path pConfig)
{
if (theConfig.UNL_DEFAULT.empty())
if (pConfig.empty())
{
std::cerr << "UNL_DEFAULT not specified." << std::endl;
std::cerr << VALIDATORS_FILE_NAME " path not specified." << std::endl;
return false;
}
if (!boost::filesystem::exists(theConfig.UNL_DEFAULT))
if (!boost::filesystem::exists(pConfig))
{
std::cerr << str(boost::format("UNL_DEFAULT not found: %s") % theConfig.UNL_DEFAULT) << std::endl;
std::cerr << str(boost::format(VALIDATORS_FILE_NAME " not found: %s") % pConfig) << std::endl;
return false;
}
if (!boost::filesystem::is_regular_file(theConfig.UNL_DEFAULT))
if (!boost::filesystem::is_regular_file(pConfig))
{
std::cerr << str(boost::format("UNL_DEFAULT not regular file: %s") % theConfig.UNL_DEFAULT) << std::endl;
std::cerr << str(boost::format(VALIDATORS_FILE_NAME " not regular file: %s") % pConfig) << std::endl;
return false;
}
std::ifstream ifsDefault(theConfig.UNL_DEFAULT.native().c_str(), std::ios::in);
std::ifstream ifsDefault(pConfig.native().c_str(), std::ios::in);
if (!ifsDefault)
{
std::cerr << str(boost::format("Failed to open: %s") % theConfig.UNL_DEFAULT) << std::endl;
std::cerr << str(boost::format(VALIDATORS_FILE_NAME " failed to open: %s") % pConfig) << std::endl;
return false;
}
@@ -1524,14 +1527,14 @@ bool UniqueNodeList::nodeLoad()
if (ifsDefault.bad())
{
std::cerr << str(boost::format("Failed to read: %s") % theConfig.UNL_DEFAULT) << std::endl;
std::cerr << str(boost::format("Failed to read: %s") % pConfig) << std::endl;
return false;
}
nodeDefault(strValidators, theConfig.UNL_DEFAULT.string());
nodeProcess("local", strValidators, pConfig.string());
std::cerr << str(boost::format("Processing: %s") % theConfig.UNL_DEFAULT) << std::endl;
std::cerr << str(boost::format("Processing: %s") % pConfig) << std::endl;
return true;
}
@@ -1542,7 +1545,7 @@ void UniqueNodeList::validatorsResponse(const boost::system::error_code& err, st
if (!err)
{
nodeDefault(strResponse, VALIDATORS_SITE);
nodeProcess("network", strResponse, theConfig.VALIDATORS_SITE);
}
else
{
@@ -1554,7 +1557,7 @@ void UniqueNodeList::nodeNetwork()
{
HttpsClient::httpsGet(
theApp->getIOService(),
VALIDATORS_SITE,
theConfig.VALIDATORS_SITE,
443,
VALIDATORS_FILE_PATH,
VALIDATORS_FILE_BYTES_MAX,
@@ -1581,23 +1584,45 @@ void UniqueNodeList::nodeBootstrap()
bool bLoaded = iDomains || iNodes;
if (!bLoaded && !theConfig.UNL_DEFAULT.empty())
// Always merge in the file specified in the config.
if (!theConfig.UNL_DEFAULT.empty())
{
std::cerr << "Bootstrapping UNL: loading from file." << std::endl;
std::cerr << "Bootstrapping UNL: loading from unl_default." << std::endl;
bLoaded = nodeLoad();
bLoaded = nodeLoad(theConfig.UNL_DEFAULT);
}
// If never loaded anything try the current directory.
if (!bLoaded && theConfig.UNL_DEFAULT.empty())
{
std::cerr << "Bootstrapping UNL: loading from '" VALIDATORS_FILE_NAME "'." << std::endl;
bLoaded = nodeLoad(VALIDATORS_FILE_NAME);
}
// Always load from newcoind.cfg
if (!theConfig.VALIDATORS.empty())
{
NewcoinAddress naInvalid; // Don't want a referrer on added entries.
std::cerr << "Bootstrapping UNL: loading from " CONFIG_FILE_NAME "." << std::endl;
if (processValidators("local", CONFIG_FILE_NAME, naInvalid, vsConfig, &theConfig.VALIDATORS))
bLoaded = true;
}
if (!bLoaded)
{
std::cerr << "Bootstrapping UNL: loading from " VALIDATORS_SITE "." << std::endl;
std::cerr << "Bootstrapping UNL: loading from " << theConfig.VALIDATORS_SITE << "." << std::endl;
nodeNetwork();
}
}
// Process a validators.txt.
// --> strSite: source of validators
// --> strValidators: contents of a validators.txt
void UniqueNodeList::nodeDefault(const std::string& strValidators, const std::string& strSource) {
void UniqueNodeList::nodeProcess(const std::string& strSite, const std::string& strValidators, const std::string& strSource) {
section secValidators = ParseSection(strValidators, true);
section::mapped_type* pmtEntries = sectionEntries(secValidators, SECTION_VALIDATORS);
@@ -1606,7 +1631,7 @@ void UniqueNodeList::nodeDefault(const std::string& strValidators, const std::st
NewcoinAddress naInvalid; // Don't want a referrer on added entries.
// YYY Unspecified might be bootstrap or rpc command
processValidators("unspecified", strSource, naInvalid, vsValidator, pmtEntries);
processValidators(strSite, strSource, naInvalid, vsValidator, pmtEntries);
}
else
{

View File

@@ -32,10 +32,11 @@ class UniqueNodeList
{
public:
typedef enum {
vsConfig = 'C', // newcoind.cfg
vsManual = 'M',
vsReferral = 'R',
vsValidator = 'V', // validators.txt
vsWeb = 'W',
vsReferral = 'R',
} validatorSource;
typedef long score;
@@ -121,7 +122,7 @@ private:
void responseValidators(const std::string& strValidatorsUrl, const NewcoinAddress& naNodePublic, section secSite, const std::string& strSite, const boost::system::error_code& err, const std::string strValidatorsFile);
void processIps(const std::string& strSite, const NewcoinAddress& naNodePublic, section::mapped_type* pmtVecStrIps);
void processValidators(const std::string& strSite, const std::string& strValidatorsSrc, const NewcoinAddress& naNodePublic, validatorSource vsWhy, section::mapped_type* pmtVecStrValidators);
int processValidators(const std::string& strSite, const std::string& strValidatorsSrc, const NewcoinAddress& naNodePublic, validatorSource vsWhy, section::mapped_type* pmtVecStrValidators);
void processFile(const std::string strDomain, const NewcoinAddress& naNodePublic, section secSite);
@@ -132,7 +133,7 @@ private:
void setSeedNodes(const seedNode& snSource, bool bNext);
void validatorsResponse(const boost::system::error_code& err, std::string strResponse);
void nodeDefault(const std::string& strValidators, const std::string& strSource);
void nodeProcess(const std::string& strSite, const std::string& strValidators, const std::string& strSource);
public:
UniqueNodeList(boost::asio::io_service& io_service);
@@ -151,7 +152,7 @@ public:
bool nodeInUNL(const NewcoinAddress& naNodePublic);
void nodeBootstrap();
bool nodeLoad();
bool nodeLoad(boost::filesystem::path pConfig);
void nodeNetwork();
Json::Value getUnlJson();