Complete the fetch by hash logic, including tracking the hashes we want.

This commit is contained in:
JoelKatz
2013-01-04 22:14:53 -08:00
parent cb6f73cc89
commit dfbd640f6c
6 changed files with 71 additions and 7 deletions

View File

@@ -229,14 +229,16 @@ void LedgerAcquire::trigger(Peer::ref peer)
{
tmGL.set_querytype(ripple::qtINDIRECT);
#if 0
if (!isProgress())
{
std::vector<neededHash_t> need = getNeededHashes();
if (!need.empty())
{
ripple::TMGetObjectByHash tmBH;
tmBH.set_query(true);
tmBH.set_ledgerhash(mHash.begin(), mHash.size());
if (mHaveBase)
tmBH.set_seq(mLedger->getLedgerSeq());
bool typeSet = false;
BOOST_FOREACH(neededHash_t& p, need)
{
@@ -247,17 +249,27 @@ void LedgerAcquire::trigger(Peer::ref peer)
}
if (p.first == tmBH.type())
{
// WRITEME: Approve this hash for local inclusion
theApp->getOPs().addWantedHash(p.second);
ripple::TMIndexedObject *io = tmBH.add_objects();
io->set_hash(p.second.begin(), p.second.size());
}
}
// WRITEME: Do something with this object
PackedMessage::pointer packet = boost::make_shared<PackedMessage>(tmBH, ripple::mtGET_OBJECTS);
if (peer)
peer->sendPacket(packet);
else
{
boost::recursive_mutex::scoped_lock sl(mLock);
for (boost::unordered_map<uint64, int>::iterator it = mPeers.begin(), end = mPeers.end();
it != end; ++it)
{
Peer::pointer iPeer = theApp->getConnectionPool().getPeerById(it->first);
if (iPeer)
iPeer->sendPacket(packet);
}
}
}
}
#endif
}

View File

@@ -15,6 +15,7 @@ LoadManager::LoadManager(int creditRate, int creditLimit, int debitWarn, int deb
addLoadCost(LoadCost(LT_RequestNoReply, 1, LC_CPU | LC_Disk));
addLoadCost(LoadCost(LT_InvalidSignature, 100, LC_CPU));
addLoadCost(LoadCost(LT_UnwantedData, 5, LC_CPU | LC_Network));
addLoadCost(LoadCost(LT_BadData, 20, LC_CPU));
addLoadCost(LoadCost(LT_NewTrusted, 10, 0));
addLoadCost(LoadCost(LT_NewTransaction, 2, 0));

View File

@@ -18,6 +18,7 @@ enum LoadType
LT_InvalidSignature, // An object whose signature we had to check and it failed
LT_UnwantedData, // Data we have no use for
LT_BadPoW, // Proof of work not valid
LT_BadData, // Data we have to verify before rejecting
// Good things
LT_NewTrusted, // A new transaction/validation/proposal we trust

View File

@@ -100,6 +100,18 @@ bool NetworkOPs::haveLedgerRange(uint32 from, uint32 to)
return mLedgerMaster->haveLedgerRange(from, to);
}
bool NetworkOPs::addWantedHash(const uint256& h)
{
boost::recursive_mutex::scoped_lock sl(mWantedHashLock);
return mWantedHashes.insert(h).second;
}
bool NetworkOPs::isWantedHash(const uint256& h, bool remove)
{
boost::recursive_mutex::scoped_lock sl(mWantedHashLock);
return (remove ? mWantedHashes.erase(h) : mWantedHashes.count(h)) != 0;
}
void NetworkOPs::submitTransaction(Job&, SerializedTransaction::pointer iTrans, stCallback callback)
{ // this is an asynchronous interface
Serializer s;

View File

@@ -108,6 +108,9 @@ protected:
boost::unordered_set<InfoSub*> mSubTransactions; // all accepted transactions
boost::unordered_set<InfoSub*> mSubRTTransactions; // all proposed and accepted transactions
boost::recursive_mutex mWantedHashLock;
boost::unordered_set<uint256> mWantedHashes;
void setMode(OperatingMode);
Json::Value transJson(const SerializedTransaction& stTxn, TER terResult, bool bAccepted, Ledger::ref lpCurrent, const std::string& strType);
@@ -245,6 +248,9 @@ public:
void storeProposal(const LedgerProposal::pointer& proposal, const RippleAddress& peerPublic);
uint256 getConsensusLCL();
bool addWantedHash(const uint256& h);
bool isWantedHash(const uint256& h, bool remove);
// client information retrieval functions
std::vector< std::pair<Transaction::pointer, TransactionMetaSet::pointer> >
getAccountTxs(const RippleAddress& account, uint32 minLedger, uint32 maxLedger);

View File

@@ -1111,6 +1111,8 @@ void Peer::recvGetObjectByHash(ripple::TMGetObjectByHash& packet)
newObj.set_data(&hObj->getData().front(), hObj->getData().size());
if (obj.has_nodeid())
newObj.set_index(obj.nodeid());
if (!packet.has_seq() && (hObj->getIndex() != 0))
packet.set_seq(hObj->getIndex());
}
}
}
@@ -1119,7 +1121,37 @@ void Peer::recvGetObjectByHash(ripple::TMGetObjectByHash& packet)
}
else
{ // this is a reply
// WRITEME
uint32 seq = packet.has_seq() ? packet.seq() : 0;
HashedObjectType type;
switch (packet.type())
{
case ripple::TMGetObjectByHash::otLEDGER: type = hotLEDGER; break;
case ripple::TMGetObjectByHash::otTRANSACTION: type = hotTRANSACTION; break;
case ripple::TMGetObjectByHash::otSTATE_NODE: type = hotACCOUNT_NODE; break;
case ripple::TMGetObjectByHash::otTRANSACTION_NODE: type = hotTRANSACTION_NODE; break;
default: type = hotUNKNOWN;
}
for (int i = 0; i < packet.objects_size(); ++i)
{
const ripple::TMIndexedObject& obj = packet.objects(i);
if (obj.has_hash() && (obj.hash().size() == (256/8)))
{
uint256 hash;
memcpy(hash.begin(), obj.hash().data(), 256 / 8);
if (theApp->getOPs().isWantedHash(hash, true))
{
std::vector<unsigned char> data(obj.data().begin(), obj.data().end());
if (Serializer::getSHA512Half(data) != hash)
{
cLog(lsWARNING) << "Bad hash in data from peer";
theApp->getOPs().addWantedHash(hash);
punishPeer(LT_BadData);
}
else
theApp->getHashedObjectStore().store(type, seq, data, hash);
}
}
}
}
}