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

This commit is contained in:
jed
2012-06-06 07:11:14 -07:00
33 changed files with 657 additions and 157 deletions

View File

@@ -79,7 +79,7 @@ public:
DatabaseCon* getLedgerDB() { return mLedgerDB; }
DatabaseCon* getWalletDB() { return mWalletDB; }
DatabaseCon* getHashNodeDB() { return mHashNodeDB; }
DatabaseCon* getNetNodeDB() { return mNetNodeDB; }
DatabaseCon* getNetNodeDB() { return mNetNodeDB; }
uint256 getNonce256() { return mNonce256; }
std::size_t getNonceST() { return mNonceST; }

View File

@@ -8,7 +8,8 @@
#include <boost/lexical_cast.hpp>
// Fees are in XNS raw.
#define DEFAULT_FEE_CREATE 1000
#define DEFAULT_FEE_ACCOUNT_CREATE 1000
#define DEFAULT_FEE_NICKNAME_CREATE 1000
#define DEFAULT_FEE_DEFAULT 100
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // newcoind.cfg
@@ -25,7 +26,8 @@
#define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water"
#define SECTION_NETWORK_QUORUM "network_quorum"
#define SECTION_VALIDATION_QUORUM "validation_quorum"
#define SECTION_FEE_CREATE "fee_create"
#define SECTION_FEE_ACCOUNT_CREATE "fee_account_create"
#define SECTION_FEE_NICKNAME_CREATE "fee_nickname_create"
#define SECTION_FEE_DEFAULT "fee_default"
#define SECTION_ACCOUNT_PROBE_MAX "account_probe_max"
@@ -61,7 +63,8 @@ Config::Config()
NETWORK_QUORUM = 0; // Don't need to see other nodes
VALIDATION_QUORUM = 1; // Only need one node to vouch
FEE_CREATE = DEFAULT_FEE_CREATE;
FEE_ACCOUNT_CREATE = DEFAULT_FEE_ACCOUNT_CREATE;
FEE_NICKNAME_CREATE = DEFAULT_FEE_NICKNAME_CREATE;
FEE_DEFAULT = DEFAULT_FEE_DEFAULT;
ACCOUNT_PROBE_MAX = 10;
@@ -123,8 +126,11 @@ void Config::load()
if (sectionSingleB(secConfig, SECTION_VALIDATION_QUORUM, strTemp))
VALIDATION_QUORUM = MAX(0, boost::lexical_cast<int>(strTemp));
if (sectionSingleB(secConfig, SECTION_FEE_CREATE, strTemp))
FEE_CREATE = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_FEE_ACCOUNT_CREATE, strTemp))
FEE_ACCOUNT_CREATE = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_FEE_NICKNAME_CREATE, strTemp))
FEE_NICKNAME_CREATE = boost::lexical_cast<int>(strTemp);
if (sectionSingleB(secConfig, SECTION_FEE_DEFAULT, strTemp))
FEE_DEFAULT = boost::lexical_cast<int>(strTemp);

View File

@@ -76,8 +76,9 @@ public:
std::string VALIDATION_KEY;
// Fees
uint64 FEE_CREATE; // Fee to create an account
uint64 FEE_DEFAULT; // Default fee.
uint64 FEE_DEFAULT; // Default fee.
uint64 FEE_ACCOUNT_CREATE; // Fee to create an account.
uint64 FEE_NICKNAME_CREATE; // Fee to create a nickname.
// Configuration parameters
std::string DATA_DIR;

View File

@@ -68,6 +68,8 @@ const char *WalletDBInit[] = {
FetchUpdated DATETIME \
);",
// Scoring and other information for domains.
//
// Domain:
// Domain source for https.
// PublicKey:
@@ -104,7 +106,7 @@ const char *WalletDBInit[] = {
"CREATE INDEX SeedDomainNext ON SeedDomains (Next);",
// Table of PublicKeys user has asked to trust.
// Fetches are made to the CAS.
// Fetches are made to the CAS. This gets the newcoin.txt so even validators without a web server can publish a newcoin.txt.
// Next:
// Time of next fetch attempt.
// Scan:
@@ -127,7 +129,8 @@ const char *WalletDBInit[] = {
// Allow us to easily find the next SeedNode to fetch.
"CREATE INDEX SeedNodeNext ON SeedNodes (Next);",
// Table of trusted nodes.
// Nodes we trust not grossly consipire. Derived from SeedDomains, SeedNodes, and ValidatorReferrals.
//
// Score:
// Computed trust score. Higher is better.
// Seen:

View File

@@ -153,6 +153,21 @@ AccountState::pointer Ledger::getAccountState(const NewcoinAddress& accountID)
return boost::make_shared<AccountState>(sle);
}
NicknameState::pointer Ledger::getNicknameState(const uint256& uNickname)
{
ScopedLock l(mAccountStateMap->Lock());
SHAMapItem::pointer item = mAccountStateMap->peekItem(Ledger::getNicknameIndex(uNickname));
if (!item)
{
return NicknameState::pointer();
}
SerializedLedgerEntry::pointer sle =
boost::make_shared<SerializedLedgerEntry>(item->peekSerializer(), item->getTag());
if (sle->getType() != ltNICKNAME) return NicknameState::pointer();
return boost::make_shared<NicknameState>(sle);
}
RippleState::pointer Ledger::getRippleState(const uint256& uNode)
{
ScopedLock l(mAccountStateMap->Lock());

View File

@@ -13,6 +13,7 @@
#include "Transaction.h"
#include "AccountState.h"
#include "RippleState.h"
#include "NicknameState.h"
#include "types.h"
#include "BitcoinUtil.h"
#include "SHAMap.h"
@@ -140,8 +141,6 @@ public:
LedgerStateParms writeBack(LedgerStateParms parms, SLE::pointer);
SLE::pointer getAccountRoot(LedgerStateParms& parms, const uint160& accountID);
SLE::pointer getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID);
SLE::pointer getNickname(LedgerStateParms& parms, const std::string& nickname);
SLE::pointer getNickname(LedgerStateParms& parms, const uint256& nickHash);
// database functions
static void saveAcceptedLedger(Ledger::pointer);
@@ -163,25 +162,21 @@ public:
static uint256 getGeneratorIndex(const uint160& uGeneratorID);
//
// Ripple functions
// Nickname functions
//
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency);
static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
{ return getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); }
static uint256 getNicknameHash(const std::string& strNickname)
{ Serializer s(strNickname); return s.getSHA256(); }
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB)
{ return getRippleStateIndex(naA, naB, uint160()); }
static uint256 getRippleDirIndex(const uint160& uAccountID);
NicknameState::pointer getNicknameState(const uint256& uNickname);
NicknameState::pointer getNicknameState(const std::string& strNickname)
{ return getNicknameState(getNicknameHash(strNickname)); }
RippleState::pointer getRippleState(const uint256& uNode);
SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode);
SLE::pointer getNickname(LedgerStateParms& parms, const uint256& uNickname);
SLE::pointer getNickname(LedgerStateParms& parms, const std::string& strNickname)
{ return getNickname(parms, getNicknameHash(strNickname)); }
SLE::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency)
{ return getRippleState(parms, getRippleStateIndex(naA, naB, uCurrency)); }
SLE::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
{ return getRippleState(parms, getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency)); }
static uint256 getNicknameIndex(const uint256& uNickname);
//
// Offer functions
@@ -203,6 +198,27 @@ public:
SLE::pointer getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex);
SLE::pointer getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex);
//
// Ripple functions
//
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency);
static uint256 getRippleStateIndex(const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
{ return getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency); }
static uint256 getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB)
{ return getRippleStateIndex(naA, naB, uint160()); }
static uint256 getRippleDirIndex(const uint160& uAccountID);
RippleState::pointer getRippleState(const uint256& uNode);
SLE::pointer getRippleState(LedgerStateParms& parms, const uint256& uNode);
SLE::pointer getRippleState(LedgerStateParms& parms, const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency)
{ return getRippleState(parms, getRippleStateIndex(naA, naB, uCurrency)); }
SLE::pointer getRippleState(LedgerStateParms& parms, const uint160& uiA, const uint160& uiB, const uint160& uCurrency)
{ return getRippleState(parms, getRippleStateIndex(NewcoinAddress::createAccountID(uiA), NewcoinAddress::createAccountID(uiB), uCurrency)); }
//
// Misc
//

