Merge branch 'develop' of github.com:jedmccaleb/NewCoin into develop

This commit is contained in:
Arthur Britto
2013-04-23 13:49:30 -07:00
19 changed files with 185 additions and 39 deletions

View File

@@ -54,9 +54,9 @@ Application::Application() :
mSNTPClient(mAuxService), mJobQueue(mIOService), mFeeTrack(),
#ifdef RESERVE_BASE_100
mFeeVote(10, 100, 25),
mFeeVote(10, 100 * SYSTEM_CURRENCY_PARTS, 25 * SYSTEM_CURRENCY_PARTS),
#else
mFeeVote(10, 200, 50),
mFeeVote(10, 200 * SYSTEM_CURRENCY_PARTS, 50 * SYSTEM_CURRENCY_PARTS),
#endif
mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL),

View File

@@ -1,4 +1,7 @@
#include "ChangeTransactor.h"
#include "Log.h"
SETUP_LOG();
TER ChangeTransactor::doApply()
{
@@ -14,10 +17,16 @@ TER ChangeTransactor::doApply()
TER ChangeTransactor::checkSig()
{
if (mTxn.getFieldAccount160(sfAccount).isNonZero())
{
cLog(lsWARNING) << "Change transaction had bad source account";
return temBAD_SRC_ACCOUNT;
}
if (!mTxn.getSigningPubKey().empty() || !mTxn.getSignature().empty())
{
cLog(lsWARNING) << "Change transaction had bad signature";
return temBAD_SIGNATURE;
}
return tesSUCCESS;
}
@@ -25,15 +34,39 @@ TER ChangeTransactor::checkSig()
TER ChangeTransactor::checkSeq()
{
if (mTxn.getSequence() != 0)
{
cLog(lsWARNING) << "Change transaction had bad sequence";
return temBAD_SEQUENCE;
}
return tesSUCCESS;
}
TER ChangeTransactor::payFee()
{
if (mTxn.getTransactionFee() != STAmount())
{
cLog(lsWARNING) << "Change transaction with non-zero fee";
return temBAD_FEE;
}
return tesSUCCESS;
}
TER ChangeTransactor::preCheck()
{
mTxnAccountID = mTxn.getSourceAccount().getAccountID();
if (mTxnAccountID.isNonZero())
{
cLog(lsWARNING) << "applyTransaction: bad source id";
return temBAD_SRC_ACCOUNT;
}
if (isSetBit(mParams, tapOPEN_LEDGER))
{
cLog(lsWARNING) << "Change transaction against open ledger";
return temINVALID;
}
return tesSUCCESS;
}
@@ -64,11 +97,16 @@ TER ChangeTransactor::applyFee()
if (!feeObject)
feeObject = mEngine->entryCreate(ltFEE_SETTINGS, Ledger::getLedgerFeeIndex());
cLog(lsINFO) << "Previous fee object: " << feeObject->getJson(0);
feeObject->setFieldU64(sfBaseFee, mTxn.getFieldU64(sfBaseFee));
feeObject->setFieldU32(sfReferenceFeeUnits, mTxn.getFieldU32(sfReferenceFeeUnits));
feeObject->setFieldU32(sfReserveBase, mTxn.getFieldU32(sfReserveBase));
feeObject->setFieldU32(sfReserveIncrement, mTxn.getFieldU32(sfReserveIncrement));
mEngine->entryModify(feeObject);
cLog(lsINFO) << "New fee object: " << feeObject->getJson(0);
cLog(lsWARNING) << "Fees have been changed";
return tesSUCCESS;
}

View File

@@ -7,6 +7,8 @@ protected:
TER applyFeature();
TER applyFee();
bool mustHaveValidAccount() { return false; }
public:
ChangeTransactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine *engine)
: Transactor(txn, params, engine)
@@ -16,6 +18,7 @@ public:
TER checkSig();
TER checkSeq();
TER payFee();
TER preCheck();
};
// vim:ts=4

View File

