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

This commit is contained in:
Arthur Britto
2012-11-21 16:25:59 -08:00
23 changed files with 264 additions and 135 deletions

View File

@@ -21,7 +21,7 @@
#define CONFIG_FILE_NAME SYSTEM_NAME "d.cfg" // rippled.cfg
#define DEFAULT_VALIDATORS_SITE "redstem.com"
#define DEFAULT_VALIDATORS_SITE ""
#define VALIDATORS_FILE_NAME "validators.txt"
const int SYSTEM_PEER_PORT = 6561;

View File

@@ -396,7 +396,7 @@ bool LedgerAcquire::takeBase(const std::string& data)
}
bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data)
const std::list< std::vector<unsigned char> >& data, SMAddNode& san)
{
if (!mHaveBase) return false;
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
@@ -406,11 +406,15 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
{
if (nodeIDit->isRoot())
{
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait, snfWIRE, &tFilter))
if (!san.combine(mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait,
snfWIRE, &tFilter)))
return false;
}
else
{
if (!san.combine(mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)))
return false;
}
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
return false;
++nodeIDit;
++nodeDatait;
}
@@ -428,7 +432,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
}
bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data)
const std::list< std::vector<unsigned char> >& data, SMAddNode& san)
{
cLog(lsTRACE) << "got ASdata (" << nodeIDs.size() <<") acquiring ledger " << mHash;
tLog(nodeIDs.size() == 1, lsTRACE) << "got AS node: " << nodeIDs.front();
@@ -446,14 +450,14 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
{
if (nodeIDit->isRoot())
{
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(),
*nodeDatait, snfWIRE, &tFilter))
if (!san.combine(mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(),
*nodeDatait, snfWIRE, &tFilter)))
{
cLog(lsWARNING) << "Bad ledger base";
return false;
}
}
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
else if (!san.combine(mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)))
{
cLog(lsWARNING) << "Unable to add AS node";
return false;
@@ -474,24 +478,22 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
return true;
}
bool LedgerAcquire::takeAsRootNode(const std::vector<unsigned char>& data)
bool LedgerAcquire::takeAsRootNode(const std::vector<unsigned char>& data, SMAddNode& san)
{
if (!mHaveBase)
return false;
AccountStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), data, snfWIRE, &tFilter))
return false;
return true;
return san.combine(
mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), data, snfWIRE, &tFilter));
}
bool LedgerAcquire::takeTxRootNode(const std::vector<unsigned char>& data)
bool LedgerAcquire::takeTxRootNode(const std::vector<unsigned char>& data, SMAddNode& san)
{
if (!mHaveBase)
return false;
TransactionStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter))
return false;
return true;
return san.combine(
mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), data, snfWIRE, &tFilter));
}
LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash)
@@ -532,13 +534,13 @@ void LedgerAcquireMaster::dropLedger(const uint256& hash)
mLedgers.erase(hash);
}
bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref peer)
SMAddNode LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref peer)
{
uint256 hash;
if (packet.ledgerhash().size() != 32)
{
std::cerr << "Acquire error" << std::endl;
return false;
return SMAddNode::invalid();
}
memcpy(hash.begin(), packet.ledgerhash().data(), 32);
cLog(lsTRACE) << "Got data (" << packet.nodes().size() << ") for acquiring ledger: " << hash;
@@ -547,7 +549,7 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
if (!ledger)
{
cLog(lsINFO) << "Got data for ledger we're not acquiring";
return false;
return SMAddNode();
}
if (packet.type() == ripple::liBASE)
@@ -555,23 +557,24 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
if (packet.nodes_size() < 1)
{
cLog(lsWARNING) << "Got empty base data";
return false;
return SMAddNode::invalid();
}
if (!ledger->takeBase(packet.nodes(0).nodedata()))
{
cLog(lsWARNING) << "Got invalid base data";
return false;
return SMAddNode::invalid();
}
if ((packet.nodes().size() > 1) && !ledger->takeAsRootNode(strCopy(packet.nodes(1).nodedata())))
SMAddNode san = SMAddNode::useful();
if ((packet.nodes().size() > 1) && !ledger->takeAsRootNode(strCopy(packet.nodes(1).nodedata()), san))
{
cLog(lsWARNING) << "Included ASbase invalid";
}
if ((packet.nodes().size() > 2) && !ledger->takeTxRootNode(strCopy(packet.nodes(2).nodedata())))
if ((packet.nodes().size() > 2) && !ledger->takeTxRootNode(strCopy(packet.nodes(2).nodedata()), san))
{
cLog(lsWARNING) << "Included TXbase invalid";
}
ledger->trigger(peer, false);
return true;
return san;
}
if ((packet.type() == ripple::liTX_NODE) || (packet.type() == ripple::liAS_NODE))
@@ -581,8 +584,8 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
if (packet.nodes().size() <= 0)
{
cLog(lsINFO) << "Got request for no nodes";
return false;
cLog(lsINFO) << "Got response with no nodes";
return SMAddNode::invalid();
}
for (int i = 0; i < packet.nodes().size(); ++i)
{
@@ -590,24 +593,24 @@ bool LedgerAcquireMaster::gotLedgerData(ripple::TMLedgerData& packet, Peer::ref
if (!node.has_nodeid() || !node.has_nodedata())
{
cLog(lsWARNING) << "Got bad node";
return false;
return SMAddNode::invalid();
}
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
}
bool ret;
SMAddNode ret;
if (packet.type() == ripple::liTX_NODE)
ret = ledger->takeTxNode(nodeIDs, nodeData);
ledger->takeTxNode(nodeIDs, nodeData, ret);
else
ret = ledger->takeAsNode(nodeIDs, nodeData);
if (ret)
ledger->takeAsNode(nodeIDs, nodeData, ret);
if (!ret.isInvalid())
ledger->trigger(peer, false);
return ret;
}
cLog(lsWARNING) << "Not sure what ledger data we got";
return false;
return SMAddNode::invalid();
}
// vim:ts=4

