diff -ur bitcoin-0.6.3-orig/src/bitcoinrpc.cpp bitcoin-0.6.3/src/bitcoinrpc.cpp --- bitcoin-0.6.3-orig/src/bitcoinrpc.cpp 2012-06-19 13:44:55.000000000 -0700 +++ bitcoin-0.6.3/src/bitcoinrpc.cpp 2012-07-09 11:56:21.329502578 -0700 @@ -1501,6 +1501,43 @@ } +Value importtransaction(const Array& params, bool fHelp) +{ + string hexdump; + if (fHelp || params.size() != 1 || (hexdump=params[0].get_str()).size()&1) + throw runtime_error( + "importtransaction \n" + "Import an offline transaction to announce it into the network"); + + std::vector rawtx; + for (int i=0; i> tx; + CInv inv(MSG_TX, tx.GetHash()); + + CTxDB txdb("r"); + if(! tx.AcceptToMemoryPool(txdb, true)) throw JSONRPCError(-4, "Transaction not accepted to memory pool."); + CDataStream msg(rawtx, SER_NETWORK, PROTOCOL_VERSION); + RelayMessage(inv, msg); + return tx.GetHash().GetHex(); + } + catch (std::exception& e) + { + throw JSONRPCError(-4, "Exception while parsing the transaction data."); + } + +} + + Value backupwallet(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -1937,8 +1974,6 @@ result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue)); - result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); result.push_back(Pair("time", (int64_t)pblock->nTime)); result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1)); result.push_back(Pair("curtime", (int64_t)GetAdjustedTime())); @@ -2059,6 +2094,7 @@ { "listsinceblock", &listsinceblock, false }, { "dumpprivkey", &dumpprivkey, false }, { "importprivkey", &importprivkey, false }, + { "importtransaction", &importtransaction, false }, }; CRPCTable::CRPCTable() diff -ur bitcoin-0.6.3-orig/src/main.cpp bitcoin-0.6.3/src/main.cpp --- bitcoin-0.6.3-orig/src/main.cpp 2012-06-19 13:44:55.000000000 -0700 +++ bitcoin-0.6.3/src/main.cpp 2012-07-09 12:00:26.989497203 -0700 @@ -3189,156 +3189,28 @@ if (!pblock.get()) return NULL; - // Create coinbase tx - CTransaction txNew; - txNew.vin.resize(1); - txNew.vin[0].prevout.SetNull(); - txNew.vout.resize(1); - txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG; - - // Add our coinbase tx as first transaction - pblock->vtx.push_back(txNew); - // Collect memory pool transactions into the block - int64 nFees = 0; { LOCK2(cs_main, mempool.cs); CTxDB txdb("r"); - // Priority order to process transactions - list vOrphan; // list memory doesn't move - map > mapDependers; - multimap mapPriority; - for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) - { - CTransaction& tx = (*mi).second; - if (tx.IsCoinBase() || !tx.IsFinal()) - continue; - - COrphan* porphan = NULL; - double dPriority = 0; - BOOST_FOREACH(const CTxIn& txin, tx.vin) - { - // Read prev transaction - CTransaction txPrev; - CTxIndex txindex; - if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex)) - { - // Has to wait for dependencies - if (!porphan) - { - // Use list for automatic deletion - vOrphan.push_back(COrphan(&tx)); - porphan = &vOrphan.back(); - } - mapDependers[txin.prevout.hash].push_back(porphan); - porphan->setDependsOn.insert(txin.prevout.hash); - continue; - } - int64 nValueIn = txPrev.vout[txin.prevout.n].nValue; - - // Read block header - int nConf = txindex.GetDepthInMainChain(); - - dPriority += (double)nValueIn * nConf; - - if (fDebug && GetBoolArg("-printpriority")) - printf("priority nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority); - } - - // Priority is sum(valuein * age) / txsize - dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - - if (porphan) - porphan->dPriority = dPriority; - else - mapPriority.insert(make_pair(-dPriority, &(*mi).second)); - - if (fDebug && GetBoolArg("-printpriority")) - { - printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str()); - if (porphan) - porphan->print(); - printf("\n"); - } - } - - // Collect transactions into block - map mapTestPool; - uint64 nBlockSize = 1000; uint64 nBlockTx = 0; - int nBlockSigOps = 100; - while (!mapPriority.empty()) + for (map::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi) { - // Take highest priority transaction off priority queue - double dPriority = -(*mapPriority.begin()).first; - CTransaction& tx = *(*mapPriority.begin()).second; - mapPriority.erase(mapPriority.begin()); - - // Size limits - unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION); - if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN) - continue; - - // Legacy limits on sigOps: - unsigned int nTxSigOps = tx.GetLegacySigOpCount(); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; - - // Transaction fee required depends on block size - bool fAllowFree = (nBlockSize + nTxSize < 4000 || CTransaction::AllowFree(dPriority)); - int64 nMinFee = tx.GetMinFee(nBlockSize, fAllowFree, GMF_BLOCK); + CTransaction& tx = (*mi).second; + if (tx.IsCoinBase() || !tx.IsFinal()) + continue; - // Connecting shouldn't fail due to dependency on other memory pool transactions - // because we're already processing them in order of dependency - map mapTestPoolTmp(mapTestPool); - MapPrevTx mapInputs; - bool fInvalid; - if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid)) - continue; - - int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut(); - if (nTxFees < nMinFee) - continue; - - nTxSigOps += tx.GetP2SHSigOpCount(mapInputs); - if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS) - continue; - - if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true)) - continue; - mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size()); - swap(mapTestPool, mapTestPoolTmp); - - // Added - pblock->vtx.push_back(tx); - nBlockSize += nTxSize; - ++nBlockTx; - nBlockSigOps += nTxSigOps; - nFees += nTxFees; - - // Add transactions that depend on this one to the priority queue - uint256 hash = tx.GetHash(); - if (mapDependers.count(hash)) + if (!tx.get_electrum_flag()) { - BOOST_FOREACH(COrphan* porphan, mapDependers[hash]) - { - if (!porphan->setDependsOn.empty()) - { - porphan->setDependsOn.erase(hash); - if (porphan->setDependsOn.empty()) - mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx)); - } - } + tx.set_electrum_flag(true); + pblock->vtx.push_back(tx); + ++nBlockTx; } } - nLastBlockTx = nBlockTx; - nLastBlockSize = nBlockSize; - printf("CreateNewBlock(): total size %lu\n", nBlockSize); - + printf("CreateNewBlock(): transactions: %lu\n", nBlockTx); } - pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); // Fill in header pblock->hashPrevBlock = pindexPrev->GetBlockHash(); diff -ur bitcoin-0.6.3-orig/src/main.h bitcoin-0.6.3/src/main.h --- bitcoin-0.6.3-orig/src/main.h 2012-06-19 13:44:55.000000000 -0700 +++ bitcoin-0.6.3/src/main.h 2012-07-09 11:56:21.333502571 -0700 @@ -395,6 +395,16 @@ mutable int nDoS; bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; } + bool electrum_flag; + + void set_electrum_flag(bool x){ + electrum_flag = x; + } + + bool get_electrum_flag(){ + return electrum_flag; + } + CTransaction() { SetNull(); @@ -416,6 +426,7 @@ vout.clear(); nLockTime = 0; nDoS = 0; // Denial-of-service prevention + set_electrum_flag(false); } bool IsNull() const