Mercurial > hg > bitcoin
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 |