tree checksum vpatch file split hunks

all signers: mircea_popescu trinque mod6 asciilifeform ben_vulpes

antecedents: funken_prikey_tools mod6_privkey_tools asciilifeform_dns_thermonyukyoolar_kleansing asciilifeform_tx-orphanage_amputation asciilifeform_aggressive_pushgetblocks asciilifeform_aggressive_pushgetblocks makefiles

press order:

genesisasciilifeform ben_vulpes mircea_popescu mod6 trinque
bitcoin-asciilifeform.1asciilifeform ben_vulpes mod6
rm_rf_upnpasciilifeform ben_vulpes mod6
bitcoin-asciilifeform.3-turdmeister-alert-snipasciilifeform ben_vulpes mod6
asciilifeform_orphanage_thermonukeasciilifeform ben_vulpes mod6
bitcoin-asciilifeform.2-https_snipsnipasciilifeform ben_vulpes mod6
bitcoin-v0_5_3_1-static_makefile_v002.8asciilifeform ben_vulpes mod6
bitcoin-asciilifeform.4-goodbye-win32asciilifeform ben_vulpes mod6
bitcoin-v0_5_3_1-rev_bump.7asciilifeform ben_vulpes mod6
bitcoin-v0_5_3-db_config.6asciilifeform ben_vulpes mod6
asciilifeform_maxint_locks_correctedasciilifeform ben_vulpes mod6
asciilifeform_tx-orphanage_amputationasciilifeform ben_vulpes mod6
asciilifeform_dnsseed_snipsnipasciilifeform ben_vulpes mod6
asciilifeform_zap_hardcoded_seedsasciilifeform ben_vulpes mod6
asciilifeform_zap_showmyip_crudasciilifeform ben_vulpes mod6
asciilifeform_dns_thermonyukyoolar_kleansingasciilifeform ben_vulpes mod6
asciilifeform_ver_now_5_4_and_irc_is_gone_and_now_must_give_ipasciilifeform ben_vulpes mod6
asciilifeform-kills-integer-retardationasciilifeform ben_vulpes mod6
asciilifeform_and_now_we_have_block_dumper_correctedasciilifeform ben_vulpes mod6
mod6_fix_dumpblock_paramsasciilifeform ben_vulpes mod6
asciilifeform_and_now_we_have_eatblockasciilifeform ben_vulpes mod6
asciilifeform_lets_lose_testnetasciilifeform ben_vulpes mod6
asciilifeform_add_verifyall_optionasciilifeform ben_vulpes mod6
programmable-versionstringben_vulpes mod6
mod6_der_high_low_sben_vulpes mod6
mod6_privkey_toolsmod6
malleus_mikehearnificarumben_vulpes mod6
makefilesben_vulpes mod6 trinque
asciilifeform_aggressive_pushgetblocksasciilifeform mod6
asciilifeform_aggressive_pushgetblocksasciilifeform
funken_prikey_tools
ben_vulpes_excise_hash_truncationben_vulpes

patch:

