1 diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
2 index 15bcf1d..805dbda 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 @@ -1933,8 +1970,6 @@ Value getmemorypool(const Array& params, bool fHelp)
50 result.push_back(Pair("version", pblock->nVersion));
51 result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
52 result.push_back(Pair("transactions", transactions));
53 - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
54 - result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
55 result.push_back(Pair("time", (int64_t)pblock->nTime));
56 result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
57 result.push_back(Pair("curtime", (int64_t)GetAdjustedTime()));
58 @@ -2055,6 +2090,7 @@ static const CRPCCommand vRPCCommands[] =
59 { "listsinceblock", &listsinceblock, false },
60 { "dumpprivkey", &dumpprivkey, false },
61 { "importprivkey", &importprivkey, false },
62 + { "importtransaction", &importtransaction, false },
65 CRPCTable::CRPCTable()
66 diff --git a/src/main.cpp b/src/main.cpp
67 index 427e435..35a0aea 100644
70 @@ -3134,156 +3134,28 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
74 - // Create coinbase tx
76 - txNew.vin.resize(1);
77 - txNew.vin[0].prevout.SetNull();
78 - txNew.vout.resize(1);
79 - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;
81 - // Add our coinbase tx as first transaction
82 - pblock->vtx.push_back(txNew);
84 // Collect memory pool transactions into the block
87 LOCK2(cs_main, mempool.cs);
90 - // Priority order to process transactions
91 - list<COrphan> vOrphan; // list memory doesn't move
92 - map<uint256, vector<COrphan*> > mapDependers;
93 - multimap<double, CTransaction*> mapPriority;
94 - for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
96 - CTransaction& tx = (*mi).second;
97 - if (tx.IsCoinBase() || !tx.IsFinal())
100 - COrphan* porphan = NULL;
101 - double dPriority = 0;
102 - BOOST_FOREACH(const CTxIn& txin, tx.vin)
104 - // Read prev transaction
105 - CTransaction txPrev;
107 - if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
109 - // Has to wait for dependencies
112 - // Use list for automatic deletion
113 - vOrphan.push_back(COrphan(&tx));
114 - porphan = &vOrphan.back();
116 - mapDependers[txin.prevout.hash].push_back(porphan);
117 - porphan->setDependsOn.insert(txin.prevout.hash);
120 - int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
122 - // Read block header
123 - int nConf = txindex.GetDepthInMainChain();
125 - dPriority += (double)nValueIn * nConf;
127 - if (fDebug && GetBoolArg("-printpriority"))
128 - printf("priority nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
131 - // Priority is sum(valuein * age) / txsize
132 - dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
135 - porphan->dPriority = dPriority;
137 - mapPriority.insert(make_pair(-dPriority, &(*mi).second));
139 - if (fDebug && GetBoolArg("-printpriority"))
141 - printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
148 - // Collect transactions into block
149 - map<uint256, CTxIndex> mapTestPool;
150 - uint64 nBlockSize = 1000;
152 - int nBlockSigOps = 100;
153 - while (!mapPriority.empty())
154 + for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
156 - // Take highest priority transaction off priority queue
157 - double dPriority = -(*mapPriority.begin()).first;
158 - CTransaction& tx = *(*mapPriority.begin()).second;
159 - mapPriority.erase(mapPriority.begin());
162 - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
163 - if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
166 - // Legacy limits on sigOps:
167 - unsigned int nTxSigOps = tx.GetLegacySigOpCount();
168 - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
171 - // Transaction fee required depends on block size
172 - bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority));
173 - int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK);
175 - // Connecting shouldn't fail due to dependency on other memory pool transactions
176 - // because we're already processing them in order of dependency
177 - map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
178 - MapPrevTx mapInputs;
180 - if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
182 + CTransaction& tx = (*mi).second;
183 + if (tx.IsCoinBase() || !tx.IsFinal())
186 - int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
187 - if (nTxFees < nMinFee)
190 - nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
191 - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
194 - if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
196 - mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
197 - swap(mapTestPool, mapTestPoolTmp);
200 - pblock->vtx.push_back(tx);
201 - nBlockSize += nTxSize;
203 - nBlockSigOps += nTxSigOps;
206 - // Add transactions that depend on this one to the priority queue
207 - uint256 hash = tx.GetHash();
208 - if (mapDependers.count(hash))
210 - BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
212 - if (!porphan->setDependsOn.empty())
214 - porphan->setDependsOn.erase(hash);
215 - if (porphan->setDependsOn.empty())
216 - mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
220 + if (!tx.get_electrum_flag())
222 + tx.set_electrum_flag(true);
223 + pblock->vtx.push_back(tx);
228 - nLastBlockTx = nBlockTx;
229 - nLastBlockSize = nBlockSize;
230 - printf("CreateNewBlock(): total size %lu\n", nBlockSize);
232 + printf("CreateNewBlock(): transactions: %lu\n", nBlockTx);
234 - pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
237 pblock->hashPrevBlock = pindexPrev->GetBlockHash();
238 diff --git a/src/main.h b/src/main.h
239 index 262e77e..4cc9319 100644
242 @@ -395,6 +395,16 @@ public:
244 bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
246 + bool electrum_flag;
248 + void set_electrum_flag(bool x){
252 + bool get_electrum_flag(){
253 + return electrum_flag;
259 @@ -416,6 +426,7 @@ public:
262 nDoS = 0; // Denial-of-service prevention
263 + set_electrum_flag(false);