mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -527,14 +527,14 @@ STAmount::operator double() const
|
||||
}
|
||||
|
||||
STAmount operator+(const STAmount& v1, const STAmount& v2)
|
||||
{ // We can check for precision loss here (value%10)!=0
|
||||
// FIXME
|
||||
{
|
||||
if (v1.isZero()) return v2;
|
||||
if (v2.isZero()) return v1;
|
||||
|
||||
v1.throwComparable(v2);
|
||||
if (v1.mIsNative)
|
||||
return STAmount(v1.name, v1.getSNValue() + v2.getSNValue());
|
||||
|
||||
if (v1.isZero()) return v2;
|
||||
if (v2.isZero()) return v1;
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<int64>(v2.mValue);
|
||||
@@ -562,14 +562,12 @@ STAmount operator+(const STAmount& v1, const STAmount& v2)
|
||||
|
||||
STAmount operator-(const STAmount& v1, const STAmount& v2)
|
||||
{
|
||||
if (v2.isZero()) return v1;
|
||||
|
||||
v1.throwComparable(v2);
|
||||
if (v2.mIsNative)
|
||||
return STAmount(v1.name, v1.getSNValue() - v2.getSNValue());
|
||||
|
||||
if (v2.isZero()) return v1;
|
||||
if (v1.isZero() || (v2.mOffset > v1.mOffset) )
|
||||
throw std::runtime_error("value underflow");
|
||||
|
||||
int ov1 = v1.mOffset, ov2 = v2.mOffset;
|
||||
int64 vv1 = static_cast<int64>(v1.mValue), vv2 = static_cast<int64>(v2.mValue);
|
||||
if (v1.mIsNegative) vv1 = -vv1;
|
||||
|
||||
@@ -37,7 +37,7 @@ DatabaseCon::~DatabaseCon()
|
||||
|
||||
Application::Application() :
|
||||
mUNL(mIOService),
|
||||
mNetOps(mIOService, &mMasterLedger), mNodeCache(16384, 600),
|
||||
mNetOps(mIOService, &mMasterLedger), mTempNodeCache(16384, 90), mHashedObjectStore(16384, 300),
|
||||
mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
|
||||
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL)
|
||||
{
|
||||
@@ -51,6 +51,7 @@ extern int TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount, NetNodeDBC
|
||||
void Application::stop()
|
||||
{
|
||||
mIOService.stop();
|
||||
mHashedObjectStore.bulkWrite();
|
||||
|
||||
Log(lsINFO) << "Stopped: " << mIOService.stopped();
|
||||
}
|
||||
|
||||
@@ -46,9 +46,10 @@ class Application
|
||||
LedgerAcquireMaster mMasterLedgerAcquire;
|
||||
TransactionMaster mMasterTransaction;
|
||||
NetworkOPs mNetOps;
|
||||
NodeCache mNodeCache;
|
||||
NodeCache mTempNodeCache;
|
||||
ValidationCollection mValidations;
|
||||
SuppressionTable mSuppressions;
|
||||
HashedObjectStore mHashedObjectStore;
|
||||
|
||||
DatabaseCon *mTxnDB, *mLedgerDB, *mWalletDB, *mHashNodeDB, *mNetNodeDB;
|
||||
|
||||
@@ -79,10 +80,11 @@ public:
|
||||
LedgerMaster& getMasterLedger() { return mMasterLedger; }
|
||||
LedgerAcquireMaster& getMasterLedgerAcquire() { return mMasterLedgerAcquire; }
|
||||
TransactionMaster& getMasterTransaction() { return mMasterTransaction; }
|
||||
NodeCache& getNodeCache() { return mNodeCache; }
|
||||
NodeCache& getTempNodeCache() { return mTempNodeCache; }
|
||||
HashedObjectStore& getHashedObjectStore() { return mHashedObjectStore; }
|
||||
ValidationCollection& getValidations() { return mValidations; }
|
||||
bool suppress(const uint256& s) { return mSuppressions.addSuppression(s); }
|
||||
bool suppress(const uint160& s) { return mSuppressions.addSuppression(s); }
|
||||
bool isNew(const uint256& s) { return mSuppressions.addSuppression(s); }
|
||||
bool isNew(const uint160& s) { return mSuppressions.addSuppression(s); }
|
||||
|
||||
DatabaseCon* getTxnDB() { return mTxnDB; }
|
||||
DatabaseCon* getLedgerDB() { return mLedgerDB; }
|
||||
|
||||
@@ -112,8 +112,6 @@ void Config::setup(const std::string& strConf)
|
||||
// Defaults
|
||||
//
|
||||
|
||||
VERSION = 1;
|
||||
|
||||
NETWORK_START_TIME = 1319844908;
|
||||
|
||||
PEER_PORT = SYSTEM_PEER_PORT;
|
||||
|
||||
@@ -43,10 +43,6 @@ const int SYSTEM_WEBSOCKET_PORT = 6562;
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
// Core software parameters
|
||||
int VERSION;
|
||||
std::string VERSION_STR;
|
||||
|
||||
// Configuration parameters
|
||||
boost::filesystem::path CONFIG_FILE;
|
||||
boost::filesystem::path CONFIG_DIR;
|
||||
|
||||
@@ -7,76 +7,95 @@
|
||||
#include "Application.h"
|
||||
#include "Log.h"
|
||||
|
||||
|
||||
bool HashedObject::checkHash() const
|
||||
HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) :
|
||||
mCache(cacheSize, cacheAge), mWritePending(false)
|
||||
{
|
||||
uint256 hash = Serializer::getSHA512Half(mData);
|
||||
return hash == mHash;
|
||||
mWriteSet.reserve(128);
|
||||
}
|
||||
|
||||
bool HashedObject::checkFixHash()
|
||||
{
|
||||
uint256 hash = Serializer::getSHA512Half(mData);
|
||||
if (hash == mHash) return true;
|
||||
mHash = hash;
|
||||
return false;
|
||||
}
|
||||
|
||||
void HashedObject::setHash()
|
||||
{
|
||||
mHash = Serializer::getSHA512Half(mData);
|
||||
}
|
||||
|
||||
// FIXME: Stores should be added to a queue that's services by an auxilliary thread or from an
|
||||
// auxilliary thread pool. These should be tied into a cache, since you need one to handle
|
||||
// an immedate read back (before the write completes)
|
||||
|
||||
bool HashedObject::store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data,
|
||||
const uint256& hash)
|
||||
{
|
||||
bool HashedObjectStore::store(HashedObjectType type, uint32 index,
|
||||
const std::vector<unsigned char>& data, const uint256& hash)
|
||||
{ // return: false=already in cache, true = added to cache
|
||||
if (!theApp->getHashNodeDB()) return true;
|
||||
#ifdef DEBUG
|
||||
Serializer s(data);
|
||||
assert(hash == s.getSHA512Half());
|
||||
#endif
|
||||
std::string sql = "INSERT INTO CommittedObjects (Hash,ObjType,LedgerIndex,Object) VALUES ('";
|
||||
sql.append(hash.GetHex());
|
||||
switch(type)
|
||||
if (mCache.touch(hash))
|
||||
{
|
||||
case LEDGER: sql.append("','L','"); break;
|
||||
case TRANSACTION: sql.append("','T','"); break;
|
||||
case ACCOUNT_NODE: sql.append("','A','"); break;
|
||||
case TRANSACTION_NODE: sql.append("','N','"); break;
|
||||
default: sql.append("','U','"); break;
|
||||
}
|
||||
sql.append(boost::lexical_cast<std::string>(index));
|
||||
sql.append("',");
|
||||
|
||||
std::string obj;
|
||||
theApp->getHashNodeDB()->getDB()->escape(&(data.front()), data.size(), obj);
|
||||
sql.append(obj);
|
||||
sql.append(");");
|
||||
|
||||
std::string exists =
|
||||
boost::str(boost::format("SELECT ObjType FROM CommittedObject WHERE Hash = '%s';") % hash.GetHex());
|
||||
|
||||
ScopedLock sl(theApp->getHashNodeDB()->getDBLock());
|
||||
Database* db = theApp->getHashNodeDB()->getDB();
|
||||
if (SQL_EXISTS(db, exists))
|
||||
Log(lsTRACE) << "HOS: " << hash.GetHex() << " store: incache";
|
||||
return false;
|
||||
return db->executeSQL(sql);
|
||||
}
|
||||
|
||||
HashedObject::pointer object = boost::make_shared<HashedObject>(type, index, data, hash);
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mWriteMutex);
|
||||
mWriteSet.push_back(object);
|
||||
if (!mWritePending && (mWriteSet.size() >= 64))
|
||||
{
|
||||
mWritePending = true;
|
||||
boost::thread t(boost::bind(&HashedObjectStore::bulkWrite, this));
|
||||
t.detach();
|
||||
}
|
||||
}
|
||||
Log(lsTRACE) << "HOS: " << hash.GetHex() << " store: deferred";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HashedObject::store() const
|
||||
void HashedObjectStore::bulkWrite()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
assert(checkHash());
|
||||
#endif
|
||||
return store(mType, mLedgerIndex, mData, mHash);
|
||||
std::vector< boost::shared_ptr<HashedObject> > set;
|
||||
set.reserve(128);
|
||||
|
||||
{
|
||||
boost::recursive_mutex::scoped_lock sl(mWriteMutex);
|
||||
mWriteSet.swap(set);
|
||||
mWritePending = false;
|
||||
}
|
||||
Log(lsINFO) << "HOS: BulkWrite " << set.size();
|
||||
|
||||
boost::format fExists("SELECT ObjType FROM CommittedObjects WHERE Hash = '%s';");
|
||||
boost::format fAdd("INSERT INTO CommittedObjects (Hash,ObjType,LedgerIndex,Object) VALUES ('%s','%c','%u',%s);");
|
||||
|
||||
Database* db = theApp->getHashNodeDB()->getDB();
|
||||
ScopedLock sl = theApp->getHashNodeDB()->getDBLock();
|
||||
|
||||
db->executeSQL("BEGIN TRANSACTION;");
|
||||
|
||||
for (std::vector< boost::shared_ptr<HashedObject> >::iterator it = set.begin(), end = set.end(); it != end; ++it)
|
||||
{
|
||||
HashedObject& obj = **it;
|
||||
if (!SQL_EXISTS(db, boost::str(fExists % obj.getHash().GetHex())))
|
||||
{
|
||||
char type;
|
||||
switch(obj.getType())
|
||||
{
|
||||
case LEDGER: type = 'L'; break;
|
||||
case TRANSACTION: type = 'T'; break;
|
||||
case ACCOUNT_NODE: type = 'A'; break;
|
||||
case TRANSACTION_NODE: type = 'N'; break;
|
||||
default: type = 'U';
|
||||
}
|
||||
std::string rawData;
|
||||
db->escape(&(obj.getData().front()), obj.getData().size(), rawData);
|
||||
db->executeSQL(boost::str(fAdd % obj.getHash().GetHex() % type % obj.getIndex() % rawData ));
|
||||
}
|
||||
}
|
||||
|
||||
db->executeSQL("END TRANSACTION;");
|
||||
}
|
||||
|
||||
HashedObject::pointer HashedObject::retrieve(const uint256& hash)
|
||||
HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash)
|
||||
{
|
||||
HashedObject::pointer obj;
|
||||
{
|
||||
ScopedLock sl(theApp->getHashNodeDB()->getDBLock());
|
||||
obj = mCache.fetch(hash);
|
||||
if (obj)
|
||||
{
|
||||
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: incache";
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
if (!theApp || !theApp->getHashNodeDB()) return HashedObject::pointer();
|
||||
std::string sql = "SELECT * FROM CommittedObjects WHERE Hash='";
|
||||
sql.append(hash.GetHex());
|
||||
@@ -90,7 +109,10 @@ HashedObject::pointer HashedObject::retrieve(const uint256& hash)
|
||||
Database* db = theApp->getHashNodeDB()->getDB();
|
||||
|
||||
if (!db->executeSQL(sql) || !db->startIterRows())
|
||||
{
|
||||
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: not in db";
|
||||
return HashedObject::pointer();
|
||||
}
|
||||
|
||||
std::string type;
|
||||
db->getStr("ObjType", type);
|
||||
@@ -102,36 +124,24 @@ HashedObject::pointer HashedObject::retrieve(const uint256& hash)
|
||||
data.resize(size);
|
||||
db->getBinary("Object", &(data.front()), size);
|
||||
db->endIterRows();
|
||||
}
|
||||
|
||||
HashedObjectType htype = UNKNOWN;
|
||||
switch(type[0])
|
||||
{
|
||||
case 'L': htype = LEDGER; break;
|
||||
case 'T': htype = TRANSACTION; break;
|
||||
case 'A': htype = ACCOUNT_NODE; break;
|
||||
case 'N': htype = TRANSACTION_NODE; break;
|
||||
default:
|
||||
Log(lsERROR) << "Invalid hashed object";
|
||||
return HashedObject::pointer();
|
||||
}
|
||||
HashedObjectType htype = UNKNOWN;
|
||||
switch(type[0])
|
||||
{
|
||||
case 'L': htype = LEDGER; break;
|
||||
case 'T': htype = TRANSACTION; break;
|
||||
case 'A': htype = ACCOUNT_NODE; break;
|
||||
case 'N': htype = TRANSACTION_NODE; break;
|
||||
default:
|
||||
Log(lsERROR) << "Invalid hashed object";
|
||||
return HashedObject::pointer();
|
||||
}
|
||||
|
||||
HashedObject::pointer obj = boost::make_shared<HashedObject>(htype, index, data);
|
||||
obj->mHash = hash;
|
||||
#ifdef DEBUG
|
||||
assert(obj->checkHash());
|
||||
#endif
|
||||
obj = boost::make_shared<HashedObject>(htype, index, data, hash);
|
||||
mCache.canonicalize(hash, obj);
|
||||
}
|
||||
Log(lsTRACE) << "HOS: " << hash.GetHex() << " fetch: in db";
|
||||
return obj;
|
||||
}
|
||||
|
||||
HashedObjectBulkWriter::HashedObjectBulkWriter() : sl(theApp->getHashNodeDB()->getDBLock())
|
||||
{
|
||||
theApp->getHashNodeDB()->getDB()->executeSQL("BEGIN TRANSACTION;");
|
||||
}
|
||||
|
||||
HashedObjectBulkWriter::~HashedObjectBulkWriter()
|
||||
{
|
||||
theApp->getHashNodeDB()->getDB()->executeSQL("END TRANSACTION;");
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "types.h"
|
||||
#include "uint256.h"
|
||||
#include "ScopedLock.h"
|
||||
#include "TaggedCache.h"
|
||||
|
||||
enum HashedObjectType
|
||||
{
|
||||
@@ -26,37 +27,34 @@ public:
|
||||
uint32 mLedgerIndex;
|
||||
std::vector<unsigned char> mData;
|
||||
|
||||
HashedObject(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data) :
|
||||
mType(type), mLedgerIndex(index), mData(data) { ; }
|
||||
HashedObject(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data, const uint256& hash) :
|
||||
mType(type), mHash(hash), mLedgerIndex(index), mData(data) { ; }
|
||||
|
||||
bool checkHash() const;
|
||||
bool checkFixHash();
|
||||
void setHash();
|
||||
|
||||
const std::vector<unsigned char>& getData() { return mData; }
|
||||
|
||||
bool store() const;
|
||||
|
||||
static bool store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data,
|
||||
const uint256& hash);
|
||||
|
||||
static HashedObject::pointer retrieve(const uint256& hash);
|
||||
const std::vector<unsigned char>& getData() { return mData; }
|
||||
const uint256& getHash() { return mHash; }
|
||||
HashedObjectType getType() { return mType; }
|
||||
uint32 getIndex() { return mLedgerIndex; }
|
||||
};
|
||||
|
||||
class HashedObjectBulkWriter
|
||||
class HashedObjectStore
|
||||
{
|
||||
protected:
|
||||
ScopedLock sl;
|
||||
TaggedCache<uint256, HashedObject> mCache;
|
||||
|
||||
boost::recursive_mutex mWriteMutex;
|
||||
std::vector< boost::shared_ptr<HashedObject> > mWriteSet;
|
||||
bool mWritePending;
|
||||
|
||||
public:
|
||||
|
||||
HashedObjectBulkWriter();
|
||||
~HashedObjectBulkWriter();
|
||||
HashedObjectStore(int cacheSize, int cacheAge);
|
||||
|
||||
bool store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data, const uint256& hash)
|
||||
{ return HashedObject::store(type, index, data, hash); }
|
||||
HashedObject::pointer retrieve(const uint256& hash)
|
||||
{ return HashedObject::retrieve(hash); }
|
||||
bool store(HashedObjectType type, uint32 index, const std::vector<unsigned char>& data,
|
||||
const uint256& hash);
|
||||
|
||||
HashedObject::pointer retrieve(const uint256& hash);
|
||||
|
||||
void bulkWrite();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#include "../json/writer.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "Ledger.h"
|
||||
#include "utils.h"
|
||||
@@ -350,6 +352,11 @@ Ledger::pointer Ledger::getSQL(const std::string& sql)
|
||||
boost::make_shared<Ledger>(prevHash, transHash, accountHash, totCoins, closingTime, ledgerSeq);
|
||||
if (ret->getHash() != ledgerHash)
|
||||
{
|
||||
Json::StyledStreamWriter ssw;
|
||||
Log(lsERROR) << "Failed on ledger";
|
||||
Json::Value p;
|
||||
ret->addJson(p, LEDGER_JSON_FULL);
|
||||
ssw.write(Log(lsERROR).ref(), p);
|
||||
assert(false);
|
||||
return Ledger::pointer();
|
||||
}
|
||||
@@ -379,7 +386,8 @@ void Ledger::addJson(Json::Value& ret, int options)
|
||||
boost::recursive_mutex::scoped_lock sl(mLock);
|
||||
ledger["parentHash"] = mParentHash.GetHex();
|
||||
|
||||
if(mClosed)
|
||||
bool full = (options & LEDGER_JSON_FULL) != 0;
|
||||
if(mClosed || full)
|
||||
{
|
||||
ledger["hash"] = mHash.GetHex();
|
||||
ledger["transactionHash"] = mTransHash.GetHex();
|
||||
@@ -391,8 +399,7 @@ void Ledger::addJson(Json::Value& ret, int options)
|
||||
else ledger["closed"] = false;
|
||||
if (mCloseTime != 0)
|
||||
ledger["closeTime"] = boost::posix_time::to_simple_string(ptFromSeconds(mCloseTime));
|
||||
bool full = (options & LEDGER_JSON_FULL) != 0;
|
||||
if (full || ((options & LEDGER_JSON_DUMP_TXNS) != 0))
|
||||
if (mTransactionMap && (full || ((options & LEDGER_JSON_DUMP_TXNS) != 0)))
|
||||
{
|
||||
Json::Value txns(Json::arrayValue);
|
||||
for (SHAMapItem::pointer item = mTransactionMap->peekFirstItem(); !!item;
|
||||
@@ -408,7 +415,7 @@ void Ledger::addJson(Json::Value& ret, int options)
|
||||
}
|
||||
ledger["transactions"] = txns;
|
||||
}
|
||||
if (full || ((options & LEDGER_JSON_DUMP_STATE) != 0))
|
||||
if (mAccountStateMap && (full || ((options & LEDGER_JSON_DUMP_STATE) != 0)))
|
||||
{
|
||||
Json::Value state(Json::arrayValue);
|
||||
for (SHAMapItem::pointer item = mAccountStateMap->peekFirstItem(); !!item;
|
||||
|
||||
@@ -7,12 +7,13 @@
|
||||
|
||||
#include "Application.h"
|
||||
#include "Log.h"
|
||||
#include "SHAMapSync.h"
|
||||
|
||||
#define LA_DEBUG
|
||||
#define LEDGER_ACQUIRE_TIMEOUT 2
|
||||
|
||||
PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval),
|
||||
mComplete(false), mFailed(false), mTimer(theApp->getIOService())
|
||||
PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval), mTimeouts(0),
|
||||
mComplete(false), mFailed(false), mProgress(true), mTimer(theApp->getIOService())
|
||||
{ ; }
|
||||
|
||||
void PeerSet::peerHas(Peer::pointer ptr)
|
||||
@@ -61,15 +62,28 @@ void PeerSet::resetTimer()
|
||||
mTimer.async_wait(boost::bind(&PeerSet::TimerEntry, pmDowncast(), boost::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void PeerSet::invokeOnTimer()
|
||||
{
|
||||
if (!mProgress)
|
||||
{
|
||||
++mTimeouts;
|
||||
Log(lsWARNING) << "Timeout " << mTimeouts << " acquiring " << mHash.GetHex();
|
||||
}
|
||||
else
|
||||
mProgress = false;
|
||||
onTimer();
|
||||
}
|
||||
|
||||
void PeerSet::TimerEntry(boost::weak_ptr<PeerSet> wptr, const boost::system::error_code& result)
|
||||
{
|
||||
if (result == boost::asio::error::operation_aborted) return;
|
||||
boost::shared_ptr<PeerSet> ptr = wptr.lock();
|
||||
if (!!ptr) ptr->onTimer();
|
||||
if (!ptr) return;
|
||||
ptr->invokeOnTimer();
|
||||
}
|
||||
|
||||
LedgerAcquire::LedgerAcquire(const uint256& hash) : PeerSet(hash, LEDGER_ACQUIRE_TIMEOUT),
|
||||
mFilter(&theApp->getNodeCache()), mHaveBase(false), mHaveState(false), mHaveTransactions(false)
|
||||
mHaveBase(false), mHaveState(false), mHaveTransactions(false)
|
||||
{
|
||||
#ifdef LA_DEBUG
|
||||
Log(lsTRACE) << "Acquiring ledger " << mHash.GetHex();
|
||||
@@ -155,7 +169,8 @@ void LedgerAcquire::trigger(Peer::pointer peer)
|
||||
{
|
||||
std::vector<SHAMapNode> nodeIDs;
|
||||
std::vector<uint256> nodeHashes;
|
||||
mLedger->peekTransactionMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &mFilter);
|
||||
TransactionStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
mLedger->peekTransactionMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &tFilter);
|
||||
if (nodeIDs.empty())
|
||||
{
|
||||
if (!mLedger->peekTransactionMap()->isValid()) mFailed = true;
|
||||
@@ -207,7 +222,8 @@ void LedgerAcquire::trigger(Peer::pointer peer)
|
||||
{
|
||||
std::vector<SHAMapNode> nodeIDs;
|
||||
std::vector<uint256> nodeHashes;
|
||||
mLedger->peekAccountStateMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &mFilter);
|
||||
AccountStateSF aFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
mLedger->peekAccountStateMap()->getMissingNodes(nodeIDs, nodeHashes, 128, &aFilter);
|
||||
if (nodeIDs.empty())
|
||||
{
|
||||
if (!mLedger->peekAccountStateMap()->isValid()) mFailed = true;
|
||||
@@ -284,6 +300,8 @@ bool LedgerAcquire::takeBase(const std::string& data, Peer::pointer peer)
|
||||
return false;
|
||||
}
|
||||
mHaveBase = true;
|
||||
theApp->getHashedObjectStore().store(LEDGER, mLedger->getLedgerSeq(), strCopy(data), mHash);
|
||||
progress();
|
||||
if (!mLedger->getTransHash()) mHaveTransactions = true;
|
||||
if (!mLedger->getAccountHash()) mHaveState = true;
|
||||
mLedger->setAcquiring();
|
||||
@@ -297,6 +315,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (!mHaveBase) return false;
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
TransactionStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
while (nodeIDit != nodeIDs.end())
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
@@ -304,7 +323,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait))
|
||||
return false;
|
||||
}
|
||||
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
|
||||
else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
|
||||
return false;
|
||||
++nodeIDit;
|
||||
++nodeDatait;
|
||||
@@ -315,6 +334,7 @@ bool LedgerAcquire::takeTxNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (mHaveState) mComplete = true;
|
||||
}
|
||||
trigger(peer);
|
||||
progress();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -327,6 +347,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (!mHaveBase) return false;
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
AccountStateSF tFilter(mLedger->getHash(), mLedger->getLedgerSeq());
|
||||
while (nodeIDit != nodeIDs.end())
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
@@ -334,7 +355,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), *nodeDatait))
|
||||
return false;
|
||||
}
|
||||
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
|
||||
else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter))
|
||||
return false;
|
||||
++nodeIDit;
|
||||
++nodeDatait;
|
||||
@@ -345,6 +366,7 @@ bool LedgerAcquire::takeAsNode(const std::list<SHAMapNode>& nodeIDs,
|
||||
if (mHaveTransactions) mComplete = true;
|
||||
}
|
||||
trigger(peer);
|
||||
progress();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ class PeerSet
|
||||
{
|
||||
protected:
|
||||
uint256 mHash;
|
||||
int mTimerInterval;
|
||||
bool mComplete, mFailed;
|
||||
int mTimerInterval, mTimeouts;
|
||||
bool mComplete, mFailed, mProgress;
|
||||
|
||||
boost::recursive_mutex mLock;
|
||||
boost::asio::deadline_timer mTimer;
|
||||
@@ -37,6 +37,9 @@ public:
|
||||
const uint256& getHash() const { return mHash; }
|
||||
bool isComplete() const { return mComplete; }
|
||||
bool isFailed() const { return mFailed; }
|
||||
int getTimeouts() const { return mTimeouts; }
|
||||
|
||||
void progress() { mProgress = true; }
|
||||
|
||||
void peerHas(Peer::pointer);
|
||||
void badPeer(Peer::pointer);
|
||||
@@ -49,36 +52,12 @@ protected:
|
||||
|
||||
void setComplete() { mComplete = true; }
|
||||
void setFailed() { mFailed = true; }
|
||||
void invokeOnTimer();
|
||||
|
||||
private:
|
||||
static void TimerEntry(boost::weak_ptr<PeerSet>, const boost::system::error_code& result);
|
||||
};
|
||||
|
||||
typedef TaggedCache< uint256, std::vector<unsigned char> > NodeCache;
|
||||
typedef std::vector<unsigned char> VUC;
|
||||
|
||||
class THSyncFilter : public SHAMapSyncFilter
|
||||
{
|
||||
protected:
|
||||
NodeCache* mCache; // holds nodes we see during the consensus process
|
||||
|
||||
public:
|
||||
THSyncFilter(NodeCache* cache) : mCache(cache) { ; }
|
||||
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
|
||||
const std::vector<unsigned char>& nodeData, bool)
|
||||
{
|
||||
boost::shared_ptr<VUC> ptr = boost::make_shared<VUC>(nodeData);
|
||||
mCache->canonicalize(nodeHash, ptr);
|
||||
}
|
||||
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
|
||||
{
|
||||
boost::shared_ptr<VUC> entry = mCache->fetch(nodeHash);
|
||||
if (!entry) return false;
|
||||
nodeData = *entry;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LedgerAcquire : public PeerSet, public boost::enable_shared_from_this<LedgerAcquire>
|
||||
{ // A ledger we are trying to acquire
|
||||
public:
|
||||
@@ -86,7 +65,6 @@ public:
|
||||
|
||||
protected:
|
||||
Ledger::pointer mLedger;
|
||||
THSyncFilter mFilter;
|
||||
bool mHaveBase, mHaveState, mHaveTransactions;
|
||||
|
||||
std::vector< boost::function<void (LedgerAcquire::pointer)> > mOnComplete;
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
#include "LedgerTiming.h"
|
||||
#include "SerializedValidation.h"
|
||||
#include "Log.h"
|
||||
#include "SHAMapSync.h"
|
||||
|
||||
#define TRUST_NETWORK
|
||||
|
||||
// #define LC_DEBUG
|
||||
|
||||
TransactionAcquire::TransactionAcquire(const uint256& hash)
|
||||
: PeerSet(hash, 1), mFilter(&theApp->getNodeCache()), mHaveRoot(false)
|
||||
TransactionAcquire::TransactionAcquire(const uint256& hash) : PeerSet(hash, 1), mHaveRoot(false)
|
||||
{
|
||||
mMap = boost::make_shared<SHAMap>();
|
||||
mMap->setSynching();
|
||||
@@ -50,9 +50,9 @@ void TransactionAcquire::trigger(Peer::pointer peer)
|
||||
}
|
||||
if (mHaveRoot)
|
||||
{
|
||||
std::vector<SHAMapNode> nodeIDs;
|
||||
std::vector<uint256> nodeHashes;
|
||||
mMap->getMissingNodes(nodeIDs, nodeHashes, 256, &mFilter);
|
||||
std::vector<SHAMapNode> nodeIDs; std::vector<uint256> nodeHashes;
|
||||
ConsensusTransSetSF sf;
|
||||
mMap->getMissingNodes(nodeIDs, nodeHashes, 256, &sf);
|
||||
if (nodeIDs.empty())
|
||||
{
|
||||
if (mMap->isValid())
|
||||
@@ -91,6 +91,7 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
{
|
||||
std::list<SHAMapNode>::const_iterator nodeIDit = nodeIDs.begin();
|
||||
std::list< std::vector<unsigned char> >::const_iterator nodeDatait = data.begin();
|
||||
ConsensusTransSetSF sf;
|
||||
while (nodeIDit != nodeIDs.end())
|
||||
{
|
||||
if (nodeIDit->isRoot())
|
||||
@@ -104,12 +105,13 @@ bool TransactionAcquire::takeNodes(const std::list<SHAMapNode>& nodeIDs,
|
||||
return false;
|
||||
else mHaveRoot = true;
|
||||
}
|
||||
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait, &mFilter))
|
||||
else if (!mMap->addKnownNode(*nodeIDit, *nodeDatait, &sf))
|
||||
return false;
|
||||
++nodeIDit;
|
||||
++nodeDatait;
|
||||
}
|
||||
trigger(peer);
|
||||
progress();
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
@@ -426,7 +428,6 @@ int LedgerConsensus::timerEntry()
|
||||
theApp->getOPs().switchLastClosedLedger(consensus);
|
||||
mPreviousLedger = consensus;
|
||||
mHaveCorrectLCL = true;
|
||||
// FIXME: We need some kind of idea what the consensus transaction set is
|
||||
}
|
||||
}
|
||||
|
||||
@@ -589,10 +590,7 @@ bool LedgerConsensus::peerPosition(LedgerProposal::pointer newPosition)
|
||||
{
|
||||
assert(newPosition->getPeerID() == currentPosition->getPeerID());
|
||||
if (newPosition->getProposeSeq() <= currentPosition->getProposeSeq())
|
||||
{
|
||||
Log(lsINFO) << "Redundant/stale positon";
|
||||
return false;
|
||||
}
|
||||
if (newPosition->getCurrentHash() == currentPosition->getCurrentHash())
|
||||
{ // we missed an intermediary change
|
||||
Log(lsINFO) << "We missed an intermediary position";
|
||||
@@ -672,7 +670,7 @@ void LedgerConsensus::applyTransaction(TransactionEngine& engine, SerializedTran
|
||||
if (result > 0)
|
||||
{
|
||||
Log(lsINFO) << " retry";
|
||||
// assert(!ledger->hasTransaction(txn->getTransactionID())); FIXME: We get these (doPasswordSet)
|
||||
assert(!ledger->hasTransaction(txn->getTransactionID()));
|
||||
failedTransactions.push_back(txn);
|
||||
}
|
||||
else if (result == 0)
|
||||
@@ -757,17 +755,6 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
Ledger::pointer newLCL = boost::make_shared<Ledger>(false, boost::ref(*mPreviousLedger));
|
||||
newLCL->armDirty();
|
||||
|
||||
#ifdef DEBUG
|
||||
Json::StyledStreamWriter ssw;
|
||||
if (1)
|
||||
{
|
||||
Log(lsTRACE) << "newLCL before transactions";
|
||||
Json::Value p;
|
||||
newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
}
|
||||
#endif
|
||||
|
||||
CanonicalTXSet failedTransactions(set->getHash());
|
||||
applyTransactions(set, newLCL, failedTransactions, true);
|
||||
newLCL->setClosed();
|
||||
@@ -775,27 +762,23 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
newLCL->updateHash();
|
||||
uint256 newLCLHash = newLCL->getHash();
|
||||
Log(lsTRACE) << "newLCL " << newLCLHash.GetHex();
|
||||
|
||||
statusChange(newcoin::neACCEPTED_LEDGER, newLCL);
|
||||
if (mValidating)
|
||||
{
|
||||
assert (theApp->getOPs().getNetworkTimeNC() > newLCL->getCloseTimeNC());
|
||||
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
|
||||
(newLCLHash, newLCL->getCloseTimeNC(), mValSeed, mProposing);
|
||||
v->setTrusted();
|
||||
theApp->getValidations().addValidation(v);
|
||||
std::vector<unsigned char> validation = v->getSigned();
|
||||
newcoin::TMValidation val;
|
||||
val.set_validation(&validation[0], validation.size());
|
||||
theApp->getConnectionPool().relayMessage(NULL, boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
|
||||
Log(lsINFO) << "Validation sent " << newLCLHash.GetHex();
|
||||
}
|
||||
else Log(lsWARNING) << "Not validating";
|
||||
|
||||
Ledger::pointer newOL = boost::make_shared<Ledger>(true, boost::ref(*newLCL));
|
||||
|
||||
#ifdef DEBUG
|
||||
if (1)
|
||||
{
|
||||
Log(lsTRACE) << "newOL before transactions";
|
||||
Json::Value p;
|
||||
newOL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
}
|
||||
if (1)
|
||||
{
|
||||
Log(lsTRACE) << "current ledger";
|
||||
Json::Value p;
|
||||
theApp->getMasterLedger().getCurrentLedger()->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
}
|
||||
#endif
|
||||
|
||||
ScopedLock sl = theApp->getMasterLedger().getLock();
|
||||
|
||||
// Apply disputed transactions that didn't get in
|
||||
@@ -825,35 +808,15 @@ void LedgerConsensus::accept(SHAMap::pointer set)
|
||||
sl.unlock();
|
||||
|
||||
#ifdef DEBUG
|
||||
Json::StyledStreamWriter ssw;
|
||||
if (1)
|
||||
{
|
||||
Log(lsTRACE) << "newOL after current ledger transactions";
|
||||
Log(lsTRACE) << "newLCL";
|
||||
Json::Value p;
|
||||
newOL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
newLCL->addJson(p, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p);
|
||||
Log(lsINFO) << "newLCL after transactions";
|
||||
Json::Value p2;
|
||||
newLCL->addJson(p2, LEDGER_JSON_DUMP_TXNS | LEDGER_JSON_DUMP_STATE);
|
||||
ssw.write(Log(lsTRACE).ref(), p2);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mValidating)
|
||||
{
|
||||
assert (theApp->getOPs().getNetworkTimeNC() > newLCL->getCloseTimeNC());
|
||||
SerializedValidation::pointer v = boost::make_shared<SerializedValidation>
|
||||
(newLCLHash, newLCL->getCloseTimeNC(), mOurPosition->peekSeed(), true);
|
||||
v->setTrusted();
|
||||
// FIXME: If not proposing, set not full
|
||||
theApp->getValidations().addValidation(v);
|
||||
std::vector<unsigned char> validation = v->getSigned();
|
||||
newcoin::TMValidation val;
|
||||
val.set_validation(&validation[0], validation.size());
|
||||
theApp->getConnectionPool().relayMessage(NULL, boost::make_shared<PackedMessage>(val, newcoin::mtVALIDATION));
|
||||
Log(lsINFO) << "Validation sent " << newLCLHash.GetHex();
|
||||
}
|
||||
else Log(lsWARNING) << "Not validating";
|
||||
statusChange(newcoin::neACCEPTED_LEDGER, newLCL);
|
||||
// FIXME: If necessary, change state to TRACKING/FULL
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ public:
|
||||
|
||||
protected:
|
||||
SHAMap::pointer mMap;
|
||||
THSyncFilter mFilter; // FIXME: Should use transaction master too
|
||||
bool mHaveRoot;
|
||||
|
||||
void onTimer() { trigger(Peer::pointer()); }
|
||||
|
||||
@@ -60,6 +60,14 @@ Ledger::pointer LedgerHistory::getLedgerByHash(const uint256& hash)
|
||||
Ledger::pointer ret = mLedgersByHash.fetch(hash);
|
||||
if (ret) return ret;
|
||||
|
||||
#if 0
|
||||
// FIXME: A ledger without SHA maps isn't very useful
|
||||
// This code will need to build them
|
||||
|
||||
// The fix is to audit all callers to this function and replace them with
|
||||
// higher-level functions that ask more-specific questions that we can
|
||||
// test against our database
|
||||
|
||||
ret = Ledger::loadByHash(hash);
|
||||
if (!ret) return ret;
|
||||
assert(ret->getHash() == hash);
|
||||
@@ -67,6 +75,8 @@ Ledger::pointer LedgerHistory::getLedgerByHash(const uint256& hash)
|
||||
boost::recursive_mutex::scoped_lock sl(mLedgersByHash.peekMutex());
|
||||
mLedgersByHash.canonicalize(hash, ret);
|
||||
if (ret->isAccepted()) mLedgersByIndex[ret->getLedgerSeq()] = ret;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ LedgerProposal::LedgerProposal(const uint256& pLgr, uint32 seq, const uint256& t
|
||||
LedgerProposal::LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLgr, const uint256& position) :
|
||||
mPreviousLedger(prevLgr), mCurrentHash(position), mProposeSeq(0)
|
||||
{
|
||||
mSeed = naSeed;
|
||||
mPublicKey = NewcoinAddress::createNodePublic(naSeed);
|
||||
mPrivateKey = NewcoinAddress::createNodePrivate(naSeed);
|
||||
mPeerID = mPublicKey.getNodeID();
|
||||
@@ -46,9 +45,9 @@ uint256 LedgerProposal::getSigningHash() const
|
||||
return s.getSHA512Half();
|
||||
}
|
||||
|
||||
bool LedgerProposal::checkSign(const std::string& signature)
|
||||
bool LedgerProposal::checkSign(const std::string& signature, const uint256& signingHash)
|
||||
{
|
||||
return mPublicKey.verifyNodePublic(getSigningHash(), signature);
|
||||
return mPublicKey.verifyNodePublic(signingHash, signature);
|
||||
}
|
||||
|
||||
void LedgerProposal::changePosition(const uint256& newPosition)
|
||||
|
||||
@@ -16,9 +16,8 @@ protected:
|
||||
uint32 mProposeSeq;
|
||||
|
||||
uint160 mPeerID;
|
||||
NewcoinAddress mPublicKey; // Peer
|
||||
NewcoinAddress mPrivateKey; // Our's
|
||||
NewcoinAddress mSeed; // Our's
|
||||
NewcoinAddress mPublicKey;
|
||||
NewcoinAddress mPrivateKey; // If ours
|
||||
|
||||
static const uint32 sProposeMagic = 0x50525000; // PRP
|
||||
|
||||
@@ -27,22 +26,24 @@ public:
|
||||
typedef boost::shared_ptr<LedgerProposal> pointer;
|
||||
|
||||
// proposal from peer
|
||||
LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose, const NewcoinAddress& naPeerPublic);
|
||||
LedgerProposal(const uint256& prevLgr, uint32 proposeSeq, const uint256& propose,
|
||||
const NewcoinAddress& naPeerPublic);
|
||||
|
||||
// our first proposal
|
||||
LedgerProposal(const NewcoinAddress& naSeed, const uint256& prevLedger, const uint256& position);
|
||||
LedgerProposal(const NewcoinAddress& privKey, const uint256& prevLedger, const uint256& position);
|
||||
|
||||
// an unsigned proposal
|
||||
LedgerProposal(const uint256& prevLedger, const uint256& position);
|
||||
|
||||
uint256 getSigningHash() const;
|
||||
bool checkSign(const std::string& signature);
|
||||
bool checkSign(const std::string& signature, const uint256& signingHash);
|
||||
bool checkSign(const std::string& signature) { return checkSign(signature, getSigningHash()); }
|
||||
|
||||
const uint160& getPeerID() const { return mPeerID; }
|
||||
const uint256& getCurrentHash() const { return mCurrentHash; }
|
||||
const uint256& getPrevLedger() const { return mPreviousLedger; }
|
||||
uint32 getProposeSeq() const { return mProposeSeq; }
|
||||
const NewcoinAddress& peekSeed() const { return mSeed; }
|
||||
const NewcoinAddress& peekPublic() const { return mPublicKey; }
|
||||
std::vector<unsigned char> getPubKey() const { return mPublicKey.getNodePublic(); }
|
||||
std::vector<unsigned char> sign();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# define LEDGER_CONVERGE 14
|
||||
|
||||
// Maximum converge time
|
||||
# define LEDGER_MAX_CONVERGE 22
|
||||
# define LEDGER_MAX_CONVERGE 20
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -98,7 +98,7 @@ Transaction::pointer NetworkOPs::processTransaction(Transaction::pointer trans,
|
||||
}
|
||||
|
||||
Log(lsDEBUG) << "Status other than success " << r ;
|
||||
if ((mMode != omFULL) && (theApp->suppress(trans->getID())))
|
||||
if ((mMode != omFULL) && (mMode != omTRACKING) && (theApp->isNew(trans->getID())))
|
||||
{
|
||||
newcoin::TMTransaction tx;
|
||||
Serializer s;
|
||||
@@ -432,26 +432,26 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector<Peer::pointer>& peerLis
|
||||
}
|
||||
if (!acq->isComplete())
|
||||
{ // add more peers
|
||||
//JED: seems like you need to do something here so it knows in beginConsensus that it isn't on the the right ledger
|
||||
// switch to an empty ledger so we won't keep going
|
||||
//Ledger::pointer emptyLedger(new Ledger());
|
||||
//switchLastClosedLedger(emptyLedger);
|
||||
|
||||
// JED: just ask everyone
|
||||
int count = 0;
|
||||
std::vector<Peer::pointer> peers=theApp->getConnectionPool().getPeerVector();
|
||||
for(int n=0; n<peers.size(); n++)
|
||||
{
|
||||
if(peers[n]->isConnected()) acq->peerHas(peers[n]);
|
||||
}
|
||||
|
||||
/* JED this wasn't adding any peers. This is also an optimization so we can do this later
|
||||
// FIXME: A peer may not have a ledger just because it accepts it as the network's consensus
|
||||
for (std::vector<Peer::pointer>::const_iterator it = peerList.begin(), end = peerList.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
if ((*it)->getClosedLedgerHash() == closedLedger)
|
||||
{
|
||||
++count;
|
||||
acq->peerHas(*it);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
if (!count)
|
||||
{ // just ask everyone
|
||||
for (std::vector<Peer::pointer>::const_iterator it = peerList.begin(), end = peerList.end();
|
||||
it != end; ++it)
|
||||
{
|
||||
if ((*it)->isConnected())
|
||||
acq->peerHas(*it);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
consensus = acq->getLedger();
|
||||
@@ -521,20 +521,28 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash,
|
||||
|
||||
// XXX Validate key.
|
||||
// XXX Take a vuc for pubkey.
|
||||
NewcoinAddress naPeerPublic = NewcoinAddress::createNodePublic(strCopy(pubKey));
|
||||
|
||||
if (mMode != omFULL)
|
||||
// Get a preliminary hash to use to suppress duplicates
|
||||
Serializer s;
|
||||
s.add32(proposeSeq);
|
||||
s.add32(getCurrentLedgerID());
|
||||
s.addRaw(pubKey);
|
||||
if (!theApp->isNew(s.getSHA512Half()))
|
||||
return false;
|
||||
|
||||
if ((mMode != omFULL) && (mMode != omTRACKING))
|
||||
{
|
||||
Log(lsINFO) << "Received proposal when not full: " << mMode;
|
||||
Serializer s(signature);
|
||||
return theApp->suppress(s.getSHA512Half());
|
||||
Log(lsINFO) << "Received proposal when not full/tracking: " << mMode;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!mConsensus)
|
||||
{
|
||||
Log(lsWARNING) << "Received proposal when full but not during consensus window";
|
||||
return false;
|
||||
}
|
||||
|
||||
NewcoinAddress naPeerPublic = NewcoinAddress::createNodePublic(strCopy(pubKey));
|
||||
LedgerProposal::pointer proposal =
|
||||
boost::make_shared<LedgerProposal>(mConsensus->getLCL(), proposeSeq, proposeHash, naPeerPublic);
|
||||
if (!proposal->checkSign(signature))
|
||||
@@ -545,15 +553,14 @@ bool NetworkOPs::recvPropose(uint32 proposeSeq, const uint256& proposeHash,
|
||||
|
||||
// Is this node on our UNL?
|
||||
// XXX Is this right?
|
||||
if (!theApp->getUNL().nodeInUNL(naPeerPublic))
|
||||
if (!theApp->getUNL().nodeInUNL(proposal->peekPublic()))
|
||||
{
|
||||
Log(lsINFO) << "Relay, but no process peer proposal " << proposal->getProposeSeq() << "/"
|
||||
<< proposal->getCurrentHash().GetHex();
|
||||
Log(lsINFO) << "Untrusted proposal: " << naPeerPublic.humanNodePublic() << " " <<
|
||||
proposal->getCurrentHash().GetHex();
|
||||
return true;
|
||||
}
|
||||
|
||||
return mConsensus->peerPosition(proposal);
|
||||
|
||||
}
|
||||
|
||||
SHAMap::pointer NetworkOPs::getTXMap(const uint256& hash)
|
||||
@@ -640,7 +647,6 @@ std::vector< std::pair<uint32, uint256> >
|
||||
bool NetworkOPs::recvValidation(SerializedValidation::pointer val)
|
||||
{
|
||||
Log(lsINFO) << "recvValidation " << val->getLedgerHash().GetHex();
|
||||
|
||||
return theApp->getValidations().addValidation(val);
|
||||
}
|
||||
|
||||
|
||||
73
src/Peer.cpp
73
src/Peer.cpp
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "../json/writer.h"
|
||||
|
||||
#include "Version.h"
|
||||
#include "Peer.h"
|
||||
#include "Config.h"
|
||||
#include "Application.h"
|
||||
@@ -565,15 +566,20 @@ void Peer::processReadBuffer()
|
||||
|
||||
void Peer::recvHello(newcoin::TMHello& packet)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Log(lsINFO) << "Recv(Hello) v=" << packet.version() << ", index=" << packet.ledgerindex();
|
||||
#endif
|
||||
Log(lsTRACE) << "Recv(Hello) v=" << packet.versionmajor() << "." << packet.versionminor();
|
||||
bool bDetach = true;
|
||||
|
||||
// Cancel verification timeout.
|
||||
(void) mVerifyTimer.cancel();
|
||||
|
||||
if (!mNodePublic.setNodePublic(packet.nodepublic()))
|
||||
if ((packet.minprotoversionmajor() > PROTO_VERSION_MAJ) ||
|
||||
((packet.minprotoversionmajor() == PROTO_VERSION_MAJ) && (packet.minprotoversionminor() > PROTO_VERSION_MIN)))
|
||||
{
|
||||
Log(lsINFO) << "Recv(Hello): Server requires protocol version " <<
|
||||
packet.minprotoversionmajor() << "." << packet.minprotoversionminor() << " we run " <<
|
||||
PROTO_VERSION_MAJ << "." << PROTO_VERSION_MIN;
|
||||
}
|
||||
else if (!mNodePublic.setNodePublic(packet.nodepublic()))
|
||||
{
|
||||
Log(lsINFO) << "Recv(Hello): Disconnect: Bad node public key.";
|
||||
}
|
||||
@@ -584,6 +590,15 @@ void Peer::recvHello(newcoin::TMHello& packet)
|
||||
else
|
||||
{ // Successful connection.
|
||||
Log(lsINFO) << "Recv(Hello): Connect: " << mNodePublic.humanNodePublic();
|
||||
mHello = packet;
|
||||
|
||||
if ( (packet.versionmajor() != SERVER_VERSION_MAJ) || (packet.versionminor() != SERVER_VERSION_MIN))
|
||||
{
|
||||
if (packet.has_fullversion())
|
||||
Log(lsINFO) << " Peer is running version " << packet.fullversion();
|
||||
else
|
||||
Log(lsINFO) << " Peer is running version " << packet.versionmajor() << "." << packet.versionminor();
|
||||
}
|
||||
|
||||
if (mClientConnect)
|
||||
{
|
||||
@@ -730,16 +745,23 @@ void Peer::recvValidation(newcoin::TMValidation& packet)
|
||||
punishPeer(PP_UNKNOWN_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Serializer s(packet.validation());
|
||||
SerializerIterator sit(s);
|
||||
SerializedValidation::pointer val = boost::make_shared<SerializedValidation>(boost::ref(sit));
|
||||
if (!val->isValid())
|
||||
SerializedValidation::pointer val = boost::make_shared<SerializedValidation>(boost::ref(sit), false);
|
||||
|
||||
uint256 signingHash = val->getSigningHash();
|
||||
if (!theApp->isNew(signingHash))
|
||||
return;
|
||||
|
||||
if (!val->isValid(signingHash))
|
||||
{
|
||||
punishPeer(PP_UNKNOWN_REQUEST);
|
||||
return;
|
||||
}
|
||||
|
||||
if (theApp->getOPs().recvValidation(val))
|
||||
{
|
||||
PackedMessage::pointer message = boost::make_shared<PackedMessage>(packet, newcoin::mtVALIDATION);
|
||||
@@ -852,7 +874,7 @@ void Peer::recvAccount(newcoin::TMAccount& packet)
|
||||
|
||||
void Peer::recvStatus(newcoin::TMStatusChange& packet)
|
||||
{
|
||||
Log(lsTRACE) << "Received status change from peer" << getIP();
|
||||
Log(lsTRACE) << "Received status change from peer " << getIP();
|
||||
if (!packet.has_networktime())
|
||||
packet.set_networktime(theApp->getOPs().getNetworkTimeNC());
|
||||
mLastStatus = packet;
|
||||
@@ -1097,16 +1119,20 @@ void Peer::sendHello()
|
||||
|
||||
newcoin::TMHello h;
|
||||
|
||||
h.set_version(theConfig.VERSION);
|
||||
h.set_ledgerindex(theApp->getOPs().getCurrentLedgerID());
|
||||
h.set_versionmajor(SERVER_VERSION_MAJ);
|
||||
h.set_versionminor(SERVER_VERSION_MIN);
|
||||
h.set_protoversionmajor(PROTO_VERSION_MAJ);
|
||||
h.set_protoversionminor(PROTO_VERSION_MIN);
|
||||
h.set_minprotoversionminor(MIN_PROTO_MAJ);
|
||||
h.set_minprotoversionmajor(MIN_PROTO_MIN);
|
||||
h.set_fullversion(SERVER_VERSION);
|
||||
h.set_nettime(theApp->getOPs().getNetworkTimeNC());
|
||||
h.set_nodepublic(theApp->getWallet().getNodePublic().humanNodePublic());
|
||||
h.set_nodeproof(&vchSig[0], vchSig.size());
|
||||
h.set_ipv4port(theConfig.PEER_PORT);
|
||||
|
||||
Ledger::pointer closedLedger = theApp->getMasterLedger().getClosedLedger();
|
||||
assert(closedLedger && closedLedger->isClosed());
|
||||
if (closedLedger->isClosed())
|
||||
if (closedLedger && closedLedger->isClosed())
|
||||
{
|
||||
uint256 hash = closedLedger->getHash();
|
||||
h.set_closedledger(hash.begin(), hash.GetSerializeSize());
|
||||
@@ -1134,13 +1160,24 @@ void Peer::punishPeer(PeerPunish)
|
||||
{
|
||||
}
|
||||
|
||||
Json::Value Peer::getJson() {
|
||||
Json::Value ret(Json::objectValue);
|
||||
Json::Value Peer::getJson()
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
ret["this"] = ADDRESS(this);
|
||||
ret["public_key"] = mNodePublic.ToString();
|
||||
ret["ip"] = mIpPortConnect.first;
|
||||
ret["port"] = mIpPortConnect.second;
|
||||
ret["this"] = ADDRESS(this);
|
||||
ret["public_key"] = mNodePublic.ToString();
|
||||
ret["ip"] = mIpPortConnect.first;
|
||||
ret["port"] = mIpPortConnect.second;
|
||||
|
||||
if (mHello.has_fullversion())
|
||||
ret["version"] = mHello.fullversion();
|
||||
else if (mHello.has_versionminor() && mHello.has_versionmajor())
|
||||
ret["version"] = boost::lexical_cast<std::string>(mHello.versionmajor()) + "." +
|
||||
boost::lexical_cast<std::string>(mHello.versionminor());
|
||||
|
||||
if (mHello.has_protoversionminor() && mHello.has_protoversionmajor())
|
||||
ret["protocol"] = boost::lexical_cast<std::string>(mHello.protoversionmajor()) + "." +
|
||||
boost::lexical_cast<std::string>(mHello.protoversionminor());
|
||||
|
||||
if (!mIpPort.first.empty())
|
||||
{
|
||||
@@ -1148,7 +1185,7 @@ Json::Value Peer::getJson() {
|
||||
ret["verified_port"] = mIpPort.second;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
@@ -55,6 +55,7 @@ protected:
|
||||
std::list<PackedMessage::pointer> mSendQ;
|
||||
PackedMessage::pointer mSendingPacket;
|
||||
newcoin::TMStatusChange mLastStatus;
|
||||
newcoin::TMHello mHello;
|
||||
|
||||
Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx);
|
||||
|
||||
|
||||
@@ -623,7 +623,7 @@ void SHAMapItem::dump()
|
||||
|
||||
bool SHAMap::fetchNode(const uint256& hash, std::vector<unsigned char>& data)
|
||||
{
|
||||
HashedObject::pointer obj(HashedObject::retrieve(hash));
|
||||
HashedObject::pointer obj(theApp->getHashedObjectStore().retrieve(hash));
|
||||
if(!obj) return false;
|
||||
data = obj->getData();
|
||||
return true;
|
||||
@@ -642,14 +642,13 @@ int SHAMap::flushDirty(int maxNodes, HashedObjectType t, uint32 seq)
|
||||
|
||||
if(mDirtyNodes)
|
||||
{
|
||||
HashedObjectBulkWriter bw;
|
||||
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>& dirtyNodes = *mDirtyNodes;
|
||||
boost::unordered_map<SHAMapNode, SHAMapTreeNode::pointer>::iterator it = dirtyNodes.begin();
|
||||
while (it != dirtyNodes.end())
|
||||
{
|
||||
s.erase();
|
||||
it->second->addRaw(s);
|
||||
bw.store(t, seq, s.peekData(), s.getSHA512Half());
|
||||
theApp->getHashedObjectStore().store(t, seq, s.peekData(), s.getSHA512Half());
|
||||
if (flushed++ >= maxNodes)
|
||||
return flushed;
|
||||
it = dirtyNodes.erase(it);
|
||||
|
||||
69
src/SHAMapSync.h
Normal file
69
src/SHAMapSync.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#ifndef __SHAMAPYSNC__
|
||||
#define __SHAMAPSYNC__
|
||||
|
||||
#include "SHAMap.h"
|
||||
#include "Application.h"
|
||||
|
||||
// Sync filters allow low-level SHAMapSync code to interact correctly with
|
||||
// higher-level structures such as caches and transaction stores
|
||||
|
||||
class ConsensusTransSetSF : public SHAMapSyncFilter
|
||||
{ // sync filter for transaction sets during consensus building
|
||||
public:
|
||||
ConsensusTransSetSF() { ; }
|
||||
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
|
||||
const std::vector<unsigned char>& nodeData, bool isLeaf)
|
||||
{
|
||||
// WRITEME: If 'isLeaf' is true, this is a transaction
|
||||
theApp->getTempNodeCache().store(nodeHash, nodeData);
|
||||
}
|
||||
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
|
||||
{
|
||||
// WRITEME: We could check our own map, we could check transaction tables
|
||||
return theApp->getTempNodeCache().retrieve(nodeHash, nodeData);
|
||||
}
|
||||
};
|
||||
|
||||
class AccountStateSF : public SHAMapSyncFilter
|
||||
{ // sync filter for account state nodes during ledger sync
|
||||
protected:
|
||||
uint256 mLedgerHash;
|
||||
uint32 mLedgerSeq;
|
||||
|
||||
public:
|
||||
AccountStateSF(const uint256& ledgerHash, uint32 ledgerSeq) : mLedgerHash(ledgerHash), mLedgerSeq(ledgerSeq)
|
||||
{ ; }
|
||||
|
||||
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
|
||||
const std::vector<unsigned char>& nodeData, bool isLeaf)
|
||||
{
|
||||
theApp->getHashedObjectStore().store(ACCOUNT_NODE, mLedgerSeq, nodeData, nodeHash);
|
||||
}
|
||||
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
|
||||
{ // fetchNode already tried
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class TransactionStateSF : public SHAMapSyncFilter
|
||||
{ // sync filter for transactions tree during ledger sync
|
||||
protected:
|
||||
uint256 mLedgerHash;
|
||||
uint32 mLedgerSeq;
|
||||
|
||||
public:
|
||||
TransactionStateSF(const uint256& ledgerHash, uint32 ledgerSeq) : mLedgerHash(ledgerHash), mLedgerSeq(ledgerSeq)
|
||||
{ ; }
|
||||
|
||||
virtual void gotNode(const SHAMapNode& id, const uint256& nodeHash,
|
||||
const std::vector<unsigned char>& nodeData, bool isLeaf)
|
||||
{
|
||||
theApp->getHashedObjectStore().store(isLeaf ? TRANSACTION : TRANSACTION_NODE, mLedgerSeq, nodeData, nodeHash);
|
||||
}
|
||||
virtual bool haveNode(const SHAMapNode& id, const uint256& nodeHash, std::vector<unsigned char>& nodeData)
|
||||
{ // fetchNode already tried
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -16,7 +16,7 @@ const uint32 SerializedValidation::sValidationMagic = 0x4c575200; // "LGR"
|
||||
SerializedValidation::SerializedValidation(SerializerIterator& sit, bool checkSignature)
|
||||
: STObject(sValidationFormat, sit), mSignature(sit, "Signature"), mTrusted(false)
|
||||
{
|
||||
if (!isValid()) throw std::runtime_error("Invalid validation");
|
||||
if (checkSignature && !isValid()) throw std::runtime_error("Invalid validation");
|
||||
}
|
||||
|
||||
SerializedValidation::SerializedValidation(const uint256& ledgerHash, uint64 closeTime,
|
||||
@@ -56,12 +56,16 @@ uint64 SerializedValidation::getCloseTime() const
|
||||
}
|
||||
|
||||
bool SerializedValidation::isValid() const
|
||||
{
|
||||
return isValid(getSigningHash());
|
||||
}
|
||||
|
||||
bool SerializedValidation::isValid(const uint256& signingHash) const
|
||||
{
|
||||
try
|
||||
{
|
||||
NewcoinAddress naPublicKey = NewcoinAddress::createNodePublic(getValueFieldVL(sfSigningKey));
|
||||
|
||||
return naPublicKey.isValid() && naPublicKey.verifyNodePublic(getSigningHash(), mSignature.peekValue());
|
||||
return naPublicKey.isValid() && naPublicKey.verifyNodePublic(signingHash, mSignature.peekValue());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ public:
|
||||
bool isTrusted() const { return mTrusted; }
|
||||
CKey::pointer getSigningKey() const;
|
||||
uint256 getSigningHash() const;
|
||||
bool isValid(const uint256&) const;
|
||||
|
||||
void setTrusted() { mTrusted = true; }
|
||||
void addSigned(Serializer&) const;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// This class implemented a cache and a map. The cache keeps objects alive
|
||||
// in the map. The map allows multiple code paths that reference objects
|
||||
@@ -121,7 +122,7 @@ template<typename c_Key, typename c_Data> bool TaggedCache<c_Key, c_Data>::touch
|
||||
// Is the object in the map?
|
||||
typename boost::unordered_map<key_type, weak_data_ptr>::iterator mit = mMap.find(key);
|
||||
if (mit == mMap.end()) return false;
|
||||
if (mit->second->expired())
|
||||
if (mit->second.expired())
|
||||
{ // in map, but expired
|
||||
mMap.erase(mit);
|
||||
return false;
|
||||
@@ -131,12 +132,12 @@ template<typename c_Key, typename c_Data> bool TaggedCache<c_Key, c_Data>::touch
|
||||
typename boost::unordered_map<key_type, cache_entry>::iterator cit = mCache.find(key);
|
||||
if (cit != mCache.end())
|
||||
{ // in both map and cache
|
||||
cit->second->first = time(NULL);
|
||||
cit->second.first = time(NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
// In map but not cache, put in cache
|
||||
mCache.insert(std::make_pair(key, std::make_pair(time(NULL), weak_data_ptr(cit->second->second))));
|
||||
mCache.insert(std::make_pair(key, std::make_pair(time(NULL), weak_data_ptr(cit->second.second))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -213,9 +214,8 @@ boost::shared_ptr<c_Data> TaggedCache<c_Key, c_Data>::fetch(const key_type& key)
|
||||
template<typename c_Key, typename c_Data>
|
||||
bool TaggedCache<c_Key, c_Data>::store(const key_type& key, const c_Data& data)
|
||||
{
|
||||
if (!canonicalize(key, boost::shared_ptr<c_Data>(data)))
|
||||
return false;
|
||||
return true;
|
||||
boost::shared_ptr<c_Data> d = boost::make_shared<c_Data>(boost::ref(data));
|
||||
return canonicalize(key, d);
|
||||
}
|
||||
|
||||
template<typename c_Key, typename c_Data>
|
||||
|
||||
@@ -31,6 +31,7 @@ enum TransactionEngineResult
|
||||
tenMSG_SET, // Can't change a message key.
|
||||
tenBAD_AUTH_MASTER, // Auth for unclaimed account needs correct master key.
|
||||
tenBAD_RIPPLE, // Ledger prevents ripple from succeeding.
|
||||
terALREADY, // The exact transaction was already in this ledger
|
||||
|
||||
// Other
|
||||
tenFAILED = -100, // Something broke horribly
|
||||
@@ -43,7 +44,6 @@ enum TransactionEngineResult
|
||||
// terFAILED_BUT_COULD_SUCCEED = >0
|
||||
// Conflict with ledger database: Fee claimed
|
||||
// Might succeed if not conflict is not caused by transaction ordering.
|
||||
terALREADY, // The transaction was already in the ledger
|
||||
terBAD_SEQ, // This sequence number should be zero for prepaid transactions.
|
||||
terCREATED, // Can not create a previously created account.
|
||||
terDIR_FULL, // Can not add entry to full dir.
|
||||
|
||||
@@ -36,7 +36,7 @@ bool ValidationCollection::addValidation(SerializedValidation::pointer val)
|
||||
|
||||
Log(lsINFO) << "Val for " << hash.GetHex() << " from " << val->getSignerPublic().humanNodePublic()
|
||||
<< " added " << (val->isTrusted() ? "trusted" : "UNtrusted");
|
||||
return true;
|
||||
return isCurrent;
|
||||
}
|
||||
|
||||
ValidationSet ValidationCollection::getValidations(const uint256& ledger)
|
||||
|
||||
22
src/Version.h
Normal file
22
src/Version.h
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
// Versions
|
||||
|
||||
#ifndef SERVER_VERSION_MAJ
|
||||
|
||||
#define SERVER_VERSION_MAJ 0
|
||||
#define SERVER_VERSION_MIN 1
|
||||
#define SERVER_VERSION_SUB "-a"
|
||||
#define SERVER_NAME "NewCoin"
|
||||
|
||||
#define SV_STRINGIZE(x) SV_STRINGIZE2(x)
|
||||
#define SV_STRINGIZE2(x) #x
|
||||
#define SERVER_VERSION \
|
||||
(SERVER_NAME "-" SV_STRINGIZE(SERVER_VERSION_MAJ) "." SV_STRINGIZE(SERVER_VERSION_MIN) SERVER_VERSION_SUB)
|
||||
|
||||
#define PROTO_VERSION_MAJ 0
|
||||
#define PROTO_VERSION_MIN 0
|
||||
|
||||
#define MIN_PROTO_MAJ 0
|
||||
#define MIN_PROTO_MIN 0
|
||||
|
||||
#endif
|
||||
@@ -76,7 +76,21 @@ bool Wallet::nodeIdentityCreate() {
|
||||
|
||||
// Make new key.
|
||||
|
||||
#ifdef CREATE_NEW_DH_PARAMS
|
||||
std::string strDh512 = DH_der_gen(512);
|
||||
#else
|
||||
static char dh512Param[] = {
|
||||
0x30, 0x46, 0x02, 0x41, 0x00, 0x98, 0x15, 0xd2, 0xd0, 0x08, 0x32, 0xda,
|
||||
0xaa, 0xac, 0xc4, 0x71, 0xa3, 0x1b, 0x11, 0xf0, 0x6c, 0x62, 0xb2, 0x35,
|
||||
0x8a, 0x10, 0x92, 0xc6, 0x0a, 0xa3, 0x84, 0x7e, 0xaf, 0x17, 0x29, 0x0b,
|
||||
0x70, 0xef, 0x07, 0x4f, 0xfc, 0x9d, 0x6d, 0x87, 0x99, 0x19, 0x09, 0x5b,
|
||||
0x6e, 0xdb, 0x57, 0x72, 0x4a, 0x7e, 0xcd, 0xaf, 0xbd, 0x3a, 0x97, 0x55,
|
||||
0x51, 0x77, 0x5a, 0x34, 0x7c, 0xe8, 0xc5, 0x71, 0x63, 0x02, 0x01, 0x02
|
||||
};
|
||||
std::string strDh512(dh512Param, sizeof(dh512Param));
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
std::string strDh1024 = strDh512; // For testing and most cases 512 is fine.
|
||||
#else
|
||||
|
||||
@@ -37,14 +37,20 @@ enum MessageType {
|
||||
|
||||
|
||||
message TMHello {
|
||||
required uint32 version = 1;
|
||||
optional uint32 ledgerIndex = 2;
|
||||
optional uint64 netTime = 3;
|
||||
optional bytes nodePublic = 4; // node may opt to remain anonymous
|
||||
optional bytes nodeProof = 5;
|
||||
optional uint32 ipv4Port = 6;
|
||||
optional bytes closedLedger = 7; // our last closed ledger
|
||||
optional bytes previousLedger = 8; // the ledger before the last closed ledger
|
||||
required uint32 versionMinor = 1;
|
||||
required uint32 versionMajor = 2;
|
||||
required uint32 protoVersionMinor = 3;
|
||||
required uint32 protoVersionMajor = 4;
|
||||
required uint32 minProtoVersionMinor = 5;
|
||||
required uint32 minProtoVersionMajor = 6;
|
||||
required bytes nodePublic = 7;
|
||||
required bytes nodeProof = 8;
|
||||
optional string fullVersion = 9;
|
||||
optional uint64 netTime = 10;
|
||||
optional uint32 ipv4Port = 11;
|
||||
optional uint32 ledgerIndex = 12;
|
||||
optional bytes closedLedger = 13; // our last closed ledger
|
||||
optional bytes previousLedger = 14; // the ledger before the last closed ledger
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,14 +15,11 @@
|
||||
#include "BitcoinUtil.h"
|
||||
#include "Config.h"
|
||||
#include "Log.h"
|
||||
#include "Version.h"
|
||||
|
||||
using namespace boost;
|
||||
using namespace boost::asio;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Json::Value JSONRPCError(int code, const std::string& message)
|
||||
{
|
||||
Json::Value error(Json::objectValue);
|
||||
@@ -116,7 +113,7 @@ std::string HTTPReply(int nStatus, const std::string& strMsg)
|
||||
rfc1123Time().c_str(),
|
||||
access.c_str(),
|
||||
strMsg.size(),
|
||||
theConfig.VERSION_STR.c_str(),
|
||||
SERVER_VERSION,
|
||||
strMsg.c_str());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user