- F8FCCCD44B3635182B65B09B51229BF30BD42E1DCFD91D66C57D82425B055DDFBB8F88249479B6C3AD45D21AE0C0C6CDD920F8AE44693C4256598EA2BB807007
+ 3AC9EF2C460D73D3376F8AD28423B75AAE47D89108E5EC7ADB6E86E315E5F095F66DB50069016CFC523E28D96BAEB022F66600302885CDA43E2CE302FED5D8E4
bitcoin/src/db.cpp
(578 . 7)(578 . 7)
5 pindexBest = mapBlockIndex[hashBestChain];
6 nBestHeight = pindexBest->nHeight;
7 bnBestChainWork = pindexBest->bnChainWork;
8 printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight);
9 printf("LoadBlockIndex(): hashBestChain=%s height=%d\n", hashBestChain.ToString().c_str(), nBestHeight);
10
11 // Load bnBestInvalidWork, OK if it doesn't exist
12 ReadBestInvalidWork(bnBestInvalidWork);
(836 . 14)(836 . 6)
14 }
15 vWalletUpgrade.push_back(hash);
16 }
17
18 //// debug print
19 //printf("LoadWallet %s\n", wtx.GetHash().ToString().c_str());
20 //printf(" %12I64d %s %s %s\n",
21 // wtx.vout[0].nValue,
22 // DateTimeStrFormat("%x %H:%M:%S", wtx.GetBlockTime()).c_str(),
23 // wtx.hashBlock.ToString().substr(0,20).c_str(),
24 // wtx.mapValue["message"].c_str());
25 }
26 else if (strType == "acentry")
27 {
- E76829B2488665287ED6037EAA5DD4651A67DDC9A44111089F55249248B6549387B9146BB1E51CC5A659558805BCF8987C10ECAD8478F83FC5EB165044AC5D3C
+ 91083AA2A87B340863C1A6E1D12075DAB306D8342813B4CADC383218E54657CA2A082AFB6067CC3CF42752504E850B619EC40809D7DD433524487D88C4B19E7E
bitcoin/src/main.cpp
(365 . 8)(365 . 8)
32 if (!ConnectInputs(txdb, mapUnused, CDiskTxPos(1,1,1), pindexBest, nFees, false, false, 0, fInvalid))
33 {
34 if (fInvalid)
35 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().substr(0,10).c_str());
36 return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().substr(0,10).c_str());
37 return error("AcceptToMemoryPool() : FetchInputs found invalid tx %s", hash.ToString().c_str());
38 return error("AcceptToMemoryPool() : ConnectInputs failed %s", hash.ToString().c_str());
39 }
40
41 // Don't accept it if it can't get into a block
(415 . 7)(415 . 7)
43 if (ptxOld)
44 EraseFromWallets(ptxOld->GetHash());
45
46 printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().substr(0,10).c_str());
47 printf("AcceptToMemoryPool(): accepted %s\n", hash.ToString().c_str());
48 return true;
49 }
50
(709 . 8)(709 . 8)
52 CTxDB().WriteBestInvalidWork(bnBestInvalidWork);
53 MainFrameRepaint();
54 }
55 printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().substr(0,20).c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
56 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
57 printf("InvalidChainFound: invalid block=%s height=%d work=%s\n", pindexNew->GetBlockHash().ToString().c_str(), pindexNew->nHeight, pindexNew->bnChainWork.ToString().c_str());
58 printf("InvalidChainFound: current best=%s height=%d work=%s\n", hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
59 if (pindexBest && bnBestInvalidWork > bnBestChainWork + pindexBest->GetBlockWork() * 6)
60 printf("InvalidChainFound: WARNING: Displayed transactions may not be correct! You may need to upgrade, or other nodes may need to upgrade.\n");
61 }
(796 . 7)(796 . 7)
63 fFound = txdb.ReadTxIndex(prevout.hash, txindex);
64 }
65 if (!fFound && (fBlock || fMiner))
66 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
67 return fMiner ? false : error("ConnectInputs() : %s prev tx %s index entry not found", GetHash().ToString().c_str(), prevout.hash.ToString().c_str());
68
69 // Read txPrev
70 CTransaction txPrev;
(806 . 7)(806 . 7)
72 CRITICAL_BLOCK(cs_mapTransactions)
73 {
74 if (!mapTransactions.count(prevout.hash))
75 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
76 return error("ConnectInputs() : %s mapTransactions prev not found %s", GetHash().ToString().c_str(), prevout.hash.ToString().c_str());
77 txPrev = mapTransactions[prevout.hash];
78 }
79 if (!fFound)
(816 . 7)(816 . 7)
81 {
82 // Get prev tx from disk
83 if (!txPrev.ReadFromDisk(txindex.pos))
84 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().substr(0,10).c_str(), prevout.hash.ToString().substr(0,10).c_str());
85 return error("ConnectInputs() : %s ReadFromDisk prev tx %s failed", GetHash().ToString().c_str(), prevout.hash.ToString().c_str());
86 }
87
88 if (prevout.n >= txPrev.vout.size() || prevout.n >= txindex.vSpent.size())
(824 . 7)(824 . 7)
90 // Revisit this if/when transaction replacement is implemented and allows
91 // adding inputs:
92 fInvalid = true;
93 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().substr(0,10).c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().substr(0,10).c_str(), txPrev.ToString().c_str()));
94 return DoS(100, error("ConnectInputs() : %s prevout.n out of range %d %d %d prev tx %s\n%s", GetHash().ToString().c_str(), prevout.n, txPrev.vout.size(), txindex.vSpent.size(), prevout.hash.ToString().c_str(), txPrev.ToString().c_str()));
95 }
96
97 // If prev is coinbase, check that it's matured
(839 . 13)(839 . 13)
99 if (fVerifyAll || (!(fBlock && (nBestHeight < Checkpoints::GetTotalBlocksEstimate()))))
100 // Verify signature
101 if (!VerifySignature(txPrev, *this, i))
102 return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().substr(0,10).c_str()));
103 return DoS(100,error("ConnectInputs() : %s VerifySignature failed", GetHash().ToString().c_str()));
104
105 // Check for conflicts (double-spend)
106 // This doesn't trigger the DoS code on purpose; if it did, it would make it easier
107 // for an attacker to attempt to split the network.
108 if (!txindex.vSpent[prevout.n].IsNull())
109 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().substr(0,10).c_str(), txindex.vSpent[prevout.n].ToString().c_str());
110 return fMiner ? false : error("ConnectInputs() : %s prev tx already used at %s", GetHash().ToString().c_str(), txindex.vSpent[prevout.n].ToString().c_str());
111
112 // Check for negative or overflow input values
113 nValueIn += txPrev.vout[prevout.n].nValue;
(863 . 12)(863 . 12)
115 }
116
117 if (nValueIn < GetValueOut())
118 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));
119 return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().c_str()));
120
121 // Tally transaction fees
122 int64 nTxFee = nValueIn - GetValueOut();
123 if (nTxFee < 0)
124 return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
125 return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().c_str()));
126 if (nTxFee < nMinFee)
127 return false;
128 nFees += nTxFee;
(1174 . 7)(1174 . 7)
130 bnBestChainWork = pindexNew->bnChainWork;
131 nTimeBestReceived = GetTime();
132 nTransactionsUpdated++;
133 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().substr(0,20).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
134 printf("SetBestChain: new best=%s height=%d work=%s\n", hashBestChain.ToString().c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
135
136 return true;
137 }
(1185 . 7)(1185 . 7)
139 // Check for duplicate
140 uint256 hash = GetHash();
141 if (mapBlockIndex.count(hash))
142 return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());
143 return error("AddToBlockIndex() : %s already exists", hash.ToString().c_str());
144
145 // Construct new block index object
146 CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
(1325 . 7)(1325 . 7)
148 // Check for duplicate
149 uint256 hash = pblock->GetHash();
150 if (mapBlockIndex.count(hash))
151 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
152 return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().c_str());
153
154 // Preliminary checks
155 if (!pblock->CheckBlock())
(1357 . 7)(1357 . 7)
157 // If don't already have its previous block, throw it out!
158 if (!mapBlockIndex.count(pblock->hashPrevBlock))
159 {
160 printf("ProcessBlock: BASTARD BLOCK, prev=%s, DISCARDED\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
161 printf("ProcessBlock: BASTARD BLOCK, prev=%s, DISCARDED\n", pblock->hashPrevBlock.ToString().c_str());
162
163 // Ask this guy to fill in what we're missing
164 if (pfrom)
(1553 . 7)(1553 . 7)
166 pindex->nHeight,
167 pindex->nFile,
168 pindex->nBlockPos,
169 block.GetHash().ToString().substr(0,20).c_str(),
170 block.GetHash().ToString().c_str(),
171 DateTimeStrFormat("%x %H:%M:%S", block.GetBlockTime()).c_str(),
172 block.vtx.size());
173
(1925 . 12)(1925 . 12)
175 pindex = pindex->pnext;
176 int nLimit = 500 + locator.GetDistanceBack();
177 unsigned int nBytes = 0;
178 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
179 printf("getblocks %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
180 for (; pindex; pindex = pindex->pnext)
181 {
182 if (pindex->GetBlockHash() == hashStop)
183 {
184 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
185 printf(" getblocks stopping at %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), nBytes);
186 break;
187 }
188 pfrom->PushInventory(CInv(MSG_BLOCK, pindex->GetBlockHash()));
(1941 . 7)(1941 . 7)
190 {
191 // When this block is requested, we'll send an inv that'll make them
192 // getblocks the next batch of inventory.
193 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().substr(0,20).c_str(), nBytes);
194 printf(" getblocks stopping at limit %d %s (%u bytes)\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str(), nBytes);
195 pfrom->hashContinue = pindex->GetBlockHash();
196 break;
197 }
(1974 . 7)(1974 . 7)
199
200 vector<CBlock> vHeaders;
201 int nLimit = 2000 + locator.GetDistanceBack();
202 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().substr(0,20).c_str(), nLimit);
203 printf("getheaders %d to %s limit %d\n", (pindex ? pindex->nHeight : -1), hashStop.ToString().c_str(), nLimit);
204 for (; pindex; pindex = pindex->pnext)
205 {
206 vHeaders.push_back(pindex->GetBlockHeader());
(2005 . 7)(2005 . 7)
208 }
209 else if (fMissingInputs)
210 {
211 printf("REJECTED orphan tx %s\n", inv.hash.ToString().substr(0,10).c_str());
212 printf("REJECTED orphan tx %s\n", inv.hash.ToString().c_str());
213 }
214 if (tx.nDoS) pfrom->Misbehaving(tx.nDoS);
215 }
(2016 . 7)(2016 . 7)
217 CBlock block;
218 vRecv >> block;
219
220 printf("received block %s\n", block.GetHash().ToString().substr(0,20).c_str());
221 printf("received block %s\n", block.GetHash().ToString().c_str());
222 // block.print();
223
224 CInv inv(MSG_BLOCK, block.GetHash());
(2524 . 9)(2524 . 9)
226
227 void print() const
228 {
229 printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().substr(0,10).c_str(), dPriority);
230 printf("COrphan(hash=%s, dPriority=%.1f)\n", ptx->GetHash().ToString().c_str(), dPriority);
231 BOOST_FOREACH(uint256 hash, setDependsOn)
232 printf(" setDependsOn %s\n", hash.ToString().substr(0,10).c_str());
233 printf(" setDependsOn %s\n", hash.ToString().c_str());
234 }
235 };
236
(2608 . 7)(2608 . 7)
238
239 if (fDebug && GetBoolArg("-printpriority"))
240 {
241 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
242 printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().c_str(), tx.ToString().c_str());
243 if (porphan)
244 porphan->print();
245 printf("\n");
- FF2BF8F8147DD8DF5E1EF1BCEA9B0159D3F83C1E30BEFEF56415B99305AA99161AC1C05EFB48BE87A383FFB6D621FD3761BFB3E4952CA244A6E1398CA3C71DC6
+ F15F152D522655F2A02A5FA4C5189D0D6D0FD4608370380D071D4BDB5B90F67F28FDC4FE43403A01FB42BF86271D656893482E09AD1E88155875748730B09BC5
bitcoin/src/main.h
(222 . 7)(222 . 7)
250
251 std::string ToString() const
252 {
253 return strprintf("COutPoint(%s, %d)", hash.ToString().substr(0,10).c_str(), n);
254 return strprintf("COutPoint(%s, %d)", hash.ToString().c_str(), n);
255 }
256
257 void print() const
(297 . 7)(297 . 7)
259 if (prevout.IsNull())
260 str += strprintf(", coinbase %s", HexStr(scriptSig).c_str());
261 else
262 str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24).c_str());
263 str += strprintf(", scriptSig=%s", scriptSig.ToString().c_str());
264 if (nSequence != UINT_MAX)
265 str += strprintf(", nSequence=%u", nSequence);
266 str += ")";
(371 . 7)(371 . 7)
268 {
269 if (scriptPubKey.size() < 6)
270 return "CTxOut(error)";
271 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30).c_str());
272 return strprintf("CTxOut(nValue=%"PRI64d".%08"PRI64d", scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().c_str());
273 }
274
275 void print() const
(608 . 7)(608 . 7)
277 {
278 std::string str;
279 str += strprintf("CTransaction(hash=%s, ver=%d, vin.size=%d, vout.size=%d, nLockTime=%d)\n",
280 GetHash().ToString().substr(0,10).c_str(),
281 GetHash().ToString().c_str(),
282 nVersion,
283 vin.size(),
284 vout.size(),
(954 . 10)(954 . 10)
286 void print() const
287 {
288 printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n",
289 GetHash().ToString().substr(0,20).c_str(),
290 GetHash().ToString().c_str(),
291 nVersion,
292 hashPrevBlock.ToString().substr(0,20).c_str(),
293 hashMerkleRoot.ToString().substr(0,10).c_str(),
294 hashPrevBlock.ToString().c_str(),
295 hashMerkleRoot.ToString().c_str(),
296 nTime, nBits, nNonce,
297 vtx.size());
298 for (int i = 0; i < vtx.size(); i++)
(967 . 7)(967 . 7)
300 }
301 printf(" vMerkleTree: ");
302 for (int i = 0; i < vMerkleTree.size(); i++)
303 printf("%s ", vMerkleTree[i].ToString().substr(0,10).c_str());
304 printf("%s ", vMerkleTree[i].ToString().c_str());
305 printf("\n");
306 }
307
(1138 . 8)(1138 . 8)
309 {
310 return strprintf("CBlockIndex(nprev=%08x, pnext=%08x, nFile=%d, nBlockPos=%-6d nHeight=%d, merkle=%s, hashBlock=%s)",
311 pprev, pnext, nFile, nBlockPos, nHeight,
312 hashMerkleRoot.ToString().substr(0,10).c_str(),
313 GetBlockHash().ToString().substr(0,20).c_str());
314 hashMerkleRoot.ToString().c_str(),
315 GetBlockHash().ToString().c_str());
316 }
317
318 void print() const
(1209 . 8)(1209 . 8)
320 str += CBlockIndex::ToString();
321 str += strprintf("\n hashBlock=%s, hashPrev=%s, hashNext=%s)",
322 GetBlockHash().ToString().c_str(),
323 hashPrev.ToString().substr(0,20).c_str(),
324 hashNext.ToString().substr(0,20).c_str());
325 hashPrev.ToString().c_str(),
326 hashNext.ToString().c_str());
327 return str;
328 }
329
- 35EFFBC7F73CDBDA92148BE58171B2337C090A7997EB3B02DAF9A88287B4315C80D7FA5EDF403BE9CF958969C0C7E0C1B578C10F146EE0EA9B2965A1F97971BF
+ 95FB7506570F1455E3E5E0B297970A6BCFA9E538C27ACA0DEA36944DFD3DD664E96F50716AAD1EEE7278E1AC89AE1443CCC795C75E870202DEA7EF27F1348F5A
bitcoin/src/protocol.cpp
(297 . 7)(297 . 7)
334
335 std::string CInv::ToString() const
336 {
337 return strprintf("%s %s", GetCommand(), hash.ToString().substr(0,20).c_str());
338 return strprintf("%s %s", GetCommand(), hash.ToString().c_str());
339 }
340
341 void CInv::print() const
- 5215203AB6BF6D76003D6E82B3C54145FB5F59B41AF5B88D72D315E0723FEA8E1313894707EC159D2303A22109B1D8961AA822AE2DD45416BD00E440832F6EE3
+ 9403DDF950C2E6FA556812F6A3925A0B78326A5580AA7BFBC563133414705A93EBCB3EEEA360449C579278161ECD58B52B5E1DD3EDCD719FD18639F9D7E67E89
bitcoin/src/wallet.cpp
(270 . 7)(270 . 7)
346 }
347
348 //// debug print
349 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
350 printf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString().c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
351
352 // Write to disk
353 if (fInsertedNew || fUpdated)
(467 . 7)(467 . 7)
355
356 }
357
358 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
359 void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
360 int64& nSent, int64& nFee) const
361 {
362 nGenerated = nReceived = nSent = nFee = 0;
(667 . 7)(667 . 7)
364 uint256 hash = GetHash();
365 if (!txdb.ContainsTx(hash))
366 {
367 printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
368 printf("Relaying wtx %s\n", hash.ToString().c_str());
369 RelayMessage(CInv(MSG_TX, hash), (CTransaction)*this);
370 }
371 }