diff --git a/src/NetworkOPs.cpp b/src/NetworkOPs.cpp index 5195ab28d9..c29da13f69 100644 --- a/src/NetworkOPs.cpp +++ b/src/NetworkOPs.cpp @@ -767,17 +767,31 @@ 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 jvObj(Json::objectValue); + std::string strToken; + std::string strHuman; + + transResultInfo(terResult, strToken, strHuman); + + jvObj["type"] = strType; + jvObj["transaction"] = stTxn.getJson(0); + jvObj["transaction"]["inLedger"] = iSeq; + jvObj["transaction"]["status"] = strStatus; + jvObj["result"] = strToken; + 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,19 +824,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); - - jvObj["type"] = "accountTransactionProposed"; - jvObj["seq"] = lpCurrent->getLedgerSeq(); - jvObj["accounts"] = jvAccounts; - jvObj["transaction"] = stTxn.getJson(0); + 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); 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,