From dc4cf069636d549c3dc5fd612068fb37b326a63c Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Wed, 1 Feb 2023 12:29:21 -0500 Subject: [PATCH 01/11] Use new session interface in data. Fix up MAPI with new HTTP types --- conanfile.py | 8 +- include/gigamonkey/boost/boost.hpp | 54 +-- include/gigamonkey/hash.hpp | 338 ++++++------- include/gigamonkey/mapi/mapi.hpp | 240 ++++----- include/gigamonkey/stratum/client_session.hpp | 110 ++--- include/gigamonkey/stratum/remote.hpp | 46 +- include/gigamonkey/stratum/server_session.hpp | 194 ++++---- include/gigamonkey/work/proof.hpp | 194 ++++---- src/gigamonkey/boost/boost.cpp | 26 +- src/gigamonkey/mapi/mapi.cpp | 454 +++++++++--------- src/gigamonkey/stratum/client_session.cpp | 76 +-- src/gigamonkey/stratum/remote.cpp | 32 +- src/gigamonkey/stratum/server_session.cpp | 42 +- 13 files changed, 894 insertions(+), 920 deletions(-) diff --git a/conanfile.py b/conanfile.py index 854cfa80..aa943eb8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -2,8 +2,8 @@ from os import environ class GigamonkeyConan(ConanFile): - name = "gigamonkey" - version = "v0.0.12" + name = "Gigamonkey" + version = "v0.0.13" license = "Open BSV" author = "Daniel Krawisz" url = "https://github.com/Gigamonkey-BSV/Gigamonkey" @@ -14,7 +14,7 @@ class GigamonkeyConan(ConanFile): default_options = {"shared": False, "fPIC": True} generators = "cmake" exports_sources = "*" - requires = "boost/1.76.0", "openssl/1.1.1k", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "SECP256K1/0.2.0@proofofwork/stable", "data/v0.0.23@proofofwork/stable", "gtest/1.12.1" + requires = "boost/1.81.0", "openssl/1.1.1k", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "SECP256K1/0.2.0@proofofwork/stable", "data/v0.0.25@proofofwork/stable", "gtest/1.12.1" def set_version(self): if "CIRCLE_TAG" in environ: @@ -22,7 +22,7 @@ def set_version(self): if "CURRENT_VERSION" in environ: self.version = environ['CURRENT_VERSION'] else: - self.version = "v0.0.12" + self.version = "v0.0.13" def config_options(self): if self.settings.os == "Windows": diff --git a/include/gigamonkey/boost/boost.hpp b/include/gigamonkey/boost/boost.hpp index 349e904f..42d33ace 100644 --- a/include/gigamonkey/boost/boost.hpp +++ b/include/gigamonkey/boost/boost.hpp @@ -26,7 +26,7 @@ namespace Gigamonkey { struct output; - bool operator==(const output&, const output&); + bool operator == (const output&, const output&); std::ostream& operator << (std::ostream& o, const output s); @@ -334,24 +334,24 @@ namespace Gigamonkey { prevout (): Bitcoin::outpoint {}, Value {} {} bool operator == (const prevout &p) const { - return static_cast(*this) == static_cast(p) + return static_cast (*this) == static_cast (p) && Value == p.Value; } bool operator < (const prevout &p) const { - return static_cast(*this) < static_cast(p); + return static_cast (*this) < static_cast (p); } bool operator > (const prevout &p) const { - return static_cast(*this) > static_cast(p); + return static_cast (*this) > static_cast (p); } bool operator <= (const prevout &p) const { - return static_cast(*this) <= static_cast(p); + return static_cast (*this) <= static_cast (p); } bool operator >= (const prevout &p) const { - return static_cast(*this) >= static_cast(p); + return static_cast (*this) >= static_cast (p); } }; @@ -402,7 +402,7 @@ namespace Gigamonkey { bytes body () const; explicit operator work::puzzle () const { - return work_puzzle(this->Script, miner_pubkey_hash ()); + return work_puzzle (this->Script, miner_pubkey_hash ()); } // construct a transaction out of a solution and outputs. @@ -467,7 +467,7 @@ namespace Gigamonkey { uint32_little user_nonce, const bytes &data, bool masked_category) { if (tag.size() > 20) return output_script {}; - return output_script{category, content, target, tag, user_nonce, data, masked_category}; + return output_script{category, content, target, tag, user_nonce, data, masked_category}; } output_script inline output_script::contract ( @@ -642,7 +642,7 @@ namespace Gigamonkey { Timestamp {timestamp}, ExtraNonce2 {extra_nonce_2}, ExtraNonce1 {extra_nonce_1}, - GeneralPurposeBits{general_purpose_bits}, + GeneralPurposeBits {general_purpose_bits}, MinerPubkeyHash {} {} bool inline input_script::valid () const { @@ -690,17 +690,17 @@ namespace Gigamonkey { } // construct a Boost contract input script. - input_script inline input_script::contract( + input_script inline input_script::contract ( const Bitcoin::signature &signature, const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1) { - return input_script{signature, pubkey, nonce, timestamp, extra_nonce_2, extra_nonce_1}; + return input_script {signature, pubkey, nonce, timestamp, extra_nonce_2, extra_nonce_1}; } - input_script inline input_script::contract( + input_script inline input_script::contract ( const Bitcoin::signature &signature, const Bitcoin::pubkey &pubkey, uint32_little nonce, @@ -708,7 +708,7 @@ namespace Gigamonkey { const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, int32_little category_bits) { - return input_script{signature, pubkey, nonce, timestamp, extra_nonce_2, extra_nonce_1, category_bits}; + return input_script {signature, pubkey, nonce, timestamp, extra_nonce_2, extra_nonce_1, category_bits}; } inline input_script::input_script (bytes b) : input_script {read (b)} {} @@ -753,7 +753,7 @@ namespace Gigamonkey { inline proof::proof (type t, const work::string &w, const bytes &h, const Stratum::session_id &n1, const bytes &n2, const bytes &b, - const Bitcoin::signature &x, const Bitcoin::pubkey &p) : + const Bitcoin::signature &x, const Bitcoin::pubkey &p) : work::proof {w, {}, h, n1, n2, b}, Type {t}, Signature {x}, Pubkey {p} {} inline proof::proof (const work::job &j, const work::share &h, type t, const Bitcoin::signature &x, const Bitcoin::pubkey &p) : @@ -778,7 +778,7 @@ namespace Gigamonkey { inline output::output () : Value {-1}, Script {}, ID {} {} inline output::output (Bitcoin::satoshi v, const output_script &x) : - Value {v}, Script {x}, ID {Script.hash()} {} + Value {v}, Script {x}, ID {Script.hash ()} {} inline output::output (const Bitcoin::output &b) : Value {b.Value}, Script {Boost::output_script::read (b.Script)}, ID {Script.hash ()} {} @@ -839,35 +839,35 @@ namespace Gigamonkey { } bytes inline puzzle::body (uint32_little user_nonce, const bytes& data) { - return write (data.size() + 4, user_nonce, data); + return write (data.size () + 4, user_nonce, data); } bytes inline puzzle::header () const { return header (Script.Tag, miner_pubkey_hash ()); } - bytes inline puzzle::body() const { - return body(Script.UserNonce, Script.AdditionalData); + bytes inline puzzle::body () const { + return body (Script.UserNonce, Script.AdditionalData); } inline puzzle::puzzle (): candidate {}, MinerKey {} {} - bool inline proof::valid() const { - return (work::proof::Puzzle.Mask == -1 || work::proof::Puzzle.Mask == work::ASICBoost::Mask) && work::proof::valid(); + bool inline proof::valid () const { + return (work::proof::Puzzle.Mask == -1 || work::proof::Puzzle.Mask == work::ASICBoost::Mask) && work::proof::valid (); } - digest256 inline candidate::id() const { - return Script.hash(); + digest256 inline candidate::id () const { + return Script.hash (); } - Bitcoin::satoshi inline candidate::value() const { - return data::fold([](const Bitcoin::satoshi so_far, const prevout &u) -> Bitcoin::satoshi { + Bitcoin::satoshi inline candidate::value () const { + return data::fold ([] (const Bitcoin::satoshi so_far, const prevout &u) -> Bitcoin::satoshi { return so_far + u.Value; - }, Bitcoin::satoshi{0}, Prevouts.values()); + }, Bitcoin::satoshi {0}, Prevouts.values ()); } - bool inline candidate::valid() const { - return Prevouts.size() > 0 && Prevouts.valid() && Script.valid(); + bool inline candidate::valid () const { + return Prevouts.size () > 0 && Prevouts.valid () && Script.valid (); } } diff --git a/include/gigamonkey/hash.hpp b/include/gigamonkey/hash.hpp index 4de9fe3b..7d3e173a 100644 --- a/include/gigamonkey/hash.hpp +++ b/include/gigamonkey/hash.hpp @@ -11,29 +11,29 @@ namespace Gigamonkey { // a hash digest. template struct digest : nonzero> { - digest() : nonzero>{} {} + digest () : nonzero> {} {} - explicit digest(const uint& u) : nonzero>{u} {} - explicit digest(string_view s); - explicit digest(const slice& x) : digest{uint(x)} {} + explicit digest (const uint& u) : nonzero> {u} {} + explicit digest (string_view s); + explicit digest (const slice& x) : digest {uint (x)} {} - operator bytes_view() const; + operator bytes_view () const; - explicit operator N() const; + explicit operator N () const; - byte* begin(); - byte* end(); + byte *begin (); + byte *end (); - const byte* begin() const; - const byte* end() const; + const byte *begin () const; + const byte *end () const; - bool operator==(const digest& d) const; - bool operator!=(const digest& d) const; + bool operator == (const digest& d) const; + bool operator != (const digest& d) const; - bool operator>(const digest& d) const; - bool operator<(const digest& d) const; - bool operator<=(const digest& d) const; - bool operator>=(const digest& d) const; + bool operator > (const digest& d) const; + bool operator < (const digest& d) const; + bool operator <= (const digest& d) const; + bool operator >= (const digest& d) const; }; using digest128 = digest<16>; @@ -46,152 +46,152 @@ namespace Gigamonkey { using digest512 = digest<64>; template - inline std::ostream& operator<<(std::ostream &o, const digest &s) { + inline std::ostream& operator << (std::ostream &o, const digest &s) { return o << "digest{" << s.Value << "}"; } template - inline writer &operator<<(writer &w, const digest &s) { - return w << bytes_view(s.Value); + inline writer &operator << (writer &w, const digest &s) { + return w << bytes_view (s.Value); } template - inline reader &operator>>(reader &r, digest &s) { - r.read(s.Value.data(), size); + inline reader &operator >> (reader &r, digest &s) { + r.read(s.Value.data (), size); return r; } // supported hash functions. - digest160 SHA1(bytes_view); - digest160 SHA1(string_view); - - digest224 SHA2_224(bytes_view); - digest224 SHA2_224(string_view); - digest256 SHA2_256(bytes_view); - digest256 SHA2_256(string_view); - digest384 SHA2_384(bytes_view); - digest384 SHA2_384(string_view); - digest512 SHA2_512(bytes_view); - digest512 SHA2_512(string_view); - - template digest SHA3(bytes_view); - template digest SHA3(string_view); - - digest224 SHA3_224(bytes_view); - digest224 SHA3_224(string_view); - digest256 SHA3_256(bytes_view); - digest256 SHA3_256(string_view); - digest384 SHA3_384(bytes_view); - digest384 SHA3_384(string_view); - digest512 SHA3_512(bytes_view); - digest512 SHA3_512(string_view); - - digest128 RIPEMD_128(bytes_view); - digest128 RIPEMD_128(string_view); - digest160 RIPEMD_160(bytes_view); - digest160 RIPEMD_160(string_view); - digest256 RIPEMD_256(bytes_view); - digest256 RIPEMD_256(string_view); - digest320 RIPEMD_320(bytes_view); - digest320 RIPEMD_320(string_view); - - digest256 inline double_SHA2_256(bytes_view b) { - return SHA2_256(SHA2_256(b)); + digest160 SHA1 (bytes_view); + digest160 SHA1 (string_view); + + digest224 SHA2_224 (bytes_view); + digest224 SHA2_224 (string_view); + digest256 SHA2_256 (bytes_view); + digest256 SHA2_256 (string_view); + digest384 SHA2_384 (bytes_view); + digest384 SHA2_384 (string_view); + digest512 SHA2_512 (bytes_view); + digest512 SHA2_512 (string_view); + + template digest SHA3 (bytes_view); + template digest SHA3 (string_view); + + digest224 SHA3_224 (bytes_view); + digest224 SHA3_224 (string_view); + digest256 SHA3_256 (bytes_view); + digest256 SHA3_256 (string_view); + digest384 SHA3_384 (bytes_view); + digest384 SHA3_384 (string_view); + digest512 SHA3_512 (bytes_view); + digest512 SHA3_512 (string_view); + + digest128 RIPEMD_128 (bytes_view); + digest128 RIPEMD_128 (string_view); + digest160 RIPEMD_160 (bytes_view); + digest160 RIPEMD_160 (string_view); + digest256 RIPEMD_256 (bytes_view); + digest256 RIPEMD_256 (string_view); + digest320 RIPEMD_320 (bytes_view); + digest320 RIPEMD_320 (string_view); + + digest256 inline double_SHA2_256 (bytes_view b) { + return SHA2_256 (SHA2_256 (b)); } namespace Bitcoin { // bitcoin hash functions. - digest160 inline Hash160(bytes_view b) { - return RIPEMD_160(SHA2_256(b)); + digest160 inline Hash160 (bytes_view b) { + return RIPEMD_160 (SHA2_256 (b)); } - digest256 inline Hash256(bytes_view b) { - return double_SHA2_256(b); + digest256 inline Hash256 (bytes_view b) { + return double_SHA2_256 (b); } - digest160 Hash160(string_view b); - digest256 Hash256(string_view b); + digest160 Hash160 (string_view b); + digest256 Hash256 (string_view b); - digest160 inline address_hash(bytes_view b) { - return Hash160(b); + digest160 inline address_hash (bytes_view b) { + return Hash160 (b); } - digest256 inline signature_hash(bytes_view b) { - return Hash256(b); + digest256 inline signature_hash (bytes_view b) { + return Hash256 (b); } } template struct lazy_hash_writer : lazy_bytes_writer { - digest (*Hash)(bytes_view); - lazy_hash_writer(digest (*h)(bytes_view)) : Hash{h} {} - digest finalize() const { - return Hash(this->operator bytes()); + digest (*Hash) (bytes_view); + lazy_hash_writer (digest (*h) (bytes_view)) : Hash {h} {} + digest finalize () const { + return Hash (this->operator bytes ()); } }; - digest160 inline SHA1(string_view b) { - return SHA1(bytes_view{(const byte*)(b.data()), b.size()}); + digest160 inline SHA1 (string_view b) { + return SHA1 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest224 inline SHA2_224(string_view b) { - return SHA2_224(bytes_view{(const byte*)(b.data()), b.size()}); + digest224 inline SHA2_224 (string_view b) { + return SHA2_224 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest256 inline SHA2_256(string_view b) { - return SHA2_256(bytes_view{(const byte*)(b.data()), b.size()}); + digest256 inline SHA2_256 (string_view b) { + return SHA2_256 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest384 inline SHA2_384(string_view b) { - return SHA2_384(bytes_view{(const byte*)(b.data()), b.size()}); + digest384 inline SHA2_384 (string_view b) { + return SHA2_384 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest512 inline SHA2_512(string_view b) { - return SHA2_512(bytes_view{(const byte*)(b.data()), b.size()}); + digest512 inline SHA2_512 (string_view b) { + return SHA2_512 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest224 inline SHA3_224(string_view b) { - return SHA3_224(bytes_view{(const byte*)(b.data()), b.size()}); + digest224 inline SHA3_224 (string_view b) { + return SHA3_224 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest256 inline SHA3_256(string_view b) { - return SHA3_256(bytes_view{(const byte*)(b.data()), b.size()}); + digest256 inline SHA3_256 (string_view b) { + return SHA3_256 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest384 inline SHA3_384(string_view b) { - return SHA3_384(bytes_view{(const byte*)(b.data()), b.size()}); + digest384 inline SHA3_384 (string_view b) { + return SHA3_384 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest512 inline SHA3_512(string_view b) { - return SHA3_512(bytes_view{(const byte*)(b.data()), b.size()}); + digest512 inline SHA3_512 (string_view b) { + return SHA3_512 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest128 inline RIPEMD_128(string_view b) { - return RIPEMD_128(bytes_view{(const byte*)(b.data()), b.size()}); + digest128 inline RIPEMD_128 (string_view b) { + return RIPEMD_128 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest160 inline RIPEMD_160(string_view b) { - return RIPEMD_160(bytes_view{(const byte*)(b.data()), b.size()}); + digest160 inline RIPEMD_160 (string_view b) { + return RIPEMD_160 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest256 inline RIPEMD_256(string_view b) { - return RIPEMD_256(bytes_view{(const byte*)(b.data()), b.size()}); + digest256 inline RIPEMD_256 (string_view b) { + return RIPEMD_256 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest320 inline RIPEMD_320(string_view b) { - return RIPEMD_320(bytes_view{(const byte*)(b.data()), b.size()}); + digest320 inline RIPEMD_320 (string_view b) { + return RIPEMD_320 (bytes_view {(const byte*) (b.data ()), b.size ()}); } namespace Bitcoin { - digest160 inline Hash160(string_view b) { - return Hash160(bytes_view{(const byte*)(b.data()), b.size()}); + digest160 inline Hash160 (string_view b) { + return Hash160 (bytes_view {(const byte*) (b.data ()), b.size ()}); } - digest256 inline Hash256(string_view b) { - return Hash256(bytes_view{(const byte*)(b.data()), b.size()}); + digest256 inline Hash256 (string_view b) { + return Hash256 (bytes_view {(const byte*) (b.data ()), b.size ()}); } } @@ -208,23 +208,23 @@ namespace Gigamonkey { hash Hash; - hash_writer() : Hash{} {} + hash_writer () : Hash {} {} - digest finalize() { + digest finalize () { digest d; - Hash.Finalize(d.Value.data()); - Hash.Reset(); + Hash.Finalize (d.Value.data ()); + Hash.Reset (); return d; } - digest operator()(bytes_view b) { + digest operator () (bytes_view b) { digest d; - Hash.Write(b.data(), b.size()).Finalize(d.Value.data()); + Hash.Write (b.data (), b.size ()).Finalize (d.Value.data ()); return d; } - void write(const byte* b, size_t x) override { - Hash.Write(b, x); + void write (const byte* b, size_t x) override { + Hash.Write (b, x); } }; @@ -239,23 +239,23 @@ namespace Gigamonkey { transform Hash; - hash_writer() : Hash{} {} + hash_writer () : Hash{} {} - digest finalize() { + digest finalize () { digest d; - Hash.Final(d.Value.data()); - Hash.Restart(); + Hash.Final (d.Value.data ()); + Hash.Restart (); return d; } - digest operator()(bytes_view b) { + digest operator () (bytes_view b) { digest d; - Hash.CalculateDigest(d.Value.data(), b.data(), b.size()); + Hash.CalculateDigest (d.Value.data (), b.data (), b.size ()); return d; } void write(const byte* b, size_t x) override { - Hash.Update(b, x); + Hash.Update (b, x); } }; @@ -300,80 +300,80 @@ namespace Gigamonkey { using SHA3_512_writer = SHA3_writer<64>; - digest160 inline SHA1(bytes_view b) { - return SHA1_writer{}(b); + digest160 inline SHA1 (bytes_view b) { + return SHA1_writer{} (b); } - digest224 inline SHA2_224(bytes_view b) { - return SHA2_224_writer{}(b); + digest224 inline SHA2_224 (bytes_view b) { + return SHA2_224_writer {} (b); } - digest256 inline SHA2_256(bytes_view b) { - return SHA2_256_writer{}(b); + digest256 inline SHA2_256 (bytes_view b) { + return SHA2_256_writer {} (b); } - digest384 inline SHA2_384(bytes_view b) { - return SHA2_384_writer{}(b); + digest384 inline SHA2_384 (bytes_view b) { + return SHA2_384_writer {} (b); } - digest512 inline SHA2_512(bytes_view b) { - return SHA2_512_writer{}(b); + digest512 inline SHA2_512 (bytes_view b) { + return SHA2_512_writer {} (b); } - digest224 inline SHA3_224(bytes_view b) { - return SHA3_224_writer{}(b); + digest224 inline SHA3_224 (bytes_view b) { + return SHA3_224_writer {} (b); } - digest256 inline SHA3_256(bytes_view b) { - return SHA3_256_writer{}(b); + digest256 inline SHA3_256 (bytes_view b) { + return SHA3_256_writer{} (b); } - digest384 inline SHA3_384(bytes_view b) { - return SHA3_384_writer{}(b); + digest384 inline SHA3_384 (bytes_view b) { + return SHA3_384_writer{} (b); } - digest512 inline SHA3_512(bytes_view b) { - return SHA3_512_writer{}(b); + digest512 inline SHA3_512 (bytes_view b) { + return SHA3_512_writer{} (b); } - digest128 inline RIPEMD_128(bytes_view b) { - return RIPEMD_128_writer{}(b); + digest128 inline RIPEMD_128 (bytes_view b) { + return RIPEMD_128_writer{} (b); } - digest160 inline RIPEMD_160(bytes_view b) { - return RIPEMD_160_writer{}(b); + digest160 inline RIPEMD_160 (bytes_view b) { + return RIPEMD_160_writer {} (b); } - digest256 inline RIPEMD_256(bytes_view b) { - return RIPEMD_256_writer{}(b); + digest256 inline RIPEMD_256 (bytes_view b) { + return RIPEMD_256_writer {} (b); } - digest320 inline RIPEMD_320(bytes_view b) { - return RIPEMD_320_writer{}(b); + digest320 inline RIPEMD_320 (bytes_view b) { + return RIPEMD_320_writer {} (b); } namespace Bitcoin { struct Hash160_writer : SHA2_256_writer { - digest160 finalize() { - return RIPEMD_160(SHA2_256_writer::finalize()); + digest160 finalize () { + return RIPEMD_160 (SHA2_256_writer::finalize ()); } - digest160 operator()(bytes_view b) { - return RIPEMD_160(SHA2_256_writer::operator()(b)); + digest160 operator () (bytes_view b) { + return RIPEMD_160 (SHA2_256_writer::operator () (b)); } }; struct Hash256_writer : SHA2_256_writer { - digest256 finalize() { - return SHA2_256(SHA2_256_writer::finalize()); + digest256 finalize () { + return SHA2_256 (SHA2_256_writer::finalize ()); } - digest256 operator()(bytes_view b) { - return SHA2_256(SHA2_256_writer::operator()(b)); + digest256 operator () (bytes_view b) { + return SHA2_256 (SHA2_256_writer::operator () (b)); } }; @@ -384,65 +384,65 @@ namespace Gigamonkey { namespace Gigamonkey { template - digest::digest(string_view s) { - ptr b = data::encoding::hex::read(s); + digest::digest (string_view s) { + ptr b = data::encoding::hex::read (s); if (b != nullptr) { - std::copy(b->begin(), b->end(), begin()); - } else *this = digest{uint{string(s)}}; + std::copy (b->begin (), b->end (), begin ()); + } else *this = digest {uint {string (s)}}; } template - inline digest::operator bytes_view() const { - return bytes_view(nonzero>::Value); + inline digest::operator bytes_view () const { + return bytes_view (nonzero>::Value); } template - byte inline *digest::begin() { - return nonzero>::Value.begin(); + byte inline *digest::begin () { + return nonzero>::Value.begin (); } template - byte inline *digest::end() { - return nonzero>::Value.end(); + byte inline *digest::end () { + return nonzero>::Value.end (); } template - const byte inline *digest::begin() const { - return nonzero>::Value.begin(); + const byte inline *digest::begin () const { + return nonzero>::Value.begin (); } template - const byte inline *digest::end() const { - return nonzero>::Value.end(); + const byte inline *digest::end () const { + return nonzero>::Value.end (); } template - bool inline digest::operator==(const digest& d) const { + bool inline digest::operator == (const digest& d) const { return nonzero>::Value == d.Value; } template - bool inline digest::operator!=(const digest& d) const { + bool inline digest::operator != (const digest& d) const { return nonzero>::Value != d.Value; } template - bool inline digest::operator>(const digest& d) const { + bool inline digest::operator > (const digest& d) const { return nonzero>::Value > d.Value; } template - bool inline digest::operator<(const digest& d) const { + bool inline digest::operator < (const digest& d) const { return nonzero>::Value < d.Value; } template - bool inline digest::operator<=(const digest& d) const { + bool inline digest::operator <= (const digest& d) const { return nonzero>::Value <= d.Value; } template - bool inline digest::operator>=(const digest& d) const { + bool inline digest::operator >= (const digest& d) const { return nonzero>::Value >= d.Value; } diff --git a/include/gigamonkey/mapi/mapi.hpp b/include/gigamonkey/mapi/mapi.hpp index 2b803e7f..639f512d 100644 --- a/include/gigamonkey/mapi/mapi.hpp +++ b/include/gigamonkey/mapi/mapi.hpp @@ -4,8 +4,8 @@ #ifndef GIGAMONKEY_MAPI_MAPI #define GIGAMONKEY_MAPI_MAPI -#include -#include +#include +#include #include #include @@ -13,27 +13,27 @@ namespace Gigamonkey::BitcoinAssociation { - struct MAPI : networking::HTTP_client { - using networking::HTTP_client::HTTP_client; + struct MAPI : net::HTTP::client { + using net::HTTP::client::client; // there are five calls in MAPI struct get_policy_quote_response; - get_policy_quote_response get_policy_quote(); + get_policy_quote_response get_policy_quote (); struct get_fee_quote_response; - get_fee_quote_response get_fee_quote(); + get_fee_quote_response get_fee_quote (); struct transaction_status_response; - transaction_status_response get_transaction_status(const Bitcoin::txid&); + transaction_status_response get_transaction_status (const Bitcoin::txid&); struct submit_transaction_request; struct submit_transaction_response; - submit_transaction_response submit_transaction(const submit_transaction_request &); + submit_transaction_response submit_transaction (const submit_transaction_request &); struct submit_transactions_request; struct submit_transactions_response; - submit_transactions_response submit_transactions(const submit_transactions_request &); + submit_transactions_response submit_transactions (const submit_transactions_request &); enum service { mine, @@ -44,16 +44,16 @@ namespace Gigamonkey::BitcoinAssociation { satoshi_per_byte MiningFee; satoshi_per_byte RelayFee; - bool valid() const; + bool valid () const; - fee(satoshi_per_byte mining, satoshi_per_byte relay) : - MiningFee{mining}, RelayFee{relay} {} + fee (satoshi_per_byte mining, satoshi_per_byte relay) : + MiningFee {mining}, RelayFee {relay} {} - satoshi_per_byte get_fee(service z) const; + satoshi_per_byte get_fee (service z) const; - fee() : MiningFee{0, 0}, RelayFee{0, 0} {} + fee () : MiningFee {0, 0}, RelayFee {0, 0} {} - bool operator==(const fee& v) const { + bool operator == (const fee& v) const { return MiningFee == v.MiningFee && RelayFee == v.RelayFee; } }; @@ -68,7 +68,7 @@ namespace Gigamonkey::BitcoinAssociation { uint64 CurrentHighestBlockHeight; map Fees; - bool valid() const; + bool valid () const; get_fee_quote_response( const string& apiVersion, @@ -79,17 +79,17 @@ namespace Gigamonkey::BitcoinAssociation { uint64 currentHighestBlockHeight, map fees); - get_fee_quote_response(const JSON &j); - operator JSON() const; + get_fee_quote_response (const JSON &j); + operator JSON () const; - get_fee_quote_response(); + get_fee_quote_response (); }; struct get_policy_quote_response : get_fee_quote_response { - list Callbacks; + list Callbacks; JSON Policies; - get_policy_quote_response( + get_policy_quote_response ( const string& apiVersion, const string& timestamp, const string& expiryTime, @@ -97,15 +97,15 @@ namespace Gigamonkey::BitcoinAssociation { const digest256& currentHighestBlockHash, uint64 currentHighestBlockHeight, map fees, - list callbacks, + list callbacks, const JSON& policies); - bool valid(); + bool valid (); - get_policy_quote_response(const JSON &); - operator JSON() const; + get_policy_quote_response (const JSON &); + operator JSON () const; - get_policy_quote_response(); + get_policy_quote_response (); }; // whether a transaction was processed or not. @@ -121,12 +121,12 @@ namespace Gigamonkey::BitcoinAssociation { uint64 Size; bytes Transaction; - bool valid() const; + bool valid () const; - conflicted_with(const JSON &); - operator JSON() const; + conflicted_with (const JSON &); + operator JSON () const; - conflicted_with() : TXID{}, Size{}, Transaction{} {} + conflicted_with () : TXID {}, Size {}, Transaction {} {} }; @@ -137,18 +137,18 @@ namespace Gigamonkey::BitcoinAssociation { string ResultDescription; list ConflictedWith; - bool valid() const; + bool valid () const; - transaction_status( + transaction_status ( const digest256& txid, return_result returnResult, const string& resultDescription, list conflicted = {}) : - TXID{txid}, ReturnResult{returnResult}, - ResultDescription{resultDescription}, ConflictedWith{conflicted} {} + TXID {txid}, ReturnResult {returnResult}, + ResultDescription {resultDescription}, ConflictedWith {conflicted} {} - transaction_status() = default; - operator JSON() const; + transaction_status () = default; + operator JSON () const; }; @@ -164,9 +164,9 @@ namespace Gigamonkey::BitcoinAssociation { optional BlockHeight; optional Confirmations; - bool valid() const; + bool valid () const; - transaction_status_response( + transaction_status_response ( const string& apiVersion, const string& timestamp, const digest256& txid, @@ -175,7 +175,7 @@ namespace Gigamonkey::BitcoinAssociation { const secp256k1::pubkey& minerId, uint32 txSecondMempoolExpiry); - transaction_status_response( + transaction_status_response ( const string& apiVersion, const string& timestamp, const digest256& txid, @@ -187,10 +187,10 @@ namespace Gigamonkey::BitcoinAssociation { uint32 blockHeight, uint32 confirmations); - transaction_status_response(const JSON &); - operator JSON() const; + transaction_status_response (const JSON &); + operator JSON () const; - transaction_status_response() = default; + transaction_status_response () = default; }; @@ -208,14 +208,14 @@ namespace Gigamonkey::BitcoinAssociation { optional DSCheck; optional CallbackEncryption; - submit_transaction_parameters() = default; + submit_transaction_parameters () = default; - submit_transaction_parameters &set_CallbackURL(const string &); - submit_transaction_parameters &set_CallbackToken(const string &); - submit_transaction_parameters &set_MerkleProof(bool); - submit_transaction_parameters &set_DSCheck(bool); - submit_transaction_parameters &set_CallbackEncryption(const string &key); - submit_transaction_parameters &set_MerkleFormat(); + submit_transaction_parameters &set_CallbackURL (const string &); + submit_transaction_parameters &set_CallbackToken (const string &); + submit_transaction_parameters &set_MerkleProof (bool); + submit_transaction_parameters &set_DSCheck (bool); + submit_transaction_parameters &set_CallbackEncryption (const string &key); + submit_transaction_parameters &set_MerkleFormat (); }; @@ -224,13 +224,13 @@ namespace Gigamonkey::BitcoinAssociation { bytes Transaction; submit_transaction_parameters Parameters; - bool valid() const; + bool valid () const; - transaction_submission(const JSON &); - operator JSON() const; + transaction_submission (const JSON &); + operator JSON () const; - transaction_submission(const bytes raw, const submit_transaction_parameters &p = {}): - Transaction{raw}, Parameters{p} {} + transaction_submission (const bytes raw, const submit_transaction_parameters &p = {}): + Transaction {raw}, Parameters {p} {} }; @@ -238,12 +238,12 @@ namespace Gigamonkey::BitcoinAssociation { content_type ContentType; - submit_transaction_request( + submit_transaction_request ( const bytes tx, const submit_transaction_parameters ¶ms = {}, - content_type ct = application_octet_stream) : transaction_submission{tx, params}, ContentType{ct} {} + content_type ct = application_octet_stream) : transaction_submission {tx, params}, ContentType {ct} {} - operator networking::REST::request() const; + operator net::HTTP::REST::request () const; }; @@ -256,7 +256,7 @@ namespace Gigamonkey::BitcoinAssociation { digest256 CurrentHighestBlockHash; uint64 CurrentHighestBlockHeight; - submit_transaction_response( + submit_transaction_response ( const string &apiVersion, const string ×tamp, const digest256 &txid, @@ -268,12 +268,12 @@ namespace Gigamonkey::BitcoinAssociation { uint64 currentHighestBlockHeight, list conflictedWith = {}); - submit_transaction_response(const JSON &); - operator JSON() const; + submit_transaction_response (const JSON &); + operator JSON () const; - submit_transaction_response() : - transaction_status{}, APIVersion{}, Timestamp{}, MinerID{}, - TxSecondMempoolExpiry{0}, CurrentHighestBlockHash{}, CurrentHighestBlockHeight{0} {} + submit_transaction_response () : + transaction_status {}, APIVersion {}, Timestamp {}, MinerID {}, + TxSecondMempoolExpiry {0}, CurrentHighestBlockHash {}, CurrentHighestBlockHeight {0} {} }; @@ -283,9 +283,9 @@ namespace Gigamonkey::BitcoinAssociation { submit_transaction_parameters DefaultParameters; - bool valid() const; + bool valid () const; - operator networking::REST::request() const; + operator net::HTTP::REST::request () const; }; @@ -300,78 +300,78 @@ namespace Gigamonkey::BitcoinAssociation { list Transactions; uint32 FailureCount; - bool valid() const { - return Timestamp != "" && MinerID.valid() && - CurrentHighestBlockHash.valid() && CurrentHighestBlockHeight != 0 && + bool valid () const { + return Timestamp != "" && MinerID.valid () && + CurrentHighestBlockHash.valid () && CurrentHighestBlockHeight != 0 && TxSecondMempoolExpiry != 0 && Transactions.valid(); } - submit_transactions_response() : - APIVersion{}, Timestamp{}, MinerID{}, - CurrentHighestBlockHash{}, - CurrentHighestBlockHeight{0}, - TxSecondMempoolExpiry{0}, Transactions{}, FailureCount{0} {} + submit_transactions_response () : + APIVersion {}, Timestamp {}, MinerID {}, + CurrentHighestBlockHash {}, + CurrentHighestBlockHeight {0}, + TxSecondMempoolExpiry {0}, Transactions {}, FailureCount {0} {} - submit_transactions_response(const JSON&); - operator JSON() const; + submit_transactions_response (const JSON&); + operator JSON () const; }; private: - networking::HTTP::request get_policy_quote_HTTP_request() const { - return this->Rest.GET("/mapi/policyQuote"); + net::HTTP::request get_policy_quote_HTTP_request () const { + return this->REST.GET ("/mapi/policyQuote"); } - networking::HTTP::request get_fee_quote_HTTP_request() const { - return this->Rest.GET("/mapi/feeQuote"); + net::HTTP::request get_fee_quote_HTTP_request () const { + return this->REST.GET ("/mapi/feeQuote"); } - networking::HTTP::request transaction_status_HTTP_request(const Bitcoin::txid&) const; - networking::HTTP::request submit_transaction_HTTP_request(const submit_transaction_request &) const; - networking::HTTP::request submit_transactions_HTTP_request(const submit_transactions_request &) const; + net::HTTP::request transaction_status_HTTP_request (const Bitcoin::txid&) const; + net::HTTP::request submit_transaction_HTTP_request (const submit_transaction_request &) const; + net::HTTP::request submit_transactions_HTTP_request (const submit_transactions_request &) const; - JSON call(const networking::HTTP::request &r); + JSON call (const net::HTTP::request &r); }; - MAPI::get_policy_quote_response inline MAPI::get_policy_quote() { - return call(get_policy_quote_HTTP_request()); + MAPI::get_policy_quote_response inline MAPI::get_policy_quote () { + return call (get_policy_quote_HTTP_request ()); } - MAPI::get_fee_quote_response inline MAPI::get_fee_quote() { - return call(get_fee_quote_HTTP_request()); + MAPI::get_fee_quote_response inline MAPI::get_fee_quote () { + return call (get_fee_quote_HTTP_request()); } - MAPI::transaction_status_response inline MAPI::get_transaction_status(const Bitcoin::txid &txid) { - return call(transaction_status_HTTP_request(txid)); + MAPI::transaction_status_response inline MAPI::get_transaction_status (const Bitcoin::txid &txid) { + return call (transaction_status_HTTP_request (txid)); } - MAPI::submit_transaction_response inline MAPI::submit_transaction(const submit_transaction_request &r) { - return call(submit_transaction_HTTP_request(r)); + MAPI::submit_transaction_response inline MAPI::submit_transaction (const submit_transaction_request &r) { + return call (submit_transaction_HTTP_request (r)); } - MAPI::submit_transactions_response inline MAPI::submit_transactions(const submit_transactions_request &r) { - return call(submit_transactions_HTTP_request(r)); + MAPI::submit_transactions_response inline MAPI::submit_transactions (const submit_transactions_request &r) { + return call (submit_transactions_HTTP_request (r)); } - bool inline MAPI::fee::valid() const { - return MiningFee.valid() && RelayFee.valid(); + bool inline MAPI::fee::valid () const { + return MiningFee.valid () && RelayFee.valid (); } - satoshi_per_byte inline MAPI::fee::get_fee(service z) const { + satoshi_per_byte inline MAPI::fee::get_fee (service z) const { return z == mine ? MiningFee : RelayFee; } - bool inline MAPI::conflicted_with::valid() const { - return TXID.valid() && Size == Transaction.size(); + bool inline MAPI::conflicted_with::valid () const { + return TXID.valid () && Size == Transaction.size (); } - bool inline MAPI::transaction_status::valid() const { - return TXID.valid(); + bool inline MAPI::transaction_status::valid () const { + return TXID.valid (); } - bool inline MAPI::get_fee_quote_response::valid() const { - return Timestamp != "" && ExpiryTime != "" && MinerID.valid() && - CurrentHighestBlockHash.valid() && CurrentHighestBlockHeight != 0 && data::valid(Fees); + bool inline MAPI::get_fee_quote_response::valid () const { + return Timestamp != "" && ExpiryTime != "" && MinerID.valid () && + CurrentHighestBlockHash.valid () && CurrentHighestBlockHeight != 0 && data::valid(Fees); } inline MAPI::get_fee_quote_response::get_fee_quote_response( @@ -382,12 +382,12 @@ namespace Gigamonkey::BitcoinAssociation { const digest256& hx, uint64 cx, map f) : - APIVersion{v}, Timestamp{t}, ExpiryTime{ex}, MinerID{id}, - CurrentHighestBlockHash{hx}, CurrentHighestBlockHeight{cx}, Fees{f} {} + APIVersion {v}, Timestamp {t}, ExpiryTime {ex}, MinerID {id}, + CurrentHighestBlockHash {hx}, CurrentHighestBlockHeight {cx}, Fees {f} {} - inline MAPI::get_fee_quote_response::get_fee_quote_response() : - APIVersion{}, Timestamp{}, ExpiryTime{}, MinerID{}, - CurrentHighestBlockHash{}, CurrentHighestBlockHeight{0}, Fees{} {} + inline MAPI::get_fee_quote_response::get_fee_quote_response () : + APIVersion {}, Timestamp {}, ExpiryTime {}, MinerID {}, + CurrentHighestBlockHash {}, CurrentHighestBlockHeight {0}, Fees {} {} inline MAPI::get_policy_quote_response::get_policy_quote_response( const string& apiVersion, @@ -397,30 +397,30 @@ namespace Gigamonkey::BitcoinAssociation { const digest256& currentHighestBlockHash, uint64 currentHighestBlockHeight, map fees, - list callbacks, + list callbacks, const JSON& policies) : get_fee_quote_response{ apiVersion, timestamp, expiryTime, minerId, currentHighestBlockHash, currentHighestBlockHeight, fees}, - Callbacks{callbacks}, Policies{policies} {} + Callbacks {callbacks}, Policies {policies} {} - bool inline MAPI::get_policy_quote_response::valid() { - return get_fee_quote_response::valid() && data::valid(Fees); + bool inline MAPI::get_policy_quote_response::valid () { + return get_fee_quote_response::valid () && data::valid (Fees); } - inline MAPI::get_policy_quote_response::get_policy_quote_response() : - get_fee_quote_response{}, Callbacks{}, Policies{} {} + inline MAPI::get_policy_quote_response::get_policy_quote_response () : + get_fee_quote_response {}, Callbacks {}, Policies {} {} - bool inline MAPI::transaction_submission::valid() const { - return Transaction.size() > 0; + bool inline MAPI::transaction_submission::valid () const { + return Transaction.size () > 0; } - bool inline MAPI::transaction_status_response::valid() const { - return APIVersion != "" && Timestamp != "" && MinerID != secp256k1::pubkey{}; + bool inline MAPI::transaction_status_response::valid () const { + return APIVersion != "" && Timestamp != "" && MinerID != secp256k1::pubkey {}; } - bool inline MAPI::submit_transactions_request::valid() const { - return Submissions.size() > 0 && data::valid(Submissions); + bool inline MAPI::submit_transactions_request::valid () const { + return Submissions.size () > 0 && data::valid (Submissions); } } diff --git a/include/gigamonkey/stratum/client_session.hpp b/include/gigamonkey/stratum/client_session.hpp index b43c2750..59882106 100644 --- a/include/gigamonkey/stratum/client_session.hpp +++ b/include/gigamonkey/stratum/client_session.hpp @@ -16,11 +16,11 @@ namespace Gigamonkey::Stratum { // A client talking to a remote server. - struct client_session : public remote, public virtual work::solver { - request_id send_configure(const extensions::requests &); - request_id send_authorize(const mining::authorize_request::parameters &); - request_id send_subscribe(const mining::subscribe_request::parameters &); - request_id send_submit(const share &x); + struct client_session : public remote_receive_handler, public virtual work::solver { + request_id send_configure (const extensions::requests &); + request_id send_authorize (const mining::authorize_request::parameters &); + request_id send_subscribe (const mining::subscribe_request::parameters &); + request_id send_submit (const share &x); struct options { // how to respond to get_version requests. @@ -31,108 +31,100 @@ namespace Gigamonkey::Stratum { optional SubscribeRequest; }; - client_session(const options &o) : Options{o} {} - virtual ~client_session() {} + client_session (ptr> p, const options &o) : remote_receive_handler {p}, Options {o} {} + virtual ~client_session () {} private: - void receive_submit(bool); - virtual void receive_submit_error(const error &); + void receive_submit (bool); + virtual void receive_submit_error (const error &); - void receive_authorize(bool); - virtual void receive_authorize_error(const error &) = 0; - void receive_configure(const extensions::results &); - virtual void receive_configure_error(const error &) = 0; - void receive_subscribe(const mining::subscribe_response::parameters &); - virtual void receive_subscribe_error(const error &) = 0; + void receive_authorize (bool); + virtual void receive_authorize_error (const error &) = 0; + void receive_configure (const extensions::results &); + virtual void receive_configure_error (const error &) = 0; + void receive_subscribe (const mining::subscribe_response::parameters &); + virtual void receive_subscribe_error (const error &) = 0; - virtual void receive_show_message(const string &m) { + virtual void receive_show_message (const string &m) { std::cout << "Server says: " << m << std::endl; } - void receive_notification(const notification &n) final override; - void receive_request(const Stratum::request &r) final override; - void receive_response(method, const Stratum::response &r) final override; - void solved(const work::solution &) final override; + void receive_notification (const notification &n) final override; + void receive_request (const Stratum::request &r) final override; + void receive_response (method, const Stratum::response &r) final override; + void solved (const work::solution &) final override; - void receive_notify(const mining::notify::parameters&); - void receive_set_difficulty(const difficulty&); - void receive_set_extranonce(const mining::set_extranonce::parameters&); - void receive_set_version_mask(const extensions::version_mask&); - - mutex Mutex{}; + void receive_notify (const mining::notify::parameters&); + void receive_set_difficulty (const difficulty&); + void receive_set_extranonce (const mining::set_extranonce::parameters&); + void receive_set_version_mask (const extensions::version_mask&); options Options; optional ExtensionResults; - bool Authorized{false}; - list Subscriptions{}; + bool Authorized {false}; + list Subscriptions {}; // last minimum difficulty accepted. - optional Minimum{}; + optional Minimum {}; // the notifications we will receive from the server that // define the mining job we are to perform. - optional Difficulty{}; - optional ExtraNonce{}; - optional VersionMask{}; - optional Notify{}; + optional Difficulty {}; + optional ExtraNonce {}; + optional VersionMask {}; + optional Notify {}; - uint32 SharesSubmitted{0}; - uint32 SharesAccepted{0}; + uint32 SharesSubmitted {0}; + uint32 SharesAccepted {0}; - void pose_current_puzzle(); + void pose_current_puzzle (); }; - request_id inline client_session::send_configure(const extensions::requests &q) { - return send_request(mining_configure, mining::configure_request::serialize(mining::configure_request::parameters{q})); + request_id inline client_session::send_configure (const extensions::requests &q) { + return send_request (mining_configure, mining::configure_request::serialize (mining::configure_request::parameters {q})); } - request_id inline client_session::send_authorize(const mining::authorize_request::parameters &p) { - return send_request(mining_authorize, mining::authorize_request::serialize(p)); + request_id inline client_session::send_authorize (const mining::authorize_request::parameters &p) { + return send_request (mining_authorize, mining::authorize_request::serialize (p)); } - request_id inline client_session::send_subscribe(const mining::subscribe_request::parameters &p) { - return send_request(mining_subscribe, mining::subscribe_request::serialize(p)); + request_id inline client_session::send_subscribe (const mining::subscribe_request::parameters &p) { + return send_request (mining_subscribe, mining::subscribe_request::serialize (p)); } - request_id inline client_session::send_submit(const share &x) { - remote::guard lock(Mutex); + request_id inline client_session::send_submit (const share &x) { SharesSubmitted++; - return send_request(mining_submit, mining::submit_request::serialize(x)); + return send_request (mining_submit, mining::submit_request::serialize (x)); } - void inline client_session::receive_submit(bool b) { - remote::guard lock(Mutex); + void inline client_session::receive_submit (bool b) { if (b) SharesAccepted++; } - void inline client_session::receive_submit_error(const error &e) { - std::cout << "Share rejected with error " << JSON(e).dump() << std::endl; + void inline client_session::receive_submit_error (const error &e) { + std::cout << "Share rejected with error " << JSON (e).dump () << std::endl; } - void inline client_session::receive_notify(const mining::notify::parameters &x) { - remote::guard lock(Mutex); + void inline client_session::receive_notify (const mining::notify::parameters &x) { Notify = x; - pose_current_puzzle(); + pose_current_puzzle (); } - void inline client_session::receive_set_difficulty(const difficulty &x) { - remote::guard lock(Mutex); + void inline client_session::receive_set_difficulty (const difficulty &x) { Difficulty = x; } - void inline client_session::receive_set_extranonce(const mining::set_extranonce::parameters &x) { - remote::guard lock(Mutex); + void inline client_session::receive_set_extranonce (const mining::set_extranonce::parameters &x) { ExtraNonce = x; } - void inline client_session::receive_set_version_mask(const extensions::version_mask &x) { - remote::guard lock(Mutex); + void inline client_session::receive_set_version_mask (const extensions::version_mask &x) { VersionMask = x; - pose_current_puzzle(); + pose_current_puzzle (); } } diff --git a/include/gigamonkey/stratum/remote.hpp b/include/gigamonkey/stratum/remote.hpp index 6afbb52a..736d6b7d 100644 --- a/include/gigamonkey/stratum/remote.hpp +++ b/include/gigamonkey/stratum/remote.hpp @@ -11,59 +11,53 @@ #include #include #include -#include -#include +#include +#include namespace Gigamonkey::Stratum { - using JSON_line_session = networking::JSON_line_session; // can be used for a remote server or a remote client. - struct remote : public JSON_line_session { + struct remote_receive_handler { + ptr> Send; - virtual void receive_notification(const notification &) = 0; - virtual void receive_request(const Stratum::request &) = 0; - virtual void receive_response(method, const Stratum::response &) = 0; + virtual void receive_notification (const notification &) = 0; + virtual void receive_request (const Stratum::request &) = 0; + virtual void receive_response (method, const Stratum::response &) = 0; - virtual void parse_error(const string &invalid) override; + virtual void parse_error (const string &invalid); - uint32 Requests{0}; + uint32 Requests {0}; std::map Request; - using mutex = std::mutex; - using guard = std::lock_guard; - - mutex Mutex{}; - - void receive(const JSON &next) final override; + void operator () (const JSON &next); // there are two ways to talk to a server: request and notify. // request expects a response and notify does not. - request_id send_request(method m, parameters p); + request_id send_request (method m, parameters p); - void send_notification(method m, parameters p); + void send_notification (method m, parameters p); - remote() {} - virtual ~remote() {} + remote_receive_handler (ptr> x): Send {x} {} }; struct exception : data::exception { using data::exception::exception; - exception(const error &e) : data::exception{} { - this->write("Stratum error returned: ", JSON(e).dump()); + exception (const error &e) : data::exception {} { + this->write ("Stratum error returned: ", JSON (e).dump ()); } - template exception &operator<<(X x) { - this->write(x); + template exception &operator << (X x) { + this->write (x); return *this; } }; - void inline remote::send_notification(method m, parameters p) { - JSON_line_session::send(notification{m, p}); + void inline remote_receive_handler::send_notification (method m, parameters p) { + Send->send (notification {m, p}); } - void inline remote::parse_error(const string &invalid) { + void inline remote_receive_handler::parse_error (const string &invalid) { throw exception {} << "Invalid JSON string: \"" << invalid << "\""; } diff --git a/include/gigamonkey/stratum/server_session.hpp b/include/gigamonkey/stratum/server_session.hpp index 5d0ac52a..9d7dabb6 100644 --- a/include/gigamonkey/stratum/server_session.hpp +++ b/include/gigamonkey/stratum/server_session.hpp @@ -19,88 +19,88 @@ namespace Gigamonkey::Stratum { // this represents a server talking to a remote client. - struct server_session : public remote, public work::selector { + struct server_session : public remote_receive_handler, public work::selector { struct options { - bool CanSubmitWithoutAuthorization{true}; + bool CanSubmitWithoutAuthorization {true}; // maximum number of seconds a share can differ from our own // clock to be accepted. - uint32 MaxTimeDifferenceSeconds{10}; + uint32 MaxTimeDifferenceSeconds {10}; - uint32 RememberOldJobsSeconds{60}; + uint32 RememberOldJobsSeconds {60}; - optional ExtensionsParameters{}; + optional ExtensionsParameters {}; // if minimum difficulty is supported, do we honor // the client's requested minimum difficulty or // do we ignore it? - bool HonorMinimumDifficulty{true}; + bool HonorMinimumDifficulty {true}; - options() {}; + options () {}; }; - server_session(const options &x = {}) : State{x} {} - virtual ~server_session() {} + server_session (ptr> p, const options &x) : remote_receive_handler {p}, State {x} {} + virtual ~server_session () {} - Stratum::difficulty difficulty() const; + Stratum::difficulty difficulty () const; // send a set_difficulty message to the client. // this will not go into effect until the next // notify message is sent. - void send_set_difficulty(const Stratum::difficulty& d); + void send_set_difficulty (const Stratum::difficulty& d); - optional username() const; + optional username () const; // notify the client of a new job. - void send_notify(const mining::notify::parameters& p); + void send_notify (const mining::notify::parameters& p); - optional client_version() const; + optional client_version () const; - extensions::version_mask version_mask() const; + extensions::version_mask version_mask () const; // send a set_version_mask message to the client. - void send_set_version_mask(const extensions::version_mask& p); + void send_set_version_mask (const extensions::version_mask& p); - Stratum::extranonce extranonce() const; + Stratum::extranonce extranonce () const; // send a set_extranonce message to the client. // this will not go into effect until the next // notify message is sent. - void send_set_extranonce(const Stratum::extranonce &n); + void send_set_extranonce (const Stratum::extranonce &n); // get_version is the only request that the server sends to the client. // It doesn't depend on state so can be sent at any time. - request_id send_get_version(); + request_id send_get_version (); private: - virtual void receive_get_version(const string &) {}; + virtual void receive_get_version (const string &) {}; // we need a database of users to check logins. // empty return value means a successful authorization. - virtual optional authorize(const mining::authorize_request::parameters&) = 0; + virtual optional authorize (const mining::authorize_request::parameters&) = 0; // authorize the client to the server. - mining::authorize_response authorize(const mining::authorize_request &r); + mining::authorize_response authorize (const mining::authorize_request &r); // We also need a way to assign session ids and subscriptions to users. - virtual mining::subscribe_response::parameters subscribe(const mining::subscribe_request::parameters&) = 0; + virtual mining::subscribe_response::parameters subscribe (const mining::subscribe_request::parameters&) = 0; // typically the client does not send notifications to the server. virtual void receive_notification(const notification &n) override { - throw exception{} << "unknown notification received: " + n.dump(); + throw exception {} << "unknown notification received: " + n.dump (); } - void receive_request(const Stratum::request &) final override; - void receive_response(method, const Stratum::response &) final override; - work::puzzle select() final override; + void receive_request (const Stratum::request &) final override; + void receive_response (method, const Stratum::response &) final override; + work::puzzle select () final override; // generate a configure response from a configure request message. // this is the optional first method of the protocol. - mining::configure_response configure(const mining::configure_request &r); + mining::configure_response configure (const mining::configure_request &r); // empty return value for an accepted share. - optional submit(const share &x); + optional submit (const share &x); // the state data of the protocol. class state { @@ -108,7 +108,7 @@ namespace Gigamonkey::Stratum { options Options; // whether we have received and responded to a mining.configure message. - bool Configured{false}; + bool Configured {false}; // Extension version_rolling allows clients to use ASICBoost. Server and client agree // on a mask that says what bits of the version field the client is allowed to alter. @@ -123,7 +123,7 @@ namespace Gigamonkey::Stratum { // The user name of the worker. // Set during the authorize method. - optional Name{}; + optional Name {}; // subscriptions are assigned during the subscribe method. list Subscriptions; @@ -138,36 +138,36 @@ namespace Gigamonkey::Stratum { Stratum::difficulty NextDifficulty; public: - bool extensions_supported() const; + bool extensions_supported () const; // whether we have received and responded to a mining.configure message. - bool configured() const; + bool configured () const; // whether we have received and responded 'true' to a mining.authorize message. - bool authorized() const; + bool authorized () const; - string name() const; - void set_name(const string &x); + string name () const; + void set_name (const string &x); - optional client_version() const; - void set_client_version(const string &x); + optional client_version () const; + void set_client_version (const string &x); // whether we have received and responded true' to a mining.subscribe message. - bool subscribed() const; + bool subscribed () const; - Stratum::difficulty difficulty() const; + Stratum::difficulty difficulty () const; bool set_difficulty(const Stratum::difficulty& d); - Stratum::extranonce extranonce() const; + Stratum::extranonce extranonce () const; bool set_extranonce(const Stratum::extranonce &n); // version mask that the client is using. - optional version_mask() const; + optional version_mask () const; // return value is whether the version mask has changed. bool set_version_mask(const extensions::version_mask &x); - Stratum::difficulty minimum_difficulty() const; + Stratum::difficulty minimum_difficulty () const; void set_minimum_difficulty(optional d); extensions::result configure_result( @@ -175,7 +175,7 @@ namespace Gigamonkey::Stratum { const extensions::request &request); // empty return value means extensions are not supported. - optional configure(const extensions::requests& p); + optional configure (const extensions::requests& p); // we need to keep track of the last few notify notifications that have been sent. struct history { @@ -184,14 +184,14 @@ namespace Gigamonkey::Stratum { Stratum::extranonce ExtraNonce; mining::notify::parameters Notification; - entry(); - entry( + entry (); + entry ( const optional &m, const Stratum::extranonce &n, const mining::notify::parameters &p) : - Mask{m}, ExtraNonce{n}, Notification{p} {} + Mask{m}, ExtraNonce {n}, Notification{p} {} - Bitcoin::timestamp time() const { + Bitcoin::timestamp time () const { return Notification.Now; } }; @@ -204,10 +204,10 @@ namespace Gigamonkey::Stratum { Stratum::extranonce n, const mining::notify::parameters &p) { - while (Notifications.size() > 0 && (p.Now - Notifications.back().time()) > RememberForThisMuchTime) - Notifications.pop_back(); + while (Notifications.size () > 0 && (p.Now - Notifications.back().time()) > RememberForThisMuchTime) + Notifications.pop_back (); - Notifications.push_front({mask, n, p}); + Notifications.push_front ({mask, n, p}); } }; @@ -219,79 +219,69 @@ namespace Gigamonkey::Stratum { bool Found; bool Stale; - found() : Proof{}, Found{false}, Stale{true} {} - found(const proof &p, bool x) : Proof{p}, Found{true}, Stale{x} {} + found () : Proof{}, Found{false}, Stale{true} {} + found (const proof &p, bool x) : Proof{p}, Found{true}, Stale{x} {} }; - found find(const share &x) const; + found find (const share &x) const; - void notify(const mining::notify::parameters& p); + void notify (const mining::notify::parameters& p); - state() {} - state(const options &x) : - Options{x}, Notifies{static_cast(x.RememberOldJobsSeconds)}, Recent{} {} + state () {} + state (const options &x) : + Options {x}, Notifies {static_cast (x.RememberOldJobsSeconds)}, Recent {} {} }; - state State{}; - - mutable std::shared_mutex Mutex{}; + state State {}; }; - optional inline server_session::username() const { - std::shared_lock lock(Mutex); - return State.name(); + optional inline server_session::username () const { + return State.name (); } - Stratum::extranonce inline server_session::extranonce() const { - std::shared_lock lock(Mutex); - return State.extranonce(); + Stratum::extranonce inline server_session::extranonce () const { + return State.extranonce (); } - void inline server_session::send_set_extranonce(const Stratum::extranonce &n) { - std::unique_lock lock(Mutex); - if (State.set_extranonce(n)) this->send_notification(mining_set_extranonce, mining::set_extranonce::serialize(n)); + void inline server_session::send_set_extranonce (const Stratum::extranonce &n) { + if (State.set_extranonce (n)) this->send_notification (mining_set_extranonce, mining::set_extranonce::serialize (n)); } - extensions::version_mask inline server_session::version_mask() const { - std::shared_lock lock(Mutex); - auto mask = State.version_mask(); - return bool(mask) ? *mask : extensions::version_mask{0}; + extensions::version_mask inline server_session::version_mask () const { + auto mask = State.version_mask (); + return bool (mask) ? *mask : extensions::version_mask {0}; } void inline server_session::send_set_version_mask(const extensions::version_mask &n) { - std::unique_lock lock(Mutex); - if (State.set_version_mask(n)) - this->send_notification(mining_set_extranonce, mining::set_version_mask::serialize(*State.version_mask())); + if (State.set_version_mask (n)) + this->send_notification (mining_set_extranonce, mining::set_version_mask::serialize (*State.version_mask ())); } - Stratum::difficulty inline server_session::difficulty() const { - std::shared_lock lock(Mutex); - return State.difficulty(); + Stratum::difficulty inline server_session::difficulty () const { + return State.difficulty (); } void inline server_session::send_set_difficulty(const Stratum::difficulty& d) { - std::unique_lock lock(Mutex); - if (State.set_difficulty(d)) this->send_notification(mining_set_difficulty, mining::set_difficulty::serialize(d)); + if (State.set_difficulty (d)) this->send_notification (mining_set_difficulty, mining::set_difficulty::serialize (d)); } void inline server_session::send_notify(const mining::notify::parameters& p) { - std::shared_lock lock(Mutex); - State.notify(p); - this->send_notification(mining_notify, mining::notify::serialize(p)); + State.notify (p); + this->send_notification (mining_notify, mining::notify::serialize (p)); } - request_id inline server_session::send_get_version() { - return this->send_request(client_get_version, {}); + request_id inline server_session::send_get_version () { + return this->send_request (client_get_version, {}); } - optional inline server_session::client_version() const { - return State.client_version(); + optional inline server_session::client_version () const { + return State.client_version (); } - bool inline server_session::state::extensions_supported() const { - return bool(Options.ExtensionsParameters); + bool inline server_session::state::extensions_supported () const { + return bool (Options.ExtensionsParameters); } // whether we have received and responded to a mining.configure message. @@ -301,11 +291,11 @@ namespace Gigamonkey::Stratum { // whether we have received and responded 'true' to a mining.authorize message. bool inline server_session::state::authorized() const { - return bool(Name); + return bool (Name); } string inline server_session::state::name() const { - return bool(Name) ? *Name : ""; + return bool (Name) ? *Name : ""; } void inline server_session::state::set_name(const string &x) { @@ -321,29 +311,29 @@ namespace Gigamonkey::Stratum { } // whether we have received and responded true' to a mining.subscribe message. - bool inline server_session::state::subscribed() const { - return Subscriptions.size() > 0; + bool inline server_session::state::subscribed () const { + return Subscriptions.size () > 0; } - Stratum::difficulty inline server_session::state::difficulty() const { + Stratum::difficulty inline server_session::state::difficulty () const { return Difficulty; } - Stratum::extranonce inline server_session::state::extranonce() const { + Stratum::extranonce inline server_session::state::extranonce () const { return Extranonce; } // version mask that the client is using. - optional inline server_session::state::version_mask() const { - return VersionRollingMaskParameters.get(); + optional inline server_session::state::version_mask () const { + return VersionRollingMaskParameters.get (); } - Stratum::difficulty inline server_session::state::minimum_difficulty() const { - if (!MinimumDifficulty) return Stratum::difficulty{0}; + Stratum::difficulty inline server_session::state::minimum_difficulty () const { + if (!MinimumDifficulty) return Stratum::difficulty {0}; return *MinimumDifficulty; } - void inline server_session::state::set_minimum_difficulty(optional d) { + void inline server_session::state::set_minimum_difficulty (optional d) { MinimumDifficulty = d; } } diff --git a/include/gigamonkey/work/proof.hpp b/include/gigamonkey/work/proof.hpp index a33184c9..94bc89dd 100644 --- a/include/gigamonkey/work/proof.hpp +++ b/include/gigamonkey/work/proof.hpp @@ -16,25 +16,25 @@ namespace Gigamonkey::work { struct solution; struct proof; - proof solve(const puzzle& p, const solution& initial); + proof solve (const puzzle& p, const solution& initial); - bool operator==(const share&, const share&); - bool operator!=(const share&, const share&); + bool operator == (const share&, const share&); + bool operator != (const share&, const share&); - bool operator==(const solution&, const solution&); - bool operator!=(const solution&, const solution&); + bool operator == (const solution&, const solution&); + bool operator != (const solution&, const solution&); - bool operator==(const job&, const job&); - bool operator!=(const job&, const job&); + bool operator == (const job&, const job&); + bool operator != (const job&, const job&); - bool operator==(const puzzle&, const puzzle&); - bool operator!=(const puzzle&, const puzzle&); + bool operator == (const puzzle&, const puzzle&); + bool operator != (const puzzle&, const puzzle&); - bool operator==(const proof&, const proof&); - bool operator!=(const proof&, const proof&); + bool operator == (const proof&, const proof&); + bool operator != (const proof&, const proof&); - bool operator==(const candidate&, const candidate&); - bool operator!=(const candidate&, const candidate&); + bool operator == (const candidate&, const candidate&); + bool operator != (const candidate&, const candidate&); // candidate corresponds to a block that has been designed by the node but not completed with a nonce, timestamp, or coinbase. struct candidate { @@ -44,11 +44,11 @@ namespace Gigamonkey::work { compact Target; Merkle::path Path; - candidate() : Category{}, Digest{}, Target{}, Path{} {} - candidate(int32_little v, const uint256& d, compact g, Merkle::path mp) : - Category{v}, Digest{d}, Target{g}, Path{mp} {} + candidate () : Category {}, Digest {}, Target {}, Path {} {} + candidate (int32_little v, const uint256& d, compact g, Merkle::path mp) : + Category {v}, Digest {d}, Target {g}, Path {mp} {} - bool valid() const; + bool valid () const; }; // puzzle corresponds to the point where the coinbase has been constructed, other than the extra nonces. @@ -65,20 +65,20 @@ namespace Gigamonkey::work { // puzzle which alter the category field according to this mask. int32_little Mask; - puzzle(); - puzzle( + puzzle (); + puzzle ( int32_little v, const uint256& d, compact g, Merkle::path mp, const bytes& h, const bytes& b, - int32_little mask = -1) : puzzle{candidate{v, d, g, mp}, h, b, mask} {} + int32_little mask = -1) : puzzle {candidate {v, d, g, mp}, h, b, mask} {} puzzle(const candidate& x, const bytes& h, const bytes& b, int32_little mask = -1) : - Candidate{x}, Header{h}, Body{b}, Mask{mask} {} + Candidate {x}, Header {h}, Body {b}, Mask {mask} {} - bool valid() const; + bool valid () const; }; // job corresponds to the point where the mining pool has assigned an extra nonce to a miner @@ -88,10 +88,10 @@ namespace Gigamonkey::work { Stratum::session_id ExtraNonce1; - job(); - job(const puzzle&, Stratum::session_id extra); + job (); + job (const puzzle&, Stratum::session_id extra); - bool valid() const; + bool valid () const; }; struct share final { @@ -105,14 +105,14 @@ namespace Gigamonkey::work { // https://en.bitcoin.it/wiki/BIP_0320 std::optional Bits; - share(Bitcoin::timestamp t, nonce n, bytes b, int32_little bits); - share(Bitcoin::timestamp t, nonce n, bytes b); - share(); + share (Bitcoin::timestamp t, nonce n, bytes b, int32_little bits); + share (Bitcoin::timestamp t, nonce n, bytes b); + share (); bool valid() const; - int32_little general_purpose_bits(int32_little mask) const { - return int32_little{bool(Bits) ? ((*Bits) & mask) : 0}; + int32_little general_purpose_bits (int32_little mask) const { + return int32_little {bool (Bits) ? ((*Bits) & mask) : 0}; } }; @@ -121,12 +121,12 @@ namespace Gigamonkey::work { Stratum::session_id ExtraNonce1; - solution() : Share{}, ExtraNonce1{} {} - solution(const share& x, Stratum::session_id n1) : Share{x}, ExtraNonce1{n1} {} - solution(Bitcoin::timestamp t, nonce n, bytes_view b, Stratum::session_id n1) : solution{share{t, n, b}, n1} {} + solution () : Share {}, ExtraNonce1 {} {} + solution (const share& x, Stratum::session_id n1) : Share {x}, ExtraNonce1 {n1} {} + solution (Bitcoin::timestamp t, nonce n, bytes_view b, Stratum::session_id n1) : solution {share {t, n, b}, n1} {} - bool valid() const { - return Share.valid(); + bool valid () const { + return Share.valid (); } }; @@ -134,12 +134,12 @@ namespace Gigamonkey::work { puzzle Puzzle; solution Solution; - bool valid() const; + bool valid () const; - proof(); - proof(const puzzle& p, const solution& x); - proof(const job& j, const share& x) : proof{j.Puzzle, solution{x, j.ExtraNonce1}} {} - proof( + proof (); + proof (const puzzle& p, const solution& x); + proof (const job& j, const share& x) : proof {j.Puzzle, solution {x, j.ExtraNonce1}} {} + proof ( const string& w, Merkle::path mp, const bytes& h, @@ -147,170 +147,170 @@ namespace Gigamonkey::work { const bytes& n2, const bytes& b); - bytes meta() const; + bytes meta () const; - digest256 merkle_root() const; + digest256 merkle_root () const; - work::string string() const; + work::string string () const; - work::job job() const { + work::job job () const { return {Puzzle, Solution.ExtraNonce1}; } }; - proof cpu_solve(const puzzle& p, const solution& initial); + proof cpu_solve (const puzzle& p, const solution& initial); // right now we only have cpu mining in this lib. - proof inline solve(puzzle p, solution initial) { - return cpu_solve(p, initial); + proof inline solve (puzzle p, solution initial) { + return cpu_solve (p, initial); } - bool inline operator==(const share& a, const share& b) { + bool inline operator == (const share& a, const share& b) { return a.Timestamp == b.Timestamp && a.Nonce == b.Nonce && a.ExtraNonce2 == b.ExtraNonce2 && a.Bits == b.Bits; } - bool inline operator!=(const share& a, const share& b) { + bool inline operator != (const share& a, const share& b) { return !(a == b); } - bool inline operator==(const solution& a, const solution& b) { + bool inline operator == (const solution& a, const solution& b) { return a.Share == b.Share && a.ExtraNonce1 == b.ExtraNonce1; } - bool inline operator!=(const solution& a, const solution& b) { + bool inline operator != (const solution& a, const solution& b) { return !(a == b); } - bool inline operator==(const candidate& a, const candidate& b) { + bool inline operator == (const candidate& a, const candidate& b) { return a.Category == b.Category && a.Digest == b.Digest && a.Target == b.Target && a.Path == b.Path; } - bool inline operator!=(const candidate& a, const candidate& b) { + bool inline operator != (const candidate& a, const candidate& b) { return !(a == b); } - bool inline operator==(const puzzle& a, const puzzle& b) { + bool inline operator == (const puzzle& a, const puzzle& b) { return a.Candidate == b.Candidate && a.Header == b.Header && a.Body == b.Body && a.Mask == b.Mask; } - bool inline operator!=(const puzzle& a, const puzzle& b) { + bool inline operator != (const puzzle& a, const puzzle& b) { return !(a == b); } - bool inline operator==(const job& a, const job& b) { + bool inline operator == (const job& a, const job& b) { return a.Puzzle == b.Puzzle && a.ExtraNonce1 == b.ExtraNonce1; } - bool inline operator!=(const job& a, const job& b) { + bool inline operator != (const job& a, const job& b) { return !(a == b); } - bool inline operator==(const proof& a, const proof& b) { + bool inline operator == (const proof& a, const proof& b) { return a.Puzzle == b.Puzzle && a.Solution == b.Solution; } - bool inline operator!=(const proof& a, const proof& b) { + bool inline operator != (const proof& a, const proof& b) { return !(a == b); } - inline std::ostream& operator<<(std::ostream& o, const share& p) { + inline std::ostream& operator << (std::ostream& o, const share& p) { o << "share{Timestamp: " << p.Timestamp << ", Nonce: " << p.Nonce << ", ExtraNonce2: " << p.ExtraNonce2; if (p.Bits) o << ", Bits: " << *p.Bits; return o << "}"; } - inline std::ostream& operator<<(std::ostream& o, const candidate& p) { + inline std::ostream& operator << (std::ostream& o, const candidate& p) { return o << "candidate{Category: " << p.Category << ", Digest: " << p.Digest << ", Target: " << p.Target << ", Path: " << p.Path << "}"; } - inline std::ostream& operator<<(std::ostream& o, const puzzle& p) { + inline std::ostream& operator << (std::ostream& o, const puzzle& p) { return o << "puzzle{" << p.Candidate << ", Header: " << p.Header << ", Body: " << p.Body << ", Mask: " << p.Mask << "}"; } - inline std::ostream& operator<<(std::ostream& o, const job& p) { + inline std::ostream& operator << (std::ostream& o, const job& p) { return o << "job{" << p.Puzzle << ", ExtraNonce1: " << p.ExtraNonce1 << "}"; } - inline std::ostream& operator<<(std::ostream& o, const solution& p) { + inline std::ostream& operator << (std::ostream& o, const solution& p) { return o << "solution{" << p.Share << ", ExtraNonce1: " << p.ExtraNonce1 << "}"; } - inline std::ostream& operator<<(std::ostream& o, const proof& p) { + inline std::ostream& operator << (std::ostream& o, const proof& p) { return o << "proof{Puzzle: " << p.Puzzle << ", Solution: " << p.Solution << "}"; } - inline share::share(Bitcoin::timestamp t, nonce n, bytes b) - : Timestamp{t}, Nonce{n}, ExtraNonce2{b}, Bits{} {} + inline share::share (Bitcoin::timestamp t, nonce n, bytes b) + : Timestamp {t}, Nonce {n}, ExtraNonce2 {b}, Bits {} {} - inline share::share(Bitcoin::timestamp t, nonce n, bytes b, int32_little bits) - : Timestamp{t}, Nonce{n}, ExtraNonce2{b}, Bits{bits} {} + inline share::share (Bitcoin::timestamp t, nonce n, bytes b, int32_little bits) + : Timestamp {t}, Nonce {n}, ExtraNonce2 {b}, Bits {bits} {} - inline share::share() : Timestamp{}, Nonce{}, ExtraNonce2{} {}; + inline share::share () : Timestamp {}, Nonce {}, ExtraNonce2 {} {}; - bool inline share::valid() const { - return Timestamp.valid(); + bool inline share::valid () const { + return Timestamp.valid (); } - inline puzzle::puzzle() : Candidate{}, Header{}, Body{}, Mask{-1} {} + inline puzzle::puzzle () : Candidate {}, Header {}, Body {}, Mask {-1} {} - inline job::job() : Puzzle{}, ExtraNonce1{} {} - inline job::job(const puzzle& p, Stratum::session_id extra) : Puzzle{p}, ExtraNonce1{extra} {} + inline job::job () : Puzzle {}, ExtraNonce1 {} {} + inline job::job (const puzzle& p, Stratum::session_id extra) : Puzzle {p}, ExtraNonce1 {extra} {} - bool inline candidate::valid() const { - return Target.valid() && Path.valid(); + bool inline candidate::valid () const { + return Target.valid () && Path.valid (); } - bool inline puzzle::valid() const { - return Candidate.valid(); + bool inline puzzle::valid () const { + return Candidate.valid (); } - bool inline job::valid() const { - return Puzzle.valid(); + bool inline job::valid () const { + return Puzzle.valid (); } - inline proof::proof() : Puzzle{}, Solution{} {} - inline proof::proof(const puzzle& p, const solution& x) : Puzzle{p}, Solution{x} {} + inline proof::proof () : Puzzle{}, Solution{} {} + inline proof::proof (const puzzle& p, const solution& x) : Puzzle{p}, Solution{x} {} - inline proof::proof( + inline proof::proof ( const struct string& w, Merkle::path mp, const bytes& h, const Stratum::session_id& n1, const bytes& n2, const bytes& b) : - Puzzle{w.Category, w.Digest, w.Target, {}, h, b}, - Solution{share{w.Timestamp, w.Nonce, n2}, n1} { - if (w.MerkleRoot != merkle_root()) *this = {}; + Puzzle {w.Category, w.Digest, w.Target, {}, h, b}, + Solution {share {w.Timestamp, w.Nonce, n2}, n1} { + if (w.MerkleRoot != merkle_root ()) *this = {}; } - bytes inline proof::meta() const { - return write(Puzzle.Header.size() + 4 + Solution.Share.ExtraNonce2.size() + Puzzle.Body.size(), + bytes inline proof::meta () const { + return write (Puzzle.Header.size () + 4 + Solution.Share.ExtraNonce2.size () + Puzzle.Body.size (), Puzzle.Header, Solution.ExtraNonce1, Solution.Share.ExtraNonce2, Puzzle.Body); } - digest256 inline proof::merkle_root() const { - return Puzzle.Candidate.Path.derive_root(Bitcoin::Hash256(meta())); + digest256 inline proof::merkle_root () const { + return Puzzle.Candidate.Path.derive_root (Bitcoin::Hash256 (meta ())); } - string inline proof::string() const { - return work::string{ - (Puzzle.Candidate.Category & Puzzle.Mask) | Solution.Share.general_purpose_bits(~Puzzle.Mask), + string inline proof::string () const { + return work::string { + (Puzzle.Candidate.Category & Puzzle.Mask) | Solution.Share.general_purpose_bits (~Puzzle.Mask), Puzzle.Candidate.Digest, - merkle_root(), + merkle_root (), Solution.Share.Timestamp, Puzzle.Candidate.Target, Solution.Share.Nonce }; } - bool inline proof::valid() const { - return string().valid(); + bool inline proof::valid () const { + return string ().valid (); } } diff --git a/src/gigamonkey/boost/boost.cpp b/src/gigamonkey/boost/boost.cpp index 5e961b4c..8ded98e1 100644 --- a/src/gigamonkey/boost/boost.cpp +++ b/src/gigamonkey/boost/boost.cpp @@ -44,7 +44,7 @@ namespace Gigamonkey::Boost { push_size {4, Nonce}, push_size {4, Timestamp}, push {x.ExtraNonce2}, - push_size{4, ExtraNonce1}, + push_size {4, ExtraNonce1}, optional {push_size {4, GeneralPurposeBits}}, optional {push_size {20, MinerPubkeyHash}}}.match (b)) return {}; @@ -62,22 +62,22 @@ namespace Gigamonkey::Boost { x.MinerPubkeyHash.begin ()); x.Pubkey.resize (MinerPubkey.size ()); - std::copy( + std::copy ( MinerPubkey.begin (), MinerPubkey.end (), x.Pubkey.begin ()); - std::copy( + std::copy ( Timestamp.begin (), Timestamp.end (), x.Timestamp.data ()); - std::copy( + std::copy ( Nonce.begin (), Nonce.end (), x.Nonce.data ()); - std::copy( + std::copy ( ExtraNonce1.begin (), ExtraNonce1.end (), x.ExtraNonce1.data ()); @@ -126,9 +126,9 @@ namespace Gigamonkey::Boost { // check that the given address matches the pubkey and check signature. OP_DUP, OP_HASH160, OP_FROMALTSTACK, OP_EQUALVERIFY, OP_CHECKSIG}; - pattern output_script_pattern = pattern{ + pattern output_script_pattern = pattern { push {bytes {0x62, 0x6F, 0x6F, 0x73, 0x74, 0x70, 0x6F, 0x77}}, OP_DROP, - optional {push_size{20, MinerPubkeyHash}}, + optional {push_size {20, MinerPubkeyHash}}, push_size {4, Category}, push_size {32, Content}, push_size {4, Target}, @@ -355,13 +355,13 @@ namespace Gigamonkey::Boost { auto miner_pubkey_hash = out.Type == bounty ? in.MinerPubkeyHash : out.MinerPubkeyHash; if (out.UseGeneralPurposeBits && bool (in.GeneralPurposeBits)) { int32_little gpr = *in.GeneralPurposeBits; - *this = proof {work::job{work::puzzle{ - out.Category, out.Content, out.Target, Merkle::path{}, - puzzle::header(out.Tag, miner_pubkey_hash), - puzzle::body(out.UserNonce, out.AdditionalData), + *this = proof {work::job {work::puzzle{ + out.Category, out.Content, out.Target, Merkle::path {}, + puzzle::header (out.Tag, miner_pubkey_hash), + puzzle::body (out.UserNonce, out.AdditionalData), work::ASICBoost::Mask}, in.ExtraNonce1}, - work::share{in.Timestamp, in.Nonce, in.ExtraNonce2, gpr}, out.Type, in.Signature, in.Pubkey}; + work::share {in.Timestamp, in.Nonce, in.ExtraNonce2, gpr}, out.Type, in.Signature, in.Pubkey}; return; } else if (!out.UseGeneralPurposeBits && !bool (in.GeneralPurposeBits)) { *this = proof {work::job {work::puzzle{ @@ -382,7 +382,7 @@ namespace Gigamonkey::Boost { return {script.Category, script.Content, script.Target, Merkle::path {}, puzzle::header (script.Tag, miner_pubkey_hash), puzzle::body (script.UserNonce, script.AdditionalData), - script.UseGeneralPurposeBits ? work::ASICBoost::Mask : int32_little{-1}}; + script.UseGeneralPurposeBits ? work::ASICBoost::Mask : int32_little {-1}}; } bool puzzle::valid () const { diff --git a/src/gigamonkey/mapi/mapi.cpp b/src/gigamonkey/mapi/mapi.cpp index 666dea6c..e608a453 100644 --- a/src/gigamonkey/mapi/mapi.cpp +++ b/src/gigamonkey/mapi/mapi.cpp @@ -6,134 +6,134 @@ namespace Gigamonkey::BitcoinAssociation { using namespace Bitcoin; - JSON MAPI::call(const networking::HTTP::request &q) { - networking::HTTP::response r = (*this)(q); + JSON MAPI::call (const net::HTTP::request &q) { + net::HTTP::response r = (*this) (q); - if (static_cast(r.Status) < 200 || - static_cast(r.Status) >= 300) - throw networking::HTTP::exception{q, r, "response code"}; + if (static_cast (r.Status) < 200 || + static_cast (r.Status) >= 300) + throw net::HTTP::exception {q, r, "response code"}; - if (r.Headers[networking::HTTP::header::content_type] != "application/json") - throw networking::HTTP::exception{q, r, string{"content type is not JSON; it is "} + - r.Headers[networking::HTTP::header::content_type]}; + if (r.Headers[net::HTTP::header::content_type] != "application/json") + throw net::HTTP::exception {q, r, string {"content type is not JSON; it is "} + + r.Headers[net::HTTP::header::content_type]}; - auto envelope = JSON_JSON_envelope{JSON_envelope{JSON::parse(r.Body)}}; + auto envelope = JSON_JSON_envelope {JSON_envelope {JSON::parse (r.Body)}}; - if (!envelope.verify()) throw networking::HTTP::exception{q, r, "MAPI signature verify fail"}; + if (!envelope.verify ()) throw net::HTTP::exception {q, r, "MAPI signature verify fail"}; - return envelope.payload(); + return envelope.payload (); } - networking::HTTP::request MAPI::transaction_status_HTTP_request(const Bitcoin::txid &request) const { - if (!request.valid()) throw std::invalid_argument{"invalid txid"}; + net::HTTP::request MAPI::transaction_status_HTTP_request (const Bitcoin::txid &request) const { + if (!request.valid ()) throw std::invalid_argument {"invalid txid"}; std::stringstream ss; ss << "/mapi/tx/" << request; - return this->Rest.GET(ss.str()); + return this->REST.GET (ss.str ()); } - networking::HTTP::request MAPI::submit_transaction_HTTP_request(const submit_transaction_request &request) const { - if (!request.valid()) throw std::invalid_argument{"invalid transaction submission request"}; - return this->Rest(networking::REST::request(request)); + net::HTTP::request MAPI::submit_transaction_HTTP_request (const submit_transaction_request &request) const { + if (!request.valid ()) throw std::invalid_argument {"invalid transaction submission request"}; + return this->REST (net::HTTP::REST::request (request)); } - networking::HTTP::request MAPI::submit_transactions_HTTP_request(const submit_transactions_request &request) const { - if (!request.valid()) throw std::invalid_argument{"invalid transactions submission request"}; - return this->Rest(networking::REST::request(request)); + net::HTTP::request MAPI::submit_transactions_HTTP_request (const submit_transactions_request &request) const { + if (!request.valid ()) throw std::invalid_argument {"invalid transactions submission request"}; + return this->REST (net::HTTP::REST::request (request)); } namespace { - satoshi_per_byte spb_from_JSON(const JSON& j) { - if (!(j.is_object() && - j.contains("satoshis") && j["satoshis"].is_number_unsigned() && - j.contains("bytes") && j["bytes"].is_number_unsigned())) return{}; + satoshi_per_byte spb_from_JSON (const JSON& j) { + if (!(j.is_object () && + j.contains ("satoshis") && j["satoshis"].is_number_unsigned () && + j.contains ("bytes") && j["bytes"].is_number_unsigned ())) return {}; - return satoshi_per_byte{satoshi{int64(j["satoshis"])}, uint64(j["bytes"])}; + return satoshi_per_byte {satoshi {int64 (j["satoshis"])}, uint64 (j["bytes"])}; } - JSON to_JSON(const digest256 &v) { + JSON to_JSON (const digest256 &v) { std::stringstream ss; ss << v; - return ss.str().substr(9, 64); + return ss.str ().substr (9, 64); } - JSON to_JSON(const satoshi_per_byte v) { - return JSON{{"satoshis", int64(v.Satoshis)}, {"bytes", v.Bytes}}; + JSON to_JSON (const satoshi_per_byte v) { + return JSON {{"satoshis", int64 (v.Satoshis)}, {"bytes", v.Bytes}}; } - string to_JSON(MAPI::return_result r) { + string to_JSON (MAPI::return_result r) { return r == MAPI::success ? "success" : "failure"; } - JSON to_JSON(list subs) { - JSON j = JSON::array(); + JSON to_JSON (list subs) { + JSON j = JSON::array (); - for (const MAPI::transaction_submission& sub : subs) j.push_back(JSON(sub)); + for (const MAPI::transaction_submission& sub : subs) j.push_back (JSON (sub)); return j; } - JSON to_JSON(map fees) { - JSON j = JSON::array(); + JSON to_JSON (map fees) { + JSON j = JSON::array (); for (const data::entry& f : fees) - j.push_back(f.valid() ? JSON{ + j.push_back (f.valid () ? JSON { {"feeType", f.Key}, - {"miningFee", to_JSON(f.Value.MiningFee)}, - {"relayFee", to_JSON(f.Value.RelayFee)}} : JSON(nullptr)); + {"miningFee", to_JSON (f.Value.MiningFee)}, + {"relayFee", to_JSON (f.Value.RelayFee)}} : JSON (nullptr)); return j; } - optional> read_ip_address_list(const JSON &j) { - if (!j.is_array()) return {}; + optional> read_ip_address_list (const JSON &j) { + if (!j.is_array ()) return {}; - list ips; + list ips; for (const JSON &i : j) { - if (!j.contains("ipAddress")) return {}; - ips = ips << networking::IP::address{string(j["ipAddress"])}; + if (!j.contains ("ipAddress")) return {}; + ips = ips << net::IP::address {string (j["ipAddress"])}; } return ips; } - JSON ip_addresses_to_JSON(list ips) { + JSON ip_addresses_to_JSON (list ips) { JSON::array_t ii; - ii.resize(ips.size()); + ii.resize (ips.size ()); int i = 0; - for (const networking::IP::address &ip : ips) ii[i++] = string(ip); + for (const net::IP::address &ip : ips) ii[i++] = string (ip); return ii; } - MAPI::transaction_status read_transaction_status(const JSON& j) { + MAPI::transaction_status read_transaction_status (const JSON& j) { MAPI::transaction_status x; - if (!(j.is_object() && - j.contains("txid") && j["txid"].is_string() && - j.contains("returnResult") && j["returnResult"].is_string() && - j.contains("returnDescription") && j["returnDescription"].is_string() && - (!j.contains("conflictedWith") || j["conflictedWith"].is_array()))) return {}; + if (!(j.is_object () && + j.contains ("txid") && j["txid"].is_string () && + j.contains ("returnResult") && j["returnResult"].is_string () && + j.contains ("returnDescription") && j["returnDescription"].is_string () && + (!j.contains ("conflictedWith") || j["conflictedWith"].is_array ()))) return {}; string rr = j["returnResult"]; if (rr == "success") x.ReturnResult = MAPI::success; else if (rr == "failure") x.ReturnResult = MAPI::failure; else return {}; - if (j.contains("conflictedWith")) { + if (j.contains ("conflictedWith")) { list cw; for (const JSON& w : j["conflictedWith"]) { - cw = cw << MAPI::conflicted_with{w}; - if (!cw.first().valid()) return {}; + cw = cw << MAPI::conflicted_with {w}; + if (!cw.first ().valid ()) return {}; } x.ConflictedWith = cw; } - x.TXID = digest256{string{"0x"} + string(j["txid"])}; - if (!x.TXID.valid()) return {}; + x.TXID = digest256 {string{"0x"} + string (j["txid"])}; + if (!x.TXID.valid ()) return {}; x.ResultDescription = j["resultDescription"]; @@ -141,59 +141,59 @@ namespace Gigamonkey::BitcoinAssociation { } JSON to_JSON(const MAPI::submit_transaction_parameters &x) { - JSON j = JSON::object_t{}; + JSON j = JSON::object_t {}; - if (x.CallbackURL.has_value()) j["callbackUrl"] = *x.CallbackURL; - if (x.CallbackToken.has_value()) j["callbackToken"] = *x.CallbackToken; - if (x.MerkleProof.has_value()) j["merkleProof"] = *x.MerkleProof; - if (x.DSCheck.has_value()) j["dsCheck"] = *x.DSCheck; - if (x.CallbackEncryption.has_value()) j["callbackEncryption"] = *x.CallbackEncryption; + if (x.CallbackURL.has_value ()) j["callbackUrl"] = *x.CallbackURL; + if (x.CallbackToken.has_value ()) j["callbackToken"] = *x.CallbackToken; + if (x.MerkleProof.has_value ()) j["merkleProof"] = *x.MerkleProof; + if (x.DSCheck.has_value ()) j["dsCheck"] = *x.DSCheck; + if (x.CallbackEncryption.has_value ()) j["callbackEncryption"] = *x.CallbackEncryption; return j; } - JSON to_JSON(const MAPI::transaction_submission &x) { - if (!x.valid()) return {}; + JSON to_JSON (const MAPI::transaction_submission &x) { + if (!x.valid ()) return {}; - JSON j = to_JSON(x.Parameters); + JSON j = to_JSON (x.Parameters); - j["rawtx"] = encoding::hex::write(x.Transaction); + j["rawtx"] = encoding::hex::write (x.Transaction); return j; } - JSON to_JSON(list cx) { + JSON to_JSON (list cx) { JSON::array_t cf; - cf.resize(cx.size()); + cf.resize (cx.size ()); int i = 0; - for (const MAPI::conflicted_with &c : cx) cf[i++] = JSON(c); + for (const MAPI::conflicted_with &c : cx) cf[i++] = JSON (c); return cf; } - JSON to_JSON(const MAPI::transaction_status &tst) { - if (!tst.valid()) return {}; + JSON to_JSON (const MAPI::transaction_status &tst) { + if (!tst.valid ()) return {}; - JSON j{ - {"txid", string(tst.TXID.Value)}, - {"returnResult", to_JSON(tst.ReturnResult)}, + JSON j { + {"txid", string (tst.TXID.Value)}, + {"returnResult", to_JSON (tst.ReturnResult)}, {"resultDescription", tst.ResultDescription}}; - if (tst.ConflictedWith.size() > 0) j["conflictedWith"] = to_JSON(tst.ConflictedWith); + if (tst.ConflictedWith.size () > 0) j["conflictedWith"] = to_JSON (tst.ConflictedWith); return j; } - list> to_url_params(const MAPI::submit_transaction_parameters &ts) { + list> to_url_params (const MAPI::submit_transaction_parameters &ts) { list> params; - if (ts.CallbackURL) params = params << data::entry{"callbackUrl", *ts.CallbackURL}; - if (ts.CallbackToken) params = params << data::entry{"callbackToken", *ts.CallbackToken}; - if (ts.MerkleProof) params = params << data::entry{"merkleProof", std::to_string(*ts.MerkleProof)}; - if (ts.MerkleFormat) params = params << data::entry{"merkleFormat", *ts.MerkleFormat}; - if (ts.DSCheck) params = params << data::entry{"dsCheck", std::to_string(*ts.DSCheck)}; - if (ts.CallbackEncryption) params = params << data::entry{"callbackEncryption", *ts.CallbackEncryption}; + if (ts.CallbackURL) params = params << data::entry {"callbackUrl", *ts.CallbackURL}; + if (ts.CallbackToken) params = params << data::entry {"callbackToken", *ts.CallbackToken}; + if (ts.MerkleProof) params = params << data::entry {"merkleProof", std::to_string (*ts.MerkleProof)}; + if (ts.MerkleFormat) params = params << data::entry {"merkleFormat", *ts.MerkleFormat}; + if (ts.DSCheck) params = params << data::entry {"dsCheck", std::to_string (*ts.DSCheck)}; + if (ts.CallbackEncryption) params = params << data::entry {"callbackEncryption", *ts.CallbackEncryption}; return params; } @@ -201,321 +201,321 @@ namespace Gigamonkey::BitcoinAssociation { } MAPI::transaction_submission::operator JSON() const { - JSON j{{"rawtx", encoding::hex::write(Transaction)}}; + JSON j{{"rawtx", encoding::hex::write (Transaction)}}; if (this->Parameters.CallbackURL) j["callbackUrl"] = *this->Parameters.CallbackURL; if (this->Parameters.CallbackToken) j["callbackToken"] = *this->Parameters.CallbackToken; - if (this->Parameters.MerkleProof) j["merkleProof"] = std::to_string(*this->Parameters.MerkleProof); + if (this->Parameters.MerkleProof) j["merkleProof"] = std::to_string (*this->Parameters.MerkleProof); if (this->Parameters.MerkleFormat) j["merkleFormat"] = *this->Parameters.MerkleFormat; - if (this->Parameters.DSCheck) j["dsCheck"] = std::to_string(*this->Parameters.DSCheck); + if (this->Parameters.DSCheck) j["dsCheck"] = std::to_string (*this->Parameters.DSCheck); if (this->Parameters.CallbackEncryption) j["callbackEncryption"] = *this->Parameters.CallbackEncryption; return j; } - MAPI::submit_transaction_request::operator networking::REST::request() const { + MAPI::submit_transaction_request::operator net::HTTP::REST::request () const { if (ContentType == application_JSON) { - return networking::REST::request{networking::HTTP::method::post, "/mapi/tx", {}, - {{networking::HTTP::header::content_type, "application/JSON"}}, - JSON(static_cast(*this))}; + return net::HTTP::REST::request {net::HTTP::method::post, "/mapi/tx", {}, + {{net::HTTP::header::content_type, "application/JSON"}}, + JSON (static_cast (*this))}; } - std::string tx{}; - tx.resize(this->Transaction.size()); - std::copy(this->Transaction.begin(), this->Transaction.end(), tx.begin()); + std::string tx {}; + tx.resize (this->Transaction.size ()); + std::copy (this->Transaction.begin (), this->Transaction.end (), tx.begin ()); - return networking::REST::request{networking::HTTP::method::post, - "/mapi/tx", to_url_params(Parameters), - {{networking::HTTP::header::content_type, "application/octet-stream"}}, tx}; + return net::HTTP::REST::request {net::HTTP::method::post, + "/mapi/tx", to_url_params (Parameters), + {{net::HTTP::header::content_type, "application/octet-stream"}}, tx}; } - MAPI::submit_transactions_request::operator networking::REST::request() const { - return networking::REST::request{networking::HTTP::method::post, "/mapi/tx", - to_url_params(DefaultParameters), - {{networking::HTTP::header::content_type, "application/JSON"}}, - to_JSON(Submissions)}; + MAPI::submit_transactions_request::operator net::HTTP::REST::request () const { + return net::HTTP::REST::request{net::HTTP::method::post, "/mapi/tx", + to_url_params (DefaultParameters), + {{net::HTTP::header::content_type, "application/JSON"}}, + to_JSON (Submissions)}; } - MAPI::conflicted_with::operator JSON() const { + MAPI::conflicted_with::operator JSON () const { return JSON { - {"txid", to_JSON(TXID)}, + {"txid", to_JSON (TXID)}, {"size", Size}, - {"hex", encoding::hex::write(Transaction)} + {"hex", encoding::hex::write (Transaction)} }; } - MAPI::conflicted_with::conflicted_with(const JSON& j) : conflicted_with{} { + MAPI::conflicted_with::conflicted_with (const JSON& j) : conflicted_with {} { - if (!(j.is_object() && - j.contains("txid") && j["txid"].is_string() && - j.contains("size") && j["size"].is_number_unsigned() && - j.contains("hex") && j["hex"].is_string())) return; + if (!(j.is_object () && + j.contains ("txid") && j["txid"].is_string () && + j.contains ("size") && j["size"].is_number_unsigned () && + j.contains ("hex") && j["hex"].is_string ())) return; - auto tx = encoding::hex::read(string(j["hex"])); + auto tx = encoding::hex::read (string (j["hex"])); if (tx == nullptr) return; - TXID = digest256{string{"0x"} + string(j["txid"])}; - Size = uint64(j["size"]); + TXID = digest256 {string{"0x"} + string (j["txid"])}; + Size = uint64 (j["size"]); Transaction = *tx; } - MAPI::get_fee_quote_response::get_fee_quote_response(const JSON& j) : get_fee_quote_response{} { + MAPI::get_fee_quote_response::get_fee_quote_response (const JSON& j) : get_fee_quote_response {} { if (!(j.is_object() && - j.contains("apiVersion") && j["apiVersion"].is_string() && - j.contains("timestamp") && j["timestamp"].is_string() && - j.contains("expiryTime") && j["expiryTime"].is_string() && - j.contains("minerId") && j["minerId"].is_string() && - j.contains("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string() && - j.contains("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned() && - j.contains("fees") && j["fees"].is_array())) return; + j.contains ("apiVersion") && j["apiVersion"].is_string () && + j.contains ("timestamp") && j["timestamp"].is_string () && + j.contains ("expiryTime") && j["expiryTime"].is_string () && + j.contains ("minerId") && j["minerId"].is_string () && + j.contains ("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string () && + j.contains ("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned () && + j.contains ("fees") && j["fees"].is_array ())) return; map f; for (const JSON& jf : j["fees"]) { - if (!(jf.is_object() && - jf.contains("feeType") && jf["feeType"].is_string() && - jf.contains("miningFee") && jf.contains("relayFee"))) return; + if (!(jf.is_object () && + jf.contains ("feeType") && jf["feeType"].is_string () && + jf.contains ("miningFee") && jf.contains ("relayFee"))) return; - satoshi_per_byte mf = spb_from_JSON(jf["miningFee"]); + satoshi_per_byte mf = spb_from_JSON (jf["miningFee"]); - if (!mf.valid()) return; + if (!mf.valid ()) return; - satoshi_per_byte rf = spb_from_JSON(jf["relayFee"]); + satoshi_per_byte rf = spb_from_JSON (jf["relayFee"]); - if (!rf.valid()) return; + if (!rf.valid ()) return; - f = f.insert(jf["feeType"], MAPI::fee{mf, rf}); + f = f.insert (jf["feeType"], MAPI::fee {mf, rf}); } - auto pk_hex = encoding::hex::read(string(j["minerId"])); + auto pk_hex = encoding::hex::read (string (j["minerId"])); if (pk_hex == nullptr) return; - digest256 last_block{string{"0x"} + string(j["currentHighestBlockHash"])}; - if (!last_block.valid()) return; + digest256 last_block {string{"0x"} + string (j["currentHighestBlockHash"])}; + if (!last_block.valid ()) return; APIVersion = j["apiVersion"]; Timestamp = j["timestamp"]; ExpiryTime = j["expiryTime"]; - MinerID = secp256k1::pubkey{*pk_hex}; + MinerID = secp256k1::pubkey {*pk_hex}; CurrentHighestBlockHash = last_block; CurrentHighestBlockHeight = j["currentHighestBlockHeight"]; Fees = f; } - MAPI::get_fee_quote_response::operator JSON() const { + MAPI::get_fee_quote_response::operator JSON () const { std::stringstream ss; ss << CurrentHighestBlockHash; - return valid() ? JSON{ + return valid () ? JSON { {"apiVersion", APIVersion}, {"timestamp", Timestamp}, {"expiryTime", ExpiryTime}, - {"minerId", encoding::hex::write(MinerID)}, - {"currentHighestBlockHash", ss.str().substr(2)}, + {"minerId", encoding::hex::write (MinerID)}, + {"currentHighestBlockHash", ss.str ().substr (2)}, {"currentHighestBlockHeight", CurrentHighestBlockHeight}, - {"fees", to_JSON(Fees)}} : JSON{}; + {"fees", to_JSON (Fees)}} : JSON {}; } - MAPI::get_policy_quote_response::get_policy_quote_response(const JSON &j) : get_fee_quote_response{} { + MAPI::get_policy_quote_response::get_policy_quote_response (const JSON &j) : get_fee_quote_response {} { - if (!j.contains("callbacks") || !j.contains("policies")) return; + if (!j.contains ("callbacks") || !j.contains ("policies")) return; - get_fee_quote_response parent{j}; - if (!parent.valid()) return; + get_fee_quote_response parent {j}; + if (!parent.valid ()) return; - auto ips = read_ip_address_list(j["callbacks"]); - if (!bool(ips)) return; + auto ips = read_ip_address_list (j["callbacks"]); + if (!bool (ips)) return; - static_cast(*this) = parent; + static_cast (*this) = parent; Policies = j["policies"]; Callbacks = *ips; } - MAPI::get_policy_quote_response::operator JSON() const { - JSON j = get_fee_quote_response::operator JSON(); + MAPI::get_policy_quote_response::operator JSON () const { + JSON j = get_fee_quote_response::operator JSON (); if (j == nullptr) return nullptr; - j["callbacks"] = ip_addresses_to_JSON(Callbacks); - j["policies"] = JSON(Policies); + j["callbacks"] = ip_addresses_to_JSON (Callbacks); + j["policies"] = JSON (Policies); return j; } - MAPI::submit_transaction_response::submit_transaction_response(const JSON& j) : - submit_transaction_response{} { + MAPI::submit_transaction_response::submit_transaction_response (const JSON& j) : + submit_transaction_response {} { - if (!(j.is_object() && - j.contains("apiVersion") && j["apiVersion"].is_string() && - j.contains("timestamp") && j["timestamp"].is_string() && - j.contains("minerId") && j["minerId"].is_string() && - j.contains("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string() && - j.contains("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned() && - j.contains("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned())) return; + if (!(j.is_object () && + j.contains ("apiVersion") && j["apiVersion"].is_string () && + j.contains ("timestamp") && j["timestamp"].is_string () && + j.contains ("minerId") && j["minerId"].is_string () && + j.contains ("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string () && + j.contains ("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned () && + j.contains ("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned ())) return; - transaction_status sub = read_transaction_status(j); + transaction_status sub = read_transaction_status (j); - if (!sub.valid()) return; + if (!sub.valid ()) return; - auto pk_hex = encoding::hex::read(string(j["minerId"])); + auto pk_hex = encoding::hex::read (string (j["minerId"])); if (pk_hex == nullptr) return; - digest256 block_hash{string{"0x"} + string(j["currentHighestBlockHash"])}; - if (!block_hash.valid()) return; + digest256 block_hash {string{"0x"} + string (j["currentHighestBlockHash"])}; + if (!block_hash.valid ()) return; APIVersion = j["apiVersion"]; Timestamp = j["timestamp"]; - MinerID = secp256k1::pubkey{*pk_hex}; + MinerID = secp256k1::pubkey {*pk_hex}; CurrentHighestBlockHash = block_hash; CurrentHighestBlockHeight = j["currentHighestBlockHeight"]; - TxSecondMempoolExpiry = uint32(j["txSecondMempoolExpiry"]); - static_cast(*this) = sub; + TxSecondMempoolExpiry = uint32 (j["txSecondMempoolExpiry"]); + static_cast (*this) = sub; } - MAPI::submit_transaction_response::operator JSON() const { - if (!valid()) return nullptr; + MAPI::submit_transaction_response::operator JSON () const { + if (!valid ()) return nullptr; - JSON j = to_JSON(static_cast(*this)); + JSON j = to_JSON (static_cast (*this)); std::stringstream ss; ss << CurrentHighestBlockHash; j["apiVersion"] = APIVersion; j["timestamp"] = Timestamp; - j["minerId"] = encoding::hex::write(MinerID); - j["currentHighestBlockHash"] = ss.str().substr(2); + j["minerId"] = encoding::hex::write (MinerID); + j["currentHighestBlockHash"] = ss.str ().substr (2); j["currentHighestBlockHeight"] = CurrentHighestBlockHeight; j["txSecondMempoolExpiry"] = TxSecondMempoolExpiry; return j; } - MAPI::transaction_status::operator JSON() const { + MAPI::transaction_status::operator JSON () const { JSON j { - {"txid", to_JSON(TXID) }, - {"returnResult", to_JSON(ReturnResult) }, + {"txid", to_JSON (TXID) }, + {"returnResult", to_JSON (ReturnResult) }, {"resultDescription", ResultDescription } }; - if (ConflictedWith.size() > 0) j["conflictedWith"] = to_JSON(ConflictedWith); + if (ConflictedWith.size () > 0) j["conflictedWith"] = to_JSON (ConflictedWith); return j; } - MAPI::transaction_status_response::transaction_status_response(const JSON& j) : - transaction_status_response{} { - - if (!(j.is_object() && - j.contains("apiVersion") && j["apiVersion"].is_string() && - j.contains("timestamp") && j["timestamp"].is_string() && - j.contains("blockHash") && j["blockHash"].is_string() && - j.contains("blockHeight") && j["blockHeight"].is_number_unsigned() && - j.contains("minerId") && j["minerId"].is_string() && - (!j.contains("confirmations") || j["confirmations"].is_number_unsigned()) && - j.contains("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned())) return; - - transaction_status sub = read_transaction_status(j); - if (!sub.valid()) return; - - auto pk_hex = encoding::hex::read(string(j["minerId"])); + MAPI::transaction_status_response::transaction_status_response (const JSON& j) : + transaction_status_response {} { + + if (!(j.is_object () && + j.contains ("apiVersion") && j["apiVersion"].is_string () && + j.contains ("timestamp") && j["timestamp"].is_string () && + j.contains("blockHash") && j["blockHash"].is_string () && + j.contains ("blockHeight") && j["blockHeight"].is_number_unsigned () && + j.contains("minerId") && j["minerId"].is_string () && + (!j.contains ("confirmations") || j["confirmations"].is_number_unsigned ()) && + j.contains ("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned ())) return; + + transaction_status sub = read_transaction_status (j); + if (!sub.valid ()) return; + + auto pk_hex = encoding::hex::read (string (j["minerId"])); if (pk_hex == nullptr) return; - digest256 block_hash{string{"0x"} + string(j["blockHash"])}; - if (!block_hash.valid()) return; + digest256 block_hash {string{"0x"} + string (j["blockHash"])}; + if (!block_hash.valid ()) return; - MinerID = secp256k1::pubkey{*pk_hex}; + MinerID = secp256k1::pubkey {*pk_hex}; BlockHash = block_hash; - static_cast(*this) = sub; + static_cast (*this) = sub; APIVersion = j["apiVersion"]; Timestamp = j["timestamp"]; BlockHeight = j["blockHeight"]; - TxSecondMempoolExpiry = uint32(j["txSecondMempoolExpiry"]); + TxSecondMempoolExpiry = uint32 (j["txSecondMempoolExpiry"]); - if (j.contains("confirmations")) Confirmations = uint64(j["confirmations"]); + if (j.contains ("confirmations")) Confirmations = uint64 (j["confirmations"]); } - MAPI::transaction_status_response::operator JSON() const { - if (!valid()) return nullptr; + MAPI::transaction_status_response::operator JSON () const { + if (!valid ()) return nullptr; - JSON j = to_JSON(static_cast(*this)); + JSON j = to_JSON (static_cast (*this)); j["apiVersion"] = APIVersion; j["timestamp"] = Timestamp; - j["minerId"] = encoding::hex::write(MinerID); + j["minerId"] = encoding::hex::write (MinerID); j["txSecondMempoolExpiry"] = TxSecondMempoolExpiry; - if (Confirmations.has_value()) j["confirmations"] = *Confirmations; + if (Confirmations.has_value ()) j["confirmations"] = *Confirmations; return j; } - MAPI::submit_transactions_response::submit_transactions_response(const JSON& j) : - submit_transactions_response{} { - - if (!(j.is_object() && - j.contains("apiVersion") && j["apiVersion"].is_string() && - j.contains("timestamp") && j["timestamp"].is_string() && - j.contains("minerId") && j["minerId"].is_string() && - j.contains("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string() && - j.contains("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned() && - j.contains("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned() && - j.contains("txs") && j["txs"].is_array() && - j.contains("failureCount") && j["failureCount"].is_number_unsigned())) return; + MAPI::submit_transactions_response::submit_transactions_response (const JSON& j) : + submit_transactions_response {} { + + if (!(j.is_object () && + j.contains ("apiVersion") && j["apiVersion"].is_string () && + j.contains ("timestamp") && j["timestamp"].is_string () && + j.contains ("minerId") && j["minerId"].is_string () && + j.contains ("currentHighestBlockHash") && j["currentHighestBlockHash"].is_string () && + j.contains ("currentHighestBlockHeight") && j["currentHighestBlockHeight"].is_number_unsigned () && + j.contains ("txSecondMempoolExpiry") && j["txSecondMempoolExpiry"].is_number_unsigned () && + j.contains ("txs") && j["txs"].is_array () && + j.contains ("failureCount") && j["failureCount"].is_number_unsigned ())) return; list sr; for (const JSON& w : j["txs"]) { sr = sr << read_transaction_status(w); - if (!sr.first().valid()) return; + if (!sr.first ().valid ()) return; } - auto pk_hex = encoding::hex::read(string(j["minerId"])); + auto pk_hex = encoding::hex::read (string (j["minerId"])); if (pk_hex == nullptr) return; - digest256 block_hash{string{"0x"} + string(j["blockHash"])}; - if (!block_hash.valid()) return; + digest256 block_hash {string {"0x"} + string (j["blockHash"])}; + if (!block_hash.valid ()) return; - MinerID = secp256k1::pubkey{*pk_hex}; + MinerID = secp256k1::pubkey {*pk_hex}; CurrentHighestBlockHash = block_hash; APIVersion = j["apiVersion"]; Timestamp = j["timestamp"]; CurrentHighestBlockHeight = j["currentHighestBlockHeight"]; - TxSecondMempoolExpiry = uint32(j["txSecondMempoolExpiry"]); + TxSecondMempoolExpiry = uint32 (j["txSecondMempoolExpiry"]); Transactions = sr; - FailureCount = uint32(j["failureCount"]); + FailureCount = uint32 (j["failureCount"]); } - MAPI::submit_transactions_response::operator JSON() const { + MAPI::submit_transactions_response::operator JSON () const { std::stringstream ss; ss << CurrentHighestBlockHash; JSON::array_t txs; - txs.resize(Transactions.size()); + txs.resize (Transactions.size ()); int i = 0; - for (const transaction_status &status : Transactions) txs[i++] = JSON(status); + for (const transaction_status &status : Transactions) txs[i++] = JSON (status); - return valid() ? JSON{ + return valid () ? JSON{ {"apiVersion", APIVersion }, {"timestamp", Timestamp }, - {"minerId", encoding::hex::write(MinerID) }, - {"currentHighestBlockHash", ss.str().substr(2) }, + {"minerId", encoding::hex::write (MinerID) }, + {"currentHighestBlockHash", ss.str ().substr (2) }, {"currentHighestBlockHeight", CurrentHighestBlockHeight }, {"txSecondMempoolExpiry", TxSecondMempoolExpiry }, {"txs", txs }, - {"failureCount", FailureCount}} : JSON{}; + {"failureCount", FailureCount}} : JSON {}; } } diff --git a/src/gigamonkey/stratum/client_session.cpp b/src/gigamonkey/stratum/client_session.cpp index b19d2f4b..e532c19b 100644 --- a/src/gigamonkey/stratum/client_session.cpp +++ b/src/gigamonkey/stratum/client_session.cpp @@ -3,78 +3,78 @@ namespace Gigamonkey::Stratum { - void client_session::receive_notification(const notification &n) { - if (mining::notify::valid(n)) return receive_notify(mining::notify{n}.params()); - if (mining::set_difficulty::valid(n)) return receive_set_difficulty(mining::set_difficulty{n}.params()); - if (mining::set_extranonce::valid(n)) return receive_set_extranonce(mining::set_extranonce{n}.params()); - if (mining::set_version_mask::valid(n)) return receive_set_version_mask(mining::set_version_mask{n}.params()); - if (client::show_message::valid(n)) return receive_show_message(client::show_message{n}.params()); - throw exception{} << "unknown notification received: " + n.dump(); + void client_session::receive_notification (const notification &n) { + if (mining::notify::valid (n)) return receive_notify (mining::notify {n}.params ()); + if (mining::set_difficulty::valid (n)) return receive_set_difficulty (mining::set_difficulty {n}.params ()); + if (mining::set_extranonce::valid (n)) return receive_set_extranonce (mining::set_extranonce {n}.params ()); + if (mining::set_version_mask::valid (n)) return receive_set_version_mask (mining::set_version_mask {n}.params ()); + if (client::show_message::valid (n)) return receive_show_message (client::show_message {n}.params ()); + throw exception{} << "unknown notification received: " + n.dump (); } - void client_session::receive_request(const Stratum::request &r) { - if (client::get_version_request::valid(r)) - return JSON_line_session::send(client::get_version_response{r.id(), Options.Version}); + void client_session::receive_request (const Stratum::request &r) { + if (client::get_version_request::valid (r)) + return this->Send->send (client::get_version_response {r.id (), Options.Version}); - JSON_line_session::send(response{r.id(), nullptr, error{ILLEGAL_METHOD}}); + this->Send->send (response {r.id (), nullptr, error {ILLEGAL_METHOD}}); - throw exception{} << "unknown request received: " << r; + throw exception {} << "unknown request received: " << r; } - void client_session::receive_response(method m, const Stratum::response &r) { + void client_session::receive_response (method m, const Stratum::response &r) { switch (m) { case mining_configure : { - if (r.error()) receive_configure_error(*r.error()); - else receive_configure(extensions::results(mining::configure_response::result(r))); + if (r.error ()) receive_configure_error (*r.error ()); + else receive_configure(extensions::results (mining::configure_response::result (r))); } break; case mining_authorize : { - if (r.error()) receive_authorize_error(*r.error()); + if (r.error ()) receive_authorize_error (*r.error ()); else { - if (!mining::authorize_response::valid(r)) - throw exception{} << "invalid authorization response received: " << r; + if (!mining::authorize_response::valid (r)) + throw exception {} << "invalid authorization response received: " << r; - receive_authorize(mining::authorize_response{r}.result()); + receive_authorize (mining::authorize_response {r}.result ()); } } break; case mining_subscribe : { - if (r.error()) receive_subscribe_error(*r.error()); - else receive_subscribe(mining::subscribe_response::deserialize(r.result())); + if (r.error ()) receive_subscribe_error (*r.error ()); + else receive_subscribe (mining::subscribe_response::deserialize (r.result ())); } break; case mining_submit : { - if (r.error()) receive_submit(false); - else receive_submit(r.result()); + if (r.error ()) receive_submit (false); + else receive_submit (r.result ()); } break; - default: throw exception{"Invalid method returned? Should not be possible."}; + default: throw exception {"Invalid method returned? Should not be possible."}; } } - void client_session::receive_configure(const extensions::results &r) { + void client_session::receive_configure (const extensions::results &r) { - if (!Options.ConfigureRequest) throw exception{} << "configure response returned without knowing what was requested."; + if (!Options.ConfigureRequest) throw exception {} << "configure response returned without knowing what was requested."; auto q = *Options.ConfigureRequest; - if (!mining::configure_response::valid_result(r, q)) - throw exception{} << "invalid configure response received. "; + if (!mining::configure_response::valid_result (r, q)) + throw exception {} << "invalid configure response received. "; - if (auto configuration = q.get(); bool(configuration)) { + if (auto configuration = q.get (); bool (configuration)) { - auto result = r.contains("version-rolling"); + auto result = r.contains ("version-rolling"); if (result) std::cout << "no response received."; else { std::cout << "response = " << *result << std::endl; if (result->Accepted) { - auto x = extensions::configured::read(result->Parameters); - if (x) receive_set_version_mask(x->Mask); + auto x = extensions::configured::read (result->Parameters); + if (x) receive_set_version_mask (x->Mask); else std::cout << "invalid version-rolling response received: " << result->Parameters << std::endl; } } } - if (auto configuration = q.get(); bool(configuration)) { + if (auto configuration = q.get (); bool (configuration)) { - auto result = r.contains("minimum-difficulty"); + auto result = r.contains ("minimum-difficulty"); if (result) std::cout << "no response received."; else { @@ -82,16 +82,16 @@ namespace Gigamonkey::Stratum { } } - if (auto configuration = q.get(); bool(configuration)) { + if (auto configuration = q.get (); bool (configuration)) { std::cout << q["subscribe-extranonce"] << " requested; "; - auto result = r.contains("subscribe-extranonce"); + auto result = r.contains ("subscribe-extranonce"); if (result) std::cout << "no response received." ; else std::cout << "response = " << *result << std::endl; } - if (auto configuration = q.get(); bool(configuration)) { + if (auto configuration = q.get (); bool (configuration)) { std::cout << q["info"] << " requested; "; auto result = r.contains("info"); @@ -103,7 +103,7 @@ namespace Gigamonkey::Stratum { ExtensionResults = r; } - void client_session::receive_authorize(bool r) { + void client_session::receive_authorize (bool r) { std::cout << (r ? "authorization successful!" : "authorization failed!") << std::endl; if (r) Authorized = true; } diff --git a/src/gigamonkey/stratum/remote.cpp b/src/gigamonkey/stratum/remote.cpp index 10793bfd..736799c3 100644 --- a/src/gigamonkey/stratum/remote.cpp +++ b/src/gigamonkey/stratum/remote.cpp @@ -5,39 +5,37 @@ namespace Gigamonkey::Stratum { - void remote::receive(const JSON &next) { - if (notification::valid(next)) { - receive_notification(notification{next}); + void remote_receive_handler::operator () (const JSON &next) { + if (notification::valid (next)) { + receive_notification (notification {next}); return; } - if (response::valid(next)) { + if (response::valid (next)) { method m; - response r{next}; + response r {next}; { - guard lock(Mutex); - auto x = Request.find(r.id()); - if (x == Request.end()) throw exception{"response with unknown message id returned"}; + auto x = Request.find (r.id ()); + if (x == Request.end ()) throw exception{"response with unknown message id returned"}; m = x->second; - Request.erase(x); + Request.erase (x); } - receive_response(m, r); + receive_response (m, r); return; } - if (Stratum::request::valid(next)) { - receive_request(Stratum::request{next}); + if (Stratum::request::valid (next)) { + receive_request (Stratum::request {next}); return; } - throw exception{} << "invalid Stratum message received: " << next.dump(); + throw exception {} << "invalid Stratum message received: " << next.dump (); } - request_id remote::send_request(method m, parameters p) { - guard lock(Mutex); - message_id id(Requests); - JSON_line_session::send(Stratum::request{id, m, p}); + request_id remote_receive_handler::send_request (method m, parameters p) { + message_id id (Requests); + Send->send (Stratum::request {id, m, p}); Request[id] = m; return Requests++; } diff --git a/src/gigamonkey/stratum/server_session.cpp b/src/gigamonkey/stratum/server_session.cpp index 90e77709..644202e5 100644 --- a/src/gigamonkey/stratum/server_session.cpp +++ b/src/gigamonkey/stratum/server_session.cpp @@ -5,56 +5,56 @@ namespace Gigamonkey::Stratum { - bool server_session::state::set_difficulty(const Stratum::difficulty& d) { - if (!subscribed()) throw exception{"Cannot set difficulty before client is subscribed"}; - if (bool(MinimumDifficulty) && d < *MinimumDifficulty) return false; + bool server_session::state::set_difficulty (const Stratum::difficulty& d) { + if (!subscribed ()) throw exception {"Cannot set difficulty before client is subscribed"}; + if (bool (MinimumDifficulty) && d < *MinimumDifficulty) return false; if (d == NextDifficulty) return false; NextDifficulty = d; return true; } - bool server_session::state::set_extranonce(const Stratum::extranonce &n) { - if (!subscribed()) throw exception{"Cannot set extra nonce before client is subscribed"}; + bool server_session::state::set_extranonce (const Stratum::extranonce &n) { + if (!subscribed ()) throw exception {"Cannot set extra nonce before client is subscribed"}; if (NextExtranonce == n || (NextExtranonce == Stratum::extranonce{} && Extranonce == n)) return false; NextExtranonce = n; return true; } // return value is whether the version mask has changed. - bool server_session::state::set_version_mask(const extensions::version_mask &x) { - auto current = version_mask(); + bool server_session::state::set_version_mask (const extensions::version_mask &x) { + auto current = version_mask (); if (bool(current) && *current == x) return false; - VersionRollingMaskParameters.set(x); + VersionRollingMaskParameters.set (x); return true; } - void server_session::receive_response(method m, const Stratum::response &r) { + void server_session::receive_response (method m, const Stratum::response &r) { if (m != client_get_version) - throw exception{} << "unknown response returned: " << method_to_string(m) << "; " << r.dump(); + throw exception {} << "unknown response returned: " << method_to_string (m) << "; " << r.dump (); - if (!client::get_version_response::valid(r)) - throw exception{} << "invalid get_version response received: " << r; + if (!client::get_version_response::valid (r)) + throw exception {} << "invalid get_version response received: " << r; - string client_version = client::get_version_response{r}.result(); - State.set_client_version(client_version); - receive_get_version(client_version); + string client_version = client::get_version_response {r}.result (); + State.set_client_version (client_version); + receive_get_version (client_version); } // authorize the client to the server. // this is the original first method of the protocol. mining::authorize_response server_session::authorize(const mining::authorize_request &r) { - if (!r.valid()) return response{r.id(), nullptr, error{ILLEGAL_PARAMS}}; + if (!r.valid ()) return response {r.id (), nullptr, error {ILLEGAL_PARAMS}}; - if (State.authorized()) return response{r.id(), false, error{ILLEGAL_METHOD}}; + if (State.authorized ()) return response {r.id (), false, error {ILLEGAL_METHOD}}; - auto authorization = authorize(r.params()); + auto authorization = authorize (r.params ()); if (authorization) { - State.set_name(r.params().Username); - return mining::authorize_response{r.id(), true}; + State.set_name (r.params ().Username); + return mining::authorize_response {r.id (), true}; } - return mining::authorize_response{r.id(), *authorization}; + return mining::authorize_response {r.id (), *authorization}; } /* // generate a configure response from a configure request message. From 9f68ad2fa914e3bb81a6bb3cd02b952490b6eca5 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Thu, 2 Feb 2023 18:18:10 -0500 Subject: [PATCH 02/11] Update conanfile --- conanfile.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index aa943eb8..e984b74b 100644 --- a/conanfile.py +++ b/conanfile.py @@ -14,7 +14,15 @@ class GigamonkeyConan(ConanFile): default_options = {"shared": False, "fPIC": True} generators = "cmake" exports_sources = "*" - requires = "boost/1.81.0", "openssl/1.1.1k", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "SECP256K1/0.2.0@proofofwork/stable", "data/v0.0.25@proofofwork/stable", "gtest/1.12.1" + requires = [ + "boost/1.80.0", + "openssl/1.1.1k", + "cryptopp/8.5.0", + "nlohmann_json/3.10.0", + "gmp/6.2.1", + "SECP256K1/0.2.0@proofofwork/stable", + "data/v0.0.25@proofofwork/stable", + "gtest/1.12.1"] def set_version(self): if "CIRCLE_TAG" in environ: From 7b2efc7d10a62a1df977058cd6928ce760c1429e Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Fri, 24 Feb 2023 21:27:51 -0500 Subject: [PATCH 03/11] formatting Formatting changes --- CMakeLists.txt | 40 +-- conanfile.py | 36 +-- include/gigamonkey/boost/boost.hpp | 7 +- include/gigamonkey/mapi/mapi.hpp | 4 +- include/gigamonkey/timechain.hpp | 358 ++++++++++++------------ src/gigamonkey/boost/boost.cpp | 8 +- src/gigamonkey/timestamp.cpp | 10 +- test/testStratum.cpp | 432 ++++++++++++++++------------- 8 files changed, 474 insertions(+), 421 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88372f5f..ef47e101 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,33 +1,33 @@ -cmake_minimum_required(VERSION 3.1...3.14) +cmake_minimum_required (VERSION 3.1...3.14) # Back compatibility for VERSION range -if(${CMAKE_VERSION} VERSION_LESS 3.12) - cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -endif() +if (${CMAKE_VERSION} VERSION_LESS 3.12) + cmake_policy (VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +endif () -project(gigamonkey VERSION 0.0.12 +project (gigamonkey VERSION 0.0.13 DESCRIPTION "open-source Bitcoin library in c++" LANGUAGES CXX) # Set cmake as import path for Find*.cmake files -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGETS) +include (${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup (TARGETS) ## Check if GTests is installed. If not, install it -option(PACKAGE_TESTS "Build the tests" ON) +option (PACKAGE_TESTS "Build the tests" ON) ## Enable testing -if(PACKAGE_TESTS) - include(CTest) - find_package(GTest REQUIRED) - enable_testing() - add_subdirectory(test) -endif() +if (PACKAGE_TESTS) + include (CTest) + find_package (GTest REQUIRED) + enable_testing () + add_subdirectory (test) +endif () -add_library(gigamonkey STATIC +add_library (gigamonkey STATIC src/sv/random.cpp src/sv/big_int.cpp @@ -88,12 +88,12 @@ add_library(gigamonkey STATIC ) -target_link_libraries(gigamonkey PUBLIC CONAN_PKG::data util CONAN_PKG::boost CONAN_PKG::openssl CONAN_PKG::cryptopp CONAN_PKG::nlohmann_json CONAN_PKG::gmp ) +target_link_libraries (gigamonkey PUBLIC CONAN_PKG::data util CONAN_PKG::boost CONAN_PKG::openssl CONAN_PKG::cryptopp CONAN_PKG::nlohmann_json CONAN_PKG::gmp ) -target_include_directories(gigamonkey PUBLIC include) +target_include_directories (gigamonkey PUBLIC include) # Set C++ version -target_compile_features(gigamonkey PUBLIC cxx_std_20) -set_target_properties(gigamonkey PROPERTIES CXX_EXTENSIONS ON) -target_compile_options(gigamonkey PUBLIC "-fconcepts") +target_compile_features (gigamonkey PUBLIC cxx_std_20) +set_target_properties (gigamonkey PROPERTIES CXX_EXTENSIONS ON) +target_compile_options (gigamonkey PUBLIC "-fconcepts") diff --git a/conanfile.py b/conanfile.py index e984b74b..6b0adeed 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,7 +1,7 @@ from conans import ConanFile, CMake from os import environ -class GigamonkeyConan(ConanFile): +class GigamonkeyConan (ConanFile): name = "Gigamonkey" version = "v0.0.13" license = "Open BSV" @@ -24,40 +24,40 @@ class GigamonkeyConan(ConanFile): "data/v0.0.25@proofofwork/stable", "gtest/1.12.1"] - def set_version(self): + def set_version (self): if "CIRCLE_TAG" in environ: - self.version = environ.get("CIRCLE_TAG")[1:] + self.version = environ.get ("CIRCLE_TAG")[1:] if "CURRENT_VERSION" in environ: self.version = environ['CURRENT_VERSION'] else: self.version = "v0.0.13" - def config_options(self): + def config_options (self): if self.settings.os == "Windows": del self.options.fPIC - def configure_cmake(self): + def configure_cmake (self): if "CMAKE_BUILD_CORES_COUNT" in environ: - cmake = CMake(self, parallel=False) + cmake = CMake (self, parallel=False) else: - cmake = CMake(self) + cmake = CMake (self) cmake.definitions["PACKAGE_TESTS"] = "Off" - cmake.configure() + cmake.configure () return cmake - def build(self): - cmake = self.configure_cmake() + def build (self): + cmake = self.configure_cmake () if "CMAKE_BUILD_CORES_COUNT" in environ: - cmake.build(args=["--", environ.get("CMAKE_BUILD_CORES_COUNT")]) + cmake.build (args=["--", environ.get ("CMAKE_BUILD_CORES_COUNT")]) else: - cmake.build() + cmake.build () - def package(self): - self.copy("*.h", dst="include", src="include") - self.copy("*.hpp", dst="include", src="include") - self.copy("libgigamonkey.a", src="lib", dst="lib", keep_path=False) + def package (self): + self.copy ("*.h", dst="include", src="include") + self.copy ("*.hpp", dst="include", src="include") + self.copy ("libgigamonkey.a", src="lib", dst="lib", keep_path=False) - def package_info(self): + def package_info (self): self.cpp_info.libdirs = ["lib"] # Default value is 'lib' - self.cpp_info.libs = self.collect_libs() + self.cpp_info.libs = self.collect_libs () # self.cpp_info.libs = ["gigamonkey"] diff --git a/include/gigamonkey/boost/boost.hpp b/include/gigamonkey/boost/boost.hpp index 42d33ace..fea4f247 100644 --- a/include/gigamonkey/boost/boost.hpp +++ b/include/gigamonkey/boost/boost.hpp @@ -286,6 +286,7 @@ namespace Gigamonkey { output (); output (Bitcoin::satoshi v, const output_script &x); output (const Bitcoin::output &b); + output (Bitcoin::satoshi v, const output_script &x, const digest256 &id); bool valid () const; @@ -777,8 +778,10 @@ namespace Gigamonkey { inline output::output () : Value {-1}, Script {}, ID {} {} - inline output::output (Bitcoin::satoshi v, const output_script &x) : - Value {v}, Script {x}, ID {Script.hash ()} {} + inline output::output (Bitcoin::satoshi v, const output_script &x) : output {v, x, x.hash ()} {} + + inline output::output (Bitcoin::satoshi v, const output_script &x, const digest256& script_hash) : + Value {v}, Script {x}, ID {script_hash} {} inline output::output (const Bitcoin::output &b) : Value {b.Value}, Script {Boost::output_script::read (b.Script)}, ID {Script.hash ()} {} diff --git a/include/gigamonkey/mapi/mapi.hpp b/include/gigamonkey/mapi/mapi.hpp index 639f512d..149ef61c 100644 --- a/include/gigamonkey/mapi/mapi.hpp +++ b/include/gigamonkey/mapi/mapi.hpp @@ -13,8 +13,8 @@ namespace Gigamonkey::BitcoinAssociation { - struct MAPI : net::HTTP::client { - using net::HTTP::client::client; + struct MAPI : net::HTTP::client_blocking { + using net::HTTP::client_blocking::client_blocking; // there are five calls in MAPI diff --git a/include/gigamonkey/timechain.hpp b/include/gigamonkey/timechain.hpp index 3cbc2e33..d3fa445e 100644 --- a/include/gigamonkey/timechain.hpp +++ b/include/gigamonkey/timechain.hpp @@ -17,79 +17,79 @@ namespace Gigamonkey::Bitcoin { struct outpoint; - bool operator==(const outpoint&, const outpoint&); + bool operator == (const outpoint&, const outpoint&); - bool operator>(const outpoint&, const outpoint&); - bool operator<(const outpoint&, const outpoint&); - bool operator>=(const outpoint&, const outpoint&); - bool operator<=(const outpoint&, const outpoint&); + bool operator > (const outpoint&, const outpoint&); + bool operator < (const outpoint&, const outpoint&); + bool operator >= (const outpoint&, const outpoint&); + bool operator <= (const outpoint&, const outpoint&); - writer &operator<<(writer &w, const outpoint& h); - reader &operator>>(reader &r, outpoint& h); + writer &operator << (writer &w, const outpoint& h); + reader &operator >> (reader &r, outpoint& h); - std::ostream &operator<<(std::ostream& o, const outpoint& p); + std::ostream &operator << (std::ostream& o, const outpoint& p); struct input; - bool operator==(const input&, const input&); + bool operator == (const input&, const input&); - writer &operator<<(writer &w, const input& h); - reader &operator>>(reader &r, input& h); + writer &operator << (writer &w, const input& h); + reader &operator >> (reader &r, input& h); - std::ostream &operator<<(std::ostream& o, const input& p); + std::ostream &operator << (std::ostream& o, const input& p); struct output; - bool operator==(const output&, const output&); + bool operator == (const output&, const output&); - writer &operator<<(writer &w, const output& h); - reader &operator>>(reader &r, output& h); + writer &operator << (writer &w, const output& h); + reader &operator >> (reader &r, output& h); - std::ostream &operator<<(std::ostream& o, const output& p); + std::ostream &operator << (std::ostream& o, const output& p); struct transaction; - bool operator==(const transaction&, const transaction&); + bool operator == (const transaction&, const transaction&); - writer &operator<<(writer &w, const transaction& h); - reader &operator>>(reader &r, transaction& h); + writer &operator << (writer &w, const transaction& h); + reader &operator >> (reader &r, transaction& h); - std::ostream &operator<<(std::ostream& o, const transaction& p); + std::ostream &operator << (std::ostream& o, const transaction& p); struct header; - bool operator==(const header& a, const header& b); + bool operator == (const header& a, const header& b); - bool operator>(const header&, const header&); - bool operator<(const header&, const header&); - bool operator>=(const header&, const header&); - bool operator<=(const header&, const header&); + bool operator > (const header&, const header&); + bool operator < (const header&, const header&); + bool operator >= (const header&, const header&); + bool operator <= (const header&, const header&); - writer &operator<<(writer &w, const header& h); - reader &operator>>(reader &r, header& h); + writer &operator << (writer &w, const header& h); + reader &operator >> (reader &r, header& h); - std::ostream &operator<<(std::ostream& o, const header& h); + std::ostream &operator << (std::ostream& o, const header& h); struct block; - bool operator==(const block&, const block&); + bool operator == (const block&, const block&); - writer &operator<<(writer &w, const block& h); - reader &operator>>(reader &r, block& h); + writer &operator << (writer &w, const block& h); + reader &operator >> (reader &r, block& h); - std::ostream &operator<<(std::ostream& o, const block& p); + std::ostream &operator << (std::ostream& o, const block& p); // The header is the first 80 bytes of a Bitcoin block. struct header { - static int32_little version(const slice<80>); - static digest256 previous(const slice<80> x); - static digest256 merkle_root(const slice<80> x); - static Bitcoin::timestamp timestamp(const slice<80>); - static Bitcoin::target target(const slice<80>); - static uint32_little nonce(const slice<80>); - static digest256 hash(const slice<80> h); - static bool valid(const slice<80> h); + static int32_little version (const slice<80>); + static digest256 previous (const slice<80> x); + static digest256 merkle_root (const slice<80> x); + static Bitcoin::timestamp timestamp (const slice<80>); + static Bitcoin::target target (const slice<80>); + static uint32_little nonce (const slice<80>); + static digest256 hash (const slice<80> h); + static bool valid (const slice<80> h); int32_little Version; digest256 Previous; @@ -98,42 +98,42 @@ namespace Gigamonkey::Bitcoin { Bitcoin::target Target; uint32_little Nonce; - header() : Version{}, Previous{}, MerkleRoot{}, Timestamp{}, Target{}, Nonce{} {} + header () : Version {}, Previous {}, MerkleRoot {}, Timestamp {}, Target {}, Nonce {} {} - header( + header ( int32_little v, digest256 p, digest256 mr, Bitcoin::timestamp ts, Bitcoin::target t, - uint32_little n) : Version{v}, Previous{p}, MerkleRoot{mr}, Timestamp{ts}, Target{t}, Nonce{n} {} + uint32_little n) : Version {v}, Previous {p}, MerkleRoot {mr}, Timestamp {ts}, Target {t}, Nonce {n} {} - explicit header(slice<80> x) : header { - version(x), - digest256{previous(x)}, - digest256{merkle_root(x)}, - Bitcoin::timestamp{timestamp(x)}, - Bitcoin::target{target(x)}, - nonce(x)} {} + explicit header (slice<80> x) : header { + version (x), + digest256 {previous (x)}, + digest256 {merkle_root (x)}, + Bitcoin::timestamp {timestamp (x)}, + Bitcoin::target {target (x)}, + nonce (x)} {} - byte_array<80> write() const; + byte_array<80> write () const; - digest256 hash() const { - return Hash256(write()); + digest256 hash () const { + return Hash256 (write ()); } - bool valid() const; + bool valid () const; - int16 version() const; - const transaction& coinbase() const; + int16 version () const; + const transaction& coinbase () const; }; // an outpoint is a reference to a previous output. struct outpoint { - static bool valid(slice<36>); - static Bitcoin::txid digest(slice<36>); - static Gigamonkey::index index(slice<36>); + static bool valid (slice<36>); + static Bitcoin::txid digest (slice<36>); + static Gigamonkey::index index (slice<36>); // the hash of a previous transaction. txid Digest; @@ -141,68 +141,68 @@ namespace Gigamonkey::Bitcoin { // Index of the previous output in the tx. Gigamonkey::index Index; - static outpoint coinbase() { - static outpoint Coinbase{txid{}, 0xffffffff}; + static outpoint coinbase () { + static outpoint Coinbase {txid {}, 0xffffffff}; return Coinbase; } }; struct input { - static bool valid(bytes_view); - static slice<36> previous(bytes_view); - static bytes_view script(bytes_view); - static uint32_little sequence(bytes_view); + static bool valid (bytes_view); + static slice<36> previous (bytes_view); + static bytes_view script (bytes_view); + static uint32_little sequence (bytes_view); outpoint Reference; Gigamonkey::script Script; uint32_little Sequence; - static constexpr uint32 Finalized{0xFFFFFFFF}; + static constexpr uint32 Finalized {0xFFFFFFFF}; - bool valid() const; + bool valid () const; - input() : Reference{}, Script{}, Sequence{} {} - input(const outpoint& o, const Gigamonkey::script& x, const uint32_little& z = Finalized) : - Reference{o}, Script{x}, Sequence{z} {} + input () : Reference {}, Script {}, Sequence {} {} + input (const outpoint& o, const Gigamonkey::script& x, const uint32_little& z = Finalized) : + Reference {o}, Script {x}, Sequence {z} {} - uint64 serialized_size() const; + uint64 serialized_size () const; }; struct output { - static bool valid(bytes_view b) { - return output{b}.valid(); + static bool valid (bytes_view b) { + return output {b}.valid (); } - static satoshi value(bytes_view); - static bytes_view script(bytes_view); + static satoshi value (bytes_view); + static bytes_view script (bytes_view); satoshi Value; Gigamonkey::script Script; - output() : Value{-1}, Script{} {} - output(satoshi v, const Gigamonkey::script& x) : Value{v}, Script{x} {} + output () : Value {-1}, Script {} {} + output (satoshi v, const Gigamonkey::script& x) : Value {v}, Script {x} {} - explicit output(bytes_view); - explicit operator bytes() const; + explicit output (bytes_view); + explicit operator bytes () const; - bool valid() const; + bool valid () const; - uint64 serialized_size() const; + uint64 serialized_size () const; }; struct transaction { - static bool valid(bytes_view); - static int32_little version(bytes_view); - static cross outputs(bytes_view); + static bool valid (bytes_view); + static int32_little version (bytes_view); + static cross outputs (bytes_view); static cross inputs(bytes_view); - static bytes_view output(bytes_view, index); - static bytes_view input(bytes_view, index); - static int32_little locktime(bytes_view); + static bytes_view output (bytes_view, index); + static bytes_view input (bytes_view, index); + static int32_little locktime (bytes_view); - static txid id(bytes_view); + static txid id (bytes_view); constexpr static int32 LatestVersion = 2; @@ -211,104 +211,104 @@ namespace Gigamonkey::Bitcoin { list Outputs; uint32_little Locktime; - transaction(int32_little v, list i, list o, uint32_little t = 0) : - Version{v}, Inputs{i}, Outputs{o}, Locktime{t} {} + transaction (int32_little v, list i, list o, uint32_little t = 0) : + Version {v}, Inputs {i}, Outputs {o}, Locktime {t} {} - transaction(list i, list o, uint32_little t = 0) : - transaction{int32_little{LatestVersion}, i, o, t} {} + transaction (list i, list o, uint32_little t = 0) : + transaction {int32_little {LatestVersion}, i, o, t} {} - transaction() : Version{}, Inputs{}, Outputs{}, Locktime{} {}; + transaction () : Version {}, Inputs {}, Outputs {}, Locktime {} {}; - explicit transaction(bytes_view b); + explicit transaction (bytes_view b); - bool valid() const; + bool valid () const; - explicit operator bytes() const; + explicit operator bytes () const; - txid id() const; + txid id () const; - uint64 serialized_size() const; + uint64 serialized_size () const; - uint32 sigops() const; + uint32 sigops () const; - satoshi sent() const { - return fold([](satoshi x, const Bitcoin::output& o) -> satoshi { + satoshi sent () const { + return fold ([] (satoshi x, const Bitcoin::output& o) -> satoshi { return x + o.Value; - }, satoshi{0}, Outputs); + }, satoshi {0}, Outputs); } }; - txid inline id(const transaction& t) { - return Hash256(bytes(t)); + txid inline id (const transaction& t) { + return Hash256 (bytes (t)); } - digest256 inline merkle_root(const list t) { - return Merkle::root(data::for_each(id, t)); + digest256 inline merkle_root (const list t) { + return Merkle::root (data::for_each (id, t)); } struct block { - static inline bool valid(bytes_view b) { - return block{b}.valid(); + static inline bool valid (bytes_view b) { + return block {b}.valid (); } - static const slice<80> header(bytes_view); - static std::vector transactions(bytes_view); + static const slice<80> header (bytes_view); + static std::vector transactions (bytes_view); - static digest256 inline merkle_root(bytes_view b) { - list ids{}; - for (bytes_view x : transactions(b)) ids = ids << Hash256(x); - return Merkle::root(ids); + static digest256 inline merkle_root (bytes_view b) { + list ids {}; + for (bytes_view x : transactions (b)) ids = ids << Hash256 (x); + return Merkle::root (ids); } Bitcoin::header Header; list Transactions; - block() : Header{}, Transactions{} {} + block () : Header {}, Transactions {} {} - bytes coinbase(); - bool valid() const { - if (!Header.valid()) return false; + bytes coinbase (); + bool valid () const { + if (!Header.valid ()) return false; list txs = Transactions; - while(!txs.empty()) { - if (!txs.first().valid()) return false; - txs = txs.rest(); + while(!txs.empty ()) { + if (!txs.first ().valid ()) return false; + txs = txs.rest (); } return true; } - explicit block(bytes_view b); + explicit block (bytes_view b); - explicit operator bytes() const; + explicit operator bytes () const; - uint64 serialized_size() const; + uint64 serialized_size () const; }; - bool inline operator==(const header& a, const header& b) { + bool inline operator == (const header& a, const header& b) { return a.Version == b.Version && a.Previous == b.Previous && a.MerkleRoot == b.MerkleRoot && a.Timestamp == b.Timestamp && a.Target == b.Target && a.Nonce == b.Nonce; } - bool inline operator==(const outpoint& a, const outpoint& b) { + bool inline operator == (const outpoint& a, const outpoint& b) { return a.Digest == b.Digest && a.Index == b.Index; } - bool inline operator==(const input& a, const input& b) { + bool inline operator == (const input& a, const input& b) { return a.Reference == b.Reference && a.Script == b.Script && a.Sequence == b.Sequence; } - bool inline operator==(const output& a, const output& b) { + bool inline operator == (const output& a, const output& b) { return a.Value == b.Value && a.Script == b.Script; } - bool inline operator==(const transaction& a, const transaction& b) { + bool inline operator == (const transaction& a, const transaction& b) { return a.Version == b.Version && a.Inputs == b.Inputs && a.Outputs == b.Outputs && a.Locktime == b.Locktime; } - bool inline operator==(const block& a, const block& b) { + bool inline operator == (const block& a, const block& b) { return a.Header == b.Header && a.Transactions == b.Transactions; } - std::ostream inline &operator<<(std::ostream& o, const header& h) { + std::ostream inline &operator << (std::ostream& o, const header& h) { return o << "header{Version : " << h.Version << ", Previous : " << h.Previous << ", MerkleRoot : " << h.MerkleRoot << @@ -317,128 +317,128 @@ namespace Gigamonkey::Bitcoin { ", Nonce : " << h.Nonce << "}"; } - std::ostream inline &operator<<(std::ostream& o, const outpoint& p) { + std::ostream inline &operator << (std::ostream& o, const outpoint& p) { return o << "outpoint{" << p.Digest << ":" << p.Index << "}"; } - std::ostream inline &operator<<(std::ostream& o, const input& p) { - return o << "input{Reference : " << p.Reference << ", Script : " << ASM(p.Script) << ", Sequence : " << p.Sequence << "}"; + std::ostream inline &operator << (std::ostream& o, const input& p) { + return o << "input{Reference : " << p.Reference << ", Script : " << ASM (p.Script) << ", Sequence : " << p.Sequence << "}"; } - std::ostream inline &operator<<(std::ostream& o, const output& p) { - return o << "output{Value : " << p.Value << ", Script : " << ASM(p.Script) << "}"; + std::ostream inline &operator << (std::ostream& o, const output& p) { + return o << "output{Value : " << p.Value << ", Script : " << ASM (p.Script) << "}"; } - std::ostream inline &operator<<(std::ostream& o, const transaction& p) { + std::ostream inline &operator << (std::ostream& o, const transaction& p) { return o << "transaction{Version : " << p.Version << ", Inputs : " << p.Inputs << ", Outputs: " << p.Outputs << ", " << p.Locktime << "}"; } - writer inline &operator<<(writer &w, const header &h) { + writer inline &operator << (writer &w, const header &h) { return w << h.Version << h.Previous << h.MerkleRoot << h.Timestamp << h.Target << h.Nonce; } - reader inline &operator>>(reader &r, header &h) { + reader inline &operator >> (reader &r, header &h) { return r >> h.Version >> h.Previous >> h.MerkleRoot >> h.Timestamp >> h.Target >> h.Nonce; } - writer inline &operator<<(writer &w, const outpoint &o) { + writer inline &operator << (writer &w, const outpoint &o) { return w << o.Digest << o.Index; } - reader inline &operator>>(reader &r, outpoint &o) { + reader inline &operator >> (reader &r, outpoint &o) { return r >> o.Digest >> o.Index; } - reader inline &operator>>(reader &r, input &in) { - return r >> in.Reference >> var_string{in.Script} >> in.Sequence; + reader inline &operator >> (reader &r, input &in) { + return r >> in.Reference >> var_string {in.Script} >> in.Sequence; } - writer inline &operator<<(writer &w, const input &in) { - return w << in.Reference << var_string{in.Script} << in.Sequence; + writer inline &operator << (writer &w, const input &in) { + return w << in.Reference << var_string {in.Script} << in.Sequence; } - reader inline &operator>>(reader &r, output &out) { - return r >> out.Value >> var_string{out.Script}; + reader inline &operator >> (reader &r, output &out) { + return r >> out.Value >> var_string {out.Script}; } - writer inline &operator<<(writer &w, const output &out) { - return w << out.Value << var_string{out.Script}; + writer inline &operator << (writer &w, const output &out) { + return w << out.Value << var_string {out.Script}; } - reader inline &operator>>(reader &r, transaction &t) { - return r >> t.Version >> var_sequence{t.Inputs} >> var_sequence{t.Outputs} >> t.Locktime; + reader inline &operator >> (reader &r, transaction &t) { + return r >> t.Version >> var_sequence {t.Inputs} >> var_sequence {t.Outputs} >> t.Locktime; } - writer inline &operator<<(writer &w, const transaction &t) { - return w << t.Version << var_sequence{t.Inputs} << var_sequence{t.Outputs} << t.Locktime; + writer inline &operator << (writer &w, const transaction &t) { + return w << t.Version << var_sequence {t.Inputs} << var_sequence {t.Outputs} << t.Locktime; } - reader inline &operator>>(reader &r, block &b) { - return r >> b.Header >> var_sequence{b.Transactions}; + reader inline &operator >> (reader &r, block &b) { + return r >> b.Header >> var_sequence {b.Transactions}; } - writer inline &operator<<(writer &w, const block &b) { - return w << b.Header << var_sequence{b.Transactions}; + writer inline &operator << (writer &w, const block &b) { + return w << b.Header << var_sequence {b.Transactions}; } - digest256 inline header::previous(const slice<80> x) { - return digest256(x.range<4, 36>()); + digest256 inline header::previous (const slice<80> x) { + return digest256 (x.range<4, 36> ()); } - digest256 inline header::merkle_root(const slice<80> x) { - return digest256(x.range<36, 68>()); + digest256 inline header::merkle_root (const slice<80> x) { + return digest256 (x.range<36, 68> ()); } - digest256 inline header::hash(const slice<80> h) { - return Bitcoin::Hash256(h); + digest256 inline header::hash (const slice<80> h) { + return Bitcoin::Hash256 (h); } - txid inline transaction::id() const { - return Bitcoin::id(*this); + txid inline transaction::id () const { + return Bitcoin::id (*this); } - inline bool operator>(const outpoint& a, const outpoint& b) { + inline bool operator > (const outpoint& a, const outpoint& b) { return a.Digest == b.Digest ? a.Index > b.Index : a.Digest > b.Digest; } - inline bool operator<(const outpoint& a, const outpoint& b) { + inline bool operator < (const outpoint& a, const outpoint& b) { return a.Digest == b.Digest ? a.Index < b.Index : a.Digest < b.Digest; } - inline bool operator>=(const outpoint& a, const outpoint& b) { + inline bool operator >= (const outpoint& a, const outpoint& b) { return a.Digest == b.Digest ? a.Index >= b.Index : a.Digest >= b.Digest; } - inline bool operator<=(const outpoint& a, const outpoint& b) { + inline bool operator <= (const outpoint& a, const outpoint& b) { return a.Digest == b.Digest ? a.Index <= b.Index : a.Digest <= b.Digest; } - bool inline operator>(const header& a, const header& b) { + bool inline operator > (const header& a, const header& b) { return a.Timestamp > b.Timestamp; } - bool inline operator<(const header& a, const header& b) { + bool inline operator < (const header& a, const header& b) { return a.Timestamp < b.Timestamp; } - bool inline operator>=(const header& a, const header& b) { + bool inline operator >= (const header& a, const header& b) { return a.Timestamp >= b.Timestamp; } - bool inline operator<=(const header& a, const header& b) { + bool inline operator <= (const header& a, const header& b) { return a.Timestamp <= b.Timestamp; } - txid inline transaction::id(bytes_view b) { - return Hash256(b); + txid inline transaction::id (bytes_view b) { + return Hash256 (b); } - uint64 inline input::serialized_size() const { - return 40u + var_int::size(Script.size()) + Script.size(); + uint64 inline input::serialized_size () const { + return 40u + var_int::size (Script.size ()) + Script.size (); } - uint64 inline output::serialized_size() const { - return 8u + var_int::size(Script.size()) + Script.size(); + uint64 inline output::serialized_size () const { + return 8u + var_int::size (Script.size ()) + Script.size (); } } diff --git a/src/gigamonkey/boost/boost.cpp b/src/gigamonkey/boost/boost.cpp index 8ded98e1..9fbc5593 100644 --- a/src/gigamonkey/boost/boost.cpp +++ b/src/gigamonkey/boost/boost.cpp @@ -133,7 +133,7 @@ namespace Gigamonkey::Boost { push_size {32, Content}, push_size {4, Target}, push {x.Tag}, - push_size{4, UserNonce}, + push_size {4, UserNonce}, push {x.AdditionalData}, OP_CAT, OP_SWAP, // copy mining pool’s pubkey hash to alt stack. A copy remains on the stack. push {5}, OP_ROLL, OP_DUP, OP_TOALTSTACK, OP_CAT, @@ -147,7 +147,7 @@ namespace Gigamonkey::Boost { OP_SWAP, OP_CAT, OP_HASH256, // target and content + merkleroot to altstack. OP_SWAP, OP_TOALTSTACK, OP_CAT, OP_TOALTSTACK, - push_data(work::ASICBoost::Mask), OP_DUP, OP_INVERT, OP_TOALTSTACK, OP_AND, + push_data (work::ASICBoost::Mask), OP_DUP, OP_INVERT, OP_TOALTSTACK, OP_AND, // check size of general purpose bits OP_SWAP, OP_FROMALTSTACK, OP_AND, OP_OR, OP_FROMALTSTACK, OP_CAT, // attach content + merkleroot @@ -170,7 +170,7 @@ namespace Gigamonkey::Boost { x.UseGeneralPurposeBits = false; } else return {}; - std::copy( + std::copy ( Category.begin (), Category.end (), x.Category.data ()); @@ -345,7 +345,7 @@ namespace Gigamonkey::Boost { ", Nonce : " << s.Nonce << ", Timestamp : " << s.Timestamp << ", ExtraNonce2 : " << s.ExtraNonce2 << - ", ExtraNonce1 : " << s.ExtraNonce1; + ", ExtraNonce1 : " << static_cast(s.ExtraNonce1); if (s.Type == bounty) o << ", MinerPubkeyHash: " << s.MinerPubkeyHash; return o << "}"; } diff --git a/src/gigamonkey/timestamp.cpp b/src/gigamonkey/timestamp.cpp index 2165a8d4..382c8536 100644 --- a/src/gigamonkey/timestamp.cpp +++ b/src/gigamonkey/timestamp.cpp @@ -5,12 +5,12 @@ namespace Gigamonkey::Bitcoin { - std::ostream& operator<<(std::ostream& o, const timestamp& s) { - time_t t = static_cast(uint32(s)); + std::ostream& operator << (std::ostream& o, const timestamp& s) { + time_t t = static_cast (uint32 (s)); std::stringstream ss; - ss << "{" << uint32(s) << ", \"" << ctime(&t); - string str = ss.str(); - return o << str.substr(0, str.size() - 1) << "\"}"; + ss << "{" << uint32 (s) << ", \"" << ctime (&t); + string str = ss.str (); + return o << str.substr (0, str.size () - 1) << "\"}"; } } diff --git a/test/testStratum.cpp b/test/testStratum.cpp index c1707a44..8878e05a 100644 --- a/test/testStratum.cpp +++ b/test/testStratum.cpp @@ -10,40 +10,40 @@ namespace Gigamonkey::Stratum { - TEST(StratumTest, TestStratumSessionID) { + TEST (StratumTest, TestStratumSessionID) { uint32 a = 303829; uint32 b = 773822929; - session_id id_a(a); - session_id id_b(b); - EXPECT_NE(id_a, id_b); - encoding::hex::fixed<4> hex_a = encoding::hex::fixed<4>(id_a); - encoding::hex::fixed<4> hex_b = encoding::hex::fixed<4>(id_b); - EXPECT_NE(hex_a, hex_b); - EXPECT_EQ(id_a, session_id{hex_a}); - EXPECT_EQ(id_b, session_id{hex_b}); - JSON j_a = session_id::serialize(id_a); - JSON j_b = session_id::serialize(id_b); - EXPECT_NE(j_a, j_b); - optional j_id_a = session_id::deserialize(j_a); - optional j_id_b = session_id::deserialize(j_b); - EXPECT_TRUE(j_id_a); - EXPECT_TRUE(j_id_b); - EXPECT_NE(*j_id_a, *j_id_b); - EXPECT_EQ(id_a, *j_id_a); - EXPECT_EQ(id_b, *j_id_b); + session_id id_a (a); + session_id id_b (b); + EXPECT_NE (id_a, id_b); + encoding::hex::fixed<4> hex_a = encoding::hex::fixed<4> (id_a); + encoding::hex::fixed<4> hex_b = encoding::hex::fixed<4> (id_b); + EXPECT_NE (hex_a, hex_b); + EXPECT_EQ (id_a, session_id {hex_a}); + EXPECT_EQ (id_b, session_id {hex_b}); + JSON j_a = session_id::serialize (id_a); + JSON j_b = session_id::serialize (id_b); + EXPECT_NE (j_a, j_b); + optional j_id_a = session_id::deserialize (j_a); + optional j_id_b = session_id::deserialize (j_b); + EXPECT_TRUE (j_id_a); + EXPECT_TRUE (j_id_b); + EXPECT_NE (*j_id_a, *j_id_b); + EXPECT_EQ (id_a, *j_id_a); + EXPECT_EQ (id_b, *j_id_b); } // taken from https://braiins.com/stratum-v1/docs TEST(StratumTest, TestStratumPuzzle) { - mining::subscribe_response subscribe_response{JSON::parse( + mining::subscribe_response subscribe_response {JSON::parse ( R"({"id": 1, "result": [ [ ["mining.set_difficulty", "b4b6693b72a50c7116db18d6497cac52"], ["mining.notify", "ae6812eb4cd7735a302a8a9dd95cf71f"]], "08000002", 4], "error": null})")}; - mining::subscribe_response::parameters srparams = subscribe_response.result(); + mining::subscribe_response::parameters srparams = subscribe_response.result (); - EXPECT_TRUE(subscribe_response.valid()); + EXPECT_TRUE (subscribe_response.valid ()); - mining::notify notify{JSON::parse( + mining::notify notify {JSON::parse ( R"({"params": ["bf", "4d16b6f85af6e2198f44ae2a6de67f78487ae5611b77c6c0440b921e00000000", "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff20020862062f503253482f04b8864e5008", @@ -51,124 +51,124 @@ namespace Gigamonkey::Stratum { [], "00000002", "1c2ac4af", "504e86b9", false], "id": null, "method": "mining.notify"})")}; - EXPECT_TRUE(notify.valid()); + EXPECT_TRUE (notify.valid ()); - mining::submit_request submit_request{JSON::parse( + mining::submit_request submit_request {JSON::parse ( R"({"params": ["slush.miner1", "bf", "00000001", "504e86ed", "b2957c02"], "id": 4, "method": "mining.submit"})")}; - EXPECT_TRUE(submit_request.valid()); + EXPECT_TRUE (submit_request.valid ()); - digest256 expected_block_hash{"32abdc31d947623a2482144f92dbc092a84fd8ee6e2b5ae60f87762000000000"}; - digest256 expected_prev_hash{"f8b6164d19e2f65a2aae448f787fe66d61e57a48c0c6771b1e920b4400000000"}; + digest256 expected_block_hash {"32abdc31d947623a2482144f92dbc092a84fd8ee6e2b5ae60f87762000000000"}; + digest256 expected_prev_hash {"f8b6164d19e2f65a2aae448f787fe66d61e57a48c0c6771b1e920b4400000000"}; - proof p{worker{"Daniel", subscribe_response.result().ExtraNonce}, notify.params(), submit_request.params()}; + proof p{worker{"Daniel", subscribe_response.result ().ExtraNonce}, notify.params (), submit_request.params ()}; - EXPECT_TRUE(p.valid()); - work::string z = work::proof(p).string(); - EXPECT_EQ(expected_block_hash, z.hash()); - EXPECT_EQ(z.Digest, expected_prev_hash); + EXPECT_TRUE (p.valid ()); + work::string z = work::proof (p).string (); + EXPECT_EQ (expected_block_hash, z.hash ()); + EXPECT_EQ (z.Digest, expected_prev_hash); } } namespace Gigamonkey::Stratum::mining { - TEST(StratumTest, TestBooleanResponse) { + TEST (StratumTest, TestBooleanResponse) { struct response_test_case { message_id ID; bool Result; - operator boolean_response() const { - return boolean_response{ID, Result}; + operator boolean_response () const { + return boolean_response {ID, Result}; } }; - std::vector test_cases{{64, true}, {94, false}}; + std::vector test_cases {{64, true}, {94, false}}; for (const auto& i : test_cases) for (const auto& j : test_cases) { - auto response_i = boolean_response(i); - auto response_j = boolean_response(j); - EXPECT_EQ(i.Result, response_i.result()); + auto response_i = boolean_response (i); + auto response_j = boolean_response (j); + EXPECT_EQ (i.Result, response_i.result ()); if (i.ID == j.ID) { - EXPECT_EQ(i.ID, response_j.id()); - EXPECT_EQ(response_i, response_j); + EXPECT_EQ (i.ID, response_j.id ()); + EXPECT_EQ (response_i, response_j); } else { - EXPECT_NE(i.ID, response_j.id()); - EXPECT_NE(response_i, response_j); + EXPECT_NE (i.ID, response_j.id ()); + EXPECT_NE (response_i, response_j); } } - boolean_response null_no_error{JSON::parse(R"({"id":55, "result": null, "error": null})")}; - boolean_response null_with_error{JSON::parse(R"({"id":55, "result": null, "error": [4, "hi"]})")}; - boolean_response false_with_error{JSON::parse(R"({"id":55, "result": false, "error": [4, "hi"]})")}; - boolean_response false_no_error{JSON::parse(R"({"id":55, "result": false, "error": null})")}; - boolean_response true_no_error{JSON::parse(R"({"id":55, "result": true, "error": null})")}; - boolean_response true_with_error{JSON::parse(R"({"id":55, "result": true, "error": [4, "hi"]})")}; + boolean_response null_no_error {JSON::parse (R"({"id":55, "result": null, "error": null})")}; + boolean_response null_with_error {JSON::parse (R"({"id":55, "result": null, "error": [4, "hi"]})")}; + boolean_response false_with_error {JSON::parse (R"({"id":55, "result": false, "error": [4, "hi"]})")}; + boolean_response false_no_error {JSON::parse (R"({"id":55, "result": false, "error": null})")}; + boolean_response true_no_error {JSON::parse (R"({"id":55, "result": true, "error": null})")}; + boolean_response true_with_error {JSON::parse (R"({"id":55, "result": true, "error": [4, "hi"]})")}; - EXPECT_FALSE(null_no_error.valid()); + EXPECT_FALSE (null_no_error.valid ()); - EXPECT_TRUE(null_with_error.valid()); - EXPECT_FALSE(null_with_error.result()); + EXPECT_TRUE (null_with_error.valid ()); + EXPECT_FALSE (null_with_error.result ()); - EXPECT_TRUE(false_with_error.valid()); - EXPECT_FALSE(false_with_error.result()); + EXPECT_TRUE (false_with_error.valid ()); + EXPECT_FALSE (false_with_error.result ()); - EXPECT_TRUE(false_no_error.valid()); - EXPECT_FALSE(false_no_error.result()); + EXPECT_TRUE (false_no_error.valid ()); + EXPECT_FALSE (false_no_error.result ()); - EXPECT_TRUE(true_no_error.valid()); - EXPECT_TRUE(true_no_error.result()); + EXPECT_TRUE (true_no_error.valid ()); + EXPECT_TRUE (true_no_error.result ()); - EXPECT_TRUE(true_with_error.valid()); - EXPECT_FALSE(true_with_error.result()); + EXPECT_TRUE (true_with_error.valid ()); + EXPECT_FALSE (true_with_error.result ()); } - TEST(StratumTest, TestMiningAuthorize) { + TEST (StratumTest, TestMiningAuthorize) { struct request_test_case { message_id ID; authorize_request::parameters Params; - operator authorize_request() const { - if (Params.Password) return authorize_request{ID, Params.Username, *Params.Password}; - return authorize_request{ID, Params.Username}; + operator authorize_reques t() const { + if (Params.Password) return authorize_request {ID, Params.Username, *Params.Password}; + return authorize_request {ID, Params.Username}; } }; - std::vector test_cases{ - {64, authorize_request::parameters{"dk", "meep"}}, - {94, authorize_request::parameters{"dk"}}}; + std::vector test_cases { + {64, authorize_request::parameters {"dk", "meep"}}, + {94, authorize_request::parameters {"dk"}}}; for (const auto& i : test_cases) for (const auto& j : test_cases) { - auto request_i = authorize_request(i); - auto request_j = authorize_request(j); - auto deserialized_i = authorize_request::deserialize(static_cast(request_i).params()); - auto deserialized_j = authorize_request::deserialize(static_cast(request_j).params()); - EXPECT_EQ(request_i.valid(), deserialized_i.valid()); + auto request_i = authorize_request (i); + auto request_j = authorize_request (j); + auto deserialized_i = authorize_request::deserialize (static_cast (request_i).params ()); + auto deserialized_j = authorize_request::deserialize (static_cast (request_j).params ()); + EXPECT_EQ (request_i.valid (), deserialized_i.valid ()); if (i.ID == j.ID) { - EXPECT_EQ(i.ID, request_j.id()); - EXPECT_EQ(request_i, request_j); - EXPECT_EQ(deserialized_i, deserialized_j); - EXPECT_EQ(i.Params, deserialized_j); + EXPECT_EQ (i.ID, request_j.id ()); + EXPECT_EQ (request_i, request_j); + EXPECT_EQ (deserialized_i, deserialized_j); + EXPECT_EQ (i.Params, deserialized_j); } else { - EXPECT_NE(i.ID, request_j.id()); - EXPECT_NE(request_i, request_j); - EXPECT_NE(deserialized_i, deserialized_j); - EXPECT_NE(i.Params, deserialized_j); + EXPECT_NE (i.ID, request_j.id ()); + EXPECT_NE (request_i, request_j); + EXPECT_NE (deserialized_i, deserialized_j); + EXPECT_NE (i.Params, deserialized_j); } } } - TEST(StratumTest, TestMiningSubscribe) { + TEST (StratumTest, TestMiningSubscribe) { struct request_test_case { message_id ID; subscribe_request::parameters Params; operator subscribe_request() const { - if (Params.ExtraNonce1) return subscribe_request{ID, Params.UserAgent, *Params.ExtraNonce1}; - return subscribe_request{ID, Params.UserAgent}; + if (Params.ExtraNonce1) return subscribe_request {ID, Params.UserAgent, *Params.ExtraNonce1}; + return subscribe_request {ID, Params.UserAgent}; } }; @@ -176,194 +176,244 @@ namespace Gigamonkey::Stratum::mining { message_id ID; subscribe_response::parameters Result; - operator subscribe_response() const { - return subscribe_response{ID, Result.Subscriptions, Result.ExtraNonce}; + operator subscribe_response () const { + return subscribe_response {ID, Result.Subscriptions, Result.ExtraNonce}; } }; - std::vector request_test_cases{{23, {"dk", 2}}, {45, {"dk"}}}; + std::vector request_test_cases {{23, {"dk", 2}}, {45, {"dk"}}}; std::vector response_test_cases { - {23, {{subscription{mining_set_difficulty, "1"}, subscription{mining_notify, "2"}}, {7, 8}}}, - {45, {{subscription{mining_notify, "3"}}, {30, 8}}}}; + {23, {{subscription {mining_set_difficulty, "1"}, subscription {mining_notify, "2"}}, {7, 8}}}, + {45, {{subscription {mining_notify, "3"}}, {30, 8}}}}; for (const auto& i : request_test_cases) for (const auto& j : request_test_cases) { - auto request_i = subscribe_request(i); - auto request_j = subscribe_request(j); - auto deserialized_i = subscribe_request::deserialize(request_i.params()); - auto deserialized_j = subscribe_request::deserialize(request_j.params()); - EXPECT_EQ(request_i.valid(), deserialized_i.valid()); + auto request_i = subscribe_request (i); + auto request_j = subscribe_request (j); + auto deserialized_i = subscribe_request::deserialize (request_i.params ()); + auto deserialized_j = subscribe_request::deserialize (request_j.params ()); + EXPECT_EQ (request_i.valid (), deserialized_i.valid ()); if (i.ID == j.ID) { - EXPECT_EQ(i.ID, request_j.id()); - EXPECT_EQ(request_i, request_j); - EXPECT_EQ(deserialized_i, deserialized_j); - EXPECT_EQ(i.Params, deserialized_j); + EXPECT_EQ (i.ID, request_j.id ()); + EXPECT_EQ (request_i, request_j); + EXPECT_EQ (deserialized_i, deserialized_j); + EXPECT_EQ (i.Params, deserialized_j); } else { - EXPECT_NE(i.ID, request_j.id()); - EXPECT_NE(request_i, request_j); - EXPECT_NE(deserialized_i, deserialized_j); - EXPECT_NE(i.Params, deserialized_j); + EXPECT_NE (i.ID, request_j.id ()); + EXPECT_NE (request_i, request_j); + EXPECT_NE (deserialized_i, deserialized_j); + EXPECT_NE (i.Params, deserialized_j); } } for (const auto& i : response_test_cases) for (const auto& j : response_test_cases) { - auto response_i = subscribe_response(i); - auto response_j = subscribe_response(j); - auto deserialized_i = subscribe_response::deserialize(static_cast(response_i).result()); - auto deserialized_j = subscribe_response::deserialize(static_cast(response_j).result()); - EXPECT_EQ(response_i.valid(), deserialized_i.valid()); + auto response_i = subscribe_response (i); + auto response_j = subscribe_response (j); + auto deserialized_i = subscribe_response::deserialize(static_cast (response_i).result ()); + auto deserialized_j = subscribe_response::deserialize(static_cast (response_j).result ()); + EXPECT_EQ (response_i.valid (), deserialized_i.valid ()); if (i.ID == j.ID) { - EXPECT_EQ(i.ID, response_j.id()); - EXPECT_EQ(response_i, response_j); - EXPECT_EQ(deserialized_i, deserialized_j); - EXPECT_EQ(i.Result, deserialized_j); + EXPECT_EQ (i.ID, response_j.id ()); + EXPECT_EQ (response_i, response_j); + EXPECT_EQ (deserialized_i, deserialized_j); + EXPECT_EQ (i.Result, deserialized_j); } else { - EXPECT_NE(i.ID, response_j.id()); - EXPECT_NE(response_i, response_j); - EXPECT_NE(deserialized_i, deserialized_j); - EXPECT_NE(i.Result, deserialized_j); + EXPECT_NE (i.ID, response_j.id ()); + EXPECT_NE (response_i, response_j); + EXPECT_NE (deserialized_i, deserialized_j); + EXPECT_NE (i.Result, deserialized_j); } } } - TEST(StratumTest, TestMiningSubmit) { + TEST (StratumTest, TestMiningSubmit) { struct notification_test_case { message_id ID; notify::parameters Params; - operator notify() const { - return notify{Params}; + operator notify () const { + return notify {Params}; } }; - std::vector notify_test_cases{}; + std::vector notify_test_cases {}; for (const auto& i : notify_test_cases) for (const auto& j : notify_test_cases) { - auto notify_i = notify(i); - auto notify_j = notify(j); - auto deserialized_i = notify::deserialize(static_cast(notify_i).params()); - auto deserialized_j = notify::deserialize(static_cast(notify_j).params()); - EXPECT_EQ(notify_i.valid(), deserialized_i.valid()); + auto notify_i = notify (i); + auto notify_j = notify (j); + auto deserialized_i = notify::deserialize (static_cast (notify_i).params ()); + auto deserialized_j = notify::deserialize (static_cast (notify_j).params ()); + EXPECT_EQ (notify_i.valid (), deserialized_i.valid ()); if (i.ID == j.ID) { - EXPECT_EQ(notify_i, notify_j); - EXPECT_EQ(deserialized_i, deserialized_j); - EXPECT_EQ(i.Params, deserialized_j); + EXPECT_EQ (notify_i, notify_j); + EXPECT_EQ (deserialized_i, deserialized_j); + EXPECT_EQ (i.Params, deserialized_j); } else { - EXPECT_NE(notify_i, notify_j); - EXPECT_NE(deserialized_i, deserialized_j); - EXPECT_NE(i.Params, deserialized_j); + EXPECT_NE (notify_i, notify_j); + EXPECT_NE (deserialized_i, deserialized_j); + EXPECT_NE (i.Params, deserialized_j); } } } - TEST(StratumTest, TestMiningNotify) { + TEST (StratumTest, TestMiningNotify) { struct request_test_case { message_id ID; share Params; - operator submit_request() const { - return submit_request{ID, Params}; + operator submit_request () const { + return submit_request {ID, Params}; } }; - std::vector request_test_cases{}; + std::vector request_test_cases {}; for (const auto& i : request_test_cases) for (const auto& j : request_test_cases) { - auto request_i = submit_request(i); - auto request_j = submit_request(j); - auto deserialized_i = submit_request::deserialize(static_cast(request_i).params()); - auto deserialized_j = submit_request::deserialize(static_cast(request_j).params()); - EXPECT_EQ(request_i.valid(), deserialized_i.valid()); + auto request_i = submit_request (i); + auto request_j = submit_request (j); + auto deserialized_i = submit_request::deserialize (static_cast (request_i).params ()); + auto deserialized_j = submit_request::deserialize (static_cast (request_j).params ()); + EXPECT_EQ (request_i.valid (), deserialized_i.valid ()); if (i.ID == j.ID) { - EXPECT_EQ(i.ID, request_j.id()); - EXPECT_EQ(request_i, request_j); - EXPECT_EQ(deserialized_i, deserialized_j); - EXPECT_EQ(i.Params, submit_request::deserialize(static_cast(request_j).params())); + EXPECT_EQ (i.ID, request_j.id ()); + EXPECT_EQ (request_i, request_j); + EXPECT_EQ (deserialized_i, deserialized_j); + EXPECT_EQ (i.Params, submit_request::deserialize (static_cast (request_j).params ())); } else { - EXPECT_NE(i.ID, request_j.id()); - EXPECT_NE(request_i, request_j); - EXPECT_NE(deserialized_i, deserialized_j); - EXPECT_NE(i.Params, submit_request::deserialize(static_cast(request_j).params())); + EXPECT_NE (i.ID, request_j.id ()); + EXPECT_NE (request_i, request_j); + EXPECT_NE (deserialized_i, deserialized_j); + EXPECT_NE (i.Params, submit_request::deserialize (static_cast (request_j).params())); } } } - TEST(StratumTest, TestStratumDifficulty) { - difficulty d1{work::difficulty{.0001}}; - difficulty d2{555}; - EXPECT_TRUE(d1.valid()); - EXPECT_TRUE(d2.valid()); - work::compact t1{work::difficulty(d1)}; - work::compact t2{work::difficulty(d2)}; - EXPECT_EQ(t1, work::compact{work::difficulty(difficulty{t1})}); - EXPECT_EQ(t2, work::compact{work::difficulty(difficulty{t2})}); + TEST (StratumTest, TestStratumDifficulty) { + difficulty d1 {work::difficulty {.0001}}; + difficulty d2 {555}; + EXPECT_TRUE (d1.valid ()); + EXPECT_TRUE (d2.valid ()); + work::compact t1 {work::difficulty (d1)}; + work::compact t2 {work::difficulty (d2)}; + EXPECT_EQ (t1, work::compact {work::difficulty (difficulty {t1})}); + EXPECT_EQ (t2, work::compact {work::difficulty (difficulty {t2})}); } - TEST(StratumTest, TestStratumProof) { + TEST (StratumTest, TestStratumProof) { job_id jid = "2333"; - extranonce en{1, 8}; + extranonce en {1, 8}; int32_little version = 2; - Bitcoin::timestamp timestamp{3}; + Bitcoin::timestamp timestamp {3}; - work::compact d{work::difficulty(.0001)}; - digest256 prevHash{"0x0000000000000000000000000000000000000000000000000000000000000001"}; - bytes gentx1 = bytes::from_hex("abcdef"); - bytes gentx2 = bytes::from_hex("010203"); + work::compact d {work::difficulty (.0001)}; + digest256 prevHash {"0x0000000000000000000000000000000000000000000000000000000000000001"}; + bytes gentx1 = bytes::from_hex ("abcdef"); + bytes gentx2 = bytes::from_hex ("010203"); - bytes extra_nonce_2 = bytes::from_hex("abcdef0123456789"); + bytes extra_nonce_2 = bytes::from_hex ("abcdef0123456789"); int32_little gpr = 0xffffffff; int32_little version_mask = work::ASICBoost::Mask; - string name{"Daniel"}; + string name {"Daniel"}; - mining::notify::parameters notify{jid, prevHash, gentx1, gentx2, {}, version, d, timestamp, true}; + mining::notify::parameters notify {jid, prevHash, gentx1, gentx2, {}, version, d, timestamp, true}; - auto worker_v1 = worker{name, en}; - auto worker_v2 = worker{name, en, version_mask}; + auto worker_v1 = worker {name, en}; + auto worker_v2 = worker {name, en, version_mask}; - EXPECT_FALSE(worker_v1.Mask); - EXPECT_TRUE(worker_v2.Mask); + EXPECT_FALSE (worker_v1.Mask); + EXPECT_TRUE (worker_v2.Mask); - auto puzzle_v1 = work::puzzle{version, prevHash, d, {}, gentx1, gentx2}; - auto puzzle_v2 = work::puzzle{version, prevHash, d, {}, gentx1, gentx2, version_mask}; + auto puzzle_v1 = work::puzzle {version, prevHash, d, {}, gentx1, gentx2}; + auto puzzle_v2 = work::puzzle {version, prevHash, d, {}, gentx1, gentx2, version_mask}; - auto initial_share_v1 = work::share{timestamp, 65067, extra_nonce_2}; - auto initial_share_v2 = work::share{timestamp, 449600, extra_nonce_2, gpr}; + auto initial_share_v1 = work::share {timestamp, 65067, extra_nonce_2}; + auto initial_share_v2 = work::share {timestamp, 449600, extra_nonce_2, gpr}; - EXPECT_FALSE(initial_share_v1.Bits); - EXPECT_TRUE(initial_share_v2.Bits); + EXPECT_FALSE (initial_share_v1.Bits); + EXPECT_TRUE (initial_share_v2.Bits); - auto work_proof_v1 = work::proof{puzzle_v1, {initial_share_v1, en.ExtraNonce1}}; - auto work_proof_v2 = work::proof{puzzle_v2, {initial_share_v2, en.ExtraNonce1}}; + auto work_proof_v1 = work::proof {puzzle_v1, {initial_share_v1, en.ExtraNonce1}}; + auto work_proof_v2 = work::proof {puzzle_v2, {initial_share_v2, en.ExtraNonce1}}; - EXPECT_TRUE(work_proof_v1.valid()); - EXPECT_TRUE(work_proof_v2.valid()); + EXPECT_TRUE (work_proof_v1.valid ()); + EXPECT_TRUE (work_proof_v2.valid ()); - auto share_v1 = share{name, jid, work_proof_v1.Solution.Share}; - auto share_v2 = share{name, jid, work_proof_v2.Solution.Share}; + auto share_v1 = share {name, jid, work_proof_v1.Solution.Share}; + auto share_v2 = share {name, jid, work_proof_v2.Solution.Share}; auto nonce_v1 = share_v1.Share.Nonce; auto nonce_v2 = share_v2.Share.Nonce; - auto proof_v1 = proof{worker_v1, notify, share_v1}; - auto proof_v2 = proof{worker_v2, notify, share_v2}; + auto proof_v1 = proof {worker_v1, notify, share_v1}; + auto proof_v2 = proof {worker_v2, notify, share_v2}; - EXPECT_EQ(work_proof_v1, work::proof(proof_v1)); - EXPECT_EQ(work_proof_v2, work::proof(proof_v2)); + EXPECT_EQ (work_proof_v1, work::proof (proof_v1)); + EXPECT_EQ (work_proof_v2, work::proof (proof_v2)); - EXPECT_NE(work_proof_v1, work::proof(proof_v2)); - EXPECT_NE(work_proof_v2, work::proof(proof_v1)); + EXPECT_NE (work_proof_v1, work::proof (proof_v2)); + EXPECT_NE (work_proof_v2, work::proof (proof_v1)); - EXPECT_TRUE(proof_v1.valid()); - EXPECT_TRUE(proof_v2.valid()); + EXPECT_TRUE (proof_v1.valid ()); + EXPECT_TRUE (proof_v2.valid ()); } - TEST(StratumTest, TestMiningConfigure) { + TEST (StratumTest, TestMiningConfigure) { //extensions::requests{ }; } } +namespace Gigamonkey { + + template + struct mock_session : net::session {}; + void send (type t) final override { + Send = Send << t; + }; + + bool closed () final override { + return false; + }; + + void close () final override {}; + + list Send; + + mock_session () : Send {} {} + }; + + template + struct mock_channel { + ptr> Session; + net::handler Receive; + + void send (type t) { + Receive (t); + }; + + optional receive () { + if (data::empty (Session->Send)) return {}; + auto next = data::first (Session->Send); + Session->Send = data::rest (Session->Send); + return next; + } + + }; + + template mock_channel open_mock (interaction interact) { + auto session = std::make_shared> (); + return mock_channel {session, interact (session)}; + } +} + +namespace Gigamonkey::Stratum { + + TEST (StratumTest, TestStratumServer) { + + } + +} From a0169acdf1bb34e82d08deb7c4da60300f3f7ef1 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Wed, 1 Mar 2023 21:03:22 -0500 Subject: [PATCH 04/11] Add difficulty and profitability functions to Boost::prevout --- include/gigamonkey/boost/boost.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/gigamonkey/boost/boost.hpp b/include/gigamonkey/boost/boost.hpp index fea4f247..d5a1720c 100644 --- a/include/gigamonkey/boost/boost.hpp +++ b/include/gigamonkey/boost/boost.hpp @@ -299,6 +299,15 @@ namespace Gigamonkey { Bitcoin::outpoint outpoint () const; Bitcoin::satoshi value () const; digest256 id () const; + + double difficulty () const { + return work::difficulty (this->Value.Script.Target); + } + + double profitability () const { + return double (value ()) / difficulty (); + } + explicit operator Bitcoin::prevout () const; }; From d693b7a6bdbcc61f55766a907dd33885f13e5a12 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Mon, 20 Mar 2023 12:13:43 -0500 Subject: [PATCH 05/11] formatting --- .../script/pattern/pay_to_address.hpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/gigamonkey/script/pattern/pay_to_address.hpp b/include/gigamonkey/script/pattern/pay_to_address.hpp index b430ead9..1967f3cc 100644 --- a/include/gigamonkey/script/pattern/pay_to_address.hpp +++ b/include/gigamonkey/script/pattern/pay_to_address.hpp @@ -9,36 +9,36 @@ namespace Gigamonkey { struct pay_to_address { - static Gigamonkey::pattern pattern(bytes& address) { + static Gigamonkey::pattern pattern (bytes& address) { using namespace Bitcoin; - return {OP_DUP, OP_HASH160, push_size{20, address}, OP_EQUALVERIFY, OP_CHECKSIG}; + return {OP_DUP, OP_HASH160, push_size {20, address}, OP_EQUALVERIFY, OP_CHECKSIG}; } - static bytes script(const digest160& a) { + static bytes script (const digest160& a) { using namespace Bitcoin; - return compile(program{OP_DUP, OP_HASH160, bytes_view(a), OP_EQUALVERIFY, OP_CHECKSIG}); + return compile (program {OP_DUP, OP_HASH160, bytes_view(a), OP_EQUALVERIFY, OP_CHECKSIG}); } digest160 Address; - bool valid() const { - return Address.valid(); + bool valid () const { + return Address.valid (); } - bytes script() const { - return script(Address); + bytes script () const { + return script (Address); } - pay_to_address(bytes_view script) : Address{} { + pay_to_address (bytes_view script) : Address {} { using namespace Bitcoin; - bytes addr{20}; - if (!pattern(addr).match(script)) return; - std::copy(addr.begin(), addr.end(), Address.Value.begin()); + bytes addr {20}; + if (!pattern (addr).match (script)) return; + std::copy (addr.begin (), addr.end (), Address.Value.begin ()); } - static bytes redeem(const Bitcoin::signature& s, const Bitcoin::pubkey& p) { + static bytes redeem (const Bitcoin::signature& s, const Bitcoin::pubkey& p) { using namespace Bitcoin; - return compile(program{} << push_data(s) << push_data(p)); + return compile (program {} << push_data (s) << push_data (p)); } }; From 6041dd17a3ad8172c5e98c440d98cf206b7bd245 Mon Sep 17 00:00:00 2001 From: KatrinaAS Date: Mon, 20 Mar 2023 17:36:34 +0000 Subject: [PATCH 06/11] feat: Upgrade conan to conan2 --- .gitignore | 3 ++- CMakeLists.txt | 24 +++++++++++++++++++---- conanfile.py | 48 ++++++++++++++++++++------------------------- test/CMakeLists.txt | 11 +++++++++-- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index b515a708..437ab82a 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,5 @@ cmake-build-debug*/ cmake-build-debug-coverage/ .idea/ .vscode/ -test/testSimplyCash.cpp \ No newline at end of file +test/testSimplyCash.cpp +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index ef47e101..93bfbf02 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,6 @@ project (gigamonkey VERSION 0.0.13 DESCRIPTION "open-source Bitcoin library in c++" LANGUAGES CXX) -# Set cmake as import path for Find*.cmake files -include (${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup (TARGETS) ## Check if GTests is installed. If not, install it @@ -19,6 +16,13 @@ option (PACKAGE_TESTS "Build the tests" ON) ## Enable testing +find_package(data CONFIG REQUIRED) +find_package(Boost CONFIG REQUIRED) +find_package(OpenSSL CONFIG REQUIRED) +find_package(cryptopp CONFIG REQUIRED) +find_package(nlohmann_json CONFIG REQUIRED) +find_package(gmp CONFIG REQUIRED) + if (PACKAGE_TESTS) include (CTest) @@ -88,7 +92,17 @@ add_library (gigamonkey STATIC ) -target_link_libraries (gigamonkey PUBLIC CONAN_PKG::data util CONAN_PKG::boost CONAN_PKG::openssl CONAN_PKG::cryptopp CONAN_PKG::nlohmann_json CONAN_PKG::gmp ) + + +target_link_libraries(gigamonkey PUBLIC +data::data +util +boost::boost +openssl::openssl +cryptopp::cryptopp +nlohmann_json::nlohmann_json +gmp::gmp ) + target_include_directories (gigamonkey PUBLIC include) @@ -97,3 +111,5 @@ target_compile_features (gigamonkey PUBLIC cxx_std_20) set_target_properties (gigamonkey PROPERTIES CXX_EXTENSIONS ON) target_compile_options (gigamonkey PUBLIC "-fconcepts") +install(DIRECTORY include/ DESTINATION include) +install(TARGETS gigamonkey) diff --git a/conanfile.py b/conanfile.py index 6b0adeed..15ad3711 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,8 +1,10 @@ -from conans import ConanFile, CMake +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps from os import environ -class GigamonkeyConan (ConanFile): - name = "Gigamonkey" + +class GigamonkeyConan(ConanFile): + name = "gigamonkey" version = "v0.0.13" license = "Open BSV" author = "Daniel Krawisz" @@ -12,17 +14,8 @@ class GigamonkeyConan (ConanFile): settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} - generators = "cmake" - exports_sources = "*" - requires = [ - "boost/1.80.0", - "openssl/1.1.1k", - "cryptopp/8.5.0", - "nlohmann_json/3.10.0", - "gmp/6.2.1", - "SECP256K1/0.2.0@proofofwork/stable", - "data/v0.0.25@proofofwork/stable", - "gtest/1.12.1"] + exports_sources = "CMakeLists.txt", "include/*", "src/*", "test/*" + requires = "boost/1.80.0", "openssl/1.1.1t", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "secp256k1/0.3@proofofwork/stable", "data/v0.0.26@proofofwork/stable", "gtest/1.12.1" def set_version (self): if "CIRCLE_TAG" in environ: @@ -37,25 +30,26 @@ def config_options (self): del self.options.fPIC def configure_cmake (self): - if "CMAKE_BUILD_CORES_COUNT" in environ: - cmake = CMake (self, parallel=False) - else: - cmake = CMake (self) - cmake.definitions["PACKAGE_TESTS"] = "Off" - cmake.configure () + cmake = CMake (self) + cmake.configure(variables={"PACKAGE_TESTS":"Off"}) return cmake + + def layout(self): + cmake_layout(self) + + def generate(self): + deps = CMakeDeps(self) + deps.generate() + tc = CMakeToolchain(self) + tc.generate() def build (self): cmake = self.configure_cmake () - if "CMAKE_BUILD_CORES_COUNT" in environ: - cmake.build (args=["--", environ.get ("CMAKE_BUILD_CORES_COUNT")]) - else: - cmake.build () + cmake.build () def package (self): - self.copy ("*.h", dst="include", src="include") - self.copy ("*.hpp", dst="include", src="include") - self.copy ("libgigamonkey.a", src="lib", dst="lib", keep_path=False) + cmake = CMake(self) + cmake.install() def package_info (self): self.cpp_info.libdirs = ["lib"] # Default value is 'lib' diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f27e5e02..d1cf2169 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,13 +6,20 @@ if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) endif() +include(GoogleTest) macro(package_add_test TESTNAME) # create an exectuable in which the tests will be stored add_executable(${TESTNAME} ${ARGN}) # link the Google test infrastructure, mocking library, and a default main fuction to # the test executable. Remove g_test_main if writing your own main function. - target_include_directories(${TESTNAME} PUBLIC . ${CMAKE_SOURCE_DIR}/include CONAN_PKG::boost CONAN_PKG::openssl CONAN_PKG::cryptopp CONAN_PKG::nlohmann_json CONAN_PKG::gmp ) - target_link_libraries(${TESTNAME} CONAN_PKG::gtest CONAN_PKG::data gigamonkey ) + target_include_directories(${TESTNAME} PUBLIC . ${CMAKE_SOURCE_DIR}/include + boost::boost + openssl::openssl + cryptopp::cryptopp + nlohmann_json::nlohmann_json + gmp::gmp ) + target_link_libraries(${TESTNAME} gtest::gtest + data::data gigamonkey ) # gtest_discover_tests replaces gtest_add_tests, # see https://cmake.org/cmake/help/v3.10/module/GoogleTest.html for more options to pass to it From bf236a5d937745eb496a838fa9400810a3d15ae5 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Mon, 20 Mar 2023 13:26:31 -0500 Subject: [PATCH 07/11] Make numbers compatible with changes in data --- include/gigamonkey/number.hpp | 19 +- src/gigamonkey/script/instruction.cpp | 240 ++++++++++++++------------ src/gigamonkey/script/pattern.cpp | 128 +++++++------- test/testStratum.cpp | 7 +- 4 files changed, 201 insertions(+), 193 deletions(-) diff --git a/include/gigamonkey/number.hpp b/include/gigamonkey/number.hpp index 9ac830dd..caac942d 100644 --- a/include/gigamonkey/number.hpp +++ b/include/gigamonkey/number.hpp @@ -1113,23 +1113,8 @@ namespace Gigamonkey { if (x == "-0") return bytes ({0x80}); - if (data::encoding::integer::valid (x)) { - bool negative = data::encoding::integer::negative (x); - ptr> positive_number; - positive_number = negative ? - data::encoding::integer::read (x.substr (1)) : - data::encoding::integer::read (x); - - bool has_sign_bit = sign_bit (positive_number->words ()); - - bytes b; - b.resize (positive_number->size () + (has_sign_bit ? 1 : 0)); - auto n = numbers::digits {data::slice {const_cast(b.data ()), b.size ()}}; - std::copy(positive_number->begin (), positive_number->end (), n.begin ()); - if (has_sign_bit) *(n.begin () + positive_number->size ()) = negative ? 0x80 : 0x00; - else if (negative) *(n.begin () + positive_number->size () - 1) += 0x80; - return b; - } + if (data::encoding::integer::valid (x)) + return static_cast(*data::encoding::integer::read (x)); throw std::logic_error {"Invalid string representation"}; } diff --git a/src/gigamonkey/script/instruction.cpp b/src/gigamonkey/script/instruction.cpp index caec7ad8..14783891 100644 --- a/src/gigamonkey/script/instruction.cpp +++ b/src/gigamonkey/script/instruction.cpp @@ -2,29 +2,29 @@ // Distributed under the Open BSV software license, see the accompanying file LICENSE. #include -#include +#include namespace Gigamonkey::Bitcoin { - writer &operator<<(writer &w, const instruction& i) { - if (is_push_data(i.Op)) { - if (i.Op <= OP_PUSHSIZE75) w << static_cast(i.Op); - else if (i.Op == OP_PUSHDATA1) w << static_cast(OP_PUSHDATA1) << static_cast(i.Data.size()); - else if (i.Op == OP_PUSHDATA2) w << static_cast(OP_PUSHDATA2) << static_cast(i.Data.size()); - else w << static_cast(OP_PUSHDATA2) << static_cast(i.Data.size()); + writer &operator << (writer &w, const instruction& i) { + if (is_push_data (i.Op)) { + if (i.Op <= OP_PUSHSIZE75) w << static_cast (i.Op); + else if (i.Op == OP_PUSHDATA1) w << static_cast (OP_PUSHDATA1) << static_cast (i.Data.size ()); + else if (i.Op == OP_PUSHDATA2) w << static_cast (OP_PUSHDATA2) << static_cast (i.Data.size ()); + else w << static_cast (OP_PUSHDATA2) << static_cast (i.Data.size ()); return w << i.Data; } - return w << static_cast(i.Op); + return w << static_cast (i.Op); } namespace { - ScriptError verify_instruction(const instruction &i) { + ScriptError verify_instruction (const instruction &i) { if (i.Op == OP_INVALIDOPCODE || i.Op == OP_RESERVED || i.Op >= FIRST_UNDEFINED_OP_VALUE) return SCRIPT_ERR_BAD_OPCODE; - size_t size = i.Data.size(); - if (!is_push_data(i.Op)) { + size_t size = i.Data.size (); + if (!is_push_data (i.Op)) { if (size > 0) return SCRIPT_ERR_PUSH_SIZE; return SCRIPT_ERR_OK; } @@ -37,30 +37,30 @@ namespace Gigamonkey::Bitcoin { return SCRIPT_ERR_OK; } - bool is_minimal_push(const op o, const bytes& data) { - if (!is_push_data(o)) return data.size() == 0; - if (data.size() == 1 && (data[0] == 0x81 || (data[0] >= 1 && data[0] <= 16))) return false; - if (o == OP_PUSHDATA1) return data.size() > 75; - if (o == OP_PUSHDATA2) return data.size() > 256; - if (o == OP_PUSHDATA4) return data.size() > 65536; + bool is_minimal_push (const op o, const bytes& data) { + if (!is_push_data (o)) return data.size () == 0; + if (data.size () == 1 && (data[0] == 0x81 || (data[0] >= 1 && data[0] <= 16))) return false; + if (o == OP_PUSHDATA1) return data.size () > 75; + if (o == OP_PUSHDATA2) return data.size () > 256; + if (o == OP_PUSHDATA4) return data.size () > 65536; return true; } struct script_writer { bytes_writer &Writer; - script_writer &operator<<(instruction o) { + script_writer &operator << (instruction o) { Writer << o; return *this; } - script_writer &operator<<(program p) { - return p.size() == 0 ? *this : (*this << p.first() << p.rest()); + script_writer &operator << (program p) { + return p.size () == 0 ? *this : (*this << p.first () << p.rest ()); } - script_writer(bytes_writer &w) : Writer{w} {} + script_writer (bytes_writer &w) : Writer {w} {} }; - bytes_reader read_push(bytes_reader read, instruction& rest) { + bytes_reader read_push (bytes_reader read, instruction& rest) { uint32 size; bytes_reader r = read; @@ -70,11 +70,13 @@ namespace Gigamonkey::Bitcoin { r >> x; size = x; } + if (rest.Op == OP_PUSHDATA2) { uint16_little x; r >> x; size = x; } + if (rest.Op == OP_PUSHDATA4) { uint32_little x; r >> x; @@ -86,14 +88,15 @@ namespace Gigamonkey::Bitcoin { return read; } - rest.Data = bytes(size); + rest.Data = bytes (size); r >> rest.Data; return r; } struct script_reader { bytes_reader Reader; - script_reader operator>>(instruction& i) { + + script_reader operator >> (instruction& i) { if ((Reader.End - Reader.Begin) == 0) { i = {}; return *this; @@ -101,73 +104,73 @@ namespace Gigamonkey::Bitcoin { byte next; Reader >> next; - i.Op = static_cast(next); - if (is_push_data(i.Op)) return read_push(Reader, i); + i.Op = static_cast (next); + if (is_push_data (i.Op)) return read_push (Reader, i); return Reader; } - bool empty() const { - return Reader.empty(); + bool empty () const { + return Reader.empty (); } - bytes read_all() { - bytes b(Reader.End - Reader.Begin); - std::copy(Reader.Begin, Reader.End, b.begin()); + bytes read_all () { + bytes b (Reader.End - Reader.Begin); + std::copy (Reader.Begin, Reader.End, b.begin ()); Reader.Begin = Reader.End; return b; } - script_reader(bytes_reader r) : Reader{r} {} - script_reader(bytes_view b) : Reader{b.data(), b.data() + b.size()} {} + script_reader (bytes_reader r) : Reader {r} {} + script_reader (bytes_view b) : Reader {b.data (), b.data () + b.size ()} {} }; } - ScriptError instruction::verify(uint32 flags) const { - auto script_error = verify_instruction(*this); + ScriptError instruction::verify (uint32 flags) const { + auto script_error = verify_instruction (*this); if (script_error != SCRIPT_ERR_OK) return script_error; - if (flags & SCRIPT_VERIFY_MINIMALDATA && !is_minimal_push(Op, Data)) return SCRIPT_ERR_MINIMALDATA; + if (flags & SCRIPT_VERIFY_MINIMALDATA && !is_minimal_push (Op, Data)) return SCRIPT_ERR_MINIMALDATA; return SCRIPT_ERR_OK; } - bool is_minimal(const instruction& i) { - return verify_instruction(i) == SCRIPT_ERR_OK && is_minimal_push(i.Op, i.Data); + bool is_minimal (const instruction& i) { + return verify_instruction (i) == SCRIPT_ERR_OK && is_minimal_push (i.Op, i.Data); } - instruction instruction::read(bytes_view b) { + instruction instruction::read (bytes_view b) { instruction i; - script_reader{b} >> i; + script_reader {b} >> i; return i; } - instruction instruction::push(bytes_view data) { - int size = data.size(); - if (size == 0) return instruction{OP_0}; + instruction instruction::push (bytes_view data) { + int size = data.size (); + if (size == 0) return instruction {OP_0}; if (size == 1) { - if (data[0] == 0x81) return instruction{OP_1NEGATE}; - if (data[0] >= 0x01 && data[0] <= 0x10) return instruction{static_cast(data[0] + 0x50)}; + if (data[0] == 0x81) return instruction {OP_1NEGATE}; + if (data[0] >= 0x01 && data[0] <= 0x10) return instruction {static_cast (data[0] + 0x50)}; } - if (size <= OP_PUSHSIZE75) return instruction{static_cast(size), data}; - if (size <= 0xffff) return instruction{OP_PUSHDATA1, data}; - if (size <= 0xffffffff) return instruction{OP_PUSHDATA2, data}; - return instruction{OP_PUSHDATA4, data}; + if (size <= OP_PUSHSIZE75) return instruction {static_cast (size), data}; + if (size <= 0xffff) return instruction {OP_PUSHDATA1, data}; + if (size <= 0xffffffff) return instruction {OP_PUSHDATA2, data}; + return instruction {OP_PUSHDATA4, data}; } bytes instruction::data() const { - if (is_push_data(Op) || Op == OP_RETURN) return Data; - if (!is_push(Op)) return {}; + if (is_push_data (Op) || Op == OP_RETURN) return Data; + if (!is_push (Op)) return {}; if (Op == OP_1NEGATE) return {0x81}; - return bytes{static_cast(Op - 0x50)}; + return bytes {static_cast (Op - 0x50)}; } - uint32 instruction::serialized_size() const { - if (Op == OP_RETURN) return Data.size() + 1; - if (!is_push_data(Op)) return 1; - uint32 size = Data.size(); + uint32 instruction::serialized_size () const { + if (Op == OP_RETURN) return Data.size () + 1; + if (!is_push_data (Op)) return 1; + uint32 size = Data.size (); if (Op <= OP_PUSHSIZE75) return size + 1; if (Op == OP_PUSHDATA1) return size + 2; if (Op == OP_PUSHDATA2) return size + 3; @@ -175,32 +178,34 @@ namespace Gigamonkey::Bitcoin { return 0; // invalid } - std::ostream& write_asm(std::ostream& o, instruction i) { + std::ostream& write_asm (std::ostream& o, instruction i) { if (i.Op == OP_0) return o << "0"; - if (is_push_data(i.Op)) return o << data::encoding::hex::write(i.Data); + if (is_push_data (i.Op)) return o << data::encoding::hex::write (i.Data); return o << i.Op; } - string ASM(bytes_view b) { + string ASM (bytes_view b) { std::stringstream ss; - program p = decompile(b); - if (p.size() != 0) { - auto i = p.begin(); - write_asm(ss, *i); - while (++i != p.end()) write_asm(ss << " ", *i); + program p = decompile (b); + + if (p.size () != 0) { + auto i = p.begin (); + write_asm (ss, *i); + while (++i != p.end ()) write_asm (ss << " ", *i); } - return ss.str(); + + return ss.str (); } - bool is_minimal(bytes_view b) { - for (const instruction &i : decompile(b)) if (!is_minimal(i)) return false; + bool is_minimal (bytes_view b) { + for (const instruction &i : decompile (b)) if (!is_minimal (i)) return false; return true; } - std::ostream& write_op_code(std::ostream& o, op x) { + std::ostream& write_op_code (std::ostream& o, op x) { if (x == OP_FALSE) return o << "push_empty"; - if (is_push(x)) { - switch(x) { + if (is_push (x)) { + switch (x) { case OP_PUSHDATA1 : return o << "push_data_1"; case OP_PUSHDATA2 : return o << "push_data_2"; case OP_PUSHDATA4 : return o << "push_data_4"; @@ -222,7 +227,7 @@ namespace Gigamonkey::Bitcoin { case OP_14: return o << "(14)"; case OP_15: return o << "(15)"; case OP_16: return o << "(16)"; - default : return o << "push_size_" << int{x}; + default : return o << "push_size_" << int {x}; } } @@ -287,54 +292,56 @@ namespace Gigamonkey::Bitcoin { } } - std::ostream& operator<<(std::ostream& o, const instruction& i) { - if (!is_push_data(i.Op)) return write_op_code(o, i.Op); - return write_op_code(o, i.Op) << "{" << data::encoding::hex::write(i.Data) << "}"; + std::ostream& operator << (std::ostream& o, const instruction& i) { + if (!is_push_data (i.Op)) return write_op_code (o, i.Op); + return write_op_code (o, i.Op) << "{" << data::encoding::hex::write (i.Data) << "}"; } - bytes compile(program p) { - bytes compiled(serialized_size(p)); - bytes_writer b{compiled.begin(), compiled.end()}; - script_writer{b} << p; + bytes compile (program p) { + bytes compiled (serialized_size (p)); + bytes_writer b {compiled.begin (), compiled.end ()}; + script_writer {b} << p; return compiled; } - bytes compile(instruction i) { - bytes compiled(serialized_size(i)); - bytes_writer b{compiled.begin(), compiled.end()}; - script_writer{b} << i; + bytes compile (instruction i) { + bytes compiled (serialized_size (i)); + bytes_writer b {compiled.begin (), compiled.end ()}; + script_writer {b} << i; return compiled; } - program decompile(bytes_view b) { + program decompile (bytes_view b) { - program p{}; - script_reader r{bytes_reader{b.data(), b.data() + b.size()}}; + program p {}; + script_reader r {bytes_reader {b.data (), b.data () + b.size ()}}; stack Control; - while(!r.empty()) { - instruction i{}; + while(!r.empty ()) { + instruction i {}; r = r >> i; - if(i.verify(0) != SCRIPT_ERR_OK) return {}; + if (i.verify(0) != SCRIPT_ERR_OK) return {}; if (i.Op == OP_RETURN) { - if (data::empty(Control)) { - i.Data = r.read_all(); + if (data::empty (Control)) { + i.Data = r.read_all (); return p << i; }; } if (i.Op == OP_ENDIF) { - if (Control.empty()) return {}; - op prev = Control.first(); - Control = Control.rest(); + if (Control.empty ()) return {}; + op prev = Control.first (); + Control = Control.rest (); + if (prev == OP_ELSE) { - if (Control.empty()) return {}; - prev = Control.first(); - Control = Control.rest(); + if (Control.empty ()) return {}; + prev = Control.first (); + Control = Control.rest (); } + if (prev != OP_IF && prev != OP_NOTIF) return {}; } else if (i.Op == OP_ELSE || i.Op == OP_IF || i.Op == OP_NOTIF) Control = Control << i.Op; @@ -344,46 +351,48 @@ namespace Gigamonkey::Bitcoin { return p; } - ScriptError valid_program(program p, stack x, uint32 flags) { + ScriptError valid_program (program p, stack x, uint32 flags) { - if (data::empty(p)) { - if (x.empty()) return SCRIPT_ERR_OK; + if (data::empty (p)) { + if (x.empty ()) return SCRIPT_ERR_OK; return SCRIPT_ERR_UNBALANCED_CONDITIONAL; } bool utxo_after_genesis = (flags & SCRIPT_UTXO_AFTER_GENESIS) != 0; - const instruction& i = p.first(); + const instruction& i = p.first (); - auto script_error = i.verify(flags); + auto script_error = i.verify (flags); if (script_error != SCRIPT_ERR_OK) return script_error; - if ((flags & SCRIPT_VERIFY_MINIMALDATA) && !is_minimal(i)) return SCRIPT_ERR_MINIMALDATA; + if ((flags & SCRIPT_VERIFY_MINIMALDATA) && !is_minimal (i)) return SCRIPT_ERR_MINIMALDATA; op o = i.Op; if (o == OP_RETURN) { if (!utxo_after_genesis) return SCRIPT_ERR_OP_RETURN; - if (data::empty(x) && p.size() == 1) return SCRIPT_ERR_OK; - if (i.Data.size() != 0) return SCRIPT_ERR_OP_RETURN; + if (data::empty (x) && p.size () == 1) return SCRIPT_ERR_OK; + if (i.Data.size () != 0) return SCRIPT_ERR_OP_RETURN; } if (o == OP_ENDIF) { - if (x.empty()) return SCRIPT_ERR_UNBALANCED_CONDITIONAL; - op prev = x.first(); - x = x.rest(); + if (x.empty ()) return SCRIPT_ERR_UNBALANCED_CONDITIONAL; + op prev = x.first (); + x = x.rest (); + if (prev == OP_ELSE) { - if (x.empty()) return SCRIPT_ERR_UNBALANCED_CONDITIONAL; - prev = x.first(); - x = x.rest(); + if (x.empty ()) return SCRIPT_ERR_UNBALANCED_CONDITIONAL; + prev = x.first (); + x = x.rest (); } + if (prev != OP_IF && prev != OP_NOTIF) return SCRIPT_ERR_UNBALANCED_CONDITIONAL; } else if (o == OP_ELSE || o == OP_IF || o == OP_NOTIF) x = x << o; - return valid_program(p.rest(), x, flags); + return valid_program (p.rest (), x, flags); } - ScriptError verify(program p, uint32 flags) { + ScriptError verify (program p, uint32 flags) { bool script_genesis = (flags & SCRIPT_GENESIS) != 0; bool utxo_after_genesis = (flags & SCRIPT_UTXO_AFTER_GENESIS) != 0; @@ -395,12 +404,13 @@ namespace Gigamonkey::Bitcoin { // first we check for OP_RETURN data. if (script_genesis && utxo_after_genesis) { - if (p.size() == 2 && p.first().Op == OP_FALSE && p.first().valid() && p.rest().first().Op == OP_RETURN) return SCRIPT_ERR_OK; + if (p.size () == 2 && p.first ().Op == OP_FALSE && p.first ().valid () && p.rest ().first ().Op == OP_RETURN) + return SCRIPT_ERR_OK; } else { - if (p.size() == 1 && p.first().Op == OP_RETURN) return SCRIPT_ERR_OK; + if (p.size () == 1 && p.first ().Op == OP_RETURN) return SCRIPT_ERR_OK; } - return valid_program(p, {}, flags); + return valid_program (p, {}, flags); } } diff --git a/src/gigamonkey/script/pattern.cpp b/src/gigamonkey/script/pattern.cpp index 08a34291..5f437ade 100644 --- a/src/gigamonkey/script/pattern.cpp +++ b/src/gigamonkey/script/pattern.cpp @@ -3,140 +3,152 @@ #include #include -#include +#include namespace Gigamonkey { // We already know that o has size at least 1 // when we call this function. - uint32 next_instruction_size(bytes_view o) { - opcodetype op = opcodetype(o[0]); + uint32 next_instruction_size (bytes_view o) { + opcodetype op = opcodetype (o[0]); if (op == OP_INVALIDOPCODE) return 0; - if (!Bitcoin::is_push_data(opcodetype(op))) return 1; + if (!Bitcoin::is_push_data (opcodetype (op))) return 1; if (op <= Bitcoin::OP_PUSHSIZE75) return (op + 1); + if (op == OP_PUSHDATA1) { - if (o.size() < 2) return 0; + if (o.size () < 2) return 0; return o[1] + 2; } + if (op == OP_PUSHDATA2) { - if (o.size() < 3) return 0; - return boost::endian::load_little_u16(&o[1]) + 3; + if (o.size () < 3) return 0; + return boost::endian::load_little_u16 (&o[1]) + 3; } + // otherwise it's OP_PUSHDATA4 - if (o.size() < 5) return 0; - return boost::endian::load_little_u32(&o[1]) + 5; + if (o.size () < 5) return 0; + return boost::endian::load_little_u32 (&o[1]) + 5; } - bytes_view pattern::atom::scan(bytes_view p) const { - if (p.size() == 0) throw fail{}; - if (p[0] != Instruction.Op) throw fail{}; - uint32 size = next_instruction_size(p); - if (p.size() < size || Instruction != Bitcoin::instruction::read(p.substr(0, size))) throw fail{}; - return p.substr(size); + bytes_view pattern::atom::scan (bytes_view p) const { + if (p.size () == 0) throw fail {}; + if (p[0] != Instruction.Op) throw fail {}; + uint32 size = next_instruction_size (p); + if (p.size () < size || Instruction != Bitcoin::instruction::read (p.substr (0, size))) throw fail {}; + return p.substr (size); } - bytes_view pattern::string::scan(bytes_view p) const { - if (p.size() < Program.size()) throw fail{}; - for (int i = 0; i < Program.size(); i++) if (p[i] != Program[i]) throw fail{}; - return p.substr(Program.size()); + bytes_view pattern::string::scan (bytes_view p) const { + if (p.size () < Program.size ()) throw fail {}; + for (int i = 0; i < Program.size (); i++) if (p[i] != Program[i]) throw fail {}; + return p.substr (Program.size ()); } - bytes_view any::scan(bytes_view p) const { - if (p.size() == 0) throw fail{}; + bytes_view any::scan (bytes_view p) const { + if (p.size () == 0) throw fail {}; uint32 size = next_instruction_size(p); - if (p.size() < size) throw fail{}; - return p.substr(size); + if (p.size () < size) throw fail {}; + return p.substr (size); } bytes_view push::scan(bytes_view p) const { - if (p.size() == 0) throw fail{}; - uint32 size = next_instruction_size(p); - if (size == 0) throw fail{}; - if (!match(Bitcoin::instruction::read(p.substr(0, size)))) throw fail{}; - return p.substr(size); + if (p.size () == 0) throw fail {}; + uint32 size = next_instruction_size (p); + if (size == 0) throw fail {}; + + if (!match (Bitcoin::instruction::read (p.substr (0, size)))) + throw fail {}; + + return p.substr (size); } bytes_view push_size::scan(bytes_view p) const { - if (p.size() == 0) throw fail{}; - uint32 size = next_instruction_size(p); - if (!match(Bitcoin::instruction::read(p.substr(0, size)))) throw fail{}; - return p.substr(size); + if (p.size () == 0) throw fail {}; + uint32 size = next_instruction_size (p); + + if (!match (Bitcoin::instruction::read (p.substr (0, size)))) + throw fail {}; + + return p.substr (size); } bytes_view op_return_data::scan(bytes_view p) const { - if (p.size() == 0) throw fail{}; - if (p[0] != OP_RETURN) throw fail{}; - return pattern::scan(p.substr(1)); + if (p.size() == 0) throw fail {}; + if (p[0] != OP_RETURN) throw fail {}; + return pattern::scan (p.substr (1)); } - bool push::match(const Bitcoin::instruction& i) const { + bool push::match (const Bitcoin::instruction& i) const { switch (Type) { case any : - return Bitcoin::is_push(i.Op); + return Bitcoin::is_push (i.Op); case value : - return Bitcoin::is_push(i.Op) && Value == Bitcoin::Z{bytes_view(i.data())}; + return Bitcoin::is_push (i.Op) && Value == Bitcoin::Z {bytes_view (i.data ())}; case data : - return Bitcoin::is_push(i.Op) && Data == i.data(); + return Bitcoin::is_push (i.Op) && Data == i.data (); case read : - if (!Bitcoin::is_push(i.Op)) return false; - Read = i.data(); + if (!Bitcoin::is_push (i.Op)) return false; + Read = i.data (); return true; default: return false; } } - bool push_size::match(const Bitcoin::instruction& i) const { - bytes Data = i.data(); - if (Data.size() != Size) return false; + bool push_size::match (const Bitcoin::instruction& i) const { + bytes Data = i.data (); + if (Data.size () != Size) return false; if (Reader) Read = Data; return true; } - bytes_view pattern::sequence::scan(bytes_view p) const { + bytes_view pattern::sequence::scan (bytes_view p) const { list> patt = Patterns; - while (!data::empty(patt)) { - p = patt.first()->scan(p); - patt = patt.rest(); + while (!data::empty (patt)) { + p = patt.first ()->scan (p); + patt = patt.rest (); } return p; } - bytes_view optional::scan(bytes_view p) const { + bytes_view optional::scan (bytes_view p) const { try { - return pattern::Pattern->scan(p); + return pattern::Pattern->scan (p); } catch (fail) { return p; } } - bytes_view repeated::scan(bytes_view p) const { + bytes_view repeated::scan (bytes_view p) const { ptr patt = pattern::Pattern; uint32 min = Second == -1 && Directive == or_less ? 0 : First; int64 max = Second != -1 ? Second : Directive == or_more ? -1 : First; uint32 matches = 0; + while (true) { try { - p = patt->scan(p); + p = patt->scan (p); matches++; if (matches == max) return p; } catch (fail) { - if (matches < min) throw fail{}; + if (matches < min) throw fail {}; return p; } } } - bytes_view alternatives::scan(bytes_view b) const { + bytes_view alternatives::scan (bytes_view b) const { list> patt = Patterns; - while (!data::empty(patt)) { + + while (!data::empty (patt)) { try { - return patt.first()->scan(b); + return patt.first ()->scan (b); } catch (fail) { - patt = patt.rest(); + patt = patt.rest (); } } - throw fail{}; + + throw fail {}; }; } diff --git a/test/testStratum.cpp b/test/testStratum.cpp index 8878e05a..4e42c2e6 100644 --- a/test/testStratum.cpp +++ b/test/testStratum.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "gtest/gtest.h" namespace Gigamonkey::Stratum { @@ -130,7 +131,7 @@ namespace Gigamonkey::Stratum::mining { message_id ID; authorize_request::parameters Params; - operator authorize_reques t() const { + operator authorize_request () const { if (Params.Password) return authorize_request {ID, Params.Username, *Params.Password}; return authorize_request {ID, Params.Username}; } @@ -366,7 +367,7 @@ namespace Gigamonkey::Stratum::mining { } } - +/* namespace Gigamonkey { template @@ -416,4 +417,4 @@ namespace Gigamonkey::Stratum { } -} +}*/ From 27e294c57554b390b799772c31d6b0bf3d6f406b Mon Sep 17 00:00:00 2001 From: KatrinaAS Date: Tue, 21 Mar 2023 18:20:31 +0000 Subject: [PATCH 08/11] feat: Fix minor packaging error --- conanfile.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 15ad3711..3382366e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -52,6 +52,5 @@ def package (self): cmake.install() def package_info (self): - self.cpp_info.libdirs = ["lib"] # Default value is 'lib' - self.cpp_info.libs = self.collect_libs () -# self.cpp_info.libs = ["gigamonkey"] +# self.cpp_info.libdirs = ["lib"] # Default value is 'lib' + self.cpp_info.libs = ["gigamonkey"] From 7c62148979b56b141fe615ffcad8e117693ee4ce Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Wed, 29 Mar 2023 11:44:59 -0500 Subject: [PATCH 09/11] Update with new version of data. --- include/gigamonkey/number.hpp | 8 ++++---- include/gigamonkey/stratum/extensions.hpp | 2 +- include/gigamonkey/stratum/session_id.hpp | 2 +- src/gigamonkey/script/typed_data_bip_276.cpp | 4 ++-- src/gigamonkey/stratum/mining.cpp | 14 +++++++------- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/gigamonkey/number.hpp b/include/gigamonkey/number.hpp index caac942d..27897f21 100644 --- a/include/gigamonkey/number.hpp +++ b/include/gigamonkey/number.hpp @@ -342,7 +342,7 @@ namespace Gigamonkey { inline uint::operator string () const { bytes r (X); std::copy (begin (), end (), r.rbegin ()); - return string {"0x"} + data::encoding::hex::write (r, data::encoding::hex::lower); + return string {"0x"} + encoding::hex::write (r, hex_case::lower); } template @@ -356,12 +356,12 @@ namespace data::encoding::hexidecimal { template std::string inline write (const Gigamonkey::uint& n) { - return write ((data::N) (n)); + return write ((data::N) (n)); } template std::ostream inline &write (std::ostream& o, const Gigamonkey::uint& n) { - return o << write (data::N (n)); + return o << write (data::N (n)); } } @@ -411,7 +411,7 @@ namespace Gigamonkey { template uint::uint(const N& n) : uint(0) { - ptr b = encoding::hex::read (encoding::hexidecimal::write (n).substr (2)); + ptr b = encoding::hex::read (encoding::hexidecimal::write (n).substr (2)); std::reverse(b->begin (), b->end ()); if (b->size () > X) std::copy(b->begin (), b->begin () + X, begin ()); else std::copy(b->begin (), b->end(), begin ()); diff --git a/include/gigamonkey/stratum/extensions.hpp b/include/gigamonkey/stratum/extensions.hpp index 1965013b..3a6f70d6 100644 --- a/include/gigamonkey/stratum/extensions.hpp +++ b/include/gigamonkey/stratum/extensions.hpp @@ -155,7 +155,7 @@ namespace Gigamonkey::Stratum::extensions { }; inline encoding::hex::fixed<4> write_version_mask(const version_mask& x) { - return encoding::hex::write(x, encoding::hex::lower); + return encoding::hex::write(x, hex_case::lower); } inline accepted::accepted() : std::variant{std::monostate{}} {} diff --git a/include/gigamonkey/stratum/session_id.hpp b/include/gigamonkey/stratum/session_id.hpp index f9d27bbe..bc331f3b 100644 --- a/include/gigamonkey/stratum/session_id.hpp +++ b/include/gigamonkey/stratum/session_id.hpp @@ -50,7 +50,7 @@ namespace Gigamonkey::Stratum { } inline session_id::operator encoding::hex::fixed<4>() const { - return encoding::hex::write(*this, encoding::hex::lower); + return encoding::hex::write(*this, hex_case::lower); } } diff --git a/src/gigamonkey/script/typed_data_bip_276.cpp b/src/gigamonkey/script/typed_data_bip_276.cpp index bcd4660e..51f4c5b9 100644 --- a/src/gigamonkey/script/typed_data_bip_276.cpp +++ b/src/gigamonkey/script/typed_data_bip_276.cpp @@ -16,11 +16,11 @@ namespace Gigamonkey { bytes data = bytes::write (b.size() + 2, version, byte(n), b); - ss << ':' << encoding::hex::write (data, encoding::hex::lower); + ss << ':' << encoding::hex::write (data, hex_case::lower); auto checksum = Bitcoin::checksum (bytes::from_string(ss.str())); - ss << encoding::hex::write (checksum, encoding::hex::lower); + ss << encoding::hex::write (checksum, hex_case::lower); return ss.str (); } diff --git a/src/gigamonkey/stratum/mining.cpp b/src/gigamonkey/stratum/mining.cpp index 0033bfa5..bca75657 100644 --- a/src/gigamonkey/stratum/mining.cpp +++ b/src/gigamonkey/stratum/mining.cpp @@ -16,7 +16,7 @@ namespace Gigamonkey::Stratum::mining { encoding::hex::fixed<32> inline write(const uint256& x) { uint256 z = x; for (int i = 0; i < 32; i+=4) std::reverse(z.begin() + i, z.begin() + i + 3); - return encoding::hex::write(z, encoding::hex::lower); + return encoding::hex::write(z, hex_case::lower); } bool read(const JSON& j, uint256& x) { @@ -30,7 +30,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::string inline write(const bytes& b) { - return encoding::hex::write(b, encoding::hex::lower); + return encoding::hex::write(b, hex_case::lower); } bool read(const JSON& j, bytes& x) { @@ -65,7 +65,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::fixed<4> inline write(const int32_little& x) { - return encoding::hex::write(x, encoding::hex::lower); + return encoding::hex::write(x, hex_case::lower); } bool read(const JSON& j, int32_little& x) { @@ -81,7 +81,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::fixed<4> inline write(const work::compact& x) { - return encoding::hex::write(uint32_big{static_cast(x)}, encoding::hex::lower); + return encoding::hex::write(uint32_big{static_cast(x)}, hex_case::lower); } bool read(const JSON& j, work::compact& x) { @@ -97,7 +97,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::fixed<4> inline write(const Bitcoin::timestamp& x) { - return encoding::hex::write(uint32_big{x.Value}, encoding::hex::lower); + return encoding::hex::write(uint32_big{x.Value}, hex_case::lower); } bool read(const JSON& j, Bitcoin::timestamp& x) { @@ -113,7 +113,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::fixed<8> inline write(const uint64_big& x) { - return encoding::hex::write(x, encoding::hex::lower); + return encoding::hex::write(x, hex_case::lower); } bool inline read(const JSON& j, uint64_big& x) { @@ -126,7 +126,7 @@ namespace Gigamonkey::Stratum::mining { } encoding::hex::fixed<4> inline write(const nonce& x) { - return encoding::hex::write(uint32_big{x}, encoding::hex::lower); + return encoding::hex::write(uint32_big{x}, hex_case::lower); } bool read(const JSON& j, nonce& x) { From aac9d67505205636bbe8a491b2c43d4c8d1b6f48 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Wed, 29 Mar 2023 11:22:43 -0500 Subject: [PATCH 10/11] Update with new URL format --- include/gigamonkey/address.hpp | 4 +- include/gigamonkey/boost/boost.hpp | 101 ++-- include/gigamonkey/hash.hpp | 21 +- include/gigamonkey/mapi/envelope.hpp | 77 ++- include/gigamonkey/mapi/mapi.hpp | 22 +- include/gigamonkey/merkle/serialize.hpp | 336 +++++----- include/gigamonkey/number.hpp | 36 +- include/gigamonkey/script/machine.hpp | 75 +-- include/gigamonkey/stratum/extensions.hpp | 168 ++--- include/gigamonkey/stratum/mining.hpp | 70 +-- .../gigamonkey/stratum/mining_authorize.hpp | 74 +-- .../stratum/mining_set_extranonce.hpp | 28 +- .../stratum/mining_set_version_mask.hpp | 28 +- .../gigamonkey/stratum/mining_subscribe.hpp | 200 +++--- include/gigamonkey/stratum/session_id.hpp | 44 +- include/gigamonkey/stratum/stratum.hpp | 140 ++--- include/gigamonkey/work/proof.hpp | 110 ++-- include/sv/policy/policy.h | 14 +- include/sv/script/interpreter.h | 36 +- src/gigamonkey/address.cpp | 8 +- src/gigamonkey/boost/boost.cpp | 2 +- src/gigamonkey/mapi/envelope.cpp | 54 +- src/gigamonkey/mapi/mapi.cpp | 28 +- src/gigamonkey/merkle.cpp | 239 ++++---- src/gigamonkey/merkle/dual.cpp | 190 +++--- src/gigamonkey/merkle/serialize.cpp | 281 ++++----- src/gigamonkey/p2p/checksum.cpp | 35 +- src/gigamonkey/script/machine.cpp | 572 +++++++++--------- src/gigamonkey/script/typed_data_bip_276.cpp | 4 +- src/gigamonkey/stratum/extensions.cpp | 58 +- src/gigamonkey/stratum/mining.cpp | 204 +++---- src/gigamonkey/stratum/mining_authorize.cpp | 34 +- src/gigamonkey/stratum/stratum.cpp | 58 +- src/gigamonkey/wif.cpp | 10 +- src/sv/script/interpreter.cpp | 34 +- test/testBoost.cpp | 6 +- test/testFormat.cpp | 12 +- test/testPush.cpp | 110 ++-- test/testStratum.cpp | 6 +- test/testTransaction.cpp | 30 +- test/testWorkString.cpp | 50 +- 41 files changed, 1834 insertions(+), 1775 deletions(-) diff --git a/include/gigamonkey/address.hpp b/include/gigamonkey/address.hpp index a83894f5..1ee3cfc1 100644 --- a/include/gigamonkey/address.hpp +++ b/include/gigamonkey/address.hpp @@ -74,8 +74,8 @@ namespace Gigamonkey::Bitcoin { pubkey (const secp256k1::pubkey &p) : secp256k1::pubkey {p} {} explicit pubkey (string_view s) : secp256k1::pubkey {} { - ptr hex = encoding::hex::read(s); - if (hex != nullptr) { + maybe hex = encoding::hex::read(s); + if (bool (hex)) { this->resize (hex->size ()); std::copy (hex->begin (), hex->end (), this->begin ()); }; diff --git a/include/gigamonkey/boost/boost.hpp b/include/gigamonkey/boost/boost.hpp index d5a1720c..c20ee009 100644 --- a/include/gigamonkey/boost/boost.hpp +++ b/include/gigamonkey/boost/boost.hpp @@ -73,21 +73,21 @@ namespace Gigamonkey { static output_script bounty ( int32_little category, - const uint256& content, + const uint256 &content, work::compact target, - const bytes& tag, + const bytes &tag, uint32_little user_nonce, - const bytes& data, + const bytes &data, bool use_general_purpose_bits = true); static output_script contract ( int32_little category, - const uint256& content, + const uint256 &content, work::compact target, - const bytes& tag, + const bytes &tag, uint32_little user_nonce, - const bytes& data, - const digest160& miner_pubkey_hash, + const bytes &data, + const digest160 &miner_pubkey_hash, bool use_general_purpose_bits = true); bool valid () const; @@ -122,32 +122,32 @@ namespace Gigamonkey { private: output_script ( int32_little category, - const uint256& content, + const uint256 &content, work::compact target, - const bytes& tag, + const bytes &tag, uint32_little user_nonce, - const bytes& data, + const bytes &data, bool use_general_purpose_bits = true); output_script ( int32_little category, - const uint256& content, + const uint256 &content, work::compact target, - const bytes& tag, + const bytes &tag, uint32_little user_nonce, - const bytes& data, + const bytes &data, const digest160& miner_pubkey_hash, bool use_general_purpose_bits = true); output_script ( Boost::type type, int32_little category, - const uint256& content, + const uint256 &content, work::compact target, - const bytes& tag, + const bytes &tag, uint32_little user_nonce, - const bytes& data, - const digest160& miner_pubkey_hash, + const bytes &data, + const digest160 &miner_pubkey_hash, bool use_general_purpose_bits = true); }; @@ -161,47 +161,47 @@ namespace Gigamonkey { Bitcoin::timestamp Timestamp; bytes ExtraNonce2; Stratum::session_id ExtraNonce1; - std::optional GeneralPurposeBits; + maybe GeneralPurposeBits; digest160 MinerPubkeyHash; private: // bounty type, no ASICBoost input_script ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, - const digest160& miner_pubkey_hash); + const digest160 &miner_pubkey_hash); // contract type, no ASICBoost input_script ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1); // bounty type compatible with ASICBoost input_script ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, int32_little general_purpose_bits, - const digest160& miner_pubkey_hash); + const digest160 &miner_pubkey_hash); // contract type compatible with ASICBoost; input_script ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, int32_little general_purpose_bits); @@ -218,41 +218,41 @@ namespace Gigamonkey { // construct a Boost bounty input script. static input_script bounty ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, - const digest160& miner_pubkey_hash); + const digest160 &miner_pubkey_hash); // construct a Boost contract input script. static input_script contract ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1); // construct a Boost bounty input script. static input_script bounty ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, int32_little category_bits, - const digest160& miner_pubkey_hash); + const digest160 &miner_pubkey_hash); // construct a Boost contract input script. static input_script contract ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, uint32_little nonce, Bitcoin::timestamp timestamp, - const bytes& extra_nonce_2, + const bytes &extra_nonce_2, Stratum::session_id extra_nonce_1, int32_little category_bits); @@ -269,9 +269,9 @@ namespace Gigamonkey { static digest160 miner_pubkey_hash (script x); input_script ( - const Bitcoin::signature& signature, - const Bitcoin::pubkey& pubkey, - const work::solution&, Boost::type, + const Bitcoin::signature &signature, + const Bitcoin::pubkey &pubkey, + const work::solution &, Boost::type, bool category_mask); static uint64 expected_size (Boost::type t, bool use_general_purpose_bits, bool compressed_pubkey = true); @@ -475,7 +475,8 @@ namespace Gigamonkey { work::compact target, const bytes &tag, uint32_little user_nonce, - const bytes &data, bool masked_category) { + const bytes &data, + bool masked_category) { if (tag.size() > 20) return output_script {}; return output_script{category, content, target, tag, user_nonce, data, masked_category}; } diff --git a/include/gigamonkey/hash.hpp b/include/gigamonkey/hash.hpp index 7d3e173a..59b63521 100644 --- a/include/gigamonkey/hash.hpp +++ b/include/gigamonkey/hash.hpp @@ -239,7 +239,7 @@ namespace Gigamonkey { transform Hash; - hash_writer () : Hash{} {} + hash_writer () : Hash {} {} digest finalize () { digest d; @@ -254,7 +254,7 @@ namespace Gigamonkey { return d; } - void write(const byte* b, size_t x) override { + void write (const byte* b, size_t x) override { Hash.Update (b, x); } @@ -301,7 +301,7 @@ namespace Gigamonkey { using SHA3_512_writer = SHA3_writer<64>; digest160 inline SHA1 (bytes_view b) { - return SHA1_writer{} (b); + return SHA1_writer {} (b); } digest224 inline SHA2_224 (bytes_view b) { @@ -325,19 +325,19 @@ namespace Gigamonkey { } digest256 inline SHA3_256 (bytes_view b) { - return SHA3_256_writer{} (b); + return SHA3_256_writer {} (b); } digest384 inline SHA3_384 (bytes_view b) { - return SHA3_384_writer{} (b); + return SHA3_384_writer {} (b); } digest512 inline SHA3_512 (bytes_view b) { - return SHA3_512_writer{} (b); + return SHA3_512_writer {} (b); } digest128 inline RIPEMD_128 (bytes_view b) { - return RIPEMD_128_writer{} (b); + return RIPEMD_128_writer {} (b); } digest160 inline RIPEMD_160 (bytes_view b) { @@ -385,10 +385,9 @@ namespace Gigamonkey { template digest::digest (string_view s) { - ptr b = data::encoding::hex::read (s); - if (b != nullptr) { - std::copy (b->begin (), b->end (), begin ()); - } else *this = digest {uint {string (s)}}; + maybe b = data::encoding::hex::read (s); + if (bool (b)) std::copy (b->begin (), b->end (), begin ()); + else *this = digest {uint {string (s)}}; } template diff --git a/include/gigamonkey/mapi/envelope.hpp b/include/gigamonkey/mapi/envelope.hpp index d111aef5..74b8d254 100644 --- a/include/gigamonkey/mapi/envelope.hpp +++ b/include/gigamonkey/mapi/envelope.hpp @@ -11,7 +11,6 @@ // https://github.com/bitcoin-sv-specs/brfc-misc/tree/master/jsonenvelope namespace Gigamonkey::BitcoinAssociation { - template using optional = std::optional; struct JSON_envelope { enum payload_encoding { @@ -24,77 +23,77 @@ namespace Gigamonkey::BitcoinAssociation { payload_encoding Encoding; string Mimetype; - optional PublicKey; - optional Signature; + maybe PublicKey; + maybe Signature; - bool valid() const; - bool verify() const; + bool valid () const; + bool verify () const; // encode as base64, no signature. - JSON_envelope(const bytes &Payload, const string &Mimetype); + JSON_envelope (const bytes &Payload, const string &Mimetype); // encode as UTF_8, no signature. - JSON_envelope(const string &Payload, const string &Mimetype); + JSON_envelope (const string &Payload, const string &Mimetype); // encode as base64 with signature. - JSON_envelope(const bytes &Payload, const string &Mimetype, secp256k1::secret &secret); + JSON_envelope (const bytes &Payload, const string &Mimetype, secp256k1::secret &secret); // encode as UTF_8 with signature. - JSON_envelope(const string &Payload, const string &Mimetype, secp256k1::secret &secret); + JSON_envelope (const string &Payload, const string &Mimetype, secp256k1::secret &secret); - JSON_envelope(const JSON &); - operator JSON() const; + JSON_envelope (const JSON &); + operator JSON () const; - static bool valid(const JSON&); - static bool verify(const JSON&); + static bool valid (const JSON &); + static bool verify (const JSON &); - JSON_envelope() : Payload{}, Encoding{none}, Mimetype{}, PublicKey{}, Signature{} {} + JSON_envelope () : Payload {}, Encoding {none}, Mimetype {}, PublicKey {}, Signature {} {} }; // A JSON_envelope that contains JSON data. struct JSON_JSON_envelope : JSON_envelope { - bool valid() const; + bool valid () const; - static string de_escape(const string &); + static string de_escape (const string &); - JSON payload() const { - return JSON::parse(JSON_envelope::Payload); + JSON payload () const { + return JSON::parse (JSON_envelope::Payload); } - JSON_JSON_envelope(const JSON &payload): - JSON_envelope{payload.dump(), "application/JSON"} {}; + JSON_JSON_envelope (const JSON &payload): + JSON_envelope {payload.dump (), "application/JSON"} {}; - JSON_JSON_envelope(const JSON &payload, secp256k1::secret &secret): - JSON_envelope{payload.dump(), "application/JSON", secret} {} + JSON_JSON_envelope (const JSON &payload, secp256k1::secret &secret): + JSON_envelope {payload.dump (), "application/JSON", secret} {} - JSON_JSON_envelope(const JSON_envelope &j) : JSON_envelope{j} {} + JSON_JSON_envelope (const JSON_envelope &j) : JSON_envelope {j} {} }; - bool inline JSON_envelope::valid() const { - return Encoding != none && ((bool(Signature) && bool(PublicKey)) || (!bool(Signature) && !bool(PublicKey))); + bool inline JSON_envelope::valid () const { + return Encoding != none && ((bool (Signature) && bool (PublicKey)) || (!bool (Signature) && !bool (PublicKey))); } - bool inline JSON_envelope::valid(const JSON &j) { - return JSON_envelope{j}.valid(); + bool inline JSON_envelope::valid (const JSON &j) { + return JSON_envelope {j}.valid (); } - bool inline JSON_envelope::verify(const JSON &j) { - return JSON_envelope{j}.verify(); + bool inline JSON_envelope::verify (const JSON &j) { + return JSON_envelope {j}.verify (); } - inline JSON_envelope::JSON_envelope(const bytes &pl, const string &mime) : - Payload{encoding::base64::write(pl)}, Encoding{base64}, Mimetype{mime}, PublicKey{}, Signature{} {} + inline JSON_envelope::JSON_envelope (const bytes &pl, const string &mime) : + Payload {encoding::base64::write (pl)}, Encoding {base64}, Mimetype {mime}, PublicKey {}, Signature {} {} - inline JSON_envelope::JSON_envelope(const string &pl, const string &mime) : - Payload{pl}, Encoding{UTF_8}, Mimetype{mime}, PublicKey{}, Signature{} {} + inline JSON_envelope::JSON_envelope (const string &pl, const string &mime) : + Payload {pl}, Encoding {UTF_8}, Mimetype {mime}, PublicKey {}, Signature {} {} - inline JSON_envelope::JSON_envelope(const bytes &pl, const string &mime, secp256k1::secret &secret) : - Payload{encoding::base64::write(pl)}, Encoding{base64}, Mimetype{mime}, - PublicKey{secret.to_public()}, Signature{secret.sign(Gigamonkey::SHA2_256(pl))} {} + inline JSON_envelope::JSON_envelope (const bytes &pl, const string &mime, secp256k1::secret &secret) : + Payload {encoding::base64::write (pl)}, Encoding {base64}, Mimetype {mime}, + PublicKey {secret.to_public ()}, Signature {secret.sign (Gigamonkey::SHA2_256 (pl))} {} - inline JSON_envelope::JSON_envelope(const string &pl, const string &mime, secp256k1::secret &secret) : - Payload{pl}, Encoding{UTF_8}, Mimetype{mime}, PublicKey{secret.to_public()}, - Signature{secret.sign(Gigamonkey::SHA2_256(encoding::unicode::utf8_encode(pl)))} {} + inline JSON_envelope::JSON_envelope (const string &pl, const string &mime, secp256k1::secret &secret) : + Payload {pl}, Encoding {UTF_8}, Mimetype {mime}, PublicKey{secret.to_public ()}, + Signature {secret.sign (Gigamonkey::SHA2_256 (pl))} {} } #endif diff --git a/include/gigamonkey/mapi/mapi.hpp b/include/gigamonkey/mapi/mapi.hpp index 149ef61c..60aa4d50 100644 --- a/include/gigamonkey/mapi/mapi.hpp +++ b/include/gigamonkey/mapi/mapi.hpp @@ -25,7 +25,7 @@ namespace Gigamonkey::BitcoinAssociation { get_fee_quote_response get_fee_quote (); struct transaction_status_response; - transaction_status_response get_transaction_status (const Bitcoin::txid&); + transaction_status_response get_transaction_status (const Bitcoin::txid &); struct submit_transaction_request; struct submit_transaction_response; @@ -159,10 +159,10 @@ namespace Gigamonkey::BitcoinAssociation { secp256k1::pubkey MinerID; uint32 TxSecondMempoolExpiry; - // optional fields included for txs that have been mined. - optional BlockHash; - optional BlockHeight; - optional Confirmations; + // maybe fields included for txs that have been mined. + maybe BlockHash; + maybe BlockHeight; + maybe Confirmations; bool valid () const; @@ -201,12 +201,12 @@ namespace Gigamonkey::BitcoinAssociation { struct submit_transaction_parameters { - optional CallbackURL; - optional CallbackToken; - optional MerkleProof; - optional MerkleFormat; - optional DSCheck; - optional CallbackEncryption; + maybe CallbackURL; + maybe CallbackToken; + maybe MerkleProof; + maybe MerkleFormat; + maybe DSCheck; + maybe CallbackEncryption; submit_transaction_parameters () = default; diff --git a/include/gigamonkey/merkle/serialize.hpp b/include/gigamonkey/merkle/serialize.hpp index 63e95453..ee1d0dd9 100644 --- a/include/gigamonkey/merkle/serialize.hpp +++ b/include/gigamonkey/merkle/serialize.hpp @@ -29,21 +29,21 @@ namespace Gigamonkey::BitcoinAssociation { // this only checks if the format is valid, but the information in the // serialized format isn't always enoughdoes not check the Merkle proof, // so we don't try to check the proof itself. - bool valid() const; - static bool valid(const JSON&); - static bool valid(bytes_view); + bool valid () const; + static bool valid (const JSON &); + static bool valid (bytes_view); // the proof format has both a binary and a JSON representation. - static proofs_serialization_standard read_JSON(const JSON&); - static proofs_serialization_standard read_binary(bytes_view); + static proofs_serialization_standard read_JSON (const JSON &); + static proofs_serialization_standard read_binary (bytes_view); - explicit operator JSON() const; - explicit operator bytes() const; + explicit operator JSON () const; + explicit operator bytes () const; // whether the full transaction is included or just the txid. - static bool transaction_included(bytes_view); - static bool transaction_included(const JSON&); - bool transaction_included() const; + static bool transaction_included (bytes_view); + static bool transaction_included (const JSON &); + bool transaction_included () const; // the target refers to the final element of the proof. enum target_type_value { @@ -53,9 +53,9 @@ namespace Gigamonkey::BitcoinAssociation { target_type_invalid = 6 }; - static target_type_value target_type(bytes_view); - static target_type_value target_type(const JSON&); - target_type_value target_type() const; + static target_type_value target_type (bytes_view); + static target_type_value target_type (const JSON &); + target_type_value target_type () const; // only proof_type_branch is supported for now. enum proof_type_value { @@ -63,49 +63,49 @@ namespace Gigamonkey::BitcoinAssociation { proof_type_tree = 8 }; - static proof_type_value proof_type(bytes_view); - static proof_type_value proof_type(const JSON&); - proof_type_value proof_type() const; + static proof_type_value proof_type (bytes_view); + static proof_type_value proof_type (const JSON &); + proof_type_value proof_type () const; // composite proofs are not yet supported, so these should always return false. - static bool composite_proof(bytes_view); - static bool composite_proof(const JSON&); - bool composite_proof() const; + static bool composite_proof (bytes_view); + static bool composite_proof (const JSON &); + bool composite_proof () const; // transaction not included, target omitted. - proofs_serialization_standard(const Merkle::branch&); + proofs_serialization_standard (const Merkle::branch &); // transaction not included, target Merkle root. - proofs_serialization_standard(const Merkle::proof&); + proofs_serialization_standard (const Merkle::proof &); // transaction not included, target header. - proofs_serialization_standard(const Merkle::branch&, const Bitcoin::header&); + proofs_serialization_standard (const Merkle::branch &, const Bitcoin::header &); // transaction not included, target block hash. - proofs_serialization_standard(const Merkle::branch&, const digest256& block_hash); + proofs_serialization_standard (const Merkle::branch &, const digest256 &block_hash); // transaction not included, target omitted. - proofs_serialization_standard(const Bitcoin::transaction&, const Merkle::path&); + proofs_serialization_standard (const Bitcoin::transaction &, const Merkle::path &); // transaction not included, target header. - proofs_serialization_standard(const Bitcoin::transaction&, const Merkle::path&, const Bitcoin::header&); + proofs_serialization_standard (const Bitcoin::transaction &, const Merkle::path &, const Bitcoin::header &); // transaction not included, target merkle root or block header depending on the value of the target type. - proofs_serialization_standard(const Bitcoin::transaction&, const Merkle::path&, const digest256& hash, target_type_value); + proofs_serialization_standard (const Bitcoin::transaction &, const Merkle::path &, const digest256 &hash, target_type_value); // all paths that might be included in this message. // since we are only doing single paths for now, there // will only be one entry in this map. - map paths() const; - static map paths(bytes_view); - static map paths(const JSON&); + map paths () const; + static map paths (bytes_view); + static map paths (const JSON &); // various kinds of targets that might be included. - std::optional block_hash() const; - std::optional Merkle_root() const; - std::optional block_header() const; + maybe block_hash () const; + maybe Merkle_root () const; + maybe block_header () const; - static std::optional block_hash(const JSON&); - static std::optional Merkle_root(const JSON&); - static std::optional block_header(const JSON&); + static maybe block_hash (const JSON &); + static maybe Merkle_root (const JSON &); + static maybe block_header (const JSON &); - static std::optional block_hash(bytes_view); - static std::optional Merkle_root(bytes_view); - static std::optional block_header(bytes_view); + static maybe block_hash (bytes_view); + static maybe Merkle_root (bytes_view); + static maybe block_header (bytes_view); // We can always calculate a root from the given information // but not necessarily check the whole proof. @@ -114,271 +114,271 @@ namespace Gigamonkey::BitcoinAssociation { private: // Everything below this point is subject to change as // more about the composite format is specified. - proofs_serialization_standard() {} + proofs_serialization_standard () {} // the first byte in the binary representation is the flags. // the JSON representation omits flags as it can be derived from // the rest of the structure. - byte flags() const; - static byte flags(const JSON&); - static byte flags(bytes_view); + byte flags () const; + static byte flags (const JSON &); + static byte flags (bytes_view); - static bool transaction_included(byte flags); - static target_type_value target_type(byte flags); - static proof_type_value proof_type(byte flags); - static bool composite_proof(byte flags); + static bool transaction_included (byte flags); + static target_type_value target_type (byte flags); + static proof_type_value proof_type (byte flags); + static bool composite_proof (byte flags); - uint32 index() const; - static uint32 index(bytes_view); - static uint32 index(const JSON&); + uint32 index () const; + static uint32 index (bytes_view); + static uint32 index (const JSON &); - digest256 txid() const; - static digest256 txid(bytes_view); - static digest256 txid(const JSON&); + digest256 txid () const; + static digest256 txid (bytes_view); + static digest256 txid (const JSON &); - Merkle::leaf leaf() const; - static Merkle::leaf leaf(bytes_view); - static Merkle::leaf leaf(const JSON&); + Merkle::leaf leaf () const; + static Merkle::leaf leaf (bytes_view); + static Merkle::leaf leaf (const JSON &); - Merkle::path path() const; - static Merkle::path path(bytes_view); - static Merkle::path path(const JSON&); + Merkle::path path () const; + static Merkle::path path (bytes_view); + static Merkle::path path (const JSON &); - Merkle::branch branch() const; - static Merkle::branch branch(bytes_view); - static Merkle::branch branch(const JSON&); + Merkle::branch branch () const; + static Merkle::branch branch (bytes_view); + static Merkle::branch branch (const JSON &); // one of these must be included. - std::optional Transaction; - std::optional Txid; + maybe Transaction; + maybe Txid; // there is always at least one path. Merkle::path Path; // one of these must be included. - std::optional BlockHash; - std::optional MerkleRoot; - std::optional BlockHeader; + maybe BlockHash; + maybe MerkleRoot; + maybe BlockHeader; }; - digest256 read_digest(const string&); - string write_digest(const digest256&); + digest256 read_digest (const string &); + string write_digest (const digest256 &); - bool inline proofs_serialization_standard::valid(bytes_view b) { - return read_binary(b).valid(); + bool inline proofs_serialization_standard::valid (bytes_view b) { + return read_binary (b).valid (); } - byte inline proofs_serialization_standard::flags(bytes_view b) { - if (b.size() == 0) return 0; + byte inline proofs_serialization_standard::flags (bytes_view b) { + if (b.size () == 0) return 0; return b[0]; } - byte inline proofs_serialization_standard::flags() const { - return (composite_proof() << 4) + proof_type() + target_type() + transaction_included(); + byte inline proofs_serialization_standard::flags () const { + return (composite_proof () << 4) + proof_type () + target_type () + transaction_included (); } - byte inline proofs_serialization_standard::flags(const JSON &j) { - return (composite_proof(j) << 4) + proof_type(j) + target_type(j) + transaction_included(j); + byte inline proofs_serialization_standard::flags (const JSON &j) { + return (composite_proof (j) << 4) + proof_type (j) + target_type (j) + transaction_included (j); } - bool inline proofs_serialization_standard::transaction_included(byte flags) { + bool inline proofs_serialization_standard::transaction_included (byte flags) { return flags & 1; } - bool inline proofs_serialization_standard::transaction_included(bytes_view b) { - return transaction_included(flags(b)); + bool inline proofs_serialization_standard::transaction_included (bytes_view b) { + return transaction_included (flags (b)); } - bool inline proofs_serialization_standard::transaction_included(const JSON& j) { - return j["txOrId"].size() > 64; + bool inline proofs_serialization_standard::transaction_included (const JSON &j) { + return j["txOrId"].size () > 64; } - bool inline proofs_serialization_standard::transaction_included() const { - return bool(Transaction); + bool inline proofs_serialization_standard::transaction_included () const { + return bool (Transaction); } - proofs_serialization_standard::target_type_value inline proofs_serialization_standard::target_type(byte flags) { - return target_type_value(flags & target_type_invalid); + proofs_serialization_standard::target_type_value inline proofs_serialization_standard::target_type (byte flags) { + return target_type_value (flags & target_type_invalid); } - proofs_serialization_standard::target_type_value inline proofs_serialization_standard::target_type(bytes_view b) { - return target_type(flags(b)); + proofs_serialization_standard::target_type_value inline proofs_serialization_standard::target_type (bytes_view b) { + return target_type (flags(b)); } - proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type(byte flags) { - return proof_type_value(flags & proof_type_tree); + proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type (byte flags) { + return proof_type_value (flags & proof_type_tree); } - proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type(bytes_view b) { - return proof_type(flags(b)); + proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type (bytes_view b) { + return proof_type (flags (b)); } - proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type(const JSON& j) { - if (!j.contains("proofType") || j["proofType"] == "branch") return proof_type_branch; + proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type (const JSON &j) { + if (!j.contains ("proofType") || j["proofType"] == "branch") return proof_type_branch; return proof_type_tree; } - proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type() const { + proofs_serialization_standard::proof_type_value inline proofs_serialization_standard::proof_type () const { return proof_type_branch; } - bool inline proofs_serialization_standard::composite_proof(byte flags) { + bool inline proofs_serialization_standard::composite_proof (byte flags) { return 0 != (flags & 16); } - bool inline proofs_serialization_standard::composite_proof(bytes_view b) { - return composite_proof(flags(b)); + bool inline proofs_serialization_standard::composite_proof (bytes_view b) { + return composite_proof (flags (b)); } - bool inline proofs_serialization_standard::composite_proof(const JSON& j) { - if (!j.contains("composite") || j["composite"] == false) return false; + bool inline proofs_serialization_standard::composite_proof (const JSON &j) { + if (!j.contains ("composite") || j["composite"] == false) return false; return true; } - bool inline proofs_serialization_standard::composite_proof() const { + bool inline proofs_serialization_standard::composite_proof () const { return false; } - digest256 inline proofs_serialization_standard::root() const { - return branch().root(); + digest256 inline proofs_serialization_standard::root () const { + return branch ().root (); } - inline proofs_serialization_standard::proofs_serialization_standard(const Merkle::branch& b) - : Txid{b.Leaf.Digest}, Path{Merkle::path(b)} {} + inline proofs_serialization_standard::proofs_serialization_standard (const Merkle::branch &b) + : Txid {b.Leaf.Digest}, Path {Merkle::path (b)} {} - inline proofs_serialization_standard::proofs_serialization_standard(const Merkle::proof& p) - : Txid{p.Branch.Leaf.Digest}, Path{Merkle::path(p.Branch)}, MerkleRoot{p.Root} {} + inline proofs_serialization_standard::proofs_serialization_standard (const Merkle::proof& p) + : Txid {p.Branch.Leaf.Digest}, Path {Merkle::path (p.Branch)}, MerkleRoot {p.Root} {} - inline proofs_serialization_standard::proofs_serialization_standard(const Merkle::branch& b, const Bitcoin::header& h) - : Txid{b.Leaf.Digest}, Path{Merkle::path(b)}, BlockHeader{h} {} + inline proofs_serialization_standard::proofs_serialization_standard (const Merkle::branch &b, const Bitcoin::header& h) + : Txid {b.Leaf.Digest}, Path {Merkle::path (b)}, BlockHeader {h} {} - inline proofs_serialization_standard::proofs_serialization_standard(const Merkle::branch& b, const digest256& block_hash) - : Txid{b.Leaf.Digest}, Path{Merkle::path(b)}, BlockHash{block_hash} {} + inline proofs_serialization_standard::proofs_serialization_standard (const Merkle::branch &b, const digest256 &block_hash) + : Txid{b.Leaf.Digest}, Path {Merkle::path (b)}, BlockHash {block_hash} {} - inline proofs_serialization_standard::proofs_serialization_standard(const Bitcoin::transaction& t, const Merkle::path& p) + inline proofs_serialization_standard::proofs_serialization_standard (const Bitcoin::transaction &t, const Merkle::path &p) : Transaction{bytes(t)}, Path{p} {} - inline proofs_serialization_standard::proofs_serialization_standard( - const Bitcoin::transaction& t, const Merkle::path& p, const Bitcoin::header& h) - : Transaction{bytes(t)}, Path{p}, BlockHeader{h} {} + inline proofs_serialization_standard::proofs_serialization_standard ( + const Bitcoin::transaction &t, const Merkle::path &p, const Bitcoin::header &h) + : Transaction {bytes (t)}, Path {p}, BlockHeader {h} {} - std::optional inline proofs_serialization_standard::block_hash() const { + maybe inline proofs_serialization_standard::block_hash () const { return BlockHash; } - std::optional inline proofs_serialization_standard::block_header() const { + maybe inline proofs_serialization_standard::block_header () const { return BlockHeader; } - std::optional inline proofs_serialization_standard::Merkle_root() const { - if (bool(MerkleRoot)) return MerkleRoot; - if (bool(BlockHeader)) return BlockHeader->MerkleRoot; + maybe inline proofs_serialization_standard::Merkle_root () const { + if (bool (MerkleRoot)) return MerkleRoot; + if (bool (BlockHeader)) return BlockHeader->MerkleRoot; return {}; } - std::optional inline proofs_serialization_standard::block_hash(const JSON& j) { - if (j.contains("targetType") && j["targetType"] == "hash") return {digest256{string{"0x"} + string(j["target"])}}; + maybe inline proofs_serialization_standard::block_hash (const JSON &j) { + if (j.contains ("targetType") && j["targetType"] == "hash") return {digest256 {string {"0x"} + string (j["target"])}}; return {}; } - std::optional inline proofs_serialization_standard::block_hash(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.block_hash(); + maybe inline proofs_serialization_standard::block_hash (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.block_hash (); return {}; } - std::optional inline proofs_serialization_standard::block_header(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.block_header(); + maybe inline proofs_serialization_standard::block_header (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.block_header (); return {}; } - std::optional inline proofs_serialization_standard::Merkle_root(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.Merkle_root(); + maybe inline proofs_serialization_standard::Merkle_root (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.Merkle_root (); return {}; } - uint32 inline proofs_serialization_standard::index() const { + uint32 inline proofs_serialization_standard::index () const { return Path.Index; } - uint32 inline proofs_serialization_standard::index(const JSON &j) { - if (!valid(j)) return 0; + uint32 inline proofs_serialization_standard::index (const JSON &j) { + if (!valid (j)) return 0; return j["index"]; } - digest256 inline proofs_serialization_standard::txid() const { - if (bool(Txid)) return *Txid; - return Bitcoin::Hash256(*Transaction); + digest256 inline proofs_serialization_standard::txid () const { + if (bool (Txid)) return *Txid; + return Bitcoin::Hash256 (*Transaction); } - digest256 inline proofs_serialization_standard::txid(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.txid(); + digest256 inline proofs_serialization_standard::txid (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.txid (); return {}; } - Merkle::leaf inline proofs_serialization_standard::leaf() const { - return {txid(), Path.Index}; + Merkle::leaf inline proofs_serialization_standard::leaf () const { + return {txid (), Path.Index}; } - Merkle::leaf inline proofs_serialization_standard::leaf(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.leaf(); + Merkle::leaf inline proofs_serialization_standard::leaf (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.leaf (); return {}; } - Merkle::leaf inline proofs_serialization_standard::leaf(const JSON& j) { - return {txid(j), index(j)}; + Merkle::leaf inline proofs_serialization_standard::leaf (const JSON &j) { + return {txid (j), index (j)}; } Merkle::path inline proofs_serialization_standard::path() const { return Path; } - Merkle::path inline proofs_serialization_standard::path(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.path(); + Merkle::path inline proofs_serialization_standard::path (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.path (); return {}; } - Merkle::path inline proofs_serialization_standard::path(const JSON& j) { - auto x = read_JSON(j); - if (x.valid()) return x.path(); + Merkle::path inline proofs_serialization_standard::path (const JSON &j) { + auto x = read_JSON (j); + if (x.valid ()) return x.path (); return {}; } - Merkle::branch inline proofs_serialization_standard::branch() const { - return {txid(), Path}; + Merkle::branch inline proofs_serialization_standard::branch () const { + return {txid (), Path}; } - Merkle::branch inline proofs_serialization_standard::branch(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.branch(); + Merkle::branch inline proofs_serialization_standard::branch (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.branch (); return {}; } - Merkle::branch inline proofs_serialization_standard::branch(const JSON& j) { - auto x = read_JSON(j); - if (x.valid()) return x.branch(); + Merkle::branch inline proofs_serialization_standard::branch (const JSON &j) { + auto x = read_JSON (j); + if (x.valid ()) return x.branch (); return {}; } - map inline proofs_serialization_standard::paths() const { - return {{txid(), path()}}; + map inline proofs_serialization_standard::paths () const { + return {{txid (), path ()}}; } - map inline proofs_serialization_standard::paths(bytes_view b) { - auto x = read_binary(b); - if (x.valid()) return x.paths(); + map inline proofs_serialization_standard::paths (bytes_view b) { + auto x = read_binary (b); + if (x.valid ()) return x.paths (); return {}; } - map inline proofs_serialization_standard::paths(const JSON& j) { - auto x = read_JSON(j); - if (x.valid()) return x.paths(); + map inline proofs_serialization_standard::paths (const JSON &j) { + auto x = read_JSON (j); + if (x.valid ()) return x.paths (); return {}; } diff --git a/include/gigamonkey/number.hpp b/include/gigamonkey/number.hpp index 27897f21..456ca260 100644 --- a/include/gigamonkey/number.hpp +++ b/include/gigamonkey/number.hpp @@ -360,7 +360,7 @@ namespace data::encoding::hexidecimal { } template - std::ostream inline &write (std::ostream& o, const Gigamonkey::uint& n) { + std::ostream inline &write (std::ostream &o, const Gigamonkey::uint &n) { return o << write (data::N (n)); } @@ -374,11 +374,11 @@ namespace data::encoding::decimal { } template - std::ostream inline &write (std::ostream& o, const Gigamonkey::uint& n) { + std::ostream inline &write (std::ostream &o, const Gigamonkey::uint &n) { return o << write (n); } -} + } namespace Gigamonkey { @@ -397,7 +397,7 @@ namespace Gigamonkey { n += step; n <<= 32; } - n += uint64(boost::endian::load_little_u32 (data ())); + n += uint64 (boost::endian::load_little_u32 (data ())); return n; } @@ -405,16 +405,16 @@ namespace Gigamonkey { inline uint::uint (const string &hex) : uint (0) { if (hex.size () != X * 2 + 2) return; if (!data::encoding::hexidecimal::valid (hex)) return; - ptr read = encoding::hex::read (hex.substr (2)); - std::reverse_copy(read->begin (), read->end (), begin ()); + maybe read = encoding::hex::read (hex.substr (2)); + std::reverse_copy (read->begin (), read->end (), begin ()); } template uint::uint(const N& n) : uint(0) { - ptr b = encoding::hex::read (encoding::hexidecimal::write (n).substr (2)); - std::reverse(b->begin (), b->end ()); - if (b->size () > X) std::copy(b->begin (), b->begin () + X, begin ()); - else std::copy(b->begin (), b->end(), begin ()); + maybe b = encoding::hex::read (encoding::hexidecimal::write (n).substr (2)); + std::reverse (b->begin (), b->end ()); + if (b->size () > X) std::copy (b->begin (), b->begin () + X, begin ()); + else std::copy (b->begin (), b->end(), begin ()); } template @@ -707,7 +707,7 @@ namespace Gigamonkey { return integer::less (a, b); } - template bool inline operator>(const integer &a, const integer &b) { + template bool inline operator > (const integer &a, const integer &b) { return integer::greater (a, b); } @@ -896,12 +896,12 @@ namespace Gigamonkey { return *this = *this >> i; } - template inline integer::integer (const integer& x) { + template inline integer::integer (const integer &x) { this->resize (x.size ()); std::copy (x.begin (), x.end (), this->rbegin ()); } - template inline natural::natural (const natural& x) { + template inline natural::natural (const natural &x) { this->resize (x.size ()); std::copy (x.begin(), x.end(), this->rbegin ()); } @@ -1096,15 +1096,15 @@ namespace Gigamonkey { template static bytes from_string (string_view x) { auto hex = data::encoding::hex::read (x); - if (hex != nullptr) { + if (bool (hex)) { bytes b; - b.resize(hex->size ()); - std::copy(hex->begin (), hex->end (), b.begin ()); + b.resize (hex->size ()); + std::copy (hex->begin (), hex->end (), b.begin ()); return b; } auto hexidecimal = data::encoding::hexidecimal::read (x); - if (hexidecimal != nullptr) { + if (bool (hexidecimal)) { bytes b; b.resize (hexidecimal->size ()); std::copy (hexidecimal->begin (), hexidecimal->end (), b.begin ()); @@ -1114,7 +1114,7 @@ namespace Gigamonkey { if (x == "-0") return bytes ({0x80}); if (data::encoding::integer::valid (x)) - return static_cast(*data::encoding::integer::read (x)); + return static_cast (*data::encoding::integer::read (x)); throw std::logic_error {"Invalid string representation"}; } diff --git a/include/gigamonkey/script/machine.hpp b/include/gigamonkey/script/machine.hpp index 89c8b205..5e36c75d 100644 --- a/include/gigamonkey/script/machine.hpp +++ b/include/gigamonkey/script/machine.hpp @@ -23,7 +23,7 @@ namespace Gigamonkey::Bitcoin::interpreter { script_config Config; - std::optional Document; + maybe Document; bytes Script; program_counter Counter; @@ -36,91 +36,92 @@ namespace Gigamonkey::Bitcoin::interpreter { long OpCount; - state(uint32 flags, bool consensus, std::optional doc, const bytes &script); + state (uint32 flags, bool consensus, maybe doc, const bytes &script); - program unread() const { - return decompile(bytes_view{Counter.Script}.substr(Counter.Counter)); + program unread () const { + return decompile (bytes_view{Counter.Script}.substr(Counter.Counter)); } - result step(); + result step (); }; state State; - machine(const script& unlock, const script& lock, uint32 flags = StandardScriptVerifyFlags(true, true)); + machine (const script &unlock, const script &lock, uint32 flags = StandardScriptVerifyFlags (true, true)); - machine(const script& unlock, const script& lock, const redemption_document &doc, uint32 flags = StandardScriptVerifyFlags(true, true)); + machine (const script &unlock, const script &lock, + const redemption_document &doc, uint32 flags = StandardScriptVerifyFlags (true, true)); - machine(program p, uint32 flags = StandardScriptVerifyFlags(true, true)); + machine (program p, uint32 flags = StandardScriptVerifyFlags (true, true)); - void step(); + void step (); - result run(); + result run (); private: - static bool isP2SH(const program p) { - bytes script = compile(p); - return script.size() == 23 && script[0] == OP_HASH160 && + static bool isP2SH (const program p) { + bytes script = compile (p); + return script.size () == 23 && script[0] == OP_HASH160 && script[1] == 0x14 && script[22] == OP_EQUAL; } - program inline full(const program unlock, const program lock) { - if (!isP2SH(lock) || data::empty(unlock)) return (unlock << OP_CODESEPARATOR) + lock; + program inline full (const program unlock, const program lock) { + if (!isP2SH (lock) || data::empty (unlock)) return (unlock << OP_CODESEPARATOR) + lock; return (unlock << OP_CODESEPARATOR) + (lock << OP_CODESEPARATOR) + decompile(data::reverse(unlock).first().data()); } - ScriptError check_scripts(const program unlock, const program lock, uint32 flags) { + ScriptError check_scripts (const program unlock, const program lock, uint32 flags) { if (flags & SCRIPT_VERIFY_SIGPUSHONLY && !is_push(unlock)) return SCRIPT_ERR_SIG_PUSHONLY; - if (isP2SH(lock)) { - if (unlock.empty()) return SCRIPT_ERR_INVALID_STACK_OPERATION; - if (!is_push(unlock)) return SCRIPT_ERR_SIG_PUSHONLY; + if (isP2SH (lock)) { + if (unlock.empty ()) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (!is_push (unlock)) return SCRIPT_ERR_SIG_PUSHONLY; } - return verify(full(unlock, lock), flags); + return verify (full (unlock, lock), flags); } - machine(std::optional doc, const program unlock, const program lock, uint32 flags); + machine(maybe doc, const program unlock, const program lock, uint32 flags); - static const element &script_false() { - static element False(0); + static const element &script_false () { + static element False (0); return False; } - static const element &script_true() { - static element True(1, 1); + static const element &script_true () { + static element True (1, 1); return True; } - static const element &script_bool(bool b) { - return b ? script_true() : script_false(); + static const element &script_bool (bool b) { + return b ? script_true () : script_false (); } - static const CScriptNum &script_zero() { - static CScriptNum Zero(0); + static const CScriptNum &script_zero () { + static CScriptNum Zero (0); return Zero; } - static const CScriptNum &script_one() { - static CScriptNum One(1); + static const CScriptNum &script_one () { + static CScriptNum One (1); return One; } }; - std::ostream& operator<<(std::ostream&, const machine&); + std::ostream& operator << (std::ostream &, const machine &); - void step_through(machine& m); + void step_through (machine &m); } namespace Gigamonkey::Bitcoin { - result inline evaluate(const script& unlock, const script& lock, uint32 flags) { - return interpreter::machine(unlock, lock, flags).run(); + result inline evaluate (const script &unlock, const script& lock, uint32 flags) { + return interpreter::machine (unlock, lock, flags).run (); } // Evaluate script with real signature operations. - result inline evaluate(const script& unlock, const script& lock, const redemption_document &doc, uint32 flags) { - return interpreter::machine(unlock, lock, doc, flags).run(); + result inline evaluate (const script &unlock, const script& lock, const redemption_document &doc, uint32 flags) { + return interpreter::machine (unlock, lock, doc, flags).run (); } } diff --git a/include/gigamonkey/stratum/extensions.hpp b/include/gigamonkey/stratum/extensions.hpp index 3a6f70d6..304dd14b 100644 --- a/include/gigamonkey/stratum/extensions.hpp +++ b/include/gigamonkey/stratum/extensions.hpp @@ -20,23 +20,23 @@ namespace Gigamonkey::Stratum::extensions { info }; - std::string extension_to_string(extension m); + std::string extension_to_string (extension m); - extension extension_from_string(std::string st); + extension extension_from_string (std::string st); struct accepted : public std::variant { using std::variant::variant; - accepted(); - accepted(JSON j); + accepted (); + accepted (JSON j); - bool valid() const; + bool valid () const; - operator bool() const; - operator JSON() const; + operator bool () const; + operator JSON () const; - bool has_error() const; - string error() const; + bool has_error () const; + string error () const; }; // request for a single extension. @@ -44,50 +44,50 @@ namespace Gigamonkey::Stratum::extensions { using result_params = data::map; template struct configuration { - operator request() const { + operator request () const { return {}; } - static std::optional read(const request &p) { + static maybe read (const request &p) { return {{}}; } }; template struct configured { - operator result_params() const { + operator result_params () const { return {}; } - static std::optional read(const result_params &p) { + static maybe read (const result_params &p) { return {{}}; } }; using version_mask = int32_little; - encoding::hex::fixed<4> write_version_mask(const version_mask &x); - std::optional read_version_mask(const string&); + encoding::hex::fixed<4> write_version_mask (const version_mask &x); + maybe read_version_mask (const string &); template <> struct configuration { version_mask Mask; byte MinBitCount; - operator request() const; - static std::optional read(const request &p); + operator request () const; + static maybe read (const request &p); }; template <> struct configured { version_mask Mask; - operator result_params() const; - static std::optional read(const result_params &p); + operator result_params () const; + static maybe read (const result_params &p); }; template <> struct configuration { difficulty Value; - operator request() const; - static std::optional read(const request &p); + operator request () const; + static maybe read (const request &p); }; template <> struct configuration { @@ -96,33 +96,33 @@ namespace Gigamonkey::Stratum::extensions { string SWVersion; string HWID; - operator request() const; - static std::optional read(const request &p); + operator request () const; + static maybe read (const request &p); }; // requests for all extensions. struct requests : public data::map { using data::map::map; - requests(data::map m) : data::map{m} {} + requests (data::map m) : data::map {m} {} template - requests insert(const configuration &n) const; + requests insert (const configuration &n) const; template - std::optional> get() const; + maybe> get () const; }; struct result { accepted Accepted; result_params Parameters; - result(const result_params &p); - result(); - result(accepted ac, const result_params &p = {}); + result (const result_params &p); + result (); + result (accepted ac, const result_params &p = {}); - bool valid() const; + bool valid () const; - bool operator==(const result &r) const; + bool operator == (const result &r) const; }; @@ -131,11 +131,11 @@ namespace Gigamonkey::Stratum::extensions { struct options { // whether extension version_rolling is supported and // parameter version mask. - optional VersionRollingMask{}; + optional VersionRollingMask {}; - bool SupportExtensionSubscribeExtranonce{false}; - bool SupportExtensionMinimumDifficulty{false}; - bool SupportExtensionInfo{false}; + bool SupportExtensionSubscribeExtranonce {false}; + bool SupportExtensionMinimumDifficulty {false}; + bool SupportExtensionInfo {false}; }; template struct parameters; @@ -144,110 +144,110 @@ namespace Gigamonkey::Stratum::extensions { version_mask LocalMask; configuration RequestedMask; - static optional make(version_mask local, const configuration &r); + static optional make (version_mask local, const configuration &r); - parameters() : LocalMask{}, RequestedMask{} {} + parameters () : LocalMask {}, RequestedMask {} {} - optional get() const; - optional configure(const configuration &requested); - optional set(const version_mask &mask); + optional get () const; + optional configure (const configuration &requested); + optional set (const version_mask &mask); }; - inline encoding::hex::fixed<4> write_version_mask(const version_mask& x) { - return encoding::hex::write(x, hex_case::lower); + inline encoding::hex::fixed<4> write_version_mask (const version_mask &x) { + return encoding::hex::write (x, hex_case::lower); } - inline accepted::accepted() : std::variant{std::monostate{}} {} + inline accepted::accepted () : std::variant {std::monostate {}} {} - inline accepted::accepted(const JSON j) : accepted{} { - if (j.is_boolean()) *this = (bool)(j); - else if (j.is_string()) *this = (string)(j); + inline accepted::accepted (const JSON j) : accepted {} { + if (j.is_boolean ()) *this = (bool) (j); + else if (j.is_string ()) *this = (string) (j); } - bool inline accepted::valid() const { - return !std::holds_alternative(*this); + bool inline accepted::valid () const { + return !std::holds_alternative (*this); } - inline accepted::operator bool() const { - return std::holds_alternative(*this) ? false : std::get(*this); + inline accepted::operator bool () const { + return std::holds_alternative (*this) ? false : std::get (*this); } - inline accepted::operator JSON() const { - return std::holds_alternative(*this) ? JSON(std::get(*this)) : JSON(std::get(*this)); + inline accepted::operator JSON () const { + return std::holds_alternative (*this) ? JSON (std::get (*this)) : JSON (std::get (*this)); } - bool inline accepted::has_error() const { - return std::holds_alternative(*this); + bool inline accepted::has_error () const { + return std::holds_alternative (*this); } - string inline accepted::error() const { - return has_error() ? std::get(*this) : string{}; + string inline accepted::error () const { + return has_error () ? std::get (*this) : string {}; } - inline configuration::operator request() const { - return {{"mask", string(write_version_mask(Mask))}, {"min-bit-count", MinBitCount}}; + inline configuration::operator request () const { + return {{"mask", string (write_version_mask (Mask))}, {"min-bit-count", MinBitCount}}; } - inline configured::operator result_params() const { - return {{"mask", string(write_version_mask(Mask))}}; + inline configured::operator result_params () const { + return {{"mask", string (write_version_mask (Mask))}}; } - inline configuration::operator request() const { + inline configuration::operator request () const { return {{"value", Value}}; } - inline configuration::operator request() const { + inline configuration::operator request () const { return {{"connection-url", ConnectionURL}, {"hw-version", HWVersion}, {"sw-version", SWVersion}, {"hw-id", HWID}}; } template - requests inline requests::insert(const configuration &n) const { - return {data::map::insert(extension_to_string(x), request(n))}; + requests inline requests::insert (const configuration &n) const { + return {data::map::insert (extension_to_string (x), request (n))}; } template - std::optional> requests::get() const { - string ext = extension_to_string(x); - auto z = this->contains(ext); - if (z) return configuration::read(*z); + maybe> requests::get () const { + string ext = extension_to_string (x); + auto z = this->contains (ext); + if (z) return configuration::read (*z); return {}; } - inline result::result(const result_params &p) : Accepted{true}, Parameters{} {} - inline result::result() : Accepted{false}, Parameters{} {} - inline result::result(accepted ac, const result_params &p): Accepted{ac}, Parameters{p} {} + inline result::result (const result_params &p) : Accepted {true}, Parameters {} {} + inline result::result () : Accepted {false}, Parameters {} {} + inline result::result (accepted ac, const result_params &p): Accepted {ac}, Parameters {p} {} - bool inline result::valid() const { - return Accepted.valid() && (!bool(Accepted) || Parameters.size() == 0); + bool inline result::valid () const { + return Accepted.valid () && (!bool (Accepted) || Parameters.size () == 0); } - std::ostream inline &operator<<(std::ostream &o, const accepted &a) { - return bool(a) ? (o << "accepted") : a.has_error() ? (o << "rejected: " << a.error()) : (o << "rejected"); + std::ostream inline &operator << (std::ostream &o, const accepted &a) { + return bool (a) ? (o << "accepted") : a.has_error () ? (o << "rejected: " << a.error ()) : (o << "rejected"); } - std::ostream inline &operator<<(std::ostream &o, const result &a) { + std::ostream inline &operator << (std::ostream &o, const result &a) { o << "[" << a.Accepted; - if (a.Parameters.size() > 0) return o << ", " << a.Parameters; + if (a.Parameters.size () > 0) return o << ", " << a.Parameters; return o << "]"; } - bool inline result::operator==(const result &r) const { + bool inline result::operator == (const result &r) const { return Accepted == r.Accepted && Parameters == r.Parameters; } - optional inline parameters::get() const { - return make(LocalMask, RequestedMask); + optional inline parameters::get () const { + return make (LocalMask, RequestedMask); } - optional inline parameters::configure(const configuration &requested) { + optional inline parameters::configure (const configuration &requested) { RequestedMask = requested; - return get(); + return get (); } - optional inline parameters::set(const version_mask &mask) { + optional inline parameters::set (const version_mask &mask) { LocalMask = mask; - return get(); + return get (); } } diff --git a/include/gigamonkey/stratum/mining.hpp b/include/gigamonkey/stratum/mining.hpp index be3b8acb..575d4704 100644 --- a/include/gigamonkey/stratum/mining.hpp +++ b/include/gigamonkey/stratum/mining.hpp @@ -18,31 +18,31 @@ namespace Gigamonkey::Stratum { struct worker; struct share; - bool operator==(const worker& a, const worker& b); - bool operator!=(const worker& a, const worker& b); + bool operator == (const worker &a, const worker &b); + bool operator != (const worker &a, const worker &b); - bool operator==(const share& a, const share& b); - bool operator!=(const share& a, const share& b); + bool operator == (const share &a, const share &b); + bool operator != (const share &a, const share &b); struct extranonce { - constexpr static uint32 BitcoinExtraNonce2Size{8}; + constexpr static uint32 BitcoinExtraNonce2Size {8}; session_id ExtraNonce1; size_t ExtraNonce2Size; - extranonce() : ExtraNonce1{0}, ExtraNonce2Size{0} {} - extranonce(session_id id) : ExtraNonce1{id}, ExtraNonce2Size{BitcoinExtraNonce2Size} {} - extranonce(session_id id, size_t size) : ExtraNonce1{id}, ExtraNonce2Size{size} {} + extranonce () : ExtraNonce1 {0}, ExtraNonce2Size {0} {} + extranonce (session_id id) : ExtraNonce1 {id}, ExtraNonce2Size {BitcoinExtraNonce2Size} {} + extranonce (session_id id, size_t size) : ExtraNonce1 {id}, ExtraNonce2Size {size} {} - bool operator==(const extranonce& p) const { + bool operator == (const extranonce &p) const { return ExtraNonce1 == p.ExtraNonce1 && ExtraNonce2Size == p.ExtraNonce2Size; } - bool operator!=(const extranonce& p) const { - return !(operator==(p)); + bool operator != (const extranonce &p) const { + return !(operator == (p)); } - bool valid() const { + bool valid () const { return ExtraNonce2Size > 0; } }; @@ -50,12 +50,12 @@ namespace Gigamonkey::Stratum { struct worker { worker_name Name; extranonce ExtraNonce; - std::optional Mask; + maybe Mask; - worker(); + worker (); - worker(worker_name n, extranonce ex); - worker(worker_name n, extranonce ex, int32_little mask); + worker (worker_name n, extranonce ex); + worker (worker_name n, extranonce ex, int32_little mask); }; // A Stratum share; also a representation of the 'submit' method. @@ -64,49 +64,49 @@ namespace Gigamonkey::Stratum { job_id JobID; work::share Share; - share(); - share(worker_name name, job_id jid, const work::share& x); - share(worker_name name, job_id jid, bytes en2, Bitcoin::timestamp t, nonce n); + share (); + share (worker_name name, job_id jid, const work::share &x); + share (worker_name name, job_id jid, bytes en2, Bitcoin::timestamp t, nonce n); - bool valid() const; + bool valid () const; }; - inline bool operator==(const worker& a, const worker& b) { + inline bool operator == (const worker &a, const worker &b) { return a.Name == b.Name && a.ExtraNonce == b.ExtraNonce && a.Mask == b.Mask; } - inline bool operator!=(const worker& a, const worker& b) { + inline bool operator != (const worker &a, const worker &b) { return !(a == b); } - inline worker::worker() : Name{}, ExtraNonce{} {} + inline worker::worker () : Name {}, ExtraNonce {} {} - inline worker::worker(worker_name n, extranonce n1) : Name{n}, ExtraNonce{n1}, Mask{} {} + inline worker::worker (worker_name n, extranonce n1) : Name {n}, ExtraNonce {n1}, Mask {} {} - inline worker::worker(worker_name n, extranonce n1, int32_little mask) : Name{n}, ExtraNonce{n1}, Mask{mask} {} + inline worker::worker (worker_name n, extranonce n1, int32_little mask) : Name {n}, ExtraNonce {n1}, Mask {mask} {} - inline bool operator==(const share& a, const share& b) { + inline bool operator == (const share &a, const share &b) { return a.Name == b.Name && a.JobID == b.JobID && a.Share == b.Share; } - inline bool operator!=(const share& a, const share& b) { + inline bool operator != (const share &a, const share &b) { return !(a == b); } - inline share::share() : Name{}, JobID{}, Share{} {} + inline share::share () : Name {}, JobID {}, Share {} {} - inline share::share(worker_name name, job_id jid, const work::share& x) : - Name{name}, JobID{jid}, Share{x} {} + inline share::share (worker_name name, job_id jid, const work::share &x) : + Name {name}, JobID {jid}, Share {x} {} - inline share::share(worker_name name, job_id jid, bytes en2, Bitcoin::timestamp t, nonce n) : - Name{name}, JobID{jid}, Share{t, n, en2} {} + inline share::share (worker_name name, job_id jid, bytes en2, Bitcoin::timestamp t, nonce n) : + Name {name}, JobID {jid}, Share {t, n, en2} {} - inline bool share::valid() const { - return Name != std::string{}; + inline bool share::valid () const { + return Name != std::string {}; } - std::ostream inline &operator<<(std::ostream &o, const extranonce &p) { + std::ostream inline &operator << (std::ostream &o, const extranonce &p) { return o << "{ExtraNonce1: " << p.ExtraNonce1 << ", ExtraNonce2Size: " << p.ExtraNonce2Size << "}"; } diff --git a/include/gigamonkey/stratum/mining_authorize.hpp b/include/gigamonkey/stratum/mining_authorize.hpp index ea793fce..0850b5d4 100644 --- a/include/gigamonkey/stratum/mining_authorize.hpp +++ b/include/gigamonkey/stratum/mining_authorize.hpp @@ -16,79 +16,79 @@ namespace Gigamonkey::Stratum::mining { struct authorize_request : request { struct parameters { string Username; - std::optional Password; + maybe Password; - bool valid() const; - bool operator==(const parameters& x) const; - bool operator!=(const parameters& x) const; + bool valid () const; + bool operator == (const parameters &x) const; + bool operator != (const parameters &x) const; - parameters(); - explicit parameters(string u); - parameters(string u, string p); + parameters (); + explicit parameters (string u); + parameters (string u, string p); }; - static Stratum::parameters serialize(const parameters&); - static parameters deserialize(const Stratum::parameters&); + static Stratum::parameters serialize (const parameters &); + static parameters deserialize (const Stratum::parameters &); - static parameters params(const request &); - parameters params() const; + static parameters params (const request &); + parameters params () const; - static bool valid(const JSON&); + static bool valid (const JSON &); - static string username(const JSON&); - static std::optional password(const JSON&); + static string username (const JSON &); + static maybe password (const JSON &); using request::request; - authorize_request(message_id id, string u); - authorize_request(message_id id, string u, string p); + authorize_request (message_id id, string u); + authorize_request (message_id id, string u, string p); - string username() const; + string username () const; - std::optional password() const; + maybe password () const; - bool valid() const; + bool valid () const; }; - bool inline authorize_request::parameters::valid() const { + bool inline authorize_request::parameters::valid () const { return Username != ""; } - bool inline authorize_request::parameters::operator==(const parameters& x) const { + bool inline authorize_request::parameters::operator == (const parameters &x) const { return Username == x.Username && Password == x.Password; } - bool inline authorize_request::parameters::operator!=(const parameters& x) const { + bool inline authorize_request::parameters::operator != (const parameters &x) const { return Username != x.Username || Password != x.Password; } - inline authorize_request::parameters::parameters() : Username{}, Password() {} - inline authorize_request::parameters::parameters(string u) : Username{u}, Password{} {} - inline authorize_request::parameters::parameters(string u, string p) : Username{u}, Password{p} {} + inline authorize_request::parameters::parameters () : Username {}, Password () {} + inline authorize_request::parameters::parameters (string u) : Username {u}, Password {} {} + inline authorize_request::parameters::parameters (string u, string p) : Username {u}, Password {p} {} - inline authorize_request::authorize_request(message_id id, string u) : + inline authorize_request::authorize_request (message_id id, string u) : request{id, mining_authorize, {u}} {} - inline authorize_request::authorize_request(message_id id, string u, string p) : + inline authorize_request::authorize_request (message_id id, string u, string p) : request{id, mining_authorize, {u, p}} {} - string inline authorize_request::username() const { - return username(*this); + string inline authorize_request::username () const { + return username (*this); } - std::optional inline authorize_request::password() const { - return password(*this); + maybe inline authorize_request::password () const { + return password (*this); } - bool inline authorize_request::valid() const { - return valid(*this); + bool inline authorize_request::valid () const { + return valid (*this); } - authorize_request::parameters inline authorize_request::params(const request &r) { - return deserialize(r.params()); + authorize_request::parameters inline authorize_request::params (const request &r) { + return deserialize (r.params ()); } - authorize_request::parameters inline authorize_request::params() const { - return params(*this); + authorize_request::parameters inline authorize_request::params () const { + return params (*this); } } diff --git a/include/gigamonkey/stratum/mining_set_extranonce.hpp b/include/gigamonkey/stratum/mining_set_extranonce.hpp index 5a3ac6f0..14fc75bd 100644 --- a/include/gigamonkey/stratum/mining_set_extranonce.hpp +++ b/include/gigamonkey/stratum/mining_set_extranonce.hpp @@ -12,34 +12,34 @@ namespace Gigamonkey::Stratum::mining { struct set_extranonce : notification { using parameters = extranonce; - static Stratum::parameters serialize(const parameters& p) { + static Stratum::parameters serialize (const parameters& p) { Stratum::parameters j; - j.push_back(encoding::hex::fixed<4>(p.ExtraNonce1)); - j.push_back(p.ExtraNonce2Size); + j.push_back (encoding::hex::fixed<4> (p.ExtraNonce1)); + j.push_back (p.ExtraNonce2Size); return j; } - static std::optional deserialize(const Stratum::parameters& p) { - if (p.size() != 2 || !p[0].is_string() || !p[1].is_number_unsigned()) return {}; - return parameters{session_id(encoding::hex::fixed<4>(p[0])), size_t(p[1])}; + static maybe deserialize (const Stratum::parameters& p) { + if (p.size () != 2 || !p[0].is_string () || !p[1].is_number_unsigned ()) return {}; + return parameters {session_id (encoding::hex::fixed<4> (p[0])), size_t (p[1])}; } using notification::notification; - set_extranonce(session_id extra_nonce_1, size_t extra_nonce_2_size); + set_extranonce (session_id extra_nonce_1, size_t extra_nonce_2_size); - static bool valid(const notification &n) { - return n.valid() && n.method() == mining_set_extranonce && deserialize(n.params()); + static bool valid (const notification &n) { + return n.valid () && n.method () == mining_set_extranonce && deserialize (n.params ()); } - bool valid() const { - return valid(*this); + bool valid () const { + return valid (*this); } - parameters params() const { - return *deserialize(notification::params()); + parameters params () const { + return *deserialize (notification::params ()); } - friend std::ostream& operator<<(std::ostream&, const parameters &); + friend std::ostream &operator << (std::ostream &, const parameters &); }; } diff --git a/include/gigamonkey/stratum/mining_set_version_mask.hpp b/include/gigamonkey/stratum/mining_set_version_mask.hpp index e6236a68..5760266e 100644 --- a/include/gigamonkey/stratum/mining_set_version_mask.hpp +++ b/include/gigamonkey/stratum/mining_set_version_mask.hpp @@ -9,35 +9,35 @@ namespace Gigamonkey::Stratum::mining { struct set_version_mask : notification { - static Stratum::parameters serialize(const extensions::version_mask& d); + static Stratum::parameters serialize (const extensions::version_mask &d); - static std::optional deserialize(const Stratum::parameters& p); + static maybe deserialize (const Stratum::parameters &p); using notification::notification; - set_version_mask(extensions::version_mask d) : notification{mining_set_version_mask, serialize(d)} {} + set_version_mask (extensions::version_mask d) : notification {mining_set_version_mask, serialize (d)} {} - static bool valid(const notification &n) { - return n.valid() && n.method() == mining_set_version_mask && deserialize(n.params()); + static bool valid (const notification &n) { + return n.valid () && n.method () == mining_set_version_mask && deserialize (n.params ()); } - bool valid() const { - return notification::valid() && deserialize(notification::params()); + bool valid () const { + return notification::valid () && deserialize (notification::params ()); } - extensions::version_mask params() const { - return *deserialize(notification::params()); + extensions::version_mask params () const { + return *deserialize (notification::params ()); } }; - Stratum::parameters inline set_version_mask::serialize(const extensions::version_mask& d) { + Stratum::parameters inline set_version_mask::serialize (const extensions::version_mask &d) { Stratum::parameters p; - p.push_back(extensions::write_version_mask(d)); + p.push_back (extensions::write_version_mask (d)); return p; } - std::optional inline set_version_mask::deserialize(const Stratum::parameters& p) { - if (p.size() != 1 || !p[0].is_string()) return {}; - return extensions::read_version_mask(string(p[0])); + maybe inline set_version_mask::deserialize (const Stratum::parameters &p) { + if (p.size () != 1 || !p[0].is_string ()) return {}; + return extensions::read_version_mask (string (p[0])); } } diff --git a/include/gigamonkey/stratum/mining_subscribe.hpp b/include/gigamonkey/stratum/mining_subscribe.hpp index dd6e25f9..55b8fa26 100644 --- a/include/gigamonkey/stratum/mining_subscribe.hpp +++ b/include/gigamonkey/stratum/mining_subscribe.hpp @@ -13,63 +13,63 @@ namespace Gigamonkey::Stratum::mining { method Method; string ID; - subscription() : Method{unset}, ID{} {} - subscription(method m, string id) : Method{m}, ID{id} {} - explicit subscription(const JSON&); - explicit operator JSON() const; + subscription () : Method {unset}, ID {} {} + subscription (method m, string id) : Method {m}, ID {id} {} + explicit subscription (const JSON &); + explicit operator JSON () const; - bool valid() const { + bool valid () const { return Method != unset; } }; - bool operator==(const subscription& a, const subscription& b); - bool operator!=(const subscription& a, const subscription& b); + bool operator == (const subscription &a, const subscription &b); + bool operator != (const subscription &a, const subscription &b); - std::ostream& operator<<(std::ostream&, const subscription&); + std::ostream &operator << (std::ostream &, const subscription &); struct subscribe_request : request { struct parameters { string UserAgent; - std::optional ExtraNonce1; + maybe ExtraNonce1; - parameters(const string& u) : UserAgent{u}, ExtraNonce1{} {} - parameters(const string& u, session_id i) : UserAgent{u}, ExtraNonce1{i} {} + parameters (const string &u) : UserAgent {u}, ExtraNonce1 {} {} + parameters (const string &u, session_id i) : UserAgent {u}, ExtraNonce1 {i} {} - bool valid() const; - bool operator==(const parameters& p) const; - bool operator!=(const parameters& p) const; + bool valid () const; + bool operator == (const parameters &p) const; + bool operator != (const parameters &p) const; - operator Stratum::parameters() const; + operator Stratum::parameters () const; private: - parameters() : UserAgent{}, ExtraNonce1{} {} + parameters () : UserAgent {}, ExtraNonce1 {} {} friend struct subscribe_request; }; - static Stratum::parameters serialize(const parameters&); - static parameters deserialize(const Stratum::parameters&); + static Stratum::parameters serialize (const parameters &); + static parameters deserialize (const Stratum::parameters &); - static bool valid(const JSON& j); - static string user_agent(const JSON& j); - static std::optional extra_nonce_1(const JSON& j); + static bool valid (const JSON &j); + static string user_agent (const JSON &j); + static maybe extra_nonce_1 (const JSON &j); - bool valid() const; - string user_agent() const; - std::optional extra_nonce_1() const; + bool valid () const; + string user_agent () const; + maybe extra_nonce_1 () const; - static parameters params(const request &r) { - return deserialize(r.params()); + static parameters params (const request &r) { + return deserialize (r.params ()); } - parameters params() const { - return params(*this); + parameters params () const { + return params (*this); } using request::request; - subscribe_request(message_id id, const string& u) : request{id, mining_subscribe, {u}} {} - subscribe_request(message_id id, const string& u, session_id i) : request{id, mining_subscribe, serialize(parameters{u, i})} {} + subscribe_request (message_id id, const string &u) : request {id, mining_subscribe, {u}} {} + subscribe_request (message_id id, const string &u, session_id i) : request {id, mining_subscribe, serialize (parameters {u, i})} {} }; @@ -78,150 +78,150 @@ namespace Gigamonkey::Stratum::mining { list Subscriptions; extranonce ExtraNonce; - bool valid() const; + bool valid () const; - parameters(list s, extranonce n1); + parameters (list s, extranonce n1); - bool operator==(const parameters& p) const; - bool operator!=(const parameters& p) const; + bool operator == (const parameters &p) const; + bool operator != (const parameters &p) const; - operator JSON() const; + operator JSON () const; private: - parameters() : Subscriptions{}, ExtraNonce{} {} + parameters () : Subscriptions {}, ExtraNonce {} {} friend struct subscribe_response; }; - static Stratum::parameters serialize(const parameters&); - static parameters deserialize(const Stratum::parameters&); + static Stratum::parameters serialize (const parameters &); + static parameters deserialize (const Stratum::parameters &); - static parameters result(const response &r) { - return deserialize(r.result()); + static parameters result (const response &r) { + return deserialize (r.result ()); } - parameters result() const { - return result(*this); + parameters result () const { + return result (*this); } - static bool valid(const JSON& j); - static list subscriptions(const JSON& j); - static session_id extra_nonce_1(const JSON& j); - static uint32 extra_nonce_2_size(const JSON& j); + static bool valid (const JSON &j); + static list subscriptions (const JSON &j); + static session_id extra_nonce_1 (const JSON &j); + static uint32 extra_nonce_2_size (const JSON &j); - bool valid() const; - list subscriptions() const; - session_id extra_nonce_1() const; - uint32 extra_nonce_2_size() const; + bool valid () const; + list subscriptions () const; + session_id extra_nonce_1 () const; + uint32 extra_nonce_2_size () const; using response::response; - subscribe_response(message_id id, list sub, extranonce en) : - subscribe_response{id, serialize(parameters{sub, en})} {} - subscribe_response(message_id id, const parameters &p) : - response{id, serialize(p)} {} + subscribe_response (message_id id, list sub, extranonce en) : + subscribe_response {id, serialize (parameters {sub, en})} {} + subscribe_response (message_id id, const parameters &p) : + response {id, serialize (p)} {} }; - bool inline operator==(const subscription& a, const subscription& b) { + bool inline operator == (const subscription& a, const subscription& b) { return a.Method && b.Method && a.ID == b.ID; } - bool inline operator!=(const subscription& a, const subscription& b) { + bool inline operator != (const subscription& a, const subscription& b) { return !(a == b); } - bool inline subscribe_request::parameters::valid() const { - return UserAgent != "" && (!bool(ExtraNonce1) || data::valid(*ExtraNonce1)); + bool inline subscribe_request::parameters::valid () const { + return UserAgent != "" && (!bool (ExtraNonce1) || data::valid (*ExtraNonce1)); } - bool inline subscribe_request::parameters::operator==(const parameters& p) const { + bool inline subscribe_request::parameters::operator == (const parameters &p) const { return UserAgent == p.UserAgent && ExtraNonce1 == p.ExtraNonce1; } - bool inline subscribe_request::parameters::operator!=(const parameters& p) const { + bool inline subscribe_request::parameters::operator != (const parameters &p) const { return UserAgent != p.UserAgent || ExtraNonce1 != p.ExtraNonce1; } - bool inline subscribe_response::parameters::valid() const { - return ExtraNonce.valid(); + bool inline subscribe_response::parameters::valid () const { + return ExtraNonce.valid (); } - inline std::ostream& operator<<(std::ostream& o, const subscription& s) { - return o << JSON(s); + std::ostream inline &operator << (std::ostream &o, const subscription &s) { + return o << JSON (s); } - inline subscribe_response::parameters::parameters(list s, extranonce n1) : - Subscriptions{s}, ExtraNonce{n1} {} + inline subscribe_response::parameters::parameters (list s, extranonce n1) : + Subscriptions {s}, ExtraNonce {n1} {} - bool inline subscribe_response::parameters::operator==(const parameters& p) const { + bool inline subscribe_response::parameters::operator == (const parameters& p) const { return Subscriptions == p.Subscriptions && ExtraNonce == p.ExtraNonce; } - bool inline subscribe_response::parameters::operator!=(const parameters& p) const { + bool inline subscribe_response::parameters::operator != (const parameters& p) const { return !(*this == p); } - bool inline subscribe_request::valid() const { - return valid(*this); + bool inline subscribe_request::valid () const { + return valid (*this); } - string inline subscribe_request::user_agent() const { - return user_agent(*this); + string inline subscribe_request::user_agent () const { + return user_agent (*this); } - std::optional inline subscribe_request::extra_nonce_1() const { - return extra_nonce_1(*this); + maybe inline subscribe_request::extra_nonce_1 () const { + return extra_nonce_1 (*this); } - bool inline subscribe_request::valid(const JSON& j) { - return request::valid(j) && deserialize(j["params"]).valid(); + bool inline subscribe_request::valid (const JSON &j) { + return request::valid (j) && deserialize (j["params"]).valid (); } - string inline subscribe_request::user_agent(const JSON& j) { - return deserialize(j["params"]).UserAgent; + string inline subscribe_request::user_agent (const JSON &j) { + return deserialize (j["params"]).UserAgent; } - std::optional inline subscribe_request::extra_nonce_1(const JSON& j) { - return deserialize(j["params"]).ExtraNonce1; + maybe inline subscribe_request::extra_nonce_1 (const JSON &j) { + return deserialize (j["params"]).ExtraNonce1; } - bool inline subscribe_response::valid(const JSON& j) { - return response::valid(j) && deserialize(j["result"]).valid(); + bool inline subscribe_response::valid (const JSON &j) { + return response::valid (j) && deserialize (j["result"]).valid (); } - list inline subscribe_response::subscriptions(const JSON& j) { - return deserialize(j["result"]).Subscriptions; + list inline subscribe_response::subscriptions (const JSON &j) { + return deserialize (j["result"]).Subscriptions; } - session_id inline subscribe_response::extra_nonce_1(const JSON& j) { - return deserialize(j["result"]).ExtraNonce.ExtraNonce1; + session_id inline subscribe_response::extra_nonce_1 (const JSON& j) { + return deserialize (j["result"]).ExtraNonce.ExtraNonce1; } - uint32 inline subscribe_response::extra_nonce_2_size(const JSON& j) { - return deserialize(j["result"]).ExtraNonce.ExtraNonce2Size; + uint32 inline subscribe_response::extra_nonce_2_size (const JSON& j) { + return deserialize (j["result"]).ExtraNonce.ExtraNonce2Size; } - bool inline subscribe_response::valid() const { - return valid(*this); + bool inline subscribe_response::valid () const { + return valid (*this); } - list inline subscribe_response::subscriptions() const { - return subscriptions(*this); + list inline subscribe_response::subscriptions () const { + return subscriptions (*this); } - session_id inline subscribe_response::extra_nonce_1() const { - return extra_nonce_1(*this); + session_id inline subscribe_response::extra_nonce_1 () const { + return extra_nonce_1 (*this); } - uint32 inline subscribe_response::extra_nonce_2_size() const { - return extra_nonce_2_size(*this); + uint32 inline subscribe_response::extra_nonce_2_size () const { + return extra_nonce_2_size (*this); } - inline subscribe_request::parameters::operator Stratum::parameters() const { - return serialize(*this); + inline subscribe_request::parameters::operator Stratum::parameters () const { + return serialize (*this); } - inline subscribe_response::parameters::operator JSON() const { - return serialize(*this); + inline subscribe_response::parameters::operator JSON () const { + return serialize (*this); } } diff --git a/include/gigamonkey/stratum/session_id.hpp b/include/gigamonkey/stratum/session_id.hpp index bc331f3b..b1df5392 100644 --- a/include/gigamonkey/stratum/session_id.hpp +++ b/include/gigamonkey/stratum/session_id.hpp @@ -10,47 +10,47 @@ namespace Gigamonkey::Stratum { struct session_id; struct session_id : uint32_big { - session_id(); + session_id (); - session_id(uint32 v); - explicit session_id(uint32_big v); + session_id (uint32 v); + explicit session_id (uint32_big v); - explicit session_id(encoding::hex::fixed<4> v); + explicit session_id (encoding::hex::fixed<4> v); - explicit operator encoding::hex::fixed<4>() const; + explicit operator encoding::hex::fixed<4> () const; - static JSON serialize(const session_id& p) { - return JSON::string_t{encoding::hex::fixed<4>(p)}; + static JSON serialize (const session_id &p) { + return JSON::string_t {encoding::hex::fixed<4> (p)}; } - static std::optional deserialize(const JSON& j) { + static maybe deserialize (const JSON &j) { session_id p = {}; - if (!j.is_string()) return {}; - auto m = encoding::hex::fixed<4>(string(j)); - if (!m.valid()) return {}; - p = session_id{m}; + if (!j.is_string ()) return {}; + auto m = encoding::hex::fixed<4> (string (j)); + if (!m.valid ()) return {}; + p = session_id {m}; return p; } }; - inline std::ostream& operator<<(std::ostream& o, const session_id id) { - return o << data::encoding::hex::fixed<4>(id); + std::ostream inline &operator << (std::ostream &o, const session_id id) { + return o << data::encoding::hex::fixed<4> (id); } - inline session_id::session_id() : uint32_big{0} {} + inline session_id::session_id () : uint32_big {0} {} - inline session_id::session_id(uint32 v) : uint32_big{v} {} + inline session_id::session_id (uint32 v) : uint32_big {v} {} - inline session_id::session_id(uint32_big v) : uint32_big{v} {} + inline session_id::session_id (uint32_big v) : uint32_big {v} {} - inline session_id::session_id(encoding::hex::fixed<4> v) : uint32_big{0} { - ptr x = encoding::hex::read(v); - if (x != nullptr) std::copy(x->begin(), x->end(), uint32_big::begin()); + inline session_id::session_id (encoding::hex::fixed<4> v) : uint32_big {0} { + maybe x = encoding::hex::read (v); + if (bool (x)) std::copy (x->begin (), x->end (), uint32_big::begin ()); } - inline session_id::operator encoding::hex::fixed<4>() const { - return encoding::hex::write(*this, hex_case::lower); + inline session_id::operator encoding::hex::fixed<4> () const { + return encoding::hex::write (*this, hex_case::lower); } } diff --git a/include/gigamonkey/stratum/stratum.hpp b/include/gigamonkey/stratum/stratum.hpp index a611abe4..ae16c8b6 100644 --- a/include/gigamonkey/stratum/stratum.hpp +++ b/include/gigamonkey/stratum/stratum.hpp @@ -15,133 +15,137 @@ namespace Gigamonkey::Stratum { using parameters = JSON::array_t; - template using optional = std::optional; + template using optional = maybe; struct notification : JSON { - static bool valid(const JSON&); + static bool valid (const JSON &); - static Stratum::method method(const JSON&); - static parameters params(const JSON&); + static Stratum::method method (const JSON &); + static parameters params (const JSON &); - bool valid() const; + bool valid () const; - Stratum::method method() const; - parameters params() const; + Stratum::method method () const; + parameters params () const; - notification(); - notification(Stratum::method m, const parameters& p); - explicit notification(const JSON& j) : JSON(j) {} + notification (); + notification (Stratum::method m, const parameters &p); + explicit notification (const JSON &j) : JSON (j) {} }; struct request : JSON { - static bool valid(const JSON&); + static bool valid (const JSON &); - static message_id id(const JSON&); - static Stratum::method method(const JSON&); - static parameters params(const JSON&); + static message_id id (const JSON &); + static Stratum::method method (const JSON &); + static parameters params (const JSON &); - bool valid() const; + bool valid () const; - message_id id() const; - Stratum::method method() const; - parameters params() const; + message_id id () const; + Stratum::method method () const; + parameters params () const; - request(); - request(message_id id, Stratum::method m, const parameters& p); - explicit request(const JSON& j) : JSON(j) {} + request (); + request (message_id id, Stratum::method m, const parameters &p); + explicit request (const JSON &j) : JSON (j) {} }; struct response : JSON { - static bool valid(const JSON&); + static bool valid(const JSON &); - static message_id id(const JSON&); - static JSON result(const JSON&); - static optional error(const JSON&); + static message_id id (const JSON &); + static JSON result (const JSON &); + static optional error (const JSON &); - bool valid() const { - return valid(*this); + bool valid () const { + return valid (*this); } - message_id id() const; - JSON result() const; - optional error() const; + message_id id () const; + JSON result () const; + optional error () const; - response(); - response(message_id id, const JSON& p); - response(message_id id, const JSON& p, const Stratum::error& e); - explicit response(const JSON& j) : JSON(j) {} + response (); + response (message_id id, const JSON &p); + response (message_id id, const JSON &p, const Stratum::error &e); + explicit response (const JSON &j) : JSON (j) {} - bool is_error() const { - return bool(error()); + bool is_error () const { + return bool (error ()); } }; - inline request::request() : JSON{} {} + inline request::request () : JSON {} {} - inline request::request(message_id id, Stratum::method m, const parameters& p) : - JSON{{"id", id}, {"method", method_to_string(m)}, {"params", p}} {} + inline request::request (message_id id, Stratum::method m, const parameters &p) : + JSON {{"id", id}, {"method", method_to_string (m)}, {"params", p}} {} - bool inline request::valid(const JSON& j) { - return request::method(j) != unset && j.contains("params") && j["params"].is_array() && j.contains("id") && message_id::valid(j["id"]); + bool inline request::valid (const JSON &j) { + return request::method (j) != unset && j.contains ("params") && + j["params"].is_array () && j.contains ("id") && message_id::valid (j["id"]); } - bool inline request::valid() const { - return valid(*this); + bool inline request::valid () const { + return valid (*this); } - message_id inline request::id() const { - return id(*this); + message_id inline request::id () const { + return id (*this); } - Stratum::method inline request::method() const { - return method(*this); + Stratum::method inline request::method () const { + return method (*this); } - parameters inline request::params() const { - return params(*this); + parameters inline request::params () const { + return params (*this); } - inline notification::notification() : JSON{} {} + inline notification::notification () : JSON{} {} - inline notification::notification(Stratum::method m, const parameters& p) : + inline notification::notification (Stratum::method m, const parameters& p) : JSON{{"id", nullptr}, {"method"}, {"params", p}} {} - bool inline notification::valid(const JSON& j) { - return notification::method(j) != unset && j.contains("params") && j["params"].is_array() && j.contains("id") && j["id"].is_null(); + bool inline notification::valid (const JSON &j) { + return notification::method (j) != unset && j.contains ("params") && + j["params"].is_array () && j.contains ("id") && j["id"].is_null (); } - bool inline notification::valid() const { - return valid(*this); + bool inline notification::valid () const { + return valid (*this); } - Stratum::method inline notification::method() const { - return method(*this); + Stratum::method inline notification::method () const { + return method (*this); } - parameters inline notification::params() const { - return params(*this); + parameters inline notification::params () const { + return params (*this); } - inline response::response() : JSON{} {} + inline response::response () : JSON {} {} - inline response::response(message_id id, const JSON& p) : JSON{{"id", id}, {"result", p}, {"error", nullptr}} {} + inline response::response (message_id id, const JSON &p) : + JSON {{"id", id}, {"result", p}, {"error", nullptr}} {} - inline response::response(message_id id, const JSON& p, const Stratum::error& e) : JSON{{"id", id}, {"result", p}, {"error", JSON(e)}} {} + inline response::response (message_id id, const JSON &p, const Stratum::error &e) : + JSON {{"id", id}, {"result", p}, {"error", JSON (e)}} {} - message_id inline response::id() const { - return id(*this); + message_id inline response::id () const { + return id (*this); } - JSON inline response::result() const { - return result(*this); + JSON inline response::result () const { + return result (*this); } - optional inline response::error() const { - return error(*this); + optional inline response::error () const { + return error (*this); } } diff --git a/include/gigamonkey/work/proof.hpp b/include/gigamonkey/work/proof.hpp index 94bc89dd..25e12b2e 100644 --- a/include/gigamonkey/work/proof.hpp +++ b/include/gigamonkey/work/proof.hpp @@ -16,25 +16,25 @@ namespace Gigamonkey::work { struct solution; struct proof; - proof solve (const puzzle& p, const solution& initial); + proof solve (const puzzle &p, const solution &initial); - bool operator == (const share&, const share&); - bool operator != (const share&, const share&); + bool operator == (const share &, const share &); + bool operator != (const share &, const share &); - bool operator == (const solution&, const solution&); - bool operator != (const solution&, const solution&); + bool operator == (const solution &, const solution &); + bool operator != (const solution &, const solution &); - bool operator == (const job&, const job&); - bool operator != (const job&, const job&); + bool operator == (const job &, const job &); + bool operator != (const job &, const job &); - bool operator == (const puzzle&, const puzzle&); - bool operator != (const puzzle&, const puzzle&); + bool operator == (const puzzle &, const puzzle &); + bool operator != (const puzzle &, const puzzle &); - bool operator == (const proof&, const proof&); - bool operator != (const proof&, const proof&); + bool operator == (const proof &, const proof &); + bool operator != (const proof &, const proof &); - bool operator == (const candidate&, const candidate&); - bool operator != (const candidate&, const candidate&); + bool operator == (const candidate &, const candidate &); + bool operator != (const candidate &, const candidate &); // candidate corresponds to a block that has been designed by the node but not completed with a nonce, timestamp, or coinbase. struct candidate { @@ -45,7 +45,7 @@ namespace Gigamonkey::work { Merkle::path Path; candidate () : Category {}, Digest {}, Target {}, Path {} {} - candidate (int32_little v, const uint256& d, compact g, Merkle::path mp) : + candidate (int32_little v, const uint256 &d, compact g, Merkle::path mp) : Category {v}, Digest {d}, Target {g}, Path {mp} {} bool valid () const; @@ -68,14 +68,14 @@ namespace Gigamonkey::work { puzzle (); puzzle ( int32_little v, - const uint256& d, + const uint256 &d, compact g, Merkle::path mp, - const bytes& h, - const bytes& b, + const bytes &h, + const bytes &b, int32_little mask = -1) : puzzle {candidate {v, d, g, mp}, h, b, mask} {} - puzzle(const candidate& x, const bytes& h, const bytes& b, int32_little mask = -1) : + puzzle (const candidate &x, const bytes &h, const bytes &b, int32_little mask = -1) : Candidate {x}, Header {h}, Body {b}, Mask {mask} {} bool valid () const; @@ -89,7 +89,7 @@ namespace Gigamonkey::work { Stratum::session_id ExtraNonce1; job (); - job (const puzzle&, Stratum::session_id extra); + job (const puzzle &, Stratum::session_id extra); bool valid () const; }; @@ -103,13 +103,13 @@ namespace Gigamonkey::work { // see BIP 320 // https://en.bitcoin.it/wiki/BIP_0320 - std::optional Bits; + maybe Bits; share (Bitcoin::timestamp t, nonce n, bytes b, int32_little bits); share (Bitcoin::timestamp t, nonce n, bytes b); share (); - bool valid() const; + bool valid () const; int32_little general_purpose_bits (int32_little mask) const { return int32_little {bool (Bits) ? ((*Bits) & mask) : 0}; @@ -122,7 +122,7 @@ namespace Gigamonkey::work { Stratum::session_id ExtraNonce1; solution () : Share {}, ExtraNonce1 {} {} - solution (const share& x, Stratum::session_id n1) : Share {x}, ExtraNonce1 {n1} {} + solution (const share &x, Stratum::session_id n1) : Share {x}, ExtraNonce1 {n1} {} solution (Bitcoin::timestamp t, nonce n, bytes_view b, Stratum::session_id n1) : solution {share {t, n, b}, n1} {} bool valid () const { @@ -137,15 +137,15 @@ namespace Gigamonkey::work { bool valid () const; proof (); - proof (const puzzle& p, const solution& x); - proof (const job& j, const share& x) : proof {j.Puzzle, solution {x, j.ExtraNonce1}} {} + proof (const puzzle &p, const solution &x); + proof (const job &j, const share &x) : proof {j.Puzzle, solution {x, j.ExtraNonce1}} {} proof ( - const string& w, + const string &w, Merkle::path mp, - const bytes& h, - const Stratum::session_id& n1, - const bytes& n2, - const bytes& b); + const bytes &h, + const Stratum::session_id &n1, + const bytes &n2, + const bytes &b); bytes meta () const; @@ -158,90 +158,90 @@ namespace Gigamonkey::work { } }; - proof cpu_solve (const puzzle& p, const solution& initial); + proof cpu_solve (const puzzle &p, const solution &initial); // right now we only have cpu mining in this lib. proof inline solve (puzzle p, solution initial) { return cpu_solve (p, initial); } - bool inline operator == (const share& a, const share& b) { + bool inline operator == (const share &a, const share &b) { return a.Timestamp == b.Timestamp && a.Nonce == b.Nonce && a.ExtraNonce2 == b.ExtraNonce2 && a.Bits == b.Bits; } - bool inline operator != (const share& a, const share& b) { + bool inline operator != (const share &a, const share &b) { return !(a == b); } - bool inline operator == (const solution& a, const solution& b) { + bool inline operator == (const solution &a, const solution &b) { return a.Share == b.Share && a.ExtraNonce1 == b.ExtraNonce1; } - bool inline operator != (const solution& a, const solution& b) { + bool inline operator != (const solution &a, const solution &b) { return !(a == b); } - bool inline operator == (const candidate& a, const candidate& b) { + bool inline operator == (const candidate &a, const candidate &b) { return a.Category == b.Category && a.Digest == b.Digest && a.Target == b.Target && a.Path == b.Path; } - bool inline operator != (const candidate& a, const candidate& b) { + bool inline operator != (const candidate &a, const candidate &b) { return !(a == b); } - bool inline operator == (const puzzle& a, const puzzle& b) { + bool inline operator == (const puzzle &a, const puzzle &b) { return a.Candidate == b.Candidate && a.Header == b.Header && a.Body == b.Body && a.Mask == b.Mask; } - bool inline operator != (const puzzle& a, const puzzle& b) { + bool inline operator != (const puzzle &a, const puzzle &b) { return !(a == b); } - bool inline operator == (const job& a, const job& b) { + bool inline operator == (const job &a, const job &b) { return a.Puzzle == b.Puzzle && a.ExtraNonce1 == b.ExtraNonce1; } - bool inline operator != (const job& a, const job& b) { + bool inline operator != (const job &a, const job &b) { return !(a == b); } - bool inline operator == (const proof& a, const proof& b) { + bool inline operator == (const proof &a, const proof &b) { return a.Puzzle == b.Puzzle && a.Solution == b.Solution; } - bool inline operator != (const proof& a, const proof& b) { + bool inline operator != (const proof &a, const proof &b) { return !(a == b); } - inline std::ostream& operator << (std::ostream& o, const share& p) { + std::ostream inline &operator << (std::ostream &o, const share &p) { o << "share{Timestamp: " << p.Timestamp << ", Nonce: " << p.Nonce << ", ExtraNonce2: " << p.ExtraNonce2; if (p.Bits) o << ", Bits: " << *p.Bits; return o << "}"; } - inline std::ostream& operator << (std::ostream& o, const candidate& p) { + std::ostream inline &operator << (std::ostream &o, const candidate &p) { return o << "candidate{Category: " << p.Category << ", Digest: " << p.Digest << ", Target: " << p.Target << ", Path: " << p.Path << "}"; } - inline std::ostream& operator << (std::ostream& o, const puzzle& p) { + std::ostream inline &operator << (std::ostream &o, const puzzle &p) { return o << "puzzle{" << p.Candidate << ", Header: " << p.Header << ", Body: " << p.Body << ", Mask: " << p.Mask << "}"; } - inline std::ostream& operator << (std::ostream& o, const job& p) { + std::ostream inline &operator << (std::ostream &o, const job &p) { return o << "job{" << p.Puzzle << ", ExtraNonce1: " << p.ExtraNonce1 << "}"; } - inline std::ostream& operator << (std::ostream& o, const solution& p) { + std::ostream inline &operator << (std::ostream &o, const solution &p) { return o << "solution{" << p.Share << ", ExtraNonce1: " << p.ExtraNonce1 << "}"; } - inline std::ostream& operator << (std::ostream& o, const proof& p) { + std::ostream inline &operator << (std::ostream &o, const proof &p) { return o << "proof{Puzzle: " << p.Puzzle << ", Solution: " << p.Solution << "}"; } @@ -274,16 +274,16 @@ namespace Gigamonkey::work { return Puzzle.valid (); } - inline proof::proof () : Puzzle{}, Solution{} {} - inline proof::proof (const puzzle& p, const solution& x) : Puzzle{p}, Solution{x} {} + inline proof::proof () : Puzzle {}, Solution {} {} + inline proof::proof (const puzzle &p, const solution &x) : Puzzle {p}, Solution {x} {} inline proof::proof ( - const struct string& w, + const struct string &w, Merkle::path mp, - const bytes& h, - const Stratum::session_id& n1, - const bytes& n2, - const bytes& b) : + const bytes &h, + const Stratum::session_id &n1, + const bytes &n2, + const bytes &b) : Puzzle {w.Category, w.Digest, w.Target, {}, h, b}, Solution {share {w.Timestamp, w.Nonce, n2}, n1} { if (w.MerkleRoot != merkle_root ()) *this = {}; diff --git a/include/sv/policy/policy.h b/include/sv/policy/policy.h index 0416786f..331d5fe4 100644 --- a/include/sv/policy/policy.h +++ b/include/sv/policy/policy.h @@ -156,7 +156,7 @@ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; /** returns flags for "standard" script*/ -inline unsigned int StandardScriptVerifyFlags(bool genesisEnabled, +inline unsigned int StandardScriptVerifyFlags (bool genesisEnabled, bool utxoAfterGenesis) { unsigned int scriptFlags = STANDARD_SCRIPT_VERIFY_FLAGS; if (utxoAfterGenesis) { @@ -170,7 +170,7 @@ inline unsigned int StandardScriptVerifyFlags(bool genesisEnabled, } /** Get the flags to use for non-final transaction checks */ -inline unsigned int StandardNonFinalVerifyFlags(bool genesisEnabled) +inline unsigned int StandardNonFinalVerifyFlags (bool genesisEnabled) { unsigned int flags { LOCKTIME_MEDIAN_TIME_PAST }; if(!genesisEnabled) { @@ -191,7 +191,7 @@ bool IsStandard(const CScriptConfig &config, const CScript &scriptPubKey, int32_ * @return True if all outputs (scriptPubKeys) use only standard transaction * forms */ -bool IsStandardTx(const CScriptConfig &config, const CTransaction &tx, int32_t nHeight, std::string &reason); +bool IsStandardTx (const CScriptConfig &config, const CTransaction &tx, int32_t nHeight, std::string &reason); /** * Check for standard transaction types @@ -199,10 +199,10 @@ bool IsStandardTx(const CScriptConfig &config, const CTransaction &tx, int32_t n * spending * @return True if all inputs (scriptSigs) use only standard transaction forms */ -std::optional AreInputsStandard( - const task::CCancellationToken& token, - const CScriptConfig& config, - const CTransaction& tx, +std::optional AreInputsStandard ( + const task::CCancellationToken &token, + const CScriptConfig &config, + const CTransaction &tx, const CCoinsViewCache &mapInputs, const int32_t mempoolHeight); diff --git a/include/sv/script/interpreter.h b/include/sv/script/interpreter.h index 05c37283..cd628c56 100644 --- a/include/sv/script/interpreter.h +++ b/include/sv/script/interpreter.h @@ -30,32 +30,32 @@ class CTransaction; * Consensus should be true when validating scripts of transactions that are part of block * and it should be false when validating scripts of transactions that are validated for acceptance to mempool */ -std::optional EvalScript( - const CScriptConfig& config, +std::optional EvalScript ( + const CScriptConfig &config, bool consensus, - LimitedStack& stack, - const CScript& script, + LimitedStack &stack, + const CScript &script, uint32_t flags, - LimitedStack& altstack, + LimitedStack &altstack, long& ipc, - std::vector& vfExec, - std::vector& vfElse, - ScriptError* error = nullptr); + std::vector &vfExec, + std::vector &vfElse, + ScriptError *error = nullptr); -std::optional EvalScript( - const CScriptConfig& config, +std::optional EvalScript ( + const CScriptConfig &config, bool consensus, - LimitedStack& stack, - const CScript& script, + LimitedStack &stack, + const CScript &script, uint32_t flags, - ScriptError* error = nullptr); + ScriptError *error = nullptr); -std::optional VerifyScript( - const CScriptConfig& config, +std::optional VerifyScript ( + const CScriptConfig &config, bool consensus, - const CScript& scriptSig, - const CScript& scriptPubKey, + const CScript &scriptSig, + const CScript &scriptPubKey, uint32_t flags, - ScriptError* serror = nullptr); + ScriptError *serror = nullptr); #endif // BITCOIN_SCRIPT_INTERPRETER_H diff --git a/src/gigamonkey/address.cpp b/src/gigamonkey/address.cpp index 0f05a0e6..0e67c200 100644 --- a/src/gigamonkey/address.cpp +++ b/src/gigamonkey/address.cpp @@ -6,13 +6,16 @@ namespace Gigamonkey::Bitcoin { - address address::encode (char prefix, const digest160& d) { + address address::encode (char prefix, const digest160 &d) { + address addr {}; static_cast (addr) = std::move (base58::check {byte (prefix), bytes_view {d}}.encode ()); return addr; + } - address::decoded address::decode (string_view s) { + address::decoded address::decode (string_view s) { + if (s.size () > 35 || s.size () < 5) return {}; base58::check b58 (s); if (!b58.valid ()) return {}; @@ -25,5 +28,6 @@ namespace Gigamonkey::Bitcoin { std::copy (b58.payload ().begin (), b58.payload ().end (), d.Digest.Value.begin ()); return d; + } } diff --git a/src/gigamonkey/boost/boost.cpp b/src/gigamonkey/boost/boost.cpp index 9fbc5593..d5016c73 100644 --- a/src/gigamonkey/boost/boost.cpp +++ b/src/gigamonkey/boost/boost.cpp @@ -223,7 +223,7 @@ namespace Gigamonkey::Boost { if (Type == Boost::contract) boost_output_script = boost_output_script.append (push_data (MinerPubkeyHash)); - boost_output_script = UseGeneralPurposeBits ? boost_output_script.append( + boost_output_script = UseGeneralPurposeBits ? boost_output_script.append ( push_data (Category), push_data (Content), push_data (Target), diff --git a/src/gigamonkey/mapi/envelope.cpp b/src/gigamonkey/mapi/envelope.cpp index 8d49abc4..23cff6f2 100644 --- a/src/gigamonkey/mapi/envelope.cpp +++ b/src/gigamonkey/mapi/envelope.cpp @@ -6,44 +6,44 @@ namespace Gigamonkey::BitcoinAssociation { - bool JSON_envelope::verify() const { - if (!valid()) return false; + bool JSON_envelope::verify () const { + if (!valid ()) return false; - if (!bool(PublicKey)) return true; + if (!bool (PublicKey)) return true; switch (Encoding) { default: return false; case base64 : { - ptr decoded = encoding::base64::read(Payload); - if (decoded == nullptr) return false; - return PublicKey->verify(Gigamonkey::SHA2_256(*decoded), *Signature); + maybe decoded = encoding::base64::read (Payload); + if (!bool (decoded)) return false; + return PublicKey->verify (Gigamonkey::SHA2_256 (*decoded), *Signature); } case UTF_8 : - return PublicKey->verify(Gigamonkey::SHA2_256(Payload), *Signature); + return PublicKey->verify (Gigamonkey::SHA2_256 (Payload), *Signature); } } - JSON_envelope::JSON_envelope(const JSON &j) : JSON_envelope{} { - if (!j.is_object() || !j.contains("payload") || !j.contains("encoding") || !j.contains("mimetype") || - !j["payload"].is_string() || !j["encoding"].is_string() || !j["mimetype"].is_string()) + JSON_envelope::JSON_envelope (const JSON &j) : JSON_envelope {} { + if (!j.is_object () || !j.contains ("payload") || !j.contains ("encoding") || !j.contains ("mimetype") || + !j["payload"].is_string () || !j["encoding"].is_string () || !j["mimetype"].is_string ()) return; JSON_envelope envelope; - if (j.contains("publicKey") || j.contains("signature")) { - if (!j.contains("publicKey") || !j.contains("signature") || - !j["publicKey"].is_string() || !j["signature"].is_string()) + if (j.contains ("publicKey") || j.contains ("signature")) { + if (!j.contains ("publicKey") || !j.contains ("signature") || + !j["publicKey"].is_string () || !j["signature"].is_string ()) return; else { - auto sig_hex = encoding::hex::read(string(j["signature"])); - if (sig_hex == nullptr) return; - envelope.Signature = secp256k1::signature{*sig_hex}; + auto sig_hex = encoding::hex::read (string (j["signature"])); + if (!bool (sig_hex)) return; + envelope.Signature = secp256k1::signature {*sig_hex}; - auto pk_hex = encoding::hex::read(string(j["publicKey"])); - if (pk_hex == nullptr) return; - envelope.PublicKey = secp256k1::pubkey{*pk_hex}; + auto pk_hex = encoding::hex::read (string (j["publicKey"])); + if (!bool (pk_hex)) return; + envelope.PublicKey = secp256k1::pubkey {*pk_hex}; } } @@ -59,24 +59,24 @@ namespace Gigamonkey::BitcoinAssociation { } - JSON_envelope::operator JSON() const { - if (!valid()) return nullptr; + JSON_envelope::operator JSON () const { + if (!valid ()) return nullptr; JSON j{{"payload", Payload}, {"mimetype", Mimetype}}; j["encoding"] = Encoding == base64 ? "base64" : "UTF_8"; - if (bool(PublicKey)) { - j["publicKey"] = encoding::hex::write(*PublicKey); - j["signature"] = encoding::hex::write(*Signature); + if (bool (PublicKey)) { + j["publicKey"] = encoding::hex::write (*PublicKey); + j["signature"] = encoding::hex::write (*Signature); } return j; } - bool JSON_JSON_envelope::valid() const { - if (!JSON_envelope::valid()) return false; + bool JSON_JSON_envelope::valid () const { + if (!JSON_envelope::valid ()) return false; try { - payload(); + payload (); return true; } catch (const JSON::exception &) { return false; diff --git a/src/gigamonkey/mapi/mapi.cpp b/src/gigamonkey/mapi/mapi.cpp index e608a453..f0c8f788 100644 --- a/src/gigamonkey/mapi/mapi.cpp +++ b/src/gigamonkey/mapi/mapi.cpp @@ -77,7 +77,7 @@ namespace Gigamonkey::BitcoinAssociation { JSON to_JSON (map fees) { JSON j = JSON::array (); - for (const data::entry& f : fees) + for (const data::entry &f : fees) j.push_back (f.valid () ? JSON { {"feeType", f.Key}, {"miningFee", to_JSON (f.Value.MiningFee)}, @@ -86,7 +86,7 @@ namespace Gigamonkey::BitcoinAssociation { return j; } - optional> read_ip_address_list (const JSON &j) { + maybe> read_ip_address_list (const JSON &j) { if (!j.is_array ()) return {}; list ips; @@ -200,7 +200,7 @@ namespace Gigamonkey::BitcoinAssociation { } - MAPI::transaction_submission::operator JSON() const { + MAPI::transaction_submission::operator JSON () const { JSON j{{"rawtx", encoding::hex::write (Transaction)}}; if (this->Parameters.CallbackURL) j["callbackUrl"] = *this->Parameters.CallbackURL; @@ -244,7 +244,7 @@ namespace Gigamonkey::BitcoinAssociation { }; } - MAPI::conflicted_with::conflicted_with (const JSON& j) : conflicted_with {} { + MAPI::conflicted_with::conflicted_with (const JSON &j) : conflicted_with {} { if (!(j.is_object () && j.contains ("txid") && j["txid"].is_string () && @@ -252,7 +252,7 @@ namespace Gigamonkey::BitcoinAssociation { j.contains ("hex") && j["hex"].is_string ())) return; auto tx = encoding::hex::read (string (j["hex"])); - if (tx == nullptr) return; + if (!bool (tx)) return; TXID = digest256 {string{"0x"} + string (j["txid"])}; Size = uint64 (j["size"]); @@ -292,7 +292,7 @@ namespace Gigamonkey::BitcoinAssociation { } auto pk_hex = encoding::hex::read (string (j["minerId"])); - if (pk_hex == nullptr) return; + if (!bool (pk_hex)) return; digest256 last_block {string{"0x"} + string (j["currentHighestBlockHash"])}; if (!last_block.valid ()) return; @@ -348,7 +348,7 @@ namespace Gigamonkey::BitcoinAssociation { return j; } - MAPI::submit_transaction_response::submit_transaction_response (const JSON& j) : + MAPI::submit_transaction_response::submit_transaction_response (const JSON &j) : submit_transaction_response {} { if (!(j.is_object () && @@ -364,7 +364,7 @@ namespace Gigamonkey::BitcoinAssociation { if (!sub.valid ()) return; auto pk_hex = encoding::hex::read (string (j["minerId"])); - if (pk_hex == nullptr) return; + if (! bool (pk_hex)) return; digest256 block_hash {string{"0x"} + string (j["currentHighestBlockHash"])}; if (!block_hash.valid ()) return; @@ -410,7 +410,7 @@ namespace Gigamonkey::BitcoinAssociation { return j; } - MAPI::transaction_status_response::transaction_status_response (const JSON& j) : + MAPI::transaction_status_response::transaction_status_response (const JSON &j) : transaction_status_response {} { if (!(j.is_object () && @@ -426,9 +426,9 @@ namespace Gigamonkey::BitcoinAssociation { if (!sub.valid ()) return; auto pk_hex = encoding::hex::read (string (j["minerId"])); - if (pk_hex == nullptr) return; + if (! bool (pk_hex)) return; - digest256 block_hash {string{"0x"} + string (j["blockHash"])}; + digest256 block_hash {string {"0x"} + string (j["blockHash"])}; if (!block_hash.valid ()) return; MinerID = secp256k1::pubkey {*pk_hex}; @@ -460,7 +460,7 @@ namespace Gigamonkey::BitcoinAssociation { return j; } - MAPI::submit_transactions_response::submit_transactions_response (const JSON& j) : + MAPI::submit_transactions_response::submit_transactions_response (const JSON &j) : submit_transactions_response {} { if (!(j.is_object () && @@ -475,12 +475,12 @@ namespace Gigamonkey::BitcoinAssociation { list sr; for (const JSON& w : j["txs"]) { - sr = sr << read_transaction_status(w); + sr = sr << read_transaction_status (w); if (!sr.first ().valid ()) return; } auto pk_hex = encoding::hex::read (string (j["minerId"])); - if (pk_hex == nullptr) return; + if (!bool (pk_hex)) return; digest256 block_hash {string {"0x"} + string (j["blockHash"])}; if (!block_hash.valid ()) return; diff --git a/src/gigamonkey/merkle.cpp b/src/gigamonkey/merkle.cpp index 345b116a..c77c19f7 100644 --- a/src/gigamonkey/merkle.cpp +++ b/src/gigamonkey/merkle.cpp @@ -10,159 +10,162 @@ namespace Gigamonkey::Merkle { namespace { - leaf_digests round(leaf_digests l) { - leaf_digests r{}; - while(l.size() >= 2) { - r = r << hash_concatinated(l.first(), l.rest().first()); - l = l.rest().rest(); + leaf_digests round (leaf_digests l) { + leaf_digests r {}; + while (l.size () >= 2) { + r = r << hash_concatinated (l.first (), l.rest ().first ()); + l = l.rest ().rest (); } - if (l.size() == 1) r = r << hash_concatinated(l.first(), l.first()); + if (l.size () == 1) r = r << hash_concatinated (l.first (), l.first ()); return r; } - bool check_proofs(ordered_list x) { - if (x.size() == 0) return true; + bool check_proofs (ordered_list x) { + if (x.size () == 0) return true; set g; for (proof p : x) { digest256 root = p.Root; branch b = p.Branch; while (true) { - if (g.contains(b.Leaf)) break; - g = g.insert(b.Leaf); - if (b.empty()) { + if (g.contains (b.Leaf)) break; + g = g.insert (b.Leaf); + if (b.empty ()) { if (b.Leaf.Digest != root) return false; else break; } - b = b.rest(); + b = b.rest (); } } return true; } - void append_proofs(list& p, uint32 index, digests l, data::tree t, const digest256& r, uint32 height) { + void append_proofs (list &p, uint32 index, digests l, data::tree t, const digest256 &r, uint32 height) { if (height == 1) { - p = p << proof{branch{leaf{t.root(), index}, l}, r}; + p = p << proof {branch {leaf {t.root (), index}, l}, r}; return; } - if (!t.right().empty()) { - append_proofs(p, (index << 1), l << t.right().root(), t.left(), r, height - 1); - append_proofs(p, (index << 1) + 1, l << t.left().root(), t.right(), r, height - 1); - } else append_proofs(p, index << 1, l << t.left().root(), t.left(), r, height - 1); + if (!t.right ().empty ()) { + append_proofs (p, (index << 1), l << t.right ().root (), t.left (), r, height - 1); + append_proofs (p, (index << 1) + 1, l << t.left ().root (), t.right (), r, height - 1); + } else append_proofs (p, index << 1, l << t.left ().root (), t.left (), r, height - 1); } template - void write_at_height(it& i, const data::tree& t, uint32 height) { + void write_at_height (it &i, const data::tree &t, uint32 height) { if (height == 0) { - *i = t.root(); + *i = t.root (); ++i; return; } - write_at_height(i, t.left(), height - 1); - if (!t.right().empty()) write_at_height(i, t.right(), height - 1); + write_at_height (i, t.left(), height - 1); + if (!t.right ().empty ()) write_at_height (i, t.right (), height - 1); } - uint32 height(data::tree t) { - if (t.empty()) return 0; - uint32 right_height = height(t.right()); - uint32 left_height = height(t.left()); + uint32 height (data::tree t) { + if (t.empty ()) return 0; + uint32 right_height = height (t.right ()); + uint32 left_height = height (t.left ()); if (right_height != left_height) return 0; return right_height + 1; } - bool check_tree(const data::tree& t, uint32 expected_width, uint32 expected_height) { + bool check_tree(const data::tree &t, uint32 expected_width, uint32 expected_height) { if (expected_height == 0) return false; - if (expected_height == 1) return expected_width == 1 && !t.empty() && t.left().empty() && t.right().empty() && t.root().valid(); + if (expected_height == 1) + return expected_width == 1 && !t.empty () && t.left ().empty () && t.right ().empty () && t.root ().valid (); - if (t.left().empty()) return false; + if (t.left ().empty ()) return false; uint32 expected_left_width; digest256 expected_value; - if (t.right().empty()) { + if (t.right ().empty ()) { expected_left_width = expected_width; - expected_value = hash_concatinated(t.left().root(), t.left().root()); + expected_value = hash_concatinated (t.left ().root (), t.left ().root ()); } else { expected_left_width = 1 << (expected_height - 2); - expected_value = hash_concatinated(t.left().root(), t.right().root()); - if (!check_tree(t.right(), expected_width - expected_left_width, expected_height - 1)) return false; + expected_value = hash_concatinated (t.left ().root (), t.right ().root ()); + if (!check_tree (t.right (), expected_width - expected_left_width, expected_height - 1)) return false; } - if (!check_tree(t.left(), expected_left_width, expected_height - 1)) return false; + if (!check_tree (t.left (), expected_left_width, expected_height - 1)) return false; - return t.root() == expected_value; + return t.root () == expected_value; } } - tree tree::make(leaf_digests h) { + tree tree::make (leaf_digests h) { - if (h.size() == 0) tree{}; - if (h.size() == 1) return tree{h.first()}; + if (h.size () == 0) tree {}; + if (h.size () == 1) return tree {h.first ()}; - uint32 width = h.size(); + uint32 width = h.size (); uint32 height = 2; - leaf_digests next_round = round(h); + leaf_digests next_round = round (h); using trees = list>; - trees Trees{}; + trees Trees {}; leaf_digests last = h; leaf_digests next = next_round; - while (!next.empty()) { - if (last.size() >= 2) { - Trees = Trees << data::tree{next.first(), - data::tree{last.first()}, - data::tree{last.rest().first()}}; - last = last.rest().rest(); + + while (!next.empty ()) { + if (last.size () >= 2) { + Trees = Trees << data::tree {next.first (), + data::tree {last.first ()}, + data::tree {last.rest ().first ()}}; + last = last.rest ().rest (); } else { - Trees = Trees << data::tree{next.first(), - data::tree{last.first()}, - data::tree{}}; - last = last.rest(); + Trees = Trees << data::tree {next.first (), + data::tree {last.first ()}, + data::tree {}}; + last = last.rest (); } - next = next.rest(); + next = next.rest (); } - while(next_round.size() > 1) { + while (next_round.size () > 1) { trees last_trees = Trees; - Trees = trees{}; - next_round = round(next_round); + Trees = trees {}; + next_round = round (next_round); next = next_round; height++; - while(!next.empty()) { - if (last_trees.size() >= 2) { - Trees = Trees << data::tree{next.first(), - data::tree{last_trees.first()}, - data::tree{last_trees.rest().first()}}; - last_trees = last_trees.rest().rest(); + while (!next.empty ()) { + if (last_trees.size () >= 2) { + Trees = Trees << data::tree {next.first (), + data::tree {last_trees.first ()}, + data::tree {last_trees.rest ().first ()}}; + last_trees = last_trees.rest ().rest (); } else { - Trees = Trees << data::tree{next.first(), - data::tree{last_trees.first()}, - data::tree{}}; - last_trees = last_trees.rest(); + Trees = Trees << data::tree {next.first (), + data::tree {last_trees.first ()}, + data::tree {}}; + last_trees = last_trees.rest (); } - next = next.rest(); + + next = next.rest (); } } // trees should have size 1 by this point. - return tree{Trees.first(), width, height}; + return tree {Trees.first(), width, height}; } - digest root(list l) { - if (l.size() == 0) return {}; - while (l.size() > 1) l = round(l); - return l.first(); + digest root (list l) { + if (l.size () == 0) return {}; + while (l.size () > 1) l = round (l); + return l.first (); } - digest root(leaf l, digests d) { - while (d.size() > 0) { - l = leaf{l.Index & 1 ? hash_concatinated(d.first(), l.Digest) : hash_concatinated(l.Digest, d.first()), l.Index >> 1}; - d = d.rest(); + digest root (leaf l, digests d) { + while (d.size () > 0) { + l = leaf {l.Index & 1 ? hash_concatinated (d.first (), l.Digest) : hash_concatinated (l.Digest, d.first ()), l.Index >> 1}; + d = d.rest (); } return l.Digest; } @@ -170,22 +173,25 @@ namespace Gigamonkey::Merkle { const list tree::proofs() const { if (Height == 0 || Width == 0) return {}; - if (Height == 1) return {proof{data::tree::root()}}; + if (Height == 1) return list {}.append (proof {data::tree::root ()}); list p; - append_proofs(p, 0, {data::tree::right().root()}, data::tree::left(), data::tree::root(), Height - 1); - append_proofs(p, 1, {data::tree::left().root()}, data::tree::right(), data::tree::root(), Height - 1); + append_proofs (p, 0, + {data::tree::right ().root ()}, data::tree::left (), data::tree::root (), Height - 1); + + append_proofs (p, 1, + {data::tree::left ().root ()}, data::tree::right (), data::tree::root (), Height - 1); return p; } - bool tree::valid() const { + bool tree::valid () const { if (Height == 0 || Width == 0) return false; - return check_tree(*this, Width, Height); + return check_tree (*this, Width, Height); } - proof tree::operator[](uint32 i) const { + proof tree::operator[] (uint32 i) const { if (i >= Width) return {}; uint32 max_index = Width - 1; @@ -194,18 +200,18 @@ namespace Gigamonkey::Merkle { stack digests; while (next_height > 0) { - digests = digests << t.root(); + digests = digests << t.root (); if ((i >> next_height) & 0 || i == max_index) { - t = t.right(); + t = t.right (); } else { - t = t.left(); + t = t.left (); } next_height--; } - return proof{branch{leaf{t.root(), i}, digests}, data::tree::root()}; + return proof {branch {leaf {t.root (), i}, digests}, data::tree::root ()}; } namespace { @@ -214,46 +220,46 @@ namespace Gigamonkey::Merkle { std::map Branches; digest Root; - bool add_nearest(uint32 index, digests d, uint32 nearest) { - uint32 height = d.size() - 1; + bool add_nearest (uint32 index, digests d, uint32 nearest) { + uint32 height = d.size () - 1; while(index >> height == nearest >> height && height > 0) height--; height += 1; - digests z{}; + digests z {}; digests x = Branches[nearest]; digests b = d; for (int i = 0; i <= height; i++) { - x = x.rest(); - z = z << b.first(); - b = b.rest(); + x = x.rest (); + z = z << b.first (); + b = b.rest (); } - while(!z.empty()) { - x = x << z.first(); - z = z.rest(); + while (!z.empty ()) { + x = x << z.first (); + z = z.rest (); } - Branches.insert_or_assign(index, x); + Branches.insert_or_assign (index, x); return true; } - bool add(const branch& p) { + bool add (const branch& p) { uint32 index = p.Leaf.Index; digests d = p.Digests << p.Leaf.Digest; - auto it = Branches.find(index); - if (it != Branches.end()) { + auto it = Branches.find (index); + if (it != Branches.end ()) { if (it->second != d) return false; return true; } - uint32 height = d.size(); + uint32 height = d.size (); cross leaves; - leaves.resize(Branches.size()); + leaves.resize (Branches.size ()); { int i = 0; for (const auto& b : Branches) { @@ -263,17 +269,21 @@ namespace Gigamonkey::Merkle { } uint32 min = 0; - uint32 max = leaves.size() - 1; + uint32 max = leaves.size () - 1; if (index < leaves[min]) { - if (leaves[min] >> (height - 2) == index >> (height - 2)) return add_nearest(index, d, leaves[min]); - Branches.insert_or_assign(index, d); + if (leaves[min] >> (height - 2) == index >> (height - 2)) + return add_nearest (index, d, leaves[min]); + + Branches.insert_or_assign (index, d); return true; } if (index > leaves[max]) { - if (leaves[max] >> (height - 2) == index >> (height - 2)) return add_nearest(index, d, leaves[max]); - Branches.insert_or_assign(index, d); + if (leaves[max] >> (height - 2) == index >> (height - 2)) + return add_nearest (index, d, leaves[max]); + + Branches.insert_or_assign (index, d); return true; } @@ -283,25 +293,28 @@ namespace Gigamonkey::Merkle { else max = mid; } - if (leaves[min] >> (height - 2) == index >> (height - 2)) return add_nearest(index, d, leaves[min]); - return add_nearest(index, d, leaves[max]); + if (leaves[min] >> (height - 2) == index >> (height - 2)) + return add_nearest (index, d, leaves[min]); + + return add_nearest (index, d, leaves[max]); } public: - dual_by_index(const dual& d) { + dual_by_index (const dual &d) { Root = d.Root; - for (const entry& e : d.Paths) Branches.insert_or_assign(e.Value.Index, e.Value.Digests << e.Key); + for (const entry &e : d.Paths) + Branches.insert_or_assign (e.Value.Index, e.Value.Digests << e.Key); } - operator dual() const { + operator dual () const { map m; - for (const auto& b : Branches) m = m.insert(b.second.first(), path{b.first, b.second.rest()}); + for (const auto &b : Branches) m = m.insert (b.second.first (), path {b.first, b.second.rest ()}); return dual{m, Root}; } - bool add_all(ordered_list p) { - for (const proof& x : p) if (!add(x.Branch)) return false; + bool add_all (ordered_list p) { + for (const proof &x : p) if (!add (x.Branch)) return false; return true; } diff --git a/src/gigamonkey/merkle/dual.cpp b/src/gigamonkey/merkle/dual.cpp index 85e6c726..7809860b 100644 --- a/src/gigamonkey/merkle/dual.cpp +++ b/src/gigamonkey/merkle/dual.cpp @@ -17,15 +17,15 @@ namespace Gigamonkey::Merkle { index Left; index Right; - tree_node() : Digest{}, Left{}, Right{} {} - tree_node(const uint32& d, index l, index r) : Digest{d}, Left{l}, Right{r} {} - explicit tree_node(const uint32& d) : Digest{d}, Left{}, Right{} {} + tree_node () : Digest {}, Left {}, Right {} {} + tree_node (const uint32 &d, index l, index r) : Digest {d}, Left {l}, Right {r} {} + explicit tree_node (const uint32 &d) : Digest {d}, Left{}, Right{} {} - bool operator==(const tree_node& t) const { + bool operator == (const tree_node &t) const { return Digest == t.Digest && Left == t.Left && Right == t.Right; } - bool operator!=(const tree_node& t) const { + bool operator != (const tree_node &t) const { return !(*this == t); } @@ -44,81 +44,81 @@ namespace Gigamonkey::Merkle { index Index; - explicit operator JSON() const; + explicit operator JSON () const; - bool valid() const { - return Nodes.size() != 0; + bool valid () const { + return Nodes.size () != 0; } - explicit inverted_from(const dual& d) : Digests{}, Nodes{}, Branches{}, Index{0} { - insert_or_find(d.Root); + explicit inverted_from (const dual &d) : Digests {}, Nodes {}, Branches {}, Index {0} { + insert_or_find (d.Root); - uint32 n = Nodes.size(); - Nodes[n] = tree_node{0}; + uint32 n = Nodes.size (); + Nodes[n] = tree_node {0}; - for (const data::entry& x : d.Paths) { - uint32 i = insert_or_find(x.Key); + for (const data::entry &x : d.Paths) { + uint32 i = insert_or_find (x.Key); if (i == 0) return; - uint32 n = Nodes.size(); - Nodes[n] = tree_node{i}; + uint32 n = Nodes.size (); + Nodes[n] = tree_node {i}; - insert_path(x.Value, n); + insert_path (x.Value, n); } } - void insert_path(const path& d, uint32 p) { + void insert_path (const path &d, uint32 p) { uint32 i; uint32 n; - if (d.Digests.size() == 0) { + if (d.Digests.size () == 0) { i = 0; n = 0; } else { - i = insert_or_find(d.Digests.first()); - if (!Branches.contains(i)) { - uint32 n = Nodes.size(); - Nodes[n] = tree_node{i}; - Branches = Branches.insert(i, index{static_cast(n)}); - insert_path(d.Digests.rest(), d.Index, n); + i = insert_or_find (d.Digests.first ()); + if (!Branches.contains (i)) { + uint32 n = Nodes.size (); + Nodes[n] = tree_node {i}; + Branches = Branches.insert (i, index {static_cast (n)}); + insert_path (d.Digests.rest (), d.Index, n); } } - if (d.Index & 1) Nodes[n].Left = index{static_cast(p)}; - else Nodes[n].Right = index{static_cast(p)}; + if (d.Index & 1) Nodes[n].Left = index {static_cast (p)}; + else Nodes[n].Right = index {static_cast (p)}; } - void insert_path(const digests& d, uint32 x, uint32 p) { + void insert_path(const digests &d, uint32 x, uint32 p) { uint32 i; uint32 n; - if (d.size() == 0) { + if (d.size () == 0) { i = 0; n = 0; } else { - i = insert_or_find(d.first()); - if (!Branches.contains(i)) { - uint32 n = Nodes.size(); + i = insert_or_find (d.first ()); + if (!Branches.contains (i)) { + uint32 n = Nodes.size (); Nodes[n] = tree_node{i}; - Branches = Branches.insert(i, index{static_cast(n)}); - insert_path(d.rest(), x >> 1, n); + Branches = Branches.insert (i, index {static_cast (n)}); + insert_path (d.rest (), x >> 1, n); } else n = Branches[i]; } - if (x & 1) Nodes[n].Right = index{static_cast(p)}; - else Nodes[n].Left = index{static_cast(p)}; + if (x & 1) Nodes[n].Right = index {static_cast (p)}; + else Nodes[n].Left = index {static_cast (p)}; } - uint32 insert_or_find(const digest& x) { - auto find = Digests.contains(x); + uint32 insert_or_find (const digest &x) { + auto find = Digests.contains (x); if (find) return *find; - Digests = Digests.insert(x, Index); + Digests = Digests.insert (x, Index); return Index++; } @@ -128,120 +128,120 @@ namespace Gigamonkey::Merkle { std::vector Digests; std::vector Nodes; - explicit inverted_to(const JSON& j); - - explicit operator dual() const; + explicit inverted_to (const JSON &j); + + explicit operator dual () const; // add all paths at index i to map p. - map paths(digests d, index i, uint32 b, map p) const; + map paths (digests d, index i, uint32 b, map p) const; - bool valid() const { - if (Digests.size() == 0 || Nodes.size() == 0) return false; + bool valid () const { + if (Digests.size () == 0 || Nodes.size () == 0) return false; return true; } }; - JSON write(const data::map d) { - JSON x = JSON::array(); - for (const data::entry& e : d) x[e.Value] = data::encoding::hex::write(e.Key); + JSON write (const data::map d) { + JSON x = JSON::array (); + for (const data::entry &e : d) x[e.Value] = encoding::hex::write (e.Key); return x; } - JSON write(const std::map v) { - JSON x = JSON::array(); + JSON write (const std::map v) { + JSON x = JSON::array (); for (const std::pair n : v) - x.push_back(JSON::array({n.second.Digest, int32(n.second.Left), int32(n.second.Right)})); + x.push_back (JSON::array ({n.second.Digest, int32 (n.second.Left), int32 (n.second.Right)})); return x; } - inverted_from::operator JSON() const { - return JSON::array({write(Digests), write(Nodes)}); + inverted_from::operator JSON () const { + return JSON::array ({write (Digests), write (Nodes)}); } - bool read_digest(const JSON& j, digest& d) { - if (!j.is_string()) return false; + bool read_digest (const JSON &j, digest &d) { + if (!j.is_string ()) return false; string hex_digest = j; - ptr v = data::encoding::hex::read(hex_digest); - if (v == nullptr || hex_digest.size() != 64) return false; - std::copy(v->begin(), v->end(), d.begin()); + maybe v = data::encoding::hex::read (hex_digest); + if (!bool (v) || hex_digest.size () != 64) return false; + std::copy (v->begin (), v->end (), d.begin ()); return true; } - std::vector read_digests(const JSON& j) { - if (!j.is_array() || j.size() == 0) return {}; + std::vector read_digests (const JSON &j) { + if (!j.is_array () || j.size () == 0) return {}; - std::vector digests{}; - digests.resize(j.size()); + std::vector digests {}; + digests.resize (j.size ()); - for (int i = 0; i < j.size(); i++) if (!read_digest(j[i], digests[i])) return {}; + for (int i = 0; i < j.size (); i++) if (!read_digest (j[i], digests[i])) return {}; return digests; } - bool read_tree_node(const JSON& j, tree_node& n) { + bool read_tree_node (const JSON &j, tree_node &n) { - if (!j.is_array() || - j.size() != 3 || - !j[0].is_number_unsigned() || - !j[1].is_number_integer() || - !j[2].is_number_integer()) return false; + if (!j.is_array () || + j.size () != 3 || + !j[0].is_number_unsigned () || + !j[1].is_number_integer () || + !j[2].is_number_integer ()) return false; - n.Digest = uint32(j[0]); + n.Digest = uint32 (j[0]); - n.Left = index(j[1]); - n.Right = index(j[2]); + n.Left = index (j[1]); + n.Right = index (j[2]); return true; } - std::vector read_nodes(const JSON& j) { - if (!j.is_array() || j.size() == 0) return {}; + std::vector read_nodes (const JSON &j) { + if (!j.is_array () || j.size () == 0) return {}; - std::vector nodes{}; - nodes.resize(j.size()); + std::vector nodes {}; + nodes.resize (j.size ()); - for (int i = 0; i < j.size(); i++) if (!read_tree_node(j[i], nodes[i])) return {}; + for (int i = 0; i < j.size (); i++) if (!read_tree_node (j[i], nodes[i])) return {}; return nodes; } - inverted_to::inverted_to(const JSON& j) { + inverted_to::inverted_to (const JSON &j) { - if (!j.is_array() || j.size() != 2) return; + if (!j.is_array () || j.size () != 2) return; - Digests = read_digests(j[0]); - if (Digests.size() == 0) return; + Digests = read_digests (j[0]); + if (Digests.size () == 0) return; - Nodes = read_nodes(j[1]); - if(Nodes.size() == 0) return; + Nodes = read_nodes (j[1]); + if (Nodes.size () == 0) return; } - map inverted_to::paths(digests d, index i, uint32 b, map p) const { + map inverted_to::paths (digests d, index i, uint32 b, map p) const { if (i < 0) return p; const tree_node& t = Nodes[i]; - if (t.Left == -1 && t.Right == -1) return p.insert(Digests[t.Digest], path{b >> 1, d}); + if (t.Left == -1 && t.Right == -1) return p.insert (Digests[t.Digest], path{b >> 1, d}); d = d << Digests[t.Digest]; // not sure if this part is right... - return paths(d, t.Right, (b << 1) + 1, paths(d, t.Left, b << 1, p)); + return paths (d, t.Right, (b << 1) + 1, paths (d, t.Left, b << 1, p)); } - inverted_to::operator dual() const { - if (!valid()) return {}; + inverted_to::operator dual () const { + if (!valid ()) return {}; - dual d{}; + dual d {}; d.Root = Digests[0]; if (Nodes[0].Left == -1 && Nodes[0].Right == -1) { - d.Paths = d.Paths.insert(d.Root, path{0, {}}); + d.Paths = d.Paths.insert (d.Root, path {0, {}}); return d; } - d.Paths = paths({}, Nodes[0].Right, 1, paths({}, Nodes[0].Left, 0, d.Paths)); + d.Paths = paths ({}, Nodes[0].Right, 1, paths ({}, Nodes[0].Left, 0, d.Paths)); return d; @@ -249,12 +249,12 @@ namespace Gigamonkey::Merkle { } - JSON dual::serialize() const { - return JSON(inverted_from{*this}); + JSON dual::serialize () const { + return JSON (inverted_from{*this}); } - dual dual::deserialize(const JSON& j) { - return dual(inverted_to{j}); + dual dual::deserialize (const JSON &j) { + return dual (inverted_to {j}); } } diff --git a/src/gigamonkey/merkle/serialize.cpp b/src/gigamonkey/merkle/serialize.cpp index 0cbf0c4a..3b4e35bb 100644 --- a/src/gigamonkey/merkle/serialize.cpp +++ b/src/gigamonkey/merkle/serialize.cpp @@ -2,118 +2,124 @@ namespace Gigamonkey::BitcoinAssociation { - digest256 read_digest(const string& x) { - return digest256{string{"0x"} + x}; + digest256 read_digest (const string &x) { + return digest256 {string {"0x"} + x}; } - string write_digest(const digest256& x) { + string write_digest (const digest256 &x) { std::stringstream ss; ss << x.Value; - return ss.str().substr(2); + return ss.str ().substr (2); } - Bitcoin::header read_header(const string& x) { - ptr b = encoding::hex::read(x); - if (b == nullptr || b->size() != 80) return {}; - return Bitcoin::header{slice<80>{b->data()}}; + Bitcoin::header read_header (const string &x) { + maybe b = encoding::hex::read (x); + if (!bool (b) || b->size () != 80) return {}; + return Bitcoin::header {slice<80> {b->data ()}}; } - string write_header(const Bitcoin::header& h) { - return encoding::hex::write(h.write()); + string write_header (const Bitcoin::header &h) { + return encoding::hex::write (h.write ()); } - Merkle::digests read_path(const JSON::array_t& j, Merkle::leaf l) { + Merkle::digests read_path (const JSON::array_t &j, Merkle::leaf l) { Merkle::digests d; - for (const JSON& n : j) { - digest256 next = (n == "*" ? l.Digest : read_digest(n)); + + for (const JSON &n : j) { + digest256 next = (n == "*" ? l.Digest : read_digest (n)); d = d << next; - l = l.next(next); + l = l.next (next); } - return data::reverse(d); + + return data::reverse (d); } - list> generate_path(Merkle::branch b) { - list> l; - while (b.Digests.size() > 0) { - if (b.Leaf.Digest == b.Digests.first()) l = l << std::optional{}; - else l = l << std::optional{b.Digests.first()}; - b = b.rest(); + list> generate_path (Merkle::branch b) { + list> l; + + while (b.Digests.size () > 0) { + if (b.Leaf.Digest == b.Digests.first ()) l = l << maybe {}; + else l = l << maybe {b.Digests.first ()}; + b = b.rest (); } + return l; } - JSON write_path(Merkle::branch b) { - JSON::array_t nodes(b.Digests.size()); + JSON write_path (Merkle::branch b) { + JSON::array_t nodes (b.Digests.size ()); + for (JSON& j : nodes) { - if (b.Leaf.Digest == b.Digests.first()) j = "*"; - else j = write_digest(b.Digests.first()); + if (b.Leaf.Digest == b.Digests.first ()) j = "*"; + else j = write_digest (b.Digests.first ()); b = b.rest(); } + return nodes; } - bool proofs_serialization_standard::valid() const { - if ((bool(Transaction) && bool(Txid)) || (!bool(Transaction) && !bool(Txid))) return false; - if (bool(BlockHash)) return !bool(BlockHeader) && !bool(MerkleRoot); - if (bool(BlockHeader)) return !bool(BlockHash) && !bool(MerkleRoot); - if (bool(MerkleRoot)) return !bool(BlockHeader) && !bool(BlockHash); + bool proofs_serialization_standard::valid () const { + if ((bool (Transaction) && bool (Txid)) || (!bool (Transaction) && !bool (Txid))) return false; + if (bool (BlockHash)) return !bool (BlockHeader) && !bool (MerkleRoot); + if (bool (BlockHeader)) return !bool (BlockHash) && !bool (MerkleRoot); + if (bool (MerkleRoot)) return !bool (BlockHeader) && !bool (BlockHash); return false; } - bool proofs_serialization_standard::valid(const JSON &j) { - if (!j.is_object()) return false; + bool proofs_serialization_standard::valid (const JSON &j) { + if (!j.is_object ()) return false; // composite proofs not yet supported. - if (j.contains("composite") && (!j["composite"].is_boolean() || j["composite"] == true)) return false; + if (j.contains ("composite") && (!j["composite"].is_boolean () || j["composite"] == true)) return false; // trees not yet supported. - if (j.contains("proofType") && (!j["proofType"].is_string() || j["proofType"] != "branch")) return false; + if (j.contains ("proofType") && (!j["proofType"].is_string () || j["proofType"] != "branch")) return false; - if (!j.contains("index") || !j["index"].is_number_unsigned()) return false; + if (!j.contains ("index") || !j["index"].is_number_unsigned ()) return false; - if (!j.contains("txOrId") || - !j["txOrId"].is_string() || - string(j["txOrId"]).size() < 64 || - !encoding::hex::valid(string(j["txOrId"]))) return false; + if (!j.contains ("txOrId") || + !j["txOrId"].is_string () || + string (j["txOrId"]).size () < 64 || + !encoding::hex::valid (string (j["txOrId"]))) return false; - if (j.contains("targetType")) { + if (j.contains ("targetType")) { JSON targetType = j["targetType"]; - if (!targetType.is_string() || (targetType != "hash" && targetType != "header" && targetType != "merkleRoot")) return false; - } else if (!j.contains("target") || !j["target"].is_string() || !encoding::hex::valid(string(j["target"]))) return false; + if (!targetType.is_string () || (targetType != "hash" && targetType != "header" && targetType != "merkleRoot")) return false; + } else if (!j.contains ("target") || !j["target"].is_string () || !encoding::hex::valid (string (j["target"]))) return false; - if (!j.contains("nodes")) return false; + if (!j.contains ("nodes")) return false; JSON nodes = j["nodes"]; - if (nodes.is_array()) { - for (const JSON& node : nodes) if (!node.is_string() || - (node != "*" && !(encoding::hex::valid(string(node)) && string(node).size() == 64))) return false; + if (nodes.is_array ()) { + for (const JSON &node : nodes) if (!node.is_string () || + (node != "*" && !(encoding::hex::valid (string (node)) && string (node).size () == 64))) return false; } else return false; return true; } - proofs_serialization_standard::operator JSON() const { - if (!valid()) return nullptr; + proofs_serialization_standard::operator JSON () const { + if (!valid ()) return nullptr; - JSON j = JSON::object_t{}; + JSON j = JSON::object_t {}; j["index"] = Path.Index; - j["nodes"] = write_path(branch()); + j["nodes"] = write_path (branch ()); - if (bool(Txid)) { - j["txOrId"] = write_digest(*Txid); + if (bool (Txid)) { + j["txOrId"] = write_digest (*Txid); } else { - j["txOrId"] = encoding::hex::write(*Transaction); + j["txOrId"] = encoding::hex::write (*Transaction); } - if (bool(BlockHash)) { - j["target"] = write_digest(*BlockHash); - } else if (bool(BlockHeader)) { + if (bool (BlockHash)) { + j["target"] = write_digest (*BlockHash); + } else if (bool (BlockHeader)) { j["targetType"] = "header"; - j["target"] = encoding::hex::write(BlockHeader->write()); - } else if (bool(MerkleRoot)) { + j["target"] = encoding::hex::write (BlockHeader->write ()); + } else if (bool (MerkleRoot)) { j["targetType"] = "merkleRoot"; - j["target"] = write_digest(*MerkleRoot); + j["target"] = write_digest (*MerkleRoot); } else { return nullptr; } @@ -121,96 +127,93 @@ namespace Gigamonkey::BitcoinAssociation { return j; } - digest256 inline proofs_serialization_standard::txid(const JSON& j) { - if (!valid(j)) return {}; - if (j["txOrId"].size() == 64) { - return read_digest(j["txOrId"]); + digest256 inline proofs_serialization_standard::txid (const JSON &j) { + if (!valid (j)) return {}; + if (j["txOrId"].size () == 64) { + return read_digest (j["txOrId"]); } else { - return Bitcoin::transaction::id(*encoding::hex::read(string(j["txOrId"]))); + return Bitcoin::transaction::id(*encoding::hex::read (string (j["txOrId"]))); } } - proofs_serialization_standard proofs_serialization_standard::read_JSON(const JSON& j) { + proofs_serialization_standard proofs_serialization_standard::read_JSON (const JSON &j) { proofs_serialization_standard x; - if (!proofs_serialization_standard::valid(j)) return {}; + if (!proofs_serialization_standard::valid (j)) return {}; - if (string(j["txOrId"]).size() == 64) { - x.Txid = read_digest(j["txOrId"]); - } else { - // we know this is ok because we checked valid earlier. - x.Transaction = *encoding::hex::read(string(j["txOrId"])); - } + if (string (j["txOrId"]).size () == 64) x.Txid = read_digest (j["txOrId"]); + // we know this is ok because we checked valid earlier. + else x.Transaction = *encoding::hex::read (string (j["txOrId"])); x.Path.Index = j["index"]; - x.Path.Digests = read_path(j["nodes"], x.leaf()); + x.Path.Digests = read_path (j["nodes"], x.leaf ()); - if (!j.contains("targetType")) { - x.BlockHash = read_digest(j["target"]); + if (!j.contains ("targetType")) { + x.BlockHash = read_digest (j["target"]); } else { if (j["targetType"] == "hash") { - x.BlockHash = read_digest(j["target"]); + x.BlockHash = read_digest (j["target"]); } else if (j["targetType"] == "header") { - x.BlockHeader = read_header(j["target"]); + x.BlockHeader = read_header (j["target"]); } else if (j["targetType"] == "merkleRoot"){ - x.MerkleRoot = read_digest(j["target"]); + x.MerkleRoot = read_digest (j["target"]); } else return {}; } return x; } - reader &read_transaction(reader &r, bytes& b) { - return r >> Bitcoin::var_string{b}; + reader &read_transaction (reader &r, bytes &b) { + return r >> Bitcoin::var_string {b}; } - reader &read_node(reader &r, std::optional& node) { + reader &read_node (reader &r, maybe &node) { byte type; r = r >> type; if (type == 1) { node = {}; } else if (type == 0) { - node = {digest256{}}; + node = {digest256 {}}; r = r >> *node; - } else throw std::logic_error{"unknown node type"}; + } else throw std::logic_error {"unknown node type"}; return r; } - reader &read_path(reader &r, digest256 leaf, Merkle::path& p) { + reader &read_path (reader &r, digest256 leaf, Merkle::path &p) { Bitcoin::var_int size; r >> size; Merkle::digests d; - Merkle::leaf l{leaf, p.Index}; + Merkle::leaf l {leaf, p.Index}; for (int i = 0; i < size; i++) { - std::optional Next; - r = read_node(r, Next); - digest256& next = bool(Next) ? *Next : l.Digest; + maybe Next; + r = read_node (r, Next); + digest256& next = bool (Next) ? *Next : l.Digest; d = d << next; - l = l.next(next); + l = l.next (next); } - p.Digests = data::reverse(d); + p.Digests = data::reverse (d); return r; } - proofs_serialization_standard proofs_serialization_standard::read_binary(bytes_view b) { + proofs_serialization_standard proofs_serialization_standard::read_binary (bytes_view b) { try { proofs_serialization_standard x; byte flags; - bytes_reader r{b.data(), b.data() + b.size()}; + bytes_reader r {b.data (), b.data () + b.size ()}; Bitcoin::var_int index; r >> flags >> index; x.Path.Index = index; - if (x.transaction_included(flags)) { + if (x.transaction_included (flags)) { bytes tx; - read_transaction(r, tx); + read_transaction (r, tx); } else { Bitcoin::txid t; r >> t; x.Txid = t; } - - switch (target_type(flags)) { + + switch (target_type (flags)) { case target_type_block_hash: { digest256 block_hash; r >> block_hash; @@ -218,9 +221,9 @@ namespace Gigamonkey::BitcoinAssociation { break; } case target_type_block_header: { - bytes header(80); + bytes header (80); r >> header; - x.BlockHeader = Bitcoin::header{slice<80>(header.data())}; + x.BlockHeader = Bitcoin::header {slice<80> (header.data ())}; break; } case target_type_Merkle_root: { @@ -234,83 +237,83 @@ namespace Gigamonkey::BitcoinAssociation { } } - read_path(r, x.txid(), x.Path); + read_path (r, x.txid (), x.Path); return x; } catch (...) {} return {}; } - writer &write_duplicate(writer &w) { - return w << byte(1); + writer &write_duplicate (writer &w) { + return w << byte (1); } - writer &write_node(writer &w, const digest256& d) { - return w << byte(0) << d; + writer &write_node (writer &w, const digest256 &d) { + return w << byte (0) << d; } - writer &write_path(writer &w, list> b) { - w << Bitcoin::var_int{b.size()}; - for (const std::optional &z : b) { - if (bool(z)) w = write_node(w, *z); - else w = write_duplicate(w); + writer &write_path (writer &w, list> b) { + w << Bitcoin::var_int {b.size ()}; + for (const maybe &z : b) { + if (bool (z)) w = write_node (w, *z); + else w = write_duplicate (w); } return w; } - writer &write_txid(writer &w, const Bitcoin::txid& t) { + writer &write_txid (writer &w, const Bitcoin::txid &t) { return w << t; } - writer &write_transaction(writer &w, const bytes& t) { - return w << Bitcoin::var_int{t.size()} << t; + writer &write_transaction (writer &w, const bytes& t) { + return w << Bitcoin::var_int {t.size ()} << t; } - proofs_serialization_standard::operator bytes() const { - bool tx_included = transaction_included(); - auto tt = target_type(); + proofs_serialization_standard::operator bytes () const { + bool tx_included = transaction_included (); + auto tt = target_type (); // we need to pre-generate some data for the path. - auto path = generate_path(branch()); + auto path = generate_path (branch ()); // figure out the serialized size. size_t size = 1 + - Bitcoin::var_int::size(Path.Index) + - Bitcoin::var_int::size(Path.Digests.size()) + - (tx_included ? Bitcoin::var_int::size(Transaction->size()) + Transaction->size() : 32); - for (const std::optional& d : path) size += (bool(d) ? 33 : 1); + Bitcoin::var_int::size (Path.Index) + + Bitcoin::var_int::size (Path.Digests.size ()) + + (tx_included ? Bitcoin::var_int::size (Transaction->size ()) + Transaction->size () : 32); + for (const maybe& d : path) size += (bool (d) ? 33 : 1); if (tt == target_type_block_hash || tt == target_type_Merkle_root) size += 32; else if (tt == target_type_block_header) size += 80; // allocate space - bytes b(size); + bytes b (size); // write flags and index. - bytes_writer w{b.begin(), b.end()}; - w << flags() << Bitcoin::var_int{index()}; + bytes_writer w {b.begin (), b.end ()}; + w << flags() << Bitcoin::var_int {index ()}; - if (tx_included) write_transaction(w, *Transaction); - else write_txid(w, *Txid); + if (tx_included) write_transaction (w, *Transaction); + else write_txid (w, *Txid); - if (tt == target_type_block_hash) write_txid(w, *BlockHash); - else if (tt == target_type_Merkle_root) write_txid(w, *MerkleRoot); - else if (target_type_block_header) w << BlockHeader->write(); + if (tt == target_type_block_hash) write_txid (w, *BlockHash); + else if (tt == target_type_Merkle_root) write_txid (w, *MerkleRoot); + else if (target_type_block_header) w << BlockHeader->write (); else return {}; - write_path(w, path); + write_path (w, path); return b; } - proofs_serialization_standard::target_type_value proofs_serialization_standard::target_type(const JSON &j) { - if (!j.contains("targetType")) return target_type_block_hash; + proofs_serialization_standard::target_type_value proofs_serialization_standard::target_type (const JSON &j) { + if (!j.contains ("targetType")) return target_type_block_hash; if (j["targetType"] == "hash") return target_type_block_hash; if (j["targetType"] == "header") return target_type_block_header; return target_type_Merkle_root; } - proofs_serialization_standard::target_type_value proofs_serialization_standard::target_type() const { - if (bool(BlockHeader)) return target_type_block_header; - if (bool(BlockHash)) return target_type_block_hash; - if (bool(MerkleRoot)) return target_type_Merkle_root; + proofs_serialization_standard::target_type_value proofs_serialization_standard::target_type () const { + if (bool (BlockHeader)) return target_type_block_header; + if (bool (BlockHash)) return target_type_block_hash; + if (bool (MerkleRoot)) return target_type_Merkle_root; return target_type_invalid; } @@ -323,15 +326,15 @@ namespace Gigamonkey::BitcoinAssociation { Path = p; } - std::optional inline proofs_serialization_standard::Merkle_root(const JSON& j) { + maybe inline proofs_serialization_standard::Merkle_root(const JSON& j) { target_type_value target = target_type(j); - if (target == target_type_Merkle_root) return {read_digest(j["target"])}; - if (target == target_type_block_header) return block_header(j)->MerkleRoot; + if (target == target_type_Merkle_root) return {read_digest (j["target"])}; + if (target == target_type_block_header) return block_header (j)->MerkleRoot; return {}; } - std::optional inline proofs_serialization_standard::block_header(const JSON& j) { - if (j.contains("targetType") && j["targetType"] == "header") return {read_header(j["target"])}; + maybe inline proofs_serialization_standard::block_header (const JSON &j) { + if (j.contains ("targetType") && j["targetType"] == "header") return {read_header (j["target"])}; return {}; } diff --git a/src/gigamonkey/p2p/checksum.cpp b/src/gigamonkey/p2p/checksum.cpp index 29b0d60a..acb7d496 100644 --- a/src/gigamonkey/p2p/checksum.cpp +++ b/src/gigamonkey/p2p/checksum.cpp @@ -8,26 +8,32 @@ namespace Gigamonkey::Bitcoin { bytes append_checksum (bytes_view b) { + bytes checked (b.size() + 4); bytes_writer w (checked.begin (), checked.end ()); w << b << checksum (b); return checked; + } Gigamonkey::checksum checksum (bytes_view b) { + Gigamonkey::checksum x; digest256 digest = Hash256 (b); std::copy (digest.Value.begin (), digest.Value.begin () + 4, x.begin ()); return x; + } bytes_view remove_checksum (bytes_view b) { + if (b.size () < 4) return {}; Gigamonkey::checksum x; std::copy (b.end () - 4, b.end (), x.begin ()); bytes_view without = b.substr (0, b.size () - 4); if (x != checksum (without)) return {}; return without; + } } @@ -35,6 +41,7 @@ namespace Gigamonkey::Bitcoin { namespace Gigamonkey::base58 { string check::encode () const { + bytes data = Bitcoin::append_checksum (static_cast (*this)); size_t leading_zeros = 0; while (leading_zeros < data.size () && data[leading_zeros] == 0) leading_zeros++; @@ -43,15 +50,28 @@ namespace Gigamonkey::base58 { std::stringstream ss; ss << ones << b58; return ss.str (); + } check check::decode (string_view s) { + size_t leading_ones = 0; - while (leading_ones < s.size() && s[leading_ones] == '1') leading_ones++; - string_view body = s.substr (leading_ones); - if (!encoding::base58::valid (body)) return {}; - bytes decoded = encoding::base58::read (body); - return {Bitcoin::remove_checksum (write (leading_ones + decoded.size (), bytes (leading_ones, 0x00), decoded))}; + while (leading_ones < s.size () && s[leading_ones] == '1') leading_ones++; + + maybe decoded; + + // this is a special case that is extremely unlikely in practice. + // The empty string is an invalid base 58 string, so if that's + // what we get then we act like we decoded it to an empty byte sequence. + if (leading_ones == s.size ()) decoded = {bytes {}}; + else { + string_view body = s.substr (leading_ones); + decoded = encoding::base58::read (body); + if (!bool (decoded)) return {}; + } + + return {Bitcoin::remove_checksum (write (leading_ones + decoded->size (), bytes (leading_ones, 0x00), *decoded))}; + } // try all single letter replacements, insertions, and deletions @@ -69,6 +89,7 @@ namespace Gigamonkey::base58 { // replacements for (int i = 0; i < test.size (); i++) { + string replace = test; for (char c : characters) { @@ -77,10 +98,12 @@ namespace Gigamonkey::base58 { check x (replace); if (x.valid ()) return x; } + } // insertions for (int i = 0; i <= test.size(); i++) { + string insert {}; insert.resize (test.size () + 1); std::copy (test.begin (), test.begin () + i, insert.begin ()); @@ -91,10 +114,12 @@ namespace Gigamonkey::base58 { check x (insert); if (x.valid ()) return x; } + } // deletions for (int i = 0; i < test.size (); i++) { + string deletions {}; deletions.resize (test.size () - 1); diff --git a/src/gigamonkey/script/machine.cpp b/src/gigamonkey/script/machine.cpp index 54b02911..e5dfe054 100644 --- a/src/gigamonkey/script/machine.cpp +++ b/src/gigamonkey/script/machine.cpp @@ -15,126 +15,125 @@ bool fRequireStandard = true; namespace Gigamonkey::Bitcoin::interpreter { - result inline verify_signature(bytes_view sig, bytes_view pub, const sighash::document &doc, uint32 flags) { + result inline verify_signature (bytes_view sig, bytes_view pub, const sighash::document &doc, uint32 flags) { - if (flags & SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE && !secp256k1::pubkey::compressed(pub)) return SCRIPT_ERR_NONCOMPRESSED_PUBKEY; - else if (flags & SCRIPT_VERIFY_STRICTENC && !secp256k1::pubkey::valid(pub)) return SCRIPT_ERR_PUBKEYTYPE; + if (flags & SCRIPT_VERIFY_COMPRESSED_PUBKEYTYPE && !secp256k1::pubkey::compressed (pub)) return SCRIPT_ERR_NONCOMPRESSED_PUBKEY; + else if (flags & SCRIPT_VERIFY_STRICTENC && !secp256k1::pubkey::valid (pub)) return SCRIPT_ERR_PUBKEYTYPE; - auto d = signature::directive(sig); - auto raw = signature::raw(sig); + auto d = signature::directive (sig); + auto raw = signature::raw (sig); - if (!sighash::valid(d)) return SCRIPT_ERR_SIG_HASHTYPE; - if (sighash::has_fork_id(d) && !(flags & SCRIPT_ENABLE_SIGHASH_FORKID)) return SCRIPT_ERR_ILLEGAL_FORKID; - if (!sighash::has_fork_id(d) && (flags & SCRIPT_ENABLE_SIGHASH_FORKID)) return SCRIPT_ERR_MUST_USE_FORKID; + if (!sighash::valid (d)) return SCRIPT_ERR_SIG_HASHTYPE; + if (sighash::has_fork_id (d) && !(flags & SCRIPT_ENABLE_SIGHASH_FORKID)) return SCRIPT_ERR_ILLEGAL_FORKID; + if (!sighash::has_fork_id (d) && (flags & SCRIPT_ENABLE_SIGHASH_FORKID)) return SCRIPT_ERR_MUST_USE_FORKID; - if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) && !signature::DER(sig)) + if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) && !signature::DER (sig)) return SCRIPT_ERR_SIG_DER; - if ((flags & SCRIPT_VERIFY_LOW_S) && !secp256k1::signature::normalized(raw)) return SCRIPT_ERR_SIG_HIGH_S; + if ((flags & SCRIPT_VERIFY_LOW_S) && !secp256k1::signature::normalized (raw)) return SCRIPT_ERR_SIG_HIGH_S; - if (signature::verify(sig, pub, doc)) return true; + if (signature::verify (sig, pub, doc)) return true; - if (flags & SCRIPT_VERIFY_NULLFAIL && sig.size() != 0) return SCRIPT_ERR_SIG_NULLFAIL; + if (flags & SCRIPT_VERIFY_NULLFAIL && sig.size () != 0) return SCRIPT_ERR_SIG_NULLFAIL; return false; } - list make_list(const std::vector &v) { + list make_list (const std::vector &v) { list l; for (const bool &b : v) l << b; return l; } - std::ostream& operator<<(std::ostream& o, const machine& i) { - return o << "machine{\n\tProgram: " << i.State.unread() + std::ostream &operator << (std::ostream &o, const machine &i) { + return o << "machine{\n\tProgram: " << i.State.unread () << ",\n\tHalt: " << (i.Halt ? "true" : "false") << ", Result: " << i.Result << ", Flags: " << i.State.Flags << ",\n\tStack: " << i.State.Stack << ",\n\tAltStack: " << i.State.AltStack << ", Exec: " << make_list(i.State.Exec) << ", Else: " << make_list(i.State.Else) << "}"; } - void step_through(machine &m) { + void step_through (machine &m) { std::cout << "begin program" << std::endl; - while(true) { + while (true) { std::cout << m << std::endl; if (m.Halt) break; - wait_for_enter(); - m.step(); + wait_for_enter (); + m.step (); } std::cout << "Result " << m.Result << std::endl; } - machine::state::state(uint32 flags, bool consensus, std::optional doc, const bytes &script) : - Flags{flags}, Consensus{consensus}, Config{}, Document{doc}, Script{script}, Counter{program_counter{Script}}, - Stack{Config.GetMaxStackMemoryUsage(Flags & SCRIPT_UTXO_AFTER_GENESIS, consensus)}, - AltStack{Stack.makeChildStack()}, Exec{}, Else{}, OpCount{0} {} + machine::state::state (uint32 flags, bool consensus, maybe doc, const bytes &script) : + Flags {flags}, Consensus {consensus}, Config {}, Document {doc}, Script {script}, Counter{program_counter{Script}}, + Stack {Config.GetMaxStackMemoryUsage (Flags & SCRIPT_UTXO_AFTER_GENESIS, consensus)}, + AltStack {Stack.makeChildStack ()}, Exec {}, Else{}, OpCount {0} {} machine::machine(const script &unlock, const script &lock, const redemption_document &doc, uint32 flags) : - machine{{doc}, decompile(unlock), decompile(lock), flags} {} + machine{{doc}, decompile (unlock), decompile (lock), flags} {} machine::machine(const script &unlock, const script &lock, uint32 flags) : - machine{{}, decompile(unlock), decompile(lock), flags} {} + machine{{}, decompile(unlock), decompile (lock), flags} {} - machine::machine(std::optional doc, const program unlock, const program lock, uint32 flags) : - Halt{false}, Result{false}, State{flags, false, doc, compile(full(unlock, lock))} { - if (auto err = check_scripts(unlock, lock, flags); err) { + machine::machine (maybe doc, const program unlock, const program lock, uint32 flags) : + Halt{false}, Result {false}, State{flags, false, doc, compile (full (unlock, lock))} { + if (auto err = check_scripts (unlock, lock, flags); err) { Halt = true; Result = err; } } - result state_step(machine::state &x) { - return x.step(); + result state_step (machine::state &x) { + return x.step (); } - result state_run(machine::state &x) { + result state_run (machine::state &x) { while (true) { - auto err = x.step(); + auto err = x.step (); if (err.Error || err.Success) return err; } } - result catch_all_errors(result (*fn)(machine::state&), machine::state &x) { + result catch_all_errors (result (*fn) (machine::state &), machine::state &x) { try { - return fn(x); - } catch(scriptnum_overflow_error& err) { + return fn (x); + } catch (scriptnum_overflow_error &err) { return SCRIPT_ERR_SCRIPTNUM_OVERFLOW; - } catch(scriptnum_minencode_error& err) { + } catch (scriptnum_minencode_error &err) { return SCRIPT_ERR_SCRIPTNUM_MINENCODE; - } catch(stack_overflow_error& err) { + } catch (stack_overflow_error &err) { return SCRIPT_ERR_STACK_SIZE; - } catch(const bsv::big_int_error&) { + } catch (const bsv::big_int_error &) { return SCRIPT_ERR_BIG_INT; - } catch(std::out_of_range& err) { + } catch (std::out_of_range &err) { return SCRIPT_ERR_INVALID_STACK_OPERATION; - } catch(...) { + } catch (...) { return SCRIPT_ERR_UNKNOWN_ERROR; } } - void machine::step() { + void machine::step () { if (Halt) return; - auto err = catch_all_errors(state_step, State); + auto err = catch_all_errors (state_step, State); if (err.Error || err.Success) { Halt = true; Result = err; } } - result machine::run() { - Result = catch_all_errors(state_run, State); + result machine::run () { + Result = catch_all_errors (state_run, State); Halt = true; return Result; } - inline bool IsValidMaxOpsPerScript(uint64_t nOpCount, - const CScriptConfig &config, - bool isGenesisEnabled, bool consensus) + inline bool IsValidMaxOpsPerScript + (uint64_t nOpCount, const CScriptConfig &config, bool isGenesisEnabled, bool consensus) { - return (nOpCount <= config.GetMaxOpsPerScript(isGenesisEnabled, consensus)); + return (nOpCount <= config.GetMaxOpsPerScript (isGenesisEnabled, consensus)); } - static bool IsOpcodeDisabled(opcodetype opcode) { + static bool IsOpcodeDisabled (opcodetype opcode) { switch (opcode) { case OP_2MUL: case OP_2DIV: @@ -148,80 +147,79 @@ namespace Gigamonkey::Bitcoin::interpreter { return false; } - bytes inline cleanup_script_code(bytes_view script_code, bytes_view sig) { - return sighash::has_fork_id(signature::directive(sig)) ? - bytes(script_code) : - find_and_delete(script_code, compile(instruction::push(sig))); + bytes inline cleanup_script_code (bytes_view script_code, bytes_view sig) { + return sighash::has_fork_id (signature::directive (sig)) ? + bytes (script_code) : + find_and_delete (script_code, compile (instruction::push (sig))); } - sighash::document *add_script_code(redemption_document &doc, bytes_view script_code) { - return new sighash::document(doc.RedeemedValue, script_code, doc.Transaction, doc.InputIndex); + sighash::document *add_script_code (redemption_document &doc, bytes_view script_code) { + return new sighash::document (doc.RedeemedValue, script_code, doc.Transaction, doc.InputIndex); } - bool CastToBool(const valtype &vch) { - for (size_t i = 0; i < vch.size(); i++) { + bool CastToBool (const valtype &vch) { + for (size_t i = 0; i < vch.size (); i++) if (vch[i] != 0) { // Can be negative zero - if (i == vch.size() - 1 && vch[i] == 0x80) { - return false; - } + if (i == vch.size () - 1 && vch[i] == 0x80) return false; return true; } - } + return false; } - bytes_view get_push_data(bytes_view instruction) { - if (instruction.size() < 1) return {}; + bytes_view get_push_data (bytes_view instruction) { + if (instruction.size () < 1) return {}; - op Op = op(instruction[0]); + op Op = op (instruction[0]); - if (!is_push_data(Op)) return {}; + if (!is_push_data (Op)) return {}; - if (Op <= OP_PUSHSIZE75) return instruction.substr(1); + if (Op <= OP_PUSHSIZE75) return instruction.substr (1); - if (Op == OP_PUSHDATA1) return instruction.substr(2); + if (Op == OP_PUSHDATA1) return instruction.substr (2); - if (Op == OP_PUSHDATA2) return instruction.substr(3); + if (Op == OP_PUSHDATA2) return instruction.substr (3); - return instruction.substr(5); + return instruction.substr (5); } - result machine::state::step() { + result machine::state::step () { - const bool utxo_after_genesis{(Flags & SCRIPT_UTXO_AFTER_GENESIS) != 0}; - const uint64_t maxScriptNumLength = Config.GetMaxScriptNumLength(utxo_after_genesis, Consensus); + const bool utxo_after_genesis {(Flags & SCRIPT_UTXO_AFTER_GENESIS) != 0}; + const uint64_t maxScriptNumLength = Config.GetMaxScriptNumLength (utxo_after_genesis, Consensus); const bool fRequireMinimal = (Flags & SCRIPT_VERIFY_MINIMALDATA) != 0; // this will always be valid because we've already checked for invalid op codes. //bytes_view next = Counter.next_instruction(); - if (Counter.Next == bytes_view{}) { - if ((Flags & SCRIPT_VERIFY_CLEANSTACK) != 0 && Stack.size() != 1) return SCRIPT_ERR_CLEANSTACK; + if (Counter.Next == bytes_view {}) { + if ((Flags & SCRIPT_VERIFY_CLEANSTACK) != 0 && Stack.size () != 1) return SCRIPT_ERR_CLEANSTACK; return true; } - op Op = op(Counter.Next[0]); + op Op = op (Counter.Next[0]); // Check opcode limits. // // Push values are not taken into consideration. // Note how OP_RESERVED does not count towards the opcode limit. - if ((Op > OP_16) && !IsValidMaxOpsPerScript(++OpCount, Config, utxo_after_genesis, Consensus)) return SCRIPT_ERR_OP_COUNT; + if ((Op > OP_16) && !IsValidMaxOpsPerScript (++OpCount, Config, utxo_after_genesis, Consensus)) + return SCRIPT_ERR_OP_COUNT; - if (!utxo_after_genesis && (Counter.Next.size() - 1 > MAX_SCRIPT_ELEMENT_SIZE_BEFORE_GENESIS)) + if (!utxo_after_genesis && (Counter.Next.size () - 1 > MAX_SCRIPT_ELEMENT_SIZE_BEFORE_GENESIS)) return SCRIPT_ERR_PUSH_SIZE; // whether this op code will be executed. - bool executed = !count(Exec.begin(), Exec.end(), false); + bool executed = !count (Exec.begin (), Exec.end (), false); if (!executed) return SCRIPT_ERR_OK; // Some opcodes are disabled. - if (IsOpcodeDisabled(Op) && (!utxo_after_genesis || executed )) return SCRIPT_ERR_DISABLED_OPCODE; + if (IsOpcodeDisabled (Op) && (!utxo_after_genesis || executed )) + return SCRIPT_ERR_DISABLED_OPCODE; - if (executed && 0 <= Op && Op <= OP_PUSHDATA4) { - Stack.push_back(get_push_data(Counter.Next)); - } else switch (Op) { + if (executed && 0 <= Op && Op <= OP_PUSHDATA4) Stack.push_back (get_push_data (Counter.Next)); + else switch (Op) { // // Push value // @@ -243,8 +241,8 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_15: case OP_16: { // ( -- value) - CScriptNum bn((int)Op - (int)(OP_1 - 1)); - Stack.push_back(bn.getvch()); + CScriptNum bn ((int) Op - (int) (OP_1 - 1)); + Stack.push_back (bn.getvch ()); // The result of these opcodes should always be the // minimal way to push the data they push, so no need // for a CheckMinimalPush here. @@ -259,11 +257,13 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_CHECKLOCKTIMEVERIFY: { if (!(Flags & SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY) || utxo_after_genesis) { // not enabled; treat as a NOP2 - if (Flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) return SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS; + if (Flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + return SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS; + break; } - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; // Note that elsewhere numeric opcodes are limited to // operands in the range -2**31+1 to 2**31-1, however it @@ -280,7 +280,7 @@ namespace Gigamonkey::Bitcoin::interpreter { // up to 5-byte bignums, which are good until 2**39-1, // well beyond the 2**32-1 limit of the nLockTime field // itself. - const CScriptNum nLockTime(Stack.stacktop(-1).GetElement(), fRequireMinimal, 5); + const CScriptNum nLockTime (Stack.stacktop (-1).GetElement (), fRequireMinimal, 5); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use @@ -289,7 +289,7 @@ namespace Gigamonkey::Bitcoin::interpreter { // Actually compare the specified lock time with the // transaction. - if (bool(Document) && !Document->check_locktime(nLockTime)) return SCRIPT_ERR_UNSATISFIED_LOCKTIME; + if (bool (Document) && !Document->check_locktime (nLockTime)) return SCRIPT_ERR_UNSATISFIED_LOCKTIME; } break; @@ -300,12 +300,12 @@ namespace Gigamonkey::Bitcoin::interpreter { break; } - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; // nSequence, like nLockTime, is a 32-bit unsigned // integer field. See the comment in CHECKLOCKTIMEVERIFY // regarding 5-byte numeric operands. - const CScriptNum nSequence(Stack.stacktop(-1).GetElement(), fRequireMinimal, 5); + const CScriptNum nSequence (Stack.stacktop (-1).GetElement(), fRequireMinimal, 5); // In the rare event that the argument may be < 0 due to // some arithmetic being done first, you can always use @@ -315,10 +315,11 @@ namespace Gigamonkey::Bitcoin::interpreter { // To provide for future soft-fork extensibility, if the // operand has the disabled lock-time flag set, // CHECKSEQUENCEVERIFY behaves as a NOP. - if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != script_zero()) return SCRIPT_ERR_OK; + if ((nSequence & CTxIn::SEQUENCE_LOCKTIME_DISABLE_FLAG) != script_zero ()) return SCRIPT_ERR_OK; // Compare the specified sequence number with the input. - if (bool(Document) && !Document->check_sequence(nSequence)) return SCRIPT_ERR_UNSATISFIED_LOCKTIME; + if (bool (Document) && !Document->check_sequence (nSequence)) + return SCRIPT_ERR_UNSATISFIED_LOCKTIME; } break; @@ -330,22 +331,23 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_NOP8: case OP_NOP9: case OP_NOP10: { - if (Flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) return SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS; + if (Flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + return SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS; } break; case OP_VERIFY: { // (true -- ) or // (false -- false) and return - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - - if (CastToBool(Stack.stacktop(-1).GetElement())) Stack.pop_back(); + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + + if (CastToBool (Stack.stacktop (-1).GetElement ())) Stack.pop_back (); else return SCRIPT_ERR_VERIFY; } break; case OP_RETURN: { if (utxo_after_genesis) { - if (Exec.empty()) return true; + if (Exec.empty ()) return true; // Pre-Genesis OP_RETURN marks script as invalid } else return SCRIPT_ERR_OP_RETURN; } break; @@ -354,129 +356,129 @@ namespace Gigamonkey::Bitcoin::interpreter { // Stack ops // case OP_TOALTSTACK: { - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - AltStack.moveTopToStack(Stack); + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + AltStack.moveTopToStack (Stack); } break; case OP_FROMALTSTACK: { - if (AltStack.size() < 1) return SCRIPT_ERR_INVALID_ALTSTACK_OPERATION; - Stack.moveTopToStack(AltStack); + if (AltStack.size () < 1) return SCRIPT_ERR_INVALID_ALTSTACK_OPERATION; + Stack.moveTopToStack (AltStack); } break; case OP_2DROP: { // (x1 x2 -- ) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.pop_back(); - Stack.pop_back(); + Stack.pop_back (); + Stack.pop_back (); } break; case OP_2DUP: { // (x1 x2 -- x1 x2 x1 x2) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch1 = Stack.stacktop(-2); - LimitedVector vch2 = Stack.stacktop(-1); + LimitedVector vch1 = Stack.stacktop (-2); + LimitedVector vch2 = Stack.stacktop (-1); - Stack.push_back(vch1); - Stack.push_back(vch2); + Stack.push_back (vch1); + Stack.push_back (vch2); } break; case OP_3DUP: { // (x1 x2 x3 -- x1 x2 x3 x1 x2 x3) - if (Stack.size() < 3) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 3) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch1 = Stack.stacktop(-3); - LimitedVector vch2 = Stack.stacktop(-2); - LimitedVector vch3 = Stack.stacktop(-1); + LimitedVector vch1 = Stack.stacktop (-3); + LimitedVector vch2 = Stack.stacktop (-2); + LimitedVector vch3 = Stack.stacktop (-1); - Stack.push_back(vch1); - Stack.push_back(vch2); - Stack.push_back(vch3); + Stack.push_back (vch1); + Stack.push_back (vch2); + Stack.push_back (vch3); } break; case OP_2OVER: { // (x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2) - if (Stack.size() < 4) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 4) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch1 = Stack.stacktop(-4); - LimitedVector vch2 = Stack.stacktop(-3); - Stack.push_back(vch1); - Stack.push_back(vch2); + LimitedVector vch1 = Stack.stacktop (-4); + LimitedVector vch2 = Stack.stacktop (-3); + Stack.push_back (vch1); + Stack.push_back (vch2); } break; case OP_2ROT: { // (x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2) - if (Stack.size() < 6) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 6) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch1 = Stack.stacktop(-6); - LimitedVector vch2 = Stack.stacktop(-5); + LimitedVector vch1 = Stack.stacktop (-6); + LimitedVector vch2 = Stack.stacktop (-5); - Stack.erase(- 6, - 4); - Stack.push_back(vch1); - Stack.push_back(vch2); + Stack.erase (- 6, - 4); + Stack.push_back (vch1); + Stack.push_back (vch2); } break; case OP_2SWAP: { // (x1 x2 x3 x4 -- x3 x4 x1 x2) - if (Stack.size() < 4) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 4) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.swapElements(Stack.size() - 4, Stack.size() - 2); - Stack.swapElements(Stack.size() - 3, Stack.size() - 1); + Stack.swapElements (Stack.size () - 4, Stack.size () - 2); + Stack.swapElements (Stack.size () - 3, Stack.size () - 1); } break; case OP_IFDUP: { // (x - 0 | x x) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) + return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch = Stack.stacktop(-1); - if (CastToBool(vch.GetElement())) { - Stack.push_back(vch); - } + LimitedVector vch = Stack.stacktop (-1); + + if (CastToBool (vch.GetElement ())) Stack.push_back (vch); } break; case OP_DEPTH: { // -- stacksize - const CScriptNum bn(bsv::bint{Stack.size()}); - Stack.push_back(bn.getvch()); + const CScriptNum bn (bsv::bint {Stack.size ()}); + Stack.push_back (bn.getvch ()); } break; case OP_DROP: { // (x -- ) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.pop_back(); + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + Stack.pop_back (); } break; case OP_DUP: { // (x -- x x) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch = Stack.stacktop(-1); - Stack.push_back(vch); + LimitedVector vch = Stack.stacktop (-1); + Stack.push_back (vch); } break; case OP_NIP: { // (x1 x2 -- x2) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.erase(-2); + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + Stack.erase (-2); } break; case OP_OVER: { // (x1 x2 -- x1 x2 x1) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch = Stack.stacktop(-2); - Stack.push_back(vch); + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + LimitedVector vch = Stack.stacktop (-2); + Stack.push_back (vch); } break; @@ -484,23 +486,25 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_ROLL: { // (xn ... x2 x1 x0 n - xn ... x2 x1 x0 xn) // (xn ... x2 x1 x0 n - ... x2 x1 x0 xn) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - const auto& top{Stack.stacktop(-1).GetElement()}; - const CScriptNum sn{ + const auto &top {Stack.stacktop (-1).GetElement ()}; + + const CScriptNum sn { top, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; - Stack.pop_back(); - if(sn < 0 || sn >= Stack.size()) return SCRIPT_ERR_INVALID_STACK_OPERATION; + Stack.pop_back (); + + if (sn < 0 || sn >= Stack.size ()) + return SCRIPT_ERR_INVALID_STACK_OPERATION; - const auto n{sn.to_size_t_limited()}; - LimitedVector vch = Stack.stacktop(-n - 1); + const auto n{sn.to_size_t_limited ()}; + LimitedVector vch = Stack.stacktop (-n - 1); - if (Op == OP_ROLL) { - Stack.erase(- n - 1); - } - Stack.push_back(vch); + if (Op == OP_ROLL) Stack.erase (- n - 1); + + Stack.push_back (vch); } break; @@ -508,33 +512,35 @@ namespace Gigamonkey::Bitcoin::interpreter { // (x1 x2 x3 -- x2 x3 x1) // x2 x1 x3 after first swap // x2 x3 x1 after second swap - if (Stack.size() < 3) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.swapElements(Stack.size() - 3, Stack.size() - 2); - Stack.swapElements(Stack.size() - 2, Stack.size() - 1); + if (Stack.size () < 3) + return SCRIPT_ERR_INVALID_STACK_OPERATION; + + Stack.swapElements (Stack.size () - 3, Stack.size () - 2); + Stack.swapElements (Stack.size () - 2, Stack.size () - 1); } break; case OP_SWAP: { // (x1 x2 -- x2 x1) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - Stack.swapElements(Stack.size() - 2, Stack.size() - 1); + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + Stack.swapElements (Stack.size () - 2, Stack.size () - 1); } break; case OP_TUCK: { // (x1 x2 -- x2 x1 x2) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector vch = Stack.stacktop(-1); - Stack.insert(-2, vch); + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + LimitedVector vch = Stack.stacktop (-1); + Stack.insert (-2, vch); } break; case OP_SIZE: { // (in -- in size) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - CScriptNum bn(bsv::bint{Stack.stacktop(-1).size()}); - Stack.push_back(bn.getvch()); + CScriptNum bn (bsv::bint {Stack.stacktop (-1).size ()}); + Stack.push_back (bn.getvch ()); } break; @@ -545,23 +551,23 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_OR: case OP_XOR: { // (x1 x2 - out) - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector &vch1 = Stack.stacktop(-2); - LimitedVector &vch2 = Stack.stacktop(-1); + LimitedVector &vch1 = Stack.stacktop (-2); + LimitedVector &vch2 = Stack.stacktop (-1); // Inputs must be the same size - if (vch1.size() != vch2.size()) return SCRIPT_ERR_INVALID_OPERAND_SIZE; + if (vch1.size () != vch2.size ()) return SCRIPT_ERR_INVALID_OPERAND_SIZE; // To avoid allocating, we modify vch1 in place. switch (Op) { - case OP_AND: for (size_t i = 0; i < vch1.size(); ++i) vch1[i] &= vch2[i]; + case OP_AND: for (size_t i = 0; i < vch1.size (); ++i) vch1[i] &= vch2[i]; break; - case OP_OR: for (size_t i = 0; i < vch1.size(); ++i) vch1[i] |= vch2[i]; + case OP_OR: for (size_t i = 0; i < vch1.size (); ++i) vch1[i] |= vch2[i]; break; - case OP_XOR: for (size_t i = 0; i < vch1.size(); ++i) vch1[i] ^= vch2[i]; + case OP_XOR: for (size_t i = 0; i < vch1.size (); ++i) vch1[i] ^= vch2[i]; break; default: @@ -569,40 +575,40 @@ namespace Gigamonkey::Bitcoin::interpreter { } // And pop vch2. - Stack.pop_back(); + Stack.pop_back (); } break; case OP_INVERT: { // (x -- out) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector &vch1 = Stack.stacktop(-1); + LimitedVector &vch1 = Stack.stacktop (-1); // To avoid allocating, we modify vch1 in place - for(size_t i=0; i &vch1 = Stack.stacktop(-2); - LimitedVector &vch2 = Stack.stacktop(-1); + LimitedVector &vch1 = Stack.stacktop (-2); + LimitedVector &vch2 = Stack.stacktop (-1); - bool fEqual = (vch1.GetElement() == vch2.GetElement()); + bool fEqual = (vch1.GetElement () == vch2.GetElement ()); // OP_NOTEQUAL is disabled because it would be too // easy to say something like n != 1 and have some // wiseguy pass in 1 with extra zero bytes after it // (numerically, 0x01 == 0x0001 == 0x000001) // if (opcode == OP_NOTEQUAL) // fEqual = !fEqual; - Stack.pop_back(); - Stack.pop_back(); - Stack.push_back(fEqual ? script_true() : script_false()); + Stack.pop_back (); + Stack.pop_back (); + Stack.push_back (fEqual ? script_true () : script_false ()); if (Op == OP_EQUALVERIFY) { - if (fEqual) Stack.pop_back(); + if (fEqual) Stack.pop_back (); else return SCRIPT_ERR_EQUALVERIFY; } @@ -618,38 +624,38 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_NOT: case OP_0NOTEQUAL: { // (in -- out) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; - const auto &top{Stack.stacktop(-1).GetElement()}; - CScriptNum bn{top, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; + const auto &top {Stack.stacktop (-1).GetElement ()}; + CScriptNum bn {top, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; switch (Op) { case OP_1ADD: - bn += utxo_after_genesis ? CScriptNum{bsv::bint{1}} : script_one(); + bn += utxo_after_genesis ? CScriptNum {bsv::bint {1}} : script_one (); break; case OP_1SUB: - bn -= utxo_after_genesis ? CScriptNum{bsv::bint{1}} : script_one(); + bn -= utxo_after_genesis ? CScriptNum {bsv::bint {1}} : script_one (); // bn -= bnOne; break; case OP_NEGATE: bn = -bn; break; case OP_ABS: - if (bn < script_zero()) bn = -bn; + if (bn < script_zero ()) bn = -bn; break; case OP_NOT: - bn = (bn == script_zero()); + bn = (bn == script_zero ()); break; case OP_0NOTEQUAL: - bn = (bn != script_zero()); + bn = (bn != script_zero ()); break; default: - assert(!"invalid opcode"); + assert (!"invalid opcode"); break; } - Stack.pop_back(); - Stack.push_back(bn.getvch()); + Stack.pop_back (); + Stack.push_back (bn.getvch ()); } break; case OP_ADD: @@ -669,16 +675,16 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_MIN: case OP_MAX: { // (x1 x2 -- out) - if (Stack.size() < 2) SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) SCRIPT_ERR_INVALID_STACK_OPERATION; - const auto& arg_2 = Stack.stacktop(-2); - const auto& arg_1 = Stack.stacktop(-1); + const auto& arg_2 = Stack.stacktop (-2); + const auto& arg_1 = Stack.stacktop (-1); - CScriptNum bn1(arg_2.GetElement(), fRequireMinimal, + CScriptNum bn1 (arg_2.GetElement (), fRequireMinimal, maxScriptNumLength, utxo_after_genesis); - CScriptNum bn2(arg_1.GetElement(), fRequireMinimal, + CScriptNum bn2 (arg_1.GetElement (), fRequireMinimal, maxScriptNumLength, utxo_after_genesis); CScriptNum bn; @@ -697,21 +703,21 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_DIV: // denominator must not be 0 - if (bn2 == script_zero()) return SCRIPT_ERR_DIV_BY_ZERO; + if (bn2 == script_zero ()) return SCRIPT_ERR_DIV_BY_ZERO; bn = bn1 / bn2; break; case OP_MOD: // divisor must not be 0 - if (bn2 == script_zero()) return SCRIPT_ERR_MOD_BY_ZERO; + if (bn2 == script_zero ()) return SCRIPT_ERR_MOD_BY_ZERO; bn = bn1 % bn2; break; case OP_BOOLAND: - bn = (bn1 != script_zero() && bn2 != script_zero()); + bn = (bn1 != script_zero () && bn2 != script_zero()); break; case OP_BOOLOR: - bn = (bn1 != script_zero() || bn2 != script_zero()); + bn = (bn1 != script_zero () || bn2 != script_zero()); break; case OP_NUMEQUAL: bn = (bn1 == bn2); @@ -741,48 +747,48 @@ namespace Gigamonkey::Bitcoin::interpreter { bn = (bn1 > bn2 ? bn1 : bn2); break; default: - assert(!"invalid opcode"); + assert (!"invalid opcode"); break; } - Stack.pop_back(); - Stack.pop_back(); - Stack.push_back(bn.getvch()); + Stack.pop_back (); + Stack.pop_back (); + Stack.push_back (bn.getvch ()); if (Op == OP_NUMEQUALVERIFY) { - if (CastToBool(Stack.stacktop(-1).GetElement())) Stack.pop_back(); + if (CastToBool (Stack.stacktop (-1).GetElement ())) Stack.pop_back (); else return SCRIPT_ERR_NUMEQUALVERIFY; } } break; case OP_WITHIN: { // (x min max -- out) - if (Stack.size() < 3) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 3) return SCRIPT_ERR_INVALID_STACK_OPERATION; - const auto& top_3{Stack.stacktop(-3).GetElement()}; - const CScriptNum bn1{ + const auto& top_3 {Stack.stacktop (-3).GetElement ()}; + const CScriptNum bn1 { top_3, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; - const auto& top_2{Stack.stacktop(-2).GetElement()}; - const CScriptNum bn2{ + const auto& top_2 {Stack.stacktop (-2).GetElement ()}; + const CScriptNum bn2 { top_2, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; - const auto& top_1{Stack.stacktop(-1).GetElement()}; - const CScriptNum bn3{ + const auto& top_1 {Stack.stacktop (-1).GetElement ()}; + const CScriptNum bn3 { top_1, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; const bool fValue = (bn2 <= bn1 && bn1 < bn3); - Stack.pop_back(); - Stack.pop_back(); - Stack.pop_back(); + Stack.pop_back (); + Stack.pop_back (); + Stack.pop_back (); - Stack.push_back(fValue ? script_true() : script_false()); + Stack.push_back (fValue ? script_true () : script_false ()); } break; // // Crypto @@ -793,37 +799,38 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_HASH160: case OP_HASH256: { // (in -- hash) - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) + return SCRIPT_ERR_INVALID_STACK_OPERATION; - LimitedVector &vch = Stack.stacktop(-1); - valtype vchHash((Op == OP_RIPEMD160 || + LimitedVector &vch = Stack.stacktop (-1); + valtype vchHash ((Op == OP_RIPEMD160 || Op == OP_SHA1 || Op == OP_HASH160) ? 20 : 32); if (Op == OP_RIPEMD160) { - CRIPEMD160() - .Write(vch.GetElement().data(), vch.size()) - .Finalize(vchHash.data()); + CRIPEMD160 () + .Write (vch.GetElement ().data (), vch.size ()) + .Finalize (vchHash.data ()); } else if (Op == OP_SHA1) { - CSHA1() - .Write(vch.GetElement().data(), vch.size()) - .Finalize(vchHash.data()); + CSHA1 () + .Write (vch.GetElement ().data (), vch.size ()) + .Finalize (vchHash.data ()); } else if (Op == OP_SHA256) { - CSHA256() - .Write(vch.GetElement().data(), vch.size()) - .Finalize(vchHash.data()); + CSHA256 () + .Write (vch.GetElement ().data (), vch.size ()) + .Finalize (vchHash.data ()); } else if (Op == OP_HASH160) { - CHash160() - .Write(vch.GetElement().data(), vch.size()) - .Finalize(vchHash.data()); + CHash160 () + .Write (vch.GetElement ().data (), vch.size ()) + .Finalize(vchHash.data ()); } else if (Op == OP_HASH256) { - CHash256() - .Write(vch.GetElement().data(), vch.size()) - .Finalize(vchHash.data()); + CHash256 () + .Write (vch.GetElement ().data (), vch.size ()) + .Finalize (vchHash.data ()); } - Stack.pop_back(); - Stack.push_back(vchHash); + Stack.pop_back (); + Stack.push_back (vchHash); } break; // we take care of this elsewhere. @@ -831,24 +838,25 @@ namespace Gigamonkey::Bitcoin::interpreter { case OP_CHECKSIG: case OP_CHECKSIGVERIFY: { - if (Stack.size() < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 2) return SCRIPT_ERR_INVALID_STACK_OPERATION; - const element &sig = Stack.stacktop(-2).GetElement(); - const element &pub = Stack.stacktop(-1).GetElement(); + const element &sig = Stack.stacktop (-2).GetElement (); + const element &pub = Stack.stacktop (-1).GetElement (); - result r = bool(Document) ? - result{verify_signature(sig, pub, Document->add_script_code(cleanup_script_code(Counter.script_code(), sig)), Flags)} : - result{true}; + result r = bool (Document) ? + result {verify_signature + (sig, pub, Document->add_script_code (cleanup_script_code (Counter.script_code (), sig)), Flags)} : + result {true}; if (r.Error) return r.Error; - Stack.pop_back(); - Stack.pop_back(); - Stack.push_back(script_bool(r.Success)); + Stack.pop_back (); + Stack.pop_back (); + Stack.push_back (script_bool (r.Success)); if (Op == OP_CHECKSIGVERIFY) { if (r.Success) { - Stack.pop_back(); + Stack.pop_back (); return true; } else return SCRIPT_ERR_CHECKSIGVERIFY; } @@ -862,20 +870,20 @@ namespace Gigamonkey::Bitcoin::interpreter { // num_of_pubkeys -- bool) uint64_t i = 1; - if (Stack.size() < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; // initialize to max size of CScriptNum::MAXIMUM_ELEMENT_SIZE (4 bytes) // because only 4 byte integers are supported by OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY int64_t nKeysCountSigned = - CScriptNum(Stack.stacktop(-i).GetElement(), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE).getint(); + CScriptNum (Stack.stacktop (-i).GetElement (), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE).getint (); if (nKeysCountSigned < 0) return SCRIPT_ERR_PUBKEY_COUNT; - uint64_t nKeysCount = static_cast(nKeysCountSigned); - if (nKeysCount > Config.GetMaxPubKeysPerMultiSig(utxo_after_genesis, Consensus)) + uint64_t nKeysCount = static_cast (nKeysCountSigned); + if (nKeysCount > Config.GetMaxPubKeysPerMultiSig (utxo_after_genesis, Consensus)) return SCRIPT_ERR_PUBKEY_COUNT; OpCount += nKeysCount; - if (!IsValidMaxOpsPerScript(OpCount, Config, utxo_after_genesis, Consensus)) + if (!IsValidMaxOpsPerScript (OpCount, Config, utxo_after_genesis, Consensus)) return SCRIPT_ERR_OP_COUNT; uint64_t ikey = ++i; @@ -885,36 +893,36 @@ namespace Gigamonkey::Bitcoin::interpreter { // operation fails. uint64_t ikey2 = nKeysCount + 2; i += nKeysCount; - if (Stack.size() < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; int64_t nSigsCountSigned = - CScriptNum(Stack.stacktop(-i).GetElement(), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE).getint(); + CScriptNum (Stack.stacktop (-i).GetElement (), fRequireMinimal, CScriptNum::MAXIMUM_ELEMENT_SIZE).getint (); if (nSigsCountSigned < 0) return SCRIPT_ERR_SIG_COUNT; - uint64_t nSigsCount = static_cast(nSigsCountSigned); + uint64_t nSigsCount = static_cast (nSigsCountSigned); if (nSigsCount > nKeysCount) return SCRIPT_ERR_SIG_COUNT; uint64_t isig = ++i; i += nSigsCount; - if (Stack.size() < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < i) return SCRIPT_ERR_INVALID_STACK_OPERATION; sighash::document *doc = nullptr; - if (bool(Document)) { - bytes script_code = Counter.script_code(); + if (bool (Document)) { + bytes script_code = Counter.script_code (); // Remove signature for pre-fork scripts - for (auto it = Stack.begin() + 1; it != Stack.begin() + 1 + nSigsCount; it++) - script_code = cleanup_script_code(script_code, it->GetElement()); + for (auto it = Stack.begin () + 1; it != Stack.begin () + 1 + nSigsCount; it++) + script_code = cleanup_script_code (script_code, it->GetElement ()); - doc = add_script_code(*Document, script_code); + doc = add_script_code (*Document, script_code); } bool fSuccess = true; while (fSuccess && nSigsCount > 0) { - const element &sig = Stack.stacktop(-isig).GetElement(); - const element &pub = Stack.stacktop(-ikey).GetElement(); + const element &sig = Stack.stacktop (-isig).GetElement (); + const element &pub = Stack.stacktop (-ikey).GetElement (); // Note how this makes the exact order of // pubkey/signature evaluation distinguishable by @@ -922,7 +930,7 @@ namespace Gigamonkey::Bitcoin::interpreter { // See the script_(in)valid tests for details. // Check signature - result r = (doc == nullptr) ? result{true} : result{verify_signature(sig, pub, *doc, Flags)}; + result r = (doc == nullptr) ? result {true} : result {verify_signature (sig, pub, *doc, Flags)}; if (r.Error) return r.Error; @@ -948,13 +956,13 @@ namespace Gigamonkey::Bitcoin::interpreter { // If the operation failed, we require that all // signatures must be empty vector if (!fSuccess && (Flags & SCRIPT_VERIFY_NULLFAIL) && - !ikey2 && Stack.stacktop(-1).size()) { + !ikey2 && Stack.stacktop (-1).size ()) { return SCRIPT_ERR_SIG_NULLFAIL; } if (ikey2 > 0) ikey2--; - Stack.pop_back(); + Stack.pop_back (); } // A bug causes CHECKMULTISIG to consume one extra @@ -963,18 +971,18 @@ namespace Gigamonkey::Bitcoin::interpreter { // Unfortunately this is a potential source of // mutability, so optionally verify it is exactly equal // to zero prior to removing it from the stack. - if (Stack.size() < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; + if (Stack.size () < 1) return SCRIPT_ERR_INVALID_STACK_OPERATION; if ((Flags & SCRIPT_VERIFY_NULLDUMMY) && - Stack.stacktop(-1).size()) return SCRIPT_ERR_SIG_NULLDUMMY; + Stack.stacktop (-1).size ()) return SCRIPT_ERR_SIG_NULLDUMMY; - Stack.pop_back(); + Stack.pop_back (); - Stack.push_back(script_bool(fSuccess)); + Stack.push_back (script_bool (fSuccess)); if (Op == OP_CHECKMULTISIGVERIFY) { if (fSuccess) { - Stack.pop_back(); + Stack.pop_back (); return true; } else return SCRIPT_ERR_CHECKMULTISIGVERIFY; } @@ -985,9 +993,9 @@ namespace Gigamonkey::Bitcoin::interpreter { ScriptError err; long count; - std::optional result = EvalScript( + maybe result = EvalScript ( Config, Consensus, - Stack, CScript(Counter.Next.begin(), Counter.Next.end()), Flags, + Stack, CScript (Counter.Next.begin (), Counter.Next.end ()), Flags, AltStack, count, Exec, Else, &err); @@ -997,10 +1005,10 @@ namespace Gigamonkey::Bitcoin::interpreter { } // Size limits - if (!utxo_after_genesis && (Stack.size() + AltStack.size() > MAX_STACK_ELEMENTS_BEFORE_GENESIS)) + if (!utxo_after_genesis && (Stack.size () + AltStack.size () > MAX_STACK_ELEMENTS_BEFORE_GENESIS)) return SCRIPT_ERR_STACK_SIZE; - Counter = Counter.next(); + Counter = Counter.next (); return SCRIPT_ERR_OK; diff --git a/src/gigamonkey/script/typed_data_bip_276.cpp b/src/gigamonkey/script/typed_data_bip_276.cpp index 51f4c5b9..86721eb4 100644 --- a/src/gigamonkey/script/typed_data_bip_276.cpp +++ b/src/gigamonkey/script/typed_data_bip_276.cpp @@ -18,7 +18,7 @@ namespace Gigamonkey { ss << ':' << encoding::hex::write (data, hex_case::lower); - auto checksum = Bitcoin::checksum (bytes::from_string(ss.str())); + auto checksum = Bitcoin::checksum (bytes::from_string (ss.str ())); ss << encoding::hex::write (checksum, hex_case::lower); @@ -31,7 +31,7 @@ namespace Gigamonkey { if (!ctre::match (z)) return {}; - bytes last_4_bytes = *encoding::hex::read (z.substr (z.size() - 8)); + bytes last_4_bytes = *encoding::hex::read (z.substr (z.size () - 8)); uint32_little expected_checksum; std::copy (last_4_bytes.begin (), last_4_bytes.end (), expected_checksum.begin ()); diff --git a/src/gigamonkey/stratum/extensions.cpp b/src/gigamonkey/stratum/extensions.cpp index c7caf8b3..a780d2b8 100644 --- a/src/gigamonkey/stratum/extensions.cpp +++ b/src/gigamonkey/stratum/extensions.cpp @@ -5,61 +5,61 @@ namespace Gigamonkey::Stratum::extensions { - std::optional read_version_mask(const string &str) { - if (str.size() != 8) return {}; - ptr b = encoding::hex::read(str); - if (b != nullptr) return {}; + maybe read_version_mask (const string &str) { + if (str.size () != 8) return {}; + maybe b = encoding::hex::read (str); + if (bool (b)) return {}; int32_big n; - std::copy(b->begin(), b->end(), n.begin()); - return {int32_little(n)}; + std::copy (b->begin (), b->end (), n.begin ()); + return {int32_little (n)}; } - std::optional> configuration::read(const request &p) { - auto m = p.contains("mask"); - auto mbc = p.contains("min-bit-count"); - if (!bool(m) || !bool(mbc) || !mbc->is_number_unsigned()) return {}; - auto mask = read_version_mask(*m); + maybe> configuration::read (const request &p) { + auto m = p.contains ("mask"); + auto mbc = p.contains ("min-bit-count"); + if (!bool(m) || !bool (mbc) || !mbc->is_number_unsigned ()) return {}; + auto mask = read_version_mask (*m); if (!mask) return {}; - return {{*mask, byte(*mbc)}}; + return {{*mask, byte (*mbc)}}; } - std::optional> configured::read(const result_params &p) { - auto x = p.contains("mask"); + maybe> configured::read (const result_params &p) { + auto x = p.contains ("mask"); if (!x) return {}; - auto mask = read_version_mask(*x); + auto mask = read_version_mask (*x); if (!mask) return {}; - return {configured{*mask}}; + return {configured {*mask}}; } - std::optional> configuration::read(const result_params &p) { - auto x = p.contains("value"); + maybe> configuration::read (const result_params &p) { + auto x = p.contains ("value"); if (!x) return {}; - return {configuration{*x}}; + return {configuration {*x}}; } - std::optional> configuration::read(const request &p) { - auto a = p.contains("connection-url"); - auto b = p.contains("hw-version"); - auto c = p.contains("sw-version"); - auto d = p.contains("sw-id"); + maybe> configuration::read (const request &p) { + auto a = p.contains ("connection-url"); + auto b = p.contains ("hw-version"); + auto c = p.contains ("sw-version"); + auto d = p.contains ("sw-id"); - if (!bool(a) || !bool(b) || !bool(c) || !bool(d)) return {}; + if (!bool (a) || !bool (b) || !bool (c) || !bool (d)) return {}; - return {configuration{*a, *b, *c, *d}}; + return {configuration {*a, *b, *c, *d}}; } - optional parameters::make( + optional parameters::make ( version_mask x, const configuration &r) { version_mask new_mask = x & r.Mask; int bit_count = 0; for (int i = 0; i < 32; i++) if (((new_mask >> i) & 1) == 1) bit_count++; - return bit_count < r.MinBitCount ? optional{} : optional{new_mask}; + return bit_count < r.MinBitCount ? optional {} : optional {new_mask}; } - std::string extension_to_string(extension m) { + std::string extension_to_string (extension m) { switch (m) { case (version_rolling) : return "version_rolling"; case (minimum_difficulty) : return "minimum_difficulty"; diff --git a/src/gigamonkey/stratum/mining.cpp b/src/gigamonkey/stratum/mining.cpp index bca75657..d0e02e65 100644 --- a/src/gigamonkey/stratum/mining.cpp +++ b/src/gigamonkey/stratum/mining.cpp @@ -7,188 +7,188 @@ namespace Gigamonkey::Stratum::mining { namespace { - bool read_job_id(const JSON& j, job_id& x) { - if (!j.is_string()) return false; - x = string(j); + bool read_job_id (const JSON &j, job_id &x) { + if (!j.is_string ()) return false; + x = string (j); return true; } - encoding::hex::fixed<32> inline write(const uint256& x) { + encoding::hex::fixed<32> inline write (const uint256 &x) { uint256 z = x; - for (int i = 0; i < 32; i+=4) std::reverse(z.begin() + i, z.begin() + i + 3); - return encoding::hex::write(z, hex_case::lower); + for (int i = 0; i < 32; i+=4) std::reverse (z.begin () + i, z.begin () + i + 3); + return encoding::hex::write (z, hex_case::lower); } - bool read(const JSON& j, uint256& x) { - if (!j.is_string()) return false; - string str(j); - if (str.size() != 64) return false; - ptr b = encoding::hex::read(str); - if (b == nullptr) return false; - for (int i = 0; i < 8; i++) for (int j = 0; j < 4; j++) x[4 * i + j] = *(b->begin() + 4 * (i + 1) - j - 1); + bool read(const JSON &j, uint256 &x) { + if (!j.is_string ()) return false; + string str (j); + if (str.size () != 64) return false; + maybe b = encoding::hex::read (str); + if (!bool (b)) return false; + for (int i = 0; i < 8; i++) for (int j = 0; j < 4; j++) x[4 * i + j] = *(b->begin () + 4 * (i + 1) - j - 1); return true; } - encoding::hex::string inline write(const bytes& b) { - return encoding::hex::write(b, hex_case::lower); + encoding::hex::string inline write (const bytes &b) { + return encoding::hex::write (b, hex_case::lower); } - bool read(const JSON& j, bytes& x) { - if (!j.is_string()) return false; - string str(j); - ptr b = encoding::hex::read(str); - if (b == nullptr) return false; + bool read (const JSON &j, bytes &x) { + if (!j.is_string ()) return false; + string str (j); + maybe b = encoding::hex::read (str); + if (!bool (b)) return false; x = *b; return true; } - parameters write(const Merkle::digests& x) { + parameters write (const Merkle::digests& x) { parameters p; Merkle::digests n; - p.resize(x.size()); - for (auto it = p.rbegin(); it != p.rend(); ++it) { - *it = write(n.first().Value); - n = n.rest(); + p.resize (x.size ()); + for (auto it = p.rbegin (); it != p.rend (); ++it) { + *it = write (n.first ().Value); + n = n.rest (); } return p; } - bool inline read(const JSON& j, Merkle::digests& x) { - if (!j.is_array()) return false; + bool inline read (const JSON &j, Merkle::digests &x) { + if (!j.is_array ()) return false; x = {}; for (JSON d : j) { uint256 o; - if (!read(d, o)) return false; - x = x << digest256{o}; + if (!read (d, o)) return false; + x = x << digest256 {o}; } return true; } - encoding::hex::fixed<4> inline write(const int32_little& x) { - return encoding::hex::write(x, hex_case::lower); + encoding::hex::fixed<4> inline write (const int32_little& x) { + return encoding::hex::write (x, hex_case::lower); } - bool read(const JSON& j, int32_little& x) { - if (!j.is_string()) return false; - string str(j); - if (str.size() != 8) return false; - ptr b = encoding::hex::read(str); - if (b == nullptr) return false; + bool read (const JSON &j, int32_little &x) { + if (!j.is_string ()) return false; + string str (j); + if (str.size () != 8) return false; + maybe b = encoding::hex::read (str); + if (!bool (b)) return false; int32_big n; - std::copy(b->begin(), b->end(), n.begin()); - x = int32_little(n); + std::copy (b->begin (), b->end (), n.begin ()); + x = int32_little (n); return true; } - encoding::hex::fixed<4> inline write(const work::compact& x) { + encoding::hex::fixed<4> inline write (const work::compact &x) { return encoding::hex::write(uint32_big{static_cast(x)}, hex_case::lower); } - bool read(const JSON& j, work::compact& x) { + bool read (const JSON &j, work::compact &x) { if (!j.is_string()) return false; string str(j); if (str.size() != 8) return false; - ptr b = encoding::hex::read(str); - if (b == nullptr) return false; + maybe b = encoding::hex::read (str); + if (!bool (b)) return false; uint32_big n; - std::copy(b->begin(), b->end(), n.begin()); - x = work::compact(uint32_little(n)); + std::copy (b->begin (), b->end (), n.begin ()); + x = work::compact (uint32_little (n)); return true; } - encoding::hex::fixed<4> inline write(const Bitcoin::timestamp& x) { - return encoding::hex::write(uint32_big{x.Value}, hex_case::lower); + encoding::hex::fixed<4> inline write (const Bitcoin::timestamp& x) { + return encoding::hex::write (uint32_big {x.Value}, hex_case::lower); } - bool read(const JSON& j, Bitcoin::timestamp& x) { - if (!j.is_string()) return false; - string str(j); - if (str.size() != 8) return false; - ptr b = encoding::hex::read(str); - if (b == nullptr) return false; + bool read(const JSON &j, Bitcoin::timestamp &x) { + if (!j.is_string ()) return false; + string str (j); + if (str.size () != 8) return false; + maybe b = encoding::hex::read (str); + if (!bool (b)) return false; uint32_big n; - std::copy(b->begin(), b->end(), n.begin()); - x = Bitcoin::timestamp(uint32_little(n)); + std::copy (b->begin (), b->end (), n.begin ()); + x = Bitcoin::timestamp (uint32_little (n)); return true; } - - encoding::hex::fixed<8> inline write(const uint64_big& x) { - return encoding::hex::write(x, hex_case::lower); + + encoding::hex::fixed<8> inline write (const uint64_big &x) { + return encoding::hex::write (x, hex_case::lower); } - bool inline read(const JSON& j, uint64_big& x) { - if (!j.is_string()) return false; - string str(j); - if (str.size() != 16) return false; - ptr b = encoding::hex::read(str); - std::copy(b->begin(), b->end(), x.begin()); + bool inline read (const JSON &j, uint64_big &x) { + if (!j.is_string ()) return false; + string str (j); + if (str.size () != 16) return false; + maybe b = encoding::hex::read (str); + std::copy (b->begin (), b->end (), x.begin ()); return true; } - encoding::hex::fixed<4> inline write(const nonce& x) { - return encoding::hex::write(uint32_big{x}, hex_case::lower); + encoding::hex::fixed<4> inline write (const nonce &x) { + return encoding::hex::write (uint32_big {x}, hex_case::lower); } - bool read(const JSON& j, nonce& x) { - if (!j.is_string()) return false; - string str(j); - if (str.size() != 8) return false; - ptr b = encoding::hex::read(str); + bool read (const JSON &j, nonce &x) { + if (!j.is_string ()) return false; + string str (j); + if (str.size () != 8) return false; + maybe b = encoding::hex::read (str); uint32_big n; - std::copy(b->begin(), b->end(), n.begin()); - x = uint32_little(n); + std::copy (b->begin (), b->end (), n.begin ()); + x = uint32_little (n); return true; } } - parameters notify::serialize(const parameters& p) { - return Stratum::parameters{p.JobID, write(p.Digest), write(p.GenerationTx1), write(p.GenerationTx2), - write(p.Path), write(p.Version), write(p.Target), write(p.Now), p.Clean}; + parameters notify::serialize (const parameters &p) { + return Stratum::parameters {p.JobID, write (p.Digest), write (p.GenerationTx1), write (p.GenerationTx2), + write (p.Path), write (p.Version), write (p.Target), write (p.Now), p.Clean}; } - notify::parameters notify::deserialize(const Stratum::parameters& n) { + notify::parameters notify::deserialize (const Stratum::parameters &n) { parameters p; - if (n.size() != 9 || !n[8].is_boolean() || - !read_job_id(n[0], p.JobID) || - !read(n[1], p.Digest) || - !read(n[2], p.GenerationTx1) || - !read(n[3], p.GenerationTx2) || - !read(n[4], p.Path) || - !read(n[5], p.Version) || - !read(n[6], p.Target) || - !read(n[7], p.Now)) return {}; + if (n.size() != 9 || !n[8].is_boolean () || + !read_job_id (n[0], p.JobID) || + !read (n[1], p.Digest) || + !read (n[2], p.GenerationTx1) || + !read (n[3], p.GenerationTx2) || + !read (n[4], p.Path) || + !read (n[5], p.Version) || + !read (n[6], p.Target) || + !read (n[7], p.Now)) return {}; - p.Clean = bool(n[8]); + p.Clean = bool (n[8]); return p; } - parameters submit_request::serialize(const share& Share) { - if (Share.Share.Bits) return parameters{Share.Name, Share.JobID, write(Share.Share.ExtraNonce2), - write(Share.Share.Timestamp), write(Share.Share.Nonce), write(*Share.Share.Bits)}; + parameters submit_request::serialize (const share &Share) { + if (Share.Share.Bits) return parameters {Share.Name, Share.JobID, write(Share.Share.ExtraNonce2), + write (Share.Share.Timestamp), write (Share.Share.Nonce), write (*Share.Share.Bits)}; - return parameters{Share.Name, Share.JobID, write(Share.Share.ExtraNonce2), - write(Share.Share.Timestamp), write(Share.Share.Nonce)}; + return parameters {Share.Name, Share.JobID, write(Share.Share.ExtraNonce2), + write (Share.Share.Timestamp), write (Share.Share.Nonce)}; } - share submit_request::deserialize(const parameters& n) { - share Share{}; + share submit_request::deserialize (const parameters &n) { + share Share {}; - if (!(n.size() == 5 || n.size() == 6) || !n[0].is_string() || - !read_job_id(n[1], Share.JobID) || - !read(n[2], Share.Share.ExtraNonce2) || - !read(n[3], Share.Share.Timestamp) || - !read(n[4], Share.Share.Nonce)) return {}; + if (!(n.size () == 5 || n.size () == 6) || !n[0].is_string () || + !read_job_id (n[1], Share.JobID) || + !read (n[2], Share.Share.ExtraNonce2) || + !read (n[3], Share.Share.Timestamp) || + !read (n[4], Share.Share.Nonce)) return {}; - if (n.size() == 6) { + if (n.size () == 6) { Share.Share.Bits = 0; - if (!read(n[5], *Share.Share.Bits)) return {}; + if (!read (n[5], *Share.Share.Bits)) return {}; } - Share.Name = string(n[0]); + Share.Name = string (n[0]); return Share; } diff --git a/src/gigamonkey/stratum/mining_authorize.cpp b/src/gigamonkey/stratum/mining_authorize.cpp index eac09a47..dbbb479f 100644 --- a/src/gigamonkey/stratum/mining_authorize.cpp +++ b/src/gigamonkey/stratum/mining_authorize.cpp @@ -4,34 +4,34 @@ #include namespace Gigamonkey::Stratum::mining { - Stratum::parameters authorize_request::serialize(const parameters& p) { + Stratum::parameters authorize_request::serialize (const parameters &p) { if (p.Password) return {p.Username, *p.Password}; return {p.Username}; } - authorize_request::parameters authorize_request::deserialize(const Stratum::parameters& p) { - if (p.size() < 1 || p.size() > 2 || !p[0].is_string()) return parameters{}; - if (p.size() == 1) return parameters{string(p[0])}; - return parameters{string(p[0]), string(p[1])}; + authorize_request::parameters authorize_request::deserialize(const Stratum::parameters &p) { + if (p.size () < 1 || p.size () > 2 || !p[0].is_string ()) return parameters {}; + if (p.size () == 1) return parameters {string (p[0])}; + return parameters {string (p[0]), string (p[1])}; } - bool authorize_request::valid(const JSON& j) { - auto p = request::params(j); - if (p.size() < 1 || p.size() > 2 || !p[0].is_string()) return false; - if (p.size() == 2 && !p[1].is_string()) return false; + bool authorize_request::valid (const JSON &j) { + auto p = request::params (j); + if (p.size () < 1 || p.size () > 2 || !p[0].is_string ()) return false; + if (p.size () == 2 && !p[1].is_string ()) return false; return true; } - string username(const JSON& j) { - auto p = request::params(j); - if (p.size() == 0) return ""; - return string(p[1]); + string username (const JSON &j) { + auto p = request::params (j); + if (p.size () == 0) return ""; + return string (p[1]); } - std::optional password(const JSON& j) { - auto p = request::params(j); - if (p.size() < 2) return {}; - return {string(p[1])}; + maybe password (const JSON &j) { + auto p = request::params (j); + if (p.size () < 2) return {}; + return {string (p[1])}; } } diff --git a/src/gigamonkey/stratum/stratum.cpp b/src/gigamonkey/stratum/stratum.cpp index 41f611e3..f80673af 100644 --- a/src/gigamonkey/stratum/stratum.cpp +++ b/src/gigamonkey/stratum/stratum.cpp @@ -5,64 +5,64 @@ namespace Gigamonkey::Stratum { - message_id request::id(const JSON& j) { - if (!j.contains("id")) return message_id{}; + message_id request::id (const JSON &j) { + if (!j.contains ("id")) return message_id {}; auto q = j["id"]; - if (message_id::valid(q)) return message_id(q); - return message_id{}; + if (message_id::valid (q)) return message_id (q); + return message_id {}; } - Stratum::method request::method(const JSON& j) { - if (!j.contains("method")) return unset; + Stratum::method request::method (const JSON &j) { + if (!j.contains ("method")) return unset; auto q = j["method"]; - if (q.is_string()) return method_from_string(string(q)); + if (q.is_string ()) return method_from_string (string (q)); return unset; } - parameters request::params(const JSON& j) { - if(!j.contains("params")) return {}; + parameters request::params (const JSON &j) { + if (!j.contains ("params")) return {}; auto q = j["params"]; - if(q.is_array()) return q; + if (q.is_array ()) return q; return {}; } - Stratum::method notification::method(const JSON& j) { - if (!j.contains("method")) return unset; + Stratum::method notification::method (const JSON &j) { + if (!j.contains ("method")) return unset; auto q = j["method"]; - if (q.is_string()) return method_from_string(string(q)); + if (q.is_string ()) return method_from_string (string (q)); return unset; } - parameters notification::params(const JSON& j) { - if(!j.contains("params")) return {}; + parameters notification::params (const JSON &j) { + if (!j.contains ("params")) return {}; auto q = j["params"]; - if(q.is_array()) return q; + if (q.is_array ()) return q; return {}; } - bool response::valid(const JSON& j) { - if (!(j.contains("id") && j.contains("result") && j.contains("error"))) return false; + bool response::valid (const JSON &j) { + if (!(j.contains ("id") && j.contains ("result") && j.contains ("error"))) return false; auto err = j["error"]; - return message_id::valid(j["id"]) && (err.is_null() || Stratum::error::valid(err)); + return message_id::valid (j["id"]) && (err.is_null () || Stratum::error::valid (err)); } - message_id response::id(const JSON& j) { - if (!j.contains("id")) return message_id{}; + message_id response::id (const JSON &j) { + if (!j.contains ("id")) return message_id {}; auto q = j["id"]; - if (message_id::valid(q)) return message_id(q); - return message_id{}; + if (message_id::valid (q)) return message_id (q); + return message_id {}; } - JSON response::result(const JSON& j) { - if (!j.contains("result")) return nullptr; + JSON response::result (const JSON &j) { + if (!j.contains ("result")) return nullptr; return j["result"]; } - std::optional response::error(const JSON& j) { - if (!valid(j)) return {}; + maybe response::error (const JSON &j) { + if (!valid (j)) return {}; auto err = j["error"]; - if (err.is_null()) return {}; - return {Stratum::error(j["error"])}; + if (err.is_null ()) return {}; + return {Stratum::error (j["error"])}; } } diff --git a/src/gigamonkey/wif.cpp b/src/gigamonkey/wif.cpp index 5cba3cbf..d6c98f23 100644 --- a/src/gigamonkey/wif.cpp +++ b/src/gigamonkey/wif.cpp @@ -8,6 +8,7 @@ namespace Gigamonkey::Bitcoin { secret WIF::decode (string_view s) { + base58::check b58 (s); if (!b58.valid ()) return Bitcoin::secret {}; Bitcoin::secret w {}; @@ -19,8 +20,8 @@ namespace Gigamonkey::Bitcoin { } else return {}; bytes_reader r (b58.data (), b58.data () + b58.size ()); - r >> (byte&) (w.Prefix); - r.read(w.Secret.Value.data (), secp256k1::secret::Size); + r >> (byte &) (w.Prefix); + r.read (w.Secret.Value.data (), secp256k1::secret::Size); if (w.Compressed) { byte suffix; @@ -29,17 +30,20 @@ namespace Gigamonkey::Bitcoin { } return w; + } WIF WIF::encode (byte prefix, const secp256k1::secret& s, bool compressed) { + bytes data (compressed ? CompressedSize - 1: UncompressedSize - 1); bytes_writer w (data.begin (), data.end ()); w << bytes_view (s.Value); if (compressed) w << CompressedSuffix; WIF wif; - static_cast (wif) = base58::check {prefix, data}.encode (); + static_cast (wif) = base58::check {prefix, data}.encode (); return wif; + } } diff --git a/src/sv/script/interpreter.cpp b/src/sv/script/interpreter.cpp index 1c8ac44b..d606712a 100644 --- a/src/sv/script/interpreter.cpp +++ b/src/sv/script/interpreter.cpp @@ -455,12 +455,12 @@ std::optional EvalScript( valtype n1(data.begin(), data.begin() + position); valtype n2(data.begin() + position, data.end()); - stack.pop_back(); - stack.pop_back(); + stack.pop_back (); + stack.pop_back (); // Replace existing stack values by the new values. - stack.push_back(n1); - stack.push_back(n2); + stack.push_back (n1); + stack.push_back (n2); } break; // @@ -468,17 +468,15 @@ std::optional EvalScript( // case OP_NUM2BIN: { // (in size -- out) - if (stack.size() < 2) { - return set_error( - serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - } + if (stack.size() < 2) + return set_error (serror, SCRIPT_ERR_INVALID_STACK_OPERATION); - const auto& arg_1 = stack.stacktop(-1).GetElement(); + const auto& arg_1 = stack.stacktop (-1).GetElement (); const CScriptNum n{ arg_1, fRequireMinimal, maxScriptNumLength, utxo_after_genesis}; - if(n < 0 || n > std::numeric_limits::max()) + if(n < 0 || n > std::numeric_limits::max ()) return set_error(serror, SCRIPT_ERR_PUSH_SIZE); const auto size{n.to_size_t_limited()}; @@ -547,16 +545,16 @@ std::optional EvalScript( return set_success(serror); } -std::optional EvalScript( - const CScriptConfig& config, +std::optional EvalScript ( + const CScriptConfig &config, bool consensus, - LimitedStack& stack, - const CScript& script, + LimitedStack &stack, + const CScript &script, uint32_t flags, - ScriptError* serror) + ScriptError *serror) { - LimitedStack altstack {stack.makeChildStack()}; - long ipc{0}; + LimitedStack altstack {stack.makeChildStack ()}; + long ipc {0}; std::vector vfExec, vfElse; - return EvalScript(config, consensus, stack, script, flags, altstack, ipc, vfExec, vfElse, serror); + return EvalScript (config, consensus, stack, script, flags, altstack, ipc, vfExec, vfElse, serror); } diff --git a/test/testBoost.cpp b/test/testBoost.cpp index 8e6d731f..3bb121d9 100644 --- a/test/testBoost.cpp +++ b/test/testBoost.cpp @@ -142,7 +142,7 @@ namespace Gigamonkey::Boost { return test_case (o, n1, extra_nonce_2, start, s); } - static test_case build(Boost::type type, + static test_case build (Boost::type type, const uint256& content, work::compact target, const bytes& tag, @@ -172,7 +172,7 @@ namespace Gigamonkey::Boost { bytes ExtraNonce2; Bitcoin::timestamp Start; Bitcoin::secret Key; - std::optional Bits; + maybe Bits; test_case ( output_script o, @@ -180,7 +180,7 @@ namespace Gigamonkey::Boost { Stratum::session_id n1, uint64_big n2, uint64 key) : - test_case (build(o, start, n1, n2, key)) {} + test_case (build (o, start, n1, n2, key)) {} test_case (Boost::type type, uint256 content, diff --git a/test/testFormat.cpp b/test/testFormat.cpp index 00167982..73610dd8 100644 --- a/test/testFormat.cpp +++ b/test/testFormat.cpp @@ -10,14 +10,14 @@ namespace Gigamonkey::Bitcoin { - TEST(FormatTest, TestWIF) { + TEST (FormatTest, TestWIF) { std::string wiki_wif = "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"; - EXPECT_TRUE(secret {wiki_wif}.encode () == wiki_wif); + EXPECT_TRUE (secret {wiki_wif}.encode () == wiki_wif); } - TEST(FormatTest, TestAddress) { + TEST (FormatTest, TestAddress) { std::string addr = "127NVqnjf8gB9BFAW2dnQeM6wqmy1gbGtv"; - EXPECT_TRUE(address {addr}.decode ().encode () == addr); + EXPECT_TRUE (address {addr}.decode ().encode () == addr); } struct test_data { @@ -113,7 +113,7 @@ namespace Gigamonkey::Bitcoin { "045A5CA5E685803CB8CD54198F3CFD71187F85F940EAECCE0D5D6551911306738C" "636205F2C171613EBDA6A345D1078D359B985C829B6E4715BC93BBEDD4E7740B", "1DXj3zwApeKaSCyEZD5Pjkzai8p5XmwxzY"); - + auto negative_tests = list {} << test_data ("IamJUNK", "IamJUNK", @@ -133,7 +133,7 @@ namespace Gigamonkey::Bitcoin { EXPECT_TRUE (x.write () == t); return b; }, positive_tests); - + list failure = data::for_each ([] (test_data t) -> bool { bool b; EXPECT_FALSE (b = test_case {t}.valid ()); diff --git a/test/testPush.cpp b/test/testPush.cpp index 3c66a014..49b49a8a 100644 --- a/test/testPush.cpp +++ b/test/testPush.cpp @@ -10,79 +10,79 @@ namespace Gigamonkey::Bitcoin::interpreter { bool Expected; string Bytes; - bool valid() const { - ptr b = encoding::hex::read(Bytes); - if (b == nullptr) return false; - program p = decompile(*b); - if (p.size() != 1) return false; - instruction i = p.first(); - if (!i.valid()) return false; - return is_minimal(i) == Expected; + bool valid () const { + maybe b = encoding::hex::read (Bytes); + if (!bool (b)) return false; + program p = decompile (*b); + if (p.size () != 1) return false; + instruction i = p.first (); + if (!i.valid ()) return false; + return is_minimal (i) == Expected; } }; // can result in stack smashing - TEST(PushTest, TestPushMinimal) { - for(const auto& x : list{ - test_case{true, "00"}, - test_case{true, "51"}, - test_case{true, "0100"}, - test_case{false, "0101"}, - test_case{true, "52"}, - test_case{false, "0102"}, - test_case{true, "60"}, - test_case{false, "0110"}, - test_case{true , "0111"}, - test_case{true , "020101"}, - test_case{false, "4c00"}, - test_case{false, "4d0000"}, - test_case{false, "4e00000000"}, - test_case{false, "4c0100"}, - test_case{false, "4c020001"}, - test_case{true, "4c4c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + TEST (PushTest, TestPushMinimal) { + for (const auto &x : list { + test_case {true, "00"}, + test_case {true, "51"}, + test_case {true, "0100"}, + test_case {false, "0101"}, + test_case {true, "52"}, + test_case {false, "0102"}, + test_case {true, "60"}, + test_case {false, "0110"}, + test_case {true , "0111"}, + test_case {true , "020101"}, + test_case {false, "4c00"}, + test_case {false, "4d0000"}, + test_case {false, "4e00000000"}, + test_case {false, "4c0100"}, + test_case {false, "4c020001"}, + test_case {true, "4c4c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000"}}) { - ptr b = encoding::hex::read(x.Bytes); - ASSERT_TRUE(b != nullptr); - program p = decompile(*b); - ASSERT_TRUE(p.size() == 1) << "decompiled " << x.Bytes << " as " << p << "; size is " << p.size(); - instruction i = p.first(); - ASSERT_TRUE(i.verify(0) == SCRIPT_ERR_OK) << x.Bytes << " failed to verify"; - EXPECT_TRUE(is_minimal(i) == x.Expected) << "expect " << x.Expected << " for " << x.Bytes << "\n\t"; + maybe b = encoding::hex::read (x.Bytes); + ASSERT_TRUE (bool (b)); + program p = decompile (*b); + ASSERT_TRUE (p.size () == 1) << "decompiled " << x.Bytes << " as " << p << "; size is " << p.size (); + instruction i = p.first (); + ASSERT_TRUE (i.verify (0) == SCRIPT_ERR_OK) << x.Bytes << " failed to verify"; + EXPECT_TRUE (is_minimal (i) == x.Expected) << "expect " << x.Expected << " for " << x.Bytes << "\n\t"; } } // can result in stack smashing - TEST(PushTest, TestPushExpectedSize) { - auto test_size = [](size_t actual, size_t expected, string test_case) -> void { - EXPECT_EQ(expected, actual) << "Failure on " << test_case << "; expected " << expected << " got " << actual; + TEST (PushTest, TestPushExpectedSize) { + auto test_size = [] (size_t actual, size_t expected, string test_case) -> void { + EXPECT_EQ (expected, actual) << "Failure on " << test_case << "; expected " << expected << " got " << actual; }; - test_size(instruction{OP_0}.serialized_size(), 1, "0:A"); - test_size(instruction{bytes{}}.serialized_size(), 1, "0:B"); - test_size(compile(instruction{OP_0}).size(), 1, "0:C"); - test_size(instruction{bytes{0x00}}.serialized_size(), 2, "0:B"); + test_size (instruction {OP_0}.serialized_size (), 1, "0:A"); + test_size (instruction {bytes {}}.serialized_size (), 1, "0:B"); + test_size (compile (instruction {OP_0}).size (), 1, "0:C"); + test_size (instruction {bytes {0x00}}.serialized_size (), 2, "0:B"); - test_size(instruction{OP_1NEGATE}.serialized_size(), 1, "-1:A"); - test_size(instruction{bytes{0x81}}.serialized_size(), 1, "-1:B"); - test_size(compile(instruction{OP_1NEGATE}).size(), 1, "-1:C"); + test_size (instruction {OP_1NEGATE}.serialized_size (), 1, "-1:A"); + test_size (instruction {bytes {0x81}}.serialized_size (), 1, "-1:B"); + test_size (compile (instruction {OP_1NEGATE}).size (), 1, "-1:C"); - test_size(instruction{OP_1}.serialized_size(), 1, "1:A"); - test_size(instruction{bytes{0x01}}.serialized_size(), 1, "1:B"); - test_size(compile(instruction{OP_1}).size(), 1, "1:C"); + test_size (instruction {OP_1}.serialized_size (), 1, "1:A"); + test_size (instruction {bytes {0x01}}.serialized_size (), 1, "1:B"); + test_size (compile (instruction {OP_1}).size (), 1, "1:C"); - test_size(instruction{OP_16}.serialized_size(), 1, "16:A"); - test_size(instruction{bytes{0x10}}.serialized_size(), 1, "16:B"); - test_size(compile(instruction{OP_16}).size(), 1, "16:C"); + test_size (instruction {OP_16}.serialized_size (), 1, "16:A"); + test_size (instruction {bytes {0x10}}.serialized_size (), 1, "16:B"); + test_size (compile (instruction {OP_16}).size (), 1, "16:C"); - test_size(instruction{bytes{0x11}}.serialized_size(), 2, "17:A"); - test_size(compile(instruction{bytes{0x11}}).size(), 2, "17:B"); + test_size (instruction {bytes {0x11}}.serialized_size (), 2, "17:A"); + test_size (compile (instruction {bytes {0x11}}).size (), 2, "17:B"); - test_size(instruction{bytes{0x82}}.serialized_size(), 2, "-2:A"); - test_size(compile(instruction{bytes{0x82}}).size(), 2, "-2:B"); + test_size (instruction {bytes {0x82}}.serialized_size (), 2, "-2:A"); + test_size (compile (instruction {bytes {0x82}}).size (), 2, "-2:B"); - test_size(instruction{bytes{0x11, 0x00}}.serialized_size(), 3, "17,0:A"); - test_size(compile(instruction{bytes{0x11, 0x00}}).size(), 3, "17,0:B"); + test_size (instruction {bytes {0x11, 0x00}}.serialized_size (), 3, "17,0:A"); + test_size (compile (instruction {bytes {0x11, 0x00}}).size (), 3, "17,0:B"); } diff --git a/test/testStratum.cpp b/test/testStratum.cpp index 4e42c2e6..3a2fdfdd 100644 --- a/test/testStratum.cpp +++ b/test/testStratum.cpp @@ -309,10 +309,10 @@ namespace Gigamonkey::Stratum::mining { work::compact d {work::difficulty (.0001)}; digest256 prevHash {"0x0000000000000000000000000000000000000000000000000000000000000001"}; - bytes gentx1 = bytes::from_hex ("abcdef"); - bytes gentx2 = bytes::from_hex ("010203"); + bytes gentx1 = *bytes::from_hex ("abcdef"); + bytes gentx2 = *bytes::from_hex ("010203"); - bytes extra_nonce_2 = bytes::from_hex ("abcdef0123456789"); + bytes extra_nonce_2 = *bytes::from_hex ("abcdef0123456789"); int32_little gpr = 0xffffffff; int32_little version_mask = work::ASICBoost::Mask; diff --git a/test/testTransaction.cpp b/test/testTransaction.cpp index 26a86846..695de985 100644 --- a/test/testTransaction.cpp +++ b/test/testTransaction.cpp @@ -9,9 +9,9 @@ namespace Gigamonkey::Bitcoin { // can result in stack smashing - TEST(TransactionTest, TestTransaction) { + TEST (TransactionTest, TestTransaction) { - string tx_hex = string{} + + string tx_hex = string {} + "0100000001DB78AC273A4113615B5FC2D5BC24904884988201A7DB977FEEE56F73F5BF718CB00000006A4730440220295348C95DBAA2E0CF67F2EDA2A442AFF7D6D8DCA2" + "765D0D5CD11D8D3F0B75800220711DA79E4BE13BDD54DBCD3C5CFAD5F4C9E4F709BDF6B93DB8E94E464BFAE8EC412102A97974AC47721DF4B4D34DAAF277E015B29D377A" + "90E546C442F9A32E4438CF61FFFFFFFF6E0000000000000000FDDA0E006A0A22686D7779646122202D20686F77206D75636820776F756C6420796F7520646F6E61746520" + @@ -126,31 +126,31 @@ namespace Gigamonkey::Bitcoin { "BFF42E6E53F3031AED7A85E2C69D1B029969074A88AC23020000000000001976A914C08965F6944CAC349AA27F1125A6C2F5D9DA2A1588AC23020000000000001976A914" + "714B401DAD2D9D4F2D127A990A38962A9BC4FD5688AC17D7FC08000000001976A9145773F7E192A69985C4EFAEA268C1D27BD089D58B88AC00000000"; - ptr tx = encoding::hex::read(tx_hex); + maybe tx = encoding::hex::read (tx_hex); - ASSERT_NE(tx, nullptr); + ASSERT_TRUE (bool (tx)); - EXPECT_EQ(tx->size(), 7676); + EXPECT_EQ (tx->size (), 7676); - EXPECT_EQ(Hash256(*tx), digest256{"0x0473718d87e0bd19437d19da0454873c074d5c9698d9e6e41b0c5cae2dcbe202"}); + EXPECT_EQ (Hash256 (*tx), digest256 {"0x0473718d87e0bd19437d19da0454873c074d5c9698d9e6e41b0c5cae2dcbe202"}); - transaction t = transaction{*tx}; + transaction t = transaction {*tx}; - EXPECT_TRUE(t.valid()); + EXPECT_TRUE (t.valid ()); - EXPECT_EQ(t.Version, 1); + EXPECT_EQ (t.Version, 1); - EXPECT_EQ(t.Inputs.size(), 1); + EXPECT_EQ (t.Inputs.size (), 1); - EXPECT_EQ(t.Outputs.size(), 110); + EXPECT_EQ (t.Outputs.size (), 110); - EXPECT_EQ(t.Locktime, 0); + EXPECT_EQ (t.Locktime, 0); - EXPECT_EQ(t.serialized_size(), 7676); + EXPECT_EQ (t.serialized_size (), 7676); - EXPECT_FALSE(pay_to_address{t.Outputs.first().Script}.valid()); + EXPECT_FALSE (pay_to_address {t.Outputs.first ().Script}.valid ()); - EXPECT_EQ(bytes(t), *tx); + EXPECT_EQ (bytes (t), *tx); } } diff --git a/test/testWorkString.cpp b/test/testWorkString.cpp index a15aec78..3884279a 100644 --- a/test/testWorkString.cpp +++ b/test/testWorkString.cpp @@ -7,9 +7,9 @@ namespace Gigamonkey::Bitcoin { - TEST(WorkStringTest, TestWorkSTring) { + TEST (WorkStringTest, TestWorkSTring) { - std::string genesis_header_string = std::string{} + + std::string genesis_header_string = std::string {} + // version "01000000" + // prev block @@ -23,37 +23,37 @@ namespace Gigamonkey::Bitcoin { // nonce "1DAC2B7C"; - ptr genesis_header_hex = encoding::hex::read(genesis_header_string); + maybe genesis_header_hex = encoding::hex::read (genesis_header_string); - ASSERT_NE(genesis_header_hex, nullptr); + ASSERT_TRUE (bool (genesis_header_hex)); - digest256 genesis_hash = Hash256(*genesis_header_hex); + digest256 genesis_hash = Hash256 (*genesis_header_hex); - EXPECT_EQ(genesis_hash, digest256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + EXPECT_EQ (genesis_hash, digest256 ("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - work::string work_string{slice<80>(genesis_header_hex->data())}; + work::string work_string {slice<80> (genesis_header_hex->data ())}; - Bitcoin::header header(slice<80>(genesis_header_hex->data())); + Bitcoin::header header (slice<80> (genesis_header_hex->data ())); - EXPECT_EQ(work_string, work::string(header)); + EXPECT_EQ (work_string, work::string (header)); - byte_array<80> work_string_written = work_string.write(); + byte_array<80> work_string_written = work_string.write (); - byte_array<80> header_written = header.write(); + byte_array<80> header_written = header.write (); - EXPECT_EQ(work_string_written, header_written); + EXPECT_EQ (work_string_written, header_written); - EXPECT_EQ(work_string.hash(), digest256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + EXPECT_EQ (work_string.hash (), digest256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - EXPECT_EQ(header.hash(), digest256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); + EXPECT_EQ (header.hash (), digest256("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - EXPECT_TRUE(work_string.valid()); + EXPECT_TRUE(work_string.valid ()); - EXPECT_TRUE(header.valid()); + EXPECT_TRUE (header.valid ()); } - TEST(WorkStringTest, TestASICBoost) { + TEST (WorkStringTest, TestASICBoost) { int32 VERSIONBITS_IGNORE_MASK = 0xE0001FFFUL; int32 VERSIONBITS_IGNORE_LEFT = 0xE0000000UL; @@ -64,14 +64,14 @@ namespace Gigamonkey::Bitcoin { int32 magic_number = ((combined & VERSIONBITS_IGNORE_LEFT) >> 16) + (combined & VERSIONBITS_IGNORE_RIGHT); int32_little combined_little = combined; - int32_little version_little = work::ASICBoost::version(combined); - uint16_little gpurpose_little = work::ASICBoost::bits(combined); - uint16_little magicnum_little = work::ASICBoost::magic_number(combined); - - EXPECT_EQ(version_little, version); - EXPECT_EQ(gpurpose_little, general_purpose_bits); - EXPECT_EQ(magicnum_little, magic_number); - EXPECT_EQ(combined_little, work::ASICBoost::category(magicnum_little, gpurpose_little)); + int32_little version_little = work::ASICBoost::version (combined); + uint16_little gpurpose_little = work::ASICBoost::bits (combined); + uint16_little magicnum_little = work::ASICBoost::magic_number (combined); + + EXPECT_EQ (version_little, version); + EXPECT_EQ (gpurpose_little, general_purpose_bits); + EXPECT_EQ (magicnum_little, magic_number); + EXPECT_EQ (combined_little, work::ASICBoost::category(magicnum_little, gpurpose_little)); } From 2194d2748680642da7dd92a573c7c7da849b1b57 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Thu, 30 Mar 2023 12:16:39 -0500 Subject: [PATCH 11/11] Upgrade to latest version of data --- conanfile.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/conanfile.py b/conanfile.py index 3382366e..9b0b7d68 100644 --- a/conanfile.py +++ b/conanfile.py @@ -2,10 +2,9 @@ from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps from os import environ - -class GigamonkeyConan(ConanFile): +class GigamonkeyConan (ConanFile): name = "gigamonkey" - version = "v0.0.13" + version = "v0.0.14" license = "Open BSV" author = "Daniel Krawisz" url = "https://github.com/Gigamonkey-BSV/Gigamonkey" @@ -15,7 +14,7 @@ class GigamonkeyConan(ConanFile): options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} exports_sources = "CMakeLists.txt", "include/*", "src/*", "test/*" - requires = "boost/1.80.0", "openssl/1.1.1t", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "secp256k1/0.3@proofofwork/stable", "data/v0.0.26@proofofwork/stable", "gtest/1.12.1" + requires = "boost/1.80.0", "openssl/1.1.1t", "cryptopp/8.5.0", "nlohmann_json/3.10.0", "gmp/6.2.1", "secp256k1/0.3@proofofwork/stable", "data/v0.0.24@proofofwork/stable", "gtest/1.12.1" def set_version (self): if "CIRCLE_TAG" in environ: