From a813b0cc9d854cefdcfc51faac393ff62140b6de Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 11 May 2013 23:30:00 -0700 Subject: [PATCH] Add TransactionErr files. --- src/cpp/TransactionErr.cpp | 126 ++++++++++++++++++++++++++++++ src/cpp/TransactionErr.h | 153 +++++++++++++++++++++++++++++++++++++ 2 files changed, 279 insertions(+) create mode 100644 src/cpp/TransactionErr.cpp create mode 100644 src/cpp/TransactionErr.h diff --git a/src/cpp/TransactionErr.cpp b/src/cpp/TransactionErr.cpp new file mode 100644 index 00000000..1e03226f --- /dev/null +++ b/src/cpp/TransactionErr.cpp @@ -0,0 +1,126 @@ +#include "TransactionErr.h" +#include "utils.h" + +bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman) +{ + static struct { + TER terCode; + const char* cpToken; + const char* cpHuman; + } transResultInfoA[] = { + { tecCLAIM, "tecCLAIM", "Fee claimed. Sequence used. No action." }, + { tecDIR_FULL, "tecDIR_FULL", "Can not add entry to full directory." }, + { tecFAILED_PROCESSING, "tecFAILED_PROCESSING", "Failed to correctly process transaction." }, + { tecINSUF_RESERVE_LINE, "tecINSUF_RESERVE_LINE", "Insufficient reserve to add trust line." }, + { tecINSUF_RESERVE_OFFER, "tecINSUF_RESERVE_OFFER", "Insufficient reserve to create offer." }, + { tecNO_DST, "tecNO_DST", "Destination does not exist. Send XRP to create it." }, + { tecNO_DST_INSUF_XRP, "tecNO_DST_INSUF_XRP", "Destination does not exist. Too little XRP sent to create it." }, + { tecNO_LINE_INSUF_RESERVE, "tecNO_LINE_INSUF_RESERVE", "No such line. Too little reserve to create it." }, + { tecNO_LINE_REDUNDANT, "tecNO_LINE_REDUNDANT", "Can't set non-existant line to default." }, + { tecPATH_DRY, "tecPATH_DRY", "Path could not send partial amount." }, + { tecPATH_PARTIAL, "tecPATH_PARTIAL", "Path could not send full amount." }, + + { tecUNFUNDED, "tecUNFUNDED", "One of _ADD, _OFFER, or _SEND. Deprecated." }, + { tecUNFUNDED_ADD, "tecUNFUNDED_ADD", "Insufficient XRP balance for WalletAdd." }, + { tecUNFUNDED_OFFER, "tecUNFUNDED_OFFER", "Insufficient balance to fund created offer." }, + { tecUNFUNDED_PAYMENT, "tecUNFUNDED_PAYMENT", "Insufficient XRP balance to send." }, + + { tefFAILURE, "tefFAILURE", "Failed to apply." }, + { tefALREADY, "tefALREADY", "The exact transaction was already in this ledger." }, + { tefBAD_ADD_AUTH, "tefBAD_ADD_AUTH", "Not authorized to add account." }, + { tefBAD_AUTH, "tefBAD_AUTH", "Transaction's public key is not authorized." }, + { tefBAD_CLAIM_ID, "tefBAD_CLAIM_ID", "Malformed: Bad claim id." }, + { tefBAD_GEN_AUTH, "tefBAD_GEN_AUTH", "Not authorized to claim generator." }, + { tefBAD_LEDGER, "tefBAD_LEDGER", "Ledger in unexpected state." }, + { tefCLAIMED, "tefCLAIMED", "Can not claim a previously claimed account." }, + { tefCREATED, "tefCREATED", "Can't add an already created account." }, + { tefDST_TAG_NEEDED, "tefDST_TAG_NEEDED", "Destination tag required." }, + { tefEXCEPTION, "tefEXCEPTION", "Unexpected program state." }, + { tefGEN_IN_USE, "tefGEN_IN_USE", "Generator already in use." }, + { tefINTERNAL, "tefINTERNAL", "Internal error." }, + { tefNO_AUTH_REQUIRED, "tefNO_AUTH_REQUIRED", "Auth is not required." }, + { tefPAST_SEQ, "tefPAST_SEQ", "This sequence number has already past." }, + + { telLOCAL_ERROR, "telLOCAL_ERROR", "Local failure." }, + { telBAD_DOMAIN, "telBAD_DOMAIN", "Domain too long." }, + { telBAD_PATH_COUNT, "telBAD_PATH_COUNT", "Malformed: Too many paths." }, + { telBAD_PUBLIC_KEY, "telBAD_PUBLIC_KEY", "Public key too long." }, + { telFAILED_PROCESSING, "telFAILED_PROCESSING", "Failed to correctly process transaction." }, + { telINSUF_FEE_P, "telINSUF_FEE_P", "Fee insufficient." }, + { telNO_DST_PARTIAL, "telNO_DST_PARTIAL", "Partial payment to create account not allowed." }, + + { temMALFORMED, "temMALFORMED", "Malformed transaction." }, + { temBAD_AMOUNT, "temBAD_AMOUNT", "Can only send positive amounts." }, + { temBAD_AUTH_MASTER, "temBAD_AUTH_MASTER", "Auth for unclaimed account needs correct master key." }, + { temBAD_CURRENCY, "temBAD_CURRENCY", "Malformed: Bad currency." }, + { temBAD_FEE, "temBAD_FEE", "Invalid fee, negative or not XRP." }, + { temBAD_EXPIRATION, "temBAD_EXPIRATION", "Malformed: Bad expiration." }, + { temBAD_ISSUER, "temBAD_ISSUER", "Malformed: Bad issuer." }, + { temBAD_LIMIT, "temBAD_LIMIT", "Limits must be non-negative." }, + { temBAD_OFFER, "temBAD_OFFER", "Malformed: Bad offer." }, + { temBAD_PATH, "temBAD_PATH", "Malformed: Bad path." }, + { temBAD_PATH_LOOP, "temBAD_PATH_LOOP", "Malformed: Loop in path." }, + { temBAD_PUBLISH, "temBAD_PUBLISH", "Malformed: Bad publish." }, + { temBAD_SIGNATURE, "temBAD_SIGNATURE", "Malformed: Bad signature." }, + { temBAD_SRC_ACCOUNT, "temBAD_SRC_ACCOUNT", "Malformed: Bad source account." }, + { temBAD_TRANSFER_RATE, "temBAD_TRANSFER_RATE", "Malformed: Transfer rate must be >= 1.0" }, + { temBAD_SEQUENCE, "temBAD_SEQUENCE", "Malformed: Sequence is not in the past." }, + { temBAD_SEND_XRP_LIMIT, "temBAD_SEND_XRP_LIMIT", "Malformed: Limit quality is not allowed for XRP to XRP." }, + { temBAD_SEND_XRP_MAX, "temBAD_SEND_XRP_MAX", "Malformed: Send max is not allowed for XRP to XRP." }, + { temBAD_SEND_XRP_NO_DIRECT, "temBAD_SEND_XRP_NO_DIRECT", "Malformed: No Ripple direct is not allowed for XRP to XRP." }, + { temBAD_SEND_XRP_PARTIAL, "temBAD_SEND_XRP_PARTIAL", "Malformed: Partial payment is not allowed for XRP to XRP." }, + { temBAD_SEND_XRP_PATHS, "temBAD_SEND_XRP_PATHS", "Malformed: Paths are not allowed for XRP to XRP." }, + { temDST_IS_SRC, "temDST_IS_SRC", "Destination may not be source." }, + { temDST_NEEDED, "temDST_NEEDED", "Destination not specified." }, + { temINVALID, "temINVALID", "The transaction is ill-formed." }, + { temINVALID_FLAG, "temINVALID_FLAG", "The transaction has an invalid flag." }, + { temREDUNDANT, "temREDUNDANT", "Sends same currency to self." }, + { temREDUNDANT_SEND_MAX, "temREDUNDANT_SEND_MAX", "Send max is redundant." }, + { temRIPPLE_EMPTY, "temRIPPLE_EMPTY", "PathSet with no paths." }, + { temUNCERTAIN, "temUNCERTAIN", "In process of determining result. Never returned." }, + { temUNKNOWN, "temUNKNOWN", "The transactions requires logic not implemented yet." }, + + { terRETRY, "terRETRY", "Retry transaction." }, + { terFUNDS_SPENT, "terFUNDS_SPENT", "Can't set password, password set funds already spent." }, + { terINSUF_FEE_B, "terINSUF_FEE_B", "Account balance can't pay fee." }, + { terLAST, "terLAST", "Process last." }, + { terNO_ACCOUNT, "terNO_ACCOUNT", "The source account does not exist." }, + { terNO_AUTH, "terNO_AUTH", "Not authorized to hold IOUs." }, + { terNO_LINE, "terNO_LINE", "No such line." }, + { terPRE_SEQ, "terPRE_SEQ", "Missing/inapplicable prior transaction." }, + { terOWNERS, "terOWNERS", "Non-zero owner count." }, + + { tesSUCCESS, "tesSUCCESS", "The transaction was applied." }, + }; + + int iIndex = NUMBER(transResultInfoA); + + while (iIndex-- && transResultInfoA[iIndex].terCode != terCode) + ; + + if (iIndex >= 0) + { + strToken = transResultInfoA[iIndex].cpToken; + strHuman = transResultInfoA[iIndex].cpHuman; + } + + return iIndex >= 0; +} + +std::string transToken(TER terCode) +{ + std::string strToken; + std::string strHuman; + + return transResultInfo(terCode, strToken, strHuman) ? strToken : "-"; +} + +std::string transHuman(TER terCode) +{ + std::string strToken; + std::string strHuman; + + return transResultInfo(terCode, strToken, strHuman) ? strHuman : "-"; +} + +// vim:ts=4 diff --git a/src/cpp/TransactionErr.h b/src/cpp/TransactionErr.h new file mode 100644 index 00000000..2e18d5f1 --- /dev/null +++ b/src/cpp/TransactionErr.h @@ -0,0 +1,153 @@ +#ifndef _TRANSACTION_ERR_ +#define _TRANSACTION_ERR_ + +#include + +enum TER // aka TransactionEngineResult +{ + // Note: Range is stable. Exact numbers are currently unstable. Use tokens. + + // -399 .. -300: L Local error (transaction fee inadequate, exceeds local limit) + // Only valid during non-consensus processing. + // Implications: + // - Not forwarded + // - No fee check + telLOCAL_ERROR = -399, + telBAD_DOMAIN, + telBAD_PATH_COUNT, + telBAD_PUBLIC_KEY, + telFAILED_PROCESSING, + telINSUF_FEE_P, + telNO_DST_PARTIAL, + + // -299 .. -200: M Malformed (bad signature) + // Causes: + // - Transaction corrupt. + // Implications: + // - Not applied + // - Not forwarded + // - Reject + // - Can not succeed in any imagined ledger. + temMALFORMED = -299, + temBAD_AMOUNT, + temBAD_AUTH_MASTER, + temBAD_CURRENCY, + temBAD_FEE, + temBAD_EXPIRATION, + temBAD_ISSUER, + temBAD_LIMIT, + temBAD_OFFER, + temBAD_PATH, + temBAD_PATH_LOOP, + temBAD_PUBLISH, + temBAD_TRANSFER_RATE, + temBAD_SEND_XRP_LIMIT, + temBAD_SEND_XRP_MAX, + temBAD_SEND_XRP_NO_DIRECT, + temBAD_SEND_XRP_PARTIAL, + temBAD_SEND_XRP_PATHS, + temBAD_SIGNATURE, + temBAD_SRC_ACCOUNT, + temBAD_SEQUENCE, + temDST_IS_SRC, + temDST_NEEDED, + temINVALID, + temINVALID_FLAG, + temREDUNDANT, + temREDUNDANT_SEND_MAX, + temRIPPLE_EMPTY, + temUNCERTAIN, // An intermediate result used internally, should never be returned. + temUNKNOWN, + + // -199 .. -100: F Failure (sequence number previously used) + // Causes: + // - Transaction cannot succeed because of ledger state. + // - Unexpected ledger state. + // - C++ exception. + // Implications: + // - Not applied + // - Not forwarded + // - Could succeed in an imagined ledger. + tefFAILURE = -199, + tefALREADY, + tefBAD_ADD_AUTH, + tefBAD_AUTH, + tefBAD_CLAIM_ID, + tefBAD_GEN_AUTH, + tefBAD_LEDGER, + tefCLAIMED, + tefCREATED, + tefDST_TAG_NEEDED, + tefEXCEPTION, + tefGEN_IN_USE, + tefINTERNAL, + tefNO_AUTH_REQUIRED, // Can't set auth if auth is not required. + tefPAST_SEQ, + + // -99 .. -1: R Retry (sequence too high, no funds for txn fee, originating account non-existent) + // Causes: + // - Prior application of another, possibly non-existant, another transaction could allow this transaction to succeed. + // Implications: + // - Not applied + // - Not forwarded + // - Might succeed later + // - Hold + // - Makes hole in sequence which jams transactions. + terRETRY = -99, + terFUNDS_SPENT, // This is a free transaction, therefore don't burden network. + terINSUF_FEE_B, // Can't pay fee, therefore don't burden network. + terNO_ACCOUNT, // Can't pay fee, therefore don't burden network. + terNO_AUTH, // Not authorized to hold IOUs. + terNO_LINE, // Internal flag. + terOWNERS, // Can't succeed with non-zero owner count. + terPRE_SEQ, // Can't pay fee, no point in forwarding, therefore don't burden network. + terLAST, // Process after all other transactions + + // 0: S Success (success) + // Causes: + // - Success. + // Implications: + // - Applied + // - Forwarded + tesSUCCESS = 0, + + // 100 .. 129 C Claim fee only (ripple transaction with no good paths, pay to non-existent account, no path) + // Causes: + // - Success, but does not achieve optimal result. + // - Invalid transaction or no effect, but claim fee to use the sequence number. + // Implications: + // - Applied + // - Forwarded + // Only allowed as a return code of appliedTransaction when !tapRetry. Otherwise, treated as terRETRY. + // + // DO NOT CHANGE THESE NUMBERS: They appear in ledger meta data. + tecCLAIM = 100, + tecPATH_PARTIAL = 101, + tecUNFUNDED_ADD = 102, + tecUNFUNDED_OFFER = 103, + tecUNFUNDED_PAYMENT = 104, + tecFAILED_PROCESSING = 105, + tecDIR_FULL = 121, + tecINSUF_RESERVE_LINE = 122, + tecINSUF_RESERVE_OFFER = 123, + tecNO_DST = 124, + tecNO_DST_INSUF_XRP = 125, + tecNO_LINE_INSUF_RESERVE = 126, + tecNO_LINE_REDUNDANT = 127, + tecPATH_DRY = 128, + tecUNFUNDED = 129, // Deprecated, old ambiguous unfunded. +}; + +#define isTelLocal(x) ((x) >= telLOCAL_ERROR && (x) < temMALFORMED) +#define isTemMalformed(x) ((x) >= temMALFORMED && (x) < tefFAILURE) +#define isTefFailure(x) ((x) >= tefFAILURE && (x) < terRETRY) +#define isTerRetry(x) ((x) >= terRETRY && (x) < tesSUCCESS) +#define isTesSuccess(x) ((x) == tesSUCCESS) +#define isTecClaim(x) ((x) >= tecCLAIM) + +bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman); +std::string transToken(TER terCode); +std::string transHuman(TER terCode); + +#endif +// vim:ts=4