@@ -3,6 +3,9 @@
#include <boost/foreach.hpp>
#include "Log.h"
#include "Application.h"
#include "ValidationCollection.h"
#include "HashPrefixes.h"
SETUP_LOG();
@@ -243,6 +246,7 @@ protected:
INT mTarget; // The setting we want
std::map<INT, int> mVoteMap;
public:
VotableInteger(INT current, INT target) : mCurrent(current), mTarget(target)
{
++mVoteMap[mTarget]; // Add our vote
@@ -268,8 +272,8 @@ protected:
INT ourVote = mCurrent;
int weight = 0;
typedef std::pair<INT, int> INTint_pair_t;
BOOST_FOREACH(INTint_pair_t& value, mVoteMap)
typedef typename std::map<INT, int>::value_type mapVType;
BOOST_FOREACH(const mapVType& value, mVoteMap)
{ // Take most voted value between current and target, inclusive
if ((value.first <= std::max(mTarget, mCurrent)) &&
(value.first >= std::min(mTarget, mCurrent)) &&
@@ -284,16 +288,87 @@ protected:
}
};
void FeeVote::doValidation(Ledger::ref lastClosedLedger, STObject& validation)
{
if (lastClosedLedger->getBaseFee() != mTargetBaseFee)
{
cLog(lsINFO) << "Voting for base fee of " << mTargetBaseFee;
validation.setFieldU64(sfBaseFee, mTargetBaseFee);
}
if (lastClosedLedger->getReserve(0) != mTargetReserveBase)
{
cLog(lsINFO) << "Voting for base resrve of " << mTargetReserveBase;
validation.setFieldU32(sfReserveBase, mTargetReserveBase);
}
if (lastClosedLedger->getReserveInc() != mTargetReserveIncrement)
{
cLog(lsINFO) << "Voting for reserve increment of " << mTargetReserveIncrement;
validation.setFieldU32(sfReserveIncrement, mTargetReserveIncrement);
}
}
void FeeVote::doFeeVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition)
{
// LCL must be flag ledger
assert((lastClosedLedger->getLedgerSeq() % 256) == 0);
VotableInteger<uint64> baseFeeVote(lastClosedLedger->getBaseFee(), mTargetBaseFee);
VotableInteger<uint32> baseReserveVote(lastClosedLedger->getReserve(0), mTargetReserveBase);
VotableInteger<uint32> incReserveVote(lastClosedLedger->getReserveInc(), mTargetReserveIncrement);
// get validations for ledger before flag
ValidationSet set = theApp->getValidations().getValidations(lastClosedLedger->getParentHash());
BOOST_FOREACH(ValidationSet::value_type& value, set)
{
SerializedValidation& val = *value.second;
if (val.isTrusted())
{
if (val.isFieldPresent(sfBaseFee))
baseFeeVote.addVote(val.getFieldU64(sfBaseFee));
else
baseFeeVote.noVote();
if (val.isFieldPresent(sfReserveBase))
baseReserveVote.addVote(val.getFieldU32(sfReserveBase));
else
baseReserveVote.noVote();
if (val.isFieldPresent(sfReserveIncrement))
incReserveVote.addVote(val.getFieldU32(sfReserveIncrement));
else
incReserveVote.noVote();
}
}
// choose our positions
uint64 baseFee = baseFeeVote.getVotes();
uint32 baseReserve = baseReserveVote.getVotes();
uint32 incReserve = incReserveVote.getVotes();
// add transactions to our position
if ((baseFee != lastClosedLedger->getBaseFee()) ||
(baseReserve != lastClosedLedger->getReserve(0)) ||
(incReserve != lastClosedLedger->getReserveInc()))
{
cLog(lsWARNING) << "We are voting for a fee change: " << baseFee << "/" << baseReserve << "/" << incReserve;
SerializedTransaction trans(ttFEE);
trans.setFieldAccount(sfAccount, uint160());
trans.setFieldU64(sfBaseFee, baseFee);
trans.setFieldU32(sfReferenceFeeUnits, 10);
trans.setFieldU32(sfReserveBase, baseReserve);
trans.setFieldU32(sfReserveIncrement, incReserve);
uint256 txID = trans.getTransactionID();
cLog(lsWARNING) << "Vote: " << txID;
Serializer s;
trans.add(s, true);
SHAMapItem::pointer tItem = boost::make_shared<SHAMapItem>(txID, s.peekData());
if (!initialPosition->addGiveItem(tItem, true, false))
{
cLog(lsWARNING) << "Ledger already had fee change";
}
}
}
// vim:ts=4

View File

