comparison src/rpcrawtransaction.cpp @ 3588:7eb24f8cf224 draft

Document RPC error codes Replace all "magic values" in RPCError(...) by constants.
author Wladimir J. van der Laan <laanwj@gmail.com>
date Thu, 04 Oct 2012 09:34:44 +0200
parents 75fad4c8df94
children abd3935e67df
comparison
equal deleted inserted replaced
3581:683f60758d5f 3588:7eb24f8cf224
117 fVerbose = (params[1].get_int() != 0); 117 fVerbose = (params[1].get_int() != 0);
118 118
119 CTransaction tx; 119 CTransaction tx;
120 uint256 hashBlock = 0; 120 uint256 hashBlock = 0;
121 if (!GetTransaction(hash, tx, hashBlock)) 121 if (!GetTransaction(hash, tx, hashBlock))
122 throw JSONRPCError(-5, "No information available about transaction"); 122 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
123 123
124 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); 124 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
125 ssTx << tx; 125 ssTx << tx;
126 string strHex = HexStr(ssTx.begin(), ssTx.end()); 126 string strHex = HexStr(ssTx.begin(), ssTx.end());
127 127
161 Array inputs = params[2].get_array(); 161 Array inputs = params[2].get_array();
162 BOOST_FOREACH(Value& input, inputs) 162 BOOST_FOREACH(Value& input, inputs)
163 { 163 {
164 CBitcoinAddress address(input.get_str()); 164 CBitcoinAddress address(input.get_str());
165 if (!address.IsValid()) 165 if (!address.IsValid())
166 throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+input.get_str()); 166 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str());
167 if (setAddress.count(address)) 167 if (setAddress.count(address))
168 throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+input.get_str()); 168 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
169 setAddress.insert(address); 169 setAddress.insert(address);
170 } 170 }
171 } 171 }
172 172
173 Array results; 173 Array results;
225 { 225 {
226 const Object& o = input.get_obj(); 226 const Object& o = input.get_obj();
227 227
228 const Value& txid_v = find_value(o, "txid"); 228 const Value& txid_v = find_value(o, "txid");
229 if (txid_v.type() != str_type) 229 if (txid_v.type() != str_type)
230 throw JSONRPCError(-8, "Invalid parameter, missing txid key"); 230 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key");
231 string txid = txid_v.get_str(); 231 string txid = txid_v.get_str();
232 if (!IsHex(txid)) 232 if (!IsHex(txid))
233 throw JSONRPCError(-8, "Invalid parameter, expected hex txid"); 233 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
234 234
235 const Value& vout_v = find_value(o, "vout"); 235 const Value& vout_v = find_value(o, "vout");
236 if (vout_v.type() != int_type) 236 if (vout_v.type() != int_type)
237 throw JSONRPCError(-8, "Invalid parameter, missing vout key"); 237 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
238 int nOutput = vout_v.get_int(); 238 int nOutput = vout_v.get_int();
239 if (nOutput < 0) 239 if (nOutput < 0)
240 throw JSONRPCError(-8, "Invalid parameter, vout must be positive"); 240 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
241 241
242 CTxIn in(COutPoint(uint256(txid), nOutput)); 242 CTxIn in(COutPoint(uint256(txid), nOutput));
243 rawTx.vin.push_back(in); 243 rawTx.vin.push_back(in);
244 } 244 }
245 245
246 set<CBitcoinAddress> setAddress; 246 set<CBitcoinAddress> setAddress;
247 BOOST_FOREACH(const Pair& s, sendTo) 247 BOOST_FOREACH(const Pair& s, sendTo)
248 { 248 {
249 CBitcoinAddress address(s.name_); 249 CBitcoinAddress address(s.name_);
250 if (!address.IsValid()) 250 if (!address.IsValid())
251 throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+s.name_); 251 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
252 252
253 if (setAddress.count(address)) 253 if (setAddress.count(address))
254 throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_); 254 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
255 setAddress.insert(address); 255 setAddress.insert(address);
256 256
257 CScript scriptPubKey; 257 CScript scriptPubKey;
258 scriptPubKey.SetDestination(address.Get()); 258 scriptPubKey.SetDestination(address.Get());
259 int64 nAmount = AmountFromValue(s.value_); 259 int64 nAmount = AmountFromValue(s.value_);
281 CTransaction tx; 281 CTransaction tx;
282 try { 282 try {
283 ssData >> tx; 283 ssData >> tx;
284 } 284 }
285 catch (std::exception &e) { 285 catch (std::exception &e) {
286 throw JSONRPCError(-22, "TX decode failed"); 286 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
287 } 287 }
288 288
289 Object result; 289 Object result;
290 TxToJSON(tx, 0, result); 290 TxToJSON(tx, 0, result);
291 291
320 CTransaction tx; 320 CTransaction tx;
321 ssData >> tx; 321 ssData >> tx;
322 txVariants.push_back(tx); 322 txVariants.push_back(tx);
323 } 323 }
324 catch (std::exception &e) { 324 catch (std::exception &e) {
325 throw JSONRPCError(-22, "TX decode failed"); 325 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
326 } 326 }
327 } 327 }
328 328
329 if (txVariants.empty()) 329 if (txVariants.empty())
330 throw JSONRPCError(-22, "Missing transaction"); 330 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
331 331
332 // mergedTx will end up with all the signatures; it 332 // mergedTx will end up with all the signatures; it
333 // starts as a clone of the rawtx: 333 // starts as a clone of the rawtx:
334 CTransaction mergedTx(txVariants[0]); 334 CTransaction mergedTx(txVariants[0]);
335 bool fComplete = true; 335 bool fComplete = true;
362 { 362 {
363 Array prevTxs = params[1].get_array(); 363 Array prevTxs = params[1].get_array();
364 BOOST_FOREACH(Value& p, prevTxs) 364 BOOST_FOREACH(Value& p, prevTxs)
365 { 365 {
366 if (p.type() != obj_type) 366 if (p.type() != obj_type)
367 throw JSONRPCError(-22, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); 367 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
368 368
369 Object prevOut = p.get_obj(); 369 Object prevOut = p.get_obj();
370 370
371 RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); 371 RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
372 372
373 string txidHex = find_value(prevOut, "txid").get_str(); 373 string txidHex = find_value(prevOut, "txid").get_str();
374 if (!IsHex(txidHex)) 374 if (!IsHex(txidHex))
375 throw JSONRPCError(-22, "txid must be hexadecimal"); 375 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal");
376 uint256 txid; 376 uint256 txid;
377 txid.SetHex(txidHex); 377 txid.SetHex(txidHex);
378 378
379 int nOut = find_value(prevOut, "vout").get_int(); 379 int nOut = find_value(prevOut, "vout").get_int();
380 if (nOut < 0) 380 if (nOut < 0)
381 throw JSONRPCError(-22, "vout must be positive"); 381 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
382 382
383 string pkHex = find_value(prevOut, "scriptPubKey").get_str(); 383 string pkHex = find_value(prevOut, "scriptPubKey").get_str();
384 if (!IsHex(pkHex)) 384 if (!IsHex(pkHex))
385 throw JSONRPCError(-22, "scriptPubKey must be hexadecimal"); 385 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "scriptPubKey must be hexadecimal");
386 vector<unsigned char> pkData(ParseHex(pkHex)); 386 vector<unsigned char> pkData(ParseHex(pkHex));
387 CScript scriptPubKey(pkData.begin(), pkData.end()); 387 CScript scriptPubKey(pkData.begin(), pkData.end());
388 388
389 COutPoint outpoint(txid, nOut); 389 COutPoint outpoint(txid, nOut);
390 if (mapPrevOut.count(outpoint)) 390 if (mapPrevOut.count(outpoint))
393 if (mapPrevOut[outpoint] != scriptPubKey) 393 if (mapPrevOut[outpoint] != scriptPubKey)
394 { 394 {
395 string err("Previous output scriptPubKey mismatch:\n"); 395 string err("Previous output scriptPubKey mismatch:\n");
396 err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+ 396 err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+
397 scriptPubKey.ToString(); 397 scriptPubKey.ToString();
398 throw JSONRPCError(-22, err); 398 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
399 } 399 }
400 } 400 }
401 else 401 else
402 mapPrevOut[outpoint] = scriptPubKey; 402 mapPrevOut[outpoint] = scriptPubKey;
403 } 403 }
412 BOOST_FOREACH(Value k, keys) 412 BOOST_FOREACH(Value k, keys)
413 { 413 {
414 CBitcoinSecret vchSecret; 414 CBitcoinSecret vchSecret;
415 bool fGood = vchSecret.SetString(k.get_str()); 415 bool fGood = vchSecret.SetString(k.get_str());
416 if (!fGood) 416 if (!fGood)
417 throw JSONRPCError(-5,"Invalid private key"); 417 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key");
418 CKey key; 418 CKey key;
419 bool fCompressed; 419 bool fCompressed;
420 CSecret secret = vchSecret.GetSecret(fCompressed); 420 CSecret secret = vchSecret.GetSecret(fCompressed);
421 key.SetSecret(secret, fCompressed); 421 key.SetSecret(secret, fCompressed);
422 tempKeystore.AddKey(key); 422 tempKeystore.AddKey(key);
441 ; 441 ;
442 string strHashType = params[3].get_str(); 442 string strHashType = params[3].get_str();
443 if (mapSigHashValues.count(strHashType)) 443 if (mapSigHashValues.count(strHashType))
444 nHashType = mapSigHashValues[strHashType]; 444 nHashType = mapSigHashValues[strHashType];
445 else 445 else
446 throw JSONRPCError(-8, "Invalid sighash param"); 446 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
447 } 447 }
448 448
449 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); 449 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
450 450
451 // Sign what we can: 451 // Sign what we can:
499 // deserialize binary data stream 499 // deserialize binary data stream
500 try { 500 try {
501 ssData >> tx; 501 ssData >> tx;
502 } 502 }
503 catch (std::exception &e) { 503 catch (std::exception &e) {
504 throw JSONRPCError(-22, "TX decode failed"); 504 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
505 } 505 }
506 uint256 hashTx = tx.GetHash(); 506 uint256 hashTx = tx.GetHash();
507 507
508 // See if the transaction is already in a block 508 // See if the transaction is already in a block
509 // or in the memory pool: 509 // or in the memory pool:
510 CTransaction existingTx; 510 CTransaction existingTx;
511 uint256 hashBlock = 0; 511 uint256 hashBlock = 0;
512 if (GetTransaction(hashTx, existingTx, hashBlock)) 512 if (GetTransaction(hashTx, existingTx, hashBlock))
513 { 513 {
514 if (hashBlock != 0) 514 if (hashBlock != 0)
515 throw JSONRPCError(-5, string("transaction already in block ")+hashBlock.GetHex()); 515 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("transaction already in block ")+hashBlock.GetHex());
516 // Not in block, but already in the memory pool; will drop 516 // Not in block, but already in the memory pool; will drop
517 // through to re-relay it. 517 // through to re-relay it.
518 } 518 }
519 else 519 else
520 { 520 {
521 // push to local node 521 // push to local node
522 CTxDB txdb("r"); 522 CTxDB txdb("r");
523 if (!tx.AcceptToMemoryPool(txdb)) 523 if (!tx.AcceptToMemoryPool(txdb))
524 throw JSONRPCError(-22, "TX rejected"); 524 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected");
525 525
526 SyncWithWallets(tx, NULL, true); 526 SyncWithWallets(tx, NULL, true);
527 } 527 }
528 RelayMessage(CInv(MSG_TX, hashTx), tx); 528 RelayMessage(CInv(MSG_TX, hashTx), tx);
529 529