Advertisement
Guest User

bitcoin-0.9.3.ljr20141002.patch

a guest
Oct 10th, 2014
6,823
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 95.05 KB | None | 0 0
  1. diff --git a/configure.ac b/configure.ac
  2. index 1c004cf..03d8e16 100644
  3. --- a/configure.ac
  4. +++ b/configure.ac
  5. @@ -77,6 +77,15 @@ AC_ARG_ENABLE([comparison-tool-reorg-tests],
  6.      [use_comparison_tool_reorg_tests=$enableval],
  7.      [use_comparison_tool_reorg_tests=no])
  8.  
  9. +AC_ARG_ENABLE([first-class-messaging],
  10. +    AS_HELP_STRING([--enable-first-class-messaging],[put messaging tools in a tab rather than popup window (default no)]),
  11. +    [use_first_class_messaging=$enableval],
  12. +    [use_first_class_messaging=no])
  13. +
  14. +if test "x$use_first_class_messaging" = xyes; then
  15. +    AC_DEFINE([FIRST_CLASS_MESSAGING],[1],[Define to 1 to use tabs instead of windows for messaging tools])
  16. +fi
  17. +
  18.  AC_ARG_WITH([qrencode],
  19.    [AS_HELP_STRING([--with-qrencode],
  20.    [enable QR code support (default is yes if qt is enabled and libqrencode is found)])],
  21. @@ -381,10 +390,22 @@ AC_TRY_COMPILE([#include <sys/socket.h>],
  22.   [ AC_MSG_RESULT(no)]
  23.  )
  24.  
  25. +dnl Check for leveldb, only if explicitly requested
  26.  LEVELDB_CPPFLAGS=
  27.  LIBLEVELDB=
  28.  LIBMEMENV=
  29. -AM_CONDITIONAL([EMBEDDED_LEVELDB],[true])
  30. +AC_ARG_WITH([system-leveldb],
  31. +  [AS_HELP_STRING([--with-system-leveldb],
  32. +  [Build with system LevelDB (default is no; DANGEROUS; NOT SUPPORTED)])],
  33. +  [system_leveldb=$withval],
  34. +  [system_leveldb=no]
  35. +)
  36. +if test x$system_leveldb != xno; then
  37. +  LEVELDB_CPPFLAGS=
  38. +  LIBLEVELDB=-lleveldb
  39. +  LIBMEMENV=-lmemenv
  40. +fi
  41. +AM_CONDITIONAL([EMBEDDED_LEVELDB],[test x$system_leveldb = xno])
  42.  AC_SUBST(LEVELDB_CPPFLAGS)
  43.  AC_SUBST(LIBLEVELDB)
  44.  AC_SUBST(LIBMEMENV)
  45. diff --git a/src/init.cpp b/src/init.cpp
  46. index de66151..19ce851 100644
  47. --- a/src/init.cpp
  48. +++ b/src/init.cpp
  49. @@ -230,6 +230,7 @@ std::string HelpMessage(HelpMessageMode hmm)
  50.      strUsage += "  -maxsendbuffer=<n>     " + _("Maximum per-connection send buffer, <n>*1000 bytes (default: 1000)") + "\n";
  51.      strUsage += "  -onion=<ip:port>       " + _("Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: -proxy)") + "\n";
  52.      strUsage += "  -onlynet=<net>         " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n";
  53. +    strUsage += "  -permitbaremultisig    " + _("Relay non-P2SH multisig (default: 1)") + "\n";
  54.      strUsage += "  -port=<port>           " + _("Listen for connections on <port> (default: 8333 or testnet: 18333)") + "\n";
  55.      strUsage += "  -proxy=<ip:port>       " + _("Connect through SOCKS proxy") + "\n";
  56.      strUsage += "  -seednode=<ip>         " + _("Connect to a node to retrieve peer addresses, and disconnect") + "\n";
  57. @@ -289,6 +290,7 @@ std::string HelpMessage(HelpMessageMode hmm)
  58.      }
  59.      strUsage += "  -mintxfee=<amt>        " + _("Fees smaller than this are considered zero fee (for transaction creation) (default:") + " " + FormatMoney(CTransaction::nMinTxFee) + ")" + "\n";
  60.      strUsage += "  -minrelaytxfee=<amt>   " + _("Fees smaller than this are considered zero fee (for relaying) (default:") + " " + FormatMoney(CTransaction::nMinRelayTxFee) + ")" + "\n";
  61. +    strUsage += "  -permitbaremultisig    " + _("Relay non-P2SH multisig (default: 0)") + "\n";
  62.      strUsage += "  -printtoconsole        " + _("Send trace/debug info to console instead of debug.log file") + "\n";
  63.      if (GetBoolArg("-help-debug", false))
  64.      {
  65. @@ -303,6 +305,10 @@ std::string HelpMessage(HelpMessageMode hmm)
  66.      strUsage += "  -shrinkdebugfile       " + _("Shrink debug.log file on client startup (default: 1 when no -debug)") + "\n";
  67.      strUsage += "  -testnet               " + _("Use the test network") + "\n";
  68.  
  69. +    strUsage += "\n" + _("Node relay options:") + "\n";
  70. +    strUsage += "  -acceptnonstdtxn       " + _("Accept \"non-standard\" transactions for relay and blocks") + "\n";
  71. +    strUsage += "  -datacarrier           " + _("Relay and mine data carrier transactions (default: 1)") + "\n";
  72. +
  73.      strUsage += "\n" + _("Block creation options:") + "\n";
  74.      strUsage += "  -blockminsize=<n>      " + _("Set minimum block size in bytes (default: 0)") + "\n";
  75.      strUsage += "  -blockmaxsize=<n>      " + strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE) + "\n";
  76. @@ -604,9 +610,13 @@ bool AppInit2(boost::thread_group& threadGroup)
  77.              InitWarning(_("Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
  78.      }
  79.      bSpendZeroConfChange = GetArg("-spendzeroconfchange", true);
  80. +    fIsBareMultisigStd = GetArg("-permitbaremultisig", false);
  81.  
  82.      strWalletFile = GetArg("-wallet", "wallet.dat");
  83. -#endif
  84. +#endif // ENABLE_WALLET
  85. +
  86. +    fIsBareMultisigStd = GetArg("-permitbaremultisig", true);
  87. +
  88.      // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
  89.      // Sanity check
  90.      if (!InitSanityCheck())
  91. diff --git a/src/main.cpp b/src/main.cpp
  92. index d172690..987c563 100644
  93. --- a/src/main.cpp
  94. +++ b/src/main.cpp
  95. @@ -22,6 +22,9 @@
  96.  #include <boost/algorithm/string/replace.hpp>
  97.  #include <boost/filesystem.hpp>
  98.  #include <boost/filesystem/fstream.hpp>
  99. +#include <boost/thread/condition_variable.hpp>
  100. +#include <boost/thread/locks.hpp>
  101. +#include <boost/thread/mutex.hpp>
  102.  
  103.  using namespace std;
  104.  using namespace boost;
  105. @@ -42,6 +45,8 @@ map<uint256, CBlockIndex*> mapBlockIndex;
  106.  CChain chainActive;
  107.  CChain chainMostWork;
  108.  int64_t nTimeBestReceived = 0;
  109. +boost::mutex csBestBlock;
  110. +boost::condition_variable cvBlockChange;
  111.  int nScriptCheckThreads = 0;
  112.  bool fImporting = false;
  113.  bool fReindex = false;
  114. @@ -498,6 +503,18 @@ unsigned int LimitOrphanTxSize(unsigned int nMaxOrphans)
  115.  
  116.  
  117.  
  118. +bool IsPushCanonicalTx(const CTransaction& tx, string& reason)
  119. +{
  120. +    BOOST_FOREACH(const CTxIn& txin, tx.vin)
  121. +    {
  122. +        if (!txin.scriptSig.HasCanonicalPushes()) {
  123. +            reason = "scriptsig-non-canonical-push";
  124. +            return false;
  125. +        }
  126. +    }
  127. +    return true;
  128. +}
  129. +
  130.  bool IsStandardTx(const CTransaction& tx, string& reason)
  131.  {
  132.      AssertLockHeld(cs_main);
  133. @@ -555,22 +572,27 @@ bool IsStandardTx(const CTransaction& tx, string& reason)
  134.              reason = "scriptsig-not-pushonly";
  135.              return false;
  136.          }
  137. -        if (!txin.scriptSig.HasCanonicalPushes()) {
  138. -            reason = "scriptsig-non-canonical-push";
  139. -            return false;
  140. -        }
  141.      }
  142. +    if (!IsPushCanonicalTx(tx, reason))
  143. +        return false;
  144.  
  145. +    unsigned int verfFlags = 0;
  146. +    if (fIsBareMultisigStd)
  147. +        verfFlags |= SCRIPT_VERIFY_BARE_MSIG_OK;
  148.      unsigned int nDataOut = 0;
  149.      txnouttype whichType;
  150.      BOOST_FOREACH(const CTxOut& txout, tx.vout) {
  151. -        if (!::IsStandard(txout.scriptPubKey, whichType)) {
  152. +        if (!::IsStandard(txout.scriptPubKey, whichType, verfFlags)) {
  153.              reason = "scriptpubkey";
  154.              return false;
  155.          }
  156. +
  157.          if (whichType == TX_NULL_DATA)
  158.              nDataOut++;
  159. -        else if (txout.IsDust(CTransaction::nMinRelayTxFee)) {
  160. +        else if ((whichType == TX_MULTISIG) && (!fIsBareMultisigStd)) {
  161. +            reason = "bare-multisig";
  162. +            return false;
  163. +        } else if (txout.IsDust(CTransaction::nMinRelayTxFee)) {
  164.              reason = "dust";
  165.              return false;
  166.          }
  167. @@ -810,6 +832,16 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state)
  168.  
  169.  int64_t GetMinFee(const CTransaction& tx, unsigned int nBytes, bool fAllowFree, enum GetMinFee_mode mode)
  170.  {
  171. +    {
  172. +        LOCK(mempool.cs);
  173. +        uint256 hash = tx.GetHash();
  174. +        double dPriorityDelta = 0;
  175. +        int64_t nFeeDelta = 0;
  176. +        mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
  177. +        if (dPriorityDelta > 0 || nFeeDelta > 0)
  178. +            return 0;
  179. +    }
  180. +
  181.      // Base fee is either nMinTxFee or nMinRelayTxFee
  182.      int64_t nBaseFee = (mode == GMF_RELAY) ? tx.nMinRelayTxFee : tx.nMinTxFee;
  183.  
  184. @@ -859,11 +891,24 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
  185.                           REJECT_INVALID, "coinbase");
  186.  
  187.      // Rather not work on nonstandard transactions (unless -testnet/-regtest)
  188. +    bool fIsNonStandard = false;
  189.      string reason;
  190.      if (Params().NetworkID() == CChainParams::MAIN && !IsStandardTx(tx, reason))
  191. -        return state.DoS(0,
  192. -                         error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
  193. -                         REJECT_NONSTANDARD, reason);
  194. +    {
  195. +        fIsNonStandard = true;
  196. +        if ((!GetBoolArg("-acceptnonstdtxn", false)) || !IsPushCanonicalTx(tx, reason))
  197. +            return state.DoS(0,
  198. +                             error("AcceptToMemoryPool : nonstandard transaction: %s", reason),
  199. +                             REJECT_NONSTANDARD, reason);
  200. +    }
  201. +
  202. +    const char *blacklistname;
  203. +    BOOST_FOREACH(const CTxOut& txout, tx.vout)
  204. +    {
  205. +        blacklistname = txout.scriptPubKey.IsBlacklisted();
  206. +        if (blacklistname)
  207. +            return error("AcceptToMemoryPool : ignoring transaction %s with blacklisted output (%s)", tx.GetHash().ToString().c_str(), blacklistname);
  208. +    }
  209.  
  210.      // is it already in the memory pool?
  211.      uint256 hash = tx.GetHash();
  212. @@ -920,13 +965,23 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
  213.          view.SetBackend(dummy);
  214.          }
  215.  
  216. +        BOOST_FOREACH(const CTxIn txin, tx.vin)
  217. +        {
  218. +            const COutPoint &outpoint = txin.prevout;
  219. +            const CCoins &coins = view.GetCoins(outpoint.hash);
  220. +            assert(coins.IsAvailable(outpoint.n));
  221. +            blacklistname = coins.vout[outpoint.n].scriptPubKey.IsBlacklisted();
  222. +            if (blacklistname)
  223. +                return error("CTxMemPool::accept() : ignoring transaction %s with blacklisted input (%s)", tx.GetHash().ToString().c_str(), blacklistname);
  224. +        }
  225. +
  226.          // Check for non-standard pay-to-script-hash in inputs
  227.          if (Params().NetworkID() == CChainParams::MAIN && !AreInputsStandard(tx, view))
  228. -            return error("AcceptToMemoryPool: : nonstandard transaction input");
  229. -
  230. -        // Note: if you modify this code to accept non-standard transactions, then
  231. -        // you should add code here to check that the transaction does a
  232. -        // reasonable number of ECDSA signature verifications.
  233. +        {
  234. +            fIsNonStandard = true;
  235. +            if (!GetBoolArg("-acceptnonstdtxn", false))
  236. +                return error("AcceptToMemoryPool: : nonstandard transaction input");
  237. +        }
  238.  
  239.          int64_t nValueIn = view.GetValueIn(tx);
  240.          int64_t nValueOut = tx.GetValueOut();
  241. @@ -936,6 +991,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
  242.          CTxMemPoolEntry entry(tx, nFees, GetTime(), dPriority, chainActive.Height());
  243.          unsigned int nSize = entry.GetTxSize();
  244.  
  245. +        if (fIsNonStandard)
  246. +        {
  247. +            // Unnecessary/implied for standard transactions
  248. +            long nBytesPerSigOp = GetArg("-bytespersigop", 0);
  249. +            int nSigOps = GetLegacySigOpCount(tx);
  250. +            nSigOps += GetP2SHSigOpCount(tx, view);
  251. +
  252. +            if (nBytesPerSigOp && nSigOps > nSize / nBytesPerSigOp)
  253. +                return error("AcceptToMemoryPool : transaction with out-of-bounds SigOpCount");
  254. +        }
  255. +
  256.          // Don't accept it if it can't get into a block
  257.          int64_t txMinFee = GetMinFee(tx, nSize, true, GMF_RELAY);
  258.          if (fLimitFree && nFees < txMinFee)
  259. @@ -1316,18 +1382,18 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
  260.      return bnNew.GetCompact();
  261.  }
  262.  
  263. -bool CheckProofOfWork(uint256 hash, unsigned int nBits)
  264. +bool CheckProofOfWork(uint256 hash, unsigned int nBits, bool fSilent)
  265.  {
  266.      CBigNum bnTarget;
  267.      bnTarget.SetCompact(nBits);
  268.  
  269.      // Check range
  270.      if (bnTarget <= 0 || bnTarget > Params().ProofOfWorkLimit())
  271. -        return error("CheckProofOfWork() : nBits below minimum work");
  272. +        return fSilent ? false : error("CheckProofOfWork() : nBits below minimum work");
  273.  
  274.      // Check proof of work matches claimed amount
  275.      if (hash > bnTarget.getuint256())
  276. -        return error("CheckProofOfWork() : hash doesn't match nBits");
  277. +        return fSilent ? false : error("CheckProofOfWork() : hash doesn't match nBits");
  278.  
  279.      return true;
  280.  }
  281. @@ -1943,11 +2009,14 @@ void static UpdateTip(CBlockIndex *pindexNew) {
  282.      // New best block
  283.      nTimeBestReceived = GetTime();
  284.      mempool.AddTransactionsUpdated(1);
  285. +
  286.      LogPrintf("UpdateTip: new best=%s  height=%d  log2_work=%.8g  tx=%lu  date=%s progress=%f\n",
  287.        chainActive.Tip()->GetBlockHash().ToString(), chainActive.Height(), log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx,
  288.        DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
  289.        Checkpoints::GuessVerificationProgress(chainActive.Tip()));
  290.  
  291. +    cvBlockChange.notify_all();
  292. +
  293.      // Check the version of the last 100 blocks to see if we need to upgrade:
  294.      if (!fIsInitialDownload)
  295.      {
  296. @@ -2041,6 +2110,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew) {
  297.          list<CTransaction> unused;
  298.          mempool.remove(tx, unused);
  299.          mempool.removeConflicts(tx, txConflicted);
  300. +        mempool.ClearPrioritisation(tx.GetHash());
  301.      }
  302.      mempool.check(pcoinsTip);
  303.      // Update chainActive & related variables.
  304. @@ -2378,7 +2448,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
  305.      return true;
  306.  }
  307.  
  308. -bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
  309. +bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp, bool fWriteToDisk)
  310.  {
  311.      AssertLockHeld(cs_main);
  312.      // Check for duplicate
  313. @@ -2448,6 +2518,9 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp)
  314.          }
  315.      }
  316.  
  317. +    if (!fWriteToDisk)
  318. +        return true;
  319. +
  320.      // Write block to history file
  321.      try {
  322.          unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
  323. @@ -2515,7 +2588,7 @@ void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd)
  324.      pnode->PushMessage("getblocks", chainActive.GetLocator(pindexBegin), hashEnd);
  325.  }
  326.  
  327. -bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp)
  328. +bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp, bool fCheckPOW)
  329.  {
  330.      AssertLockHeld(cs_main);
  331.  
  332. @@ -2527,9 +2600,16 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
  333.          return state.Invalid(error("ProcessBlock() : already have block (orphan) %s", hash.ToString()), 0, "duplicate");
  334.  
  335.      // Preliminary checks
  336. -    if (!CheckBlock(*pblock, state))
  337. +    if (!CheckBlock(*pblock, state, fCheckPOW))
  338.          return error("ProcessBlock() : CheckBlock FAILED");
  339.  
  340. +    bool fHasPOW = fCheckPOW;
  341. +    if (!fHasPOW)
  342. +    {
  343. +        CValidationState dummy;
  344. +        fHasPOW = CheckProofOfWork(pblock->GetHash(), pblock->nBits, true);
  345. +    }
  346. +
  347.      CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex);
  348.      if (pcheckpoint && pblock->hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0)))
  349.      {
  350. @@ -2574,13 +2654,27 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
  351.              // Ask this guy to fill in what we're missing
  352.              PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(hash));
  353.          }
  354. -        return true;
  355. +        // The block is accepted, but not immediately processed
  356. +        return state.Orphan();
  357.      }
  358.  
  359.      // Store to disk
  360. -    if (!AcceptBlock(*pblock, state, dbp))
  361. +    if (!AcceptBlock(*pblock, state, dbp, fHasPOW))
  362.          return error("ProcessBlock() : AcceptBlock FAILED");
  363.  
  364. +    if (!fHasPOW)
  365. +    {
  366. +        // The block isn't committed to disk since it was just a proposal, but we need to do connect checks still
  367. +        CBlockIndex* pindexPrev = mapBlockIndex[pblock->hashPrevBlock];
  368. +        if (pblock->hashPrevBlock != pcoinsTip->GetBestBlock())
  369. +            return state.Invalid("stale-prevblk", error("ProcessBlock() : proposed block built on non-best %s", pblock->hashPrevBlock.ToString().c_str()));
  370. +        CBlockIndex indexDummy(*pblock);
  371. +        indexDummy.pprev = pindexPrev;
  372. +        indexDummy.nHeight = pindexPrev->nHeight + 1;
  373. +        CCoinsViewCache viewNew(*pcoinsTip, true);
  374. +        return ConnectBlock(*pblock, state, &indexDummy, viewNew, true);
  375. +    }
  376. +
  377.      // Recursively process any orphan blocks that depended on this one
  378.      vector<uint256> vWorkQueue;
  379.      vWorkQueue.push_back(hash);
  380. @@ -3499,6 +3593,11 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
  381.              }
  382.          }
  383.  
  384. +        // Trigger download of remote node's memory pool
  385. +        if (!IsInitialBlockDownload() && !pfrom->fInbound &&
  386. +            pfrom->nVersion >= MEMPOOL_GD_VERSION)
  387. +            pfrom->PushMessage("mempool");
  388. +
  389.          // Relay alerts
  390.          {
  391.              LOCK(cs_mapAlerts);
  392. diff --git a/src/main.h b/src/main.h
  393. index dc50dff..4e7bf0f 100644
  394. --- a/src/main.h
  395. +++ b/src/main.h
  396. @@ -29,6 +29,9 @@
  397.  #include <utility>
  398.  #include <vector>
  399.  
  400. +#include <boost/thread/condition_variable.hpp>
  401. +#include <boost/thread/mutex.hpp>
  402. +
  403.  class CBlockIndex;
  404.  class CBloomFilter;
  405.  class CInv;
  406. @@ -92,11 +95,14 @@ extern uint64_t nLastBlockTx;
  407.  extern uint64_t nLastBlockSize;
  408.  extern const std::string strMessageMagic;
  409.  extern int64_t nTimeBestReceived;
  410. +extern boost::mutex csBestBlock;
  411. +extern boost::condition_variable cvBlockChange;
  412.  extern bool fImporting;
  413.  extern bool fReindex;
  414.  extern bool fBenchmark;
  415.  extern int nScriptCheckThreads;
  416.  extern bool fTxIndex;
  417. +extern bool fIsBareMultisigStd;
  418.  extern unsigned int nCoinCacheSize;
  419.  
  420.  // Minimum disk space required - used in CheckDiskSpace()
  421. @@ -131,7 +137,7 @@ void UnregisterNodeSignals(CNodeSignals& nodeSignals);
  422.  void PushGetBlocks(CNode* pnode, CBlockIndex* pindexBegin, uint256 hashEnd);
  423.  
  424.  /** Process an incoming block */
  425. -bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL);
  426. +bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBlockPos *dbp = NULL, bool fCheckPOW = true);
  427.  /** Check whether enough disk space is available for an incoming block */
  428.  bool CheckDiskSpace(uint64_t nAdditionalBytes = 0);
  429.  /** Open a block file (blk?????.dat) */
  430. @@ -157,7 +163,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle);
  431.  /** Run an instance of the script checking thread */
  432.  void ThreadScriptCheck();
  433.  /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
  434. -bool CheckProofOfWork(uint256 hash, unsigned int nBits);
  435. +bool CheckProofOfWork(uint256 hash, unsigned int nBits, bool fSilent = false);
  436.  /** Calculate the minimum amount of work a received block needs, without knowing its direct parent */
  437.  unsigned int ComputeMinWork(unsigned int nBase, int64_t nTime);
  438.  /** Check whether we are doing an initial block download (synchronizing from disk or network) */
  439. @@ -316,6 +322,8 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
  440.  // Context-independent validity checks
  441.  bool CheckTransaction(const CTransaction& tx, CValidationState& state);
  442.  
  443. +bool IsPushCanonicalTx(const CTransaction&, string& reason);
  444. +
  445.  /** Check for standard transaction types
  446.      @return True if all outputs (scriptPubKeys) use only standard transaction forms
  447.  */
  448. @@ -605,7 +613,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = t
  449.  
  450.  // Store block on disk
  451.  // if dbp is provided, the file is known to already reside on disk
  452. -bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp = NULL);
  453. +bool AcceptBlock(CBlock& block, CValidationState& state, CDiskBlockPos* dbp = NULL, bool fWriteToDisk = true);
  454.  
  455.  
  456.  
  457. @@ -941,6 +949,7 @@ private:
  458.          MODE_VALID,   // everything ok
  459.          MODE_INVALID, // network rule violation (DoS value may be set)
  460.          MODE_ERROR,   // run-time error
  461. +        MODE_ORPHAN,  // orphan data, processing deferred
  462.      } mode;
  463.      int nDoS;
  464.      std::string strRejectReason;
  465. @@ -974,8 +983,16 @@ public:
  466.          AbortNode(msg);
  467.          return Error(msg);
  468.      }
  469. +    bool Orphan() {
  470. +        if (IsValid())
  471. +            mode = MODE_ORPHAN;
  472. +        return true;
  473. +    }
  474.      bool IsValid() const {
  475. -        return mode == MODE_VALID;
  476. +        return mode == MODE_VALID || mode == MODE_ORPHAN;
  477. +    }
  478. +    bool IsOrphan() const {
  479. +        return mode == MODE_ORPHAN;
  480.      }
  481.      bool IsInvalid() const {
  482.          return mode == MODE_INVALID;
  483. diff --git a/src/miner.cpp b/src/miner.cpp
  484. index e8abb8c..e980dc1 100644
  485. --- a/src/miner.cpp
  486. +++ b/src/miner.cpp
  487. @@ -3,6 +3,8 @@
  488.  // Distributed under the MIT/X11 software license, see the accompanying
  489.  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  490.  
  491. +#include <inttypes.h>
  492. +
  493.  #include "miner.h"
  494.  
  495.  #include "core.h"
  496. @@ -52,28 +54,170 @@ void SHA256Transform(void* pstate, void* pinput, const void* pinit)
  497.          ((uint32_t*)pstate)[i] = ctx.h[i];
  498.  }
  499.  
  500. -// Some explaining would be appreciated
  501. -class COrphan
  502. +//
  503. +// Unconfirmed transactions in the memory pool often depend on other
  504. +// transactions in the memory pool. When we select transactions from the
  505. +// pool, we select by highest priority or fee rate, so we might consider
  506. +// transactions that depend on transactions that aren't yet in the block.
  507. +// CTxInfo represents a logical transaction to potentially be included in blocks
  508. +// It stores extra metadata such as the subjective priority of a transaction at
  509. +// the time of building the block. When there are unconfirmed transactions that
  510. +// depend on other unconfirmed transactions, these "child" transactions' CTxInfo
  511. +// object factors in its "parents" to its priority and effective size; this way,
  512. +// the "child" can cover the "cost" of its "parents", and the "parents" are
  513. +// included into the block as part of the "child".
  514. +//
  515. +class CTxInfo;
  516. +typedef std::map<uint256, CTxInfo> mapInfo_t;
  517. +
  518. +class CTxInfo
  519.  {
  520.  public:
  521. +    mapInfo_t *pmapInfoById;
  522.      const CTransaction* ptx;
  523. +    uint256 hash;
  524. +private:
  525.      set<uint256> setDependsOn;
  526. +public:
  527. +    set<uint256> setDependents;
  528.      double dPriority;
  529. -    double dFeePerKb;
  530. +    uint64_t nTxFee;
  531. +    int nTxSigOps;
  532. +    bool fInvalid;
  533. +    unsigned int nSize;
  534. +    unsigned int nEffectiveSizeCached;
  535.  
  536. -    COrphan(const CTransaction* ptxIn)
  537. +    CTxInfo() : pmapInfoById(NULL), hash(0), fInvalid(false), nSize(0), nEffectiveSizeCached(0)
  538.      {
  539. -        ptx = ptxIn;
  540. -        dPriority = dFeePerKb = 0;
  541. +        ptx = NULL;
  542. +        dPriority = nTxFee = 0;
  543.      }
  544.  
  545.      void print() const
  546.      {
  547. -        LogPrintf("COrphan(hash=%s, dPriority=%.1f, dFeePerKb=%.1f)\n",
  548. -               ptx->GetHash().ToString(), dPriority, dFeePerKb);
  549. +        LogPrintf("CTxInfo(hash=%s, dPriority=%.1f, nTxFee=%d)\n",
  550. +               ptx->GetHash().ToString(), dPriority, nTxFee);
  551.          BOOST_FOREACH(uint256 hash, setDependsOn)
  552.              LogPrintf("   setDependsOn %s\n", hash.ToString());
  553.      }
  554. +
  555. +    void addDependsOn(const uint256& hashPrev)
  556. +    {
  557. +        setDependsOn.insert(hashPrev);
  558. +        nEffectiveSizeCached = 0;
  559. +    }
  560. +
  561. +    void rmDependsOn(const uint256& hashPrev)
  562. +    {
  563. +        setDependsOn.erase(hashPrev);
  564. +        nEffectiveSizeCached = 0;
  565. +    }
  566. +
  567. +    // effectiveSize handles inheriting the fInvalid flag as a side effect
  568. +    unsigned int effectiveSize()
  569. +    {
  570. +        if (fInvalid)
  571. +            return -1;
  572. +
  573. +        if (nEffectiveSizeCached)
  574. +            return nEffectiveSizeCached;
  575. +
  576. +        assert(pmapInfoById);
  577. +
  578. +        if (!nSize)
  579. +            nSize = ::GetSerializeSize(*ptx, SER_NETWORK, PROTOCOL_VERSION);
  580. +        unsigned int nEffectiveSize = nSize;
  581. +        BOOST_FOREACH(const uint256& dephash, setDependsOn)
  582. +        {
  583. +            CTxInfo& depinfo = (*pmapInfoById)[dephash];
  584. +            nEffectiveSize += depinfo.effectiveSize();
  585. +
  586. +            if (depinfo.fInvalid)
  587. +            {
  588. +                fInvalid = true;
  589. +                return -1;
  590. +            }
  591. +        }
  592. +        nEffectiveSizeCached = nEffectiveSize;
  593. +        return nEffectiveSize;
  594. +    }
  595. +
  596. +    unsigned int effectiveSizeMod()
  597. +    {
  598. +        unsigned int nTxSizeMod = effectiveSize();
  599. +        const CTransaction &tx = *ptx;
  600. +        // In order to avoid disincentivizing cleaning up the UTXO set we don't count
  601. +        // the constant overhead for each txin and up to 110 bytes of scriptSig (which
  602. +        // is enough to cover a compressed pubkey p2sh redemption) for priority.
  603. +        // Providing any more cleanup incentive than making additional inputs free would
  604. +        // risk encouraging people to create junk outputs to redeem later.
  605. +        BOOST_FOREACH(const CTxIn& txin, tx.vin)
  606. +        {
  607. +            unsigned int offset = 41U + min(110U, (unsigned int)txin.scriptSig.size());
  608. +            if (nTxSizeMod > offset)
  609. +                nTxSizeMod -= offset;
  610. +        }
  611. +        return nTxSizeMod;
  612. +    }
  613. +
  614. +    double getPriority()
  615. +    {
  616. +        // Priority is sum(valuein * age) / modified_txsize
  617. +        return dPriority / effectiveSizeMod();
  618. +    }
  619. +
  620. +    double getFeeRate()
  621. +    {
  622. +        return nTxFee / effectiveSize();
  623. +    }
  624. +
  625. +    unsigned int GetLegacySigOpCount()
  626. +    {
  627. +        assert(pmapInfoById);
  628. +
  629. +        unsigned int n = ::GetLegacySigOpCount(*ptx);
  630. +        BOOST_FOREACH(const uint256& dephash, setDependsOn)
  631. +        {
  632. +            CTxInfo& depinfo = (*pmapInfoById)[dephash];
  633. +            n += depinfo.GetLegacySigOpCount();
  634. +        }
  635. +        return n;
  636. +    }
  637. +
  638. +    bool DoInputs(CCoinsViewCache& view, CBlockIndex*pindexPrev, std::vector<CTxInfo*>& vAdded, unsigned int& nSigOpCounter)
  639. +    {
  640. +        const CTransaction& tx = *ptx;
  641. +
  642. +        if (view.HaveCoins(hash))
  643. +            // Already included in block template
  644. +            return true;
  645. +
  646. +        assert(pmapInfoById);
  647. +
  648. +        BOOST_FOREACH(const uint256& dephash, setDependsOn)
  649. +        {
  650. +            CTxInfo& depinfo = (*pmapInfoById)[dephash];
  651. +            if (!depinfo.DoInputs(view, pindexPrev, vAdded, nSigOpCounter))
  652. +                return false;
  653. +        }
  654. +
  655. +        if (!view.HaveInputs(tx))
  656. +            return false;
  657. +
  658. +        nTxSigOps = GetP2SHSigOpCount(tx, view);
  659. +        nSigOpCounter += nTxSigOps;
  660. +
  661. +        CValidationState state;
  662. +        if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH))
  663. +            return false;
  664. +
  665. +        CTxUndo txundo;
  666. +        UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1, hash);
  667. +
  668. +        vAdded.push_back(this);
  669. +
  670. +        return true;
  671. +    }
  672.  };
  673.  
  674.  
  675. @@ -81,7 +225,7 @@ uint64_t nLastBlockTx = 0;
  676.  uint64_t nLastBlockSize = 0;
  677.  
  678.  // We want to sort transactions by priority and fee, so:
  679. -typedef boost::tuple<double, double, const CTransaction*> TxPriority;
  680. +typedef CTxInfo* TxPriority;
  681.  class TxPriorityCompare
  682.  {
  683.      bool byFee;
  684. @@ -91,15 +235,15 @@ public:
  685.      {
  686.          if (byFee)
  687.          {
  688. -            if (a.get<1>() == b.get<1>())
  689. -                return a.get<0>() < b.get<0>();
  690. -            return a.get<1>() < b.get<1>();
  691. +            if (a->getFeeRate() == b->getFeeRate())
  692. +                return a->getPriority() < b->getPriority();
  693. +            return a->getFeeRate() < b->getFeeRate();
  694.          }
  695.          else
  696.          {
  697. -            if (a.get<0>() == b.get<0>())
  698. -                return a.get<1>() < b.get<1>();
  699. -            return a.get<0>() < b.get<0>();
  700. +            if (a->getPriority() == b->getPriority())
  701. +                return a->getFeeRate() < b->getFeeRate();
  702. +            return a->getPriority() < b->getPriority();
  703.          }
  704.      }
  705.  };
  706. @@ -147,81 +291,75 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  707.          CCoinsViewCache view(*pcoinsTip, true);
  708.  
  709.          // Priority order to process transactions
  710. -        list<COrphan> vOrphan; // list memory doesn't move
  711. -        map<uint256, vector<COrphan*> > mapDependers;
  712. +        mapInfo_t mapInfoById;
  713.          bool fPrintPriority = GetBoolArg("-printpriority", false);
  714.  
  715.          // This vector will be sorted into a priority queue:
  716.          vector<TxPriority> vecPriority;
  717.          vecPriority.reserve(mempool.mapTx.size());
  718. +
  719.          for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
  720.               mi != mempool.mapTx.end(); ++mi)
  721.          {
  722.              const CTransaction& tx = mi->second.GetTx();
  723. +
  724. +            const uint256& hash = tx.GetHash();
  725. +            CTxInfo& txinfo = mapInfoById[hash];
  726. +            txinfo.hash = hash;
  727. +            txinfo.pmapInfoById = &mapInfoById;
  728. +            txinfo.ptx = &tx;
  729. +
  730.              if (tx.IsCoinBase() || !IsFinalTx(tx, pindexPrev->nHeight + 1))
  731. +            {
  732. +                txinfo.fInvalid = true;
  733.                  continue;
  734. +            }
  735.  
  736. -            COrphan* porphan = NULL;
  737. -            double dPriority = 0;
  738. +            double& dPriority = txinfo.dPriority;
  739. +            uint64_t& nTxFee = txinfo.nTxFee;
  740.              int64_t nTotalIn = 0;
  741. -            bool fMissingInputs = false;
  742.              BOOST_FOREACH(const CTxIn& txin, tx.vin)
  743.              {
  744.                  // Read prev transaction
  745. -                if (!view.HaveCoins(txin.prevout.hash))
  746. +                int64_t nValueIn;
  747. +                int nConf;
  748. +                if (view.HaveCoins(txin.prevout.hash))
  749.                  {
  750. -                    // This should never happen; all transactions in the memory
  751. -                    // pool should connect to either transactions in the chain
  752. -                    // or other transactions in the memory pool.
  753. -                    if (!mempool.mapTx.count(txin.prevout.hash))
  754. -                    {
  755. -                        LogPrintf("ERROR: mempool transaction missing input\n");
  756. -                        if (fDebug) assert("mempool transaction missing input" == 0);
  757. -                        fMissingInputs = true;
  758. -                        if (porphan)
  759. -                            vOrphan.pop_back();
  760. -                        break;
  761. -                    }
  762. -
  763. -                    // Has to wait for dependencies
  764. -                    if (!porphan)
  765. -                    {
  766. -                        // Use list for automatic deletion
  767. -                        vOrphan.push_back(COrphan(&tx));
  768. -                        porphan = &vOrphan.back();
  769. -                    }
  770. -                    mapDependers[txin.prevout.hash].push_back(porphan);
  771. -                    porphan->setDependsOn.insert(txin.prevout.hash);
  772. -                    nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue;
  773. -                    continue;
  774. +                    const CCoins &coins = view.GetCoins(txin.prevout.hash);
  775. +                    // Input is confirmed
  776. +                    nConf = pindexPrev->nHeight - coins.nHeight + 1;
  777. +                    nValueIn = coins.vout[txin.prevout.n].nValue;
  778. +                    dPriority += (double)nValueIn * nConf;
  779. +                }
  780. +                else
  781. +                if (mempool.mapTx.count(txin.prevout.hash))
  782. +                {
  783. +                    // Input is still unconfirmed
  784. +                    const uint256& hashPrev = txin.prevout.hash;
  785. +                    nValueIn = mempool.mapTx[hashPrev].GetTx().vout[txin.prevout.n].nValue;
  786. +                    txinfo.addDependsOn(hashPrev);
  787. +                    mapInfoById[hashPrev].setDependents.insert(hash);
  788. +                    nConf = 0;
  789. +                }
  790. +                else
  791. +                {
  792. +                    // We don't know where the input is
  793. +                    // In this case, it's impossible to include this transaction in a block, so mark it invalid and move on
  794. +                    txinfo.fInvalid = true;
  795. +                    LogPrintf("priority %s invalid input %s\n", txinfo.hash.ToString().substr(0,10).c_str(), txin.prevout.hash.ToString().substr(0,10).c_str());
  796. +                    goto nexttxn;
  797.                  }
  798. -                const CCoins &coins = view.GetCoins(txin.prevout.hash);
  799.  
  800. -                int64_t nValueIn = coins.vout[txin.prevout.n].nValue;
  801.                  nTotalIn += nValueIn;
  802. -
  803. -                int nConf = pindexPrev->nHeight - coins.nHeight + 1;
  804. -
  805. -                dPriority += (double)nValueIn * nConf;
  806.              }
  807. -            if (fMissingInputs) continue;
  808.  
  809. -            // Priority is sum(valuein * age) / modified_txsize
  810. -            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
  811. -            dPriority = tx.ComputePriority(dPriority, nTxSize);
  812. +            nTxFee = nTotalIn - tx.GetValueOut();
  813.  
  814. -            // This is a more accurate fee-per-kilobyte than is used by the client code, because the
  815. -            // client code rounds up the size to the nearest 1K. That's good, because it gives an
  816. -            // incentive to create smaller transactions.
  817. -            double dFeePerKb =  double(nTotalIn-tx.GetValueOut()) / (double(nTxSize)/1000.0);
  818. +            mempool.ApplyDeltas(hash, dPriority, nTotalIn);
  819.  
  820. -            if (porphan)
  821. -            {
  822. -                porphan->dPriority = dPriority;
  823. -                porphan->dFeePerKb = dFeePerKb;
  824. -            }
  825. -            else
  826. -                vecPriority.push_back(TxPriority(dPriority, dFeePerKb, &mi->second.GetTx()));
  827. +            vecPriority.push_back(&txinfo);
  828. +
  829. +nexttxn:    (void)1;
  830.          }
  831.  
  832.          // Collect transactions into block
  833. @@ -236,28 +374,36 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  834.          while (!vecPriority.empty())
  835.          {
  836.              // Take highest priority transaction off the priority queue:
  837. -            double dPriority = vecPriority.front().get<0>();
  838. -            double dFeePerKb = vecPriority.front().get<1>();
  839. -            const CTransaction& tx = *(vecPriority.front().get<2>());
  840. -
  841. +            CTxInfo& txinfo = *(vecPriority.front());
  842.              std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
  843.              vecPriority.pop_back();
  844.  
  845. +            if (txinfo.fInvalid)
  846. +                continue;
  847. +
  848. +            const CTransaction& tx = *txinfo.ptx;
  849. +            double dPriority = txinfo.getPriority();
  850. +            double dFeePerKb = txinfo.getFeeRate();
  851. +
  852.              // Size limits
  853. -            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
  854. +            unsigned int nTxSize = txinfo.effectiveSize();
  855.              if (nBlockSize + nTxSize >= nBlockMaxSize)
  856.                  continue;
  857.  
  858.              // Legacy limits on sigOps:
  859. -            unsigned int nTxSigOps = GetLegacySigOpCount(tx);
  860. +            unsigned int nTxSigOps = txinfo.GetLegacySigOpCount();
  861.              if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
  862.                  continue;
  863.  
  864.              // Skip free transactions if we're past the minimum block size:
  865. -            if (fSortedByFee && (dFeePerKb < CTransaction::nMinRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
  866. +            const uint256& hash = tx.GetHash();
  867. +            double dPriorityDelta = 0;
  868. +            int64_t nFeeDelta = 0;
  869. +            mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
  870. +            if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (dFeePerKb < CTransaction::nMinRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
  871.                  continue;
  872.  
  873. -            // Prioritize by fee once past the priority size or we run out of high-priority
  874. +            // Prioritise by fee once past the priority size or we run out of high-priority
  875.              // transactions:
  876.              if (!fSortedByFee &&
  877.                  ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
  878. @@ -267,31 +413,23 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  879.                  std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
  880.              }
  881.  
  882. -            if (!view.HaveInputs(tx))
  883. -                continue;
  884. +            // second layer cached modifications just for this transaction
  885. +            CCoinsViewCache viewTemp(view, true);
  886.  
  887. -            int64_t nTxFees = view.GetValueIn(tx)-tx.GetValueOut();
  888. -
  889. -            nTxSigOps += GetP2SHSigOpCount(tx, view);
  890. -            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
  891. +            std::vector<CTxInfo*> vAdded;
  892. +            if (!txinfo.DoInputs(viewTemp, pindexPrev, vAdded, nTxSigOps))
  893.                  continue;
  894.  
  895. -            CValidationState state;
  896. -            if (!CheckInputs(tx, state, view, true, SCRIPT_VERIFY_P2SH))
  897. +            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
  898.                  continue;
  899.  
  900. -            CTxUndo txundo;
  901. -            uint256 hash = tx.GetHash();
  902. -            UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1, hash);
  903. +            // push changes from the second layer cache to the first one
  904. +            viewTemp.Flush();
  905.  
  906.              // Added
  907. -            pblock->vtx.push_back(tx);
  908. -            pblocktemplate->vTxFees.push_back(nTxFees);
  909. -            pblocktemplate->vTxSigOps.push_back(nTxSigOps);
  910.              nBlockSize += nTxSize;
  911. -            ++nBlockTx;
  912. +            nBlockTx += vAdded.size();
  913.              nBlockSigOps += nTxSigOps;
  914. -            nFees += nTxFees;
  915.  
  916.              if (fPrintPriority)
  917.              {
  918. @@ -299,22 +437,29 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  919.                         dPriority, dFeePerKb, tx.GetHash().ToString());
  920.              }
  921.  
  922. -            // Add transactions that depend on this one to the priority queue
  923. -            if (mapDependers.count(hash))
  924. +            bool fResort = false;
  925. +            BOOST_FOREACH(CTxInfo* ptxinfo, vAdded)
  926.              {
  927. -                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
  928. +                pblock->vtx.push_back(*ptxinfo->ptx);
  929. +                pblocktemplate->vTxFees.push_back(ptxinfo->nTxFee);
  930. +                pblocktemplate->vTxSigOps.push_back(ptxinfo->nTxSigOps);
  931. +                nFees += ptxinfo->nTxFee;
  932. +
  933. +                ptxinfo->fInvalid = true;
  934. +                if (!ptxinfo->setDependents.empty())
  935.                  {
  936. -                    if (!porphan->setDependsOn.empty())
  937. +                    fResort = true;
  938. +                    BOOST_FOREACH(const uint256& dhash, ptxinfo->setDependents)
  939.                      {
  940. -                        porphan->setDependsOn.erase(hash);
  941. -                        if (porphan->setDependsOn.empty())
  942. -                        {
  943. -                            vecPriority.push_back(TxPriority(porphan->dPriority, porphan->dFeePerKb, porphan->ptx));
  944. -                            std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
  945. -                        }
  946. +                        CTxInfo& dtxinfo = mapInfoById[dhash];
  947. +                        dtxinfo.rmDependsOn(ptxinfo->hash);
  948. +                        fResort = true;
  949.                      }
  950.                  }
  951.              }
  952. +            if (fResort)
  953. +                // Re-sort the priority queue to pick up on improved standing
  954. +                std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
  955.          }
  956.  
  957.          nLastBlockTx = nBlockTx;
  958. diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am
  959. index 648971b..cae0070 100644
  960. --- a/src/qt/Makefile.am
  961. +++ b/src/qt/Makefile.am
  962. @@ -201,6 +201,7 @@ BITCOIN_QT_H = \
  963.    sendcoinsentry.h \
  964.    signverifymessagedialog.h \
  965.    splashscreen.h \
  966. +  tonalutils.h \
  967.    trafficgraphwidget.h \
  968.    transactiondesc.h \
  969.    transactiondescdialog.h \
  970. @@ -278,6 +279,7 @@ BITCOIN_QT_CPP = \
  971.    qvaluecombobox.cpp \
  972.    rpcconsole.cpp \
  973.    splashscreen.cpp \
  974. +  tonalutils.cpp \
  975.    trafficgraphwidget.cpp \
  976.    utilitydialog.cpp \
  977.    winshutdownmonitor.cpp
  978. diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
  979. index 08fe3e7..5d57ac4 100644
  980. --- a/src/qt/bitcoin.cpp
  981. +++ b/src/qt/bitcoin.cpp
  982. @@ -520,7 +520,7 @@ int main(int argc, char *argv[])
  983.      /// - Do not call GetDataDir(true) before this step finishes
  984.      if (!boost::filesystem::is_directory(GetDataDir(false)))
  985.      {
  986. -        QMessageBox::critical(0, QObject::tr("Bitcoin"),
  987. +        QMessageBox::critical(0, QObject::tr("Bitcoin Core"),
  988.                                QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"])));
  989.          return 1;
  990.      }
  991. diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
  992. index 25ad0c6..9b87eaa 100644
  993. --- a/src/qt/bitcoinamountfield.cpp
  994. +++ b/src/qt/bitcoinamountfield.cpp
  995. @@ -14,17 +14,67 @@
  996.  #include <QKeyEvent>
  997.  #include <qmath.h> // for qPow()
  998.  
  999. +#include "tonalutils.h"
  1000. +
  1001. +BitcoinAmountSpinBox::BitcoinAmountSpinBox(QWidget *parent)
  1002. + : QDoubleSpinBox(parent), currentUnit(-1)
  1003. +{
  1004. +    setLocale(QLocale::c());
  1005. +    setDecimals(8);
  1006. +    installEventFilter(parent);
  1007. +    setMaximumWidth(170);
  1008. +    setMaximum(21e14);
  1009. +}
  1010. +
  1011. +QValidator::State BitcoinAmountSpinBox::validate(QString&text, int&pos) const
  1012. +{
  1013. +    switch (currentNumsys) {
  1014. +    default:
  1015. +    case BitcoinUnits::BTC:
  1016. +        return QDoubleSpinBox::validate(text, pos);
  1017. +    case BitcoinUnits::TBC:
  1018. +        return TonalUtils::validate(text, pos);
  1019. +    }
  1020. +}
  1021. +
  1022. +QString BitcoinAmountSpinBox::textFromValue(double value) const
  1023. +{
  1024. +    return BitcoinUnits::format(currentUnit, value);
  1025. +}
  1026. +
  1027. +double BitcoinAmountSpinBox::valueFromText(const QString&text) const
  1028. +{
  1029. +    qint64 val;
  1030. +    BitcoinUnits::parse(currentUnit, text, &val);
  1031. +    return val;
  1032. +}
  1033. +
  1034. +void BitcoinAmountSpinBox::setUnit(int unit)
  1035. +{
  1036. +    currentUnit = unit;
  1037. +    currentNumsys = BitcoinUnits::numsys(unit);
  1038. +    qint64 factor = BitcoinUnits::factor(unit);
  1039. +    switch (currentNumsys) {
  1040. +    default:
  1041. +    case BitcoinUnits::BTC:
  1042. +        if (currentUnit == BitcoinUnits::uBTC)
  1043. +            setSingleStep(0.01 * factor);
  1044. +        else
  1045. +            setSingleStep(0.001 * factor);
  1046. +        break;
  1047. +    case BitcoinUnits::TBC:
  1048. +        setSingleStep(factor / 0x400);
  1049. +    }
  1050. +}
  1051. +
  1052. +
  1053.  BitcoinAmountField::BitcoinAmountField(QWidget *parent) :
  1054.      QWidget(parent),
  1055.      amount(0),
  1056. -    currentUnit(-1)
  1057. +    currentUnit(-1),
  1058. +    nSingleStep(0)
  1059.  {
  1060. -    nSingleStep = 100000; // satoshis
  1061. -
  1062. -    amount = new QDoubleSpinBox(this);
  1063. -    amount->setLocale(QLocale::c());
  1064. -    amount->installEventFilter(this);
  1065. -    amount->setMaximumWidth(170);
  1066. +    amount = new BitcoinAmountSpinBox(this);
  1067.  
  1068.      QHBoxLayout *layout = new QHBoxLayout(this);
  1069.      layout->addWidget(amount);
  1070. @@ -52,7 +102,7 @@ void BitcoinAmountField::setText(const QString &text)
  1071.      if (text.isEmpty())
  1072.          amount->clear();
  1073.      else
  1074. -        amount->setValue(text.toDouble());
  1075. +        amount->setValue(amount->valueFromText(text));
  1076.  }
  1077.  
  1078.  void BitcoinAmountField::clear()
  1079. @@ -61,16 +111,18 @@ void BitcoinAmountField::clear()
  1080.      unit->setCurrentIndex(0);
  1081.  }
  1082.  
  1083. -bool BitcoinAmountField::validate()
  1084. +bool BitcoinAmountField::_is_valid() const
  1085.  {
  1086. -    bool valid = true;
  1087.      if (amount->value() == 0.0)
  1088. -        valid = false;
  1089. -    else if (!BitcoinUnits::parse(currentUnit, text(), 0))
  1090. -        valid = false;
  1091. -    else if (amount->value() > BitcoinUnits::maxAmount(currentUnit))
  1092. -        valid = false;
  1093. +        return false;
  1094. +    if (amount->value() > BitcoinUnits::maxAmount(BitcoinUnits::uBTC))
  1095. +        return false;
  1096. +    return true;
  1097. +}
  1098.  
  1099. +bool BitcoinAmountField::validate()
  1100. +{
  1101. +    bool valid = _is_valid();
  1102.      setValid(valid);
  1103.  
  1104.      return valid;
  1105. @@ -122,8 +174,8 @@ QWidget *BitcoinAmountField::setupTabChain(QWidget *prev)
  1106.  
  1107.  qint64 BitcoinAmountField::value(bool *valid_out) const
  1108.  {
  1109. -    qint64 val_out = 0;
  1110. -    bool valid = BitcoinUnits::parse(currentUnit, text(), &val_out);
  1111. +    qint64 val_out = amount->value();
  1112. +    bool valid = _is_valid();
  1113.      if (valid_out)
  1114.      {
  1115.          *valid_out = valid;
  1116. @@ -133,7 +185,7 @@ qint64 BitcoinAmountField::value(bool *valid_out) const
  1117.  
  1118.  void BitcoinAmountField::setValue(qint64 value)
  1119.  {
  1120. -    setText(BitcoinUnits::format(currentUnit, value));
  1121. +    amount->setValue(value);
  1122.  }
  1123.  
  1124.  void BitcoinAmountField::setReadOnly(bool fReadOnly)
  1125. @@ -154,12 +206,24 @@ void BitcoinAmountField::unitChanged(int idx)
  1126.      bool valid = false;
  1127.      qint64 currentValue = value(&valid);
  1128.  
  1129. +    amount->setUnit(newUnit);
  1130.      currentUnit = newUnit;
  1131.  
  1132. -    // Set max length after retrieving the value, to prevent truncation
  1133. -    amount->setDecimals(BitcoinUnits::decimals(currentUnit));
  1134. -    amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
  1135. -    amount->setSingleStep((double)nSingleStep / (double)BitcoinUnits::factor(currentUnit));
  1136. +    qint64 nSS = nSingleStep;
  1137. +    if (!nSS)
  1138. +    {
  1139. +        int numsys = BitcoinUnits::numsys(newUnit);
  1140. +        switch (numsys)
  1141. +        {
  1142. +            case BitcoinUnits::BTC:
  1143. +                nSS = 100000;
  1144. +                break;
  1145. +            case BitcoinUnits::TBC:
  1146. +                nSS = 0x10000;
  1147. +                break;
  1148. +        }
  1149. +    }
  1150. +    amount->setSingleStep(nSS);
  1151.  
  1152.      if (valid)
  1153.      {
  1154. diff --git a/src/qt/bitcoinamountfield.h b/src/qt/bitcoinamountfield.h
  1155. index 521a9ed..8355c6d 100644
  1156. --- a/src/qt/bitcoinamountfield.h
  1157. +++ b/src/qt/bitcoinamountfield.h
  1158. @@ -5,13 +5,30 @@
  1159.  #ifndef BITCOINAMOUNTFIELD_H
  1160.  #define BITCOINAMOUNTFIELD_H
  1161.  
  1162. +#include <QDoubleSpinBox>
  1163.  #include <QWidget>
  1164.  
  1165.  QT_BEGIN_NAMESPACE
  1166. -class QDoubleSpinBox;
  1167.  class QValueComboBox;
  1168.  QT_END_NAMESPACE
  1169.  
  1170. +class BitcoinAmountSpinBox : public QDoubleSpinBox
  1171. +{
  1172. +    Q_OBJECT
  1173. +public:
  1174. +    BitcoinAmountSpinBox(QWidget *parent = 0);
  1175. +
  1176. +    virtual QValidator::State validate(QString&text, int&pos) const;
  1177. +    virtual QString textFromValue(double) const;
  1178. +    virtual double valueFromText(const QString&) const;
  1179. +
  1180. +    void setUnit(int unit);
  1181. +
  1182. +private:
  1183. +    int currentUnit;
  1184. +    int currentNumsys;
  1185. +};
  1186. +
  1187.  /** Widget for entering bitcoin amounts.
  1188.    */
  1189.  class BitcoinAmountField: public QWidget
  1190. @@ -56,10 +73,11 @@ protected:
  1191.      bool eventFilter(QObject *object, QEvent *event);
  1192.  
  1193.  private:
  1194. -    QDoubleSpinBox *amount;
  1195. +    BitcoinAmountSpinBox *amount;
  1196.      QValueComboBox *unit;
  1197.      int currentUnit;
  1198.      qint64 nSingleStep;
  1199. +    bool _is_valid() const;
  1200.  
  1201.      void setText(const QString &text);
  1202.      QString text() const;
  1203. diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
  1204. index e6190ae..991a5cd 100644
  1205. --- a/src/qt/bitcoingui.cpp
  1206. +++ b/src/qt/bitcoingui.cpp
  1207. @@ -276,7 +276,7 @@ void BitcoinGUI::createActions(bool fIsTestnet)
  1208.      aboutQtAction->setStatusTip(tr("Show information about Qt"));
  1209.      aboutQtAction->setMenuRole(QAction::AboutQtRole);
  1210.      optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this);
  1211. -    optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin"));
  1212. +    optionsAction->setStatusTip(tr("Modify configuration options for Bitcoin Core"));
  1213.      optionsAction->setMenuRole(QAction::PreferencesRole);
  1214.      if (!fIsTestnet)
  1215.          toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this);
  1216. @@ -327,6 +327,19 @@ void BitcoinGUI::createActions(bool fIsTestnet)
  1217.          connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses()));
  1218.          connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses()));
  1219.          connect(openAction, SIGNAL(triggered()), this, SLOT(openClicked()));
  1220. +
  1221. +# ifdef FIRST_CLASS_MESSAGING
  1222. +        firstClassMessagingAction = new QAction(QIcon(":/icons/edit"), tr("S&ignatures"), this);
  1223. +        firstClassMessagingAction->setToolTip(signMessageAction->toolTip() + QString(". / ") + verifyMessageAction->toolTip() + QString("."));
  1224. +        firstClassMessagingAction->setCheckable(true);
  1225. +        tabGroup->addAction(firstClassMessagingAction);
  1226. +
  1227. +        connect(signMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
  1228. +        connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
  1229. +        connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
  1230. +        // Always start with the sign message tab for FIRST_CLASS_MESSAGING
  1231. +        connect(firstClassMessagingAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
  1232. +# endif
  1233.      }
  1234.  #endif
  1235.  }
  1236. @@ -347,8 +360,10 @@ void BitcoinGUI::createMenuBar()
  1237.      {
  1238.          file->addAction(openAction);
  1239.          file->addAction(backupWalletAction);
  1240. +#ifndef FIRST_CLASS_MESSAGING
  1241.          file->addAction(signMessageAction);
  1242.          file->addAction(verifyMessageAction);
  1243. +#endif
  1244.          file->addSeparator();
  1245.          file->addAction(usedSendingAddressesAction);
  1246.          file->addAction(usedReceivingAddressesAction);
  1247. @@ -386,6 +401,9 @@ void BitcoinGUI::createToolBars()
  1248.          toolbar->addAction(sendCoinsAction);
  1249.          toolbar->addAction(receiveCoinsAction);
  1250.          toolbar->addAction(historyAction);
  1251. +#ifdef FIRST_CLASS_MESSAGING
  1252. +        toolbar->addAction(firstClassMessagingAction);
  1253. +#endif
  1254.          overviewAction->setChecked(true);
  1255.      }
  1256.  }
  1257. @@ -467,12 +485,12 @@ void BitcoinGUI::createTrayIcon(bool fIsTestnet)
  1258.  
  1259.      if (!fIsTestnet)
  1260.      {
  1261. -        trayIcon->setToolTip(tr("Bitcoin client"));
  1262. +        trayIcon->setToolTip(tr("Bitcoin Core client"));
  1263.          trayIcon->setIcon(QIcon(":/icons/toolbar"));
  1264.      }
  1265.      else
  1266.      {
  1267. -        trayIcon->setToolTip(tr("Bitcoin client") + " " + tr("[testnet]"));
  1268. +        trayIcon->setToolTip(tr("Bitcoin Core client") + " " + tr("[testnet]"));
  1269.          trayIcon->setIcon(QIcon(":/icons/toolbar_testnet"));
  1270.      }
  1271.  
  1272. @@ -507,7 +525,9 @@ void BitcoinGUI::createTrayIconMenu()
  1273.      trayIconMenu->addSeparator();
  1274.      trayIconMenu->addAction(sendCoinsAction);
  1275.      trayIconMenu->addAction(receiveCoinsAction);
  1276. +#ifndef FIRST_CLASS_MESSAGING
  1277.      trayIconMenu->addSeparator();
  1278. +#endif
  1279.      trayIconMenu->addAction(signMessageAction);
  1280.      trayIconMenu->addAction(verifyMessageAction);
  1281.      trayIconMenu->addSeparator();
  1282. @@ -726,7 +746,7 @@ void BitcoinGUI::setNumBlocks(int count)
  1283.  
  1284.  void BitcoinGUI::message(const QString &title, const QString &message, unsigned int style, bool *ret)
  1285.  {
  1286. -    QString strTitle = tr("Bitcoin"); // default title
  1287. +    QString strTitle = tr("Bitcoin Core"); // default title
  1288.      // Default to information icon
  1289.      int nMBoxIcon = QMessageBox::Information;
  1290.      int nNotifyIcon = Notificator::Information;
  1291. diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
  1292. index b4675b9..eabfae1 100644
  1293. --- a/src/qt/bitcoingui.h
  1294. +++ b/src/qt/bitcoingui.h
  1295. @@ -83,6 +83,7 @@ private:
  1296.      QAction *usedReceivingAddressesAction;
  1297.      QAction *signMessageAction;
  1298.      QAction *verifyMessageAction;
  1299. +    QAction *firstClassMessagingAction;
  1300.      QAction *aboutAction;
  1301.      QAction *receiveCoinsAction;
  1302.      QAction *optionsAction;
  1303. diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp
  1304. index 2fed443..ab1cb07 100644
  1305. --- a/src/qt/bitcoinunits.cpp
  1306. +++ b/src/qt/bitcoinunits.cpp
  1307. @@ -6,6 +6,8 @@
  1308.  
  1309.  #include <QStringList>
  1310.  
  1311. +#include "tonalutils.h"
  1312. +
  1313.  BitcoinUnits::BitcoinUnits(QObject *parent):
  1314.          QAbstractListModel(parent),
  1315.          unitlist(availableUnits())
  1316. @@ -14,10 +16,19 @@ BitcoinUnits::BitcoinUnits(QObject *parent):
  1317.  
  1318.  QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits()
  1319.  {
  1320. -    QList<BitcoinUnits::Unit> unitlist;
  1321. -    unitlist.append(BTC);
  1322. -    unitlist.append(mBTC);
  1323. -    unitlist.append(uBTC);
  1324. +    static QList<BitcoinUnits::Unit> unitlist;
  1325. +    if (unitlist.empty())
  1326. +    {
  1327. +        unitlist.append(BTC);
  1328. +        unitlist.append(mBTC);
  1329. +        unitlist.append(uBTC);
  1330. +        if (TonalUtils::Supported())
  1331. +        {
  1332. +            unitlist.append(bTBC);
  1333. +            unitlist.append(sTBC);
  1334. +            unitlist.append(TBC);
  1335. +        }
  1336. +    }
  1337.      return unitlist;
  1338.  }
  1339.  
  1340. @@ -28,6 +39,9 @@ bool BitcoinUnits::valid(int unit)
  1341.      case BTC:
  1342.      case mBTC:
  1343.      case uBTC:
  1344. +    case bTBC:
  1345. +    case sTBC:
  1346. +    case TBC:
  1347.          return true;
  1348.      default:
  1349.          return false;
  1350. @@ -41,6 +55,9 @@ QString BitcoinUnits::name(int unit)
  1351.      case BTC: return QString("BTC");
  1352.      case mBTC: return QString("mBTC");
  1353.      case uBTC: return QString::fromUtf8("μBTC");
  1354. +    case bTBC: return QString::fromUtf8("ᵇTBC");
  1355. +    case sTBC: return QString::fromUtf8("Ë¢TBC");
  1356. +    case TBC: return QString("TBC");
  1357.      default: return QString("???");
  1358.      }
  1359.  }
  1360. @@ -49,9 +66,12 @@ QString BitcoinUnits::description(int unit)
  1361.  {
  1362.      switch(unit)
  1363.      {
  1364. -    case BTC: return QString("Bitcoins");
  1365. +    case BTC: return QString("Bitcoins (decimal)");
  1366.      case mBTC: return QString("Milli-Bitcoins (1 / 1,000)");
  1367.      case uBTC: return QString("Micro-Bitcoins (1 / 1,000,000)");
  1368. +    case bTBC: return QString("Bong-Bitcoins (1,0000 tonal)");
  1369. +    case sTBC: return QString("San-Bitcoins (100 tonal)");
  1370. +    case TBC: return QString("Bitcoins (tonal)");
  1371.      default: return QString("???");
  1372.      }
  1373.  }
  1374. @@ -63,6 +83,9 @@ qint64 BitcoinUnits::factor(int unit)
  1375.      case BTC:  return 100000000;
  1376.      case mBTC: return 100000;
  1377.      case uBTC: return 100;
  1378. +    case bTBC: return 0x100000000LL;
  1379. +    case sTBC: return 0x1000000;
  1380. +    case TBC:  return 0x10000;
  1381.      default:   return 100000000;
  1382.      }
  1383.  }
  1384. @@ -85,6 +108,9 @@ int BitcoinUnits::amountDigits(int unit)
  1385.      case BTC: return 8; // 21,000,000 (# digits, without commas)
  1386.      case mBTC: return 11; // 21,000,000,000
  1387.      case uBTC: return 14; // 21,000,000,000,000
  1388. +    case bTBC: return 6; // 49,63
  1389. +    case sTBC: return 8; // 49,6384
  1390. +    case TBC: return 10; // 49,63,8448
  1391.      default: return 0;
  1392.      }
  1393.  }
  1394. @@ -96,10 +122,52 @@ int BitcoinUnits::decimals(int unit)
  1395.      case BTC: return 8;
  1396.      case mBTC: return 5;
  1397.      case uBTC: return 2;
  1398. +    case bTBC: return 8;
  1399. +    case sTBC: return 6;
  1400. +    case TBC: return 4;
  1401.      default: return 0;
  1402.      }
  1403.  }
  1404.  
  1405. +int BitcoinUnits::minPlaces(int unit)
  1406. +{
  1407. +    switch(unit)
  1408. +    {
  1409. +    case bTBC:
  1410. +    case sTBC:
  1411. +    case TBC:
  1412. +        return -1;
  1413. +    default:
  1414. +        return 2;
  1415. +    }
  1416. +}
  1417. +
  1418. +int BitcoinUnits::radix(int unit)
  1419. +{
  1420. +    switch(unit)
  1421. +    {
  1422. +    case bTBC:
  1423. +    case sTBC:
  1424. +    case TBC:
  1425. +        return 0x10;
  1426. +    default:
  1427. +        return 10;
  1428. +    }
  1429. +}
  1430. +
  1431. +int BitcoinUnits::numsys(int unit)
  1432. +{
  1433. +    switch(unit)
  1434. +    {
  1435. +    case bTBC:
  1436. +    case sTBC:
  1437. +    case TBC:
  1438. +        return TBC;
  1439. +    default:
  1440. +        return BTC;
  1441. +    }
  1442. +}
  1443. +
  1444.  QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
  1445.  {
  1446.      // Note: not using straight sprintf here because we do NOT want
  1447. @@ -111,20 +179,31 @@ QString BitcoinUnits::format(int unit, qint64 n, bool fPlus)
  1448.      qint64 n_abs = (n > 0 ? n : -n);
  1449.      qint64 quotient = n_abs / coin;
  1450.      qint64 remainder = n_abs % coin;
  1451. -    QString quotient_str = QString::number(quotient);
  1452. -    QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
  1453. +    int uradix = radix(unit);
  1454. +    QString s = QString::number(quotient, uradix) + "." + QString::number(remainder, uradix).rightJustified(num_decimals, '0');
  1455.  
  1456.      // Right-trim excess zeros after the decimal point
  1457. -    int nTrim = 0;
  1458. -    for (int i = remainder_str.size()-1; i>=2 && (remainder_str.at(i) == '0'); --i)
  1459. -        ++nTrim;
  1460. -    remainder_str.chop(nTrim);
  1461. +    int nTrim = num_decimals - minPlaces(unit);
  1462. +    if (nTrim > 0)
  1463. +    {
  1464. +        int nTrimStop = s.size() - nTrim;
  1465. +        nTrim = 0;
  1466. +        for (int i = s.size()-1; i>=nTrimStop && (s.at(i) == '0'); --i)
  1467. +            ++nTrim;
  1468. +        if (s.at(nTrimStop) == '.' && nTrimStop + nTrim + 1 == s.size())
  1469. +            ++nTrim;
  1470. +        s.chop(nTrim);
  1471. +    }
  1472. +
  1473. +    int unumsys = numsys(unit);
  1474. +    if (unumsys == TBC)
  1475. +        TonalUtils::ConvertFromHex(s);
  1476.  
  1477.      if (n < 0)
  1478. -        quotient_str.insert(0, '-');
  1479. +        s.insert(0, '-');
  1480.      else if (fPlus && n > 0)
  1481. -        quotient_str.insert(0, '+');
  1482. -    return quotient_str + QString(".") + remainder_str;
  1483. +        s.insert(0, '+');
  1484. +    return s;
  1485.  }
  1486.  
  1487.  QString BitcoinUnits::formatWithUnit(int unit, qint64 amount, bool plussign)
  1488. @@ -157,11 +236,22 @@ bool BitcoinUnits::parse(int unit, const QString &value, qint64 *val_out)
  1489.      bool ok = false;
  1490.      QString str = whole + decimals.leftJustified(num_decimals, '0');
  1491.  
  1492. +    int unumsys = numsys(unit);
  1493. +    if (unumsys == TBC)
  1494. +    {
  1495. +        if (str.size() > 15)
  1496. +            return false; // Longer numbers may exceed 63 bits
  1497. +        TonalUtils::ConvertToHex(str);
  1498. +    }
  1499. +    else
  1500. +    {
  1501.      if(str.size() > 18)
  1502.      {
  1503.          return false; // Longer numbers will exceed 63 bits
  1504.      }
  1505. -    qint64 retvalue = str.toLongLong(&ok);
  1506. +    }
  1507. +
  1508. +    qint64 retvalue = str.toLongLong(&ok, radix(unit));
  1509.      if(val_out)
  1510.      {
  1511.          *val_out = retvalue;
  1512. diff --git a/src/qt/bitcoinunits.h b/src/qt/bitcoinunits.h
  1513. index 46517fc..f3019b0 100644
  1514. --- a/src/qt/bitcoinunits.h
  1515. +++ b/src/qt/bitcoinunits.h
  1516. @@ -25,7 +25,10 @@ public:
  1517.      {
  1518.          BTC,
  1519.          mBTC,
  1520. -        uBTC
  1521. +        uBTC,
  1522. +        bTBC,
  1523. +        sTBC,
  1524. +        TBC,
  1525.      };
  1526.  
  1527.      //! @name Static API
  1528. @@ -46,8 +49,14 @@ public:
  1529.      static qint64 maxAmount(int unit);
  1530.      //! Number of amount digits (to represent max number of coins)
  1531.      static int amountDigits(int unit);
  1532. -    //! Number of decimals left
  1533. +    //! Number of fractional places
  1534.      static int decimals(int unit);
  1535. +    //! Minimum number of fractional places to show
  1536. +    static int minPlaces(int unit);
  1537. +    //! Radix
  1538. +    static int radix(int unit);
  1539. +    //! Number system
  1540. +    static int numsys(int unit);
  1541.      //! Format as string
  1542.      static QString format(int unit, qint64 amount, bool plussign=false);
  1543.      //! Format as string (with unit)
  1544. diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui
  1545. index bc49214..bed0f4a 100644
  1546. --- a/src/qt/forms/askpassphrasedialog.ui
  1547. +++ b/src/qt/forms/askpassphrasedialog.ui
  1548. @@ -23,7 +23,7 @@
  1549.     </size>
  1550.    </property>
  1551.    <property name="windowTitle">
  1552. -   <string>Passphrase Dialog</string>
  1553. +   <string>Bitcoin Core - Passphrase Dialog</string>
  1554.    </property>
  1555.    <layout class="QVBoxLayout" name="verticalLayout">
  1556.     <item>
  1557. diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui
  1558. index c1aea36..13a630e 100644
  1559. --- a/src/qt/forms/editaddressdialog.ui
  1560. +++ b/src/qt/forms/editaddressdialog.ui
  1561. @@ -11,7 +11,7 @@
  1562.     </rect>
  1563.    </property>
  1564.    <property name="windowTitle">
  1565. -   <string>Edit Address</string>
  1566. +   <string>Bitcoin Core - Edit Address</string>
  1567.    </property>
  1568.    <layout class="QVBoxLayout" name="verticalLayout">
  1569.     <item>
  1570. diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui
  1571. index 0103842..572bb32 100644
  1572. --- a/src/qt/forms/optionsdialog.ui
  1573. +++ b/src/qt/forms/optionsdialog.ui
  1574. @@ -11,7 +11,7 @@
  1575.     </rect>
  1576.    </property>
  1577.    <property name="windowTitle">
  1578. -   <string>Options</string>
  1579. +   <string>Bitcoin Core - Options</string>
  1580.    </property>
  1581.    <property name="modal">
  1582.     <bool>true</bool>
  1583. diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
  1584. index fcb6bb6..aeabf42 100644
  1585. --- a/src/qt/forms/rpcconsole.ui
  1586. +++ b/src/qt/forms/rpcconsole.ui
  1587. @@ -11,7 +11,7 @@
  1588.     </rect>
  1589.    </property>
  1590.    <property name="windowTitle">
  1591. -   <string>Debug window</string>
  1592. +   <string>Bitcoin Core - Debug window</string>
  1593.    </property>
  1594.    <layout class="QVBoxLayout" name="verticalLayout_2">
  1595.     <item>
  1596. @@ -305,7 +305,7 @@
  1597.         <item row="14" column="0">
  1598.          <widget class="QPushButton" name="openDebugLogfileButton">
  1599.           <property name="toolTip">
  1600. -          <string>Open the Bitcoin debug log file from the current data directory. This can take a few seconds for large log files.</string>
  1601. +          <string>Open the client debug log file from the current data directory. This can take a few seconds for large log files.</string>
  1602.           </property>
  1603.           <property name="text">
  1604.            <string>&amp;Open</string>
  1605. diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
  1606. index 4cb1670..531efab 100644
  1607. --- a/src/qt/forms/sendcoinsdialog.ui
  1608. +++ b/src/qt/forms/sendcoinsdialog.ui
  1609. @@ -11,7 +11,7 @@
  1610.     </rect>
  1611.    </property>
  1612.    <property name="windowTitle">
  1613. -   <string>Send Coins</string>
  1614. +   <string>Bitcoin Core - Send Coins</string>
  1615.    </property>
  1616.    <layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
  1617.     <property name="bottomMargin">
  1618. diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
  1619. index aa271b4..fd23777 100644
  1620. --- a/src/qt/forms/signverifymessagedialog.ui
  1621. +++ b/src/qt/forms/signverifymessagedialog.ui
  1622. @@ -11,7 +11,7 @@
  1623.     </rect>
  1624.    </property>
  1625.    <property name="windowTitle">
  1626. -   <string>Signatures - Sign / Verify a Message</string>
  1627. +   <string>Bitcoin Core - Signatures</string>
  1628.    </property>
  1629.    <property name="modal">
  1630.     <bool>true</bool>
  1631. diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui
  1632. index 5ae1e12..92306cd 100644
  1633. --- a/src/qt/forms/transactiondescdialog.ui
  1634. +++ b/src/qt/forms/transactiondescdialog.ui
  1635. @@ -11,7 +11,7 @@
  1636.     </rect>
  1637.    </property>
  1638.    <property name="windowTitle">
  1639. -   <string>Transaction details</string>
  1640. +   <string>Bitcoin Core - Transaction Details</string>
  1641.    </property>
  1642.    <layout class="QVBoxLayout" name="verticalLayout">
  1643.     <item>
  1644. diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
  1645. index 004befe..da141e5 100644
  1646. --- a/src/qt/guiutil.cpp
  1647. +++ b/src/qt/guiutil.cpp
  1648. @@ -2,6 +2,10 @@
  1649.  // Distributed under the MIT/X11 software license, see the accompanying
  1650.  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  1651.  
  1652. +#include <sstream>
  1653. +
  1654. +#include <QApplication>
  1655. +
  1656.  #include "guiutil.h"
  1657.  
  1658.  #include "bitcoinaddressvalidator.h"
  1659. @@ -112,6 +116,52 @@ void setupAmountWidget(QLineEdit *widget, QWidget *parent)
  1660.      widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
  1661.  }
  1662.  
  1663. +qint64 URIParseAmount(std::string strAmount)
  1664. +{
  1665. +    bool ok;
  1666. +    qint64 nAmount = 0;
  1667. +    bool fHex = false;
  1668. +    if (strAmount[0] == 'x' || strAmount[0] == 'X')
  1669. +    {
  1670. +        fHex = true;
  1671. +        strAmount = strAmount.substr(1);
  1672. +    }
  1673. +    size_t nPosX = strAmount.find('X', 1);
  1674. +    if (nPosX == std::string::npos)
  1675. +        nPosX = strAmount.find('x', 1);
  1676. +    int nExponent = 0;
  1677. +    if (nPosX != std::string::npos)
  1678. +    {
  1679. +        nExponent = QString::fromStdString(strAmount.substr(nPosX + 1)).toInt(&ok, fHex ? 0x10 : 10);
  1680. +        if (!ok)
  1681. +            return -1;
  1682. +    }
  1683. +    else
  1684. +    {
  1685. +        // Non-compliant URI, assume standard units
  1686. +        nExponent = fHex ? 4 : 8;
  1687. +        nPosX = strAmount.size();
  1688. +    }
  1689. +    size_t nPosP = strAmount.find('.');
  1690. +    size_t nFractionLen = 0;
  1691. +    if (nPosP == std::string::npos)
  1692. +        nPosP = nPosX;
  1693. +    else
  1694. +        nFractionLen = (nPosX - nPosP) - 1;
  1695. +    nExponent -= nFractionLen;
  1696. +    strAmount = strAmount.substr(0, nPosP) + (nFractionLen ? strAmount.substr(nPosP + 1, nFractionLen) : "");
  1697. +    if (nExponent > 0)
  1698. +        strAmount.append(nExponent, '0');
  1699. +    else
  1700. +    if (nExponent < 0)
  1701. +        // WTF? truncate I guess
  1702. +        strAmount = strAmount.substr(0, strAmount.size() + nExponent);
  1703. +    nAmount = QString::fromStdString(strAmount).toLongLong(&ok, fHex ? 0x10 : 10);
  1704. +    if (!ok)
  1705. +        return -1;
  1706. +    return nAmount;
  1707. +}
  1708. +
  1709.  bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
  1710.  {
  1711.      // return if URI is not valid or is no bitcoin: URI
  1712. @@ -151,10 +201,9 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
  1713.          {
  1714.              if(!i->second.isEmpty())
  1715.              {
  1716. -                if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount))
  1717. -                {
  1718. +                rv.amount = URIParseAmount((i->second).toStdString());
  1719. +                if (rv.amount < 0)
  1720.                      return false;
  1721. -                }
  1722.              }
  1723.              fShouldReturnFalse = false;
  1724.          }
  1725. diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
  1726. index 3e99e94..9bc67d0 100644
  1727. --- a/src/qt/intro.cpp
  1728. +++ b/src/qt/intro.cpp
  1729. @@ -181,7 +181,7 @@ void Intro::pickDataDirectory()
  1730.                  TryCreateDirectory(GUIUtil::qstringToBoostPath(dataDir));
  1731.                  break;
  1732.              } catch(fs::filesystem_error &e) {
  1733. -                QMessageBox::critical(0, tr("Bitcoin"),
  1734. +                QMessageBox::critical(0, tr("Bitcoin Core"),
  1735.                      tr("Error: Specified data directory \"%1\" can not be created.").arg(dataDir));
  1736.                  /* fall through, back to choosing screen */
  1737.              }
  1738. diff --git a/src/qt/tonalutils.cpp b/src/qt/tonalutils.cpp
  1739. new file mode 100644
  1740. index 0000000..969eaec
  1741. --- /dev/null
  1742. +++ b/src/qt/tonalutils.cpp
  1743. @@ -0,0 +1,52 @@
  1744. +#include <QFont>
  1745. +#include <QFontMetrics>
  1746. +#include <QRegExp>
  1747. +#include <QRegExpValidator>
  1748. +#include <QString>
  1749. +
  1750. +#include "tonalutils.h"
  1751. +
  1752. +bool TonalUtils::Supported()
  1753. +{
  1754. +    QFontMetrics fm = QFontMetrics(QFont());
  1755. +    return fm.inFont(0xe9d9);
  1756. +}
  1757. +
  1758. +static QRegExpValidator tv(QRegExp("-?(?:[\\d\\xe9d9-\\xe9df]+\\.?|[\\d\\xe9d9-\\xe9df]*\\.[\\d\\xe9d9-\\xe9df]*)"), NULL);
  1759. +
  1760. +QValidator::State TonalUtils::validate(QString&input, int&pos)
  1761. +{
  1762. +    return tv.validate(input, pos);
  1763. +}
  1764. +
  1765. +void TonalUtils::ConvertFromHex(QString&str)
  1766. +{
  1767. +    for (int i = 0; i < str.size(); ++i)
  1768. +    {
  1769. +        ushort c = str[i].unicode();
  1770. +        if (c == '9')
  1771. +            str[i] = 0xe9d9;
  1772. +        else
  1773. +        if (c >= 'A' && c <= 'F')
  1774. +            str[i] = c + 0xe999;
  1775. +        else
  1776. +        if (c >= 'a' && c <= 'f')
  1777. +            str[i] = c + 0xe979;
  1778. +    }
  1779. +}
  1780. +
  1781. +void TonalUtils::ConvertToHex(QString&str)
  1782. +{
  1783. +    for (int i = 0; i < str.size(); ++i)
  1784. +    {
  1785. +        ushort c = str[i].unicode();
  1786. +        if (c == 0xe9d9)
  1787. +            str[i] = '9';
  1788. +        else
  1789. +        if (c == '9')
  1790. +            str[i] = 'a';
  1791. +        else
  1792. +        if (c >= 0xe9da && c <= 0xe9df)
  1793. +            str[i] = c - 0xe999;
  1794. +    }
  1795. +}
  1796. diff --git a/src/qt/tonalutils.h b/src/qt/tonalutils.h
  1797. new file mode 100644
  1798. index 0000000..426a312
  1799. --- /dev/null
  1800. +++ b/src/qt/tonalutils.h
  1801. @@ -0,0 +1,21 @@
  1802. +#ifndef TONALUTILS_H
  1803. +#define TONALUTILS_H
  1804. +
  1805. +#include <QValidator>
  1806. +
  1807. +QT_BEGIN_NAMESPACE
  1808. +class QString;
  1809. +QT_END_NAMESPACE
  1810. +
  1811. +class TonalUtils
  1812. +{
  1813. +public:
  1814. +    static bool Supported();
  1815. +
  1816. +    static QValidator::State validate(QString&input, int&pos);
  1817. +
  1818. +    static void ConvertFromHex(QString&);
  1819. +    static void ConvertToHex(QString&);
  1820. +};
  1821. +
  1822. +#endif
  1823. diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
  1824. index 1cef483..b5686e3 100644
  1825. --- a/src/qt/walletview.cpp
  1826. +++ b/src/qt/walletview.cpp
  1827. @@ -58,6 +58,10 @@ WalletView::WalletView(QWidget *parent):
  1828.      addWidget(transactionsPage);
  1829.      addWidget(receiveCoinsPage);
  1830.      addWidget(sendCoinsPage);
  1831. +#ifdef FIRST_CLASS_MESSAGING
  1832. +    signVerifyMessageDialog = new SignVerifyMessageDialog(NULL);
  1833. +    addWidget(signVerifyMessageDialog);
  1834. +#endif
  1835.  
  1836.      // Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
  1837.      connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
  1838. @@ -112,6 +116,9 @@ void WalletView::setWalletModel(WalletModel *walletModel)
  1839.      overviewPage->setWalletModel(walletModel);
  1840.      receiveCoinsPage->setModel(walletModel);
  1841.      sendCoinsPage->setModel(walletModel);
  1842. +#ifdef FIRST_CLASS_MESSAGING
  1843. +    signVerifyMessageDialog->setModel(walletModel);
  1844. +#endif
  1845.  
  1846.      if (walletModel)
  1847.      {
  1848. @@ -175,11 +182,17 @@ void WalletView::gotoSendCoinsPage(QString addr)
  1849.  
  1850.  void WalletView::gotoSignMessageTab(QString addr)
  1851.  {
  1852. +#ifdef FIRST_CLASS_MESSAGING
  1853. +    setCurrentWidget(signVerifyMessageDialog);
  1854. +
  1855. +    signVerifyMessageDialog->showTab_SM(false);
  1856. +#else
  1857.      // calls show() in showTab_SM()
  1858.      SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
  1859.      signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
  1860.      signVerifyMessageDialog->setModel(walletModel);
  1861.      signVerifyMessageDialog->showTab_SM(true);
  1862. +#endif
  1863.  
  1864.      if (!addr.isEmpty())
  1865.          signVerifyMessageDialog->setAddress_SM(addr);
  1866. @@ -187,11 +200,17 @@ void WalletView::gotoSignMessageTab(QString addr)
  1867.  
  1868.  void WalletView::gotoVerifyMessageTab(QString addr)
  1869.  {
  1870. +#ifdef FIRST_CLASS_MESSAGING
  1871. +    setCurrentWidget(signVerifyMessageDialog);
  1872. +
  1873. +    signVerifyMessageDialog->showTab_VM(false);
  1874. +#else
  1875.      // calls show() in showTab_VM()
  1876.      SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(this);
  1877.      signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
  1878.      signVerifyMessageDialog->setModel(walletModel);
  1879.      signVerifyMessageDialog->showTab_VM(true);
  1880. +#endif
  1881.  
  1882.      if (!addr.isEmpty())
  1883.          signVerifyMessageDialog->setAddress_VM(addr);
  1884. diff --git a/src/qt/walletview.h b/src/qt/walletview.h
  1885. index 9cfa8d6..566578f 100644
  1886. --- a/src/qt/walletview.h
  1887. +++ b/src/qt/walletview.h
  1888. @@ -13,6 +13,7 @@ class OverviewPage;
  1889.  class ReceiveCoinsDialog;
  1890.  class SendCoinsDialog;
  1891.  class SendCoinsRecipient;
  1892. +class SignVerifyMessageDialog;
  1893.  class TransactionView;
  1894.  class WalletModel;
  1895.  
  1896. @@ -58,6 +59,7 @@ private:
  1897.      QWidget *transactionsPage;
  1898.      ReceiveCoinsDialog *receiveCoinsPage;
  1899.      SendCoinsDialog *sendCoinsPage;
  1900. +    SignVerifyMessageDialog *signVerifyMessageDialog;
  1901.  
  1902.      TransactionView *transactionView;
  1903.  
  1904. diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp
  1905. index 4f3c39c..ec28830 100644
  1906. --- a/src/rpcclient.cpp
  1907. +++ b/src/rpcclient.cpp
  1908. @@ -149,6 +149,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
  1909.      if (strMethod == "listtransactions"       && n > 2) ConvertTo<int64_t>(params[2]);
  1910.      if (strMethod == "listaccounts"           && n > 0) ConvertTo<int64_t>(params[0]);
  1911.      if (strMethod == "walletpassphrase"       && n > 1) ConvertTo<int64_t>(params[1]);
  1912. +    if (strMethod == "prioritisetransaction"  && n > 1) ConvertTo<double>(params[1]);
  1913. +    if (strMethod == "prioritisetransaction"  && n > 2) ConvertTo<int64_t>(params[2]);
  1914.      if (strMethod == "getblocktemplate"       && n > 0) ConvertTo<Object>(params[0]);
  1915.      if (strMethod == "listsinceblock"         && n > 1) ConvertTo<int64_t>(params[1]);
  1916.      if (strMethod == "sendmany"               && n > 1) ConvertTo<Object>(params[1]);
  1917. diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
  1918. index ef99cb3..a1dfde6 100644
  1919. --- a/src/rpcmining.cpp
  1920. +++ b/src/rpcmining.cpp
  1921. @@ -3,12 +3,17 @@
  1922.  // Distributed under the MIT/X11 software license, see the accompanying
  1923.  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  1924.  
  1925. +#include <boost/date_time/posix_time/posix_time.hpp>
  1926. +#include <boost/thread/locks.hpp>
  1927. +#include <boost/thread/thread_time.hpp>
  1928. +
  1929.  #include "rpcserver.h"
  1930.  #include "chainparams.h"
  1931.  #include "init.h"
  1932.  #include "net.h"
  1933.  #include "main.h"
  1934.  #include "miner.h"
  1935. +#include "util.h"
  1936.  #ifdef ENABLE_WALLET
  1937.  #include "db.h"
  1938.  #include "wallet.h"
  1939. @@ -274,6 +279,20 @@ Value getmininginfo(const Array& params, bool fHelp)
  1940.  }
  1941.  
  1942.  
  1943. +Value prioritisetransaction(const Array& params, bool fHelp)
  1944. +{
  1945. +    if (fHelp || params.size() != 3)
  1946. +        throw runtime_error(
  1947. +            "prioritisetransaction <txid> <priority delta> <fee delta>\n"
  1948. +            "Accepts the transaction into mined blocks at a higher (or lower) priority");
  1949. +
  1950. +    uint256 hash;
  1951. +    hash.SetHex(params[0].get_str());
  1952. +    mempool.PrioritiseTransaction(hash, params[0].get_str(), params[1].get_real(), params[2].get_int64());
  1953. +    return true;
  1954. +}
  1955. +
  1956. +
  1957.  #ifdef ENABLE_WALLET
  1958.  Value getwork(const Array& params, bool fHelp)
  1959.  {
  1960. @@ -400,6 +419,8 @@ Value getwork(const Array& params, bool fHelp)
  1961.  }
  1962.  #endif
  1963.  
  1964. +static Value TestBlock(const Value& valData, bool fCheckPOW);
  1965. +
  1966.  Value getblocktemplate(const Array& params, bool fHelp)
  1967.  {
  1968.      if (fHelp || params.size() > 1)
  1969. @@ -463,6 +484,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
  1970.           );
  1971.  
  1972.      std::string strMode = "template";
  1973. +    Value lpval = Value::null;
  1974.      if (params.size() > 0)
  1975.      {
  1976.          const Object& oparam = params[0].get_obj();
  1977. @@ -475,6 +497,17 @@ Value getblocktemplate(const Array& params, bool fHelp)
  1978.          }
  1979.          else
  1980.              throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
  1981. +
  1982. +        if (strMode == "proposal")
  1983. +        {
  1984. +            const Value& dataval = find_value(oparam, "data");
  1985. +            if (dataval.type() == str_type)
  1986. +                return TestBlock(dataval, false);
  1987. +            else
  1988. +                throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
  1989. +        }
  1990. +
  1991. +        lpval = find_value(oparam, "longpollid");
  1992.      }
  1993.  
  1994.      if (strMode != "template")
  1995. @@ -486,8 +519,62 @@ Value getblocktemplate(const Array& params, bool fHelp)
  1996.      if (IsInitialBlockDownload())
  1997.          throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
  1998.  
  1999. -    // Update block
  2000.      static unsigned int nTransactionsUpdatedLast;
  2001. +
  2002. +    if (lpval.type() != null_type)
  2003. +    {
  2004. +        // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions
  2005. +        uint256 hashWatchedChain;
  2006. +        boost::system_time checktxtime;
  2007. +        unsigned int nTransactionsUpdatedLastLP;
  2008. +
  2009. +        if (lpval.type() == str_type)
  2010. +        {
  2011. +            // Format: <hashBestChain><nTransactionsUpdatedLast>
  2012. +            std::string lpstr = lpval.get_str();
  2013. +
  2014. +            hashWatchedChain.SetHex(lpstr.substr(0, 64));
  2015. +            nTransactionsUpdatedLastLP = atoi64(lpstr.substr(64));
  2016. +        }
  2017. +        else
  2018. +        {
  2019. +            // NOTE: Spec does not specify behaviour for non-string longpollid, but this makes testing easier
  2020. +            hashWatchedChain = chainActive.Tip()->GetBlockHash();
  2021. +            nTransactionsUpdatedLastLP = nTransactionsUpdatedLast;
  2022. +        }
  2023. +
  2024. +#ifdef ENABLE_WALLET
  2025. +        if (pwalletMain)
  2026. +            LEAVE_CRITICAL_SECTION(pwalletMain->cs_wallet);
  2027. +#endif
  2028. +        LEAVE_CRITICAL_SECTION(cs_main);
  2029. +        {
  2030. +            checktxtime = boost::get_system_time() + boost::posix_time::minutes(1);
  2031. +
  2032. +            boost::unique_lock<boost::mutex> lock(csBestBlock);
  2033. +            while (chainActive.Tip()->GetBlockHash() == hashWatchedChain && fRPCRunning)
  2034. +            {
  2035. +                if (!cvBlockChange.timed_wait(lock, checktxtime))
  2036. +                {
  2037. +                    // Timeout: Check transactions for update
  2038. +                    if (nTransactionsUpdatedLast != nTransactionsUpdatedLastLP)
  2039. +                        break;
  2040. +                    checktxtime += boost::posix_time::seconds(10);
  2041. +                }
  2042. +            }
  2043. +        }
  2044. +        ENTER_CRITICAL_SECTION(cs_main);
  2045. +#ifdef ENABLE_WALLET
  2046. +        if (pwalletMain)
  2047. +            ENTER_CRITICAL_SECTION(pwalletMain->cs_wallet);
  2048. +#endif
  2049. +
  2050. +        if (!fRPCRunning)
  2051. +            throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Shutting down");
  2052. +        // TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
  2053. +    }
  2054. +
  2055. +    // Update block
  2056.      static CBlockIndex* pindexPrev;
  2057.      static int64_t nStart;
  2058.      static CBlockTemplate* pblocktemplate;
  2059. @@ -522,6 +609,10 @@ Value getblocktemplate(const Array& params, bool fHelp)
  2060.      UpdateTime(*pblock, pindexPrev);
  2061.      pblock->nNonce = 0;
  2062.  
  2063. +    static Array aCaps;
  2064. +    if (aCaps.empty())
  2065. +        aCaps.push_back("proposal");
  2066. +
  2067.      Array transactions;
  2068.      map<uint256, int64_t> setTxIndex;
  2069.      int i = 0;
  2070. @@ -570,11 +661,13 @@ Value getblocktemplate(const Array& params, bool fHelp)
  2071.      }
  2072.  
  2073.      Object result;
  2074. +    result.push_back(Pair("capabilities", aCaps));
  2075.      result.push_back(Pair("version", pblock->nVersion));
  2076.      result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
  2077.      result.push_back(Pair("transactions", transactions));
  2078.      result.push_back(Pair("coinbaseaux", aux));
  2079.      result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
  2080. +    result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)));
  2081.      result.push_back(Pair("target", hashTarget.GetHex()));
  2082.      result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
  2083.      result.push_back(Pair("mutable", aMutable));
  2084. @@ -588,6 +681,42 @@ Value getblocktemplate(const Array& params, bool fHelp)
  2085.      return result;
  2086.  }
  2087.  
  2088. +static Value TestBlock(const Value& valData, bool fCheckPOW)
  2089. +{
  2090. +    vector<unsigned char> blockData(ParseHex(valData.get_str()));
  2091. +    CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
  2092. +    CBlock pblock;
  2093. +    try {
  2094. +        ssBlock >> pblock;
  2095. +    }
  2096. +    catch (std::exception &e) {
  2097. +        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
  2098. +    }
  2099. +
  2100. +    CValidationState state;
  2101. +    bool fAccepted = ProcessBlock(state, NULL, &pblock, NULL, fCheckPOW);
  2102. +    if (!fAccepted)
  2103. +    {
  2104. +        std::string strRejectReason = state.GetRejectReason();
  2105. +        if (state.IsError())
  2106. +            throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason);
  2107. +        if (state.IsInvalid())
  2108. +        {
  2109. +            if (strRejectReason.empty())
  2110. +                return "rejected";
  2111. +            return strRejectReason;
  2112. +        }
  2113. +        // Should be impossible
  2114. +        return "valid?";
  2115. +    }
  2116. +
  2117. +    // NOTE: If we process an orphan, it is accepted yet not immediately processed
  2118. +    if (state.IsOrphan())
  2119. +        return "orphan";
  2120. +
  2121. +    return Value::null;
  2122. +}
  2123. +
  2124.  Value submitblock(const Array& params, bool fHelp)
  2125.  {
  2126.      if (fHelp || params.size() < 1 || params.size() > 2)
  2127. @@ -609,20 +738,5 @@ Value submitblock(const Array& params, bool fHelp)
  2128.              + HelpExampleRpc("submitblock", "\"mydata\"")
  2129.          );
  2130.  
  2131. -    vector<unsigned char> blockData(ParseHex(params[0].get_str()));
  2132. -    CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION);
  2133. -    CBlock pblock;
  2134. -    try {
  2135. -        ssBlock >> pblock;
  2136. -    }
  2137. -    catch (std::exception &e) {
  2138. -        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
  2139. -    }
  2140. -
  2141. -    CValidationState state;
  2142. -    bool fAccepted = ProcessBlock(state, NULL, &pblock);
  2143. -    if (!fAccepted)
  2144. -        return "rejected"; // TODO: report validation state
  2145. -
  2146. -    return Value::null;
  2147. +    return TestBlock(params[0], true);
  2148.  }
  2149. diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h
  2150. index 8b3df19..90aeec0 100644
  2151. --- a/src/rpcprotocol.h
  2152. +++ b/src/rpcprotocol.h
  2153. @@ -49,9 +49,14 @@ enum RPCErrorCode
  2154.      RPC_INVALID_PARAMETER           = -8,  // Invalid, missing or duplicate parameter
  2155.      RPC_DATABASE_ERROR              = -20, // Database error
  2156.      RPC_DESERIALIZATION_ERROR       = -22, // Error parsing or validating structure in raw format
  2157. -    RPC_TRANSACTION_ERROR           = -25, // General error during transaction submission
  2158. -    RPC_TRANSACTION_REJECTED        = -26, // Transaction was rejected by network rules
  2159. -    RPC_TRANSACTION_ALREADY_IN_CHAIN= -27, // Transaction already in chain
  2160. +    RPC_VERIFY_ERROR                = -25, // General error during transaction or block submission
  2161. +    RPC_VERIFY_REJECTED             = -26, // Transaction or block was rejected by network rules
  2162. +    RPC_VERIFY_ALREADY_IN_CHAIN     = -27, // Transaction already in chain
  2163. +
  2164. +    // Aliases for backward compatibility
  2165. +    RPC_TRANSACTION_ERROR           = RPC_VERIFY_ERROR,
  2166. +    RPC_TRANSACTION_REJECTED        = RPC_VERIFY_REJECTED,
  2167. +    RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN,
  2168.  
  2169.      // P2P client errors
  2170.      RPC_CLIENT_NOT_CONNECTED        = -9,  // Bitcoin is not connected
  2171. diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
  2172. index f43acf4..9f83785 100644
  2173. --- a/src/rpcserver.cpp
  2174. +++ b/src/rpcserver.cpp
  2175. @@ -33,6 +33,7 @@ using namespace json_spirit;
  2176.  static std::string strRPCUserColonPass;
  2177.  
  2178.  // These are created by StartRPCThreads, destroyed in StopRPCThreads
  2179. +bool fRPCRunning = false;
  2180.  static asio::io_service* rpc_io_service = NULL;
  2181.  static map<string, boost::shared_ptr<deadline_timer> > deadlineTimers;
  2182.  static ssl::context* rpc_ssl_context = NULL;
  2183. @@ -253,6 +254,7 @@ static const CRPCCommand vRPCCommands[] =
  2184.      { "getblocktemplate",       &getblocktemplate,       true,      false,      false },
  2185.      { "getmininginfo",          &getmininginfo,          true,      false,      false },
  2186.      { "getnetworkhashps",       &getnetworkhashps,       true,      false,      false },
  2187. +    { "prioritisetransaction",  &prioritisetransaction,  true,      false,      false },
  2188.      { "submitblock",            &submitblock,            false,     false,      false },
  2189.  
  2190.      /* Raw transactions */
  2191. @@ -614,6 +616,8 @@ void StartRPCThreads()
  2192.          return;
  2193.      }
  2194.  
  2195. +    fRPCRunning = true;
  2196. +
  2197.      rpc_worker_group = new boost::thread_group();
  2198.      for (int i = 0; i < GetArg("-rpcthreads", 4); i++)
  2199.          rpc_worker_group->create_thread(boost::bind(&asio::io_service::run, rpc_io_service));
  2200. @@ -636,6 +640,7 @@ void StopRPCThreads()
  2201.  {
  2202.      if (rpc_io_service == NULL) return;
  2203.  
  2204. +    fRPCRunning = false;
  2205.      // First, cancel all timers and acceptors
  2206.      // This is not done automatically by ->stop(), and in some cases the destructor of
  2207.      // asio::io_service can hang if this is skipped.
  2208. @@ -656,6 +661,7 @@ void StopRPCThreads()
  2209.      deadlineTimers.clear();
  2210.  
  2211.      rpc_io_service->stop();
  2212. +    cvBlockChange.notify_all();
  2213.      if (rpc_worker_group != NULL)
  2214.          rpc_worker_group->join_all();
  2215.      delete rpc_dummy_work; rpc_dummy_work = NULL;
  2216. diff --git a/src/rpcserver.h b/src/rpcserver.h
  2217. index 1092c69..c5f4609 100644
  2218. --- a/src/rpcserver.h
  2219. +++ b/src/rpcserver.h
  2220. @@ -19,6 +19,7 @@
  2221.  #include "json/json_spirit_writer_template.h"
  2222.  
  2223.  class CBlockIndex;
  2224. +extern bool fRPCRunning;
  2225.  
  2226.  /* Start RPC threads */
  2227.  void StartRPCThreads();
  2228. @@ -126,6 +127,7 @@ extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHe
  2229.  extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
  2230.  extern json_spirit::Value gethashespersec(const json_spirit::Array& params, bool fHelp);
  2231.  extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
  2232. +extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
  2233.  extern json_spirit::Value getwork(const json_spirit::Array& params, bool fHelp);
  2234.  extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
  2235.  extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
  2236. diff --git a/src/script.cpp b/src/script.cpp
  2237. index 81d2754..24bbbad 100644
  2238. --- a/src/script.cpp
  2239. +++ b/src/script.cpp
  2240. @@ -3,6 +3,9 @@
  2241.  // Distributed under the MIT/X11 software license, see the accompanying
  2242.  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  2243.  
  2244. +#include <stdint.h>
  2245. +
  2246. +#include "compat.h"
  2247.  #include "script.h"
  2248.  
  2249.  #include "core.h"
  2250. @@ -1199,7 +1202,8 @@ bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, vector<vector<unsi
  2251.          mTemplates.insert(make_pair(TX_MULTISIG, CScript() << OP_SMALLINTEGER << OP_PUBKEYS << OP_SMALLINTEGER << OP_CHECKMULTISIG));
  2252.  
  2253.          // Empty, provably prunable, data-carrying output
  2254. -        mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
  2255. +        if (GetBoolArg("-datacarrier", true))
  2256. +            mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN << OP_SMALLDATA));
  2257.          mTemplates.insert(make_pair(TX_NULL_DATA, CScript() << OP_RETURN));
  2258.      }
  2259.  
  2260. @@ -1400,7 +1404,8 @@ int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned c
  2261.      return -1;
  2262.  }
  2263.  
  2264. -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
  2265. +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType,
  2266. +                unsigned int flags)
  2267.  {
  2268.      vector<valtype> vSolutions;
  2269.      if (!Solver(scriptPubKey, whichType, vSolutions))
  2270. @@ -1408,6 +1413,8 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
  2271.  
  2272.      if (whichType == TX_MULTISIG)
  2273.      {
  2274. +        if (!(flags & SCRIPT_VERIFY_BARE_MSIG_OK))
  2275. +            return false;
  2276.          unsigned char m = vSolutions.front()[0];
  2277.          unsigned char n = vSolutions.back()[0];
  2278.          // Support up to x-of-3 multisig txns as standard
  2279. @@ -1843,6 +1850,49 @@ unsigned int CScript::GetSigOpCount(const CScript& scriptSig) const
  2280.      return subscript.GetSigOpCount(true);
  2281.  }
  2282.  
  2283. +struct BlacklistEntry {
  2284. +    uint32_t begin;
  2285. +    uint32_t end;
  2286. +    const char *name;
  2287. +};
  2288. +
  2289. +static struct BlacklistEntry BlacklistedPrefixes[] = {
  2290. +    {0x946cb2e0, 0x946cb2e0, "Mastercoin"},
  2291. +    {0x06f1b600, 0x06f1b6ff, "SatoshiDice"},
  2292. +    {0x74db3700, 0x74db59ff, "BetCoin Dice"},
  2293. +    {0xc4c5d791, 0xc4c5d791, "CHBS"},  // 1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T
  2294. +    {0x434e5452, 0x434e5452, "Counterparty"},
  2295. +    {0x069532d8, 0x069532da, "SatoshiBones"},
  2296. +    {0xda5dde84, 0xda5dde94, "Lucky Bit"},
  2297. +};
  2298. +
  2299. +bool fIsBareMultisigStd = false;
  2300. +
  2301. +const char *CScript::IsBlacklisted() const
  2302. +{
  2303. +    if (this->size() >= 7 && this->at(0) == OP_DUP)
  2304. +    {
  2305. +        // pay-to-pubkeyhash
  2306. +        uint32_t pfx = ntohl(*(uint32_t*)&this->data()[3]);
  2307. +        unsigned i;
  2308. +
  2309. +        for (i = 0; i < (sizeof(BlacklistedPrefixes) / sizeof(BlacklistedPrefixes[0])); ++i)
  2310. +            if (pfx >= BlacklistedPrefixes[i].begin && pfx <= BlacklistedPrefixes[i].end)
  2311. +                return BlacklistedPrefixes[i].name;
  2312. +    }
  2313. +    else
  2314. +    if (!fIsBareMultisigStd)
  2315. +    {
  2316. +        txnouttype type;
  2317. +        vector<vector<unsigned char> > vSolutions;
  2318. +        Solver(*this, type, vSolutions);
  2319. +        if (type == TX_MULTISIG)
  2320. +            return "bare multisig";
  2321. +    }
  2322. +
  2323. +    return NULL;
  2324. +}
  2325. +
  2326.  bool CScript::IsPayToScriptHash() const
  2327.  {
  2328.      // Extra-fast test for pay-to-script-hash CScripts:
  2329. diff --git a/src/script.h b/src/script.h
  2330. index 1742ce8..20514c0 100644
  2331. --- a/src/script.h
  2332. +++ b/src/script.h
  2333. @@ -190,6 +190,7 @@ enum
  2334.      SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys
  2335.      SCRIPT_VERIFY_EVEN_S    = (1U << 2), // enforce even S values in signatures (depends on STRICTENC)
  2336.      SCRIPT_VERIFY_NOCACHE   = (1U << 3), // do not store results in signature cache (but do query it)
  2337. +    SCRIPT_VERIFY_BARE_MSIG_OK = (1U << 4), // are bare msig outputs permitted?
  2338.  };
  2339.  
  2340.  enum txnouttype
  2341. @@ -652,6 +653,8 @@ public:
  2342.      // pay-to-script-hash transactions:
  2343.      unsigned int GetSigOpCount(const CScript& scriptSig) const;
  2344.  
  2345. +    const char *IsBlacklisted() const;
  2346. +
  2347.      bool IsPayToScriptHash() const;
  2348.  
  2349.      // Called by IsStandardTx and P2SH VerifyScript (which makes it consensus-critical).
  2350. @@ -790,7 +793,8 @@ bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int
  2351.  bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags, int nHashType);
  2352.  bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);
  2353.  int ScriptSigArgsExpected(txnouttype t, const std::vector<std::vector<unsigned char> >& vSolutions);
  2354. -bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType);
  2355. +bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType,
  2356. +                unsigned int flags);
  2357.  bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey);
  2358.  bool IsMine(const CKeyStore& keystore, const CTxDestination &dest);
  2359.  void ExtractAffectedKeys(const CKeyStore &keystore, const CScript& scriptPubKey, std::vector<CKeyID> &vKeys);
  2360. diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
  2361. index 3775abd..8e6f7d2 100644
  2362. --- a/src/test/multisig_tests.cpp
  2363. +++ b/src/test/multisig_tests.cpp
  2364. @@ -131,23 +131,30 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard)
  2365.      for (int i = 0; i < 4; i++)
  2366.          key[i].MakeNewKey(true);
  2367.  
  2368. +    unsigned int verfFlags = SCRIPT_VERIFY_BARE_MSIG_OK;
  2369.      txnouttype whichType;
  2370.  
  2371.      CScript a_and_b;
  2372.      a_and_b << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
  2373. -    BOOST_CHECK(::IsStandard(a_and_b, whichType));
  2374. +    BOOST_CHECK(::IsStandard(a_and_b, whichType, verfFlags));
  2375. +    BOOST_CHECK(!::IsStandard(a_and_b, whichType,
  2376. +                              verfFlags & ~SCRIPT_VERIFY_BARE_MSIG_OK));
  2377.  
  2378.      CScript a_or_b;
  2379.      a_or_b  << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
  2380. -    BOOST_CHECK(::IsStandard(a_or_b, whichType));
  2381. +    BOOST_CHECK(::IsStandard(a_or_b, whichType, verfFlags));
  2382. +    BOOST_CHECK(!::IsStandard(a_or_b, whichType,
  2383. +                              verfFlags & ~SCRIPT_VERIFY_BARE_MSIG_OK));
  2384.  
  2385.      CScript escrow;
  2386.      escrow << OP_2 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << OP_3 << OP_CHECKMULTISIG;
  2387. -    BOOST_CHECK(::IsStandard(escrow, whichType));
  2388. +    BOOST_CHECK(::IsStandard(escrow, whichType, verfFlags));
  2389. +    BOOST_CHECK(!::IsStandard(escrow, whichType,
  2390. +                              verfFlags & ~SCRIPT_VERIFY_BARE_MSIG_OK));
  2391.  
  2392.      CScript one_of_four;
  2393.      one_of_four << OP_1 << key[0].GetPubKey() << key[1].GetPubKey() << key[2].GetPubKey() << key[3].GetPubKey() << OP_4 << OP_CHECKMULTISIG;
  2394. -    BOOST_CHECK(!::IsStandard(one_of_four, whichType));
  2395. +    BOOST_CHECK(!::IsStandard(one_of_four, whichType, verfFlags));
  2396.  
  2397.      CScript malformed[6];
  2398.      malformed[0] << OP_3 << key[0].GetPubKey() << key[1].GetPubKey() << OP_2 << OP_CHECKMULTISIG;
  2399. @@ -158,7 +165,7 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard)
  2400.      malformed[5] << OP_1 << key[0].GetPubKey() << key[1].GetPubKey();
  2401.  
  2402.      for (int i = 0; i < 6; i++)
  2403. -        BOOST_CHECK(!::IsStandard(malformed[i], whichType));
  2404. +        BOOST_CHECK(!::IsStandard(malformed[i], whichType, verfFlags));
  2405.  }
  2406.  
  2407.  BOOST_AUTO_TEST_CASE(multisig_Solver1)
  2408. diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
  2409. index 9b1290e..9bf8dc8 100644
  2410. --- a/src/test/script_P2SH_tests.cpp
  2411. +++ b/src/test/script_P2SH_tests.cpp
  2412. @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(set)
  2413.          txTo[i].vin[0].prevout.n = i;
  2414.          txTo[i].vin[0].prevout.hash = txFrom.GetHash();
  2415.          txTo[i].vout[0].nValue = 1*CENT;
  2416. -        txTo[i].vout[0].scriptPubKey = inner[i];
  2417. +        txTo[i].vout[0].scriptPubKey = outer[i];
  2418.          BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i));
  2419.      }
  2420.      for (int i = 0; i < 4; i++)
  2421. diff --git a/src/txmempool.cpp b/src/txmempool.cpp
  2422. index 64c9eac..9713422 100644
  2423. --- a/src/txmempool.cpp
  2424. +++ b/src/txmempool.cpp
  2425. @@ -195,6 +195,35 @@ bool CTxMemPool::lookup(uint256 hash, CTransaction& result) const
  2426.      return true;
  2427.  }
  2428.  
  2429. +void CTxMemPool::PrioritiseTransaction(const uint256 hash, const string strHash, double dPriorityDelta, int64_t nFeeDelta)
  2430. +{
  2431. +    {
  2432. +        LOCK(cs);
  2433. +        std::pair<double, int64_t> &deltas = mapDeltas[hash];
  2434. +        deltas.first += dPriorityDelta;
  2435. +        deltas.second += nFeeDelta;
  2436. +    }
  2437. +    LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", strHash.c_str(), dPriorityDelta, nFeeDelta);
  2438. +}
  2439. +
  2440. +void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta)
  2441. +{
  2442. +    LOCK(cs);
  2443. +    std::map<uint256, std::pair<double, int64_t> >::iterator pos = mapDeltas.find(hash);
  2444. +    if (pos == mapDeltas.end())
  2445. +        return;
  2446. +    const std::pair<double, int64_t> &deltas = pos->second;
  2447. +    dPriorityDelta += deltas.first;
  2448. +    nFeeDelta += deltas.second;
  2449. +}
  2450. +
  2451. +void CTxMemPool::ClearPrioritisation(const uint256 hash)
  2452. +{
  2453. +    LOCK(cs);
  2454. +    mapDeltas.erase(hash);
  2455. +}
  2456. +
  2457. +
  2458.  CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView &baseIn, CTxMemPool &mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
  2459.  
  2460.  bool CCoinsViewMemPool::GetCoins(const uint256 &txid, CCoins &coins) {
  2461. diff --git a/src/txmempool.h b/src/txmempool.h
  2462. index 4509e95..2d46816 100644
  2463. --- a/src/txmempool.h
  2464. +++ b/src/txmempool.h
  2465. @@ -61,6 +61,7 @@ public:
  2466.      mutable CCriticalSection cs;
  2467.      std::map<uint256, CTxMemPoolEntry> mapTx;
  2468.      std::map<COutPoint, CInPoint> mapNextTx;
  2469. +    std::map<uint256, std::pair<double, int64_t> > mapDeltas;
  2470.  
  2471.      CTxMemPool();
  2472.  
  2473. @@ -82,6 +83,11 @@ public:
  2474.      unsigned int GetTransactionsUpdated() const;
  2475.      void AddTransactionsUpdated(unsigned int n);
  2476.  
  2477. +    /** Affect CreateNewBlock prioritisation of transactions */
  2478. +    void PrioritiseTransaction(const uint256 hash, const std::string strHash, double dPriorityDelta, int64_t nFeeDelta);
  2479. +    void ApplyDeltas(const uint256 hash, double &dPriorityDelta, int64_t &nFeeDelta);
  2480. +    void ClearPrioritisation(const uint256 hash);
  2481. +
  2482.      unsigned long size()
  2483.      {
  2484.          LOCK(cs);
  2485. diff --git a/src/util.cpp b/src/util.cpp
  2486. index b8036a3..88af740 100644
  2487. --- a/src/util.cpp
  2488. +++ b/src/util.cpp
  2489. @@ -1336,6 +1336,8 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
  2490.      if (!comments.empty())
  2491.          ss << "(" << boost::algorithm::join(comments, "; ") << ")";
  2492.      ss << "/";
  2493. +    ss << "ljr" << ":" << "20141002";
  2494. +    ss << "/";
  2495.      return ss.str();
  2496.  }
  2497.  
  2498. diff --git a/src/wallet.cpp b/src/wallet.cpp
  2499. index 80f011e..6f80fda 100644
  2500. --- a/src/wallet.cpp
  2501. +++ b/src/wallet.cpp
  2502. @@ -1246,6 +1246,25 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
  2503.  
  2504.      wtxNew.BindWallet(this);
  2505.  
  2506. +    // Discourage fee sniping.
  2507. +    //
  2508. +    // However because of a off-by-one-error in previous versions we need to
  2509. +    // neuter it by setting nLockTime to at least one less than nBestHeight.
  2510. +    // Secondly currently propagation of transactions created for block heights
  2511. +    // corresponding to blocks that were just mined may be iffy - transactions
  2512. +    // aren't re-accepted into the mempool - we additionally neuter the code by
  2513. +    // going ten blocks back. Doesn't yet do anything for sniping, but does act
  2514. +    // to shake out wallet bugs like not showing nLockTime'd transactions at
  2515. +    // all.
  2516. +    wtxNew.nLockTime = chainActive.Height() - 10;
  2517. +
  2518. +    // Secondly occasionally randomly pick a nLockTime even further back, so
  2519. +    // that transactions that are delayed after signing for whatever reason,
  2520. +    // e.g. high-latency mix networks and some CoinJoin implementations, have
  2521. +    // better privacy.
  2522. +    if (GetRandInt(10) == 0)
  2523. +        wtxNew.nLockTime -= GetRandInt(100);
  2524. +
  2525.      {
  2526.          LOCK2(cs_main, cs_wallet);
  2527.          {
  2528. @@ -1349,8 +1368,12 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
  2529.                      reservekey.ReturnKey();
  2530.  
  2531.                  // Fill vin
  2532. +                //
  2533. +                // Note how the sequence number is set to max()-1 so that the
  2534. +                // nLockTime set above actually works.
  2535.                  BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
  2536. -                    wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
  2537. +                    wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
  2538. +                                std::numeric_limits<unsigned int>::max()-1));
  2539.  
  2540.                  // Sign
  2541.                  int nIn = 0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement