diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index 71bd3c0e9..8af9d7712 100755 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -274,6 +274,8 @@ public: // Default transaction version. static const int32_t CURRENT_VERSION=2; + static const int32_t MAX_FLO_DATA_SIZE=1040; + // Changing the default transaction version requires a two step process: first // adapting relay policy by bumping MAX_STANDARD_VERSION, and then later date // bumping the default CURRENT_VERSION at which point both CURRENT_VERSION and diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index bbae830f4..b3235bbba 100755 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -19,6 +19,7 @@ #include "base58.h" #include "chainparams.h" #include "wallet/coincontrol.h" +#include "primitives/transaction.h" // FloData size limits #include "validation.h" // mempool and minRelayTxFee #include "ui_interface.h" #include "txmempool.h" @@ -133,6 +134,8 @@ SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, QWidget *p ui->customFee->setValue(settings.value("nTransactionFee").toLongLong()); ui->checkBoxMinimumFee->setChecked(settings.value("fPayOnlyMinFee").toBool()); minimizeFeeSection(settings.value("fFeeSectionMinimized").toBool()); + + ui->floData->setMaxLength(CTransaction::MAX_FLO_DATA_SIZE-5); // room for "text:" prefix } void SendCoinsDialog::setClientModel(ClientModel *_clientModel) diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1fb91e343..021454bce 100755 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -353,6 +353,10 @@ UniValue createrawtransaction(const JSONRPCRequest& request) rawTx.strFloData = request.params[4].get_str(); } + if (rawTx.strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Flo Data too large"); + } + for (unsigned int idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; const UniValue& o = input.get_obj(); @@ -612,6 +616,9 @@ UniValue combinerawtransaction(const JSONRPCRequest& request) // starts as a clone of the rawtx: CMutableTransaction mergedTx(txVariants[0]); mergedTx.strFloData = strFloData; + if (mergedTx.strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + throw JSONRPCError(RPC_VERIFY_ERROR, "Flo Data too large"); + } // Fetch previous transactions (inputs): CCoinsView viewDummy; @@ -935,6 +942,11 @@ UniValue sendrawtransaction(const JSONRPCRequest& request) CMutableTransaction mtx; if (!DecodeHexTx(mtx, request.params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); + + if (mtx.strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + throw JSONRPCError(RPC_TRANSACTION_ERROR, "Flo Data too large"); + } + CTransactionRef tx(MakeTransactionRef(std::move(mtx))); const uint256& hashTx = tx->GetHash(); diff --git a/src/validation.cpp b/src/validation.cpp index 0a3bc343d..345d6f2cb 100755 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -461,14 +461,8 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool return state.DoS(0, false, REJECT_NONSTANDARD, "no-witness-yet", true); } - if (tx.nVersion >= 2) { - int maxCommentLen = 528; - if (witnessEnabled) { - maxCommentLen = 1040; - } - if (tx.strFloData.length() > maxCommentLen) { - return state.DoS(0, false, REJECT_INVALID, "flo-data-too-large"); - } + if (tx.strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + return state.DoS(0, false, REJECT_INVALID, "flo-data-too-large"); } // Rather not work on nonstandard transactions (unless -testnet/-regtest) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 15965afb6..15f2e9709 100755 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -379,6 +379,10 @@ static void SendMoney(CWallet * const pwallet, const CTxDestination &address, CA { CAmount curBalance = pwallet->GetBalance(); + if (strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Flo data too long"); + } + // Check amount if (nValue <= 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); @@ -1065,6 +1069,10 @@ UniValue sendmany(const JSONRPCRequest& request) if (totalAmount > nBalance) throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); + if (strFloData.length() > CTransaction::MAX_FLO_DATA_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Flo data too long"); + } + // Send CReserveKey keyChange(pwallet); CAmount nFeeRequired = 0;