View File

@@ -403,7 +403,6 @@ bool LedgerAcquireMaster::gotLedgerData(newcoin::TMLedgerData& packet, Peer::poi
{
if (packet.nodes_size() != 1) return false;
const newcoin::TMLedgerNode& node = packet.nodes(0);
if (!node.has_nodedata()) return false;
return ledger->takeBase(node.nodedata(), peer);
}
else if ((packet.type() == newcoin::liTX_NODE) || (packet.type() == newcoin::liAS_NODE))

View File

@@ -584,12 +584,11 @@ void LedgerConsensus::Saccept(boost::shared_ptr<LedgerConsensus> This, SHAMap::p
}
void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer ledger,
std::deque<SerializedTransaction::pointer>& failedTransactions)
std::list<SerializedTransaction::pointer>& failedTransactions)
{
TransactionEngine engine(ledger);
SHAMapItem::pointer item = set->peekFirstItem();
while (item)
for (SHAMapItem::pointer item = set->peekFirstItem(); !!item; item = set->peekNextItem(item->getTag()))
{
Log(lsINFO) << "Processing candidate transaction: " << item->getTag().GetHex();
#ifndef TRUST_NETWORK
@@ -622,14 +621,13 @@ void LedgerConsensus::applyTransactions(SHAMap::pointer set, Ledger::pointer led
Log(lsWARNING) << " Throws";
}
#endif
item = set->peekNextItem(item->getTag());
}
int successes;
do
{
successes = 0;
std::deque<SerializedTransaction::pointer>::iterator it = failedTransactions.begin();
std::list<SerializedTransaction::pointer>::iterator it = failedTransactions.begin();
while (it != failedTransactions.end())
{
try
@@ -674,7 +672,7 @@ void LedgerConsensus::accept(SHAMap::pointer set)
}
#endif
std::deque<SerializedTransaction::pointer> failedTransactions;
std::list<SerializedTransaction::pointer> failedTransactions;
applyTransactions(set, newLCL, failedTransactions);
newLCL->setClosed();
newLCL->setAccepted();

View File

@@ -2,7 +2,6 @@
#define __LEDGER_CONSENSUS__
#include <list>
#include <deque>
#include <boost/weak_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
@@ -114,7 +113,7 @@ protected:
void removePosition(LedgerProposal&, bool ours);
void sendHaveTxSet(const std::vector<uint256>& txSetHashes);
void applyTransactions(SHAMap::pointer transactionSet, Ledger::pointer targetLedger,
std::deque<SerializedTransaction::pointer>& failedTransactions);
std::list<SerializedTransaction::pointer>& failedTransactions);
// manipulating our own position
void takeInitialPosition(Ledger::pointer initialLedger);

View File

@@ -35,17 +35,16 @@ LedgerEntryFormat LedgerFormats[]=
},
{ "GeneratorMap", ltGENERATOR_MAP, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 },
// { S_FIELD(GeneratorID), STI_HASH160, SOE_REQUIRED, 0 },
{ S_FIELD(Generator), STI_VL, SOE_REQUIRED, 0 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Nickname", ltNICKNAME, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
// { S_FIELD(Nickname), STI_HASH256, SOE_REQUIRED, 0 },
{ S_FIELD(Account), STI_ACCOUNT, SOE_REQUIRED, 0 },
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(OfferCurrency), STI_HASH160, SOE_IFFLAG, 2 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x01000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},

View File

