1 // Copyright (c) 2018-2020 Daniel Kraft
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_RPC_AUXPOW_MINER_H
6 #define BITCOIN_RPC_AUXPOW_MINER_H
7 
8 #include <miner.h>
9 #include <rpc/request.h>
10 #include <script/script.h>
11 #include <script/standard.h>
12 #include <sync.h>
13 #include <txmempool.h>
14 #include <uint256.h>
15 #include <univalue.h>
16 
17 #include <map>
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 namespace auxpow_tests
23 {
24 class AuxpowMinerForTest;
25 }
26 
27 /**
28  * This class holds "global" state used to construct blocks for the auxpow
29  * mining RPCs and the map of already constructed blocks to look them up
30  * in the submitauxblock RPC.
31  *
32  * It is used as a singleton that is initialised during startup, taking the
33  * place of the previously real global and static variables.
34  */
35 class AuxpowMiner
36 {
37 
38 private:
39 
40   /** The lock used for state in this object.  */
41   mutable RecursiveMutex cs;
42   /** All currently "active" block templates.  */
43   std::vector<std::unique_ptr<CBlockTemplate>> templates;
44   /** Maps block hashes to pointers in vTemplates.  Does not own the memory.  */
45   std::map<uint256, const CBlock*> blocks;
46   /** Maps coinbase script hashes to pointers in vTemplates.  Does not own the memory.  */
47   std::map<CScriptID, const CBlock*> curBlocks;
48 
49   /** The current extra nonce for block creation.  */
50   unsigned extraNonce = 0;
51 
52   /* Some data about when the current block (pblock) was constructed.  */
53   unsigned txUpdatedLast;
54   const CBlockIndex* pindexPrev = nullptr;
55   uint64_t startTime;
56 
57   /**
58    * Constructs a new current block if necessary (checking the current state to
59    * see if "enough changed" for this), and returns a pointer to the block
60    * that should be returned to a miner for working on at the moment.  Also
61    * fills in the difficulty target value.
62    */
63   const CBlock* getCurrentBlock (const CTxMemPool& mempool,
64                                  const CScript& scriptPubKey, uint256& target);
65 
66   /**
67    * Looks up a previously constructed block by its (hex-encoded) hash.  If the
68    * block is found, it is returned.  Otherwise, a JSONRPCError is thrown.
69    */
70   const CBlock* lookupSavedBlock (const std::string& hashHex) const;
71 
72   friend class auxpow_tests::AuxpowMinerForTest;
73 
74 public:
75 
76   AuxpowMiner () = default;
77 
78   /**
79    * Performs the main work for the "createauxblock" RPC:  Construct a new block
80    * to work on with the given address for the block reward and return the
81    * necessary information for the miner to construct an auxpow for it.
82    */
83   UniValue createAuxBlock (const JSONRPCRequest& request,
84                            const CScript& scriptPubKey);
85 
86   /**
87    * Performs the main work for the "submitauxblock" RPC:  Look up the block
88    * previously created for the given hash, attach the given auxpow to it
89    * and try to submit it.  Returns true if all was successful and the block
90    * was accepted.
91    */
92   bool submitAuxBlock (const JSONRPCRequest& request,
93                        const std::string& hashHex,
94                        const std::string& auxpowHex) const;
95 
96   /**
97    * Returns the singleton instance of AuxpowMiner that is used for RPCs.
98    */
99   static AuxpowMiner& get ();
100 
101 };
102 
103 #endif // BITCOIN_RPC_AUXPOW_MINER_H
104