View File

@@ -97,10 +97,12 @@ public:
void addOnComplete(boost::function<void (LedgerAcquire::pointer)>);
bool takeBase(const std::string& data);
bool takeTxNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data);
bool takeTxRootNode(const std::vector<unsigned char>& data);
bool takeAsNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data);
bool takeAsRootNode(const std::vector<unsigned char>& data);
bool takeTxNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
SMAddNode&);
bool takeTxRootNode(const std::vector<unsigned char>& data, SMAddNode&);
bool takeAsNode(const std::list<SHAMapNode>& IDs, const std::list<std::vector<unsigned char> >& data,
SMAddNode&);
bool takeAsRootNode(const std::vector<unsigned char>& data, SMAddNode&);
void trigger(Peer::ref, bool timer);
bool tryLocal();
void addPeers();
@@ -119,7 +121,7 @@ public:
LedgerAcquire::pointer find(const uint256& hash);
bool hasLedger(const uint256& ledgerHash);
void dropLedger(const uint256& ledgerHash);
bool gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
SMAddNode gotLedgerData(ripple::TMLedgerData& packet, Peer::ref);
};
#endif

View File

@@ -126,21 +126,23 @@ void TransactionAcquire::trigger(Peer::ref peer, bool timer)
resetTimer();
}
bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
SMAddNode TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
const std::list< std::vector<unsigned char> >& data, Peer::ref peer)
{
if (mComplete)
{
cLog(lsTRACE) << "TX set complete";
return true;
return SMAddNode();
}
if (mFailed)
{
cLog(lsTRACE) << "TX set failed";
return false;
return SMAddNode();
}
try
{
if (nodeIDs.empty())
return SMAddNode::invalid();
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
ConsensusTransSetSF sf;
@@ -151,12 +153,12 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
if (mHaveRoot)
{
cLog(lsWARNING) << "Got root TXS node, already have it";
return false;
return SMAddNode();
}
if (!mMap->addRootNode(getHash(), *nodeDatait, snfWIRE, NULL))
{
cLog(lsWARNING) << "TX acquire got bad root node";
return false;
return SMAddNode::invalid();
}
else
mHaveRoot = true;
@@ -164,19 +166,19 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait, &sf))
{
cLog(lsWARNING) << "TX acquire got bad non-root node";
return false;
return SMAddNode::invalid();
}
++nodeIDit;
++nodeDatait;
}
trigger(peer, false);
progress();
return true;
return SMAddNode::useful();
}
catch (...)
{
cLog(lsERROR) << "Peer sends us junky transaction node data";
return false;
return SMAddNode::invalid();
}
}
@@ -996,14 +998,14 @@ bool LedgerConsensus::peerHasSet(Peer::ref peer, const uint256& hashSet, ripple:
return true;
}
bool LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
SMAddNode LedgerConsensus::peerGaveNodes(Peer::ref peer, const uint256& setHash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
{
boost::unordered_map<uint256, TransactionAcquire::pointer>::iterator acq = mAcquiring.find(setHash);
if (acq == mAcquiring.end())
{
cLog(lsINFO) << "Got TX data for set not acquiring: " << setHash;
return false;
return SMAddNode();
}
TransactionAcquire::pointer set = acq->second; // We must keep the set around during the function
return set->takeNodes(nodeIDs, nodeData, peer);

View File

@@ -45,7 +45,8 @@ public:
SHAMap::pointer getMap() { return mMap; }
bool takeNodes(const std::list<SHAMapNode>& IDs, const std::list< std::vector<unsigned char> >& data, Peer::ref);
SMAddNode takeNodes(const std::list<SHAMapNode>& IDs,
const std::list< std::vector<unsigned char> >& data, Peer::ref);
};
class LCTransaction
@@ -184,7 +185,7 @@ public:
bool peerHasSet(Peer::ref peer, const uint256& set, ripple::TxSetStatus status);
bool peerGaveNodes(Peer::ref peer, const uint256& setHash,
SMAddNode peerGaveNodes(Peer::ref peer, const uint256& setHash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
bool isOurPubKey(const RippleAddress &k) { return k == mValPublic; }

View File

@@ -407,22 +407,26 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
mSet.setAffectedNode(it.first, *type, nodeType);
if (type == &sfDeletedNode)
{ // nodes was deleted
{
assert(origNode);
assert(curNode);
threadOwners(origNode, mLedger, newMod); // thread transaction to owners
STObject mods(sfPreviousFields);
STObject prevs(sfPreviousFields);
BOOST_FOREACH(const SerializedType& obj, *origNode)
{ // go through the original node for modified fields saved on modification
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
prevs.addObject(obj);
}
if (!prevs.empty())
mSet.getAffectedNode(it.first, *type).addObject(prevs);
STObject finals(sfFinalFields);
BOOST_FOREACH(const SerializedType& obj, *curNode)
{
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
mods.addObject(obj);
{ // go through the final node for final fields
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_DeleteFinal))
finals.addObject(obj);
}
if (!mods.empty())
mSet.getAffectedNode(it.first, *type).addObject(mods);
if (!finals.empty())
mSet.getAffectedNode(it.first, *type).addObject(finals);
}
@@ -431,17 +435,21 @@ void LedgerEntrySet::calcRawMeta(Serializer& s, TER result)
if (curNode->isThreadedType()) // thread transaction to node it modified
threadTx(curNode, mLedger, newMod);
STObject mods(sfPreviousFields);
STObject finals(sfFinalFields);
STObject prevs(sfPreviousFields);
BOOST_FOREACH(const SerializedType& obj, *origNode)
{ // search the original node for values saved on modify
if (obj.getFName().shouldMeta(SField::sMD_ChangeOrig) && !curNode->hasMatchingEntry(obj))
mods.addObject(obj);
prevs.addObject(obj);
}
if (!prevs.empty())
mSet.getAffectedNode(it.first, *type).addObject(prevs);
STObject finals(sfFinalFields);
BOOST_FOREACH(const SerializedType& obj, *curNode)
{ // search the final node for values saved always
if (obj.getFName().shouldMeta(SField::sMD_Always | SField::sMD_ChangeNew))
finals.addObject(obj);
}
if (!mods.empty())
mSet.getAffectedNode(it.first, *type).addObject(mods);
if (!finals.empty())
mSet.getAffectedNode(it.first, *type).addObject(finals);
}

View File

@@ -813,13 +813,13 @@ SHAMap::pointer NetworkOPs::getTXMap(const uint256& hash)
return mConsensus->getTransactionTree(hash, false);
}
bool NetworkOPs::gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
SMAddNode NetworkOPs::gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData)
{
if (!haveConsensusObject())
{
cLog(lsWARNING) << "Got TX data with no consensus object";
return false;
return SMAddNode();
}
return mConsensus->peerGaveNodes(peer, hash, nodeIDs, nodeData);
}
@@ -1029,18 +1029,17 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted)
for (SHAMapItem::pointer item = txSet.peekFirstItem(); !!item; item = txSet.peekNextItem(item->getTag()))
{
SerializedTransaction::pointer stTxn = theApp->getMasterTransaction().fetch(item, false, 0);
if(stTxn)
{
// XXX Need to support other results.
// XXX Need to give failures too.
TER terResult = tesSUCCESS;
SerializerIterator it(item->peekSerializer());
SerializerIterator it(item->peekSerializer());
TransactionMetaSet::pointer meta = boost::make_shared<TransactionMetaSet>(stTxn->getTransactionID(), lpAccepted->getLedgerSeq(), it.getVL());
pubAcceptedTransaction(lpAccepted, *stTxn, terResult,meta);
}
// OPTIMIZEME: Could get transaction from txn master, but still must call getVL
Serializer txnSer(it.getVL());
SerializerIterator txnIt(txnSer);
SerializedTransaction stTxn(txnIt);
TransactionMetaSet::pointer meta = boost::make_shared<TransactionMetaSet>(
stTxn.getTransactionID(), lpAccepted->getLedgerSeq(), it.getVL());
pubAcceptedTransaction(lpAccepted, stTxn, meta->getResultTER(), meta);
}
}
}
@@ -1135,6 +1134,7 @@ void NetworkOPs::pubAccountTransaction(Ledger::ref lpCurrent, const SerializedTr
if (!notify.empty())
{
Json::Value jvObj = transJson(stTxn, terResult, bAccepted, lpCurrent, "account");
if(meta) jvObj["meta"]=meta->getJson(0);
BOOST_FOREACH(InfoSub* ispListener, notify)
{
@@ -1194,7 +1194,7 @@ void NetworkOPs::subAccount(InfoSub* ispListener, const boost::unordered_set<Rip
boost::unordered_set<InfoSub*> usisElement;
usisElement.insert(ispListener);
mSubAccount.insert(simIterator, make_pair(naAccountID.getAccountID(), usisElement));
subMap.insert(simIterator, make_pair(naAccountID.getAccountID(), usisElement));
}
else
{

View File

@@ -199,7 +199,7 @@ public:
// ledger proposal/close functions
void processTrustedProposal(LedgerProposal::pointer proposal, boost::shared_ptr<ripple::TMProposeSet> set,
RippleAddress nodePublic, uint256 checkLedger, bool sigGood);
bool gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
SMAddNode gotTXData(const boost::shared_ptr<Peer>& peer, const uint256& hash,
const std::list<SHAMapNode>& nodeIDs, const std::list< std::vector<unsigned char> >& nodeData);
bool recvValidation(const SerializedValidation::pointer& val);
SHAMap::pointer getTXMap(const uint256& hash);

View File

@@ -1432,12 +1432,14 @@ void Peer::recvLedger(ripple::TMLedgerData& packet)
nodeIDs.push_back(SHAMapNode(node.nodeid().data(), node.nodeid().size()));
nodeData.push_back(std::vector<unsigned char>(node.nodedata().begin(), node.nodedata().end()));
}
if (!theApp->getOPs().gotTXData(shared_from_this(), hash, nodeIDs, nodeData))
SMAddNode san = theApp->getOPs().gotTXData(shared_from_this(), hash, nodeIDs, nodeData);
if (san.isInvalid())
punishPeer(PP_UNWANTED_DATA);
return;
}
if (!theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this()))
SMAddNode san = theApp->getMasterLedgerAcquire().gotLedgerData(packet, shared_from_this());
if (san.isInvalid())
punishPeer(PP_UNWANTED_DATA);
}