@@ -11,6 +11,29 @@ uint256 Ledger::getAccountRootIndex(const uint160& uAccountID)
return s.getSHA512Half();
}
// What is important:
// --> uNickname: is a Sha256
// <-- SHA512/2: for consistency and speed in generating indexes.
uint256 Ledger::getNicknameIndex(const uint256& uNickname)
{
Serializer s;
s.add16(spaceNickname);
s.add256(uNickname);
return s.getSHA512Half();
}
uint256 Ledger::getGeneratorIndex(const uint160& uGeneratorID)
{
Serializer s;
s.add16(spaceGenerator);
s.add160(uGeneratorID);
return s.getSHA512Half();
}
uint256 Ledger::getRippleStateIndex(const NewcoinAddress& naA, const NewcoinAddress& naB, const uint160& uCurrency)
{
uint160 uAID = naA.getAccountID();
@@ -36,16 +59,6 @@ uint256 Ledger::getRippleDirIndex(const uint160& uAccountID)
return s.getSHA512Half();
}
uint256 Ledger::getGeneratorIndex(const uint160& uGeneratorID)
{
Serializer s;
s.add16(spaceGenerator);
s.add160(uGeneratorID);
return s.getSHA512Half();
}
uint160 Ledger::getOfferBase(const uint160& currencyIn, const uint160& accountIn,
const uint160& currencyOut, const uint160& accountOut)
{

View File

@@ -6,7 +6,7 @@
#include "utils.h"
#include "Log.h"
LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SerializedLedgerEntry::pointer entry)
LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SLE::pointer entry)
{
ScopedLock l(mAccountStateMap->Lock());
bool create = false;
@@ -43,7 +43,7 @@ LedgerStateParms Ledger::writeBack(LedgerStateParms parms, SerializedLedgerEntry
return lepOKAY;
}
SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const uint256& nodeID,
SLE::pointer Ledger::getASNode(LedgerStateParms& parms, const uint256& nodeID,
LedgerEntryType let )
{
SHAMapItem::pointer account = mAccountStateMap->peekItem(nodeID);
@@ -53,23 +53,23 @@ SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const
if ( (parms & lepCREATE) == 0 )
{
parms = lepMISSING;
return SerializedLedgerEntry::pointer();
return SLE::pointer();
}
parms = parms | lepCREATED | lepOKAY;
SerializedLedgerEntry::pointer sle=boost::make_shared<SerializedLedgerEntry>(let);
SLE::pointer sle=boost::make_shared<SLE>(let);
sle->setIndex(nodeID);
return sle;
}
SerializedLedgerEntry::pointer sle =
boost::make_shared<SerializedLedgerEntry>(account->peekSerializer(), nodeID);
SLE::pointer sle =
boost::make_shared<SLE>(account->peekSerializer(), nodeID);
if(sle->getType() != let)
{ // maybe it's a currency or something
parms = parms | lepWRONGTYPE;
return SerializedLedgerEntry::pointer();
return SLE::pointer();
}
parms = parms | lepOKAY;
@@ -78,56 +78,45 @@ SerializedLedgerEntry::pointer Ledger::getASNode(LedgerStateParms& parms, const
}
SerializedLedgerEntry::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const uint160& accountID)
SLE::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const uint160& accountID)
{
uint256 nodeID=getAccountRootIndex(accountID);
return getASNode(parms, nodeID, ltACCOUNT_ROOT);
}
SerializedLedgerEntry::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID)
SLE::pointer Ledger::getAccountRoot(LedgerStateParms& parms, const NewcoinAddress& naAccountID)
{
return getAccountRoot(parms, naAccountID.getAccountID());
}
SerializedLedgerEntry::pointer Ledger::getNickname(LedgerStateParms& parms, const std::string& nickname)
{
return getNickname(parms, Serializer::getSHA512Half(nickname));
}
SerializedLedgerEntry::pointer Ledger::getNickname(LedgerStateParms& parms, const uint256& nickHash)
{
ScopedLock l(mAccountStateMap->Lock());
return getASNode(parms, nickHash, ltNICKNAME);
}
//
// Generator Map
//
SerializedLedgerEntry::pointer Ledger::getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID)
SLE::pointer Ledger::getGenerator(LedgerStateParms& parms, const uint160& uGeneratorID)
{
uint256 nodeID=getGeneratorIndex(uGeneratorID);
ScopedLock l(mAccountStateMap->Lock());
try
{
return getASNode(parms, nodeID, ltGENERATOR_MAP);
}
catch (...)
{
parms = lepERROR;
return SerializedLedgerEntry::pointer();
}
return getASNode(parms, getGeneratorIndex(uGeneratorID), ltGENERATOR_MAP);
}
//
// Nickname
//
SLE::pointer Ledger::getNickname(LedgerStateParms& parms, const uint256& uNickname)
{
ScopedLock l(mAccountStateMap->Lock());
return getASNode(parms, uNickname, ltNICKNAME);
}
//
// Ripple State
//
SerializedLedgerEntry::pointer Ledger::getRippleState(LedgerStateParms& parms, const uint256& uNode)
SLE::pointer Ledger::getRippleState(LedgerStateParms& parms, const uint256& uNode)
{
ScopedLock l(mAccountStateMap->Lock());
@@ -152,14 +141,14 @@ uint256 Ledger::getDirIndex(const uint256& uBase, const uint64 uNodeDir)
return uNode;
}
SerializedLedgerEntry::pointer Ledger::getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex)
SLE::pointer Ledger::getDirRoot(LedgerStateParms& parms, const uint256& uRootIndex)
{
ScopedLock l(mAccountStateMap->Lock());
return getASNode(parms, uRootIndex, ltDIR_ROOT);
}
SerializedLedgerEntry::pointer Ledger::getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex)
SLE::pointer Ledger::getDirNode(LedgerStateParms& parms, const uint256& uNodeIndex)
{
ScopedLock l(mAccountStateMap->Lock());

View File

@@ -210,6 +210,15 @@ STVector256 NetworkOPs::getDirNode(const uint256& uLedger, const uint256& uDirLi
return svIndexes;
}
//
// Nickname functions
//
NicknameState::pointer NetworkOPs::getNicknameState(const uint256& uLedger, const std::string& strNickname)
{
return mLedgerMaster->getLedgerByHash(uLedger)->getNicknameState(strNickname);
}
//
// Ripple functions
//

View File

@@ -4,6 +4,7 @@
#include "LedgerMaster.h"
#include "AccountState.h"
#include "RippleState.h"
#include "NicknameState.h"
// #include <boost/asio.hpp>
@@ -82,6 +83,12 @@ public:
uint256& uDirNodeFirst, uint256& uDirNodeLast);
STVector256 getDirNode(const uint256& uLedger, const uint256& uDirLineNode);
//
// Nickname functions
//
NicknameState::pointer getNicknameState(const uint256& uLedger, const std::string& strNickname);
//
// Ripple functions
//

29
src/NicknameState.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include "NicknameState.h"
NicknameState::NicknameState(SerializedLedgerEntry::pointer ledgerEntry) :
mLedgerEntry(ledgerEntry)
{
if (!mLedgerEntry || mLedgerEntry->getType() != ltNICKNAME) return;
}
bool NicknameState::haveMinimumOffer() const
{
return mLedgerEntry->getIFieldPresent(sfMinimumOffer);
}
STAmount NicknameState::getMinimumOffer() const
{
return mLedgerEntry->getIFieldPresent(sfMinimumOffer)
? mLedgerEntry->getIValueFieldAmount(sfMinimumOffer)
: STAmount();
}
NewcoinAddress NicknameState::getAccountID() const
{
return mLedgerEntry->getIValueFieldAccount(sfAccount);
}
void NicknameState::addJson(Json::Value& val)
{
val = mLedgerEntry->getJson(0);
}

37
src/NicknameState.h Normal file
View File

@@ -0,0 +1,37 @@
#ifndef _NICKNAMESTATE_
#define _NICKNAMESTATE_
//
// State of a nickname node.
// - Isolate ledger entry format.
//
#include "SerializedLedger.h"
#include <boost/shared_ptr.hpp>
class NicknameState
{
public:
typedef boost::shared_ptr<NicknameState> pointer;
private:
SerializedLedgerEntry::pointer mLedgerEntry;
public:
NicknameState(SerializedLedgerEntry::pointer ledgerEntry); // For accounts in a ledger
bool haveMinimumOffer() const;
STAmount getMinimumOffer() const;
NewcoinAddress getAccountID() const;
SerializedLedgerEntry::pointer getSLE() { return mLedgerEntry; }
const SerializedLedgerEntry& peekSLE() const { return *mLedgerEntry; }
SerializedLedgerEntry& peekSLE() { return *mLedgerEntry; }
std::vector<unsigned char> getRaw() const;
void addJson(Json::Value& value);
};
#endif
// vim:ts=4

View File

