From aac9d67505205636bbe8a491b2c43d4c8d1b6f48 Mon Sep 17 00:00:00 2001 From: Daniel Krawisz Date: Wed, 29 Mar 2023 11:22:43 -0500 Subject: [PATCH] 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)); }