Mercurial > hg > bitcoin
annotate src/rpcrawtransaction.cpp @ 3649:eb986f1e2e93 draft
Ultraprune
This switches bitcoin's transaction/block verification logic to use a
"coin database", which contains all unredeemed transaction output scripts,
amounts and heights.
The name ultraprune comes from the fact that instead of a full transaction
index, we only (need to) keep an index with unspent outputs. For now, the
blocks themselves are kept as usual, although they are only necessary for
serving, rescanning and reorganizing.
The basic datastructures are CCoins (representing the coins of a single
transaction), and CCoinsView (representing a state of the coins database).
There are several implementations for CCoinsView. A dummy, one backed by
the coins database (coins.dat), one backed by the memory pool, and one
that adds a cache on top of it. FetchInputs, ConnectInputs, ConnectBlock,
DisconnectBlock, ... now operate on a generic CCoinsView.
The block switching logic now builds a single cached CCoinsView with
changes to be committed to the database before any changes are made.
This means no uncommitted changes are ever read from the database, and
should ease the transition to another database layer which does not
support transactions (but does support atomic writes), like LevelDB.
For the getrawtransaction() RPC call, access to a txid-to-disk index
would be preferable. As this index is not necessary or even useful
for any other part of the implementation, it is not provided. Instead,
getrawtransaction() uses the coin database to find the block height,
and then scans that block to find the requested transaction. This is
slow, but should suffice for debug purposes.
author | Pieter Wuille <pieter.wuille@gmail.com> |
---|---|
date | Sun, 01 Jul 2012 18:54:00 +0200 |
parents | abd3935e67df |
children | 12e3ba3a9c4b |
rev | line source |
---|---|
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
1 // Copyright (c) 2010 Satoshi Nakamoto |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
2 // Copyright (c) 2009-2012 The Bitcoin developers |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
3 // Distributed under the MIT/X11 software license, see the accompanying |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
5 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
6 #include <boost/assign/list_of.hpp> |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
7 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
8 #include "base58.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
9 #include "bitcoinrpc.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
10 #include "db.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
11 #include "init.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
12 #include "main.h" |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
13 #include "net.h" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
14 #include "wallet.h" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
15 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
16 using namespace std; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
17 using namespace boost; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
18 using namespace boost::assign; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
19 using namespace json_spirit; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
20 |
3374
8c4e49592ec8
Avoid leaving return types or function attributes on their own lines.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
21 void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
22 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
23 txnouttype type; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
24 vector<CTxDestination> addresses; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
25 int nRequired; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
26 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
27 out.push_back(Pair("asm", scriptPubKey.ToString())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
28 out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
29 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
30 if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
31 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
32 out.push_back(Pair("type", GetTxnOutputType(TX_NONSTANDARD))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
33 return; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
34 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
35 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
36 out.push_back(Pair("reqSigs", nRequired)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
37 out.push_back(Pair("type", GetTxnOutputType(type))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
38 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
39 Array a; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
40 BOOST_FOREACH(const CTxDestination& addr, addresses) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
41 a.push_back(CBitcoinAddress(addr).ToString()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
42 out.push_back(Pair("addresses", a)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
43 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
44 |
3374
8c4e49592ec8
Avoid leaving return types or function attributes on their own lines.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
45 void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
46 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
47 entry.push_back(Pair("txid", tx.GetHash().GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
48 entry.push_back(Pair("version", tx.nVersion)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
49 entry.push_back(Pair("locktime", (boost::int64_t)tx.nLockTime)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
50 Array vin; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
51 BOOST_FOREACH(const CTxIn& txin, tx.vin) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
52 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
53 Object in; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
54 if (tx.IsCoinBase()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
55 in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
56 else |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
57 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
58 in.push_back(Pair("txid", txin.prevout.hash.GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
59 in.push_back(Pair("vout", (boost::int64_t)txin.prevout.n)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
60 Object o; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
61 o.push_back(Pair("asm", txin.scriptSig.ToString())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
62 o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
63 in.push_back(Pair("scriptSig", o)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
64 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
65 in.push_back(Pair("sequence", (boost::int64_t)txin.nSequence)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
66 vin.push_back(in); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
67 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
68 entry.push_back(Pair("vin", vin)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
69 Array vout; |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
70 for (unsigned int i = 0; i < tx.vout.size(); i++) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
71 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
72 const CTxOut& txout = tx.vout[i]; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
73 Object out; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
74 out.push_back(Pair("value", ValueFromAmount(txout.nValue))); |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
75 out.push_back(Pair("n", (boost::int64_t)i)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
76 Object o; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
77 ScriptPubKeyToJSON(txout.scriptPubKey, o); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
78 out.push_back(Pair("scriptPubKey", o)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
79 vout.push_back(out); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
80 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
81 entry.push_back(Pair("vout", vout)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
82 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
83 if (hashBlock != 0) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
84 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
85 entry.push_back(Pair("blockhash", hashBlock.GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
86 map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
87 if (mi != mapBlockIndex.end() && (*mi).second) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
88 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
89 CBlockIndex* pindex = (*mi).second; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
90 if (pindex->IsInMainChain()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
91 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
92 entry.push_back(Pair("confirmations", 1 + nBestHeight - pindex->nHeight)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
93 entry.push_back(Pair("time", (boost::int64_t)pindex->nTime)); |
3362
494bece0648d
JSON-RPC: Add "blocktime" and (for wallet transactions) "timereceived" to transaction Object outputs
Luke Dashjr <luke-jr+git@utopios.org>
parents:
3340
diff
changeset
|
94 entry.push_back(Pair("blocktime", (boost::int64_t)pindex->nTime)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
95 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
96 else |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
97 entry.push_back(Pair("confirmations", 0)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
98 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
99 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
100 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
101 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
102 Value getrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
103 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
104 if (fHelp || params.size() < 1 || params.size() > 2) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
105 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
106 "getrawtransaction <txid> [verbose=0]\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
107 "If verbose=0, returns a string that is\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
108 "serialized, hex-encoded data for <txid>.\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
109 "If verbose is non-zero, returns an Object\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
110 "with information about <txid>."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
111 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
112 uint256 hash; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
113 hash.SetHex(params[0].get_str()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
114 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
115 bool fVerbose = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
116 if (params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
117 fVerbose = (params[1].get_int() != 0); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
118 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
119 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
120 uint256 hashBlock = 0; |
3649 | 121 if (!GetTransaction(hash, tx, hashBlock, true)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
122 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
123 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
124 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
125 ssTx << tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
126 string strHex = HexStr(ssTx.begin(), ssTx.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
127 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
128 if (!fVerbose) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
129 return strHex; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
130 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
131 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
132 result.push_back(Pair("hex", strHex)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
133 TxToJSON(tx, hashBlock, result); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
134 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
135 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
136 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
137 Value listunspent(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
138 { |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
139 if (fHelp || params.size() > 3) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
140 throw runtime_error( |
3377
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
141 "listunspent [minconf=1] [maxconf=9999999] [\"address\",...]\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
142 "Returns array of unspent transaction outputs\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
143 "with between minconf and maxconf (inclusive) confirmations.\n" |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
144 "Optionally filtered to only include txouts paid to specified addresses.\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
145 "Results are an array of Objects, each of which has:\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
146 "{txid, vout, scriptPubKey, amount, confirmations}"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
147 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
148 RPCTypeCheck(params, list_of(int_type)(int_type)(array_type)); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
149 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
150 int nMinDepth = 1; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
151 if (params.size() > 0) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
152 nMinDepth = params[0].get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
153 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
154 int nMaxDepth = 9999999; |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
155 if (params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
156 nMaxDepth = params[1].get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
157 |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
158 set<CBitcoinAddress> setAddress; |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
159 if (params.size() > 2) |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
160 { |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
161 Array inputs = params[2].get_array(); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
162 BOOST_FOREACH(Value& input, inputs) |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
163 { |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
164 CBitcoinAddress address(input.get_str()); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
165 if (!address.IsValid()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
166 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str()); |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
167 if (setAddress.count(address)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
168 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str()); |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
169 setAddress.insert(address); |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
170 } |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
171 } |
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
172 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
173 Array results; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
174 vector<COutput> vecOutputs; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
175 pwalletMain->AvailableCoins(vecOutputs, false); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
176 BOOST_FOREACH(const COutput& out, vecOutputs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
177 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
178 if (out.nDepth < nMinDepth || out.nDepth > nMaxDepth) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
179 continue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
180 |
3377
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
181 if(setAddress.size()) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
182 { |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
183 CTxDestination address; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
184 if(!ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
185 continue; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
186 |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
187 if (!setAddress.count(address)) |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
188 continue; |
8da60f83a63f
Change CWallet addressgrouping to use CTxDestination instead of strings.
Gregory Maxwell <greg@xiph.org>
parents:
3376
diff
changeset
|
189 } |
3376
a15769159fbd
Add txout address filtering to listunspent.
Gregory Maxwell <greg@xiph.org>
parents:
3362
diff
changeset
|
190 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
191 int64 nValue = out.tx->vout[out.i].nValue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
192 const CScript& pk = out.tx->vout[out.i].scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
193 Object entry; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
194 entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
195 entry.push_back(Pair("vout", out.i)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
196 entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
197 entry.push_back(Pair("amount",ValueFromAmount(nValue))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
198 entry.push_back(Pair("confirmations",out.nDepth)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
199 results.push_back(entry); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
200 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
201 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
202 return results; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
203 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
204 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
205 Value createrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
206 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
207 if (fHelp || params.size() != 2) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
208 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
209 "createrawtransaction [{\"txid\":txid,\"vout\":n},...] {address:amount,...}\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
210 "Create a transaction spending given inputs\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
211 "(array of objects containing transaction id and output number),\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
212 "sending to given address(es).\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
213 "Returns hex-encoded raw transaction.\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
214 "Note that the transaction's inputs are not signed, and\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
215 "it is not stored in the wallet or transmitted to the network."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
216 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
217 RPCTypeCheck(params, list_of(array_type)(obj_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
218 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
219 Array inputs = params[0].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
220 Object sendTo = params[1].get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
221 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
222 CTransaction rawTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
223 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
224 BOOST_FOREACH(Value& input, inputs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
225 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
226 const Object& o = input.get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
227 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
228 const Value& txid_v = find_value(o, "txid"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
229 if (txid_v.type() != str_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
230 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
231 string txid = txid_v.get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
232 if (!IsHex(txid)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
233 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
234 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
235 const Value& vout_v = find_value(o, "vout"); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
236 if (vout_v.type() != int_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
237 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
238 int nOutput = vout_v.get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
239 if (nOutput < 0) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
240 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
241 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
242 CTxIn in(COutPoint(uint256(txid), nOutput)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
243 rawTx.vin.push_back(in); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
244 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
245 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
246 set<CBitcoinAddress> setAddress; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
247 BOOST_FOREACH(const Pair& s, sendTo) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
248 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
249 CBitcoinAddress address(s.name_); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
250 if (!address.IsValid()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
251 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
252 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
253 if (setAddress.count(address)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
254 throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
255 setAddress.insert(address); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
256 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
257 CScript scriptPubKey; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
258 scriptPubKey.SetDestination(address.Get()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
259 int64 nAmount = AmountFromValue(s.value_); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
260 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
261 CTxOut out(nAmount, scriptPubKey); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
262 rawTx.vout.push_back(out); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
263 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
264 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
265 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
266 ss << rawTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
267 return HexStr(ss.begin(), ss.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
268 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
269 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
270 Value decoderawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
271 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
272 if (fHelp || params.size() != 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
273 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
274 "decoderawtransaction <hex string>\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
275 "Return a JSON object representing the serialized, hex-encoded transaction."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
276 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
277 RPCTypeCheck(params, list_of(str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
278 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
279 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
280 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
281 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
282 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
283 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
284 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
285 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
286 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
287 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
288 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
289 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
290 TxToJSON(tx, 0, result); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
291 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
292 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
293 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
294 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
295 Value signrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
296 { |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
297 if (fHelp || params.size() < 1 || params.size() > 4) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
298 throw runtime_error( |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
299 "signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
300 "Sign inputs for raw transaction (serialized, hex-encoded).\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
301 "Second optional argument (may be null) is an array of previous transaction outputs that\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
302 "this transaction depends on but may not yet be in the blockchain.\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
303 "Third optional argument (may be null) is an array of base58-encoded private\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
304 "keys that, if given, will be the only keys used to sign the transaction.\n" |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
305 "Fourth optional argument is a string that is one of six values; ALL, NONE, SINGLE or\n" |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
306 "ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n" |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
307 "Returns json object with keys:\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
308 " hex : raw transaction with signature(s) (hex-encoded string)\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
309 " complete : 1 if transaction has a complete set of signature (0 if not)" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
310 + HelpRequiringPassphrase()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
311 |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
312 RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
313 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
314 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
315 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
316 vector<CTransaction> txVariants; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
317 while (!ssData.empty()) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
318 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
319 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
320 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
321 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
322 txVariants.push_back(tx); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
323 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
324 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
325 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
326 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
327 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
328 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
329 if (txVariants.empty()) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
330 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
331 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
332 // mergedTx will end up with all the signatures; it |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
333 // starts as a clone of the rawtx: |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
334 CTransaction mergedTx(txVariants[0]); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
335 bool fComplete = true; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
336 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
337 // Fetch previous transactions (inputs): |
3649 | 338 CCoinsView viewDummy; |
339 CCoinsViewCache view(viewDummy); | |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
340 { |
3649 | 341 LOCK(mempool.cs); |
342 CCoinsDB coinsdb("r"); | |
343 CCoinsViewDB viewDB(coinsdb); | |
344 CCoinsViewMemPool viewMempool(viewDB, mempool); | |
345 view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view | |
3289
0addd08564e8
Correctly handle missing inputs in signrawtransaction. Fixes #1654.
Gregory Maxwell <greg@xiph.org>
parents:
3225
diff
changeset
|
346 |
3649 | 347 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) { |
348 const uint256& prevHash = txin.prevout.hash; | |
349 CCoins coins; | |
350 view.GetCoins(prevHash, coins); // this is certainly allowed to fail | |
351 } | |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
352 |
3649 | 353 view.SetBackend(viewDummy); // switch back to avoid locking db/mempool too long |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
354 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
355 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
356 // Add previous txouts given in the RPC call: |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
357 if (params.size() > 1 && params[1].type() != null_type) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
358 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
359 Array prevTxs = params[1].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
360 BOOST_FOREACH(Value& p, prevTxs) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
361 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
362 if (p.type() != obj_type) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
363 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
364 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
365 Object prevOut = p.get_obj(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
366 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
367 RPCTypeCheck(prevOut, map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
368 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
369 string txidHex = find_value(prevOut, "txid").get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
370 if (!IsHex(txidHex)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
371 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
372 uint256 txid; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
373 txid.SetHex(txidHex); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
374 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
375 int nOut = find_value(prevOut, "vout").get_int(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
376 if (nOut < 0) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
377 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
378 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
379 string pkHex = find_value(prevOut, "scriptPubKey").get_str(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
380 if (!IsHex(pkHex)) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
381 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "scriptPubKey must be hexadecimal"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
382 vector<unsigned char> pkData(ParseHex(pkHex)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
383 CScript scriptPubKey(pkData.begin(), pkData.end()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
384 |
3649 | 385 CCoins coins; |
386 if (view.GetCoins(txid, coins)) { | |
387 if (coins.IsAvailable(nOut) && coins.vout[nOut].scriptPubKey != scriptPubKey) { | |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
388 string err("Previous output scriptPubKey mismatch:\n"); |
3649 | 389 err = err + coins.vout[nOut].scriptPubKey.ToString() + "\nvs:\n"+ |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
390 scriptPubKey.ToString(); |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
391 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
392 } |
3649 | 393 // what todo if txid is known, but the actual output isn't? |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
394 } |
3649 | 395 coins.vout[nOut].scriptPubKey = scriptPubKey; |
396 coins.vout[nOut].nValue = 0; // we don't know the actual output value | |
397 view.SetCoins(txid, coins); | |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
398 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
399 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
400 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
401 bool fGivenKeys = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
402 CBasicKeyStore tempKeystore; |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
403 if (params.size() > 2 && params[2].type() != null_type) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
404 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
405 fGivenKeys = true; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
406 Array keys = params[2].get_array(); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
407 BOOST_FOREACH(Value k, keys) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
408 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
409 CBitcoinSecret vchSecret; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
410 bool fGood = vchSecret.SetString(k.get_str()); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
411 if (!fGood) |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
412 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
413 CKey key; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
414 bool fCompressed; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
415 CSecret secret = vchSecret.GetSecret(fCompressed); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
416 key.SetSecret(secret, fCompressed); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
417 tempKeystore.AddKey(key); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
418 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
419 } |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
420 else |
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
421 EnsureWalletIsUnlocked(); |
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
422 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
423 const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
424 |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
425 int nHashType = SIGHASH_ALL; |
3330
71d199d19f59
Allow signrawtransaction '...' null null 'hashtype'
Gavin Andresen <gavinandresen@gmail.com>
parents:
3327
diff
changeset
|
426 if (params.size() > 3 && params[3].type() != null_type) |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
427 { |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
428 static map<string, int> mapSigHashValues = |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
429 boost::assign::map_list_of |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
430 (string("ALL"), int(SIGHASH_ALL)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
431 (string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
432 (string("NONE"), int(SIGHASH_NONE)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
433 (string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
434 (string("SINGLE"), int(SIGHASH_SINGLE)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
435 (string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
436 ; |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
437 string strHashType = params[3].get_str(); |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
438 if (mapSigHashValues.count(strHashType)) |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
439 nHashType = mapSigHashValues[strHashType]; |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
440 else |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
441 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); |
3225
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
442 } |
13158535565e
New feature for signrawtransaction: specify signature hash (ALL/NONE/etc)
Gavin Andresen <gavinandresen@gmail.com>
parents:
3197
diff
changeset
|
443 |
3327
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
444 bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
445 |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
446 // Sign what we can: |
3156
505666711e5b
Use unsigned ints to fix signed/unsigned warnings
Gavin Andresen <gavinandresen@gmail.com>
parents:
3154
diff
changeset
|
447 for (unsigned int i = 0; i < mergedTx.vin.size(); i++) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
448 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
449 CTxIn& txin = mergedTx.vin[i]; |
3649 | 450 CCoins coins; |
451 if (!view.GetCoins(txin.prevout.hash, coins) || !coins.IsAvailable(txin.prevout.n)) | |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
452 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
453 fComplete = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
454 continue; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
455 } |
3649 | 456 const CScript& prevPubKey = coins.vout[txin.prevout.n].scriptPubKey; |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
457 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
458 txin.scriptSig.clear(); |
3327
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
459 // Only sign SIGHASH_SINGLE if there's a corresponding output: |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
460 if (!fHashSingle || (i < mergedTx.vout.size())) |
71eb723dde0e
When using SIGHASH_SINGLE, do not sign inputs that have no corresponding outputs.
Gavin Andresen <gavinandresen@gmail.com>
parents:
3289
diff
changeset
|
461 SignSignature(keystore, prevPubKey, mergedTx, i, nHashType); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
462 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
463 // ... and merge in other signatures: |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
464 BOOST_FOREACH(const CTransaction& txv, txVariants) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
465 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
466 txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
467 } |
3520
ce8540bec751
Check for canonical public keys and signatures
Pieter Wuille <pieter.wuille@gmail.com>
parents:
3378
diff
changeset
|
468 if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, true, true, 0)) |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
469 fComplete = false; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
470 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
471 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
472 Object result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
473 CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
474 ssTx << mergedTx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
475 result.push_back(Pair("hex", HexStr(ssTx.begin(), ssTx.end()))); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
476 result.push_back(Pair("complete", fComplete)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
477 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
478 return result; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
479 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
480 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
481 Value sendrawtransaction(const Array& params, bool fHelp) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
482 { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
483 if (fHelp || params.size() < 1 || params.size() > 1) |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
484 throw runtime_error( |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
485 "sendrawtransaction <hex string>\n" |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
486 "Submits raw transaction (serialized, hex-encoded) to local node and network."); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
487 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
488 RPCTypeCheck(params, list_of(str_type)); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
489 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
490 // parse hex string from parameter |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
491 vector<unsigned char> txData(ParseHex(params[0].get_str())); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
492 CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
493 CTransaction tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
494 |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
495 // deserialize binary data stream |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
496 try { |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
497 ssData >> tx; |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
498 } |
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
499 catch (std::exception &e) { |
3588
7eb24f8cf224
Document RPC error codes
Wladimir J. van der Laan <laanwj@gmail.com>
parents:
3378
diff
changeset
|
500 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
501 } |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
502 uint256 hashTx = tx.GetHash(); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
503 |
3649 | 504 bool fHave = false; |
505 CCoins existingCoins; | |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
506 { |
3649 | 507 CCoinsDB coinsdb("r"); |
508 { | |
509 CCoinsViewDB coinsviewDB(coinsdb); | |
510 CCoinsViewMemPool coinsview(coinsviewDB, mempool); | |
511 fHave = coinsview.GetCoins(hashTx, existingCoins); | |
512 } | |
513 if (!fHave) { | |
514 // push to local node | |
515 if (!tx.AcceptToMemoryPool(coinsdb)) | |
516 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); | |
517 } | |
518 } | |
519 if (fHave) { | |
520 if (existingCoins.nHeight < 1000000000) | |
521 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "transaction already in block chain"); | |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
522 // Not in block, but already in the memory pool; will drop |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
523 // through to re-relay it. |
3649 | 524 } else { |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
525 SyncWithWallets(tx, NULL, true); |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
526 } |
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
527 RelayMessage(CInv(MSG_TX, hashTx), tx); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
528 |
3197
b63a5263d11a
Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents:
3156
diff
changeset
|
529 return hashTx.GetHex(); |
3154
6c1eeeb7e4c2
Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff
changeset
|
530 } |