├── .gitignore
├── BlockSim.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── BlockSim
├── arithmetic_type
│ ├── License.md
│ ├── Readme.md
│ ├── arithmetic_istream.hpp
│ ├── arithmetic_ostream.hpp
│ ├── arithmetic_to_string.hpp
│ ├── arithmetic_type.hpp
│ ├── enable_if.hpp
│ ├── primitive_cast.hpp
│ ├── returns.hpp
│ └── traits.hpp
├── block.cpp
├── block.hpp
├── blockchain.cpp
├── blockchain.hpp
├── blockchain_settings.cpp
├── blockchain_settings.hpp
├── clever_selfish_miner.cpp
├── clever_selfish_miner.hpp
├── default_miner.cpp
├── default_miner.hpp
├── default_selfish_miner.cpp
├── default_selfish_miner.hpp
├── function_fork_miner.cpp
├── function_fork_miner.hpp
├── function_fork_selfish_miner.cpp
├── function_fork_selfish_miner.hpp
├── game.cpp
├── game.hpp
├── game_result.cpp
├── game_result.hpp
├── gap_miner.cpp
├── gap_miner.hpp
├── lazy_fork_miner.cpp
├── lazy_fork_miner.hpp
├── logging.h
├── miner.cpp
├── miner.hpp
├── minerGroup.cpp
├── minerGroup.hpp
├── minerParameters.h
├── minerStrategies.h
├── miner_result.cpp
├── miner_result.hpp
├── mining_style.cpp
├── mining_style.hpp
├── petty_miner.cpp
├── petty_miner.hpp
├── picky_mining_style.cpp
├── picky_mining_style.hpp
├── publishing_strategy.cpp
├── publishing_strategy.hpp
├── selfish_miner.cpp
├── selfish_miner.hpp
├── simple_mining_style.cpp
├── simple_mining_style.hpp
├── simple_publisher.cpp
├── simple_publisher.hpp
├── strategy.cpp
├── strategy.hpp
├── typeDefs.cpp
├── typeDefs.hpp
├── utils.cpp
├── utils.hpp
├── withholding_publisher.cpp
└── withholding_publisher.hpp
├── LICENSE.txt
├── Makefile
├── Readme.md
├── SelfishSim
└── main.cpp
└── StratSim
├── exp3_learning_model.cpp
├── exp3_learning_model.hpp
├── learning_model.cpp
├── learning_model.hpp
├── learning_strategy.cpp
├── learning_strategy.hpp
├── main.cpp
├── multiplicative_weights_learning_model.cpp
└── multiplicative_weights_learning_model.hpp
/.gitignore:
--------------------------------------------------------------------------------
1 | *.o
2 |
3 |
--------------------------------------------------------------------------------
/BlockSim.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/License.md:
--------------------------------------------------------------------------------
1 | Boost Software License - Version 1.0 - August 17th, 2003
2 |
3 | Permission is hereby granted, free of charge, to any person or organization
4 | obtaining a copy of the software and accompanying documentation covered by
5 | this license (the "Software") to use, reproduce, display, distribute,
6 | execute, and transmit the Software, and to prepare derivative works of the
7 | Software, and to permit third-parties to whom the Software is furnished to
8 | do so, all subject to the following:
9 |
10 | The copyright notices in the Software and this entire statement, including
11 | the above license grant, this restriction and the following disclaimer,
12 | must be included in all copies of the Software, in whole or in part, and
13 | all derivative works of the Software, unless such copies or derivative
14 | works are solely in the form of machine-executable object code generated by
15 | a source language processor.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 | DEALINGS IN THE SOFTWARE.
24 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/Readme.md:
--------------------------------------------------------------------------------
1 | ## Arithmetic types
2 |
3 | ### Provides
4 |
5 | `Arithmetic` where `T` models the `Arithmetic` concept is a `T` wrapper that:
6 | - disables _any_ implicit conversions between `T` and other types, and
7 | - can be made opaque by passing it a unique tag as second template parameter
8 | `Arithmetic`.
9 |
10 | ### Why is this useful?
11 |
12 | It let's you easily specify strongly typed interfaces when Arithmetic types are
13 | involved!
14 |
15 | ### Example 1: disabling implicit conversions
16 |
17 | ```c++
18 | int a{2};
19 | long b{3};
20 | b = a; // works: the implicit conversion is safe
21 |
22 | Arithmetic a{2};
23 | Arithmetic b{3};
24 | b = a; // fails: implicit assignment requires implicit conversion
25 | b = Arithmetic{a}; // works: explicit construction
26 | b = static_cast>(a); // works: explicit conversion
27 | ```
28 |
29 | ### Example 2: opaque type-defs
30 |
31 | ```c++
32 | struct Tag1 {};
33 | struct Tag2 {};
34 |
35 | using Type1 = Arithmetic;
36 | using Type2 = Arithmetic;
37 | Type1 a{2};
38 | Type2 b{3};
39 | a = b; // fails: Type1 != Type2 even tho both wrap an int
40 | b = Type2{a}; // works: explicit construction
41 | b = static_cast(a); // works: explicit conversion
42 | ```
43 |
44 | See the [tests](https://github.com/gnzlbg/arithmetic_type/blob/master/test/all_test.cpp)
45 | for more examples.
46 |
47 | ### Other facilities
48 | - `to_string` function is provided in
49 | `arithmetic_type/arithmetic_to_string.hpp`
50 | - i/o stream operators are provided in
51 | `arithmetic_type/arithmetic_istream.hpp` and
52 | `arithmetic_type/arithmetic_ostream.hpp`
53 | - when writing generic code one sometimes need to deal with both `Arithmetic`
54 | and `T`. The function `primitive_cast(T t)` does the right thing.
55 |
56 | ### Dependencies:
57 | - C++11/14 compiler (currently tested with clang 3.5 only)
58 |
59 | ### License
60 | - Boost Software License Version 1.0
61 |
62 | ### Comparison with BOOST_STRONG_TYPEDEF
63 |
64 | `Arithmetic` supports C++1y `constexpr`, move semantics, and disables
65 | implicit conversions.
66 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/arithmetic_istream.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_ISTREAM_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_ISTREAM_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include
5 | ////////////////////////////////////////////////////////////////////////////////
6 |
7 | namespace arithmetic {
8 |
9 | /// \brief istream operator
10 | template
11 | inline auto operator>>(std::basic_istream& i, Arithmetic& v)
12 | -> decltype(i >> v()) {
13 | return i >> v();
14 | }
15 |
16 | } // namespace arithmetic
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_ISTREAM_
20 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/arithmetic_ostream.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_OSTREAM_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_OSTREAM_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include
5 | ////////////////////////////////////////////////////////////////////////////////
6 |
7 | namespace arithmetic {
8 |
9 | /// \brief ostream operator
10 | template
11 | inline auto operator<<(std::basic_ostream& o, const Arithmetic& v)
12 | -> decltype(o << v()) {
13 | return o << v();
14 | }
15 |
16 | } // namespace arithmetic
17 |
18 | ////////////////////////////////////////////////////////////////////////////////
19 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_OSTREAM_
20 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/arithmetic_to_string.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TO_STRING_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TO_STRING_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include
5 | ////////////////////////////////////////////////////////////////////////////////
6 |
7 | namespace arithmetic {
8 |
9 | /// \brief to_string
10 | template
11 | inline std::string to_string(const Arithmetic a) {
12 | return std::to_string(a());
13 | }
14 |
15 | } // namespace arithmetic
16 |
17 | ////////////////////////////////////////////////////////////////////////////////
18 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TO_STRING_
19 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/arithmetic_type.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include
5 | #include
6 | #include "returns.hpp"
7 | #include "enable_if.hpp"
8 | ////////////////////////////////////////////////////////////////////////////////
9 | namespace arithmetic {
10 | ////////////////////////////////////////////////////////////////////////////////
11 |
12 | /// \name Index types
13 | ///@{
14 | /// \brief Implements an integer type
15 | template struct Arithmetic {
16 | using value_type = T;
17 | using type = T;
18 |
19 | /// \name Asignment operators
20 | ///@{
21 | constexpr Arithmetic() = default;
22 | constexpr Arithmetic(const Arithmetic& other) = default;
23 | constexpr Arithmetic(Arithmetic&& other) = default;
24 | constexpr Arithmetic& operator=(const Arithmetic& other) = default;
25 | constexpr Arithmetic& operator=(Arithmetic&& other) = default;
26 |
27 | constexpr explicit Arithmetic(const T& other) noexcept(
28 | std::is_nothrow_constructible::value)
29 | : value{other} {}
30 | template
31 | constexpr explicit Arithmetic(const Arithmetic& other) noexcept(
32 | std::is_nothrow_constructible::value)
33 | : value(other.value) {}
34 | constexpr Arithmetic& operator=(const T& other) noexcept {
35 | value = other;
36 | return *this;
37 | }
38 | ///@}
39 |
40 | /// \name Conversion operators
41 | ///@{
42 | explicit constexpr operator T() noexcept { return value; }
43 | explicit constexpr operator const T() const noexcept { return value; }
44 |
45 | template
46 | explicit constexpr operator Arithmetic() noexcept {
47 | return value;
48 | }
49 |
50 | template
51 | explicit constexpr operator const Arithmetic() const noexcept {
52 | return value;
53 | }
54 | ///@}
55 |
56 | /// \name Compound assignment +=, -=, *=, /=
57 | ///@{
58 | constexpr Arithmetic& operator+=(const Arithmetic& other) noexcept {
59 | value += other.value;
60 | return *this;
61 | }
62 | constexpr Arithmetic& operator-=(const Arithmetic& other) noexcept {
63 | value -= other.value;
64 | return *this;
65 | }
66 | constexpr Arithmetic& operator*=(const Arithmetic& other) noexcept {
67 | value *= other.value;
68 | return *this;
69 | }
70 | constexpr Arithmetic& operator/=(const Arithmetic& other) noexcept {
71 | value /= other.value;
72 | return *this;
73 | }
74 | ///@}
75 |
76 | /// \name Prefix increment operators ++(),--()
77 | ///@{
78 | constexpr Arithmetic& operator++() noexcept {
79 | ++value;
80 | return *this;
81 | }
82 | constexpr Arithmetic& operator--() noexcept {
83 | --value;
84 | return *this;
85 | }
86 | ///@}
87 |
88 | /// \name Postfix increment operators ()++,()--
89 | ///@{
90 | constexpr Arithmetic operator++(int) noexcept {
91 | Arithmetic tmp(*this);
92 | ++(*this);
93 | return tmp;
94 | }
95 | constexpr Arithmetic operator--(int) noexcept {
96 | Arithmetic tmp(*this);
97 | --(*this);
98 | return tmp;
99 | }
100 | ///@}
101 |
102 | /// \name Access operator
103 | ///@{
104 | constexpr T& operator()() & noexcept { return value; }
105 | constexpr T operator()() && noexcept { return value; }
106 | constexpr T operator()() const& noexcept { return value; }
107 | ///@}
108 |
109 | /// Data (wrapped value):
110 | T value;
111 | };
112 | ///@}
113 |
114 | /// \brief swap
115 | /// \relates Arithmetic
116 | template
117 | constexpr void swap(Arithmetic&& a, Arithmetic&& b) noexcept {
118 | using std::swap;
119 | swap(a.value, b.value);
120 | }
121 |
122 | /// \name Arithmetic operators +,-,*,/,unary -
123 | /// \relates Arithmetic
124 | ///@{
125 | template
126 | constexpr Arithmetic operator+(Arithmetic a,
127 | const Arithmetic& b) noexcept {
128 | return a += b;
129 | }
130 | template
131 | constexpr Arithmetic operator-(Arithmetic a,
132 | const Arithmetic& b) noexcept {
133 | return a -= b;
134 | }
135 | template
136 | constexpr Arithmetic operator*(Arithmetic a,
137 | const Arithmetic& b) noexcept {
138 | return a *= b;
139 | }
140 | template
141 | constexpr Arithmetic operator/(Arithmetic a,
142 | const Arithmetic& b) noexcept {
143 | return a /= b;
144 | }
145 |
146 | template
147 | constexpr Arithmetic operator-(Arithmetic const& other) noexcept {
148 | return Arithmetic{-other.value};
149 | }
150 | ///@}
151 |
152 | /// \name Comparison operators ==, !=, <, >, <=, >=
153 | /// \relates Arithmetic
154 | ///@{
155 | template
156 | constexpr bool operator==(const Arithmetic& a,
157 | const Arithmetic& b) noexcept {
158 | return a.value == b.value;
159 | }
160 | template
161 | constexpr bool operator<(const Arithmetic& a,
162 | const Arithmetic& b) noexcept {
163 | return a.value < b.value;
164 | }
165 | template
166 | constexpr bool operator<=(const Arithmetic& a,
167 | const Arithmetic& b) noexcept {
168 | return a < b || a == b;
169 | }
170 | template
171 | constexpr bool operator!=(const Arithmetic& a,
172 | const Arithmetic& b) noexcept {
173 | return !(a == b);
174 | }
175 | template
176 | constexpr bool operator>(const Arithmetic& a,
177 | const Arithmetic& b) noexcept {
178 | return !(a <= b);
179 | }
180 | template
181 | constexpr bool operator>=(const Arithmetic& a,
182 | const Arithmetic& b) noexcept {
183 | return !(a < b);
184 | }
185 | ///@}
186 |
187 | /// \name Pointer arithmetic
188 | ///@{
189 |
190 | template> = detail_::dummy>
192 | constexpr auto operator+(T a, const Arithmetic& i)
193 | RETURNS(a + i());
194 |
195 | template> = detail_::dummy>
197 | constexpr auto operator+(T a, const Arithmetic& i)
198 | RETURNS(a + i());
199 |
200 | template> = detail_::dummy>
202 | constexpr auto operator-(T a, const Arithmetic& i)
203 | RETURNS(a - i());
204 |
205 | template> = detail_::dummy>
207 | constexpr auto operator-(T a, const Arithmetic& i)
208 | RETURNS(a - i());
209 |
210 | ///@}
211 |
212 | ////////////////////////////////////////////////////////////////////////////////
213 | } // namespace arithmetic
214 | ////////////////////////////////////////////////////////////////////////////////
215 |
216 | /// \name Arithmetic types are numeric types
217 | /// \relates Arithmetic
218 | ///@{
219 | namespace std {
220 |
221 | template
222 | class numeric_limits> : public numeric_limits {
223 | public:
224 | static constexpr bool is_specialized = true;
225 | };
226 |
227 | } // namespace std
228 | ///@}
229 |
230 | ////////////////////////////////////////////////////////////////////////////////
231 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_ARITHMETIC_TYPE_
232 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/enable_if.hpp:
--------------------------------------------------------------------------------
1 | // (C) Copyright Martinho Fernandes (see below)
2 | // Use, modification and distribution are subject to the Boost Software License,
3 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4 | // http://www.boost.org/LICENSE_1_0.txt).
5 |
6 | /// \brief EnableIf / DisableIf as proposed by Martinho Fernandes in
7 | /// http://flamingdangerzone.com/cxx11/2012/06/01/almost-static-if.html
8 |
9 | #if !defined(ARITHMETIC_TYPE_DETAIL_ENABLE_IF_HPP_)
10 | #define ARITHMETIC_TYPE_DETAIL_ENABLE_IF_HPP_
11 |
12 | #include
13 |
14 | namespace detail_ {
15 | enum class enabler {};
16 | constexpr enabler dummy = {};
17 |
18 | template
19 | using EnableIf = std::enable_if_t;
20 |
21 | template
22 | using DisableIf = std::enable_if_t;
23 |
24 | } // namespace detail_
25 |
26 | #endif // ARITHMETIC_TYPE_ENABLE_IF_HPP_
27 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/primitive_cast.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_PRIMITIVE_CAST_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_PRIMITIVE_CAST_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include "traits.hpp"
5 | #include "enable_if.hpp"
6 | ////////////////////////////////////////////////////////////////////////////////
7 |
8 | namespace arithmetic {
9 |
10 | template > = detail_::dummy>
11 | constexpr inline auto&& primitive_cast(T&& t) {
12 | static_assert(is_arithmetic::value, "T must be an integer!");
13 | return t();
14 | }
15 |
16 | template > = detail_::dummy>
17 | constexpr inline auto primitive_cast(const T& t) -> decltype(t()) {
18 | static_assert(is_arithmetic::value, "T must be an integer!");
19 | return t();
20 | }
21 |
22 | template > = detail_::dummy>
23 | constexpr inline auto& primitive_cast(T& t) {
24 | static_assert(is_arithmetic::value, "T must be an integer!");
25 | return t();
26 | }
27 |
28 | template > = detail_::dummy>
29 | constexpr inline auto&& primitive_cast(T&& t) {
30 | static_assert(!is_arithmetic::value, "T can't be an integer!");
31 | return std::forward(t);
32 | }
33 |
34 | template > = detail_::dummy>
35 | constexpr inline auto primitive_cast(const T& t) -> decltype(t) {
36 | static_assert(!is_arithmetic::value, "T can't be an integer!");
37 | return t;
38 | }
39 |
40 | template > = detail_::dummy>
41 | constexpr inline auto& primitive_cast(T& t) {
42 | static_assert(!is_arithmetic::value, "T can't be an integer!");
43 | return t;
44 | }
45 |
46 | } // namespace arithmetic
47 |
48 | ////////////////////////////////////////////////////////////////////////////////
49 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_PRIMITIVE_CAST_
50 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/returns.hpp:
--------------------------------------------------------------------------------
1 | // (C) Copyright Dave Abrahams and Eric Niebler (see below)
2 | // Use, modification and distribution are subject to the Boost Software License,
3 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
4 | // http://www.boost.org/LICENSE_1_0.txt).
5 |
6 | /// \brief Returns macro
7 |
8 | #if !defined(ARITHMETIC_TYPE_DETAIL_RETURNS_HPP_)
9 | #define ARITHMETIC_TYPE_DETAIL_RETURNS_HPP_
10 |
11 | #include
12 |
13 | /// \brief RETURNS() is used to avoid writing boilerplate
14 | /// "->decltype(x) { return x; }" phrases.
15 | //
16 | /// USAGE: auto function() RETURNS();
17 | ///
18 | /// Note: we end with a unique typedef so the function can be followed
19 | /// by a semicolon. If we omit the semicolon, editors get confused and
20 | /// think we haven't completed the function declaration.
21 | ///
22 | /// Author: Dave Abrahams, see
23 | /// https://groups.google.com/forum/#!msg/boost-devel-archive/OzJ5Ft3pSnU\
24 | /// /b_Ter9bgNqAJ .
25 | ///
26 | /// \todo Eric Niebler discusses how to improve errors messages when combining
27 | /// the RETURNS macro with SFINAE for expressions here:
28 | /// https://groups.google.com/forum/#!topic/boost-developers-archive\
29 | /// /Ipn1bF24STc%5B1-25-false%5D .
30 | ///
31 | #define RETURNS(...) \
32 | noexcept(noexcept(decltype(__VA_ARGS__)(std::move(__VA_ARGS__)))) \
33 | ->decltype(__VA_ARGS__) { \
34 | return (__VA_ARGS__); \
35 | } \
36 | using RETURNS_CAT(RETURNS_, __LINE__) = int
37 | // Standard PP concatenation formula
38 | #define RETURNS_CAT_0(x, y) x##y
39 | #define RETURNS_CAT(x, y) RETURNS_CAT_0(x, y)
40 |
41 | #endif // ARITHMETIC_TYPE_RETURNS_HPP_
42 |
--------------------------------------------------------------------------------
/BlockSim/arithmetic_type/traits.hpp:
--------------------------------------------------------------------------------
1 | #ifndef ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_TRAITS_
2 | #define ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_TRAITS_
3 | ////////////////////////////////////////////////////////////////////////////////
4 | #include "arithmetic_type.hpp"
5 | ////////////////////////////////////////////////////////////////////////////////
6 |
7 | namespace arithmetic {
8 |
9 | template struct is_arithmetic_ {
10 | static const bool value = false;
11 | };
12 | template struct is_arithmetic_> {
13 | static const bool value = true;
14 | };
15 |
16 | template struct is_arithmetic {
17 | static const bool value
18 | = is_arithmetic_>>::value;
19 | };
20 |
21 | } // namespace arithmetic
22 |
23 | ////////////////////////////////////////////////////////////////////////////////
24 | #endif // ARITHMETIC_UTILITIES_ARITHMETIC_TYPE_TRAITS_
25 |
--------------------------------------------------------------------------------
/BlockSim/block.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // block.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "block.hpp"
10 | #include "miner.hpp"
11 |
12 | #include
13 | #include
14 | #include
15 |
16 | constexpr auto timeMax = std::numeric_limits::max();
17 |
18 | Block::Block(BlockValue blockReward_) : Block(nullptr, nullptr, BlockTime(0), Value(0), BlockHeight(0), Value(0), Value(0), Value(rawValue(blockReward_))) {}
19 |
20 | Block::Block(const Block *parent_, const Miner *miner_, BlockTime timeSeconds_, Value txFees, BlockHeight height_, Value txFeesInChain_, Value valueInChain_, Value blockReward_) : timeBroadcast(timeMax), parent(parent_), miner(miner_), height(height_), timeMined(timeSeconds_), value(txFees + blockReward_), txFeesInChain(txFeesInChain_), valueInChain(valueInChain_), blockReward(blockReward_) {}
21 |
22 | Block::Block(const Block *parent_, const Miner *miner_, BlockTime timeSeconds_, Value txFees) :
23 | Block(parent_, miner_, timeSeconds_, txFees, parent_->height + BlockHeight(1), parent_->txFeesInChain + txFees, parent_->valueInChain + parent_->blockReward + txFees, parent_->nextBlockReward()) {}
24 |
25 | void Block::reset(const Block *parent_, const Miner *miner_, BlockTime timeSeconds_, Value txFees) {
26 | height = parent_->height + BlockHeight(1);
27 | timeMined = timeSeconds_;
28 | timeBroadcast = timeMax;
29 | value = txFees + parent_->nextBlockReward();
30 | txFeesInChain = txFees + parent_->txFeesInChain;
31 | valueInChain = txFees + parent_->valueInChain + parent_->nextBlockReward();
32 | blockReward = parent_->nextBlockReward();
33 | parent = parent_;
34 | miner = miner_;
35 | }
36 |
37 | Value Block::nextBlockReward() const {
38 | return blockReward;
39 | }
40 |
41 | void Block::broadcast(BlockTime timePub) {
42 | timeBroadcast = timePub;
43 | }
44 |
45 | bool Block::isBroadcast() const {
46 | return timeBroadcast < timeMax;
47 | }
48 |
49 | BlockTime Block::getTimeBroadcast() const {
50 | return timeBroadcast;
51 | }
52 |
53 | std::ostream& operator<< (std::ostream& out, const Block& mc) {
54 | mc.print(out, true);
55 | return out;
56 | }
57 |
58 | std::vector Block::getChain() const {
59 | std::vector chain;
60 | const Block *current = this;
61 | while (current) {
62 | chain.push_back(current);
63 | current = current->parent;
64 | }
65 | return chain;
66 | }
67 |
68 | void Block::print(std::ostream& os, bool isPublished) const {
69 | if (height == BlockHeight(0)) {
70 | os << "[h:0, m:gen]";
71 | return;
72 | }
73 | if (isPublished) {
74 | os << "{";
75 | }
76 | else {
77 | os << "[";
78 | }
79 |
80 | os << "h:" << height << ", m:" << miner->params.name << ", v:" << value << ", t:" << timeMined;
81 |
82 | if (isPublished) {
83 | os << "}->";
84 | }
85 | else {
86 | os << "]->";
87 | }
88 | }
89 |
90 | bool Block::minedBy(const Miner *miner_) const {
91 | return miner == miner_;
92 | }
93 |
--------------------------------------------------------------------------------
/BlockSim/block.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // block.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef block_hpp
10 | #define block_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | #include
15 | #include
16 |
17 | class Miner;
18 |
19 | class Block {
20 | protected:
21 | BlockTime timeBroadcast;
22 | public:
23 | const Block *parent;
24 | const Miner *miner;
25 | BlockHeight height;
26 | BlockTime timeMined;
27 | Value value;
28 | Value txFeesInChain;
29 | Value valueInChain;
30 | Value blockReward;
31 |
32 | Block(const Block *parent_, const Miner *miner_, BlockTime timeSeconds, Value txFees, BlockHeight height, Value txFeesInChain, Value valueInChain, Value blockReward);
33 |
34 | Block(BlockValue blockReward);
35 | Block(const Block *parent_, const Miner *miner_, BlockTime timeSeconds_, Value txFees);
36 |
37 | void reset(const Block *parent, const Miner *miner, BlockTime timeSeconds, Value txFees);
38 |
39 | void broadcast(BlockTime timePub);
40 | BlockTime getTimeBroadcast() const;
41 | bool isBroadcast() const;
42 |
43 | Value nextBlockReward() const;
44 |
45 | bool minedBy(const Miner *miner) const;
46 | void print(std::ostream& where, bool isPublished) const;
47 | std::vector getChain() const;
48 |
49 | };
50 |
51 | std::ostream& operator<< (std::ostream& out, const Block& mc);
52 |
53 | #endif /* block_hpp */
54 |
--------------------------------------------------------------------------------
/BlockSim/blockchain.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // blockchain.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "blockchain.hpp"
10 | #include "utils.hpp"
11 | #include "block.hpp"
12 | #include "blockchain_settings.hpp"
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | Blockchain::Blockchain(BlockchainSettings blockchainSettings) :
21 | valueNetworkTotal(0),
22 | timeInSecs(0),
23 | secondsPerBlock(blockchainSettings.secondsPerBlock),
24 | transactionFeeRate(blockchainSettings.transactionFeeRate),
25 | _maxHeightPub(0)
26 | {
27 | _blocks.reserve(rawCount(blockchainSettings.numberOfBlocks) * 2);
28 | _blocksIndex.resize(rawCount(blockchainSettings.numberOfBlocks) * 2);
29 | _smallestBlocks.resize(rawCount(blockchainSettings.numberOfBlocks) * 2);
30 | reset(blockchainSettings);
31 | }
32 |
33 | std::unique_ptr Blockchain::createBlock(const Block *parent, const Miner *miner, Value value) {
34 | Value txFees = value - parent->nextBlockReward();
35 | if (_oldBlocks.size() == 0) {
36 | return std::make_unique(parent, miner, getTime(), txFees);
37 | }
38 |
39 | auto block = std::move(_oldBlocks.back());
40 | _oldBlocks.pop_back();
41 | block->reset(parent, miner, getTime(), txFees);
42 | return block;
43 | }
44 |
45 | void Blockchain::reset(BlockchainSettings blockchainSettings) {
46 | valueNetworkTotal = 0;
47 | timeInSecs = BlockTime(0);
48 | secondsPerBlock = blockchainSettings.secondsPerBlock;
49 | transactionFeeRate = blockchainSettings.transactionFeeRate;
50 | _maxHeightPub = BlockHeight(0);
51 | _oldBlocks.reserve(_oldBlocks.size() + _blocks.size());
52 | for (auto &block : _blocks) {
53 | _oldBlocks.push_back(std::move(block));
54 | }
55 | _blocks.clear();
56 | _smallestBlocks[0].clear();
57 | _blocksIndex[0].clear();
58 | auto genesis = std::make_unique(blockchainSettings.blockReward);
59 | _smallestBlocks[0].push_back(genesis.get());
60 | _blocksIndex[0].push_back(_blocks.size());
61 | _blocks.push_back(std::move(genesis));
62 | }
63 |
64 | void Blockchain::publishBlock(std::unique_ptr block) {
65 | assert(block);
66 | assert(block->height <= _maxHeightPub + BlockHeight(1));
67 |
68 | HeightType height = rawHeight(block->height);
69 |
70 | if (block->height > _maxHeightPub) {
71 | _blocksIndex[height].clear();
72 | _smallestBlocks[height].clear();
73 | _smallestBlocks[height].push_back(block.get());
74 | _maxHeightPub = block->height;
75 | } else {
76 | std::vector &smallestVector = _smallestBlocks[height];
77 |
78 | if (block->value < smallestVector.front()->value) {
79 | smallestVector.clear();
80 | smallestVector.push_back(block.get());
81 | } else if (block->value == smallestVector.front()->value) {
82 | smallestVector.push_back(block.get());
83 | }
84 | }
85 |
86 | _blocksIndex[height].push_back(_blocks.size());
87 | _blocks.push_back(std::move(block));
88 | }
89 |
90 | BlockCount Blockchain::blocksOfHeight(BlockHeight height) const {
91 | return BlockCount(_blocksIndex[rawHeight(height)].size());
92 | }
93 |
94 | const std::vector Blockchain::oldestBlocks(BlockHeight height) const {
95 | BlockTime minTimePublished(std::numeric_limits::max());
96 | for (size_t index : _blocksIndex[rawHeight(height)]) {
97 | minTimePublished = std::min(_blocks[index]->getTimeBroadcast(), minTimePublished);
98 | }
99 |
100 | std::vector possiblities;
101 | for (size_t index : _blocksIndex[rawHeight(height)]) {
102 | if (_blocks[index]->getTimeBroadcast() == minTimePublished) {
103 | possiblities.push_back(_blocks[index].get());
104 | }
105 | }
106 | assert(possiblities.size() > 0);
107 | return possiblities;
108 | }
109 |
110 | Block &Blockchain::oldest(BlockHeight height) const {
111 | auto possiblities = oldestBlocks(height);
112 | return *possiblities[selectRandomIndex(possiblities.size())];
113 | }
114 |
115 | Block &Blockchain::most(BlockHeight height) const {
116 | auto &smallestBlocks = _smallestBlocks[rawHeight(height)];
117 | size_t index = selectRandomIndex(smallestBlocks.size());
118 | Block *block = smallestBlocks[index];
119 | return *block;
120 | }
121 |
122 | const Block &Blockchain::winningHead() const {
123 | Value largestValue(0);
124 | for (size_t index : _blocksIndex[rawHeight(getMaxHeightPub())]) {
125 | largestValue = std::max(largestValue, _blocks[index]->valueInChain);
126 | }
127 |
128 | std::vector possiblities;
129 | for (size_t index : _blocksIndex[rawHeight(getMaxHeightPub())]) {
130 | if (_blocks[index]->valueInChain == largestValue) {
131 | possiblities.push_back(_blocks[index].get());
132 | }
133 | }
134 | std::uniform_int_distribution vectorDis(0, possiblities.size() - 1);
135 | return *possiblities[selectRandomIndex(possiblities.size())];
136 | }
137 |
138 | void Blockchain::advanceToTime(BlockTime time) {
139 | assert(time >= timeInSecs);
140 | valueNetworkTotal += transactionFeeRate * (time - timeInSecs);
141 | timeInSecs = time;
142 | }
143 |
144 | BlockValue Blockchain::expectedBlockSize() const {
145 | return transactionFeeRate * secondsPerBlock + BlockValue(_smallestBlocks[rawHeight(getMaxHeightPub())].front()->nextBlockReward());
146 | }
147 |
148 | TimeRate Blockchain::chanceToWin(HashRate hashRate) const {
149 | return hashRate / secondsPerBlock;
150 | }
151 |
152 | Block *Blockchain::blockByMinerAtHeight(BlockHeight height, const Miner &miner) const {
153 | for (size_t index : _blocksIndex[rawHeight(height)]) {
154 | if (_blocks[index]->minedBy(&miner)) {
155 | return _blocks[index].get();
156 | }
157 | }
158 | return nullptr;
159 | }
160 |
161 | Block &Blockchain::most(BlockHeight height, const Miner &miner) const {
162 | Block *block = blockByMinerAtHeight(height, miner);
163 | if (block) {
164 | return *block;
165 | }
166 |
167 | return most(height);
168 | }
169 |
170 | Block &Blockchain::oldest(BlockHeight height, const Miner &miner) const {
171 | Block *block = blockByMinerAtHeight(height, miner);
172 | if (block) {
173 | return *block;
174 | }
175 |
176 | return oldest(height);
177 | }
178 |
179 | Value Blockchain::gap(BlockHeight height) const {
180 | return rem(most(height - BlockHeight(1))) - rem(most(height));
181 | }
182 |
183 | Value Blockchain::rem(const Block &block) const {
184 | return valueNetworkTotal - block.txFeesInChain;
185 | }
186 |
187 | const std::vector Blockchain::getHeads() const {
188 | std::unordered_set nonHeadBlocks;
189 | std::unordered_set possibleHeadBlocks;
190 | for (auto &block : _blocks) {
191 | if (block->parent != nullptr) {
192 | nonHeadBlocks.insert(block->parent);
193 | possibleHeadBlocks.erase(block->parent);
194 | }
195 | if (nonHeadBlocks.find(block.get()) == end(nonHeadBlocks)) {
196 | possibleHeadBlocks.insert(block.get());
197 | }
198 | }
199 | return std::vector(std::begin(possibleHeadBlocks), std::end(possibleHeadBlocks));
200 | }
201 |
202 | void Blockchain::printBlockchain() const {
203 | std::unordered_set printedBlocks;
204 | for (auto ¤t : getHeads()) {
205 | auto chain = current->getChain();
206 | for (auto block : chain) {
207 | if (printedBlocks.find(block) == end(printedBlocks)) {
208 | std::cout << *block;
209 | printedBlocks.insert(block);
210 | } else {
211 | break;
212 | }
213 | }
214 | std::cout << std::endl;
215 | }
216 | }
217 |
218 | void Blockchain::printHeads() const {
219 | std::cout << "heads:" << std::endl;
220 | for (auto current : getHeads()) {
221 | std::cout << *current << std::endl;
222 | }
223 | std::cout << "end heads." << std::endl;
224 | }
225 |
226 |
227 |
--------------------------------------------------------------------------------
/BlockSim/blockchain.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // blockchain.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef blockchain_hpp
10 | #define blockchain_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | #include
15 | #include
16 | #include
17 |
18 | class Block;
19 | class GenesisBlock;
20 | class Miner;
21 | struct BlockchainSettings;
22 |
23 | class Blockchain {
24 | Value valueNetworkTotal;
25 | BlockTime timeInSecs;
26 | BlockRate secondsPerBlock;
27 | ValueRate transactionFeeRate;
28 |
29 |
30 | BlockHeight _maxHeightPub;
31 | std::vector> _blocksIndex;
32 | std::vector> _smallestBlocks; // cache smallest blocks of a given height
33 | std::vector> _blocks;
34 |
35 | std::vector> _oldBlocks;
36 |
37 | Block *blockByMinerAtHeight(BlockHeight height, const Miner &miner) const;
38 |
39 | public:
40 | Blockchain(BlockchainSettings blockchainSettings);
41 |
42 | std::unique_ptr createBlock(const Block *parent, const Miner *miner, Value value);
43 | void reset(BlockchainSettings blockchainSettings);
44 |
45 | void publishBlock(std::unique_ptr block);
46 |
47 | const std::vector getHeads() const;
48 | void printBlockchain() const;
49 | void printHeads() const;
50 |
51 | const Block &winningHead() const;
52 |
53 | BlockCount blocksOfHeight(BlockHeight height) const;
54 |
55 | const std::vector oldestBlocks(BlockHeight height) const;
56 | Block &oldest(BlockHeight height) const;
57 | Block &most(BlockHeight age) const;
58 |
59 | void advanceToTime(BlockTime time);
60 |
61 | inline BlockHeight getMaxHeightPub() const {
62 | return _maxHeightPub;
63 | }
64 |
65 | inline BlockTime getTime() const {
66 | return timeInSecs;
67 | }
68 |
69 | inline Value getTotalFees() const {
70 | return valueNetworkTotal;
71 | }
72 |
73 | BlockValue expectedBlockSize() const;
74 | TimeRate chanceToWin(HashRate hashRate) const;
75 |
76 | Value gap(BlockHeight i) const;
77 | Value rem(const Block &block) const;
78 |
79 | Block &most(BlockHeight age, const Miner &miner) const;
80 | Block &oldest(BlockHeight age, const Miner &miner) const;
81 | };
82 |
83 | #endif /* blockchain_hpp */
84 |
--------------------------------------------------------------------------------
/BlockSim/blockchain_settings.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // blockchain_settings.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 10/26/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "blockchain_settings.hpp"
10 |
--------------------------------------------------------------------------------
/BlockSim/blockchain_settings.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // blockchain_settings.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 10/26/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef blockchain_settings_hpp
10 | #define blockchain_settings_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | struct BlockchainSettings {
15 | BlockRate secondsPerBlock;
16 | ValueRate transactionFeeRate;
17 | BlockValue blockReward;
18 | BlockCount numberOfBlocks;
19 | };
20 |
21 | #endif /* blockchain_settings_hpp */
22 |
--------------------------------------------------------------------------------
/BlockSim/clever_selfish_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // clevel_selfish_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "clever_selfish_miner.hpp"
10 |
11 | #include "block.hpp"
12 | #include "blockchain.hpp"
13 | #include "logging.h"
14 | #include "minerParameters.h"
15 | #include "miner.hpp"
16 | #include "default_miner.hpp"
17 | #include "strategy.hpp"
18 |
19 | #include
20 | #include
21 |
22 | using std::placeholders::_1;
23 | using std::placeholders::_2;
24 |
25 | std::unique_ptr createCleverSelfishStrategy(bool noiseInTransactions, Value cutoff) {
26 | auto valueFunc = std::bind(defaultValueInMinedChild, _1, _2, noiseInTransactions);
27 |
28 | return std::make_unique("clever-selfish", selfishBlockToMineOn, valueFunc, std::make_unique(cutoff));
29 | }
30 |
31 | CleverSelfishPublishingStyle::CleverSelfishPublishingStyle(Value cutoff_) : SelfishPublishingStyle(), cutoff(cutoff_) {}
32 |
33 | BlockHeight CleverSelfishPublishingStyle::heightToPublish(const Blockchain &blockchain, const Miner &me, std::vector> &unpublishedBlocks) const {
34 | assert(unpublishedBlocks.back());
35 | if(unpublishedBlocks.back()->height == blockchain.getMaxHeightPub() + BlockHeight(1) &&
36 | unpublishedBlocks.back()->value >= cutoff &&
37 | unpublishedBlocks.size() == 1) {
38 | //finding a block. Normally hide (point of selfish mining) Might decide to normal mine if big block
39 | //(not worth the risk of using it to selfish mine)
40 | COMMENTARY("Miner " << me.params.name << " publishes selfish chain. Too large a block to selfishly mine." << std::endl);
41 | return unpublishedBlocks.back()->height;
42 | } else {
43 | return SelfishPublishingStyle::heightToPublish(blockchain, me, unpublishedBlocks);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/BlockSim/clever_selfish_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // clevel_selfish_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef clevel_selfish_miner_hpp
10 | #define clevel_selfish_miner_hpp
11 |
12 | #include "selfish_miner.hpp"
13 |
14 | class CleverSelfishPublishingStyle : public SelfishPublishingStyle {
15 | private:
16 | const Value cutoff;
17 | BlockHeight heightToPublish(const Blockchain &blockchain, const Miner &me, std::vector> &unpublishedBlocks) const override;
18 | public:
19 | CleverSelfishPublishingStyle(Value cutoff);
20 | };
21 |
22 | std::unique_ptr createCleverSelfishStrategy(bool noiseInTransactions, Value cutoff);
23 |
24 | #endif /* clevel_selfish_miner_hpp */
25 |
--------------------------------------------------------------------------------
/BlockSim/default_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // default_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "default_miner.hpp"
10 | #include "block.hpp"
11 | #include "blockchain.hpp"
12 | #include "utils.hpp"
13 | #include "miner.hpp"
14 | #include "publishing_strategy.hpp"
15 | #include "strategy.hpp"
16 |
17 | #include
18 | #include
19 |
20 | using std::placeholders::_1;
21 | using std::placeholders::_2;
22 |
23 | std::unique_ptr createDefaultStrategy(bool atomic, bool noiseInTransactions) {
24 | ParentSelectorFunc mineFunc;
25 |
26 | if (atomic) {
27 | mineFunc = defaultBlockToMineOnAtomic;
28 | } else {
29 | mineFunc = defaultBlockToMineOnNonAtomic;
30 | }
31 |
32 | auto valueFunc = std::bind(defaultValueInMinedChild, _1, _2, noiseInTransactions);
33 |
34 | return std::make_unique("default-honest", mineFunc, valueFunc);
35 | }
36 |
37 | Block &defaultBlockToMineOnAtomic(const Miner &me, const Blockchain &chain) {
38 | return chain.oldest(chain.getMaxHeightPub(), me);
39 | }
40 |
41 | Block &defaultBlockToMineOnNonAtomic(const Miner &, const Blockchain &chain) {
42 | return chain.oldest(chain.getMaxHeightPub());
43 | }
44 |
45 | Value defaultValueInMinedChild(const Blockchain &chain, const Block &mineHere, bool noiseInTransactions) {
46 | auto minVal = mineHere.nextBlockReward();
47 | auto maxVal = chain.rem(mineHere) + mineHere.nextBlockReward();
48 | //this represents some noise-- no noise, value would = valueMax
49 | //value = ((valueMax - valueMin)*((dis(gen)+.7)/1.7)) + valueMin;
50 | auto value = maxVal;
51 | if (noiseInTransactions) {
52 | value = valWithNoise(minVal, maxVal);
53 | }
54 | return value;
55 | }
56 |
--------------------------------------------------------------------------------
/BlockSim/default_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // default_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef default_miner_hpp
10 | #define default_miner_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | #include
15 |
16 | class Miner;
17 | class Block;
18 | class Blockchain;
19 | class Strategy;
20 |
21 | std::unique_ptr createDefaultStrategy(bool atomic, bool noiseInTransactions);
22 |
23 | Value defaultValueInMinedChild(const Blockchain &blockchain, const Block &mineHere, bool noiseInTransactions);
24 |
25 | Block &defaultBlockToMineOnAtomic(const Miner &me, const Blockchain &chain);
26 | Block &defaultBlockToMineOnNonAtomic(const Miner &me, const Blockchain &chain);
27 |
28 | #endif /* default_miner_hpp */
29 |
--------------------------------------------------------------------------------
/BlockSim/default_selfish_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // default_selfish_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "default_selfish_miner.hpp"
10 | #include "block.hpp"
11 | #include "blockchain.hpp"
12 | #include "miner.hpp"
13 | #include "selfish_miner.hpp"
14 | #include "default_miner.hpp"
15 | #include "logging.h"
16 | #include "utils.hpp"
17 | #include "strategy.hpp"
18 |
19 | #include
20 | #include
21 |
22 |
23 | using std::placeholders::_1;
24 | using std::placeholders::_2;
25 |
26 | Block &blockToMineOn(const Miner &me, const Blockchain &blockchain, double gamma);
27 |
28 | std::unique_ptr createDefaultSelfishStrategy(bool noiseInTransactions, double gamma) {
29 | auto mineFunc = std::bind(blockToMineOn, _1, _2, gamma);
30 | auto valueFunc = std::bind(defaultValueInMinedChild, _1, _2, noiseInTransactions);
31 |
32 | return std::make_unique("default-selfish", mineFunc, valueFunc);
33 | }
34 |
35 | Block &blockToMineOn(const Miner &me, const Blockchain &chain, double gamma) {
36 |
37 | std::vector possiblities = chain.oldestBlocks(chain.getMaxHeightPub());
38 | if (possiblities.size() == 1) { //no forking
39 | return *possiblities[0];
40 | }
41 | else if (possiblities.size() == 2) { //fork between the selfish miner and the rest of the network
42 | //mineHere should already be set to the side of the fork not the selfish miner
43 | Block *selfishBlock = nullptr;
44 | Block *defaultBlock = nullptr;
45 | if (ownBlock(&me, possiblities[0])) {
46 | defaultBlock = possiblities[0];
47 | selfishBlock = possiblities[1];
48 | } else {
49 | defaultBlock = possiblities[1];
50 | selfishBlock = possiblities[0];
51 | }
52 |
53 | assert(ownBlock(&me, defaultBlock));
54 |
55 | //with chance gamma, mine on the selfish miner's block, otherwise not
56 | if (selectRandomChance() < gamma) {
57 | return *selfishBlock;
58 |
59 | } else {
60 | COMMENTARY("Having to mine on selfish block due to gamma. ");
61 | return *defaultBlock;
62 | }
63 | } else { //lolwut
64 | ERROR("\n#####ERROR UNFORSEEN CIRCUMSTANCES IN LOGIC FOR SELFISH MINING SIM###\n\n" << std::endl);
65 | return *possiblities[0];
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/BlockSim/default_selfish_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // default_selfish_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef default_selfish_miner_hpp
10 | #define default_selfish_miner_hpp
11 |
12 | #include
13 |
14 | class Strategy;
15 |
16 | std::unique_ptr createDefaultSelfishStrategy(bool noiseInTransactions, double gamma);
17 |
18 | #endif /* default_selfish_miner_hpp */
19 |
--------------------------------------------------------------------------------
/BlockSim/function_fork_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // function_fork_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "function_fork_miner.hpp"
10 | #include "block.hpp"
11 | #include "blockchain.hpp"
12 | #include "miner.hpp"
13 | #include "publishing_strategy.hpp"
14 | #include "strategy.hpp"
15 |
16 | #include
17 |
18 | #include
19 | #include
20 |
21 | #include
22 |
23 | using std::placeholders::_1;
24 | using std::placeholders::_2;
25 |
26 | Block &blockToMineOnNonAtomic(const Miner &, const Blockchain &chain, ForkFunc f);
27 | Block &blockToMineOnAtomic(const Miner &me, const Blockchain &chain, ForkFunc f);
28 |
29 | Value valCont(const Blockchain &chain, ForkFunc f, const Block &block);
30 | Value valUnder(const Blockchain &chain, ForkFunc f, const Block &block);
31 |
32 | std::unique_ptr createFunctionForkStrategy(bool atomic, ForkFunc f, std::string type) {
33 | ParentSelectorFunc mineFunc;
34 |
35 | if (atomic) {
36 | mineFunc = std::bind(blockToMineOnAtomic, _1, _2, f);
37 | } else {
38 | mineFunc = std::bind(blockToMineOnNonAtomic, _1, _2, f);
39 | }
40 | auto valueFunc = std::bind(functionForkValueInMinedChild, _1, _2, f);
41 |
42 | return std::make_unique("function-fork-" + type, mineFunc, valueFunc);
43 | }
44 |
45 | Block &blockToMineOnNonAtomic(const Miner &, const Blockchain &chain, ForkFunc f) {
46 | Block &contBlock = chain.most(chain.getMaxHeightPub());
47 | if (chain.getMaxHeightPub() == BlockHeight(0)) {
48 | return contBlock;
49 | }
50 | Block &underBlock = chain.most(chain.getMaxHeightPub() - BlockHeight(1));
51 |
52 | if (valCont(chain, f, contBlock) >= valUnder(chain, f, underBlock)) {
53 | return contBlock;
54 | } else {
55 | return underBlock;
56 | }
57 | }
58 |
59 | Block &blockToMineOnAtomic(const Miner &me, const Blockchain &chain, ForkFunc f) {
60 | Block &contBlock = chain.most(chain.getMaxHeightPub(), me);
61 | if (chain.getMaxHeightPub() == BlockHeight(0)) {
62 | return contBlock;
63 | }
64 |
65 | Block &underBlock = chain.most(chain.getMaxHeightPub() - BlockHeight(1), me);
66 | if (contBlock.minedBy(&me) || valCont(chain, f, contBlock) >= valUnder(chain, f, underBlock)) {
67 | return contBlock;
68 | } else {
69 | return underBlock;
70 | }
71 | }
72 |
73 | Value functionForkValueInMinedChild(const Blockchain &chain, const Block &block, ForkFunc f) {
74 | if (block.height == chain.getMaxHeightPub()) {
75 | return valCont(chain, f, block);
76 | } else {
77 | return valUnder(chain, f, block);
78 | }
79 | }
80 |
81 | Value valCont(const Blockchain &chain, ForkFunc f, const Block &contBlock) {
82 | return f(chain, chain.rem(contBlock)) + contBlock.nextBlockReward();
83 | }
84 |
85 | Value valUnder(const Blockchain &chain, ForkFunc f, const Block &underBlock) {
86 | return std::min(f(chain, chain.rem(underBlock)), chain.gap(chain.getMaxHeightPub()) - UNDERCUT_VALUE) + underBlock.nextBlockReward();
87 | }
88 |
89 | Value functionForkPercentage(const Blockchain &, Value maxVal, double funcCoeff) {
90 | double coeff = 1.0 / funcCoeff;
91 | double newValue = rawValue(maxVal) * coeff;
92 | return Value(static_cast(newValue));
93 | }
94 |
95 | Value functionForkLambert(const Blockchain &blockchain, Value maxVal, double lambertCoeff) {
96 | //don't include B-- this is about the expected portion form tx fees
97 | auto expectedBlockSize = blockchain.expectedBlockSize();
98 | auto expectedSizeRaw = rawValue(expectedBlockSize);
99 | auto blockRatio = valuePercentage(maxVal, Value(expectedBlockSize));
100 | if (blockRatio <= lambertCoeff) {
101 | return maxVal;
102 | } else if (blockRatio < 2*lambertCoeff - std::log(lambertCoeff) - 1) {
103 |
104 | double argToLambertFunct0 = -lambertCoeff*std::exp(blockRatio-2*lambertCoeff);
105 | double lambertRes = gsl_sf_lambert_W0(argToLambertFunct0);
106 |
107 | double newValue = -expectedSizeRaw * lambertRes;
108 | return Value(static_cast(newValue));
109 | } else {
110 | return Value(expectedBlockSize);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/BlockSim/function_fork_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // function_fork_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef function_fork_miner_hpp
10 | #define function_fork_miner_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | #include
15 | #include
16 |
17 | class Strategy;
18 | class Blockchain;
19 | class Block;
20 |
21 | using ForkFunc = std::function;
22 |
23 | std::unique_ptr createFunctionForkStrategy(bool atomic, ForkFunc f, std::string type);
24 |
25 | Value functionForkValueInMinedChild(const Blockchain &blockchain, const Block &block, ForkFunc f);
26 |
27 | Value functionForkPercentage(const Blockchain &blockchain, Value maxVal, double funcCoeff);
28 | Value functionForkLambert(const Blockchain &blockchain, Value maxVal, double lambertCoeff);
29 |
30 | #endif /* function_fork_miner_hpp */
31 |
--------------------------------------------------------------------------------
/BlockSim/function_fork_selfish_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // function_fork_selfish_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 11/4/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "function_fork_selfish_miner.hpp"
10 | #include "clever_selfish_miner.hpp"
11 | #include "strategy.hpp"
12 | #include "block.hpp"
13 |
14 | using std::placeholders::_1;
15 | using std::placeholders::_2;
16 |
17 | std::unique_ptr createFunctionForkSelfishStrategy(Value cutoff, ForkFunc func) {
18 | auto valueFunc = std::bind(functionForkValueInMinedChild, _1, _2, func);
19 |
20 | return std::make_unique("function-selfish", selfishBlockToMineOn, valueFunc, std::make_unique(cutoff));
21 | }
22 |
--------------------------------------------------------------------------------
/BlockSim/function_fork_selfish_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // function_fork_selfish_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 11/4/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef function_fork_selfish_miner_hpp
10 | #define function_fork_selfish_miner_hpp
11 |
12 | #include "function_fork_miner.hpp"
13 |
14 |
15 | std::unique_ptr createFunctionForkSelfishStrategy(Value cutoff, ForkFunc func);
16 |
17 | #endif /* function_fork_selfish_miner_hpp */
18 |
--------------------------------------------------------------------------------
/BlockSim/game.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // game.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "game.hpp"
10 | #include "blockchain.hpp"
11 | #include "block.hpp"
12 | #include "miner.hpp"
13 | #include "logging.h"
14 | #include "minerGroup.hpp"
15 | #include "miner_result.hpp"
16 | #include "game_result.hpp"
17 |
18 | #include "minerStrategies.h"
19 | #include "strategy.hpp"
20 |
21 | #include
22 | #include
23 |
24 | GameResult runGame(MinerGroup &minerGroup, Blockchain &blockchain, GameSettings gameSettings) {
25 |
26 | GAMEINFO("Players:" << std::endl << minerGroup);
27 |
28 | //mining loop
29 |
30 | BlockTime totalSeconds = gameSettings.blockchainSettings.numberOfBlocks * gameSettings.blockchainSettings.secondsPerBlock;
31 |
32 | while (blockchain.getTime() < totalSeconds) {
33 | BlockTime nextTime = minerGroup.nextEventTime(blockchain);
34 |
35 | assert(blockchain.getTime() <= nextTime);
36 |
37 | blockchain.advanceToTime(nextTime);
38 |
39 | assert(blockchain.getTime() == nextTime);
40 |
41 | //steps through in second intervals
42 | //on each step each miner gets a turn
43 | COMMENTARY("Round " << blockchain.getTime() << " of the game..." << std::endl);
44 |
45 | minerGroup.nextMineRound(blockchain);
46 |
47 | minerGroup.nextBroadcastRound(blockchain);
48 |
49 | COMMENTARY("Publish phase:" << std::endl);
50 |
51 | minerGroup.nextPublishRound(blockchain);
52 |
53 | COMMENTARY("Round " << blockchain.getTime() << " over. Current blockchain:" << std::endl);
54 | COMMENTARYBLOCK (
55 | blockchain.printBlockchain();
56 | blockchain.printHeads();
57 | )
58 | }
59 |
60 | minerGroup.finalize(blockchain);
61 |
62 | std::vector minerResults;
63 | minerResults.resize(minerGroup.miners.size());
64 |
65 | auto &winningBlock = blockchain.winningHead();
66 | auto winningChain = winningBlock.getChain();
67 | int parentCount = 0;
68 | Value totalValue(0);
69 | for (auto mined : winningChain) {
70 | if (mined->height == BlockHeight(0)) {
71 | break;
72 | }
73 | if (mined->parent->minedBy(mined->miner)) {
74 | parentCount++;
75 | }
76 | auto miner = mined->miner;
77 | size_t minerIndex = minerGroup.miners.size();
78 | for (size_t ind = 0; ind < minerGroup.miners.size(); ind++) {
79 | if (minerGroup.miners[ind].get() == miner) {
80 | minerIndex = ind;
81 | break;
82 | }
83 | }
84 |
85 | minerResults[minerIndex].addBlock(mined);
86 | totalValue += mined->value;
87 | }
88 |
89 | // std::cout << parentCount << " block mined over parent" << std::endl;
90 |
91 |
92 | //calculate the score at the end
93 | BlockCount totalBlocks(0);
94 | BlockCount finalBlocks(0);
95 |
96 | for (size_t i = 0; i < minerGroup.miners.size(); i++) {
97 | const auto &miner = minerGroup.miners[i];
98 | GAMEINFO(*miner << " earned:" << minerResults[i].totalProfit << " mined " << miner->getBlocksMinedTotal() <<" total, of which " << minerResults[i].blocksInWinningChain << " made it into the final chain" << std::endl);
99 | totalBlocks += miner->getBlocksMinedTotal();
100 | finalBlocks += minerResults[i].blocksInWinningChain;
101 | }
102 |
103 | Value moneyLeftAtEnd = blockchain.rem(*winningChain[0]);
104 |
105 | GameResult result(minerResults, totalBlocks, finalBlocks, moneyLeftAtEnd, totalValue);
106 |
107 | assert(winningBlock.valueInChain == totalValue);
108 | for (size_t i = 0; i < minerGroup.miners.size(); i++) {
109 | assert(minerResults[i].totalProfit <= totalValue);
110 | }
111 |
112 |
113 | GAMEINFO("Total blocks mined:" << totalBlocks << " with " << finalBlocks << " making it into the final chain" << std::endl);
114 | return result;
115 | }
116 |
--------------------------------------------------------------------------------
/BlockSim/game.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // game.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef game_hpp
10 | #define game_hpp
11 |
12 | #include "blockchain_settings.hpp"
13 | #include "typeDefs.hpp"
14 |
15 | class Blockchain;
16 | struct GameResult;
17 | class MinerGroup;
18 | struct BlockchainSettings;
19 |
20 | struct GameSettings {
21 | BlockchainSettings blockchainSettings;
22 | };
23 |
24 | GameResult runGame(MinerGroup &minerGroup, Blockchain &blockchain, GameSettings gameSettings);
25 |
26 | #endif /* game_hpp */
27 |
--------------------------------------------------------------------------------
/BlockSim/game_result.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // game_result.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 7/1/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "game_result.hpp"
10 |
11 | #include "miner_result.hpp"
12 |
13 | GameResult::GameResult(std::vector minerResults_, BlockCount totalBlocksMined_, BlockCount blocksInLongestChain_, Value moneyLeftAtEnd_, Value moneyInLongestChain_) : minerResults(minerResults_), totalBlocksMined(totalBlocksMined_), blocksInLongestChain(blocksInLongestChain_), moneyLeftAtEnd(moneyLeftAtEnd_), moneyInLongestChain(moneyInLongestChain_) {}
14 |
--------------------------------------------------------------------------------
/BlockSim/game_result.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // game_result.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 7/1/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef game_result_hpp
10 | #define game_result_hpp
11 |
12 | #include "typeDefs.hpp"
13 |
14 | #include
15 |
16 | struct MinerResult;
17 | class Miner;
18 |
19 | struct GameResult {
20 | std::vector minerResults;
21 | BlockCount totalBlocksMined;
22 | BlockCount blocksInLongestChain;
23 | Value moneyLeftAtEnd;
24 | Value moneyInLongestChain;
25 |
26 | GameResult(std::vector minerResults, BlockCount totalBlocksMined, BlockCount blocksInLongestChain, Value moneyLeftAtEnd, Value moneyInLongestChain);
27 | };
28 |
29 | #endif /* game_result_hpp */
30 |
--------------------------------------------------------------------------------
/BlockSim/gap_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // gap_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "gap_miner.hpp"
10 |
11 | #include "blockchain.hpp"
12 | #include "block.hpp"
13 | #include "logging.h"
14 | #include "miner.hpp"
15 | #include "default_miner.hpp"
16 | #include "publishing_strategy.hpp"
17 | #include "strategy.hpp"
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | using std::placeholders::_1;
24 | using std::placeholders::_2;
25 |
26 | bool shouldMine(const Miner &me, const Blockchain &blockchain, const Block &block);
27 |
28 | std::unique_ptr createGapStrategy(bool atomic, bool noiseInTransactions) {
29 | ParentSelectorFunc mineFunc;
30 | if (atomic) {
31 | mineFunc = defaultBlockToMineOnAtomic;
32 | } else {
33 | mineFunc = defaultBlockToMineOnNonAtomic;
34 | }
35 |
36 | auto valueFunc = std::bind(defaultValueInMinedChild, _1, _2, noiseInTransactions);
37 |
38 | return std::make_unique("gap", mineFunc, valueFunc, shouldMine);
39 | }
40 |
41 | bool shouldMine(const Miner &me, const Blockchain &blockchain, const Block &block) {
42 | auto expectedValue = blockchain.chanceToWin(me.params.hashRate) * block.value; //chance to win * value won
43 | auto shouldMine = me.params.costPerSecond < expectedValue || ownBlock(&me, block.parent);
44 | if (!shouldMine) {
45 | COMMENTARY("\n Miner " << me.params.name << " declines to mine. (cost:" << me.params.costPerSecond);
46 | COMMENTARY(" expected payout:" << expectedValue << ")");
47 | }
48 | return shouldMine;
49 | }
50 |
--------------------------------------------------------------------------------
/BlockSim/gap_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // gap_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef gap_miner_hpp
10 | #define gap_miner_hpp
11 |
12 | #include
13 |
14 | class Strategy;
15 |
16 | std::unique_ptr createGapStrategy(bool atomic, bool noiseInTransactions);
17 |
18 | #endif /* gap_miner_hpp */
19 |
--------------------------------------------------------------------------------
/BlockSim/lazy_fork_miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // lazy_miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "lazy_fork_miner.hpp"
10 |
11 | #include "block.hpp"
12 | #include "blockchain.hpp"
13 | #include "miner.hpp"
14 | #include "default_miner.hpp"
15 | #include "publishing_strategy.hpp"
16 | #include "strategy.hpp"
17 |
18 | #include
19 |
20 | using std::placeholders::_1;
21 | using std::placeholders::_2;
22 |
23 | Value lazyValueInMinedChild(const Blockchain &blockchain, const Block &mineHere);
24 | Block &lazyBlockToMineOnAtomic(const Miner &me, const Blockchain &chain);
25 | Block &lazyBlockToMineOnNonAtomic(const Miner &me, const Blockchain &chain);
26 |
27 | std::unique_ptr createLazyForkStrategy(bool atomic) {
28 |
29 | ParentSelectorFunc mineFunc;
30 |
31 | if (atomic) {
32 | mineFunc = lazyBlockToMineOnAtomic;
33 | } else {
34 | mineFunc = lazyBlockToMineOnNonAtomic;
35 | }
36 | auto valueFunc = lazyValueInMinedChild;
37 |
38 | return std::make_unique("lazy-fork", mineFunc, valueFunc);
39 | }
40 |
41 | Block &lazyBlockToMineOnAtomic(const Miner &me, const Blockchain &chain) {
42 | if (chain.getMaxHeightPub() == BlockHeight(0)) {
43 | return chain.most(chain.getMaxHeightPub(), me);
44 | }
45 |
46 | if (chain.rem(chain.most(chain.getMaxHeightPub(), me)) >= chain.gap(chain.getMaxHeightPub())) {
47 | return chain.most(chain.getMaxHeightPub(), me);
48 | } else {
49 | return chain.most(chain.getMaxHeightPub() - BlockHeight(1), me);
50 | }
51 | }
52 |
53 | Block &lazyBlockToMineOnNonAtomic(const Miner &, const Blockchain &chain) {
54 | if (chain.getMaxHeightPub() == BlockHeight(0)) {
55 | return chain.most(chain.getMaxHeightPub());
56 | }
57 |
58 | if (chain.rem(chain.most(chain.getMaxHeightPub())) >= chain.gap(chain.getMaxHeightPub())) {
59 | return chain.most(chain.getMaxHeightPub());
60 | } else {
61 | return chain.most(chain.getMaxHeightPub() - BlockHeight(1));
62 | }
63 | }
64 |
65 | Value lazyValueInMinedChild(const Blockchain &chain, const Block &mineHere) {
66 | return chain.rem(mineHere) / Value(2.0) + mineHere.nextBlockReward();
67 | }
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/BlockSim/lazy_fork_miner.hpp:
--------------------------------------------------------------------------------
1 | //
2 | // undercut_miner.hpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef undercut_miner_hpp
10 | #define undercut_miner_hpp
11 |
12 | #include
13 |
14 | class Strategy;
15 |
16 | std::unique_ptr createLazyForkStrategy(bool atomic);
17 |
18 | #endif /* undercut_miner_hpp */
19 |
--------------------------------------------------------------------------------
/BlockSim/logging.h:
--------------------------------------------------------------------------------
1 | //
2 | // simulationState.h
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 6/6/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #ifndef logging_h
10 | #define logging_h
11 |
12 |
13 |
14 | #define _ERROROUTPUT 1
15 | //#define _GAMEINFO 1
16 | //#define _COMMENTARY 1
17 |
18 | #ifdef _GAMEINFO
19 | #define GAMEINFO(arg) std::cout << arg
20 | #define GAMEINFOBLOCK(arg) arg
21 | #else
22 | #define GAMEINFO(arg)
23 | #define GAMEINFOBLOCK(arg)
24 | #endif
25 |
26 | #ifdef _COMMENTARY
27 | #define COMMENTARY_ON true
28 | #define COMMENTARY(arg) std::cout << arg
29 | #define COMMENTARYBLOCK(arg) arg
30 | #else
31 | #define COMMENTARY_ON false
32 | #define COMMENTARY(arg)
33 | #define COMMENTARYBLOCK(arg)
34 | #endif
35 |
36 | #ifdef _ERROROUTPUT
37 | #define ERROR(arg) std::cout << arg
38 | #else
39 | #define ERROR(arg)
40 | #endif
41 |
42 |
43 | #endif /* logging_h */
44 |
--------------------------------------------------------------------------------
/BlockSim/miner.cpp:
--------------------------------------------------------------------------------
1 | //
2 | // miner.cpp
3 | // BlockSim
4 | //
5 | // Created by Harry Kalodner on 5/25/16.
6 | // Copyright © 2016 Harry Kalodner. All rights reserved.
7 | //
8 |
9 | #include "miner.hpp"
10 | #include "block.hpp"
11 | #include "blockchain.hpp"
12 | #include "logging.h"
13 | #include "minerParameters.h"
14 | #include "mining_style.hpp"
15 | #include "simple_mining_style.hpp"
16 | #include "picky_mining_style.hpp"
17 | #include "publishing_strategy.hpp"
18 | #include "simple_publisher.hpp"
19 | #include "utils.hpp"
20 | #include "strategy.hpp"
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include