@@ -93,8 +93,10 @@ public:
mTargetReserveIncrement(targetReserveIncrement)
{ ; }
void doValidation(STObject& baseValidation);
// add our wishes to our validation
void doValidation(Ledger::ref lastClosedLedger, STObject& baseValidation);
// vote on the fee we want
void doFeeVoting(Ledger::ref lastClosedLedger, SHAMap::ref initialPosition);
};

View File

@@ -96,9 +96,9 @@ bool PeerSet::isActive()
return !isDone();
}
LedgerAcquire::LedgerAcquire(const uint256& hash) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT),
LedgerAcquire::LedgerAcquire(const uint256& hash, uint32 seq) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT),
mHaveBase(false), mHaveState(false), mHaveTransactions(false), mAborted(false), mSignaled(false), mAccept(false),
mByHash(true), mWaitCount(0)
mByHash(true), mWaitCount(0), mSeq(seq)
{
#ifdef LA_DEBUG
cLog(lsTRACE) << "Acquiring ledger " << mHash;
@@ -243,14 +243,15 @@ void LedgerAcquire::addPeers()
// We traverse the peer list in random order so as not to favor any particular peer
int firstPeer = rand() & vSize;
bool found = false;
int found = 0;
for (int i = 0; i < vSize; ++i)
{
Peer::ref peer = peerList[(i + firstPeer) % vSize];
if (peer->hasLedger(getHash()))
if (peer->hasLedger(getHash(), mSeq))
{
found = true;
peerHas(peer);
if (++found == 3)
break;
}
}
@@ -775,7 +776,7 @@ bool LedgerAcquire::takeTxRootNode(const std::vector<unsigned char>& data, SMAdd
mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter));
}
LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash)
LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash, uint32 seq)
{
assert(hash.isNonZero());
boost::mutex::scoped_lock sl(mLock);
@@ -785,7 +786,7 @@ LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash)
ptr->touch();
return ptr;
}
ptr = boost::make_shared<LedgerAcquire>(hash);
ptr = boost::make_shared<LedgerAcquire>(hash, seq);
if (!ptr->isDone())
{
ptr->addPeers();
@@ -941,6 +942,8 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash,
}
if (!san.isInvalid())
ledger->trigger(peer);
else
cLog(lsDEBUG) << "Peer sends invalid base data";
return;
}
@@ -975,6 +978,8 @@ void LedgerAcquireMaster::gotLedgerData(Job&, uint256 hash,
ledger->takeAsNode(nodeIDs, nodeData, ret);
if (!ret.isInvalid())
ledger->trigger(peer);
else
cLog(lsDEBUG) << "Peer sends invalid node data";
return;
}

View File

@@ -85,9 +85,10 @@ public:
typedef boost::shared_ptr<LedgerAcquire> pointer;
protected:
Ledger::pointer mLedger;
bool mHaveBase, mHaveState, mHaveTransactions, mAborted, mSignaled, mAccept, mByHash;
int mWaitCount;
Ledger::pointer mLedger;
bool mHaveBase, mHaveState, mHaveTransactions, mAborted, mSignaled, mAccept, mByHash;
int mWaitCount;
uint32 mSeq;
std::set<SHAMapNode> mRecentTXNodes;
std::set<SHAMapNode> mRecentASNodes;
@@ -104,7 +105,7 @@ protected:
boost::weak_ptr<PeerSet> pmDowncast();
public:
LedgerAcquire(const uint256& hash);
LedgerAcquire(const uint256& hash, uint32 seq);
virtual ~LedgerAcquire() { ; }
bool isBase() const { return mHaveBase; }
@@ -149,7 +150,7 @@ protected:
public:
LedgerAcquireMaster() : mRecentFailures("LedgerAcquireRecentFailures", 0, LEDGER_REACQUIRE_INTERVAL) { ; }
LedgerAcquire::pointer findCreate(const uint256& hash);
LedgerAcquire::pointer findCreate(const uint256& hash, uint32 seq);
LedgerAcquire::pointer find(const uint256& hash);
bool hasLedger(const uint256& ledgerHash);
void dropLedger(const uint256& ledgerHash);

View File

