1 // Aleth: Ethereum C++ client, tools and libraries.
2 // Copyright 2014-2019 Aleth Authors.
3 // Licensed under the GNU General Public License, Version 3.
4 #pragma once
5 
6 #include <libdevcore/Address.h>
7 #include <libdevcore/Common.h>
8 #include <libdevcore/Exceptions.h>
9 #include <libdevcore/FixedHash.h>
10 
11 #include <functional>
12 #include <string>
13 
14 namespace dev
15 {
16 
17 class RLP;
18 class RLPStream;
19 
20 namespace eth
21 {
22 
23 /// Current protocol version.
24 extern const unsigned c_protocolVersion;
25 
26 /// Current minor database version (for the extras database).
27 extern const unsigned c_databaseMinorVersion;
28 
29 /// Current database version.
30 extern const unsigned c_databaseVersion;
31 
32 /// Address of the special contract for block hash storage defined in EIP96
33 extern const Address c_blockhashContractAddress;
34 /// Code of the special contract for block hash storage defined in EIP96
35 extern const bytes c_blockhashContractCode;
36 
37 /// User-friendly string representation of the amount _b in wei.
38 std::string formatBalance(bigint const& _b);
39 
40 DEV_SIMPLE_EXCEPTION(InvalidAddress);
41 
42 /// Convert the given string into an address.
43 Address toAddress(std::string const& _s);
44 
45 /// Get information concerning the currency denominations.
46 std::vector<std::pair<u256, std::string>> const& units();
47 
48 /// The log bloom's size (2048-bit).
49 using LogBloom = h2048;
50 
51 /// Many log blooms.
52 using LogBlooms = std::vector<LogBloom>;
53 
54 // The various denominations; here for ease of use where needed within code.
55 static const u256 ether = exp10<18>();
56 static const u256 finney = exp10<15>();
57 static const u256 szabo = exp10<12>();
58 static const u256 shannon = exp10<9>();
59 static const u256 wei = exp10<0>();
60 
61 using Nonce = h64;
62 
63 using BlockNumber = unsigned;
64 
65 static const BlockNumber LatestBlock = (BlockNumber)-2;
66 static const BlockNumber PendingBlock = (BlockNumber)-1;
67 static const h256 LatestBlockHash = h256(2);
68 static const h256 EarliestBlockHash = h256(1);
69 static const h256 PendingBlockHash = h256(0);
70 
71 static const u256 DefaultBlockGasLimit = 4712388;
72 
73 enum class RelativeBlock: BlockNumber
74 {
75 	Latest = LatestBlock,
76 	Pending = PendingBlock
77 };
78 
79 enum class BlockPolarity
80 {
81 	Unknown,
82 	Dead,
83 	Live
84 };
85 
86 class Transaction;
87 
88 struct ImportRoute
89 {
90 	h256s deadBlocks;
91 	h256s liveBlocks;
92 	std::vector<Transaction> goodTransactions;
93 };
94 
95 enum class ImportResult
96 {
97 	Success = 0,
98 	UnknownParent,
99 	FutureTimeKnown,
100 	FutureTimeUnknown,
101 	AlreadyInChain,
102 	AlreadyKnown,
103 	Malformed,
104 	OverbidGasPrice,
105 	BadChain,
106 	ZeroSignature
107 };
108 
109 struct ImportRequirements
110 {
111 	using value = unsigned;
112 	enum
113 	{
114 		ValidSeal = 1, ///< Validate seal
115 		UncleBasic = 4, ///< Check the basic structure of the uncles.
116 		TransactionBasic = 8, ///< Check the basic structure of the transactions.
117 		UncleSeals = 16, ///< Check the basic structure of the uncles.
118 		TransactionSignatures = 32, ///< Check the basic structure of the transactions.
119 		Parent = 64, ///< Check parent block header.
120 		UncleParent = 128, ///< Check uncle parent block header.
121 		PostGenesis = 256, ///< Require block to be non-genesis.
122 		CheckUncles = UncleBasic | UncleSeals, ///< Check uncle seals.
123 		CheckTransactions = TransactionBasic | TransactionSignatures, ///< Check transaction signatures.
124 		OutOfOrderChecks = ValidSeal | CheckUncles | CheckTransactions, ///< Do all checks that can be done independently of prior blocks having been imported.
125 		InOrderChecks = Parent | UncleParent, ///< Do all checks that cannot be done independently of prior blocks having been imported.
126 		Everything = ValidSeal | CheckUncles | CheckTransactions | Parent | UncleParent,
127 		None = 0
128 	};
129 };
130 
131 /// Super-duper signal mechanism. TODO: replace with somthing a bit heavier weight.
132 template<typename... Args> class Signal
133 {
134 public:
135 	using Callback = std::function<void(Args...)>;
136 
137 	class HandlerAux
138 	{
139 		friend class Signal;
140 
141 	public:
~HandlerAux()142 		~HandlerAux() { if (m_s) m_s->m_fire.erase(m_i); }
reset()143 		void reset() { m_s = nullptr; }
fire(Args const &..._args)144 		void fire(Args const&... _args) { m_h(_args...); }
145 
146 	private:
HandlerAux(unsigned _i,Signal * _s,Callback const & _h)147 		HandlerAux(unsigned _i, Signal* _s, Callback const& _h): m_i(_i), m_s(_s), m_h(_h) {}
148 
149 		unsigned m_i = 0;
150 		Signal* m_s = nullptr;
151 		Callback m_h;
152 	};
153 
~Signal()154 	~Signal()
155 	{
156 		for (auto const& h : m_fire)
157 			if (auto l = h.second.lock())
158 				l->reset();
159 	}
160 
add(Callback const & _h)161 	std::shared_ptr<HandlerAux> add(Callback const& _h)
162 	{
163 		auto n = m_fire.empty() ? 0 : (m_fire.rbegin()->first + 1);
164 		auto h =  std::shared_ptr<HandlerAux>(new HandlerAux(n, this, _h));
165 		m_fire[n] = h;
166 		return h;
167 	}
168 
operator()169 	void operator()(Args const&... _args)
170 	{
171 		for (auto const& f: valuesOf(m_fire))
172 			if (auto h = f.lock())
173 				h->fire(_args...);
174 	}
175 
176 private:
177 	std::map<unsigned, std::weak_ptr<typename Signal::HandlerAux>> m_fire;
178 };
179 
180 template<class... Args> using Handler = std::shared_ptr<typename Signal<Args...>::HandlerAux>;
181 
182 struct TransactionSkeleton
183 {
184 	bool creation = false;
185 	Address from;
186 	Address to;
187 	u256 value;
188 	bytes data;
189 	u256 nonce = Invalid256;
190 	u256 gas = Invalid256;
191 	u256 gasPrice = Invalid256;
192 
193 	std::string userReadable(bool _toProxy, std::function<std::pair<bool, std::string>(TransactionSkeleton const&)> const& _getNatSpec, std::function<std::string(Address const&)> const& _formatAddress) const;
194 };
195 
196 
197 void badBlock(bytesConstRef _header, std::string const& _err);
badBlock(bytes const & _header,std::string const & _err)198 inline void badBlock(bytes const& _header, std::string const& _err) { badBlock(&_header, _err); }
199 
200 // TODO: move back into a mining subsystem and have it be accessible from Sealant only via a dynamic_cast.
201 /**
202  * @brief Describes the progress of a mining operation.
203  */
204 struct WorkingProgress
205 {
206 //	MiningProgress& operator+=(MiningProgress const& _mp) { hashes += _mp.hashes; ms = std::max(ms, _mp.ms); return *this; }
207 	uint64_t hashes = 0;		///< Total number of hashes computed.
208 	uint64_t ms = 0;			///< Total number of milliseconds of mining thus far.
rateWorkingProgress209 	u256 rate() const { return ms == 0 ? 0 : hashes * 1000 / ms; }
210 };
211 
212 /// Import transaction policy
213 enum class IfDropped
214 {
215 	Ignore, ///< Don't import transaction that was previously dropped.
216 	Retry 	///< Import transaction even if it was dropped before.
217 };
218 
219 /// Errors returned from main
220 enum AlethErrors
221 {
222     Success = 0,
223     UnrecognizedPeerset,
224     ArgumentProcessingFailure,
225     UnknownArgument,
226     UnknownMiningOption,
227     ConfigFileEmptyOrNotFound,
228     ConfigFileInvalid,
229     UnknownNetworkType,
230     BadNetworkIdOption,
231     BadConfigOption,
232     BadExtraDataOption,
233     BadAskOption,
234     BadBidOption,
235     BadFormatOption,
236     BadUpnpOption,
237     BadAddressOption,
238     BadHexValueInAddressOption,
239     BadBlockNumberHashOption,
240     KeyManagerInitializationFailure,
241     SnapshotImportFailure,
242     NetworkStartFailure,
243     BadRlp,
244     RlpDataNotAList,
245     UnsupportedJsonType,
246     InvalidJson
247 };
248 }
249 }
250