@@ -6,7 +6,7 @@
#define SECTION_DEFAULT_NAME ""
section ParseSection(const std::string strInput, const bool bTrim)
section ParseSection(const std::string& strInput, const bool bTrim)
{
std::string strData(strInput);
std::vector<std::string> vLines;
@@ -66,7 +66,7 @@ void PrintSection(section secInput)
std::cerr << "PrintSection<" << std::endl;
}
section::mapped_type* sectionEntries(section& secSource, const std::string strSection)
section::mapped_type* sectionEntries(section& secSource, const std::string& strSection)
{
section::iterator it;
section::mapped_type* smtResult;
@@ -86,14 +86,14 @@ section::mapped_type* sectionEntries(section& secSource, const std::string strSe
return smtResult;
}
int sectionCount(section& secSource, std::string strSection)
int sectionCount(section& secSource, const std::string& strSection)
{
section::mapped_type* pmtEntries = sectionEntries(secSource, strSection);
return pmtEntries ? -1 : pmtEntries->size();
}
bool sectionSingleB(section& secSource, const std::string strSection, std::string& strValue)
bool sectionSingleB(section& secSource, const std::string& strSection, std::string& strValue)
{
section::mapped_type* pmtEntries = sectionEntries(secSource, strSection);
bool bSingle = pmtEntries && 1 == pmtEntries->size();

View File

@@ -7,10 +7,10 @@
typedef std::map<const std::string, std::vector<std::string> > section;
section ParseSection(const std::string strInput, const bool bTrim);
section ParseSection(const std::string& strInput, const bool bTrim);
void PrintSection(section secInput);
bool sectionSingleB(section& secSource, const std::string strSection, std::string& strValue);
int sectionCount(section& secSource, std::string strSection);
section::mapped_type* sectionEntries(section& secSource, 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);
#endif

View File

@@ -800,6 +800,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
if(packet.itype() == newcoin::liBASE)
{ // they want the ledger base data
Log(lsTRACE) << "Want ledger base data";
Serializer nData(128);
ledger->addRaw(nData);
reply.add_nodes()->set_nodedata(nData.getDataPtr(), nData.getLength());
@@ -834,6 +835,7 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
{
std::vector<SHAMapNode>::iterator nodeIDIterator;
std::list< std::vector<unsigned char> >::iterator rawNodeIterator;
int count = 0;
for(nodeIDIterator = nodeIDs.begin(), rawNodeIterator = rawNodes.begin();
nodeIDIterator != nodeIDs.end(); ++nodeIDIterator, ++rawNodeIterator)
{
@@ -842,7 +844,9 @@ void Peer::recvGetLedger(newcoin::TMGetLedger& packet)
newcoin::TMLedgerNode* node = reply.add_nodes();
node->set_nodeid(nID.getDataPtr(), nID.getLength());
node->set_nodedata(&rawNodeIterator->front(), rawNodeIterator->size());
++count;
}
Log(lsTRACE) << "GetNodeFat: sending " << count << " nodes";
}
}
PackedMessage::pointer oPacket = boost::make_shared<PackedMessage>(reply, newcoin::mtLEDGER_DATA);
@@ -875,12 +879,12 @@ void Peer::recvLedger(newcoin::TMLedgerData& packet)
for (int i = 0; i < packet.nodes().size(); ++i)
{
const newcoin::TMLedgerNode& node = packet.nodes(i);
if (!node.has_nodeid() || !node.has_nodedata())
if (!node.has_nodeid() || !node.has_nodedata() || (node.nodeid().size() != 33))
{
Log(lsWARNING) << "LedgerData request with invalid node ID";
punishPeer(PP_INVALID_REQUEST);
return;
}
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
}

View File

@@ -22,6 +22,7 @@
#include "Conversion.h"
#include "NewcoinAddress.h"
#include "AccountState.h"
#include "NicknameState.h"
#include "utils.h"
#define VALIDATORS_FETCH_SECONDS 30
@@ -215,7 +216,7 @@ Json::Value RPCServer::getMasterGenerator(const uint256& uLedger, const NewcoinA
Json::Value RPCServer::authorize(const uint256& uLedger,
const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID,
NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate,
STAmount& saSrcBalance, uint64 uFee, AccountState::pointer& asSrc,
STAmount& saSrcBalance, const STAmount& saFee, AccountState::pointer& asSrc,
const NewcoinAddress& naVerifyGenerator)
{
// Source/paying account must exist.
@@ -276,13 +277,13 @@ Json::Value RPCServer::authorize(const uint256& uLedger,
saSrcBalance = asSrc->getBalance();
if (saSrcBalance < uFee)
if (saSrcBalance < saFee)
{
return JSONRPCError(500, "insufficent funds");
}
else
{
saSrcBalance -= uFee;
saSrcBalance -= saFee;
}
return obj;
@@ -779,7 +780,7 @@ Json::Value RPCServer::doCreditSet(Json::Value& params)
}
else if (!saLimitAmount.setValue(params[3u].asString(), params.size() >= 5 ? params[4u].asString() : ""))
{
return JSONRPCError(500, "bad src amount/currency");
return JSONRPCError(400, "bad src amount/currency");
}
else if (!mNetOps->available())
{
@@ -826,6 +827,144 @@ Json::Value RPCServer::doCreditSet(Json::Value& params)
}
}
// nickname_info <nickname>
// Note: Nicknames are not automatically looked up by commands as they are advisory and can be changed.
Json::Value RPCServer::doNicknameInfo(Json::Value& params)
{
uint256 uLedger;
if (params.size() != 1)
{
return JSONRPCError(400, "invalid params");
}
std::string strNickname = params[0u].asString();
boost::trim(strNickname);
if (strNickname.empty())
{
return JSONRPCError(400, "invalid nickname (zero length)");
}
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else if ((uLedger = mNetOps->getCurrentLedger()).isZero())
{
return JSONRPCError(503, "no current ledger");
}
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname);
if (!nsSrc)
{
return JSONRPCError(500, "nickname does not exist");
}
Json::Value ret(Json::objectValue);
ret["nickname"] = strNickname;
nsSrc->addJson(ret);
return ret;
}
// nickname_set <seed> <paying_account> <nickname> [<offer_minimum>] [<authorization>]
Json::Value RPCServer::doNicknameSet(Json::Value& params)
{
NewcoinAddress naSrcAccountID;
NewcoinAddress naSeed;
uint256 uLedger;
if (params.size() < 2 || params.size() > 3)
{
return JSONRPCError(400, "invalid params");
}
else if (!naSeed.setFamilySeedGeneric(params[0u].asString()))
{
return "disallowed seed";
}
else if (!naSrcAccountID.setAccountID(params[1u].asString()))
{
return "bad source account id needed";
}
STAmount saMinimumOffer;
bool bSetOffer = params.size() >= 4;
std::string strOfferCurrency;
std::string strNickname = params[2u].asString();
boost::trim(strNickname);
std::vector<unsigned char> vucSignature;
if (strNickname.empty())
{
return JSONRPCError(400, "invalid nickname (zero length)");
}
else if (params.size() >= 4 && !saMinimumOffer.setValue(params[3u].asString(), strOfferCurrency))
{
return JSONRPCError(400, "bad dst amount/currency");
}
else if (!mNetOps->available())
{
return JSONRPCError(503, "network not available");
}
else if ((uLedger = mNetOps->getCurrentLedger()).isZero())
{
return JSONRPCError(503, "no current ledger");
}
STAmount saFee;
NicknameState::pointer nsSrc = mNetOps->getNicknameState(uLedger, strNickname);
if (!nsSrc)
{
// Creating nickname.
saFee = theConfig.FEE_NICKNAME_CREATE;
}
else if (naSrcAccountID != nsSrc->getAccountID())
{
// We don't own the nickname.
return JSONRPCError(400, "account does not control nickname");
}
else
{
// Setting the minimum offer.
saFee = theConfig.FEE_DEFAULT;
}
NewcoinAddress naMasterGenerator;
NewcoinAddress naAccountPublic;
NewcoinAddress naAccountPrivate;
AccountState::pointer asSrc;
STAmount saSrcBalance;
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
saSrcBalance, saFee, asSrc, naMasterGenerator);
if (!obj.empty())
return obj;
// YYY Could verify nickname does not exist or points to paying account.
// XXX Adjust fee for nickname create.
Transaction::pointer trans = Transaction::sharedNicknameSet(
naAccountPublic, naAccountPrivate,
naSrcAccountID,
asSrc->getSeq(),
saFee,
0, // YYY No source tag
Ledger::getNicknameHash(strNickname),
bSetOffer,
saMinimumOffer,
vucSignature);
(void) mNetOps->processTransaction(trans);
obj["transaction"] = trans->getSTransaction()->getJson(0);
obj["status"] = trans->getStatus();
return obj;
}
// password_fund <seed> <paying_account> [<account>]
// YYY Make making account default to first account for seed.
Json::Value RPCServer::doPasswordFund(Json::Value &params)
@@ -1033,11 +1172,11 @@ Json::Value RPCServer::doSend(Json::Value& params)
}
else if (!saDstAmount.setValue(params[3u].asString(), sDstCurrency))
{
return JSONRPCError(500, "bad dst amount/currency");
return JSONRPCError(400, "bad dst amount/currency");
}
else if (params.size() >= 6 && !saSrcAmount.setValue(params[5u].asString(), sSrcCurrency))
{
return JSONRPCError(500, "bad src amount/currency");
return JSONRPCError(400, "bad src amount/currency");
}
else if (!mNetOps->available())
{
@@ -1216,7 +1355,7 @@ Json::Value RPCServer::doLedger(Json::Value& params)
return "not implemented";
}
// unl_add <domain><node_public> [<comment>]
// unl_add <domain>|<node_public> [<comment>]
Json::Value RPCServer::doUnlAdd(Json::Value& params)
{
if (params.size() == 1 || params.size() == 2)
@@ -1401,7 +1540,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params)
}
else if (params.size() >= 4 && !saAmount.setValue(params[3u].asString(), sDstCurrency))
{
return JSONRPCError(500, "bad dst amount/currency");
return JSONRPCError(400, "bad dst amount/currency");
}
else if (!mNetOps->available())
{
@@ -1424,7 +1563,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params)
AccountState::pointer asSrc;
STAmount saSrcBalance;
Json::Value obj = authorize(uLedger, naRegularSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
saSrcBalance, theConfig.FEE_CREATE, asSrc, naMasterGenerator);
saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator);
if (!obj.empty())
return obj;
@@ -1471,7 +1610,7 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params)
naAccountPublic, naAccountPrivate,
naSrcAccountID,
asSrc->getSeq(),
theConfig.FEE_CREATE,
theConfig.FEE_ACCOUNT_CREATE,
0, // YYY No source tag
saAmount,
naAuthKeyID,
@@ -1632,7 +1771,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params)
AccountState::pointer asSrc;
STAmount saSrcBalance;
Json::Value obj = authorize(uLedger, naSeed, naSrcAccountID, naAccountPublic, naAccountPrivate,
saSrcBalance, theConfig.FEE_CREATE, asSrc, naMasterGenerator);
saSrcBalance, theConfig.FEE_ACCOUNT_CREATE, asSrc, naMasterGenerator);
if (!obj.empty())
return obj;
@@ -1646,7 +1785,7 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params)
naAccountPublic, naAccountPrivate,
naSrcAccountID,
asSrc->getSeq(),
theConfig.FEE_CREATE,
theConfig.FEE_ACCOUNT_CREATE,
0, // YYY No source tag
naDstAccountID,
saInitialFunds); // Initial funds in XNC.
@@ -1867,6 +2006,8 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
if (command == "account_wallet_set") return doAccountWalletSet(params);
if (command == "connect") return doConnect(params);
if (command == "credit_set") return doCreditSet(params);
if (command == "nickname_info") return doNicknameInfo(params);
if (command == "nickname_set") return doNicknameSet(params);
if (command == "password_fund") return doPasswordFund(params);
if (command == "password_set") return doPasswordSet(params);
if (command == "peers") return doPeers(params);