@@ -298,7 +298,7 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
{ // need to start acquiring the correct consensus LCL
cLog(lsWARNING) << "Need consensus ledger " << mPrevLedgerHash;
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash);
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(mPrevLedgerHash, 0);
mHaveCorrectLCL = false;
return;
}
@@ -317,7 +317,17 @@ void LedgerConsensus::handleLCL(const uint256& lclHash)
void LedgerConsensus::takeInitialPosition(Ledger& initialLedger)
{
SHAMap::pointer initialSet = initialLedger.peekTransactionMap()->snapShot(false);
SHAMap::pointer initialSet;
if ((theConfig.RUN_STANDALONE || (mProposing && mHaveCorrectLCL))
&& ((mPreviousLedger->getLedgerSeq() % 256) == 0))
{ // previous ledger was flag ledger
SHAMap::pointer preSet = initialLedger.peekTransactionMap()->snapShot(true);
theApp->getFeeVote().doFeeVoting(mPreviousLedger, preSet);
initialSet = preSet->snapShot(false);
}
else
initialSet = initialLedger.peekTransactionMap()->snapShot(false);
uint256 txSet = initialSet->getHash();
cLog(lsINFO) << "initial position " << txSet;
mapComplete(txSet, initialSet, false);
@@ -1208,6 +1218,8 @@ void LedgerConsensus::accept(SHAMap::ref set, LoadEvent::pointer)
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
(newLCLHash, theApp->getOPs().getValidationTimeNC(), mValPublic, mProposing);
v->setFieldU32(sfLedgerSequence, newLCL->getLedgerSeq());
if (((newLCL->getLedgerSeq() + 1) % 256) == 0) // next ledger is flag ledger
theApp->getFeeVote().doValidation(newLCL, *v);
v->sign(signingHash, mValPrivate);
v->setTrusted();
theApp->isNew(signingHash); // suppress it if we receive it

View File

@@ -25,8 +25,6 @@ enum TransactionEngineParams
tapRETRY = 0x20, // This is not the transaction's last pass
// Transaction can be retried, soft failures allowed
tapAFTER_END = 0x40, // We are processing the transaction last
tapADMIN = 0x400, // Transaction came from a privileged source
};

View File

@@ -33,7 +33,7 @@ enum LedgerNameSpace
spaceContract = 'c',
spaceSkipList = 's',
spaceFeature = 'f',
spaceFee = 's',
spaceFee = 'e',
};
enum LedgerSpecificFlags

View File