View File

@@ -22,6 +22,12 @@ enum PeerPunish
PP_BAD_SIGNATURE = 4, // Object had bad signature
};
enum PeerReward
{
PR_NEEDED_DATA = 1,
PR_NEW_TRANSACTION = 2,
};
typedef std::pair<std::string,int> ipPort;
DEFINE_INSTANCE(Peer);

View File

@@ -213,12 +213,28 @@ void ProofOfWorkGenerator::sweep()
void ProofOfWorkGenerator::loadHigh()
{
// WRITEME
time_t now = time(NULL);
boost::mutex::scoped_lock sl(mLock);
if (mLastDifficultyChange == now)
return;
if (mPowEntry == 30)
return;
++mPowEntry;
mLastDifficultyChange = now;
}
void ProofOfWorkGenerator::loadLow()
{
// WRITEME
time_t now = time(NULL);
boost::mutex::scoped_lock sl(mLock);
if (mLastDifficultyChange == now)
return;
if (mPowEntry == 0)
return;
--mPowEntry;
mLastDifficultyChange = now;
}
struct PowEntry

View File

@@ -281,6 +281,44 @@ public:
extern std::ostream& operator<<(std::ostream&, const SHAMapMissingNode&);
class SMAddNode
{ // results of adding nodes
protected:
bool mInvalid, mUseful;
SMAddNode(bool i, bool u) : mInvalid(i), mUseful(u) { ; }
public:
SMAddNode() : mInvalid(false), mUseful(false) { ; }
void setInvalid() { mInvalid = true; }
void setUseful() { mUseful = true; }
void reset() { mInvalid = false; mUseful = false; }
bool isInvalid() const { return mInvalid; }
bool isUseful() const { return mUseful; }
bool combine(const SMAddNode& n)
{
if (n.mInvalid)
{
mInvalid = true;
return false;
}
if (n.mUseful)
mUseful = true;
return true;
}
operator bool() const { return !mInvalid; }
static SMAddNode okay() { return SMAddNode(false, false); }
static SMAddNode useful() { return SMAddNode(false, true); }
static SMAddNode invalid() { return SMAddNode(true, false); }
};
extern bool SMANCombine(SMAddNode& existing, const SMAddNode& additional);
class SHAMap : public IS_INSTANCE(SHAMap)
{
public:
@@ -374,11 +412,11 @@ public:
bool getNodeFat(const SHAMapNode& node, std::vector<SHAMapNode>& nodeIDs,
std::list<std::vector<unsigned char> >& rawNode, bool fatRoot, bool fatLeaves);
bool getRootNode(Serializer& s, SHANodeFormat format);
bool addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SMAddNode addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter);
bool addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SMAddNode addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter);
bool addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode,
SMAddNode addKnownNode(const SHAMapNode& nodeID, const std::vector<unsigned char>& rawNode,
SHAMapSyncFilter* filter);
// status functions