View File

@@ -42,7 +42,7 @@ private:
Json::Value getMasterGenerator(const uint256& uLedger, const NewcoinAddress& naRegularSeed, NewcoinAddress& naMasterGenerator);
Json::Value authorize(const uint256& uLedger, const NewcoinAddress& naRegularSeed, const NewcoinAddress& naSrcAccountID,
NewcoinAddress& naAccountPublic, NewcoinAddress& naAccountPrivate,
STAmount& saSrcBalance, uint64 uFee, AccountState::pointer& asSrc,
STAmount& saSrcBalance, const STAmount& saFee, AccountState::pointer& asSrc,
const NewcoinAddress& naVerifyGenerator);
Json::Value accounts(const uint256& uLedger, const NewcoinAddress& naMasterGenerator);
@@ -56,6 +56,8 @@ private:
Json::Value doConnect(Json::Value& params);
Json::Value doCreditSet(Json::Value& params);
Json::Value doLedger(Json::Value& params);
Json::Value doNicknameInfo(Json::Value& params);
Json::Value doNicknameSet(Json::Value& params);
Json::Value doPasswordFund(Json::Value& params);
Json::Value doPasswordSet(Json::Value& params);
Json::Value doPeers(Json::Value& params);

View File

@@ -3,6 +3,7 @@
//
// A ripple line's state.
// - Isolate ledger entry format.
//
#include "SerializedLedger.h"

View File

