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

This commit is contained in:
jed
2012-09-05 15:56:29 -07:00
13 changed files with 1408 additions and 1434 deletions

View File

@@ -10,6 +10,8 @@
#include "SerializedTypes.h"
#include "utils.h"
uint64 STAmount::uRateOne = STAmount::getRate(STAmount(1), STAmount(1));
bool STAmount::currencyFromString(uint160& uDstCurrency, const std::string& sCurrency)
{
bool bSuccess = true;

View File

@@ -248,23 +248,43 @@ void LedgerConsensus::checkLCL()
{
uint256 netLgr = mPrevLedgerHash;
int netLgrCount = 0;
{
boost::unordered_map<uint256, int> vals = theApp->getValidations().getCurrentValidations();
typedef std::pair<const uint256, int> u256_int_pair;
BOOST_FOREACH(u256_int_pair& it, vals)
uint256 favorLedger;
if (mState != lcsPRE_CLOSE)
favorLedger = mPrevLedgerHash;
boost::unordered_map<uint256, int> vals = theApp->getValidations().getCurrentValidations(favorLedger);
typedef std::pair<const uint256, int> u256_int_pair;
BOOST_FOREACH(u256_int_pair& it, vals)
{
if ((it.second > netLgrCount) && !theApp->getValidations().isDeadLedger(it.first))
{
if ((it.second > netLgrCount) && !theApp->getValidations().isDeadLedger(it.first))
{
netLgr = it.first;
netLgrCount = it.second;
}
netLgr = it.first;
netLgrCount = it.second;
}
}
if (netLgr != mPrevLedgerHash)
{ // LCL change
Log(lsWARNING) << "View of consensus changed during consensus (" << netLgrCount << ")";
const char *status;
switch (mState)
{
case lcsPRE_CLOSE: status="PreClose"; break;
case lcsESTABLISH: status="Establish"; break;
case lcsFINISHED: status="Finised"; break;
case lcsACCEPTED: status="Accepted"; break;
default: status="unknown";
}
Log(lsWARNING) << "View of consensus changed during consensus (" << netLgrCount << ") status="
<< status << ", " << (mHaveCorrectLCL ? "CorrectLCL" : "IncorrectLCL");
Log(lsWARNING) << mPrevLedgerHash << " to " << netLgr;
#ifdef DEBUG
BOOST_FOREACH(u256_int_pair& it, vals)
Log(lsDEBUG) << "V: " << it.first << ", " << it.second;
#endif
if (mHaveCorrectLCL)
theApp->getOPs().consensusViewChange();
handleLCL(netLgr);
@@ -485,8 +505,6 @@ void LedgerConsensus::statePreClose()
statusChange(newcoin::neCLOSING_LEDGER, *mPreviousLedger);
takeInitialPosition(*theApp->getMasterLedger().closeLedger());
}
else if (mHaveCorrectLCL)
checkLCL(); // double check
}
void LedgerConsensus::stateEstablish()
@@ -520,7 +538,7 @@ void LedgerConsensus::stateAccepted()
void LedgerConsensus::timerEntry()
{
if ((!mHaveCorrectLCL) || (mState == lcsPRE_CLOSE))
if ((mState != lcsFINISHED) && (mState != lcsACCEPTED))
checkLCL();
mCurrentMSeconds =
@@ -614,7 +632,7 @@ void LedgerConsensus::updateOurPositions()
++closeTimes[roundCloseTime(mOurPosition->getCloseTime())];
++thresh;
}
thresh = thresh * neededWeight / 100;
thresh = ((thresh * neededWeight) + (neededWeight / 2)) / 100;
if (thresh == 0)
thresh = 1;
@@ -623,12 +641,15 @@ void LedgerConsensus::updateOurPositions()
Log(lsINFO) << "CCTime: " << it->first << " has " << it->second << " out of " << thresh;
if (it->second > thresh)
{
Log(lsINFO) << "Close time consensus reached: " << closeTime;
Log(lsINFO) << "Close time consensus reached: " << it->first;
mHaveCloseTimeConsensus = true;
closeTime = it->first;
thresh = it->second;
}
}
if (!mHaveCloseTimeConsensus)
Log(lsDEBUG) << "No CT consensus: Proposers:" << mPeerPositions.size() << " Proposing:" <<
(mProposing ? "yes" : "no") << " Thresh:" << thresh << " Pos:" << closeTime;
}
if ((!changes) &&

View File

@@ -1316,15 +1316,15 @@ Json::Value RPCServer::doPeers(const Json::Value& params)
}
// ripple <regular_seed> <paying_account>
// <source_max> <source_currency> [<source_issuerID>] // XXX [noredeem] [noissue]
// <source_max> <source_currency> [<source_issuerID>]
// <path>+
// full|partial <dest_account> <dest_amount> <dest_currency> [<dest_issuerID>]
// full|partial limit|average <dest_account> <dest_amount> <dest_currency> [<dest_issuerID>]
//
// path:
// path <path_element>+
//
// path_element:
// account <accountID> [<currency>] [<issuerID>] [noredeem] [noissue]
// account <accountID> [<currency>] [<issuerID>]
// offer <currency> [<issuerID>]
Json::Value RPCServer::doRipple(const Json::Value &params)
{
@@ -1333,15 +1333,14 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
uint160 uSrcCurrencyID;
NewcoinAddress naSrcAccountID;
NewcoinAddress naSrcIssuerID;
bool bSrcRedeem = true;
bool bSrcIssue = true;
bool bPartial;
bool bFull;
bool bLimit;
bool bAverage;
NewcoinAddress naDstAccountID;
STAmount saDstAmount;
uint160 uDstCurrencyID;
std::vector<paymentNode> vpnPath;
STPathSet spsPaths;
naSrcIssuerID.setAccountID(params[4u].asString()); // <source_issuerID>
@@ -1367,18 +1366,6 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
int iArg = 4 + naSrcIssuerID.isValid();
if (params[iArg].asString() == "noredeem") // [noredeem]
{
++iArg;
bSrcRedeem = false;
}
if (params[iArg].asString() == "noissue") // [noissue]
{
++iArg;
bSrcIssue = false;
}
// XXX bSrcRedeem & bSrcIssue not used.
STPath spPath;
@@ -1418,8 +1405,6 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
NewcoinAddress naAccountID;
uint160 uCurrencyID;
NewcoinAddress naIssuerID;
bool bRedeem = true;
bool bIssue = true;
++iArg;
@@ -1438,24 +1423,10 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
++iArg;
}
if (params.size() != iArg && params[iArg].asString() == "noredeem") // [noredeem]
{
++iArg;
bRedeem = false;
}
if (params.size() != iArg && params[iArg].asString() == "noissue") // [noissue]
{
++iArg;
bIssue = false;
}
spPath.addElement(STPathElement(
naAccountID.getAccountID(),
uCurrencyID,
naIssuerID.isValid() ? naIssuerID.getAccountID() : uint160(0),
bRedeem,
bIssue));
naIssuerID.isValid() ? naIssuerID.getAccountID() : uint160(0)));
}
else
{
@@ -1487,6 +1458,19 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
++iArg;
}
// limit|average
bLimit = params.size() != iArg ? params[iArg].asString() == "limit" : false;
bAverage = params.size() != iArg ? params[iArg].asString() == "average" : false;
if (!bPartial && !bFull)
{
return RPCError(rpcINVALID_PARAMS);
}
else
{
++iArg;
}
if (params.size() != iArg && !naDstAccountID.setAccountID(params[iArg++].asString())) // <dest_account>
{
return RPCError(rpcDST_ACT_MALFORMED);
@@ -1544,7 +1528,9 @@ Json::Value RPCServer::doRipple(const Json::Value &params)
naDstAccountID,
saDstAmount,
saSrcAmountMax,
spsPaths);
spsPaths,
bPartial,
bLimit);
trans = mNetOps->submitTransaction(trans);
@@ -2565,7 +2551,7 @@ Json::Value RPCServer::doCommand(const std::string& command, Json::Value& params
{ "password_fund", &RPCServer::doPasswordFund, 2, 3, false, optCurrent },
{ "password_set", &RPCServer::doPasswordSet, 2, 3, false, optNetwork },
{ "peers", &RPCServer::doPeers, 0, 0, true },
{ "ripple", &RPCServer::doRipple, 8, -1, false, optCurrent|optClosed },
{ "ripple", &RPCServer::doRipple, 9, -1, false, optCurrent|optClosed },
{ "ripple_lines_get", &RPCServer::doRippleLinesGet, 1, 2, false, optCurrent },
{ "ripple_line_set", &RPCServer::doRippleLineSet, 4, 7, false, optCurrent },
{ "send", &RPCServer::doSend, 3, 9, false, optCurrent },

View File

@@ -332,8 +332,6 @@ STPathSet* STPathSet::construct(SerializerIterator& s, const char *name)
else
{
const bool bAccount = !!(iType & STPathElement::typeAccount);
const bool bRedeem = !!(iType & STPathElement::typeRedeem);
const bool bIssue = !!(iType & STPathElement::typeIssue);
const bool bCurrency = !!(iType & STPathElement::typeCurrency);
const bool bIssuer = !!(iType & STPathElement::typeIssuer);
@@ -350,7 +348,7 @@ STPathSet* STPathSet::construct(SerializerIterator& s, const char *name)
if (bIssuer)
uIssuerID = s.get160();
path.push_back(STPathElement(uAccountID, uCurrency, uIssuerID, bRedeem, bIssue));
path.push_back(STPathElement(uAccountID, uCurrency, uIssuerID));
}
} while(1);
}

