From 308ca21b977b6be5d548e91b11c41d9103c70527 Mon Sep 17 00:00:00 2001 From: Arthur Britto Date: Sat, 19 Jan 2013 14:15:56 -0800 Subject: [PATCH] Make tecUNFUNDED more specific and fix WalletAdd. --- src/cpp/ripple/OfferCreateTransactor.cpp | 2 +- src/cpp/ripple/PaymentTransactor.cpp | 2 +- src/cpp/ripple/TransactionErr.cpp | 5 ++++- src/cpp/ripple/TransactionErr.h | 5 ++++- src/cpp/ripple/WalletAddTransactor.cpp | 26 ++++++++++++++---------- test/offer-test.js | 2 +- test/reserve-test.js | 2 +- 7 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/cpp/ripple/OfferCreateTransactor.cpp b/src/cpp/ripple/OfferCreateTransactor.cpp index 05a469ebfa..546f0c75ad 100644 --- a/src/cpp/ripple/OfferCreateTransactor.cpp +++ b/src/cpp/ripple/OfferCreateTransactor.cpp @@ -340,7 +340,7 @@ TER OfferCreateTransactor::doApply() { cLog(lsWARNING) << "OfferCreate: delay: Offers must be at least partially funded."; - terResult = tecUNFUNDED; + terResult = tecUNFUNDED_OFFER; } if (tesSUCCESS == terResult && !saTakerPays.isNative()) diff --git a/src/cpp/ripple/PaymentTransactor.cpp b/src/cpp/ripple/PaymentTransactor.cpp index 74e3763932..8133280527 100644 --- a/src/cpp/ripple/PaymentTransactor.cpp +++ b/src/cpp/ripple/PaymentTransactor.cpp @@ -161,7 +161,7 @@ TER PaymentTransactor::doApply() cLog(lsINFO) << boost::str(boost::format("Payment: Delay transaction: Insufficient funds: %s / %s (%d)") % saSrcXRPBalance.getText() % (saDstAmount + uReserve).getText() % uReserve); - terResult = tecUNFUNDED; + terResult = tecUNFUNDED_PAYMENT; } else { diff --git a/src/cpp/ripple/TransactionErr.cpp b/src/cpp/ripple/TransactionErr.cpp index d9a55901f2..a10f4c97d8 100644 --- a/src/cpp/ripple/TransactionErr.cpp +++ b/src/cpp/ripple/TransactionErr.cpp @@ -19,7 +19,10 @@ bool transResultInfo(TER terCode, std::string& strToken, std::string& strHuman) { tecPATH_DRY, "tecPATH_DRY", "Path could not send partial amount." }, { tecPATH_PARTIAL, "tecPATH_PARTIAL", "Path could not send full amount." }, - { tecUNFUNDED, "tecUNFUNDED", "Source account had insufficient balance for transaction." }, + { 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." }, diff --git a/src/cpp/ripple/TransactionErr.h b/src/cpp/ripple/TransactionErr.h index e87ac3ead9..525f03645f 100644 --- a/src/cpp/ripple/TransactionErr.h +++ b/src/cpp/ripple/TransactionErr.h @@ -111,6 +111,9 @@ enum TER // aka TransactionEngineResult // 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, tecDIR_FULL = 121, tecINSUF_RESERVE_LINE = 122, tecINSUF_RESERVE_OFFER = 123, @@ -119,7 +122,7 @@ enum TER // aka TransactionEngineResult tecNO_LINE_INSUF_RESERVE = 126, tecNO_LINE_REDUNDANT = 127, tecPATH_DRY = 128, - tecUNFUNDED = 129, + tecUNFUNDED = 129, // Old ambigous unfunded. }; #define isTelLocal(x) ((x) >= telLOCAL_ERROR && (x) < temMALFORMED) diff --git a/src/cpp/ripple/WalletAddTransactor.cpp b/src/cpp/ripple/WalletAddTransactor.cpp index 05a06dc1c4..5dd9350074 100644 --- a/src/cpp/ripple/WalletAddTransactor.cpp +++ b/src/cpp/ripple/WalletAddTransactor.cpp @@ -38,29 +38,33 @@ TER WalletAddTransactor::doApply() return tefCREATED; } - STAmount saAmount = mTxn.getFieldAmount(sfAmount); - STAmount saSrcBalance = mTxnAccount->getFieldAmount(sfBalance); + // Direct XRP payment. - if (saSrcBalance < saAmount) + STAmount saDstAmount = mTxn.getFieldAmount(sfAmount); + const STAmount saSrcBalance = mTxnAccount->getFieldAmount(sfBalance); + const uint32 uOwnerCount = mTxnAccount->getFieldU32(sfOwnerCount); + const uint64 uReserve = mEngine->getLedger()->getReserve(uOwnerCount); + STAmount saPaid = mTxn.getTransactionFee(); + + // Make sure have enough reserve to send. Allow final spend to use reserve for fee. + if (saSrcBalance + saPaid < saDstAmount + uReserve) // Reserve is not scaled by fee. { - std::cerr - << boost::str(boost::format("WalletAdd: Delay transaction: insufficient balance: balance=%s amount=%s") - % saSrcBalance.getText() - % saAmount.getText()) - << std::endl; + // Vote no. However, transaction might succeed, if applied in a different order. + cLog(lsINFO) << boost::str(boost::format("WalletAdd: Delay transaction: Insufficient funds: %s / %s (%d)") + % saSrcBalance.getText() % (saDstAmount + uReserve).getText() % uReserve); - return tecUNFUNDED; + return tecUNFUNDED_ADD; } // Deduct initial balance from source account. - mTxnAccount->setFieldAmount(sfBalance, saSrcBalance-saAmount); + mTxnAccount->setFieldAmount(sfBalance, saSrcBalance-saDstAmount); // Create the account. sleDst = mEngine->entryCreate(ltACCOUNT_ROOT, Ledger::getAccountRootIndex(uDstAccountID)); sleDst->setFieldAccount(sfAccount, uDstAccountID); sleDst->setFieldU32(sfSequence, 1); - sleDst->setFieldAmount(sfBalance, saAmount); + sleDst->setFieldAmount(sfBalance, saDstAmount); sleDst->setFieldAccount(sfRegularKey, uAuthKeyID); std::cerr << "WalletAdd<" << std::endl; diff --git a/test/offer-test.js b/test/offer-test.js index 1e347fd13d..09d6aeb287 100644 --- a/test/offer-test.js +++ b/test/offer-test.js @@ -517,7 +517,7 @@ buster.testCase("Offer tests", { .offer_create("bob", "50/USD/alice", "200/EUR/carol") .on('proposed', function (m) { // console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); - callback(m.result !== 'tecUNFUNDED'); + callback(m.result !== 'tecUNFUNDED_OFFER'); seq = m.tx_json.Sequence; }) diff --git a/test/reserve-test.js b/test/reserve-test.js index 50c5d4e74b..995345ccca 100644 --- a/test/reserve-test.js +++ b/test/reserve-test.js @@ -481,7 +481,7 @@ buster.testCase("Reserve", { .offer_create("bob", "50/USD/alice", "200/EUR/carol") .on('proposed', function (m) { // console.log("PROPOSED: offer_create: %s", JSON.stringify(m)); - callback(m.result !== 'tecUNFUNDED'); + callback(m.result !== 'tecUNFUNDED_OFFER'); seq = m.tx_json.Sequence; })