| 237 | } |
| 238 | |
| 239 | WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransaction& transaction, const CCoinControl* coinControl, bool sign) |
| 240 | { |
| 241 | CAmount total = 0; |
| 242 | bool fSubtractFeeFromAmount = false; |
| 243 | QList<SendCoinsRecipient> recipients = transaction.getRecipients(); |
| 244 | std::vector<CRecipient> vecSend; |
| 245 | |
| 246 | if (recipients.empty()) { |
| 247 | return OK; |
| 248 | } |
| 249 | |
| 250 | if (isUnlockStakingOnly()) { |
| 251 | return StakingOnlyUnlocked; |
| 252 | } |
| 253 | |
| 254 | QSet<QString> setAddress; // Used to detect duplicates |
| 255 | int nAddresses = 0; |
| 256 | |
| 257 | // Pre-check input data for validity |
| 258 | Q_FOREACH (const SendCoinsRecipient& rcp, recipients) { |
| 259 | if (rcp.fSubtractFeeFromAmount) |
| 260 | fSubtractFeeFromAmount = true; |
| 261 | if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... |
| 262 | CAmount subtotal = 0; |
| 263 | const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); |
| 264 | for (int i = 0; i < details.outputs_size(); i++) { |
| 265 | const payments::Output& out = details.outputs(i); |
| 266 | if (out.amount() <= 0) continue; |
| 267 | subtotal += out.amount(); |
| 268 | const unsigned char* scriptStr = (const unsigned char*)out.script().data(); |
| 269 | CScript scriptPubKey(scriptStr, scriptStr + out.script().size()); |
| 270 | CAmount nAmount = out.amount(); |
| 271 | CRecipient recipient = {scriptPubKey, nAmount, rcp.fSubtractFeeFromAmount}; |
| 272 | vecSend.push_back(recipient); |
| 273 | } |
| 274 | if (subtotal <= 0) { |
| 275 | return InvalidAmount; |
| 276 | } |
| 277 | total += subtotal; |
| 278 | } else { // User-entered lux address / amount: |
| 279 | if (!validateAddress(rcp.address)) { |
| 280 | return InvalidAddress; |
| 281 | } |
| 282 | if (rcp.amount <= 0) { |
| 283 | return InvalidAmount; |
| 284 | } |
| 285 | setAddress.insert(rcp.address); |
| 286 | ++nAddresses; |
| 287 | |
| 288 | CScript scriptPubKey = GetScriptForDestination(DecodeDestination(rcp.address.toStdString())); |
| 289 | CRecipient recipient = {scriptPubKey, rcp.amount, rcp.fSubtractFeeFromAmount}; |
| 290 | vecSend.push_back(recipient); |
| 291 | |
| 292 | total += rcp.amount; |
| 293 | } |
| 294 | } |
| 295 | if (setAddress.size() != nAddresses) { |
| 296 | return DuplicateAddress; |
no test coverage detected