View File

@@ -255,6 +255,8 @@ protected:
static uint64 muldiv(uint64, uint64, uint64);
public:
static uint64 uRateOne;
STAmount(uint64 v = 0, bool isNeg = false) : mValue(v), mOffset(0), mIsNative(true), mIsNegative(isNeg)
{ if (v==0) mIsNegative = false; }
@@ -354,7 +356,16 @@ public:
friend STAmount operator-(const STAmount& v1, const STAmount& v2);
static STAmount divide(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
static STAmount divide(const STAmount& v1, const STAmount& v2, const STAmount& saUnit)
{ return divide(v1, v2, saUnit.getCurrency(), saUnit.getIssuer()); }
static STAmount divide(const STAmount& v1, const STAmount& v2)
{ return divide(v1, v2, v1); }
static STAmount multiply(const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID);
static STAmount multiply(const STAmount& v1, const STAmount& v2, const STAmount& saUnit)
{ return multiply(v1, v2, saUnit.getCurrency(), saUnit.getIssuer()); }
static STAmount multiply(const STAmount& v1, const STAmount& v2)
{ return multiply(v1, v2, v1); }
// Someone is offering X for Y, what is the rate?
// Rate: smaller is better, the taker wants the most out: in/out
@@ -535,15 +546,11 @@ public:
enum {
typeEnd = 0x00,
typeAccount = 0x01, // Rippling through an account (vs taking an offer).
typeRedeem = 0x04, // Redeem IOUs.
typeIssue = 0x08, // Issue IOUs.
typeCurrency = 0x10, // Currency follows.
typeIssuer = 0x20, // Issuer follows.
typeBoundary = 0xFF, // Boundary between alternate paths.
typeValidBits = (
typeAccount
| typeRedeem
| typeIssue
| typeCurrency
| typeIssuer
), // Bits that may be non-zero.
@@ -556,15 +563,13 @@ protected:
uint160 mIssuerID;
public:
STPathElement(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID, bool bRedeem=false, bool bIssue=false)
STPathElement(const uint160& uAccountID, const uint160& uCurrencyID, const uint160& uIssuerID)
: mAccountID(uAccountID), mCurrencyID(uCurrencyID), mIssuerID(uIssuerID)
{
mType =
(uAccountID.isZero() ? 0 : STPathElement::typeAccount)
| (uCurrencyID.isZero() ? 0 : STPathElement::typeCurrency)
| (uIssuerID.isZero() ? 0 : STPathElement::typeIssuer)
| (bRedeem ? STPathElement::typeRedeem : 0)
| (bIssue ? STPathElement::typeIssue : 0);
| (uIssuerID.isZero() ? 0 : STPathElement::typeIssuer);
}
int getNodeType() const { return mType; }

View File

@@ -8,6 +8,7 @@ class SerializedValidation : public STObject
{
protected:
STVariableLength mSignature;
uint256 mPreviousHash;
bool mTrusted;
void setNode();
@@ -40,6 +41,11 @@ public:
void addSignature(Serializer&) const;
std::vector<unsigned char> getSigned() const;
std::vector<unsigned char> getSignature() const;
// The validation this replaced
const uint256& getPreviousHash() { return mPreviousHash; }
bool isPreviousHash(const uint256& h) { return mPreviousHash == h; }
void setPreviousHash(const uint256& h) { mPreviousHash = h; }
};
#endif

View File

@@ -489,7 +489,9 @@ Transaction::pointer Transaction::setPayment(
const NewcoinAddress& naDstAccountID,
const STAmount& saAmount,
const STAmount& saSendMax,
const STPathSet& spsPaths)
const STPathSet& spsPaths,
const bool bPartial,
const bool bLimit)
{
mTransaction->setITFieldAccount(sfDestination, naDstAccountID);
mTransaction->setITFieldAmount(sfAmount, saAmount);
@@ -518,11 +520,13 @@ Transaction::pointer Transaction::sharedPayment(
const NewcoinAddress& naDstAccountID,
const STAmount& saAmount,
const STAmount& saSendMax,
const STPathSet& spsPaths)
const STPathSet& spsPaths,
const bool bPartial,
const bool bLimit)
{
pointer tResult = boost::make_shared<Transaction>(ttPAYMENT, naPublicKey, naSourceAccount, uSeq, saFee, uSourceTag);
return tResult->setPayment(naPrivateKey, naDstAccountID, saAmount, saSendMax, spsPaths);
return tResult->setPayment(naPrivateKey, naDstAccountID, saAmount, saSendMax, spsPaths, bPartial, bLimit);
}
//

View File

@@ -116,7 +116,9 @@ private:
const NewcoinAddress& naDstAccountID,
const STAmount& saAmount,
const STAmount& saSendMax,
const STPathSet& spsPaths);
const STPathSet& spsPaths,
const bool bPartial,
const bool bLimit);
Transaction::pointer setWalletAdd(
const NewcoinAddress& naPrivateKey,
@@ -231,7 +233,9 @@ public:
const NewcoinAddress& naDstAccountID,
const STAmount& saAmount,
const STAmount& saSendMax,
const STPathSet& spsPaths);
const STPathSet& spsPaths,
const bool bPartial = false,
const bool bLimit = false);
// Place an offer.
static Transaction::pointer sharedOfferCreate(

File diff suppressed because it is too large Load Diff

View File

@@ -138,7 +138,11 @@ enum TransactionEngineParams
// Transaction can be retried, soft failures allowed
};
typedef struct {
class PaymentNode {
protected:
friend class TransactionEngine;
friend class PathState;
uint16 uFlags; // --> From path.
uint160 uAccountID; // --> Accounts: Recieving/sending account.
@@ -146,6 +150,8 @@ typedef struct {
// --- For offer's next has currency out.
uint160 uIssuerID; // --> Currency's issuer
STAmount saTransferRate; // Transfer rate for uIssuerID.
// Computed by Reverse.
STAmount saRevRedeem; // <-- Amount to redeem to next.
STAmount saRevIssue; // <-- Amount to issue to next limited by credit and outstanding IOUs.
@@ -157,7 +163,29 @@ typedef struct {
STAmount saFwdIssue; // <-- Amount node will issue to next.
// Issue isn't used by offers.
STAmount saFwdDeliver; // <-- Amount to deliver to next regardless of fee.
} paymentNode;
// For offers:
STAmount saRateMax; // XXX Should rate be sticky for forward too?
// Directory
uint256 uDirectTip; // Current directory.
uint256 uDirectEnd; // Next order book.
bool bDirectAdvance; // Need to advance directory.
SLE::pointer sleDirectDir;
STAmount saOfrRate; // For correct ratio.
// Node
bool bEntryAdvance; // Need to advance entry.
unsigned int uEntry;
uint256 uOfferIndex;
SLE::pointer sleOffer;
uint160 uOfrOwnerID;
bool bFundsDirty; // Need to refresh saOfferFunds, saTakerPays, & saTakerGets.
STAmount saOfferFunds;
STAmount saTakerPays;
STAmount saTakerGets;
};
// account id, currency id, issuer id :: node
typedef boost::tuple<uint160, uint160, uint160> aciSource;
@@ -165,9 +193,8 @@ typedef boost::unordered_map<aciSource, unsigned int> curIssuerNode; // Map
typedef boost::unordered_map<aciSource, unsigned int>::const_iterator curIssuerNodeConstIterator;
extern std::size_t hash_value(const aciSource& asValue);
// extern std::size_t hash_value(const boost::tuple<uint160, uint160, uint160>& bt);
// Hold a path state under incremental application.
// Holds a path state under incremental application.
class PathState
{
protected:
@@ -180,12 +207,13 @@ public:
typedef boost::shared_ptr<PathState> pointer;
TER terStatus;
std::vector<paymentNode> vpnNodes;
std::vector<PaymentNode> vpnNodes;
// When processing, don't want to complicate directory walking with deletion.
std::vector<uint256> vUnfundedBecame; // Offers that became unfunded or were completely consumed.
// First time working foward a funding source was mentioned for accounts. Source may only be used there.
// First time scanning foward, as part of path contruction, a funding source was mentioned for accounts. Source may only be
// used there.
curIssuerNode umForward; // Map of currency, issuer to node index.
// First time working in reverse a funding source was used.
@@ -209,8 +237,7 @@ public:
const uint160& uReceiverID,
const uint160& uSenderID,
const STAmount& saSend,
const STAmount& saSendMax,
const bool bPartialPayment
const STAmount& saSendMax
);
Json::Value getJson() const;
@@ -223,11 +250,10 @@ public:
const uint160& uReceiverID,
const uint160& uSenderID,
const STAmount& saSend,
const STAmount& saSendMax,
const bool bPartialPayment
const STAmount& saSendMax
)
{
return boost::make_shared<PathState>(lpLedger, iIndex, lesSource, spSourcePath, uReceiverID, uSenderID, saSend, saSendMax, bPartialPayment);
return boost::make_shared<PathState>(lpLedger, iIndex, lesSource, spSourcePath, uReceiverID, uSenderID, saSend, saSendMax);
}
static bool lessPriority(const PathState::pointer& lhs, const PathState::pointer& rhs);
@@ -308,22 +334,43 @@ protected:
STAmount accountFunds(const uint160& uAccountID, const STAmount& saDefault);
PathState::pointer pathCreate(const STPath& spPath);
void pathNext(const PathState::pointer& pspCur, const int iPaths);
void pathNext(const PathState::pointer& pspCur, const int iPaths, const LedgerEntrySet& lesCheckpoint);
TER calcNode(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeRev(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeFwd(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeOfferRev(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeOfferFwd(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeAccountRev(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeAccountFwd(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality);
TER calcNodeAdvance(const unsigned int uIndex, const PathState::pointer& pspCur, const bool bMultiQuality, const bool bReverse);
TER calcNodeDeliverRev(
const unsigned int uIndex,
const PathState::pointer& pspCur,
const bool bMultiQuality,
const uint160& uOutAccountID,
const STAmount& saOutReq,
STAmount& saOutAct);
TER calcNodeDeliverFwd(
const unsigned int uIndex,
const PathState::pointer& pspCur,
const bool bMultiQuality,
const uint160& uInAccountID,
const STAmount& saInFunds,
const STAmount& saInReq,
STAmount& saInAct,
STAmount& saInFees);
void calcNodeRipple(const uint32 uQualityIn, const uint32 uQualityOut,
const STAmount& saPrvReq, const STAmount& saCurReq,
STAmount& saPrvAct, STAmount& saCurAct);
STAmount& saPrvAct, STAmount& saCurAct,
uint64& uRateMax);
void txnWrite();
TER doAccountSet(const SerializedTransaction& txn);
TER doClaim(const SerializedTransaction& txn);
TER doCreditSet(const SerializedTransaction& txn);
TER doDelete(const SerializedTransaction& txn);
TER doInvoice(const SerializedTransaction& txn);
TER doOfferCreate(const SerializedTransaction& txn);
TER doOfferCancel(const SerializedTransaction& txn);
@@ -331,8 +378,6 @@ protected:
TER doPasswordFund(const SerializedTransaction& txn);
TER doPasswordSet(const SerializedTransaction& txn);
TER doPayment(const SerializedTransaction& txn);
TER doStore(const SerializedTransaction& txn);
TER doTake(const SerializedTransaction& txn);
TER doWalletAdd(const SerializedTransaction& txn);
TER doContractAdd(const SerializedTransaction& txn);
TER doContractRemove(const SerializedTransaction& txn);

View File

@@ -47,7 +47,8 @@ const uint32 tfPassive = 0x00010000;
// Payment flags:
const uint32 tfCreateAccount = 0x00010000;
const uint32 tfPartialPayment = 0x00020000;
const uint32 tfNoRippleDirect = 0x00040000;
const uint32 tfLimitQuality = 0x00040000;
const uint32 tfNoRippleDirect = 0x00080000;
extern TransactionFormat InnerTxnFormats[];
extern TransactionFormat* getTxnFormat(TransactionType t);

View File

@@ -41,6 +41,7 @@ bool ValidationCollection::addValidation(const SerializedValidation::pointer& va
it->second = val;
else if (val->getSignTime() > it->second->getSignTime())
{
val->setPreviousHash(it->second->getLedgerHash());
mStaleValidations.push_back(it->second);
it->second = val;
condWrite();
@@ -128,9 +129,11 @@ int ValidationCollection::getCurrentValidationCount(uint32 afterTime)
return count;
}
boost::unordered_map<uint256, int> ValidationCollection::getCurrentValidations()
boost::unordered_map<uint256, int> ValidationCollection::getCurrentValidations(uint256 currentLedger)
{
uint32 cutoff = theApp->getOPs().getNetworkTimeNC() - LEDGER_VAL_INTERVAL;
bool valCurrentLedger = currentLedger.isNonZero();
boost::unordered_map<uint256, int> ret;
{
@@ -149,7 +152,10 @@ boost::unordered_map<uint256, int> ValidationCollection::getCurrentValidations()
}
else
{ // contains a live record
++ret[it->second->getLedgerHash()];
if (valCurrentLedger && it->second->isPreviousHash(currentLedger))
++ret[currentLedger]; // count for the favored ledger
else
++ret[it->second->getLedgerHash()];
++it;
}
}
@@ -160,6 +166,7 @@ boost::unordered_map<uint256, int> ValidationCollection::getCurrentValidations()
bool ValidationCollection::isDeadLedger(const uint256& ledger)
{
boost::mutex::scoped_lock sl(mValidationLock);
BOOST_FOREACH(const uint256& it, mDeadLedgers)
if (it == ledger)
return true;
@@ -168,11 +175,14 @@ bool ValidationCollection::isDeadLedger(const uint256& ledger)
void ValidationCollection::addDeadLedger(const uint256& ledger)
{
if (isDeadLedger(ledger))
return;
boost::mutex::scoped_lock sl(mValidationLock);
BOOST_FOREACH(const uint256& it, mDeadLedgers)
if (it == ledger)
return;
mDeadLedgers.push_back(ledger);
if (mDeadLedgers.size() >= 128)
if (mDeadLedgers.size() >= 32)
mDeadLedgers.pop_front();
}
@@ -220,13 +230,11 @@ void ValidationCollection::doWrite()
std::vector<SerializedValidation::pointer> vector;
mStaleValidations.swap(vector);
sl.unlock();
{
ScopedLock dbl(theApp->getLedgerDB()->getDBLock());
Database *db = theApp->getLedgerDB()->getDB();
ScopedLock dbl(theApp->getLedgerDB()->getDBLock());
db->executeSQL("BEGIN TRANSACTION;");
BOOST_FOREACH(const SerializedValidation::pointer& it, vector)
db->executeSQL(boost::str(insVal % it->getLedgerHash().GetHex()
% it->getSignerPublic().humanNodePublic() % it->getFlags() % it->getSignTime()

View File

@@ -37,7 +37,7 @@ public:
int getTrustedValidationCount(const uint256& ledger);
int getCurrentValidationCount(uint32 afterTime);
boost::unordered_map<uint256, int> getCurrentValidations();
boost::unordered_map<uint256, int> getCurrentValidations(uint256 currentLedger = uint256());
void addDeadLedger(const uint256&);
bool isDeadLedger(const uint256&);