View File

@@ -135,7 +135,8 @@ bool SHAMap::getRootNode(Serializer& s, SHANodeFormat format)
return true;
}
bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format, SHAMapSyncFilter* filter)
SMAddNode SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter)
{
boost::recursive_mutex::scoped_lock sl(mLock);
@@ -143,12 +144,12 @@ bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeForm
if (root->getNodeHash().isNonZero())
{
cLog(lsTRACE) << "got root node, already have one";
return true;
return SMAddNode::okay();
}
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), rootNode, 0, format);
if (!node)
return false;
return SMAddNode::invalid();
#ifdef DEBUG
node->dump();
@@ -170,10 +171,10 @@ bool SHAMap::addRootNode(const std::vector<unsigned char>& rootNode, SHANodeForm
filter->gotNode(*root, root->getNodeHash(), s.peekData(), root->getType());
}
return true;
return SMAddNode::useful();
}
bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SMAddNode SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>& rootNode, SHANodeFormat format,
SHAMapSyncFilter* filter)
{
boost::recursive_mutex::scoped_lock sl(mLock);
@@ -183,14 +184,12 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
{
cLog(lsTRACE) << "got root node, already have one";
assert(root->getNodeHash() == hash);
return true;
return SMAddNode::okay();
}
SHAMapTreeNode::pointer node = boost::make_shared<SHAMapTreeNode>(SHAMapNode(), rootNode, 0, format);
if (!node)
return false;
if (node->getNodeHash() != hash)
return false;
if (!node || node->getNodeHash() != hash)
return SMAddNode::invalid();
returnNode(root, true);
root = node;
@@ -207,42 +206,42 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector<unsigned char>&
filter->gotNode(*root, root->getNodeHash(), s.peekData(), root->getType());
}
return true;
return SMAddNode::useful();
}
bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode,
SMAddNode SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned char>& rawNode,
SHAMapSyncFilter* filter)
{ // return value: true=okay, false=error
assert(!node.isRoot());
if (!isSynching())
{
cLog(lsINFO) << "AddKnownNode while not synching";
return true;
return SMAddNode::okay();
}
boost::recursive_mutex::scoped_lock sl(mLock);
if (checkCacheNode(node))
return true;
return SMAddNode::okay();
std::stack<SHAMapTreeNode::pointer> stack = getStack(node.getNodeID(), true, true);
if (stack.empty())
{
cLog(lsWARNING) << "AddKnownNode with empty stack";
return false;
return SMAddNode::invalid();
}
SHAMapTreeNode::pointer iNode = stack.top();
if (!iNode)
{ // we should always have a root
assert(false);
return true;
return SMAddNode::invalid();
}
if (iNode->isLeaf() || (iNode->getDepth() >= node.getDepth()))
{
cLog(lsTRACE) << "got inner node, already had it (late)";
return true;
return SMAddNode::okay();
}
if (iNode->getDepth() != (node.getDepth() - 1))
@@ -250,25 +249,25 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
cLog(lsWARNING) << "unable to hook node " << node;
cLog(lsINFO) << " stuck at " << *iNode;
cLog(lsINFO) << "got depth=" << node.getDepth() << ", walked to= " << iNode->getDepth();
return false;
return SMAddNode::invalid();
}
int branch = iNode->selectBranch(node.getNodeID());
if (branch < 0)
{
assert(false);
return false;
return SMAddNode::invalid();
}
uint256 hash = iNode->getChildHash(branch);
if (!hash)
{
cLog(lsWARNING) << "AddKnownNode for empty branch";
return false;
return SMAddNode::invalid();
}
SHAMapTreeNode::pointer newNode = boost::make_shared<SHAMapTreeNode>(node, rawNode, mSeq, snfWIRE);
if (hash != newNode->getNodeHash()) // these aren't the droids we're looking for
return false;
return SMAddNode::invalid();
if (filter)
{
@@ -279,7 +278,7 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
mTNByID[*newNode] = newNode;
if (!newNode->isLeaf())
return true; // only a leaf can fill a branch
return SMAddNode::useful(); // only a leaf can fill a branch
// did this new leaf cause its parents to fill up
do
@@ -294,11 +293,11 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
{
SHAMapTreeNode::pointer nextNode = getNode(iNode->getChildNodeID(i), iNode->getChildHash(i), false);
if (nextNode->isInner() && !nextNode->isFullBelow())
return true;
return SMAddNode::useful();
}
catch (SHAMapMissingNode&)
{
return true;
return SMAddNode::useful();
}
}
iNode->setFullBelow();
@@ -306,7 +305,7 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vector<unsigned cha
if (root->isFullBelow())
clearSynching();
return true;
return SMAddNode::useful();
}
bool SHAMap::deepCompare(SHAMap& other)
@@ -486,6 +485,8 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test )
cLog(lsFATAL) << "Didn't get root node " << gotNodes.size();
BOOST_FAIL("NodeSize");
}
SMAddNode node();
if (!destination.addRootNode(*gotNodes.begin(), snfWIRE, NULL))
{
cLog(lsFATAL) << "AddRootNode fails";

View File

@@ -93,6 +93,7 @@ public:
// totality functions
const std::vector<unsigned char>& peekData() const { return mData; }
std::vector<unsigned char> getData() const { return mData; }
std::vector<unsigned char>& modData() { return mData; }
int getCapacity() const { return mData.capacity(); }
int getDataLength() const { return mData.size(); }
const void* getDataPtr() const { return &mData.front(); }

View File

@@ -31,16 +31,29 @@ Transaction::pointer TransactionMaster::fetch(const uint256& txnID, bool checkDi
return txn;
}
SerializedTransaction::pointer TransactionMaster::fetch(SHAMapItem::ref item, bool checkDisk, uint32 uCommitLedger)
SerializedTransaction::pointer TransactionMaster::fetch(SHAMapItem::ref item, SHAMapTreeNode::TNType type,
bool checkDisk, uint32 uCommitLedger)
{
SerializedTransaction::pointer txn;
Transaction::pointer iTx = theApp->getMasterTransaction().fetch(item->getTag(), false);
if (!iTx)
{
SerializerIterator sit(item->peekSerializer());
txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
if (type == SHAMapTreeNode::tnTRANSACTION_NM)
{
SerializerIterator sit(item->peekSerializer());
txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
}
else if (type == SHAMapTreeNode::tnTRANSACTION_MD)
{
Serializer s;
int length;
item->peekSerializer().getVL(s.modData(), 0, length);
SerializerIterator sit(s);
txn = boost::make_shared<SerializedTransaction>(boost::ref(sit));
}
}
else
{

View File

@@ -16,7 +16,8 @@ public:
TransactionMaster();
Transaction::pointer fetch(const uint256&, bool checkDisk);
SerializedTransaction::pointer fetch(SHAMapItem::ref item, bool checkDisk, uint32 uCommitLedger);
SerializedTransaction::pointer fetch(SHAMapItem::ref item, SHAMapTreeNode:: TNType type,
bool checkDisk, uint32 uCommitLedger);
// return value: true = we had the transaction already
bool canonicalize(Transaction::pointer& txn, bool maybeNew);

View File

@@ -37,6 +37,8 @@ public:
const uint256& getTxID() { return mTransactionID; }
uint32 getLgrSeq() { return mLedger; }
int getResult() const { return mResult; }
TER getResultTER() const { return static_cast<TER>(mResult); }
bool isNodeAffected(const uint256&) const;
void setAffectedNode(const uint256&, SField::ref type, uint16 nodeType);
@@ -45,6 +47,7 @@ public:
const STObject& peekAffectedNode(const uint256&) const;
//std::vector<RippleAddress> getAffectedAccounts();
Json::Value getJson(int p) const { return getAsObject().getJson(p); }
void addRaw(Serializer&, TER);

View File

@@ -1547,14 +1547,17 @@ void UniqueNodeList::validatorsResponse(const boost::system::error_code& err, st
void UniqueNodeList::nodeNetwork()
{
HttpsClient::httpsGet(
theApp->getIOService(),
theConfig.VALIDATORS_SITE,
443,
VALIDATORS_FILE_PATH,
VALIDATORS_FILE_BYTES_MAX,
boost::posix_time::seconds(VALIDATORS_FETCH_SECONDS),
boost::bind(&UniqueNodeList::validatorsResponse, this, _1, _2));
if(!theConfig.VALIDATORS_SITE.empty())
{
HttpsClient::httpsGet(
theApp->getIOService(),
theConfig.VALIDATORS_SITE,
443,
VALIDATORS_FILE_PATH,
VALIDATORS_FILE_BYTES_MAX,
boost::posix_time::seconds(VALIDATORS_FETCH_SECONDS),
boost::bind(&UniqueNodeList::validatorsResponse, this, _1, _2));
}
}
void UniqueNodeList::nodeBootstrap()

View File

@@ -50,7 +50,6 @@ Json::Value WSConnection::invokeCommand(Json::Value& jvRequest)
// Regular RPC command
{
boost::recursive_mutex::scoped_lock sl(theApp->getMasterLock());
jvResult["result"] = mRPCHandler.doCommand(
jvRequest["command"].asString(),
jvRequest.isMember("params")

View File

@@ -5,6 +5,7 @@ enum MessageType {
mtHELLO = 1;
mtERROR_MSG = 2;
mtPING = 3;
mtPOW = 4;
// network presence detection
mtGET_CONTACTS = 10;
@@ -32,20 +33,44 @@ enum MessageType {
}
// Sent on connect
// empty message (or just result) = request proof of work
// token, iterations, target, challenge = give proof of work challenge
// token, response = show proof of work
// token, result = result of pow attempt
message TMProofWork
{
optional string token = 1;
optional uint32 iterations = 2;
optional bytes target = 3;
optional bytes challenge = 4;
optional bytes response = 5;
enum POWResult
{
powrOK = 0;
powrREUSED = 1;
powrEXPIRED = 2; // You took too long solving
powrTOOEASY = 3; // Difficulty went way up, sorry
powrINVALID = 4;
powrDISCONNECT = 5; // We are disconnecting
}
optional POWResult result = 6;
}
// Sent on connect
message TMHello {
required uint32 protoVersion = 1;
required uint32 protoVersionMin = 2;
required bytes nodePublic = 3;
required bytes nodeProof = 4;
optional string fullVersion = 5;
optional uint64 netTime = 6;
optional uint32 ipv4Port = 7;
optional uint32 ledgerIndex = 8;
optional bytes ledgerClosed = 9; // our last closed ledger
optional bytes ledgerPrevious = 10; // the ledger before the last closed ledger
optional bool nodePrivate = 11; // Request to not forward IP.
required uint32 protoVersion = 1;
required uint32 protoVersionMin = 2;
required bytes nodePublic = 3;
required bytes nodeProof = 4;
optional string fullVersion = 5;
optional uint64 netTime = 6;
optional uint32 ipv4Port = 7;
optional uint32 ledgerIndex = 8;
optional bytes ledgerClosed = 9; // our last closed ledger
optional bytes ledgerPrevious = 10; // the ledger before the last closed ledger
optional bool nodePrivate = 11; // Request to not forward IP.
optional TMProofWork proofOfWork = 12; // request/provide proof of work
}