You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

miner.cpp 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2014 The Bitcoin Core developers
  3. // Distributed under the MIT software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "miner.h"
  6. #include "amount.h"
  7. #include "chainparams.h"
  8. #include "consensus/consensus.h"
  9. #include "consensus/validation.h"
  10. #include "hash.h"
  11. #include "main.h"
  12. #include "net.h"
  13. #include "pow.h"
  14. #include "primitives/transaction.h"
  15. #include "timedata.h"
  16. #include "util.h"
  17. #include "utilmoneystr.h"
  18. #ifdef ENABLE_WALLET
  19. #include "wallet/wallet.h"
  20. #endif
  21. #include <boost/thread.hpp>
  22. #include <boost/tuple/tuple.hpp>
  23. using namespace std;
  24. //////////////////////////////////////////////////////////////////////////////
  25. //
  26. // BitcoinMiner
  27. //
  28. //
  29. // Unconfirmed transactions in the memory pool often depend on other
  30. // transactions in the memory pool. When we select transactions from the
  31. // pool, we select by highest priority or fee rate, so we might consider
  32. // transactions that depend on transactions that aren't yet in the block.
  33. // The COrphan class keeps track of these 'temporary orphans' while
  34. // CreateBlock is figuring out which transactions to include.
  35. //
  36. class COrphan
  37. {
  38. public:
  39. const CTransaction* ptx;
  40. set<uint256> setDependsOn;
  41. CFeeRate feeRate;
  42. double dPriority;
  43. COrphan(const CTransaction* ptxIn) : ptx(ptxIn), feeRate(0), dPriority(0)
  44. {
  45. }
  46. };
  47. uint64_t nLastBlockTx = 0;
  48. uint64_t nLastBlockSize = 0;
  49. // We want to sort transactions by priority and fee rate, so:
  50. typedef boost::tuple<double, CFeeRate, const CTransaction*> TxPriority;
  51. class TxPriorityCompare
  52. {
  53. bool byFee;
  54. public:
  55. TxPriorityCompare(bool _byFee) : byFee(_byFee) { }
  56. bool operator()(const TxPriority& a, const TxPriority& b)
  57. {
  58. if (byFee)
  59. {
  60. if (a.get<1>() == b.get<1>())
  61. return a.get<0>() < b.get<0>();
  62. return a.get<1>() < b.get<1>();
  63. }
  64. else
  65. {
  66. if (a.get<0>() == b.get<0>())
  67. return a.get<1>() < b.get<1>();
  68. return a.get<0>() < b.get<0>();
  69. }
  70. }
  71. };
  72. void UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev)
  73. {
  74. pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
  75. // Updating time can change work required on testnet:
  76. if (consensusParams.fPowAllowMinDifficultyBlocks)
  77. pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, consensusParams);
  78. }
  79. CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
  80. {
  81. const CChainParams& chainparams = Params();
  82. // Create new block
  83. auto_ptr<CBlockTemplate> pblocktemplate(new CBlockTemplate());
  84. if(!pblocktemplate.get())
  85. return NULL;
  86. CBlock *pblock = &pblocktemplate->block; // pointer for convenience
  87. // -regtest only: allow overriding block.nVersion with
  88. // -blockversion=N to test forking scenarios
  89. if (Params().MineBlocksOnDemand())
  90. pblock->nVersion = GetArg("-blockversion", pblock->nVersion);
  91. // Create coinbase tx
  92. CMutableTransaction txNew;
  93. txNew.vin.resize(1);
  94. txNew.vin[0].prevout.SetNull();
  95. txNew.vout.resize(1);
  96. txNew.vout[0].scriptPubKey = scriptPubKeyIn;
  97. // Add dummy coinbase tx as first transaction
  98. pblock->vtx.push_back(CTransaction());
  99. pblocktemplate->vTxFees.push_back(-1); // updated at end
  100. pblocktemplate->vTxSigOps.push_back(-1); // updated at end
  101. // Largest block you're willing to create:
  102. unsigned int nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE);
  103. // Limit to betweeen 1K and MAX_BLOCK_SIZE-1K for sanity:
  104. nBlockMaxSize = std::max((unsigned int)1000, std::min((unsigned int)(MAX_BLOCK_SIZE-1000), nBlockMaxSize));
  105. // How much of the block should be dedicated to high-priority transactions,
  106. // included regardless of the fees they pay
  107. unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE);
  108. nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize);
  109. // Minimum block size you want to create; block will be filled with free transactions
  110. // until there are no more or the block reaches this size:
  111. unsigned int nBlockMinSize = GetArg("-blockminsize", DEFAULT_BLOCK_MIN_SIZE);
  112. nBlockMinSize = std::min(nBlockMaxSize, nBlockMinSize);
  113. // Collect memory pool transactions into the block
  114. CAmount nFees = 0;
  115. {
  116. LOCK2(cs_main, mempool.cs);
  117. CBlockIndex* pindexPrev = chainActive.Tip();
  118. const int nHeight = pindexPrev->nHeight + 1;
  119. pblock->nTime = GetAdjustedTime();
  120. CCoinsViewCache view(pcoinsTip);
  121. // Priority order to process transactions
  122. list<COrphan> vOrphan; // list memory doesn't move
  123. map<uint256, vector<COrphan*> > mapDependers;
  124. bool fPrintPriority = GetBoolArg("-printpriority", false);
  125. // This vector will be sorted into a priority queue:
  126. vector<TxPriority> vecPriority;
  127. vecPriority.reserve(mempool.mapTx.size());
  128. for (map<uint256, CTxMemPoolEntry>::iterator mi = mempool.mapTx.begin();
  129. mi != mempool.mapTx.end(); ++mi)
  130. {
  131. const CTransaction& tx = mi->second.GetTx();
  132. if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight, pblock->nTime))
  133. continue;
  134. COrphan* porphan = NULL;
  135. double dPriority = 0;
  136. CAmount nTotalIn = 0;
  137. bool fMissingInputs = false;
  138. BOOST_FOREACH(const CTxIn& txin, tx.vin)
  139. {
  140. // Read prev transaction
  141. if (!view.HaveCoins(txin.prevout.hash))
  142. {
  143. // This should never happen; all transactions in the memory
  144. // pool should connect to either transactions in the chain
  145. // or other transactions in the memory pool.
  146. if (!mempool.mapTx.count(txin.prevout.hash))
  147. {
  148. LogPrintf("ERROR: mempool transaction missing input\n");
  149. if (fDebug) assert("mempool transaction missing input" == 0);
  150. fMissingInputs = true;
  151. if (porphan)
  152. vOrphan.pop_back();
  153. break;
  154. }
  155. // Has to wait for dependencies
  156. if (!porphan)
  157. {
  158. // Use list for automatic deletion
  159. vOrphan.push_back(COrphan(&tx));
  160. porphan = &vOrphan.back();
  161. }
  162. mapDependers[txin.prevout.hash].push_back(porphan);
  163. porphan->setDependsOn.insert(txin.prevout.hash);
  164. nTotalIn += mempool.mapTx[txin.prevout.hash].GetTx().vout[txin.prevout.n].nValue;
  165. continue;
  166. }
  167. const CCoins* coins = view.AccessCoins(txin.prevout.hash);
  168. assert(coins);
  169. CAmount nValueIn = coins->vout[txin.prevout.n].nValue;
  170. nTotalIn += nValueIn;
  171. int nConf = nHeight - coins->nHeight;
  172. dPriority += (double)nValueIn * nConf;
  173. }
  174. if (fMissingInputs) continue;
  175. // Priority is sum(valuein * age) / modified_txsize
  176. unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
  177. dPriority = tx.ComputePriority(dPriority, nTxSize);
  178. uint256 hash = tx.GetHash();
  179. mempool.ApplyDeltas(hash, dPriority, nTotalIn);
  180. CFeeRate feeRate(nTotalIn-tx.GetValueOut(), nTxSize);
  181. if (porphan)
  182. {
  183. porphan->dPriority = dPriority;
  184. porphan->feeRate = feeRate;
  185. }
  186. else
  187. vecPriority.push_back(TxPriority(dPriority, feeRate, &mi->second.GetTx()));
  188. }
  189. // Collect transactions into block
  190. uint64_t nBlockSize = 1000;
  191. uint64_t nBlockTx = 0;
  192. int nBlockSigOps = 100;
  193. bool fSortedByFee = (nBlockPrioritySize <= 0);
  194. TxPriorityCompare comparer(fSortedByFee);
  195. std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
  196. while (!vecPriority.empty())
  197. {
  198. // Take highest priority transaction off the priority queue:
  199. double dPriority = vecPriority.front().get<0>();
  200. CFeeRate feeRate = vecPriority.front().get<1>();
  201. const CTransaction& tx = *(vecPriority.front().get<2>());
  202. std::pop_heap(vecPriority.begin(), vecPriority.end(), comparer);
  203. vecPriority.pop_back();
  204. // Size limits
  205. unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
  206. if (nBlockSize + nTxSize >= nBlockMaxSize)
  207. continue;
  208. // Legacy limits on sigOps:
  209. unsigned int nTxSigOps = GetLegacySigOpCount(tx);
  210. if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
  211. continue;
  212. // Skip free transactions if we're past the minimum block size:
  213. const uint256& hash = tx.GetHash();
  214. double dPriorityDelta = 0;
  215. CAmount nFeeDelta = 0;
  216. mempool.ApplyDeltas(hash, dPriorityDelta, nFeeDelta);
  217. if (fSortedByFee && (dPriorityDelta <= 0) && (nFeeDelta <= 0) && (feeRate < ::minRelayTxFee) && (nBlockSize + nTxSize >= nBlockMinSize))
  218. continue;
  219. // Prioritise by fee once past the priority size or we run out of high-priority
  220. // transactions:
  221. if (!fSortedByFee &&
  222. ((nBlockSize + nTxSize >= nBlockPrioritySize) || !AllowFree(dPriority)))
  223. {
  224. fSortedByFee = true;
  225. comparer = TxPriorityCompare(fSortedByFee);
  226. std::make_heap(vecPriority.begin(), vecPriority.end(), comparer);
  227. }
  228. if (!view.HaveInputs(tx))
  229. continue;
  230. CAmount nTxFees = view.GetValueIn(tx)-tx.GetValueOut();
  231. nTxSigOps += GetP2SHSigOpCount(tx, view);
  232. if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
  233. continue;
  234. // Note that flags: we don't want to set mempool/IsStandard()
  235. // policy here, but we still have to ensure that the block we
  236. // create only contains transactions that are valid in new blocks.
  237. CValidationState state;
  238. if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
  239. continue;
  240. UpdateCoins(tx, state, view, nHeight);
  241. // Added
  242. pblock->vtx.push_back(tx);
  243. pblocktemplate->vTxFees.push_back(nTxFees);
  244. pblocktemplate->vTxSigOps.push_back(nTxSigOps);
  245. nBlockSize += nTxSize;
  246. ++nBlockTx;
  247. nBlockSigOps += nTxSigOps;
  248. nFees += nTxFees;
  249. if (fPrintPriority)
  250. {
  251. LogPrintf("priority %.1f fee %s txid %s\n",
  252. dPriority, feeRate.ToString(), tx.GetHash().ToString());
  253. }
  254. // Add transactions that depend on this one to the priority queue
  255. if (mapDependers.count(hash))
  256. {
  257. BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
  258. {
  259. if (!porphan->setDependsOn.empty())
  260. {
  261. porphan->setDependsOn.erase(hash);
  262. if (porphan->setDependsOn.empty())
  263. {
  264. vecPriority.push_back(TxPriority(porphan->dPriority, porphan->feeRate, porphan->ptx));
  265. std::push_heap(vecPriority.begin(), vecPriority.end(), comparer);
  266. }
  267. }
  268. }
  269. }
  270. }
  271. nLastBlockTx = nBlockTx;
  272. nLastBlockSize = nBlockSize;
  273. LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize);
  274. // Compute final coinbase transaction.
  275. txNew.vout[0].nValue = nFees + GetBlockSubsidy(nHeight, chainparams.GetConsensus());
  276. txNew.vin[0].scriptSig = CScript() << nHeight << OP_0;
  277. pblock->vtx[0] = txNew;
  278. pblocktemplate->vTxFees[0] = -nFees;
  279. // Fill in header
  280. pblock->hashPrevBlock = pindexPrev->GetBlockHash();
  281. UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
  282. pblock->nBits = GetNextWorkRequired(pindexPrev, pblock, Params().GetConsensus());
  283. pblock->nNonce = 0;
  284. pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]);
  285. CValidationState state;
  286. if (!TestBlockValidity(state, *pblock, pindexPrev, false, false))
  287. throw std::runtime_error("CreateNewBlock(): TestBlockValidity failed");
  288. }
  289. return pblocktemplate.release();
  290. }
  291. void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
  292. {
  293. // Update nExtraNonce
  294. static uint256 hashPrevBlock;
  295. if (hashPrevBlock != pblock->hashPrevBlock)
  296. {
  297. nExtraNonce = 0;
  298. hashPrevBlock = pblock->hashPrevBlock;
  299. }
  300. ++nExtraNonce;
  301. unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2
  302. CMutableTransaction txCoinbase(pblock->vtx[0]);
  303. txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce)) + COINBASE_FLAGS;
  304. assert(txCoinbase.vin[0].scriptSig.size() <= 100);
  305. pblock->vtx[0] = txCoinbase;
  306. pblock->hashMerkleRoot = pblock->BuildMerkleTree();
  307. }
  308. #ifdef ENABLE_WALLET
  309. //////////////////////////////////////////////////////////////////////////////
  310. //
  311. // Internal miner
  312. //
  313. //
  314. // ScanHash scans nonces looking for a hash with at least some zero bits.
  315. // The nonce is usually preserved between calls, but periodically or if the
  316. // nonce is 0xffff0000 or above, the block is rebuilt and nNonce starts over at
  317. // zero.
  318. //
  319. bool static ScanHash(const CBlockHeader *pblock, uint32_t& nNonce, uint256 *phash)
  320. {
  321. // Write the first 76 bytes of the block header to a double-SHA256 state.
  322. CHash256 hasher;
  323. CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
  324. ss << *pblock;
  325. assert(ss.size() == 80);
  326. hasher.Write((unsigned char*)&ss[0], 76);
  327. while (true) {
  328. nNonce++;
  329. // Write the last 4 bytes of the block header (the nonce) to a copy of
  330. // the double-SHA256 state, and compute the result.
  331. CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);
  332. // Return the nonce if the hash has at least some zero bits,
  333. // caller will check if it has enough to reach the target
  334. if (((uint16_t*)phash)[15] == 0)
  335. return true;
  336. // If nothing found after trying for a while, return -1
  337. if ((nNonce & 0xfff) == 0)
  338. return false;
  339. }
  340. }
  341. CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey)
  342. {
  343. CPubKey pubkey;
  344. if (!reservekey.GetReservedKey(pubkey))
  345. return NULL;
  346. CScript scriptPubKey = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
  347. return CreateNewBlock(scriptPubKey);
  348. }
  349. static bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey)
  350. {
  351. LogPrintf("%s\n", pblock->ToString());
  352. LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue));
  353. // Found a solution
  354. {
  355. LOCK(cs_main);
  356. if (pblock->hashPrevBlock != chainActive.Tip()->GetBlockHash())
  357. return error("BitcoinMiner: generated block is stale");
  358. }
  359. // Remove key from key pool
  360. reservekey.KeepKey();
  361. // Track how many getdata requests this block gets
  362. {
  363. LOCK(wallet.cs_wallet);
  364. wallet.mapRequestCount[pblock->GetHash()] = 0;
  365. }
  366. // Process this block the same as if we had received it from another node
  367. CValidationState state;
  368. if (!ProcessNewBlock(state, NULL, pblock, true, NULL))
  369. return error("BitcoinMiner: ProcessNewBlock, block not accepted");
  370. return true;
  371. }
  372. void static BitcoinMiner(CWallet *pwallet)
  373. {
  374. LogPrintf("BitcoinMiner started\n");
  375. SetThreadPriority(THREAD_PRIORITY_LOWEST);
  376. RenameThread("bitcoin-miner");
  377. const CChainParams& chainparams = Params();
  378. // Each thread has its own key and counter
  379. CReserveKey reservekey(pwallet);
  380. unsigned int nExtraNonce = 0;
  381. try {
  382. while (true) {
  383. if (chainparams.MiningRequiresPeers()) {
  384. // Busy-wait for the network to come online so we don't waste time mining
  385. // on an obsolete chain. In regtest mode we expect to fly solo.
  386. do {
  387. bool fvNodesEmpty;
  388. {
  389. LOCK(cs_vNodes);
  390. fvNodesEmpty = vNodes.empty();
  391. }
  392. if (!fvNodesEmpty && !IsInitialBlockDownload())
  393. break;
  394. MilliSleep(1000);
  395. } while (true);
  396. }
  397. //
  398. // Create new block
  399. //
  400. unsigned int nTransactionsUpdatedLast = mempool.GetTransactionsUpdated();
  401. CBlockIndex* pindexPrev = chainActive.Tip();
  402. auto_ptr<CBlockTemplate> pblocktemplate(CreateNewBlockWithKey(reservekey));
  403. if (!pblocktemplate.get())
  404. {
  405. LogPrintf("Error in BitcoinMiner: Keypool ran out, please call keypoolrefill before restarting the mining thread\n");
  406. return;
  407. }
  408. CBlock *pblock = &pblocktemplate->block;
  409. IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);
  410. LogPrintf("Running BitcoinMiner with %u transactions in block (%u bytes)\n", pblock->vtx.size(),
  411. ::GetSerializeSize(*pblock, SER_NETWORK, PROTOCOL_VERSION));
  412. //
  413. // Search
  414. //
  415. int64_t nStart = GetTime();
  416. arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
  417. uint256 hash;
  418. uint32_t nNonce = 0;
  419. while (true) {
  420. // Check if something found
  421. if (ScanHash(pblock, nNonce, &hash))
  422. {
  423. if (UintToArith256(hash) <= hashTarget)
  424. {
  425. // Found a solution
  426. pblock->nNonce = nNonce;
  427. assert(hash == pblock->GetHash());
  428. SetThreadPriority(THREAD_PRIORITY_NORMAL);
  429. LogPrintf("BitcoinMiner:\n");
  430. LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex());
  431. ProcessBlockFound(pblock, *pwallet, reservekey);
  432. SetThreadPriority(THREAD_PRIORITY_LOWEST);
  433. // In regression test mode, stop mining after a block is found.
  434. if (chainparams.MineBlocksOnDemand())
  435. throw boost::thread_interrupted();
  436. break;
  437. }
  438. }
  439. // Check for stop or if block needs to be rebuilt
  440. boost::this_thread::interruption_point();
  441. // Regtest mode doesn't require peers
  442. if (vNodes.empty() && chainparams.MiningRequiresPeers())
  443. break;
  444. if (nNonce >= 0xffff0000)
  445. break;
  446. if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)
  447. break;
  448. if (pindexPrev != chainActive.Tip())
  449. break;
  450. // Update nTime every few seconds
  451. UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev);
  452. if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)
  453. {
  454. // Changing pblock->nTime can change work required on testnet:
  455. hashTarget.SetCompact(pblock->nBits);
  456. }
  457. }
  458. }
  459. }
  460. catch (const boost::thread_interrupted&)
  461. {
  462. LogPrintf("BitcoinMiner terminated\n");
  463. throw;
  464. }
  465. catch (const std::runtime_error &e)
  466. {
  467. LogPrintf("BitcoinMiner runtime error: %s\n", e.what());
  468. return;
  469. }
  470. }
  471. void GenerateBitcoins(bool fGenerate, CWallet* pwallet, int nThreads)
  472. {
  473. static boost::thread_group* minerThreads = NULL;
  474. if (nThreads < 0) {
  475. // In regtest threads defaults to 1
  476. if (Params().DefaultMinerThreads())
  477. nThreads = Params().DefaultMinerThreads();
  478. else
  479. nThreads = boost::thread::hardware_concurrency();
  480. }
  481. if (minerThreads != NULL)
  482. {
  483. minerThreads->interrupt_all();
  484. delete minerThreads;
  485. minerThreads = NULL;
  486. }
  487. if (nThreads == 0 || !fGenerate)
  488. return;
  489. minerThreads = new boost::thread_group();
  490. for (int i = 0; i < nThreads; i++)
  491. minerThreads->create_thread(boost::bind(&BitcoinMiner, pwallet));
  492. }
  493. #endif // ENABLE_WALLET