From dacbc58ef3be2578d49f11ddb7041048423a4d37 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 29 Jun 2012 17:51:37 -0700 Subject: [PATCH 01/11] Improvements for WS account_transaction_subscribe. --- src/NetworkOPs.cpp | 10 ++++- src/TransactionEngine.cpp | 65 ++++++++++++++++++++++++++++++ src/TransactionEngine.h | 84 ++++++++++++++++++++------------------- 3 files changed, 117 insertions(+), 42 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 5195ab28d9..2c25ba0837 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -818,11 +818,19 @@ void NetworkOPs::pubTransaction(const Ledger::pointer& lpCurrent, const Serializ } Json::Value jvObj(Json::objectValue); + std::string strToken; + std::string strHuman; - jvObj["type"] = "accountTransactionProposed"; + transResultInfo(terResult, strToken, strHuman); + + jvObj["type"] = "accountTransaction"; jvObj["seq"] = lpCurrent->getLedgerSeq(); jvObj["accounts"] = jvAccounts; jvObj["transaction"] = stTxn.getJson(0); + jvObj["status"] = "proposed"; + jvObj["result"] = strToken; + jvObj["result_message"] = strHuman; + jvObj["result_code"] = terResult; BOOST_FOREACH(InfoSub* ispListener, usisNotify) { diff --git a/src/TransactionEngine.cpp b/src/TransactionEngine.cpp index 7545df35bb..18a30aaa7a 100644 --- a/src/TransactionEngine.cpp +++ b/src/TransactionEngine.cpp @@ -17,6 +17,71 @@ #define DIR_NODE_MAX 32 +bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std::string& strHuman) +{ + static struct { + TransactionEngineResult terCode; + const char* cpToken; + const char* cpHuman; + } transResultInfoA[] = { + { tenGEN_IN_USE, "tenGEN_IN_USE", "Generator already in use." }, + { tenCREATEXNS, "tenCREATEXNS", "Can not specify non XNS for Create." }, + { tenEXPLICITXNS, "tenEXPLICITXNS", "XNS is used by default, don't specify it." }, + { tenDST_NEEDED, "tenDST_NEEDED", "Destination not specified." }, + { tenDST_IS_SRC, "tenDST_IS_SRC", "Destination may not be source." }, + { tenBAD_GEN_AUTH, "tenBAD_GEN_AUTH", "Not authorized to claim generator." }, + { tenBAD_ADD_AUTH, "tenBAD_ADD_AUTH", "Not authorized to add account." }, + { tenBAD_CLAIM_ID, "tenBAD_CLAIM_ID", "Malformed." }, + { tenBAD_SET_ID, "tenBAD_SET_ID", "Malformed." }, + { tenDIRECT_XNS_ONLY, "tenDIRECT_XNS_ONLY", "Direct payments are non-ripple XNS only." }, + { tenRIPPLE_EMPTY, "tenRIPPLE_EMPTY", "PathSet with no paths." }, + { tenCLAIMED, "tenCLAIMED", "Can not claim a previously claimed account." }, + { tenCREATED, "tenCREATED", "Can't add an already created account." }, + { tenMSG_SET, "tenMSG_SET", "Can't change a message key." }, + { tenBAD_AUTH_MASTER, "tenBAD_AUTH_MASTER", "Auth for unclaimed account needs correct master key." }, + { tenBAD_RIPPLE, "tenBAD_RIPPLE", "Ledger prevents ripple from succeeding." }, + { terALREADY, "terALREADY", "The exact transaction was already in this ledger" }, + { tenFAILED, "tenFAILED", "Something broke horribly" }, + { tenUNKNOWN, "tenUNKNOWN", "The transactions requires logic not implemented yet" }, + { tenINSUF_FEE_P, "tenINSUF_FEE_P", "fee totally insufficient" }, + { tenINVALID, "tenINVALID", "The transaction is ill-formed" }, + { terSUCCESS, "terSUCCESS", "The transaction was applied" }, + { terBAD_SEQ, "terBAD_SEQ", "This sequence number should be zero for prepaid transactions." }, + { terCREATED, "terCREATED", "Can not create a previously created account." }, + { terDIR_FULL, "terDIR_FULL", "Can not add entry to full dir." }, + { terINSUF_FEE_B, "terINSUF_FEE_B", "Account balance can't pay fee" }, + { terINSUF_FEE_T, "terINSUF_FEE_T", "fee insufficient now (account doesn't exist, network load)" }, + { terNODE_NOT_FOUND, "terNODE_NOT_FOUND", "Can not delete a dir node." }, + { terNODE_NOT_MENTIONED, "terNODE_NOT_MENTIONED", "?"}, + { terNODE_NO_ROOT, "terNODE_NO_ROOT", "?"}, + { terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist" }, + { terNO_DST, "terNO_DST", "The destination does not exist" }, + { terNO_PATH, "terNO_PATH", "No path existed or met transaction/balance requirements" }, + { terPAST_LEDGER, "terPAST_LEDGER", "The transaction expired and can't be applied" }, + { terPAST_SEQ, "terPAST_SEQ", "This sequence number has already past" }, + { terPRE_SEQ, "terPRE_SEQ", "Missing/inapplicable prior transaction" }, + { terUNFUNDED, "terUNFUNDED", "Source account had insufficient balance for transaction." }, + { terNO_LINE_NO_ZERO, "terNO_LINE_NO_ZERO", "Can't zero non-existant line, destination might make it." }, + { terSET_MISSING_DST, "terSET_MISSING_DST", "Can't set password, destination missing." }, + { terFUNDS_SPENT, "terFUNDS_SPENT", "Can't set password, password set funds already spent." }, + { terUNCLAIMED, "terUNCLAIMED", "Can not use an unclaimed account." }, + { terBAD_AUTH, "terBAD_AUTH", "Transaction's public key is not authorized." }, + { terBAD_RIPPLE, "terBAD_RIPPLE", "No ripple path can be satisfied." }, + }; + + int iIndex = NUMBER(transResultInfoA); + + while (iIndex-- && transResultInfoA[iIndex].terCode != terCode) + ; + + if (iIndex >= 0) + { + strToken = transResultInfoA[iIndex].cpToken; + strHuman = transResultInfoA[iIndex].cpHuman; + } + + return iIndex >= 0; +} // We return the uNodeDir so that on delete we can quickly know where the element is mentioned in the directory. TransactionEngineResult TransactionEngine::dirAdd( std::vector& accounts, diff --git a/src/TransactionEngine.h b/src/TransactionEngine.h index 960fff12b6..037ac19b87 100644 --- a/src/TransactionEngine.h +++ b/src/TransactionEngine.h @@ -13,60 +13,62 @@ enum TransactionEngineResult // tenCAN_NEVER_SUCCEED = <0 // Malformed: Fee claimed - tenGEN_IN_USE = -300, // Generator already in use. - tenCREATEXNS, // Can not specify non XNS for Create. - tenEXPLICITXNS, // XNS is used by default, don't specify it. - tenDST_NEEDED, // Destination not specified. - tenDST_IS_SRC, // Destination may not be source. - tenBAD_GEN_AUTH, // Not authorized to claim generator. - tenBAD_ADD_AUTH, // Not authorized to add account. - tenBAD_CLAIM_ID, // Malformed. - tenBAD_SET_ID, // Malformed. - tenDIRECT_XNS_ONLY, // Direct payments are non-ripple XNS only. - tenRIPPLE_EMPTY, // PathSet with no paths. + tenGEN_IN_USE = -300, + tenCREATEXNS, + tenEXPLICITXNS, + tenDST_NEEDED, + tenDST_IS_SRC, + tenBAD_GEN_AUTH, + tenBAD_ADD_AUTH, + tenBAD_CLAIM_ID, + tenBAD_SET_ID, + tenDIRECT_XNS_ONLY, + tenRIPPLE_EMPTY, // Invalid: Ledger won't allow. - tenCLAIMED = -200, // Can not claim a previously claimed account. - tenCREATED, // Can't add an already created account. - 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 + tenCLAIMED = -200, + tenCREATED, + tenMSG_SET, + tenBAD_AUTH_MASTER, + tenBAD_RIPPLE, + terALREADY, // Other - tenFAILED = -100, // Something broke horribly - tenUNKNOWN, // The transactions requires logic not implemented yet - tenINSUF_FEE_P, // fee totally insufficient - tenINVALID, // The transaction is ill-formed + tenFAILED = -100, + tenUNKNOWN, + tenINSUF_FEE_P, + tenINVALID, - terSUCCESS = 0, // The transaction was applied + terSUCCESS = 0, // terFAILED_BUT_COULD_SUCCEED = >0 // Conflict with ledger database: Fee claimed // Might succeed if not conflict is not caused by transaction ordering. - 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. - terINSUF_FEE_B, // Account balance can't pay fee - terINSUF_FEE_T, // fee insufficient now (account doesn't exist, network load) - terNODE_NOT_FOUND, // Can not delete a dir node. + terBAD_SEQ, + terCREATED, + terDIR_FULL, + terINSUF_FEE_B, + terINSUF_FEE_T, + terNODE_NOT_FOUND, terNODE_NOT_MENTIONED, terNODE_NO_ROOT, - terNO_ACCOUNT, // The source account does not exist - terNO_DST, // The destination does not exist - terNO_PATH, // No path existed or met transaction/balance requirements - terPAST_LEDGER, // The transaction expired and can't be applied - terPAST_SEQ, // This sequence number has already past - terPRE_SEQ, // Missing/inapplicable prior transaction - terUNFUNDED, // Source account had insufficient balance for transaction. - terNO_LINE_NO_ZERO, // Can't zero non-existant line, destination might make it. - terSET_MISSING_DST, // Can't set password, destination missing. - terFUNDS_SPENT, // Can't set password, password set funds already spent. - terUNCLAIMED, // Can not use an unclaimed account. - terBAD_AUTH, // Transaction's public key is not authorized. - terBAD_RIPPLE, // No ripple path can be satisfied. + terNO_ACCOUNT, + terNO_DST, + terNO_PATH, + terPAST_LEDGER, + terPAST_SEQ, + terPRE_SEQ, + terUNFUNDED, + terNO_LINE_NO_ZERO, + terSET_MISSING_DST, + terFUNDS_SPENT, + terUNCLAIMED, + terBAD_AUTH, + terBAD_RIPPLE, }; +bool transResultInfo(TransactionEngineResult terCode, std::string& strToken, std::string& strHuman); + enum TransactionEngineParams { tepNONE = 0, From 1804530577aff5867a51fc8359576145cfcd40ae Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Fri, 29 Jun 2012 18:04:39 -0700 Subject: [PATCH 02/11] Make WS transaction_subscribe consistent with account_transaction_subscribe. --- src/NetworkOPs.cpp | 55 ++++++++++++++++++++++++---------------------- src/NetworkOPs.h | 2 ++ 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 2c25ba0837..06590e3ca2 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -767,17 +767,40 @@ void NetworkOPs::pubLedger(const Ledger::pointer& lpAccepted) } } +Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TransactionEngineResult terResult, const std::string& strStatus, int iSeq, const std::string& strType) +{ + Json::Value jvAccounts(Json::arrayValue); + + BOOST_FOREACH(const NewcoinAddress& naAccountID, stTxn.getAffectedAccounts()) + { + jvAccounts.append(Json::Value(naAccountID.humanAccountID())); + } + + Json::Value jvObj(Json::objectValue); + std::string strToken; + std::string strHuman; + + transResultInfo(terResult, strToken, strHuman); + + jvObj["type"] = strType; + jvObj["seq"] = iSeq; + jvObj["accounts"] = jvAccounts; + jvObj["transaction"] = stTxn.getJson(0); + jvObj["status"] = strStatus; + jvObj["result"] = strToken; + jvObj["result_message"] = strHuman; + jvObj["result_code"] = terResult; + + return jvObj; +} + void NetworkOPs::pubTransaction(const Ledger::pointer& lpCurrent, const SerializedTransaction& stTxn, TransactionEngineResult terResult) { { boost::interprocess::sharable_lock sl(mMonitorLock); if (!mSubTransaction.empty()) { - Json::Value jvObj(Json::objectValue); - - jvObj["type"] = "transactionProposed"; - jvObj["seq"] = lpCurrent->getLedgerSeq(); - jvObj["transaction"] = stTxn.getJson(0); + Json::Value jvObj = transJson(stTxn, terResult, "proposed", lpCurrent->getLedgerSeq(), "transaction"); BOOST_FOREACH(InfoSub* ispListener, mSubTransaction) { @@ -810,27 +833,7 @@ void NetworkOPs::pubTransaction(const Ledger::pointer& lpCurrent, const Serializ if (!usisNotify.empty()) { - Json::Value jvAccounts(Json::arrayValue); - - BOOST_FOREACH(const NewcoinAddress& naAccountID, stTxn.getAffectedAccounts()) - { - jvAccounts.append(Json::Value(naAccountID.humanAccountID())); - } - - Json::Value jvObj(Json::objectValue); - std::string strToken; - std::string strHuman; - - transResultInfo(terResult, strToken, strHuman); - - jvObj["type"] = "accountTransaction"; - jvObj["seq"] = lpCurrent->getLedgerSeq(); - jvObj["accounts"] = jvAccounts; - jvObj["transaction"] = stTxn.getJson(0); - jvObj["status"] = "proposed"; - jvObj["result"] = strToken; - jvObj["result_message"] = strHuman; - jvObj["result_code"] = terResult; + Json::Value jvObj = transJson(stTxn, terResult, "proposed", lpCurrent->getLedgerSeq(), "account"); BOOST_FOREACH(InfoSub* ispListener, usisNotify) { diff --git a/src/NetworkOPs.h b/src/NetworkOPs.h index cd2d570b7e..cf0b4dab78 100644 --- a/src/NetworkOPs.h +++ b/src/NetworkOPs.h @@ -66,6 +66,8 @@ protected: boost::unordered_set mSubTransaction; // all transactions // subInfoMapType mSubTransactionAccounts; + Json::Value transJson(const SerializedTransaction& stTxn, TransactionEngineResult terResult, const std::string& strStatus, int iSeq, const std::string& strType); + public: NetworkOPs(boost::asio::io_service& io_service, LedgerMaster* pLedgerMaster); From 94a9def72e3788c40091b2a3c11c664df73cb692 Mon Sep 17 00:00:00 2001 From: jed Date: Fri, 29 Jun 2012 21:36:29 -0700 Subject: [PATCH 03/11] tweak json returns --- src/NetworkOPs.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 06590e3ca2..c29da13f69 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -769,13 +769,6 @@ void NetworkOPs::pubLedger(const Ledger::pointer& lpAccepted) Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, TransactionEngineResult terResult, const std::string& strStatus, int iSeq, const std::string& strType) { - Json::Value jvAccounts(Json::arrayValue); - - BOOST_FOREACH(const NewcoinAddress& naAccountID, stTxn.getAffectedAccounts()) - { - jvAccounts.append(Json::Value(naAccountID.humanAccountID())); - } - Json::Value jvObj(Json::objectValue); std::string strToken; std::string strHuman; @@ -783,12 +776,10 @@ Json::Value NetworkOPs::transJson(const SerializedTransaction& stTxn, Transactio transResultInfo(terResult, strToken, strHuman); jvObj["type"] = strType; - jvObj["seq"] = iSeq; - jvObj["accounts"] = jvAccounts; jvObj["transaction"] = stTxn.getJson(0); - jvObj["status"] = strStatus; + jvObj["transaction"]["inLedger"] = iSeq; + jvObj["transaction"]["status"] = strStatus; jvObj["result"] = strToken; - jvObj["result_message"] = strHuman; jvObj["result_code"] = terResult; return jvObj; From 6bbf7f58f025142522e303d66a2c5e9a29ccd426 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 22:40:48 -0700 Subject: [PATCH 04/11] Fix a small bug. Catch bad store/retrieeves sooner. --- src/HashedObject.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/HashedObject.cpp b/src/HashedObject.cpp index 4305a5b5cb..8c9ef0ac7c 100644 --- a/src/HashedObject.cpp +++ b/src/HashedObject.cpp @@ -17,6 +17,7 @@ HashedObjectStore::HashedObjectStore(int cacheSize, int cacheAge) : bool HashedObjectStore::store(HashedObjectType type, uint32 index, const std::vector& data, const uint256& hash) { // return: false=already in cache, true = added to cache + assert(hash == Serializer::getSHA512Half(data)); if (!theApp->getHashNodeDB()) return true; if (mCache.touch(hash)) { @@ -25,7 +26,7 @@ bool HashedObjectStore::store(HashedObjectType type, uint32 index, } HashedObject::pointer object = boost::make_shared(type, index, data, hash); - + if (!mCache.canonicalize(hash, object)) { boost::recursive_mutex::scoped_lock sl(mWriteMutex); mWriteSet.push_back(object); @@ -126,6 +127,8 @@ HashedObject::pointer HashedObjectStore::retrieve(const uint256& hash) db->getBinary("Object", &(data.front()), size); db->endIterRows(); + assert(Serializer::getSHA512Half(data) == hash); + HashedObjectType htype = UNKNOWN; switch(type[0]) { From b95dc249c06ac7a2d3d4704ee765446aefa9bc58 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 22:41:14 -0700 Subject: [PATCH 05/11] Fix two bugs that could have been what Jed reported. --- src/LedgerAcquire.cpp | 8 +++++++- src/SHAMapSync.cpp | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index c87d16ee3a..7a0892b523 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -8,6 +8,7 @@ #include "Application.h" #include "Log.h" #include "SHAMapSync.h" +#include "HashPrefixes.h" #define LA_DEBUG #define LEDGER_ACQUIRE_TIMEOUT 2 @@ -300,7 +301,12 @@ bool LedgerAcquire::takeBase(const std::string& data, Peer::pointer peer) return false; } mHaveBase = true; - theApp->getHashedObjectStore().store(LEDGER, mLedger->getLedgerSeq(), strCopy(data), mHash); + + Serializer s(data.size() + 4); + s.add32(sHP_Ledger); + s.addRaw(data); + theApp->getHashedObjectStore().store(LEDGER, mLedger->getLedgerSeq(), s.peekData(), mHash); + progress(); if (!mLedger->getTransHash()) mHaveTransactions = true; if (!mLedger->getAccountHash()) mHaveState = true; diff --git a/src/SHAMapSync.cpp b/src/SHAMapSync.cpp index 6ebc64344b..b9a29210c3 100644 --- a/src/SHAMapSync.cpp +++ b/src/SHAMapSync.cpp @@ -234,7 +234,11 @@ bool SHAMap::addKnownNode(const SHAMapNode& node, const std::vectorgotNode(node, hash, rawNode, newNode->isLeaf()); + { + Serializer s; + newNode->addRaw(s, STN_ARF_PREFIXED); + filter->gotNode(node, hash, s.peekData(), newNode->isLeaf()); + } mTNByID[*newNode] = newNode; if (!newNode->isLeaf()) From 6a9b5ccd7d738ebd294c65400ceafa1f484f8611 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 23:19:29 -0700 Subject: [PATCH 06/11] Support STN_ARF_UNKNOWN for contexts where the format of a node is not known. Format is auto-detected. --- src/SHAMap.h | 7 ++++--- src/SHAMapNodes.cpp | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/SHAMap.h b/src/SHAMap.h index 2e1af1dcaf..64eec583a8 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -157,11 +157,12 @@ public: SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq); // copy node from older tree SHAMapTreeNode(const SHAMapNode& nodeID, SHAMapItem::pointer item, TNType type, uint32 seq); - // raw node functions - SHAMapTreeNode(const SHAMapNode& id, const std::vector& contents, uint32 seq, int format); - +#define STN_ARF_UNKNOWN 0 #define STN_ARF_PREFIXED 1 #define STN_ARF_WIRE 2 + + // raw node functions + SHAMapTreeNode(const SHAMapNode& id, const std::vector& contents, uint32 seq, int format); void addRaw(Serializer &, int format); virtual bool isPopulated() const { return true; } diff --git a/src/SHAMapNodes.cpp b/src/SHAMapNodes.cpp index dbdc8ee109..3a9c682414 100644 --- a/src/SHAMapNodes.cpp +++ b/src/SHAMapNodes.cpp @@ -192,6 +192,14 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& node, SHAMapItem::pointer item, SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector& rawNode, uint32 seq, int format) : SHAMapNode(id), mSeq(seq), mType(tnERROR), mFullBelow(false) { + if (format == STN_ARF_UNKNOWN) + { + if ((rawNode.size() < 4) || (rawNode[0] < 10)) + format = STN_ARF_WIRE; + else + format = STN_ARF_PREFIXED; + } + if (format == STN_ARF_WIRE) { Serializer s(rawNode); From ce14aa81914db875e4e047e98b81c50c0987cfb3 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 23:19:56 -0700 Subject: [PATCH 07/11] Make 'addRootNode' support both prefixed and wire formats. Fix getMissingNodes to retrieve from the node store in prefixed format. --- src/SHAMapSync.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SHAMapSync.cpp b/src/SHAMapSync.cpp index b9a29210c3..538ebfdb35 100644 --- a/src/SHAMapSync.cpp +++ b/src/SHAMapSync.cpp @@ -58,7 +58,7 @@ void SHAMap::getMissingNodes(std::vector& nodeIDs, std::vector nodeData; if (filter->haveNode(childID, childHash, nodeData)) { - d = boost::make_shared(childID, nodeData, mSeq, STN_ARF_WIRE); + d = boost::make_shared(childID, nodeData, mSeq, STN_ARF_PREFIXED); if (childHash != d->getNodeHash()) { Log(lsERROR) << "Wrong hash from cached object"; @@ -133,7 +133,7 @@ bool SHAMap::addRootNode(const std::vector& rootNode) return true; } - SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_WIRE); + SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_UNKNOWN); if (!node) return false; #ifdef DEBUG @@ -165,7 +165,7 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector& return true; } - SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_WIRE); + SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_UNKNOWN); if (!node) return false; if (node->getNodeHash() != hash) From 0627ae22da7e8241a4d9903895ce017b840577d6 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 23:32:26 -0700 Subject: [PATCH 08/11] A better fix. Take the format as a parameter in addRootNode. --- src/LedgerAcquire.cpp | 4 ++-- src/SHAMap.h | 5 ++--- src/SHAMapNodes.cpp | 8 -------- src/SHAMapSync.cpp | 10 +++++----- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/LedgerAcquire.cpp b/src/LedgerAcquire.cpp index 7a0892b523..8049ddfbd0 100644 --- a/src/LedgerAcquire.cpp +++ b/src/LedgerAcquire.cpp @@ -326,7 +326,7 @@ bool LedgerAcquire::takeTxNode(const std::list& nodeIDs, { if (nodeIDit->isRoot()) { - if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait)) + if (!mLedger->peekTransactionMap()->addRootNode(mLedger->getTransHash(), *nodeDatait, STN_ARF_WIRE)) return false; } else if (!mLedger->peekTransactionMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)) @@ -358,7 +358,7 @@ bool LedgerAcquire::takeAsNode(const std::list& nodeIDs, { if (nodeIDit->isRoot()) { - if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), *nodeDatait)) + if (!mLedger->peekAccountStateMap()->addRootNode(mLedger->getAccountHash(), *nodeDatait, STN_ARF_WIRE)) return false; } else if (!mLedger->peekAccountStateMap()->addKnownNode(*nodeIDit, *nodeDatait, &tFilter)) diff --git a/src/SHAMap.h b/src/SHAMap.h index 64eec583a8..f0083dd277 100644 --- a/src/SHAMap.h +++ b/src/SHAMap.h @@ -157,7 +157,6 @@ public: SHAMapTreeNode(const SHAMapTreeNode& node, uint32 seq); // copy node from older tree SHAMapTreeNode(const SHAMapNode& nodeID, SHAMapItem::pointer item, TNType type, uint32 seq); -#define STN_ARF_UNKNOWN 0 #define STN_ARF_PREFIXED 1 #define STN_ARF_WIRE 2 @@ -324,8 +323,8 @@ public: SHAMapSyncFilter* filter); bool getNodeFat(const SHAMapNode& node, std::vector& nodeIDs, std::list >& rawNode, bool fatLeaves); - bool addRootNode(const uint256& hash, const std::vector& rootNode); - bool addRootNode(const std::vector& rootNode); + bool addRootNode(const uint256& hash, const std::vector& rootNode, int format); + bool addRootNode(const std::vector& rootNode, int format); bool addKnownNode(const SHAMapNode& nodeID, const std::vector& rawNode, SHAMapSyncFilter* filter); diff --git a/src/SHAMapNodes.cpp b/src/SHAMapNodes.cpp index 3a9c682414..dbdc8ee109 100644 --- a/src/SHAMapNodes.cpp +++ b/src/SHAMapNodes.cpp @@ -192,14 +192,6 @@ SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& node, SHAMapItem::pointer item, SHAMapTreeNode::SHAMapTreeNode(const SHAMapNode& id, const std::vector& rawNode, uint32 seq, int format) : SHAMapNode(id), mSeq(seq), mType(tnERROR), mFullBelow(false) { - if (format == STN_ARF_UNKNOWN) - { - if ((rawNode.size() < 4) || (rawNode[0] < 10)) - format = STN_ARF_WIRE; - else - format = STN_ARF_PREFIXED; - } - if (format == STN_ARF_WIRE) { Serializer s(rawNode); diff --git a/src/SHAMapSync.cpp b/src/SHAMapSync.cpp index 538ebfdb35..548008a68b 100644 --- a/src/SHAMapSync.cpp +++ b/src/SHAMapSync.cpp @@ -122,7 +122,7 @@ bool SHAMap::getNodeFat(const SHAMapNode& wanted, std::vector& nodeI return true; } -bool SHAMap::addRootNode(const std::vector& rootNode) +bool SHAMap::addRootNode(const std::vector& rootNode, int format) { boost::recursive_mutex::scoped_lock sl(mLock); @@ -133,7 +133,7 @@ bool SHAMap::addRootNode(const std::vector& rootNode) return true; } - SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_UNKNOWN); + SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, format); if (!node) return false; #ifdef DEBUG @@ -153,7 +153,7 @@ bool SHAMap::addRootNode(const std::vector& rootNode) return true; } -bool SHAMap::addRootNode(const uint256& hash, const std::vector& rootNode) +bool SHAMap::addRootNode(const uint256& hash, const std::vector& rootNode, int format) { boost::recursive_mutex::scoped_lock sl(mLock); @@ -165,7 +165,7 @@ bool SHAMap::addRootNode(const uint256& hash, const std::vector& return true; } - SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, STN_ARF_UNKNOWN); + SHAMapTreeNode::pointer node = boost::make_shared(SHAMapNode(), rootNode, 0, format); if (!node) return false; if (node->getNodeHash() != hash) @@ -447,7 +447,7 @@ BOOST_AUTO_TEST_CASE( SHAMapSync_test ) Log(lsFATAL) << "Didn't get root node " << gotNodes.size(); BOOST_FAIL("NodeSize"); } - if (!destination.addRootNode(*gotNodes.begin())) + if (!destination.addRootNode(*gotNodes.begin(), STN_ARF_WIRE)) { Log(lsFATAL) << "AddRootNode fails"; BOOST_FAIL("AddRootNode"); From c1d01348f88c6e8e1ba1bb6b7b6088e04b12b6d4 Mon Sep 17 00:00:00 2001 From: JoelKatz Date: Fri, 29 Jun 2012 23:33:12 -0700 Subject: [PATCH 09/11] Add root node in wire format. --- src/LedgerConsensus.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LedgerConsensus.cpp b/src/LedgerConsensus.cpp index 8da8844529..755b74c2c4 100644 --- a/src/LedgerConsensus.cpp +++ b/src/LedgerConsensus.cpp @@ -101,7 +101,7 @@ bool TransactionAcquire::takeNodes(const std::list& nodeIDs, Log(lsWARNING) << "Got root TXS node, already have it"; return false; } - if (!mMap->addRootNode(getHash(), *nodeDatait)) + if (!mMap->addRootNode(getHash(), *nodeDatait, STN_ARF_WIRE)) return false; else mHaveRoot = true; } From 64a869d6e81ce8d4229b0b0ec5a6e3c3c0f0b65f Mon Sep 17 00:00:00 2001 From: jed Date: Sat, 30 Jun 2012 05:58:45 -0700 Subject: [PATCH 10/11] less chatty --- src/ConnectionPool.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ConnectionPool.cpp b/src/ConnectionPool.cpp index 4d666ef221..6497ede5f6 100644 --- a/src/ConnectionPool.cpp +++ b/src/ConnectionPool.cpp @@ -544,7 +544,7 @@ void ConnectionPool::peerVerified(Peer::pointer peer) std::string strIpPort = str(boost::format("%s %d") % strIp % iPort); - Log(lsINFO) << str(boost::format("Pool: Scan: connected: %s %s %s (scanned)") % ADDRESS_SHARED(peer) % strIp % iPort); + //Log(lsINFO) << str(boost::format("Pool: Scan: connected: %s %s %s (scanned)") % ADDRESS_SHARED(peer) % strIp % iPort); if (peer->getNodePublic() == theApp->getWallet().getNodePublic()) { @@ -628,7 +628,7 @@ void ConnectionPool::scanRefresh() if (tpNow.is_not_a_date_time()) { - Log(lsINFO) << "Pool: Scan: stop."; + //Log(lsINFO) << "Pool: Scan: stop."; (void) mScanTimer.cancel(); } @@ -643,8 +643,8 @@ void ConnectionPool::scanRefresh() tpNext = tpNow + boost::posix_time::seconds(iInterval); - Log(lsINFO) << str(boost::format("Pool: Scan: Now: %s %s (next %s, delay=%d)") - % mScanIp % mScanPort % tpNext % (tpNext-tpNow).total_seconds()); + //Log(lsINFO) << str(boost::format("Pool: Scan: Now: %s %s (next %s, delay=%d)") + // % mScanIp % mScanPort % tpNext % (tpNext-tpNow).total_seconds()); iInterval *= 2; @@ -668,8 +668,8 @@ void ConnectionPool::scanRefresh() } else { - Log(lsINFO) << str(boost::format("Pool: Scan: Next: %s (next %s, delay=%d)") - % strIpPort % tpNext % (tpNext-tpNow).total_seconds()); + //Log(lsINFO) << str(boost::format("Pool: Scan: Next: %s (next %s, delay=%d)") + // % strIpPort % tpNext % (tpNext-tpNow).total_seconds()); mScanTimer.expires_at(tpNext); mScanTimer.async_wait(boost::bind(&ConnectionPool::scanHandler, this, _1)); From 8f7c984ef764c0379143a45bbb421c55e7a199a8 Mon Sep 17 00:00:00 2001 From: jed Date: Sat, 30 Jun 2012 06:52:05 -0700 Subject: [PATCH 11/11] don't validate if ledger # is too low --- src/Config.cpp | 4 ++++ src/Config.h | 3 +++ src/NetworkOPs.cpp | 13 +++++++++---- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Config.cpp b/src/Config.cpp index 6e4b67ce87..0ca3ec46cd 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -121,6 +121,7 @@ void Config::setup(const std::string& strConf) // a new ledger every minute LEDGER_SECONDS = 60; + LEDGER_CREATOR = false; RPC_USER = "admin"; RPC_PASSWORD = "pass"; @@ -201,6 +202,9 @@ void Config::load() if (sectionSingleB(secConfig, SECTION_RPC_PORT, strTemp)) RPC_PORT = boost::lexical_cast(strTemp); + if (sectionSingleB(secConfig, "ledger_creator" , strTemp)) + LEDGER_CREATOR = boost::lexical_cast(strTemp); + if (sectionSingleB(secConfig, SECTION_RPC_ALLOW_REMOTE, strTemp)) RPC_ALLOW_REMOTE = boost::lexical_cast(strTemp); diff --git a/src/Config.h b/src/Config.h index 6a88d13cfe..7c900523f5 100644 --- a/src/Config.h +++ b/src/Config.h @@ -54,12 +54,15 @@ public: std::vector VALIDATORS; // Validators from newcoind.cfg. std::vector IPS; // Peer IPs from newcoind.cfg. + + // Network parameters int NETWORK_START_TIME; // The Unix time we start ledger 0. int TRANSACTION_FEE_BASE; int LEDGER_SECONDS; int LEDGER_PROPOSAL_DELAY_SECONDS; int LEDGER_AVALANCHE_SECONDS; + bool LEDGER_CREATOR; // should be false unless we are starting a new ledger // Note: The following parameters do not relate to the UNL or trust at all int NETWORK_QUORUM; // Minimum number of nodes to consider the network present diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index c29da13f69..4d3485c479 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -369,10 +369,15 @@ bool NetworkOPs::checkLastClosedLedger(const std::vector& peerLis } Ledger::pointer ourClosed = mLedgerMaster->getClosedLedger(); - uint256 closedLedger = ourClosed->getHash(); - ValidationCount& ourVC = ledgers[closedLedger]; - ++ourVC.nodesUsing; - ourVC.highNode = theApp->getWallet().getNodePublic(); + uint256 closedLedger=0; + if(theConfig.LEDGER_CREATOR || ourClosed->getLedgerSeq() > 100) + { + closedLedger = ourClosed->getHash(); + ValidationCount& ourVC = ledgers[closedLedger]; + ++ourVC.nodesUsing; + ourVC.highNode = theApp->getWallet().getNodePublic(); + } + for (std::vector::const_iterator it = peerList.begin(), end = peerList.end(); it != end; ++it) {