b55e8c83c9ba41bc0f04dfce75c17ccbb3801479
[electrum-server.git] / patches / bitcoin-0.6.2.diff
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)
6  }
7  
8  
9 +Value importtransaction(const Array& params, bool fHelp)
10 +{
11 +  string hexdump;
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");
16 +
17 +  std::vector<unsigned char> rawtx;
18 +  for (int i=0; i<hexdump.size(); i+=2)
19 +    {
20 +      int v;
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);
24 +    }
25 +try
26 +  {
27 +    CDataStream ss(rawtx, SER_NETWORK, PROTOCOL_VERSION);
28 +    CTransaction tx;
29 +    ss >> tx;
30 +    CInv inv(MSG_TX, tx.GetHash());
31 +
32 +    CTxDB txdb("r");
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();
37 +  }
38 + catch (std::exception& e)
39 +   {
40 +     throw JSONRPCError(-4, "Exception while parsing the transaction data.");
41 +   }
42 +
43 +}
44 +
45 +
46  Value backupwallet(const Array& params, bool fHelp)
47  {
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 },
54  };
55  
56  CRPCTable::CRPCTable()
57 diff --git a/src/main.cpp b/src/main.cpp
58 index 427e435..35a0aea 100644
59 --- a/src/main.cpp
60 +++ b/src/main.cpp
61 @@ -3134,156 +3134,28 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
62      if (!pblock.get())
63          return NULL;
64  
65 -    // Create coinbase tx
66 -    CTransaction txNew;
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;
71 -
72 -    // Add our coinbase tx as first transaction
73 -    pblock->vtx.push_back(txNew);
74 -
75      // Collect memory pool transactions into the block
76 -    int64 nFees = 0;
77      {
78          LOCK2(cs_main, mempool.cs);
79          CTxDB txdb("r");
80  
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)
86 -        {
87 -            CTransaction& tx = (*mi).second;
88 -            if (tx.IsCoinBase() || !tx.IsFinal())
89 -                continue;
90 -
91 -            COrphan* porphan = NULL;
92 -            double dPriority = 0;
93 -            BOOST_FOREACH(const CTxIn& txin, tx.vin)
94 -            {
95 -                // Read prev transaction
96 -                CTransaction txPrev;
97 -                CTxIndex txindex;
98 -                if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
99 -                {
100 -                    // Has to wait for dependencies
101 -                    if (!porphan)
102 -                    {
103 -                        // Use list for automatic deletion
104 -                        vOrphan.push_back(COrphan(&tx));
105 -                        porphan = &vOrphan.back();
106 -                    }
107 -                    mapDependers[txin.prevout.hash].push_back(porphan);
108 -                    porphan->setDependsOn.insert(txin.prevout.hash);
109 -                    continue;
110 -                }
111 -                int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
112 -
113 -                // Read block header
114 -                int nConf = txindex.GetDepthInMainChain();
115 -
116 -                dPriority += (double)nValueIn * nConf;
117 -
118 -                if (fDebug && GetBoolArg("-printpriority"))
119 -                    printf("priority     nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
120 -            }
121 -
122 -            // Priority is sum(valuein * age) / txsize
123 -            dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
124 -
125 -            if (porphan)
126 -                porphan->dPriority = dPriority;
127 -            else
128 -                mapPriority.insert(make_pair(-dPriority, &(*mi).second));
129 -
130 -            if (fDebug && GetBoolArg("-printpriority"))
131 -            {
132 -                printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
133 -                if (porphan)
134 -                    porphan->print();
135 -                printf("\n");
136 -            }
137 -        }
138 -
139 -        // Collect transactions into block
140 -        map<uint256, CTxIndex> mapTestPool;
141 -        uint64 nBlockSize = 1000;
142          uint64 nBlockTx = 0;
143 -        int nBlockSigOps = 100;
144 -        while (!mapPriority.empty())
145 +        for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
146          {
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());
151 -
152 -            // Size limits
153 -            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
154 -            if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
155 -                continue;
156 -
157 -            // Legacy limits on sigOps:
158 -            unsigned int nTxSigOps = tx.GetLegacySigOpCount();
159 -            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
160 -                continue;
161 -
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);
165 -
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;
170 -            bool fInvalid;
171 -            if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
172 -                continue;
173 +         CTransaction& tx = (*mi).second;
174 +         if (tx.IsCoinBase() || !tx.IsFinal())
175 +           continue;
176  
177 -            int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
178 -            if (nTxFees < nMinFee)
179 -                continue;
180 -
181 -            nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
182 -            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
183 -                continue;
184 -
185 -            if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
186 -                continue;
187 -            mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
188 -            swap(mapTestPool, mapTestPoolTmp);
189 -
190 -            // Added
191 -            pblock->vtx.push_back(tx);
192 -            nBlockSize += nTxSize;
193 -            ++nBlockTx;
194 -            nBlockSigOps += nTxSigOps;
195 -            nFees += nTxFees;
196 -
197 -            // Add transactions that depend on this one to the priority queue
198 -            uint256 hash = tx.GetHash();
199 -            if (mapDependers.count(hash))
200 -            {
201 -                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
202 -                {
203 -                    if (!porphan->setDependsOn.empty())
204 -                    {
205 -                        porphan->setDependsOn.erase(hash);
206 -                        if (porphan->setDependsOn.empty())
207 -                            mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
208 -                    }
209 -                }
210 -            }
211 +         if (!tx.get_electrum_flag())
212 +           {
213 +               tx.set_electrum_flag(true);
214 +               pblock->vtx.push_back(tx);
215 +               ++nBlockTx;
216 +           }
217          }
218  
219 -        nLastBlockTx = nBlockTx;
220 -        nLastBlockSize = nBlockSize;
221 -        printf("CreateNewBlock(): total size %lu\n", nBlockSize);
222 -
223 +        printf("CreateNewBlock(): transactions: %lu\n", nBlockTx);
224      }
225 -    pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
226  
227      // Fill in header
228      pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
229 diff --git a/src/main.h b/src/main.h
230 index 262e77e..4cc9319 100644
231 --- a/src/main.h
232 +++ b/src/main.h
233 @@ -395,6 +395,16 @@ public:
234      mutable int nDoS;
235      bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
236  
237 +    bool electrum_flag;
238 +
239 +    void set_electrum_flag(bool x){
240 +      electrum_flag = x;
241 +    }
242 +
243 +    bool get_electrum_flag(){
244 +      return electrum_flag;
245 +    }
246 +
247      CTransaction()
248      {
249          SetNull();
250 @@ -416,6 +426,7 @@ public:
251          vout.clear();
252          nLockTime = 0;
253          nDoS = 0;  // Denial-of-service prevention
254 +       set_electrum_flag(false);
255      }
256  
257      bool IsNull() const