1 diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
2 index 15bcf1d..1ace361 100644
3 --- a/src/bitcoinrpc.cpp
4 +++ b/src/bitcoinrpc.cpp
5 @@ -1497,6 +1497,43 @@ Value gettransaction(const Array& params, bool fHelp)
9 +Value importtransaction(const Array& params, bool fHelp)
12 + if (fHelp || params.size() != 1 || (hexdump=params[0].get_str()).size()&1)
13 + throw runtime_error(
14 + "importtransaction <hexdata>\n"
15 + "Import an offline transaction to announce it into the network");
17 + std::vector<unsigned char> rawtx;
18 + for (int i=0; i<hexdump.size(); i+=2)
21 + if (sscanf(hexdump.substr(i,2).c_str(), "%x", &v)!=1)
22 + throw JSONRPCError(-4, "Error in hex data.");
23 + rawtx.push_back((unsigned char)v);
27 + CDataStream ss(rawtx, SER_NETWORK, PROTOCOL_VERSION);
30 + CInv inv(MSG_TX, tx.GetHash());
33 + if(! tx.AcceptToMemoryPool(txdb, true)) throw JSONRPCError(-4, "Transaction not accepted to memory pool.");
34 + CDataStream msg(rawtx, SER_NETWORK, PROTOCOL_VERSION);
35 + RelayMessage(inv, msg);
36 + return tx.GetHash().GetHex();
38 + catch (std::exception& e)
40 + throw JSONRPCError(-4, "Exception while parsing the transaction data.");
46 Value backupwallet(const Array& params, bool fHelp)
48 if (fHelp || params.size() != 1)
49 @@ -2055,6 +2092,7 @@ static const CRPCCommand vRPCCommands[] =
50 { "listsinceblock", &listsinceblock, false },
51 { "dumpprivkey", &dumpprivkey, false },
52 { "importprivkey", &importprivkey, false },
53 + { "importtransaction", &importtransaction, false },
56 CRPCTable::CRPCTable()
57 diff --git a/src/main.cpp b/src/main.cpp
58 index 427e435..35a0aea 100644
61 @@ -3134,156 +3134,28 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
65 - // Create coinbase tx
67 - txNew.vin.resize(1);
68 - txNew.vin[0].prevout.SetNull();
69 - txNew.vout.resize(1);
70 - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
72 - // Add our coinbase tx as first transaction
73 - pblock->vtx.push_back(txNew);
75 // Collect memory pool transactions into the block
78 LOCK2(cs_main, mempool.cs);
81 - // Priority order to process transactions
82 - list<COrphan> vOrphan; // list memory doesn't move
83 - map<uint256, vector<COrphan*> > mapDependers;
84 - multimap<double, CTransaction*> mapPriority;
85 - for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
87 - CTransaction& tx = (*mi).second;
88 - if (tx.IsCoinBase() || !tx.IsFinal())
91 - COrphan* porphan = NULL;
92 - double dPriority = 0;
93 - BOOST_FOREACH(const CTxIn& txin, tx.vin)
95 - // Read prev transaction
96 - CTransaction txPrev;
98 - if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
100 - // Has to wait for dependencies
103 - // Use list for automatic deletion
104 - vOrphan.push_back(COrphan(&tx));
105 - porphan = &vOrphan.back();
107 - mapDependers[txin.prevout.hash].push_back(porphan);
108 - porphan->setDependsOn.insert(txin.prevout.hash);
111 - int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
113 - // Read block header
114 - int nConf = txindex.GetDepthInMainChain();
116 - dPriority += (double)nValueIn * nConf;
118 - if (fDebug && GetBoolArg("-printpriority"))
119 - printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
122 - // Priority is sum(valuein * age) / txsize
123 - dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
126 - porphan->dPriority = dPriority;
128 - mapPriority.insert(make_pair(-dPriority, &(*mi).second));
130 - if (fDebug && GetBoolArg("-printpriority"))
132 - printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
139 - // Collect transactions into block
140 - map<uint256, CTxIndex> mapTestPool;
141 - uint64 nBlockSize = 1000;
143 - int nBlockSigOps = 100;
144 - while (!mapPriority.empty())
145 + for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
147 - // Take highest priority transaction off priority queue
148 - double dPriority = -(*mapPriority.begin()).first;
149 - CTransaction& tx = *(*mapPriority.begin()).second;
150 - mapPriority.erase(mapPriority.begin());
153 - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
154 - if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
157 - // Legacy limits on sigOps:
158 - unsigned int nTxSigOps = tx.GetLegacySigOpCount();
159 - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
162 - // Transaction fee required depends on block size
163 - bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
164 - int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK);
166 - // Connecting shouldn't fail due to dependency on other memory pool transactions
167 - // because we're already processing them in order of dependency
168 - map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
169 - MapPrevTx mapInputs;
171 - if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
173 + CTransaction& tx = (*mi).second;
174 + if (tx.IsCoinBase() || !tx.IsFinal())
177 - int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
178 - if (nTxFees < nMinFee)
181 - nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
182 - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
185 - if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
187 - mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
188 - swap(mapTestPool, mapTestPoolTmp);
191 - pblock->vtx.push_back(tx);
192 - nBlockSize += nTxSize;
194 - nBlockSigOps += nTxSigOps;
197 - // Add transactions that depend on this one to the priority queue
198 - uint256 hash = tx.GetHash();
199 - if (mapDependers.count(hash))
201 - BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
203 - if (!porphan->setDependsOn.empty())
205 - porphan->setDependsOn.erase(hash);
206 - if (porphan->setDependsOn.empty())
207 - mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
211 + if (!tx.get_electrum_flag())
213 + tx.set_electrum_flag(true);
214 + pblock->vtx.push_back(tx);
219 - nLastBlockTx = nBlockTx;
220 - nLastBlockSize = nBlockSize;
221 - printf("CreateNewBlock(): total size %lu\n", nBlockSize);
223 + printf("CreateNewBlock(): transactions: %lu\n", nBlockTx);
225 - pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
228 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
229 diff --git a/src/main.h b/src/main.h
230 index 262e77e..4cc9319 100644
233 @@ -395,6 +395,16 @@ public:
235 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
237 + bool electrum_flag;
239 + void set_electrum_flag(bool x){
243 + bool get_electrum_flag(){
244 + return electrum_flag;
250 @@ -416,6 +426,7 @@ public:
253 nDoS = 0; // Denial-of-service prevention
254 + set_electrum_flag(false);