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

This commit is contained in:
JoelKatz
2012-06-05 15:42:09 -07:00
28 changed files with 559 additions and 114 deletions

View File

@@ -103,7 +103,6 @@
<ClCompile Include="src\Config.cpp" />
<ClCompile Include="src\ConnectionPool.cpp" />
<ClCompile Include="src\Conversion.cpp" />
<ClCompile Include="src\Currency.cpp" />
<ClCompile Include="src\DBInit.cpp" />
<ClCompile Include="src\DeterministicKeys.cpp" />
<ClCompile Include="src\ECIES.cpp" />
@@ -112,12 +111,14 @@
<ClCompile Include="src\HttpsClient.cpp" />
<ClCompile Include="src\Ledger.cpp" />
<ClCompile Include="src\LedgerAcquire.cpp" />
<ClCompile Include="src\LedgerConsensus.cpp" />
<ClCompile Include="src\LedgerFormats.cpp" />
<ClCompile Include="src\LedgerHistory.cpp" />
<ClCompile Include="src\LedgerIndex.cpp" />
<ClCompile Include="src\LedgerMaster.cpp" />
<ClCompile Include="src\LedgerNode.cpp" />
<ClCompile Include="src\LocalTransaction.cpp" />
<ClCompile Include="src\LedgerProposal.cpp" />
<ClCompile Include="src\Log.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\NetworkOPs.cpp" />
<ClCompile Include="src\NewcoinAddress.cpp" />
@@ -129,6 +130,7 @@
<ClCompile Include="src\PubKeyCache.cpp" />
<ClCompile Include="src\RequestParser.cpp" />
<ClCompile Include="src\rfc1751.cpp" />
<ClCompile Include="src\RippleState.cpp" />
<ClCompile Include="src\rpc.cpp" />
<ClCompile Include="src\RPCCommands.cpp" />
<ClCompile Include="src\RPCDoor.cpp" />

View File

@@ -81,9 +81,6 @@
<ClCompile Include="src\Conversion.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Currency.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\DBInit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -123,9 +120,6 @@
<ClCompile Include="src\LedgerNode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LocalTransaction.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@@ -237,6 +231,18 @@
<ClCompile Include="obj\src\newcoin.pb.cc">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\RippleState.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Log.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LedgerConsensus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\LedgerProposal.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Application.h">

View File

@@ -100,7 +100,7 @@ bool STAmount::setValue(const std::string& sAmount, const std::string& sCurrency
if (bInteger)
{
uValue = sAmount.empty() ? 0 : boost::lexical_cast<uint>(sAmount);
uValue = sAmount.empty() ? 0 : boost::lexical_cast<unsigned int>(sAmount);
iOffset = 0;
}
else

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
@@ -24,7 +25,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"
@@ -59,7 +61,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;
@@ -118,8 +121,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

@@ -75,8 +75,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

@@ -1,4 +1,3 @@
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>

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

@@ -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

@@ -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.
@@ -248,7 +249,7 @@ Json::Value RPCServer::authorize(const uint256& uLedger,
// Find the index of the account from the master generator, so we can generate the public and private keys.
NewcoinAddress naMasterAccountPublic;
uint iIndex = -1; // Compensate for initial increment.
unsigned int iIndex = -1; // Compensate for initial increment.
// XXX Stop after Config.account_probe_max
// Don't look at ledger entries to determine if the account exists. Don't want to leak to thin server that these accounts are
@@ -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)
@@ -945,7 +1084,7 @@ Json::Value RPCServer::doPasswordSet(Json::Value& params)
NewcoinAddress naMasterXPublic;
NewcoinAddress naRegularXPublic;
uint iIndex = -1; // Compensate for initial increment.
unsigned int iIndex = -1; // Compensate for initial increment.
int iMax = theConfig.ACCOUNT_PROBE_MAX;
// YYY Could probe peridoically to see if accounts exists.
@@ -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())
{
@@ -1295,7 +1434,7 @@ Json::Value RPCServer::accounts(const uint256& uLedger, const NewcoinAddress& na
// YYY Don't want to leak to thin server that these accounts are related.
// YYY Would be best to alternate requests to servers and to cache results.
uint uIndex = 0;
unsigned int uIndex = 0;
do {
NewcoinAddress naAccount;
@@ -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);

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

@@ -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

@@ -102,4 +102,32 @@ DH* DH_der_load_hex(const std::string& strDer)
return DH_der_load(strBuf);
}
#ifdef WIN32
#define _WINSOCK_
#include <winsock2.h>
//#include "Winsock2.h"
//#include <windows.h>
// from: http://stackoverflow.com/questions/3022552/is-there-any-standard-htonl-like-function-for-64-bits-integers-in-c
// but we don't need to check the endianness
uint64_t htobe64(uint64_t value)
{
// The answer is 42
//static const int num = 42;
// Check the endianness
//if (*reinterpret_cast<const char*>(&num) == num)
//{
const uint32_t high_part = htonl(static_cast<uint32_t>(value >> 32));
const uint32_t low_part = htonl(static_cast<uint32_t>(value & 0xFFFFFFFFLL));
return (static_cast<uint64_t>(low_part) << 32) | high_part;
//} else
//{
// return value;
//}
}
#endif
// vim:ts=4

View File

@@ -19,6 +19,10 @@
#define MIN(x,y) ((x) > (y) ? (y) : (x))
#endif
#ifdef WIN32
extern uint64_t htobe64(uint64_t value);
#endif
boost::posix_time::ptime ptEpoch();
int iToSeconds(boost::posix_time::ptime ptWhen);
boost::posix_time::ptime ptFromSeconds(int iSeconds);