@@ -1,6 +1,7 @@
#include "SerializedLedger.h"
#include <boost/format.hpp>
SerializedLedgerEntry::SerializedLedgerEntry(SerializerIterator& sit, const uint256& index)
: SerializedType("LedgerEntry"), mIndex(index)
{
@@ -47,12 +48,10 @@ std::string SerializedLedgerEntry::getFullText() const
std::string SerializedLedgerEntry::getText() const
{
std::string ret = "{";
ret += mIndex.GetHex();
ret += mVersion.getText();
ret += mObject.getText();
ret += "}";
return ret;
return str(boost::format("{ %s, %s, %s }")
% mIndex.GetHex()
% mVersion.getText()
% mObject.getText());
}
Json::Value SerializedLedgerEntry::getJson(int options) const

View File

@@ -259,6 +259,49 @@ Transaction::pointer Transaction::sharedCreditSet(
return tResult->setCreditSet(naPrivateKey, naDstAccountID, saLimitAmount, uAcceptRate);
}
//
// NicknameSet
//
Transaction::pointer Transaction::setNicknameSet(
const NewcoinAddress& naPrivateKey,
const uint256& uNickname,
bool bSetOffer,
const STAmount& saMinimumOffer,
const std::vector<unsigned char>& vucSignature)
{
mTransaction->setITFieldH256(sfNickname, uNickname);
// XXX Make sure field is present even for 0!
if (bSetOffer)
mTransaction->setITFieldAmount(sfMinimumOffer, saMinimumOffer);
if (!vucSignature.empty())
mTransaction->setITFieldVL(sfSignature, vucSignature);
sign(naPrivateKey);
return shared_from_this();
}
// --> bSetOffer: true, change offer
// --> saMinimumOffer: 0 to remove.
Transaction::pointer Transaction::sharedNicknameSet(
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naSourceAccount,
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const uint256& uNickname,
bool bSetOffer,
const STAmount& saMinimumOffer,
const std::vector<unsigned char>& vucSignature)
{
pointer tResult = boost::make_shared<Transaction>(ttNICKNAME_SET, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag);
return tResult->setNicknameSet(naPrivateKey, uNickname, bSetOffer, saMinimumOffer, vucSignature);
}
//
// PasswordFund
//

View File

@@ -71,6 +71,13 @@ private:
const STAmount& saLimitAmount,
uint32 uAcceptRate);
Transaction::pointer setNicknameSet(
const NewcoinAddress& naPrivateKey,
const uint256& uNickname,
bool bSetOffer,
const STAmount& saMinimumOffer,
const std::vector<unsigned char>& vucSignature);
Transaction::pointer setPasswordFund(
const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naDstAccountID);
@@ -157,6 +164,18 @@ public:
const STAmount& saLimitAmount,
uint32 uAcceptRate);
// Set Nickname
static Transaction::pointer sharedNicknameSet(
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,
const NewcoinAddress& naSourceAccount,
uint32 uSeq,
const STAmount& saFee,
uint32 uSourceTag,
const uint256& uNickname,
bool bSetOffer,
const STAmount& saMinimumOffer,
const std::vector<unsigned char>& vucSignature);
// Pre-fund password change.
static Transaction::pointer sharedPasswordFund(
const NewcoinAddress& naPublicKey, const NewcoinAddress& naPrivateKey,

View File

@@ -259,7 +259,7 @@ TransactionEngineResult TransactionEngine::setAuthorized(const SerializedTransac
sleGen = boost::make_shared<SerializedLedgerEntry>(ltGENERATOR_MAP);
sleGen->setIndex(Ledger::getGeneratorIndex(hGeneratorID));
sleGen->setIFieldH160(sfGeneratorID, hGeneratorID);
// sleGen->setIFieldH160(sfGeneratorID, hGeneratorID);
sleGen->setIFieldVL(sfGenerator, vucCipher);
accounts.push_back(std::make_pair(taaCREATE, sleGen));
@@ -364,7 +364,17 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
case ttPAYMENT:
if (txn.getFlags() & tfCreateAccount)
{
saCost = theConfig.FEE_CREATE;
saCost = theConfig.FEE_ACCOUNT_CREATE;
}
break;
case ttNICKNAME_SET:
{
LedgerStateParms qry = lepNONE;
SLE::pointer sleNickname = mLedger->getNickname(qry, txn.getITFieldH256(sfNickname));
if (!sleNickname)
saCost = theConfig.FEE_NICKNAME_CREATE;
}
break;
@@ -473,7 +483,7 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
{
std::cerr << "applyTransaction: Source is an unclaimed account." << std::endl;
result = tenUNCLAIMED;
result = terUNCLAIMED;
}
break;
}
@@ -514,9 +524,9 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
// Verify the transaction's signing public key is the key authorized for signing.
if (naSigningPubKey.getAccountID() != sleSrc->getIValueFieldAccount(sfAuthorizedKey).getAccountID())
{
std::cerr << "applyTransaction: Not authorized to use account." << std::endl;
std::cerr << "applyTransaction: Delay: Not authorized to use account." << std::endl;
result = tenBAD_AUTH;
result = terBAD_AUTH;
}
break;
}
@@ -554,7 +564,6 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
Log(lsINFO) << "Aseq=" << a_seq << ", Tseq=" << t_seq;
if (t_seq != a_seq)
{
// WRITEME: Special case code for changing transaction key
if (a_seq < t_seq)
{
std::cerr << "applyTransaction: future sequence number" << std::endl;
@@ -623,6 +632,10 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
result = doOffer(txn, accounts);
break;
case ttNICKNAME_SET:
result = doNicknameSet(txn, accounts, srcAccountID);
break;
case ttPASSWORD_FUND:
result = doPasswordFund(txn, accounts, srcAccountID);
break;
@@ -651,7 +664,6 @@ TransactionEngineResult TransactionEngine::applyTransaction(const SerializedTran
if (terSUCCESS == result)
{ // Write back the account states and add the transaction to the ledger
// WRITEME: Special case code for changing transaction key
for (std::vector<AffectedAccount>::iterator it = accounts.begin(), end = accounts.end();
it != end; ++it)
{
@@ -870,6 +882,60 @@ TransactionEngineResult TransactionEngine::doCreditSet(const SerializedTransacti
return terResult;
}
TransactionEngineResult TransactionEngine::doNicknameSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, const uint160& uSrcAccountID)
{
std::cerr << "doNicknameSet>" << std::endl;
SLE::pointer sleSrc = accounts[0].second;
uint256 uNickname = txn.getITFieldH256(sfNickname);
bool bMinOffer = txn.getITFieldPresent(sfMinimumOffer);
STAmount saMinOffer = bMinOffer ? txn.getITFieldAmount(sfAmount) : STAmount();
LedgerStateParms qry = lepNONE;
SLE::pointer sleNickname = mLedger->getNickname(qry, uNickname);
if (sleNickname)
{
// Edit old entry.
sleNickname->setIFieldAccount(sfAccount, uSrcAccountID);
if (bMinOffer && !saMinOffer.isZero())
{
sleNickname->setIFieldAmount(sfMinimumOffer, saMinOffer);
}
else
{
sleNickname->makeIFieldAbsent(sfMinimumOffer);
}
accounts.push_back(std::make_pair(taaMODIFY, sleNickname));
}
else
{
// Make a new entry.
// XXX Need to include authorization limiting.
sleNickname = boost::make_shared<SerializedLedgerEntry>(ltNICKNAME);
sleNickname->setIndex(Ledger::getNicknameIndex(uNickname));
std::cerr << "doNicknameSet: Creating nickname node: " << sleNickname->getIndex().ToString() << std::endl;
sleNickname->setIFieldAccount(sfAccount, uSrcAccountID);
if (bMinOffer && !saMinOffer.isZero())
sleNickname->setIFieldAmount(sfMinimumOffer, saMinOffer);
// sleNickname->setIFieldH256(sfNickname, uNickname);
accounts.push_back(std::make_pair(taaCREATE, sleNickname));
}
std::cerr << "doNicknameSet<" << std::endl;
return terSUCCESS;
}
TransactionEngineResult TransactionEngine::doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts, const uint160& uSrcAccountID)
{
std::cerr << "doPasswordFund>" << std::endl;

View File

@@ -24,9 +24,7 @@ enum TransactionEngineResult
tenBAD_SET_ID, // Malformed.
// Invalid: Ledger won't allow.
tenUNCLAIMED = -200, // Can not use an unclaimed account.
tenCLAIMED, // Can not claim a previously claimed account.
tenBAD_AUTH, // Transaction's public key is not authorized.
tenCLAIMED = -200, // Can not claim a previously claimed account.
tenCREATED, // Can't add an already created account.
tenMSG_SET, // Can't change a message key.
@@ -60,6 +58,8 @@ enum TransactionEngineResult
terNO_LINE_NO_ZERO, // Can't zero non-existant line, destination might make it.
terSET_MISSING_DST, // Can't set password, destination missing.
terFUNDS_SPENT, // Can't set password, password set funds already spent.
terUNCLAIMED, // Can not use an unclaimed account.
terBAD_AUTH, // Transaction's public key is not authorized.
};
enum TransactionEngineParams
@@ -108,6 +108,8 @@ protected:
TransactionEngineResult doDelete(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doInvoice(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doOffer(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
TransactionEngineResult doNicknameSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
const uint160& uSrcAccountID);
TransactionEngineResult doPasswordFund(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts,
const uint160& uSrcAccountID);
TransactionEngineResult doPasswordSet(const SerializedTransaction& txn, std::vector<AffectedAccount>& accounts);
@@ -125,7 +127,7 @@ public:
Ledger::pointer getDefaultLedger() { return mDefaultLedger; }
void setDefaultLedger(Ledger::pointer ledger) { mDefaultLedger = ledger; }
Ledger::pointer getAlternateLedger() { return mAlternateLedger; }
void setAlternateLedger(Ledger::pointer ledger) { mDefaultLedger = ledger; }
void setAlternateLedger(Ledger::pointer ledger) { mAlternateLedger = ledger; }
void setLedger(Ledger::pointer ledger) { mDefaultLedger = ledger;
mAlternateLedger = Ledger::pointer(); }

View File

@@ -44,6 +44,15 @@ TransactionFormat InnerTxnFormats[]=
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "NicknameSet", ttNICKNAME_SET, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(Nickname), STI_HASH256, SOE_IFFLAG, 8 },
{ S_FIELD(MinimumOffer), STI_AMOUNT, SOE_IFFLAG, 1 },
{ S_FIELD(Signature), STI_VL, SOE_IFFLAG, 2 },
{ S_FIELD(SourceTag), STI_UINT32, SOE_IFFLAG, 1 },
{ S_FIELD(Extensions), STI_TL, SOE_IFFLAG, 0x02000000 },
{ sfInvalid, NULL, STI_DONE, SOE_NEVER, -1 } }
},
{ "Offer", ttOFFER, {
{ S_FIELD(Flags), STI_UINT32, SOE_FLAGS, 0 },
{ S_FIELD(AmountIn), STI_AMOUNT, SOE_REQUIRED, 0 },

View File

@@ -12,6 +12,7 @@ enum TransactionType
ttACCOUNT_SET = 3,
ttPASSWORD_FUND = 4,
ttPASSWORD_SET = 5,
ttNICKNAME_SET = 6,
ttCREDIT_SET = 20,
ttTRANSIT_SET = 21,
ttINVOICE = 10,

View File

@@ -40,6 +40,8 @@ UniqueNodeList::UniqueNodeList(boost::asio::io_service& io_service) :
{
}
// This is called when the application is started.
// Get update times and start fetching and scoring as needed.
void UniqueNodeList::start()
{
miscLoad();
@@ -51,6 +53,7 @@ void UniqueNodeList::start()
scoreNext(false); // Start scoring.
}
// Load information about when we last updated.
bool UniqueNodeList::miscLoad()
{
ScopedLock sl(theApp->getWalletDB()->getDBLock());
@@ -65,9 +68,12 @@ bool UniqueNodeList::miscLoad()
db->endIterRows();
trustedLoad();
return true;
}
// Persist update information.
bool UniqueNodeList::miscSave()
{
Database* db=theApp->getWalletDB()->getDB();
@@ -80,6 +86,25 @@ bool UniqueNodeList::miscSave()
return true;
}
void UniqueNodeList::trustedLoad()
{
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
ScopedLock slUNL(mUNLLock);
mUNL.clear();
SQL_FOREACH(db, "SELECT PublicKey FROM TrustedNodes WHERE Score != 0;")
{
std::string strPublicKey;
db->getStr("PublicKey", strPublicKey);
mUNL.insert(strPublicKey);
}
}
// For a round of scoring we destribute points from a node to nodes it refers to.
// Returns true, iff scores were distributed.
bool UniqueNodeList::scoreRound(std::vector<scoreNode>& vsnNodes)
{
@@ -143,6 +168,7 @@ bool UniqueNodeList::scoreRound(std::vector<scoreNode>& vsnNodes)
return bDist;
}
// From SeedDomains and ValidatorReferrals compute scores and update TrustedNodes.
void UniqueNodeList::scoreCompute()
{
strIndex umPulicIdx; // Map of public key to index.
@@ -271,6 +297,9 @@ void UniqueNodeList::scoreCompute()
}
}
//
// Distribute the points from the seeds.
//
bool bDist = true;
for (int i = SCORE_ROUNDS; bDist && i--;)
@@ -289,6 +318,7 @@ void UniqueNodeList::scoreCompute()
<< std::endl;
}
// Persist validator scores.
ScopedLock sl(theApp->getWalletDB()->getDBLock());
db->executeSQL("BEGIN;");
@@ -317,9 +347,11 @@ void UniqueNodeList::scoreCompute()
}
}
boost::unordered_set<std::string> usUNL;
if (vsnNodes.size())
{
// Update old entries and add new ones.
// Update the score old entries and add new entries as needed.
std::vector<std::string> vstrValues;
vstrValues.resize(vsnNodes.size());
@@ -333,12 +365,20 @@ void UniqueNodeList::scoreCompute()
% db->escape(sn.strValidator)
% sn.iScore
% strSeen);
usUNL.insert(sn.strValidator);
}
db->executeSQL(str(boost::format("REPLACE INTO TrustedNodes (PublicKey,Score,Seen) VALUES %s;")
% strJoin(vstrValues.begin(), vstrValues.end(), ",")));
}
{
ScopedLock sl(mUNLLock);
mUNL.swap(usUNL);
}
// Score IPs.
db->executeSQL("UPDATE PeerIps SET Score = 0 WHERE Score != 0;");
@@ -507,7 +547,10 @@ void UniqueNodeList::fetchDirty()
scoreNext(false);
}
void UniqueNodeList::processIps(const std::string& strSite, NewcoinAddress naNodePublic, section::mapped_type* pmtVecStrIps)
// Persist the IPs refered to by a Validator.
// --> strSite: source of the IPs (for debugging)
// --> naNodePublic: public key of the validating node.
void UniqueNodeList::processIps(const std::string& strSite, const NewcoinAddress& naNodePublic, section::mapped_type* pmtVecStrIps)
{
Database* db=theApp->getWalletDB()->getDB();
@@ -590,7 +633,8 @@ void UniqueNodeList::processIps(const std::string& strSite, NewcoinAddress naNod
fetchDirty();
}
void UniqueNodeList::processValidators(const std::string& strSite, const std::string& strValidatorsSrc, NewcoinAddress naNodePublic, section::mapped_type* pmtVecStrValidators)
// Persist ValidatorReferrals.
void UniqueNodeList::processValidators(const std::string& strSite, const std::string& strValidatorsSrc, const NewcoinAddress& naNodePublic, section::mapped_type* pmtVecStrValidators)
{
Database* db=theApp->getWalletDB()->getDB();
@@ -651,7 +695,8 @@ void UniqueNodeList::processValidators(const std::string& strSite, const std::st
fetchDirty();
}
void UniqueNodeList::responseIps(const std::string& strSite, NewcoinAddress naNodePublic, const boost::system::error_code& err, const std::string strIpsFile)
// Given a section with IPs, parse and persist it for a validator.
void UniqueNodeList::responseIps(const std::string& strSite, const NewcoinAddress& naNodePublic, const boost::system::error_code& err, const std::string strIpsFile)
{
if (!err)
{
@@ -663,9 +708,8 @@ void UniqueNodeList::responseIps(const std::string& strSite, NewcoinAddress naNo
fetchFinish();
}
//
// Process [ips_url]
//
// Process section [ips_url].
// If we have a section with a single entry, fetch the url and process it.
void UniqueNodeList::getIpsUrl(NewcoinAddress naNodePublic, section secSite)
{
std::string strIpsUrl;
@@ -691,6 +735,7 @@ void UniqueNodeList::getIpsUrl(NewcoinAddress naNodePublic, section secSite)
}
}
// Given a section with validators, parse and persist it.
void UniqueNodeList::responseValidators(const std::string& strValidatorsUrl, NewcoinAddress naNodePublic, section secSite, const std::string& strSite, const boost::system::error_code& err, const std::string strValidatorsFile)
{
if (!err)
@@ -703,9 +748,7 @@ void UniqueNodeList::responseValidators(const std::string& strValidatorsUrl, New
getIpsUrl(naNodePublic, secSite);
}
//
// Process [validators_url]
//
// Process section [validators_url].
void UniqueNodeList::getValidatorsUrl(NewcoinAddress naNodePublic, section secSite)
{
std::string strValidatorsUrl;
@@ -758,6 +801,7 @@ void UniqueNodeList::processFile(const std::string strDomain, NewcoinAddress naN
getValidatorsUrl(naNodePublic, secSite);
}
// Given a newcoin.txt, process it.
void UniqueNodeList::responseFetch(const std::string strDomain, const boost::system::error_code& err, const std::string strSiteFile)
{
section secSite = ParseSection(strSiteFile, true);
@@ -838,7 +882,7 @@ void UniqueNodeList::responseFetch(const std::string strDomain, const boost::sys
seedDomain sdCurrent;
bool bFound = getSeedDomains(strDomain, sdCurrent);
bool bFound = getSeedDomains(strDomain, sdCurrent);
assert(bFound);
@@ -910,7 +954,7 @@ void UniqueNodeList::fetchTimerHandler(const boost::system::error_code& err)
}
}
// Try to process the next fetch.
// Try to process the next fetch of a newcoin.txt.
void UniqueNodeList::fetchNext()
{
bool bFull;
@@ -999,6 +1043,7 @@ void UniqueNodeList::fetchNext()
}
}
// For each kind of source, have a starting number of points to be distributed.
int UniqueNodeList::iSourceScore(validatorSource vsWhy)
{
int iScore = 0;
@@ -1056,6 +1101,7 @@ void UniqueNodeList::nodeAddDomain(const std::string& strDomain, validatorSource
setSeedDomains(sdCurrent, true);
}
// Retrieve a SeedDomain for DB.
bool UniqueNodeList::getSeedDomains(const std::string& strDomain, seedDomain& dstSeedDomain)
{
bool bResult;
@@ -1111,6 +1157,7 @@ bool UniqueNodeList::getSeedDomains(const std::string& strDomain, seedDomain& ds
return bResult;
}
// Persist a SeedDomain.
void UniqueNodeList::setSeedDomains(const seedDomain& sdSource, bool bNext)
{
Database* db=theApp->getWalletDB()->getDB();
@@ -1147,34 +1194,60 @@ void UniqueNodeList::setSeedDomains(const seedDomain& sdSource, bool bNext)
}
}
// Add a trusted node. Called by RPC or other source.
// XXX allow update of comment.
void UniqueNodeList::nodeAddPublic(NewcoinAddress naNodePublic, std::string strComment)
// XXX Broken should opperate on seeds.
void UniqueNodeList::nodeAddPublic(const NewcoinAddress& naNodePublic, const std::string& strComment)
{
std::string strPublicKey = naNodePublic.humanNodePublic();
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
{
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
db->executeSQL(str(boost::format("INSERT INTO TrustedNodes (PublicKey,Comment) values (%s,%s);")
% db->escape(strPublicKey) % db->escape(strComment)));
db->executeSQL(str(boost::format("INSERT INTO TrustedNodes (PublicKey,Comment) values (%s,%s);")
% db->escape(strPublicKey) % db->escape(strComment)));
}
{
ScopedLock slUNL(mUNLLock);
mUNL.insert(strPublicKey);
}
}
// XXX Broken should opperate on seeds.
void UniqueNodeList::nodeRemove(NewcoinAddress naNodePublic)
{
std::string strPublic = naNodePublic.humanNodePublic();
std::string strPublicKey = naNodePublic.humanNodePublic();
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
{
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
db->executeSQL(str(boost::format("DELETE FROM TrustedNodes where PublicKey=%s") % db->escape(strPublic)));
db->executeSQL(str(boost::format("DELETE FROM TrustedNodes where PublicKey=%s") % db->escape(strPublicKey)));
}
{
ScopedLock slUNL(mUNLLock);
mUNL.erase(strPublicKey);
}
}
// XXX Broken should opperate on seeds.
void UniqueNodeList::nodeReset()
{
Database* db=theApp->getWalletDB()->getDB();
{
Database* db=theApp->getWalletDB()->getDB();
ScopedLock sl(theApp->getWalletDB()->getDBLock());
db->executeSQL("DELETE FROM TrustedNodes");
ScopedLock sl(theApp->getWalletDB()->getDBLock());
db->executeSQL("DELETE FROM TrustedNodes");
}
{
ScopedLock slUNL(mUNLLock);
mUNL.clear();
}
}
Json::Value UniqueNodeList::getUnlJson()
@@ -1203,7 +1276,9 @@ Json::Value UniqueNodeList::getUnlJson()
return ret;
}
void UniqueNodeList::nodeDefault(std::string strValidators) {
// Process a validators.txt.
// --> strValidators: a validators.txt
void UniqueNodeList::nodeDefault(const std::string& strValidators) {
section secValidators = ParseSection(strValidators, true);
section::mapped_type* pmtEntries = sectionEntries(secValidators, SECTION_VALIDATORS);
@@ -1220,4 +1295,10 @@ void UniqueNodeList::nodeDefault(std::string strValidators) {
}
}
bool UniqueNodeList::nodeInUNL(const NewcoinAddress& naNodePublic)
{
ScopedLock sl(mUNLLock);
return mUNL.end() != mUNL.find(naNodePublic.humanNodePublic());
}
// vim:ts=4

View File

@@ -12,6 +12,7 @@
#include <boost/thread/mutex.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
// Guarantees minimum thoughput of 1 node per second.
#define NODE_FETCH_JOBS 10
@@ -44,6 +45,10 @@ private:
boost::posix_time::ptime mtpScoreUpdated;
boost::posix_time::ptime mtpFetchUpdated;
boost::recursive_mutex mUNLLock;
// XXX Make this faster, make this the contents vector unsigned char or raw public key.
boost::unordered_set<std::string> mUNL;
bool miscLoad();
bool miscSave();
@@ -58,6 +63,7 @@ private:
std::string strComment;
} seedDomain;
// Used to distribute scores.
typedef struct {
int iScore;
int iRoundScore;
@@ -71,6 +77,8 @@ private:
typedef std::pair<std::string,int> ipPort;
typedef boost::unordered_map<std::pair< std::string, int>, score> epScore;
void trustedLoad();
bool scoreRound(std::vector<scoreNode>& vsnNodes);
int iSourceScore(validatorSource vsWhy);
@@ -98,11 +106,11 @@ private:
void getValidatorsUrl(NewcoinAddress naNodePublic, section secSite);
void getIpsUrl(NewcoinAddress naNodePublic, section secSite);
void responseIps(const std::string& strSite, NewcoinAddress naNodePublic, const boost::system::error_code& err, const std::string strIpsFile);
void responseIps(const std::string& strSite, const NewcoinAddress& naNodePublic, const boost::system::error_code& err, const std::string strIpsFile);
void responseValidators(const std::string& strValidatorsUrl, NewcoinAddress naNodePublic, section secSite, const std::string& strSite, const boost::system::error_code& err, const std::string strValidatorsFile);
void processIps(const std::string& strSite, NewcoinAddress naNodePublic, section::mapped_type* pmtVecStrIps);
void processValidators(const std::string& strSite, const std::string& strValidatorsSrc, NewcoinAddress naNodePublic, section::mapped_type* pmtVecStrValidators);
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, section::mapped_type* pmtVecStrValidators);
void processFile(const std::string strDomain, NewcoinAddress naNodePublic, section secSite);
@@ -115,14 +123,16 @@ public:
// Begin processing.
void start();
void nodeAddPublic(NewcoinAddress naNodePublic, std::string strComment);
void nodeAddPublic(const NewcoinAddress& naNodePublic, const std::string& strComment);
void nodeAddDomain(const std::string& strDomain, validatorSource vsWhy, std::string strComment="");
void nodeRemove(NewcoinAddress naNodePublic);
void nodeDefault(std::string strValidators);
void nodeDefault(const std::string& strValidators);
void nodeReset();
void nodeScore();
bool nodeInUNL(const NewcoinAddress& naNodePublic);
Json::Value getUnlJson();
};

View File

@@ -46,6 +46,8 @@ void printHelp(const po::options_description& desc)
cout << " connect <ip> [<port>]" << endl;
cout << " credit_set <seed> <paying_account> <destination_account> <limit_amount> <currency> [<account_rate>]" << endl;
cout << " ledger" << endl;
cout << " nickname_info <nickname>" << endl;
cout << " nickname_set <seed> <paying_account> <nickname> [<offer_minimum>] [<authorization>]" << endl;
cout << " password_fund <seed> <paying_account> [<account>]" << endl;
cout << " password_set <master_seed> <regular_seed> [<account>]" << endl;
cout << " peers" << endl;

View File

@@ -203,8 +203,8 @@ message TMObjectByHash
}
message TMLedgerNode {
required bytes nodeid = 1;
required bytes nodedata = 2;
required bytes nodedata = 1;
optional bytes nodeid = 2; // missing for ledger base data
}
enum TMLedgerInfoType {