From 7fba10da4e687cfcbb2ba9adc5748e3cf4ea9b67 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 9 Oct 2012 11:09:02 -0700 Subject: [PATCH 01/14] Create a new open ledger based on the last closed ledger from the DB. Ledgers loaded from DB are always immutable. --- src/Application.cpp | 18 ++++++++++++------ src/Ledger.cpp | 6 +++--- src/Ledger.h | 4 ++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index 1a67e0b74d..ef00d19fdf 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -88,15 +88,17 @@ void Application::run() boost::thread t6(boost::bind(&InitDB, &mNetNodeDB, "netnode.db", NetNodeDBInit, NetNodeDBCount)); t1.join(); t2.join(); t3.join(); t4.join(); t5.join(); t6.join(); - if(theConfig.START_UP==Config::FRESH) + if (theConfig.START_UP == Config::FRESH) { Log(lsINFO) << "Starting new Ledger"; startNewLedger(); - }else if(theConfig.START_UP==Config::LOAD) + } + else if (theConfig.START_UP == Config::LOAD) { Log(lsINFO) << "Loading Old Ledger"; loadOldLedger(); - }else + } + else { // TODO: This should really not validate a ledger until it gets the current one from our peers // but I'll let david make this change since a lot of code assumes we have a ledger // for now just do what we always were doing @@ -173,6 +175,7 @@ Application::~Application() delete mHashNodeDB; delete mNetNodeDB; } + void Application::startNewLedger() { // New stuff. @@ -203,14 +206,17 @@ void Application::startNewLedger() void Application::loadOldLedger() { - Ledger::pointer lastLedger = Ledger::getSQL("SELECT * from Ledgers order by LedgerSeq desc limit 1;",true); + Ledger::pointer lastLedger = Ledger::getSQL("SELECT * from Ledgers order by LedgerSeq desc limit 1;"); - if(!lastLedger) + if (!lastLedger) { std::cout << "No Ledger found?" << std::endl; exit(-1); } - mMasterLedger.pushLedger(lastLedger); + + lastLedger->setClosed(); + Ledger::pointer openLedger = boost::make_shared(false, boost::ref(*lastLedger)); + mMasterLedger.switchLedgers(lastLedger, openLedger); mNetOps.setLastCloseTime(lastLedger->getCloseTimeNC()); } // vim:ts=4 diff --git a/src/Ledger.cpp b/src/Ledger.cpp index 25a94db5ca..f52e1f1e71 100644 --- a/src/Ledger.cpp +++ b/src/Ledger.cpp @@ -391,7 +391,7 @@ void Ledger::saveAcceptedLedger(Ledger::ref ledger) theApp->getOPs().pubLedger(ledger); } -Ledger::pointer Ledger::getSQL(const std::string& sql,bool isMutable) +Ledger::pointer Ledger::getSQL(const std::string& sql) { uint256 ledgerHash, prevHash, accountHash, transHash; uint64 totCoins; @@ -424,8 +424,8 @@ Ledger::pointer Ledger::getSQL(const std::string& sql,bool isMutable) db->endIterRows(); } - Ledger::pointer ret =Ledger::pointer(new Ledger(prevHash, transHash, accountHash, totCoins, closingTime, prevClosingTime, - closeFlags, closeResolution, ledgerSeq,isMutable)); + Ledger::pointer ret = Ledger::pointer(new Ledger(prevHash, transHash, accountHash, totCoins, + closingTime, prevClosingTime, closeFlags, closeResolution, ledgerSeq, true)); if (ret->getHash() != ledgerHash) { if (sLog(lsERROR)) diff --git a/src/Ledger.h b/src/Ledger.h index 71a1bbb2a9..3a96bcf6f0 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -93,7 +93,7 @@ public: Ledger(const uint256 &parentHash, const uint256 &transHash, const uint256 &accountHash, uint64 totCoins, uint32 closeTime, uint32 parentCloseTime, int closeFlags, int closeResolution, - uint32 ledgerSeq,bool immutable); // used for database ledgers + uint32 ledgerSeq, bool immutable); // used for database ledgers Ledger(const std::vector& rawLedger); @@ -103,7 +103,7 @@ public: Ledger(Ledger& target, bool isMutable); // snapshot - static Ledger::pointer getSQL(const std::string& sqlStatement,bool immutable=false); + static Ledger::pointer getSQL(const std::string& sqlStatement); void updateHash(); void setClosed() { mClosed = true; } From 366aad13e733c6cc8eb417f26cf3d0081fee691a Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Tue, 9 Oct 2012 12:06:13 -0700 Subject: [PATCH 02/14] Remove Ledger::bumpSeq --- src/Ledger.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Ledger.h b/src/Ledger.h index 3a96bcf6f0..41e30d2dbf 100644 --- a/src/Ledger.h +++ b/src/Ledger.h @@ -116,10 +116,6 @@ public: void armDirty() { mTransactionMap->armDirty(); mAccountStateMap->armDirty(); } void disarmDirty() { mTransactionMap->disarmDirty(); mAccountStateMap->disarmDirty(); } - // This ledger has closed, will never be accepted, and is accepting - // new transactions to be re-reprocessed when do accept a new last-closed ledger - void bumpSeq() { mClosed = true; mLedgerSeq++; } - // ledger signature operations void addRaw(Serializer &s) const; void setRaw(const Serializer& s); From 4c61648a7b32ba15933a70452695297edb5fbfef Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 9 Oct 2012 12:25:51 -0700 Subject: [PATCH 03/14] WS: Add ledger_accept commnd. --- src/WSDoor.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/WSDoor.cpp b/src/WSDoor.cpp index 25eabb907f..f40d0d4539 100644 --- a/src/WSDoor.cpp +++ b/src/WSDoor.cpp @@ -79,6 +79,7 @@ public: boost::unordered_set parseAccountIds(const Json::Value& jvArray); // Request-Response Commands + void doLedgerAccept(Json::Value& jvResult, const Json::Value& jvRequest); void doLedgerClosed(Json::Value& jvResult, const Json::Value& jvRequest); void doLedgerCurrent(Json::Value& jvResult, const Json::Value& jvRequest); void doLedgerEntry(Json::Value& jvResult, const Json::Value& jvRequest); @@ -303,6 +304,7 @@ Json::Value WSConnection::invokeCommand(const Json::Value& jvRequest) doFuncPtr dfpFunc; } commandsA[] = { // Request-Response Commands: + { "ledger_accept", &WSConnection::doLedgerAccept }, { "ledger_closed", &WSConnection::doLedgerClosed }, { "ledger_current", &WSConnection::doLedgerCurrent }, { "ledger_entry", &WSConnection::doLedgerEntry }, @@ -541,6 +543,18 @@ void WSConnection::doLedgerAccountsUnsubscribe(Json::Value& jvResult, const Json } } +void WSConnection::doLedgerAccept(Json::Value& jvResult, const Json::Value& jvRequest) +{ + if (!theConfig.RUN_STANDALONE) + { + jvResult["error"] = "notStandAlone"; + } + else + { + jvResult["ledger_current_index"] = mNetwork.getCurrentLedgerID(); + } +} + void WSConnection::doLedgerClosed(Json::Value& jvResult, const Json::Value& jvRequest) { uint256 uLedger = mNetwork.getClosedLedger(); From 8714e40bcfd0d94695e95e832484bb7bd3946f74 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 9 Oct 2012 16:04:46 -0700 Subject: [PATCH 04/14] Improve amount parsing (accept e notation). --- src/Amount.cpp | 91 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 24 deletions(-) diff --git a/src/Amount.cpp b/src/Amount.cpp index 9012cf69f3..78cde08d5f 100644 --- a/src/Amount.cpp +++ b/src/Amount.cpp @@ -194,24 +194,30 @@ std::string STAmount::createHumanCurrency(const uint160& uCurrency) return sCurrency; } +// Assumes trusted input. bool STAmount::setValue(const std::string& sAmount) { // Note: mIsNative must be set already! uint64 uValue; int iOffset; size_t uDecimal = sAmount.find_first_of(mIsNative ? "^" : "."); - bool bInteger = uDecimal == std::string::npos; + size_t uExp = uDecimal == std::string::npos ? sAmount.find_first_of("e") : std::string::npos; + bool bInteger = uDecimal == std::string::npos && uExp == std::string::npos; mIsNegative = false; if (bInteger) { + // Integer input: does not necessarily mean native. + try { int64 a = sAmount.empty() ? 0 : lexical_cast_st(sAmount); if (a >= 0) - uValue = static_cast(a); + { + uValue = static_cast(a); + } else { - uValue = static_cast(-a); + uValue = static_cast(-a); mIsNegative = true; } @@ -224,36 +230,73 @@ bool STAmount::setValue(const std::string& sAmount) } iOffset = 0; } + else if (uExp != std::string::npos) + { + // e input + + try + { + int64 iInteger = uExp ? lexical_cast_st(sAmount.substr(0, uExp)) : 0; + if (iInteger >= 0) + { + uValue = static_cast(iInteger); + } + else + { + uValue = static_cast(-iInteger); + mIsNegative = true; + } + + iOffset = lexical_cast_st(sAmount.substr(uExp+1)); + } + catch (...) + { + Log(lsINFO) << "Bad e amount: " << sAmount; + + return false; + } + } else { + // Float input: has a decimal + // Example size decimal size-decimal offset // ^1 2 0 2 -1 // 123^ 4 3 1 0 // 1^23 4 1 3 -2 - iOffset = -int(sAmount.size() - uDecimal - 1); - - - // Issolate integer and fraction. - uint64 uInteger; - int64 iInteger = uDecimal ? lexical_cast_st(sAmount.substr(0, uDecimal)) : 0; - if (iInteger >= 0) - uInteger = static_cast(iInteger); - else + try { - uInteger = static_cast(-iInteger); - mIsNegative = true; + iOffset = -int(sAmount.size() - uDecimal - 1); + + // Issolate integer and fraction. + uint64 uInteger; + int64 iInteger = uDecimal ? lexical_cast_st(sAmount.substr(0, uDecimal)) : 0; + if (iInteger >= 0) + { + uInteger = static_cast(iInteger); + } + else + { + uInteger = static_cast(-iInteger); + mIsNegative = true; + } + + uint64 uFraction = iOffset ? lexical_cast_st(sAmount.substr(uDecimal+1)) : 0; + + // Scale the integer portion to the same offset as the fraction. + uValue = uInteger; + for (int i = -iOffset; i--;) + uValue *= 10; + + // Add in the fraction. + uValue += uFraction; } + catch (...) + { + Log(lsINFO) << "Bad float amount: " << sAmount; - - uint64 uFraction = iOffset ? lexical_cast_st(sAmount.substr(uDecimal+1)) : 0; - - // Scale the integer portion to the same offset as the fraction. - uValue = uInteger; - for (int i = -iOffset; i--;) - uValue *= 10; - - // Add in the fraction. - uValue += uFraction; + return false; + } } if (mIsNative) From 891744431e71823748e1e3a6c2f0908648727818 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 9 Oct 2012 16:05:25 -0700 Subject: [PATCH 05/14] UT: test for empty string with stringToHex and hexToString. --- test/standalone-test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/standalone-test.js b/test/standalone-test.js index 572b0d0b51..640c274860 100644 --- a/test/standalone-test.js +++ b/test/standalone-test.js @@ -24,6 +24,9 @@ buster.testCase("Utils", { }, "Under 10: 1" : function () { buster.assert.equals("01", utils.stringToHex(utils.hexToString("1"))); + }, + "Empty" : function () { + buster.assert.equals("", utils.stringToHex(utils.hexToString(""))); } } }); From 25e10ce9cbc225fbad39f78bc4abc567db601d78 Mon Sep 17 00:00:00 2001 From: MJK Date: Tue, 9 Oct 2012 17:02:01 -0700 Subject: [PATCH 06/14] bug fix for Pathfinder. Drop zero-length paths; prevent them from getting added and avoid pathbuilding errors later --- src/Pathfinder.cpp | 27 ++++++++++++++++++++++++++- src/SerializedTypes.h | 3 +++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/Pathfinder.cpp b/src/Pathfinder.cpp index 9290f921ae..6585730936 100644 --- a/src/Pathfinder.cpp +++ b/src/Pathfinder.cpp @@ -104,6 +104,9 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet if (ele.mAccountID == mDstAccountID) { path.mPath.erase(path.mPath.begin()); path.mPath.erase(path.mPath.begin() + path.mPath.size()-1); + if (path.mPath.size() == 0) { + continue; + } retPathSet.addPath(path); return true; } @@ -118,7 +121,11 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet STPath new_path(path); STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut()); new_path.mPath.push_back(new_ele); + new_path.mCurrencyID = book->getCurrencyOut(); + new_path.mCurrencyID = book->getCurrencyOut(); + pqueue.push(new_path); + } } @@ -136,8 +143,26 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet new_path.mPath.push_back(new_ele); pqueue.push(new_path); } + } // BOOST_FOREACHE + + // every offer that wants the source currency + std::vector books; + mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books); + + BOOST_FOREACH(OrderBook::pointer book,books) + { + STPath new_path(path); + STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut()); + + new_path.mPath.push_back(new_ele); + new_path.mCurrentAccount=book->getIssuerOut(); + new_path.mCurrencyID=book->getCurrencyOut(); + + pqueue.push(new_path); + } - } + + } // else // enumerate all adjacent nodes, construct a new path and push it into the queue } // While } // if there is a ledger diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index 9b502409f5..90438442a8 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -595,6 +595,9 @@ public: // std::string getText() const; Json::Value getJson(int) const; + uint160 mCurrencyID; + uint160 mCurrentAccount; // what account is at the end of the path + std::vector::iterator begin() { return mPath.begin(); } std::vector::iterator end() { return mPath.end(); } std::vector::const_iterator begin() const { return mPath.begin(); } From 6d87af5e933b96b1f35393c9fa04fa1bb24c926b Mon Sep 17 00:00:00 2001 From: MJK Date: Tue, 9 Oct 2012 17:19:12 -0700 Subject: [PATCH 07/14] fix typo in code in previous Pathfinder fix --- src/Pathfinder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pathfinder.cpp b/src/Pathfinder.cpp index 6585730936..23e596aab4 100644 --- a/src/Pathfinder.cpp +++ b/src/Pathfinder.cpp @@ -122,7 +122,7 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut()); new_path.mPath.push_back(new_ele); new_path.mCurrencyID = book->getCurrencyOut(); - new_path.mCurrencyID = book->getCurrencyOut(); + new_path.mCurrentAccount = book->getCurrencyOut(); pqueue.push(new_path); From 867ff01a2df5783bbdb13046286841f60490208d Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Tue, 9 Oct 2012 19:14:36 -0700 Subject: [PATCH 08/14] UT: split out utils test. --- test/standalone-test.js | 25 ++----------------------- test/utils-test.js | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 23 deletions(-) create mode 100644 test/utils-test.js diff --git a/test/standalone-test.js b/test/standalone-test.js index 640c274860..68d86b7843 100644 --- a/test/standalone-test.js +++ b/test/standalone-test.js @@ -1,9 +1,8 @@ -var fs = require("fs"); -var buster = require("buster"); +var fs = require("fs"); +var buster = require("buster"); var server = require("./server.js"); var remote = require("../js/remote.js"); -var utils = require("../js/utils.js"); var config = require("./config.js"); // How long to wait for server to start. @@ -11,26 +10,6 @@ var serverDelay = 1500; buster.testRunner.timeout = 5000; -buster.testCase("Utils", { - "hexToString and stringToHex" : { - "Even: 123456" : function () { - buster.assert.equals("123456", utils.stringToHex(utils.hexToString("123456"))); - }, - "Odd: 12345" : function () { - buster.assert.equals("012345", utils.stringToHex(utils.hexToString("12345"))); - }, - "Under 10: 0" : function () { - buster.assert.equals("00", utils.stringToHex(utils.hexToString("0"))); - }, - "Under 10: 1" : function () { - buster.assert.equals("01", utils.stringToHex(utils.hexToString("1"))); - }, - "Empty" : function () { - buster.assert.equals("", utils.stringToHex(utils.hexToString(""))); - } - } -}); - buster.testCase("Standalone server startup", { "server start and stop" : function (done) { server.start("alpha", diff --git a/test/utils-test.js b/test/utils-test.js new file mode 100644 index 0000000000..5b22fb5cce --- /dev/null +++ b/test/utils-test.js @@ -0,0 +1,26 @@ +var fs = require("fs"); +var buster = require("buster"); + +var utils = require("../js/utils.js"); + +buster.testCase("Utils", { + "hexToString and stringToHex" : { + "Even: 123456" : function () { + buster.assert.equals("123456", utils.stringToHex(utils.hexToString("123456"))); + }, + "Odd: 12345" : function () { + buster.assert.equals("012345", utils.stringToHex(utils.hexToString("12345"))); + }, + "Under 10: 0" : function () { + buster.assert.equals("00", utils.stringToHex(utils.hexToString("0"))); + }, + "Under 10: 1" : function () { + buster.assert.equals("01", utils.stringToHex(utils.hexToString("1"))); + }, + "Empty" : function () { + buster.assert.equals("", utils.stringToHex(utils.hexToString(""))); + } + } +}); + +// vim:sw=2:sts=2:ts=8 From 9e6a885af9028ad51bca6f91276086da1bf99c69 Mon Sep 17 00:00:00 2001 From: MJK Date: Tue, 9 Oct 2012 22:48:27 -0700 Subject: [PATCH 09/14] Fix minor typo --- src/RPCServer.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 6d669e03f1..0723e7936a 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1828,9 +1828,6 @@ Json::Value RPCServer::doSend(const Json::Value& params) if (params.size() >= 9) sSrcIssuer = params[8u].asString(); - if (params.size() >= 9) - sSrcIssuer = params[8u].asString(); - if (!naSeed.setSeedGeneric(params[0u].asString())) { return RPCError(rpcBAD_SEED); From 23938b8c2d88aefa8ae48cc4066083ff61e71ea1 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 10 Oct 2012 00:06:26 -0700 Subject: [PATCH 10/14] WS: fix ledger_accept. --- src/WSDoor.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/WSDoor.cpp b/src/WSDoor.cpp index f40d0d4539..8905788b43 100644 --- a/src/WSDoor.cpp +++ b/src/WSDoor.cpp @@ -551,6 +551,8 @@ void WSConnection::doLedgerAccept(Json::Value& jvResult, const Json::Value& jvRe } else { + theApp->getOPs().acceptLedger(); + jvResult["ledger_current_index"] = mNetwork.getCurrentLedgerID(); } } From fc73e286c4390fcd90511610c24bdb38451ce39d Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 10 Oct 2012 00:15:40 -0700 Subject: [PATCH 11/14] WS: Changed response of server_subscribe. --- src/NetworkOPs.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index f336e9463d..00bc4e5f69 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -931,10 +931,10 @@ void NetworkOPs::pubLedger(Ledger::ref lpAccepted) { Json::Value jvObj(Json::objectValue); - jvObj["type"] = "ledgerAccepted"; - jvObj["seq"] = lpAccepted->getLedgerSeq(); - jvObj["hash"] = lpAccepted->getHash().ToString(); - jvObj["time"] = Json::Value::UInt(lpAccepted->getCloseTimeNC()); + jvObj["type"] = "ledgerAccepted"; + jvObj["ledger_closed_index"] = lpAccepted->getLedgerSeq(); + jvObj["ledger_closed"] = lpAccepted->getHash().ToString(); + jvObj["time"] = Json::Value::UInt(lpAccepted->getCloseTimeNC()); BOOST_FOREACH(InfoSub* ispListener, mSubLedger) { From 84aec6750779e7480bba4bb865653e8f4a5a8a04 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Wed, 10 Oct 2012 00:38:29 -0700 Subject: [PATCH 12/14] JS: Add ledger_accept to remote.js --- js/remote.js | 24 +++++++++++++++++++----- src/WSDoor.cpp | 2 +- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/js/remote.js b/js/remote.js index 8919d6308a..3bf421d697 100644 --- a/js/remote.js +++ b/js/remote.js @@ -299,16 +299,30 @@ Remote.prototype.server_subscribe = function (onDone, onFailure) { this.request( { 'command' : 'server_subscribe' }, - function (r) { - self.ledger_current_index = r.ledger_current_index; - self.ledger_closed = r.ledger_closed; - self.stand_alone = r.stand_alone; - onDone(); + function (r) { + self.ledger_current_index = r.ledger_current_index; + self.ledger_closed = r.ledger_closed; + self.stand_alone = r.stand_alone; + onDone(); }, onFailure ); }; +Remote.prototype.ledger_accept = function (onDone, onFailure) { + if (this.stand_alone) + { + this.request( + { 'command' : 'ledger_accept' }, + onDone, + onFailure + ); + } + else { + onFailure({ 'error' : 'notStandAlone' }); + } +}; + // Refresh accounts[account].seq // done(result); Remote.prototype.account_seq = function (account, advance, onDone, onFailure) { diff --git a/src/WSDoor.cpp b/src/WSDoor.cpp index 8905788b43..7aaa64009f 100644 --- a/src/WSDoor.cpp +++ b/src/WSDoor.cpp @@ -551,7 +551,7 @@ void WSConnection::doLedgerAccept(Json::Value& jvResult, const Json::Value& jvRe } else { - theApp->getOPs().acceptLedger(); + mNetwork.acceptLedger(); jvResult["ledger_current_index"] = mNetwork.getCurrentLedgerID(); } From 850fee99e764c068526bedcf6f6933129e98fa8d Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 10 Oct 2012 01:39:20 -0700 Subject: [PATCH 13/14] Types for templates, if we decide to use them. --- src/SerializeProto.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/SerializeProto.h b/src/SerializeProto.h index 736a83a3e8..df7d2f6d5c 100644 --- a/src/SerializeProto.h +++ b/src/SerializeProto.h @@ -24,6 +24,7 @@ // 8-bit integers FIELD(CloseResolution, UINT8, 1) + FIELD(TemplateEntryType, UINT8, 2) // 16-bit integers FIELD(LedgerEntryType, UINT16, 1) @@ -123,9 +124,13 @@ // inner object // OBJECT/1 is reserved for end of object + FIELD(TemplateEntry, OBJECT, 1) // array of objects // ARRAY/1 is reserved for end of array FIELD(SigningAccounts, ARRAY, 2) FIELD(TxnSignatures, ARRAY, 3) FIELD(Signatures, ARRAY, 4) + FIELD(Template, ARRAY, 5) + FIELD(Necessary, ARRAY, 6) + FIELD(Sufficient, ARRAY, 7) From 1448eb1a5cc6b205073cc7c22954a1a57a051bf3 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Wed, 10 Oct 2012 01:40:02 -0700 Subject: [PATCH 14/14] '--net' startup option to require the node to get its ledger from the network. Once we have a stable network, this will likely be the default. --- src/Application.cpp | 10 ++++++---- src/Config.h | 2 +- src/NetworkOPs.cpp | 12 ++++++++---- src/NetworkOPs.h | 2 ++ src/main.cpp | 10 ++++++---- 5 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/Application.cpp b/src/Application.cpp index ef00d19fdf..a5d458dc18 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -98,12 +98,14 @@ void Application::run() Log(lsINFO) << "Loading Old Ledger"; loadOldLedger(); } - else - { // TODO: This should really not validate a ledger until it gets the current one from our peers - // but I'll let david make this change since a lot of code assumes we have a ledger - // for now just do what we always were doing + else if (theConfig.START_UP == Config::NETWORK) + { // This should probably become the default once we have a stable network + if (!theConfig.RUN_STANDALONE) + mNetOps.needNetworkLedger(); startNewLedger(); } + else + startNewLedger(); // // Begin validation and ip maintenance. diff --git a/src/Config.h b/src/Config.h index cc2b85ed4b..f4c0d9a96b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -56,7 +56,7 @@ public: std::vector IPS; // Peer IPs from newcoind.cfg. std::vector SNTP_SERVERS; // SNTP servers from newcoind.cfg. - enum StartUpType {FRESH,NORMAL,LOAD}; + enum StartUpType { FRESH, NORMAL, LOAD, NETWORK }; StartUpType START_UP; // Network parameters diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 00bc4e5f69..855128bdf2 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -26,8 +26,9 @@ SETUP_LOG(); NetworkOPs::NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster) : - mMode(omDISCONNECTED),mNetTimer(io_service), mLedgerMaster(pLedgerMaster), mCloseTimeOffset(0), - mLastCloseProposers(0), mLastCloseConvergeTime(1000 * LEDGER_IDLE_INTERVAL), mLastValidationTime(0) + mMode(omDISCONNECTED), mNeedNetworkLedger(false), mNetTimer(io_service), mLedgerMaster(pLedgerMaster), + mCloseTimeOffset(0), mLastCloseProposers(0), mLastCloseConvergeTime(1000 * LEDGER_IDLE_INTERVAL), + mLastValidationTime(0) { } @@ -424,7 +425,8 @@ void NetworkOPs::checkState(const boost::system::error_code& result) // If full or tracking, check only at wobble time! uint256 networkClosed; bool ledgerChange = checkLastClosedLedger(peerList, networkClosed); - if(networkClosed.isZero())return; + if(networkClosed.isZero()) + return; // WRITEME: Unless we are in omFULL and in the process of doing a consensus, // we must count how many nodes share our LCL, how many nodes disagree with our LCL, @@ -435,7 +437,8 @@ void NetworkOPs::checkState(const boost::system::error_code& result) if ((mMode == omCONNECTED) && !ledgerChange) { // count number of peers that agree with us and UNL nodes whose validations we have for LCL // if the ledger is good enough, go to omTRACKING - TODO - setMode(omTRACKING); + if (!mNeedNetworkLedger) + setMode(omTRACKING); } if ((mMode == omTRACKING) && !ledgerChange ) @@ -617,6 +620,7 @@ void NetworkOPs::switchLastClosedLedger(Ledger::pointer newLedger, bool duringCo else cLog(lsERROR) << "JUMP last closed ledger to " << newLedger->getHash(); + mNeedNetworkLedger = false; newLedger->setClosed(); Ledger::pointer openLedger = boost::make_shared(false, boost::ref(*newLedger)); mLedgerMaster->switchLedgers(newLedger, openLedger); diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index 8f4d3557d1..043ae313b7 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -52,6 +52,7 @@ protected: typedef boost::unordered_map >::iterator subInfoMapIterator; OperatingMode mMode; + bool mNeedNetworkLedger; boost::posix_time::ptime mConnectTime; boost::asio::deadline_timer mNetTimer; boost::shared_ptr mConsensus; @@ -184,6 +185,7 @@ public: void setStandAlone() { setMode(omFULL); } void setStateTimer(); void newLCL(int proposers, int convergeTime, const uint256& ledgerHash); + void needNetworkLedger() { mNeedNetworkLedger = true; } void consensusViewChange(); int getPreviousProposers() { return mLastCloseProposers; } int getPreviousConvergeTime() { return mLastCloseConvergeTime; } diff --git a/src/main.cpp b/src/main.cpp index 63a7812136..17a46eefa2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -98,8 +98,9 @@ int main(int argc, char* argv[]) ("test,t", "Perform unit tests.") ("parameters", po::value< vector >(), "Specify comma separated parameters.") ("verbose,v", "Increase log level.") - ("load","Load the current ledger from the local DB.") - ("start","Start from a fresh Ledger.") + ("load", "Load the current ledger from the local DB.") + ("start", "Start from a fresh Ledger.") + ("net", "Get the initial ledger from the network.") ; // Interpret positional arguments as --parameters. @@ -156,8 +157,9 @@ int main(int argc, char* argv[]) } } - if(vm.count("start")) theConfig.START_UP=Config::FRESH; - else if(vm.count("load")) theConfig.START_UP=Config::LOAD; + if (vm.count("start")) theConfig.START_UP = Config::FRESH; + else if (vm.count("load")) theConfig.START_UP = Config::LOAD; + else if (vm.count("net")) theConfig.START_UP = Config::NETWORK; if (iResult) {