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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
338 CCoinsView viewDummy;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
339 CCoinsViewCache view(viewDummy);
3154
6c1eeeb7e4c2 Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff changeset
340 {
3649
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
341 LOCK(mempool.cs);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
342 CCoinsDB coinsdb("r");
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
343 CCoinsViewDB viewDB(coinsdb);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
344 CCoinsViewMemPool viewMempool(viewDB, mempool);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
347 BOOST_FOREACH(const CTxIn& txin, mergedTx.vin) {
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
348 const uint256& prevHash = txin.prevout.hash;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
349 CCoins coins;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
350 view.GetCoins(prevHash, coins); // this is certainly allowed to fail
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
351 }
3154
6c1eeeb7e4c2 Implement raw transaction RPC calls
Gavin Andresen <gavinandresen@gmail.com>
parents:
diff changeset
352
3649
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
385 CCoins coins;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
386 if (view.GetCoins(txid, coins)) {
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
395 coins.vout[nOut].scriptPubKey = scriptPubKey;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
396 coins.vout[nOut].nValue = 0; // we don't know the actual output value
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
450 CCoins coins;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
504 bool fHave = false;
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
505 CCoins existingCoins;
3197
b63a5263d11a Bug fix: sendrawtransaction was not relaying properly
Gavin Andresen <gavinandresen@gmail.com>
parents: 3156
diff changeset
506 {
3649
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
507 CCoinsDB coinsdb("r");
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
508 {
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
509 CCoinsViewDB coinsviewDB(coinsdb);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
510 CCoinsViewMemPool coinsview(coinsviewDB, mempool);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
511 fHave = coinsview.GetCoins(hashTx, existingCoins);
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
512 }
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
513 if (!fHave) {
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
514 // push to local node
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
515 if (!tx.AcceptToMemoryPool(coinsdb))
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
516 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected");
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
517 }
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
518 }
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
519 if (fHave) {
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
520 if (existingCoins.nHeight < 1000000000)
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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
eb986f1e2e93 Ultraprune
Pieter Wuille <pieter.wuille@gmail.com>
parents: 3632
diff changeset
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 }