7add15c738c598fcdc75499ed2a7d8eeb05800f6
[electrum-server.git] / patches / bitcoin-0.6.2.diff
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)
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 @@ -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 },
63  };
64  
65  CRPCTable::CRPCTable()
66 diff --git a/src/main.cpp b/src/main.cpp
67 index 427e435..35a0aea 100644
68 --- a/src/main.cpp
69 +++ b/src/main.cpp
70 @@ -3134,156 +3134,28 @@ CBlock* CreateNewBlock(CReserveKey& reservekey)
71      if (!pblock.get())
72          return NULL;
73  
74 -    // Create coinbase tx
75 -    CTransaction txNew;
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;
80 -
81 -    // Add our coinbase tx as first transaction
82 -    pblock->vtx.push_back(txNew);
83 -
84      // Collect memory pool transactions into the block
85 -    int64 nFees = 0;
86      {
87          LOCK2(cs_main, mempool.cs);
88          CTxDB txdb("r");
89  
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)
95 -        {
96 -            CTransaction& tx = (*mi).second;
97 -            if (tx.IsCoinBase() || !tx.IsFinal())
98 -                continue;
99 -
100 -            COrphan* porphan = NULL;
101 -            double dPriority = 0;
102 -            BOOST_FOREACH(const CTxIn& txin, tx.vin)
103 -            {
104 -                // Read prev transaction
105 -                CTransaction txPrev;
106 -                CTxIndex txindex;
107 -                if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
108 -                {
109 -                    // Has to wait for dependencies
110 -                    if (!porphan)
111 -                    {
112 -                        // Use list for automatic deletion
113 -                        vOrphan.push_back(COrphan(&tx));
114 -                        porphan = &vOrphan.back();
115 -                    }
116 -                    mapDependers[txin.prevout.hash].push_back(porphan);
117 -                    porphan->setDependsOn.insert(txin.prevout.hash);
118 -                    continue;
119 -                }
120 -                int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
121 -
122 -                // Read block header
123 -                int nConf = txindex.GetDepthInMainChain();
124 -
125 -                dPriority += (double)nValueIn * nConf;
126 -
127 -                if (fDebug && GetBoolArg("-printpriority"))
128 -                    printf("priority     nValueIn=%-12I64d nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
129 -            }
130 -
131 -            // Priority is sum(valuein * age) / txsize
132 -            dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
133 -
134 -            if (porphan)
135 -                porphan->dPriority = dPriority;
136 -            else
137 -                mapPriority.insert(make_pair(-dPriority, &(*mi).second));
138 -
139 -            if (fDebug && GetBoolArg("-printpriority"))
140 -            {
141 -                printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
142 -                if (porphan)
143 -                    porphan->print();
144 -                printf("\n");
145 -            }
146 -        }
147 -
148 -        // Collect transactions into block
149 -        map<uint256, CTxIndex> mapTestPool;
150 -        uint64 nBlockSize = 1000;
151          uint64 nBlockTx = 0;
152 -        int nBlockSigOps = 100;
153 -        while (!mapPriority.empty())
154 +        for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
155          {
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());
160 -
161 -            // Size limits
162 -            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
163 -            if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
164 -                continue;
165 -
166 -            // Legacy limits on sigOps:
167 -            unsigned int nTxSigOps = tx.GetLegacySigOpCount();
168 -            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
169 -                continue;
170 -
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);
174 -
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;
179 -            bool fInvalid;
180 -            if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
181 -                continue;
182 +         CTransaction& tx = (*mi).second;
183 +         if (tx.IsCoinBase() || !tx.IsFinal())
184 +           continue;
185  
186 -            int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
187 -            if (nTxFees < nMinFee)
188 -                continue;
189 -
190 -            nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
191 -            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
192 -                continue;
193 -
194 -            if (!tx.ConnectInputs(mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
195 -                continue;
196 -            mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
197 -            swap(mapTestPool, mapTestPoolTmp);
198 -
199 -            // Added
200 -            pblock->vtx.push_back(tx);
201 -            nBlockSize += nTxSize;
202 -            ++nBlockTx;
203 -            nBlockSigOps += nTxSigOps;
204 -            nFees += nTxFees;
205 -
206 -            // Add transactions that depend on this one to the priority queue
207 -            uint256 hash = tx.GetHash();
208 -            if (mapDependers.count(hash))
209 -            {
210 -                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
211 -                {
212 -                    if (!porphan->setDependsOn.empty())
213 -                    {
214 -                        porphan->setDependsOn.erase(hash);
215 -                        if (porphan->setDependsOn.empty())
216 -                            mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
217 -                    }
218 -                }
219 -            }
220 +         if (!tx.get_electrum_flag())
221 +           {
222 +               tx.set_electrum_flag(true);
223 +               pblock->vtx.push_back(tx);
224 +               ++nBlockTx;
225 +           }
226          }
227  
228 -        nLastBlockTx = nBlockTx;
229 -        nLastBlockSize = nBlockSize;
230 -        printf("CreateNewBlock(): total size %lu\n", nBlockSize);
231 -
232 +        printf("CreateNewBlock(): transactions: %lu\n", nBlockTx);
233      }
234 -    pblock->vtx[0].vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees);
235  
236      // Fill in header
237      pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
238 diff --git a/src/main.h b/src/main.h
239 index 262e77e..4cc9319 100644
240 --- a/src/main.h
241 +++ b/src/main.h
242 @@ -395,6 +395,16 @@ public:
243      mutable int nDoS;
244      bool DoS(int nDoSIn, bool fIn) const { nDoS += nDoSIn; return fIn; }
245  
246 +    bool electrum_flag;
247 +
248 +    void set_electrum_flag(bool x){
249 +      electrum_flag = x;
250 +    }
251 +
252 +    bool get_electrum_flag(){
253 +      return electrum_flag;
254 +    }
255 +
256      CTransaction()
257      {
258          SetNull();
259 @@ -416,6 +426,7 @@ public:
260          vout.clear();
261          nLockTime = 0;
262          nDoS = 0;  // Denial-of-service prevention
263 +       set_electrum_flag(false);
264      }
265  
266      bool IsNull() const