@@ -230,7 +230,7 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l
return false;
}
mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash);
mMissingLedger = theApp->getMasterLedgerAcquire().findCreate(ledgerHash, ledgerSeq);
if (mMissingLedger->isComplete())
{
Ledger::pointer lgr = mMissingLedger->getLedger();
@@ -270,7 +270,7 @@ bool LedgerMaster::acquireMissingLedger(Ledger::ref origLedger, const uint256& l
if ((fetchCount < fetchMax) && (it.first < ledgerSeq) &&
!mCompleteLedgers.hasValue(it.first) && !theApp->getMasterLedgerAcquire().find(it.second))
{
LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(it.second);
LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(it.second, it.first);
if (acq && acq->isComplete())
{
acq->getLedger()->setAccepted();
@@ -602,7 +602,7 @@ void LedgerMaster::tryPublish()
}
else
{
LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(hash);
LedgerAcquire::pointer acq = theApp->getMasterLedgerAcquire().findCreate(hash, 0);
if (!acq->isDone())
{
acq->setAccept();

View File

@@ -772,7 +772,7 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
{
cLog(lsINFO) << "Acquiring consensus ledger " << closedLedger;
if (!mAcquiringLedger || (mAcquiringLedger->getHash() != closedLedger))
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger);
mAcquiringLedger = theApp->getMasterLedgerAcquire().findCreate(closedLedger, 0);
if (!mAcquiringLedger || mAcquiringLedger->isFailed())
{
theApp->getMasterLedgerAcquire().dropLedger(closedLedger);
@@ -2031,7 +2031,7 @@ void NetworkOPs::makeFetchPack(Job&, boost::weak_ptr<Peer> wPeer, boost::shared_
newObj.set_ledgerseq(lSeq);
std::list<SHAMap::fetchPackEntry_t> pack = wantLedger->peekAccountStateMap()->getFetchPack(
haveLedger->peekAccountStateMap().get(), false, 1024 - reply.objects().size());
haveLedger->peekAccountStateMap().get(), true, 1024);
BOOST_FOREACH(SHAMap::fetchPackEntry_t& node, pack)
{
ripple::TMIndexedObject& newObj = *reply.add_objects();

View File

@@ -1488,11 +1488,14 @@ void Peer::recvGetLedger(ripple::TMGetLedger& packet)
tLog(!ledger, lsTRACE) << "Don't have ledger " << ledgerhash;
if (!ledger && (packet.has_querytype() && !packet.has_requestcookie()))
{
uint32 seq = 0;
if (packet.has_ledgerseq())
seq = packet.ledgerseq();
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
std::vector<Peer::pointer> usablePeers;
BOOST_FOREACH(Peer::ref peer, peerList)
{
if (peer->hasLedger(ledgerhash) && (peer.get() != this))
if (peer->hasLedger(ledgerhash, seq) && (peer.get() != this))
usablePeers.push_back(peer);
}
if (usablePeers.empty())
@@ -1716,8 +1719,10 @@ void Peer::recvLedger(const boost::shared_ptr<ripple::TMLedgerData>& packet_ptr)
punishPeer(LT_UnwantedData);
}
bool Peer::hasLedger(const uint256& hash) const
bool Peer::hasLedger(const uint256& hash, uint32 seq) const
{
if ((seq != 0) && (seq >= mMinLedger) && (seq <= mMaxLedger))
return true;
BOOST_FOREACH(const uint256& ledger, mRecentLedgers)
if (ledger == hash)
return true;

View File

@@ -157,7 +157,7 @@ public:
bool isOutbound() const { return !mInbound; }
const uint256& getClosedLedgerHash() const { return mClosedLedgerHash; }
bool hasLedger(const uint256& hash) const;
bool hasLedger(const uint256& hash, uint32 seq) const;
bool hasTxSet(const uint256& hash) const;
uint64 getPeerId() const { return mPeerId; }

View File

@@ -71,7 +71,6 @@ void SHAMap::getMissingNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint2
SHAMapTreeNode::pointer ptr =
boost::make_shared<SHAMapTreeNode>(childID, nodeData, mSeq - 1,
snfPREFIX, childHash, true);
cLog(lsTRACE) << "Got sync node from cache: " << *ptr;
mTNByID[*ptr] = ptr;
d = ptr.get();
filter->gotNode(true, childID, childHash, nodeData, ptr->getType());

View File

@@ -15,8 +15,10 @@ void SVFInit()
sValidationFormat.push_back(SOElement(sfLedgerSequence, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfCloseTime, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfLoadFee, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfFeatures, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfBaseFee, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfReserveBase, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfReserveIncrement, SOE_OPTIONAL));
sValidationFormat.push_back(SOElement(sfSigningTime, SOE_REQUIRED));
sValidationFormat.push_back(SOElement(sfSigningPubKey, SOE_REQUIRED));
sValidationFormat.push_back(SOElement(sfSignature, SOE_OPTIONAL));

View File

@@ -204,10 +204,13 @@ TER Transactor::apply()
if (!mTxnAccount)
{
cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
mTxn.getSourceAccount().humanAccountID());
if (mustHaveValidAccount())
{
cLog(lsTRACE) << boost::str(boost::format("applyTransaction: Delay transaction: source account does not exist: %s") %
mTxn.getSourceAccount().humanAccountID());
return terNO_ACCOUNT;
return terNO_ACCOUNT;
}
}
else
{
@@ -225,7 +228,8 @@ TER Transactor::apply()
terResult = checkSig();
if (terResult != tesSUCCESS) return(terResult);
mEngine->entryModify(mTxnAccount);
if (mTxnAccount)
mEngine->entryModify(mTxnAccount);
return doApply();
}

View File

@@ -36,6 +36,8 @@ protected:
Transactor(const SerializedTransaction& txn, TransactionEngineParams params, TransactionEngine* engine);
virtual bool mustHaveValidAccount() { return true; }
public:
typedef boost::shared_ptr<Transactor> pointer;

View File

@@ -94,9 +94,9 @@ public:
<< std::endl;*/
if (!m_avaliable.empty()) {
p = m_avaliable.front();
p = m_avaliable.front(); // FIXME can call intrusive_ptr_add_ref (line 215) which can deadlock
q = p;
m_avaliable.pop(); // FIXME can call intrusive_ptr_release(line 217) which can deadlock
m_avaliable.pop(); // FIXME can call intrusive_ptr_release (line 217) which can deadlock
m_used[p->get_index()] = p;
} else {
if (m_cur_elements == m_max_elements) {