From 65d96d521f2085505a0dfffcb29dfd8159feee79 Mon Sep 17 00:00:00 2001 From: Chris Johnson Date: Mon, 18 Feb 2019 21:29:00 -0600 Subject: [PATCH 01/29] fix: correct submodule ignore paths (#70) --- platformio.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio.ini b/platformio.ini index 406cb8d4..34525eb9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,7 +15,7 @@ description = "A simple Cryptography Implementation in C++ for the ARK Blockchai lib_ldf_mode = off lib_deps = micro-ecc, bip39@^1.1, ArduinoJson build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - - - - - +src_filter = +<*> -<.git/> - - - - - upload_speed = 921600 [env:esp8266] From 44d4c6a52d7082ac2ee60da1e2707627fd888bf2 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 18 Feb 2019 19:38:20 -0800 Subject: [PATCH 02/29] fix: Update Build Flag (#69) --- library.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library.json b/library.json index 5e5873b6..188b50d6 100644 --- a/library.json +++ b/library.json @@ -47,7 +47,8 @@ }, "build": { "flags": [ - "-I src/include/cpp-crypto" + "-I src/include/cpp-crypto", + "-I src/lib" ] } } From c98b5b2c37303a7b29875252e32fb177816827fb Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 19 Feb 2019 08:53:12 -0800 Subject: [PATCH 03/29] chore(release): 0.3.1 (#71) --- CHANGELOG.md | 33 ++++++++++++++++++++++++--------- library.json | 2 +- library.properties | 2 +- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7051d501..492e3e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,29 +7,39 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +## [0.3.1] - 2019-02-19 + +### Fixed + +- fixed PIO submodule ignore paths in `./platformio.ini` ([#70]) +- added `./src/lib` to build flags for PIO in `./library.json` ([#69]) + ## [0.3.0] - 2019-02-16 + ## [0.3.0-arduino] - 2019-02-16 ### Added -- Arduino CircleCI config + +- Arduino CircleCI config ([#61]) ### Changed -- updated `keywords.txt`. -- updated `./library.json` package export settings. -- removed unnecessary files: + +- updated `keywords.txt` ([#64]) +- updated `./library.json` package export settings ([#64]) +- removed unnecessary files ([#64]): - `./appveyor.yml`. - `./CMakeSettings.json`. - `./test/travis.yml`. - `uECC_README.md`. - - submodule from `cmake_example` -- moved external packages to `./src/lib/`: + - submodule from `cmake_example`. +- moved external packages to `./src/lib/` ([#64]): - `./src/bcl`. - `./src/rfc6979`. - `./src/stl`. - `./date`. -- moved `./docs` to `./extras` in arduino builds. -- automated `ARDUINO_IDE.sh` script. -- updated `ARDUINO_IDE.sh` script to reflect `lib/` changes. +- moved `./docs` to `./extras` in arduino builds ([#64]) +- updated `ARDUINO_IDE.sh` script to reflect `lib/` changes ([#64]) +- automated `ARDUINO_IDE.sh` script ([#60]) ## [0.2.0] - 2019-02-07 @@ -58,3 +68,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. [#49]: https://github.com/ArkEcosystem/cpp-crypto/pull/49 [#52]: https://github.com/ArkEcosystem/cpp-crypto/pull/52 [#53]: https://github.com/ArkEcosystem/cpp-crypto/pull/53 +[#60]: https://github.com/ArkEcosystem/cpp-crypto/pull/60 +[#61]: https://github.com/ArkEcosystem/cpp-crypto/pull/61 +[#64]: https://github.com/ArkEcosystem/cpp-crypto/pull/64 +[#69]: https://github.com/ArkEcosystem/cpp-crypto/pull/69 +[#70]: https://github.com/ArkEcosystem/cpp-crypto/pull/70 diff --git a/library.json b/library.json index 188b50d6..f4404dd3 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Crypto.git" }, - "version": "0.3.0", + "version": "0.3.1", "authors": [ { "name": "Ark Ecosystem", diff --git a/library.properties b/library.properties index 9f1c3ddf..f9450d1b 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Crypto -version=0.3.0 +version=0.3.1 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple Cryptography Implementation in C++ for the ARK Blockchain. From d6f53e9f0cbd62bdac3188134fd67f5015a4d37e Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 15 Apr 2019 20:32:05 -0700 Subject: [PATCH 04/29] test: use core fixtures (#74) --- examples/arduino/ESP32/ESP32.ino | 34 ++++++++++---------- examples/arduino/ESP8266/ESP8266.ino | 24 +++++++------- examples/platformio_example/src/main.ino | 22 ++++++------- test/identities/address.cpp | 23 +++++++------ test/identities/privatekey.cpp | 41 ++++++++++++++---------- test/identities/publickey.cpp | 36 +++++++++++++-------- test/identities/wif.cpp | 27 ++++++++++------ test/utils/message.cpp | 14 +++++--- 8 files changed, 125 insertions(+), 96 deletions(-) diff --git a/examples/arduino/ESP32/ESP32.ino b/examples/arduino/ESP32/ESP32.ino index 14fe4530..2c82de74 100644 --- a/examples/arduino/ESP32/ESP32.ino +++ b/examples/arduino/ESP32/ESP32.ino @@ -49,10 +49,10 @@ void checkCrypto() { * This is done by passing a 12-word 'Passphrase' and the 'Network' 'Version' "byte". * The 'Version" "byte" is a BASE58 P2PKH byte. Ark Devnet is '0x1E'; Ark Mainnet is '0x17'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * and the 'Devnet' 'Version' byte (0x1E); the ARK Address should be "DStZXkgpEjxbG355nQ26vnkp95p24U9tsV" + * Given the passphrase "this is a top secret passphrase", + * and the 'Devnet' 'Version' byte (0x1E); the ARK Address should be "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib" */ - const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase = "this is a top secret passphrase"; const uint8_t networkVersion = 0x1E; Address arkAddress = Address::fromPassphrase(passphrase, networkVersion); @@ -67,11 +67,11 @@ void checkCrypto() { * The following methods allows create a 'PrivateKey'. * This is done by passing a 12-word 'Passphrase'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * the 'PrivateKey" should be "950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021". + * Given the passphrase "this is a top secret passphrase", + * the 'PrivateKey" should be "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712". * This is a 'SHA256' of your "Passphrase". */ - const auto passphrase2 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase2 = "this is a top secret passphrase"; PrivateKey privateKeyFromPassphrase = PrivateKey::fromPassphrase(passphrase2); Serial.print("\nPrivateKey from Passphrase: "); Serial.println(privateKeyFromPassphrase.toString().c_str()); // The 'PrivateKey' object is a type. Use 'toString()' to view the output. Arduino requires a 'c_str()' to 'print'. @@ -83,10 +83,10 @@ void checkCrypto() { * The following methods allows create a 'PublicKey'. * This is done by passing a 12-word 'Passphrase'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * the 'PublicKey" should be "029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4". + * Given the passphrase "this is a top secret passphrase", + * the 'PublicKey" should be "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192". */ - const auto passphrase3 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase3 = "this is a top secret passphrase"; PublicKey publicKeyFromPassphrase = PublicKey::fromPassphrase(passphrase3); Serial.print("\nPublicKey from Passphrase: "); Serial.println(publicKeyFromPassphrase.toString().c_str()); // the 'PublicKey' object is a type. Use 'toString()' to view the output. Arduino requires a 'c_str()' to 'print'. @@ -101,11 +101,11 @@ void checkCrypto() { * The 'WIF" "byte" is a BASE58 WIF byte. Ark Devnet is '0xaa'; Ark Mainnet is also '0xaa'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", + * Given the passphrase "this is a top secret passphrase", * and the 'Devnet' 'WIF' byte (0xaa); - * The 'WIF" should be "SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB". + * The 'WIF" should be "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA". */ - const auto passphrase4 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase4 = "this is a top secret passphrase"; const uint8_t wifByte = 0xaa; WIF wifFromPassphrase = WIF::fromPassphrase(passphrase4, wifByte); Serial.print("\nWIF from Passphrase: "); @@ -118,12 +118,12 @@ void checkCrypto() { * The following methods allows you to 'Sign' a text 'Message'. * This is done by passing the text to be signed, and a 12-word 'Passphrase'. * - * Given the text "Computer science is no more about computers than astronomy is about telescopes.", - * and the passphrase "bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * The 'Signature" should be "3044022021704f2adb2e4a10a3ddc1d7d64552b8061c05f6d12a168c69091c75581d611402200edf37689d2786fc690af9f0f6fa1f629c95695039f648a6d455484302402e93". + * Given the text "Hello World", + * and the passphrase "this is a top secret passphrase", + * The 'Signature" should be "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8". */ - const auto text = "Computer science is no more about computers than astronomy is about telescopes."; - const auto passphrase5 = "viable weasel wage promote praise inflict jaguar tackle color unusual exclude direct"; + const auto text = "Hello World"; + const auto passphrase5 = "this is a top secret passphrase"; Ark::Crypto::Utils::Message message; message.sign(text, passphrase5); Serial.print("\nSignature from Signed Message: "); diff --git a/examples/arduino/ESP8266/ESP8266.ino b/examples/arduino/ESP8266/ESP8266.ino index 66d4f891..876a2aaf 100644 --- a/examples/arduino/ESP8266/ESP8266.ino +++ b/examples/arduino/ESP8266/ESP8266.ino @@ -49,10 +49,10 @@ void checkCrypto() { * This is done by passing a 12-word 'Passphrase' and the 'Network' 'Version' "byte". * The 'Version" "byte" is a BASE58 P2PKH byte. Ark Devnet is '0x1E'; Ark Mainnet is '0x17'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * and the 'Devnet' 'Version' byte (0x1E); the ARK Address should be "DStZXkgpEjxbG355nQ26vnkp95p24U9tsV" + * Given the passphrase "this is a top secret passphrase", + * and the 'Devnet' 'Version' byte (0x1E); the ARK Address should be "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib" */ - const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase = "this is a top secret passphrase"; const uint8_t networkVersion = 0x1E; Address arkAddress = Address::fromPassphrase(passphrase, networkVersion); @@ -67,11 +67,11 @@ void checkCrypto() { * The following methods allows create a 'PrivateKey'. * This is done by passing a 12-word 'Passphrase'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * the 'PrivateKey" should be "950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021". + * Given the passphrase "this is a top secret passphrase", + * the 'PrivateKey" should be "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712". * This is a 'SHA256' of your "Passphrase". */ - const auto passphrase2 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase2 = "this is a top secret passphrase"; PrivateKey privateKeyFromPassphrase = PrivateKey::fromPassphrase(passphrase2); Serial.print("\nPrivateKey from Passphrase: "); Serial.println(privateKeyFromPassphrase.toString().c_str()); // The 'PrivateKey' object is a type. Use 'toString()' to view the output. Arduino requires a 'c_str()' to 'print'. @@ -83,10 +83,10 @@ void checkCrypto() { * The following methods allows create a 'PublicKey'. * This is done by passing a 12-word 'Passphrase'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", - * the 'PublicKey" should be "029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4". + * Given the passphrase "this is a top secret passphrase", + * the 'PublicKey" should be "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192". */ - const auto passphrase3 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase3 = "this is a top secret passphrase"; PublicKey publicKeyFromPassphrase = PublicKey::fromPassphrase(passphrase3); Serial.print("\nPublicKey from Passphrase: "); Serial.println(publicKeyFromPassphrase.toString().c_str()); // the 'PublicKey' object is a type. Use 'toString()' to view the output. Arduino requires a 'c_str()' to 'print'. @@ -101,11 +101,11 @@ void checkCrypto() { * The 'WIF" "byte" is a BASE58 WIF byte. Ark Devnet is '0xaa'; Ark Mainnet is also '0xaa'. * - * Given the passphrase ""bullet parade snow bacon mutual deposit brass floor staff list concert ask", + * Given the passphrase "this is a top secret passphrase", * and the 'Devnet' 'WIF' byte (0xaa); - * The 'WIF" should be "SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB". + * The 'WIF" should be "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA". */ - const auto passphrase4 = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; + const auto passphrase4 = "this is a top secret passphrase"; const uint8_t wifByte = 0xaa; WIF wifFromPassphrase = WIF::fromPassphrase(passphrase4, wifByte); Serial.print("\nWIF from Passphrase: "); diff --git a/examples/platformio_example/src/main.ino b/examples/platformio_example/src/main.ino index 729bbdf6..9194ae72 100644 --- a/examples/platformio_example/src/main.ino +++ b/examples/platformio_example/src/main.ino @@ -14,8 +14,8 @@ void setup() { } void loop() { - const auto text = "Computer science is no more about computers than astronomy is about telescopes."; - const auto passphrase = "viable weasel wage promote praise inflict jaguar tackle color unusual exclude direct"; + const auto text = "Hello World"; + const auto passphrase = "this is a top secret passphrase"; // Message - sign Ark::Crypto::Utils::Message message; @@ -28,8 +28,8 @@ void loop() { Serial.println(); // Message - verify - auto publicKey = PublicKey::fromHex("0275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a456"); - auto signature = HexToBytes("3044022021704f2adb2e4a10a3ddc1d7d64552b8061c05f6d12a168c69091c75581d611402200edf37689d2786fc690af9f0f6fa1f629c95695039f648a6d455484302402e93"); + auto publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + auto signature = HexToBytes("304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"); message = Ark::Crypto::Utils::Message( text, @@ -57,7 +57,7 @@ void loop() { Serial.println(); // Address - from publickey - publicKey = PublicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + publicKey = PublicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); address = Address::fromPublicKey(publicKey, networkVersion); Serial.println("Address from public key"); Serial.print("\tPublic Key: "); Serial.print(publicKey.toString().c_str()); Serial.println(); @@ -65,7 +65,7 @@ void loop() { Serial.println(); // Address - from privatekey - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); address = Address::fromPrivateKey(privateKey, networkVersion); Serial.println("Address from private key"); Serial.print("\tPrivate Key: "); Serial.print(privateKey.toString().c_str()); Serial.println(); @@ -73,7 +73,7 @@ void loop() { Serial.println(); // Address - validate - address = Address("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV"); + address = Address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); auto isValidAddress = Address::validate(address, networkVersion); Serial.println("Valid Address"); Serial.print("\tAddress: "); Serial.print(address.toString().c_str()); Serial.println(); @@ -88,9 +88,9 @@ void loop() { Serial.println(); // Private Key - object from hex - privateKey = PrivateKey::fromHex("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + privateKey = PrivateKey::fromHex("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); Serial.println("Private Key from hex"); - Serial.println("\tHex: 950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + Serial.println("\tHex: d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); Serial.print("\tPrivate Key: "); Serial.print(privateKey.toString().c_str()); Serial.println(); Serial.println(); @@ -102,9 +102,9 @@ void loop() { Serial.println(); // Public Key - object from hex - publicKey = PublicKey::fromHex("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); Serial.println("Public Key from hex"); - Serial.println("\tHex: 029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + Serial.println("\tHex: 034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); Serial.print("\tPublic Key: "); Serial.print(publicKey.toString().c_str()); Serial.println(); Serial.println(); diff --git a/test/identities/address.cpp b/test/identities/address.cpp index 10eb27a8..9b0e85e6 100644 --- a/test/identities/address.cpp +++ b/test/identities/address.cpp @@ -6,34 +6,37 @@ #include "identities/publickey.h" using namespace Ark::Crypto::Identities; -namespace { -const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; +namespace { // NOLINT + +// ARK Core test fixtures: +// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json +const auto passphrase = "this is a top secret passphrase"; const uint8_t networkVersion = 0x1E; } // namespace TEST(identities, address_from_passphrase) { Address address = Address::fromPassphrase(passphrase, networkVersion); - ASSERT_STREQ("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV", address.toString().c_str()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); } TEST(identities, address_from_privatekey) { - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); Address address = Address::fromPrivateKey(privateKey, networkVersion); - ASSERT_STREQ("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV", address.toString().c_str()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); } TEST(identities, address_from_publickey) { - PublicKey publicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); Address address = Address::fromPublicKey(publicKey, networkVersion); - ASSERT_STREQ("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV", address.toString().c_str()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); } TEST(identities, address_from_string) { - Address address("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV"); - ASSERT_STREQ("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV", address.toString().c_str()); + Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); } TEST(identities, address_validate) { - Address address("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV"); + Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); ASSERT_TRUE(Address::validate(address, networkVersion)); } diff --git a/test/identities/privatekey.cpp b/test/identities/privatekey.cpp index ae310271..9243a34a 100644 --- a/test/identities/privatekey.cpp +++ b/test/identities/privatekey.cpp @@ -4,47 +4,54 @@ #include "identities/privatekey.h" using namespace Ark::Crypto::Identities; -namespace { -const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; -const uint8_t testPrivateKeyBytes[32] = {149, 9, 129, 206, 23, 223, 102, 45, 188, 29, 37, 48, 95, 133, 151, 167, - 19, 9, 251, 143, 114, 50, 32, 58, 9, 68, 71, 126, 37, 52, 176, 33}; +namespace { // NOLINT + +// ARK Core test fixtures: +// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json +const auto passphrase = "this is a top secret passphrase"; +const uint8_t testPrivateKeyBytes[32] = { + 216, 131, 156, 36, 50, 191, 208, 166, + 126, 241, 10, 128, 75, 169, 145, 234, + 187, 161, 159, 21, 74, 61, 112, 121, + 23, 104, 29, 69, 130, 42, 87, 18 +}; const uint8_t wifByte = 0xaa; } // namespace TEST(identities, privatekey_construct_bytes) { PrivateKey privateKey(testPrivateKeyBytes); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_construct_string) { - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_from_hex) { - PrivateKey privateKey = PrivateKey::fromHex("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromHex("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_from_passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_from_string) { - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_from_wif_string) { - const char* wifStr = "SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB"; + const char* wifStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, wifByte); - ASSERT_STREQ("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021", privateKey.toString().c_str()); + ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); } TEST(identities, privatekey_get_bytes) { - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); const auto privateKeyBytes = privateKey.toBytes(); for (unsigned int i = 0; i < PRIVATEKEY_SIZE; i++) { ASSERT_EQ(privateKeyBytes[i], testPrivateKeyBytes[i]); @@ -52,7 +59,7 @@ TEST(identities, privatekey_get_bytes) { } TEST(identities, privatekey_validate) { - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); + PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); ASSERT_TRUE(PrivateKey::validate(privateKey)); } @@ -61,5 +68,5 @@ TEST(identities, privatekey_validate_bytes) { } TEST(identities, privatekey_validate_string) { - ASSERT_TRUE(PrivateKey::validate("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021")); + ASSERT_TRUE(PrivateKey::validate("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712")); } diff --git a/test/identities/publickey.cpp b/test/identities/publickey.cpp index 328c7163..5e9cfdc8 100644 --- a/test/identities/publickey.cpp +++ b/test/identities/publickey.cpp @@ -4,35 +4,43 @@ #include "identities/publickey.h" using namespace Ark::Crypto::Identities; -namespace { -const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; -const uint8_t testPublicKeyBytes[33] = {2, 159, 223, 65, 167, 214, 157, 142, 252, 123, 35, - 108, 33, 185, 80, 154, 35, 216, 98, 234, 78, 216, - 177, 58, 86, 227, 30, 238, 88, 219, 253, 151, 180}; +namespace { // NOLINT + +// ARK Core test fixtures: +// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json +const auto passphrase = "this is a top secret passphrase"; +const uint8_t testPublicKeyBytes[33] = { + 3, + 65, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 +}; + } // namespace TEST(identities, publickey_from_bytes) { PublicKey publicKey(testPublicKeyBytes); - ASSERT_STREQ("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4", publicKey.toString().c_str()); + ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); } TEST(identities, publickey_from_hex) { - PublicKey publicKey = PublicKey::fromHex("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); - ASSERT_STREQ("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4", publicKey.toString().c_str()); + PublicKey publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); } TEST(identities, publickey_from_passphrase) { PublicKey publicKey = PublicKey::fromPassphrase(passphrase); - ASSERT_STREQ("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4", publicKey.toString().c_str()); + ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); } TEST(identities, publickey_from_string) { - PublicKey publicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); - ASSERT_STREQ("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4", publicKey.toString().c_str()); + PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); } TEST(identities, publickey_get_bytes) { - PublicKey publicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); const auto publicKeyBytes = publicKey.toBytes(); for (unsigned int i = 0; i < COMPRESSED_PUBLICKEY_SIZE; i++) { ASSERT_EQ(publicKeyBytes[i], testPublicKeyBytes[i]); @@ -40,7 +48,7 @@ TEST(identities, publickey_get_bytes) { } TEST(identities, publickey_validate) { - PublicKey publicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); + PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); ASSERT_TRUE(PublicKey::validate(publicKey)); } @@ -49,5 +57,5 @@ TEST(identities, publickey_validate_bytes) { } TEST(identities, publickey_validate_string) { - ASSERT_TRUE(PublicKey::validate("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4")); + ASSERT_TRUE(PublicKey::validate("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192")); } diff --git a/test/identities/wif.cpp b/test/identities/wif.cpp index df62a5e3..275acf2a 100644 --- a/test/identities/wif.cpp +++ b/test/identities/wif.cpp @@ -4,31 +4,38 @@ #include "identities/wif.h" using namespace Ark::Crypto::Identities; -namespace { -const auto passphrase = "bullet parade snow bacon mutual deposit brass floor staff list concert ask"; -const uint8_t testWIFBytes[52] = {83, 69, 90, 117, 74, 90, 111, 117, 78, 75, 56, 71, 76, 88, 78, 65, 112, 106, - 99, 105, 72, 52, 81, 110, 83, 75, 105, 78, 114, 57, 55, 49, 101, 120, 86, 99, - 76, 50, 89, 54, 88, 102, 114, 68, 70, 53, 111, 57, 55, 55, 122, 66}; +namespace { // NOLINT + +// ARK Core test fixtures: +// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json +const auto passphrase = "this is a top secret passphrase"; +const uint8_t testWIFBytes[52] = { + 83, 71, 113, 52, 120, 76, 103, 90, 75, 67, 71, 120, 115, + 55, 98, 106, 109, 119, 110, 66, 114, 87, 99, 84, 52, 67, + 49, 65, 68, 70, 69, 101, 114, 109, 106, 56, 52, 54, 75, + 67, 57, 55, 70, 83, 118, 49, 87, 70, 68, 49, 100, 65 +}; const uint8_t wifByte = 0xaa; + } // namespace TEST(identities, wif_from_bytes) { WIF wif(testWIFBytes); - ASSERT_STREQ("SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB", wif.toString().c_str()); + ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); } TEST(identities, wif_from_passphrase) { WIF wif = WIF::fromPassphrase(passphrase, wifByte); - ASSERT_STREQ("SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB", wif.toString().c_str()); + ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); } TEST(identities, wif_from_string) { - WIF wif("SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB"); - ASSERT_STREQ("SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB", wif.toString().c_str()); + WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); + ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); } TEST(identities, wif_get_bytes) { - WIF wif("SEZuJZouNK8GLXNApjciH4QnSKiNr971exVcL2Y6XfrDF5o977zB"); + WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); const auto wifBytes = wif.toBytes(); for (unsigned int i = 0; i < WIF_SIZE; i++) { ASSERT_EQ(wifBytes[i], testWIFBytes[i]); diff --git a/test/utils/message.cpp b/test/utils/message.cpp index b1170001..a538045c 100644 --- a/test/utils/message.cpp +++ b/test/utils/message.cpp @@ -6,11 +6,15 @@ #include namespace { // NOLINT -const auto text = "Computer science is no more about computers than astronomy is about telescopes."; -const auto passphrase = "viable weasel wage promote praise inflict jaguar tackle color unusual exclude direct"; -const auto expectedSignature = "3044022021704f2adb2e4a10a3ddc1d7d64552b8061c05f6d12a168c69091c75581d611402200edf37689d2786fc690af9f0f6fa1f629c95695039f648a6d455484302402e93"; -const auto expectedPublicKey = "0275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a456"; -const auto expectedJsonString = "{\"publickey\":\"0275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a456\",\"signature\":\"3044022021704f2adb2e4a10a3ddc1d7d64552b8061c05f6d12a168c69091c75581d611402200edf37689d2786fc690af9f0f6fa1f629c95695039f648a6d455484302402e93\",\"message\":\"Computer science is no more about computers than astronomy is about telescopes.\"}"; + +// ARK Core test fixtures: +// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts +const auto text = "Hello World"; +const auto passphrase = "this is a top secret passphrase"; +const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; +const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; +const auto expectedJsonString = "{\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\",\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\",\"message\":\"Hello World\"}"; + } // namespace TEST(utils, message_sign) { From 5b9cd15802ad2964a108dd9d57281c9ffe448ff4 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 16 Apr 2019 19:24:04 -0700 Subject: [PATCH 05/29] chore: Update ArduinoJson Package (#76) --- .circleci/script_arduino.sh | 2 +- docs/INSTALL_PLATFORMIO.md | 4 +- platformio.ini | 2 +- src/lib/ArduinoJson | 2 +- src/transactions/transaction.cpp | 89 ++++++++++++------------ src/utils/message.cpp | 30 ++++---- test/platformio.ini | 2 +- test/transactions/transaction.cpp | 110 ++++++++++++++++-------------- 8 files changed, 125 insertions(+), 116 deletions(-) diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 1b9fc6ac..a0d36579 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -5,6 +5,6 @@ bash ./extras/ARDUINO_IDE.sh --auto mkdir -p ~/Arduino/libraries/cpp-crypto/ mv ~/project/* ~/Arduino/libraries/cpp-crypto -arduino-cli lib install "ArduinoJson@5.13.4" +arduino-cli lib install "ArduinoJson@6.10.0" arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/arduino/ESP32/ESP32.ino --debug diff --git a/docs/INSTALL_PLATFORMIO.md b/docs/INSTALL_PLATFORMIO.md index 1dad9614..7466e153 100644 --- a/docs/INSTALL_PLATFORMIO.md +++ b/docs/INSTALL_PLATFORMIO.md @@ -18,8 +18,8 @@ or also install platformio dependencies: -> install AUnit (2778), micro-ecc (1665) bip39 (5886) ArduinoJson@5.13.4 libraries ->```platformio lib -g install 2778 1665 5886 ArduinoJson@5.13.4``` +> install AUnit (2778), micro-ecc (1665) bip39 (5886) ArduinoJson@6.10.0 libraries +>```platformio lib -g install 2778 1665 5886 ArduinoJson@6.10.0``` # diff --git a/platformio.ini b/platformio.ini index 34525eb9..522182d1 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,7 +13,7 @@ description = "A simple Cryptography Implementation in C++ for the ARK Blockchai [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, ArduinoJson +lib_deps = micro-ecc, bip39@^1.1, ArduinoJson@6.10.0 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto src_filter = +<*> -<.git/> - - - - - upload_speed = 921600 diff --git a/src/lib/ArduinoJson b/src/lib/ArduinoJson index 0685a36f..1c814d3b 160000 --- a/src/lib/ArduinoJson +++ b/src/lib/ArduinoJson @@ -1 +1 @@ -Subproject commit 0685a36f0e51ba71b96c441697e0432ed2a6b176 +Subproject commit 1c814d3bb657752d29a342ef20ce8074f8cde5d7 diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index fa022886..f72c1841 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -137,7 +137,15 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( std::map Ark::Crypto::Transactions::Transaction::toArray() { // buffers for variable and non-string type-values. - char amount[24], assetName[16], assetValue[512], fee[24], network[8], signatures[512], timestamp[36], type[8], version[8]; + char amount[24], + assetName[16], + assetValue[512], + fee[24], + network[8], + signatures[512], + timestamp[36], + type[8], + version[8]; // Amount sprintf(amount, "%llu", this->amount); @@ -205,54 +213,51 @@ std::map Ark::Crypto::Transactions::Transaction::toArr sprintf(version, "%d", this->version); return { - {"amount", amount}, - {assetName, assetValue}, - {"fee", fee}, - {"id", this->id}, - {"network", network}, - {"recipientId", this->recipientId}, - {"secondSignature", this->secondSignature}, - {"senderPublicKey", this->senderPublicKey}, - {"signature", this->signature}, - {"signatures", signatures}, - {"signSignature", this->signSignature}, - {"timestamp", timestamp}, - {"type", type}, - {"vendorField", this->vendorField}, - {"version", version} + { "amount", amount }, + { assetName, assetValue }, + { "fee", fee }, + { "id", this->id }, + { "network", network }, + { "recipientId", this->recipientId }, + { "secondSignature", this->secondSignature }, + { "senderPublicKey", this->senderPublicKey }, + { "signature", this->signature }, + { "signatures", signatures }, + { "signSignature", this->signSignature }, + { "timestamp", timestamp }, + { "type", type }, + { "vendorField", this->vendorField }, + { "version", version } }; } std::string Ark::Crypto::Transactions::Transaction::toJson() { std::map txArray = this->toArray(); - const size_t capacity = JSON_OBJECT_SIZE(15); - DynamicJsonBuffer jsonBuffer(capacity); - - JsonObject& root = jsonBuffer.createObject(); + DynamicJsonDocument doc(900); // Amount - root["amount"] = txArray["amount"]; + doc["amount"] = txArray["amount"]; // Asset if (this->type == 0) { // Transfer //do nothing } else if (this->type == 1) { // Second Signature Registration - JsonObject& tAsset = root.createNestedObject("asset"); - JsonObject& signature = tAsset.createNestedObject("signature"); + JsonObject tAsset = doc.createNestedObject("asset"); + JsonObject signature = tAsset.createNestedObject("signature"); signature["publicKey"] = txArray["publicKey"]; } else if (this->type == 2) { // Delegate Registration - JsonObject& dAsset = root.createNestedObject("asset"); - JsonObject& delegate = dAsset.createNestedObject("delegate"); + JsonObject dAsset = doc.createNestedObject("asset"); + JsonObject delegate = dAsset.createNestedObject("delegate"); delegate["username"] = txArray["username"]; }else if (this->type == 3) { // Vote - JsonObject& vAsset = root.createNestedObject("asset"); - JsonArray& votes = vAsset.createNestedArray("votes"); + JsonObject vAsset = doc.createNestedObject("asset"); + JsonArray votes = vAsset.createNestedArray("votes"); std::string::size_type lastPos = txArray["votes"].find_first_not_of(",", 0); std::string::size_type pos = txArray["votes"].find_first_of(",", lastPos); @@ -275,33 +280,33 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { }; // Fee - root["fee"] = txArray["fee"]; + doc["fee"] = txArray["fee"]; // Id - root["id"] = txArray["id"]; + doc["id"] = txArray["id"]; // Network if (txArray["network"] != "0") { - root["network"] = txArray["network"]; + doc["network"] = txArray["network"]; } // RecipientId - root["recipientId"] = txArray["recipientId"]; + doc["recipientId"] = txArray["recipientId"]; // SecondSignature if (std::strlen(txArray["secondSignature"].c_str()) > 0) { - root["secondSignature"] = txArray["secondSignature"]; + doc["secondSignature"] = txArray["secondSignature"]; } // SenderPublicKey - root["senderPublicKey"] = txArray["senderPublicKey"]; + doc["senderPublicKey"] = txArray["senderPublicKey"]; // Signature - root["signature"] = txArray["signature"]; + doc["signature"] = txArray["signature"]; // Signatures if (this->signatures.size() > 0) { - JsonArray& signatures = root.createNestedArray("signatures"); + JsonArray signatures = doc.createNestedArray("signatures"); std::string::size_type lastPos = txArray["signatures"].find_first_not_of(",", 0); std::string::size_type pos = txArray["signatures"].find_first_of(",", lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { @@ -313,27 +318,27 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // SignSignature if (std::strlen(txArray["signSignature"].c_str()) > 0) { - root["signSignature"] = txArray["signSignature"]; + doc["signSignature"] = txArray["signSignature"]; } // Timestamp - root["timestamp"] = txArray["timestamp"]; + doc["timestamp"] = txArray["timestamp"]; // Type - root["type"] = txArray["type"]; + doc["type"] = txArray["type"]; // VendorField if (std::strlen(txArray["vendorField"].c_str()) > 0) { - root["vendorField"] = txArray["vendorField"]; + doc["vendorField"] = txArray["vendorField"]; } // Version if (txArray["version"] != "0") { - root["version"] = txArray["version"]; + doc["version"] = txArray["version"]; } - char jsonChar[root.measureLength() + 1]; - root.printTo((char*)jsonChar, sizeof(jsonChar)); + char jsonChar[measureJson(doc) + 1]; + serializeJson(doc, jsonChar, measureJson(doc) + 1); return jsonChar; } diff --git a/src/utils/message.cpp b/src/utils/message.cpp index ddc32737..bdd687ee 100644 --- a/src/utils/message.cpp +++ b/src/utils/message.cpp @@ -34,14 +34,16 @@ Ark::Crypto::Utils::Message::Message( * * @return bool **/ -bool Ark::Crypto::Utils::Message::sign(std::string newMessage, const char *const passphrase) { +bool Ark::Crypto::Utils::Message::sign( + std::string newMessage, + const char *const passphrase) { this->message = newMessage; /* Get the PrivateKey */ - PrivateKey privateKey = Ark::Crypto::Identities::PrivateKey::fromPassphrase(passphrase); + auto privateKey = PrivateKey::fromPassphrase(passphrase); /* Set the PublicKey from the derived PrivateKey */ - this->publicKey = Ark::Crypto::Identities::PublicKey::fromPrivateKey(privateKey); + this->publicKey = PublicKey::fromPrivateKey(privateKey); /* Get the Hash */ const auto unsignedMessage = reinterpret_cast(message.c_str()); @@ -75,9 +77,9 @@ bool Ark::Crypto::Utils::Message::verify() { **/ std::map Ark::Crypto::Utils::Message::toArray() { return { - {"publickey", this->publicKey.toString()}, - {"signature", BytesToHex(this->signature.begin(), this->signature.end())}, - {"message", this->message} + { "publickey", this->publicKey.toString() }, + { "signature", BytesToHex(this->signature.begin(), this->signature.end()) }, + { "message", this->message } }; } /**/ @@ -90,17 +92,15 @@ std::map Ark::Crypto::Utils::Message::toArray() { std::string Ark::Crypto::Utils::Message::toJson() { std::map messageArray = this->toArray(); - const size_t capacity = JSON_OBJECT_SIZE(3); - DynamicJsonBuffer jsonBuffer(capacity); + // const size_t capacity = JSON_OBJECT_SIZE(3); + DynamicJsonDocument doc(400); - JsonObject& root = jsonBuffer.createObject(); + doc["publickey"] = messageArray["publickey"]; + doc["signature"] = messageArray["signature"]; + doc["message"] = messageArray["message"]; - root["publickey"] = messageArray["publickey"]; - root["signature"] = messageArray["signature"]; - root["message"] = messageArray["message"]; - - char jsonChar[root.measureLength() + 1]; - root.printTo((char*)jsonChar, sizeof(jsonChar)); + char jsonChar[measureJson(doc) + 1]; + serializeJson(doc, jsonChar, measureJson(doc) + 1); return jsonChar; } diff --git a/test/platformio.ini b/test/platformio.ini index c1b53faf..8b519ad4 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -15,7 +15,7 @@ lib_dir = .. [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@5.13.4 +lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@6.10.0 build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - upload_speed = 921600 diff --git a/test/transactions/transaction.cpp b/test/transactions/transaction.cpp index 3f4db81b..1870cdab 100644 --- a/test/transactions/transaction.cpp +++ b/test/transactions/transaction.cpp @@ -115,41 +115,43 @@ TEST(transactions, transaction_to_json) { std::string tJson = transfer.toJson(); const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; - DynamicJsonBuffer tJsonBuffer(tCapacity); + DynamicJsonDocument tDoc(tCapacity); - JsonObject& tRoot = tJsonBuffer.parseObject(tJson); + DeserializationError tError = deserializeJson(tDoc, tJson); + ASSERT_FALSE(tError); - ASSERT_EQ(tRoot["amount"], 1); - ASSERT_EQ(tRoot["fee"], 10000000); - ASSERT_STRNE("", tRoot["id"].as()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tRoot["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tRoot["senderPublicKey"].as()); - ASSERT_STRNE("", tRoot["signature"].as()); - ASSERT_GT(tRoot["timestamp"], 50000000); - ASSERT_LT(tRoot["timestamp"], 1000000000); - ASSERT_EQ(tRoot["type"], 0); + ASSERT_EQ(tDoc["amount"], 1); + ASSERT_EQ(tDoc["fee"], 10000000); + ASSERT_STRNE("", tDoc["id"].as()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tDoc["recipientId"].as()); + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tDoc["senderPublicKey"].as()); + ASSERT_STRNE("", tDoc["signature"].as()); + ASSERT_GT(tDoc["timestamp"], 50000000); + ASSERT_LT(tDoc["timestamp"], 1000000000); + ASSERT_EQ(tDoc["type"], 0); // Type 1 auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration("Secret passphrase", "Second Secret passphrase"); std::string ssJson = secondSignatureRegistration.toJson(); - const size_t ssCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; - DynamicJsonBuffer ssJsonBuffer(ssCapacity); + const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; + DynamicJsonDocument ssDoc(ssCapacity); - JsonObject& ssRoot = ssJsonBuffer.parseObject(ssJson); + DeserializationError ssError = deserializeJson(ssDoc, ssJson); + ASSERT_FALSE(ssError); - ASSERT_EQ(ssRoot["amount"], 0); - ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssRoot["asset"]["signature"]["publicKey"].as()); - ASSERT_EQ(ssRoot["fee"], 500000000); - ASSERT_STRNE("", ssRoot["id"].as()); - ASSERT_STREQ("", ssRoot["recipientId"].as()); - ASSERT_STRNE("", ssRoot["secondSignature"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssRoot["senderPublicKey"].as()); - ASSERT_STRNE("", ssRoot["signature"].as()); - ASSERT_GT(ssRoot["timestamp"], 50000000); - ASSERT_LT(ssRoot["timestamp"], 1000000000); - ASSERT_EQ(ssRoot["type"], 1); + ASSERT_EQ(ssDoc["amount"], 0); + ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssDoc["asset"]["signature"]["publicKey"].as()); + ASSERT_EQ(ssDoc["fee"], 500000000); + ASSERT_STRNE("", ssDoc["id"].as()); + ASSERT_STREQ("", ssDoc["recipientId"].as()); + ASSERT_STRNE("", ssDoc["secondSignature"].as()); + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssDoc["senderPublicKey"].as()); + ASSERT_STRNE("", ssDoc["signature"].as()); + ASSERT_GT(ssDoc["timestamp"], 50000000); + ASSERT_LT(ssDoc["timestamp"], 1000000000); + ASSERT_EQ(ssDoc["type"], 1); // Type 2 @@ -157,20 +159,21 @@ TEST(transactions, transaction_to_json) { std::string dJson = delegateRegistration.toJson(); const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; - DynamicJsonBuffer dJsonBuffer(dCapacity); + DynamicJsonDocument dDoc(dCapacity); - JsonObject& dRoot = dJsonBuffer.parseObject(dJson); + DeserializationError dError = deserializeJson(dDoc, dJson); + ASSERT_FALSE(dError); - ASSERT_EQ(dRoot["amount"], 0); - ASSERT_STREQ("testName", dRoot["asset"]["delegate"]["username"].as()); - ASSERT_EQ(dRoot["fee"], 2500000000); - ASSERT_STRNE("", dRoot["id"].as()); - ASSERT_STREQ("", dRoot["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dRoot["senderPublicKey"].as()); - ASSERT_STRNE("", dRoot["signature"].as()); - ASSERT_GT(dRoot["timestamp"], 50000000); - ASSERT_LT(dRoot["timestamp"], 1000000000); - ASSERT_EQ(dRoot["type"], 2); + ASSERT_EQ(dDoc["amount"], 0); + ASSERT_STREQ("testName", dDoc["asset"]["delegate"]["username"].as()); + ASSERT_EQ(dDoc["fee"], 2500000000); + ASSERT_STRNE("", dDoc["id"].as()); + ASSERT_STREQ("", dDoc["recipientId"].as()); + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dDoc["senderPublicKey"].as()); + ASSERT_STRNE("", dDoc["signature"].as()); + ASSERT_GT(dDoc["timestamp"], 50000000); + ASSERT_LT(dDoc["timestamp"], 1000000000); + ASSERT_EQ(dDoc["type"], 2); // Type 3 @@ -178,20 +181,21 @@ TEST(transactions, transaction_to_json) { auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); std::string vJson = vote.toJson(); - const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 540; - DynamicJsonBuffer vJsonBuffer(vCapacity); - - JsonObject& vRoot = vJsonBuffer.parseObject(vJson); - - ASSERT_EQ(vRoot["amount"], 0); - ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vRoot["asset"]["votes"][0].as()); - ASSERT_STREQ("+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vRoot["asset"]["votes"][1].as()); - ASSERT_EQ(vRoot["fee"], 100000000); - ASSERT_STRNE("", vRoot["id"].as()); - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vRoot["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vRoot["senderPublicKey"].as()); - ASSERT_STRNE("", vRoot["signature"].as()); - ASSERT_GT(vRoot["timestamp"], 50000000); - ASSERT_LT(vRoot["timestamp"], 1000000000); - ASSERT_EQ(vRoot["type"], 3); + const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 700; + DynamicJsonDocument vDoc(vCapacity); + + DeserializationError vError = deserializeJson(vDoc, vJson); + ASSERT_FALSE(vError); + + ASSERT_EQ(vDoc["amount"], 0); + ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][0].as()); + ASSERT_STREQ("+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][1].as()); + ASSERT_EQ(vDoc["fee"], 100000000); + ASSERT_STRNE("", vDoc["id"].as()); + ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vDoc["recipientId"].as()); + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vDoc["senderPublicKey"].as()); + ASSERT_STRNE("", vDoc["signature"].as()); + ASSERT_GT(vDoc["timestamp"], 50000000); + ASSERT_LT(vDoc["timestamp"], 1000000000); + ASSERT_EQ(vDoc["type"], 3); }; From 14a8b1994b67dd9a71d682f0373185d4f7b9f0ea Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 20 May 2019 19:53:00 -0700 Subject: [PATCH 06/29] fix: improve Windows support. (#83) Windows doesn't handle dynamic allocation well. - transaction.cpp - explicitly define est. doc max size of 900. - No need for string since we're stating size. - message.cpp - let string handle doc size allocation. --- CHANGELOG.md | 2 ++ src/transactions/transaction.cpp | 7 ++++--- src/utils/message.cpp | 16 +++++++++++----- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 492e3e23..439e5550 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +- improved Windows support ([#83]) + ## [0.3.1] - 2019-02-19 ### Fixed diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index f72c1841..1c419a23 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -234,7 +234,8 @@ std::map Ark::Crypto::Transactions::Transaction::toArr std::string Ark::Crypto::Transactions::Transaction::toJson() { std::map txArray = this->toArray(); - DynamicJsonDocument doc(900); + const size_t docCapacity = 900; + DynamicJsonDocument doc(docCapacity); // Amount doc["amount"] = txArray["amount"]; @@ -337,8 +338,8 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { doc["version"] = txArray["version"]; } - char jsonChar[measureJson(doc) + 1]; - serializeJson(doc, jsonChar, measureJson(doc) + 1); + char jsonChar[docCapacity]; + serializeJson(doc, jsonChar, docCapacity); return jsonChar; } diff --git a/src/utils/message.cpp b/src/utils/message.cpp index bdd687ee..916fc0d4 100644 --- a/src/utils/message.cpp +++ b/src/utils/message.cpp @@ -92,16 +92,22 @@ std::map Ark::Crypto::Utils::Message::toArray() { std::string Ark::Crypto::Utils::Message::toJson() { std::map messageArray = this->toArray(); - // const size_t capacity = JSON_OBJECT_SIZE(3); - DynamicJsonDocument doc(400); + const size_t docLength + = (33 + 1) // publickey length + + (72 + 1) // signature length + + this->message.length(); + const size_t docCapacity = JSON_OBJECT_SIZE(3) + docLength + 120; + + DynamicJsonDocument doc(docCapacity); doc["publickey"] = messageArray["publickey"]; doc["signature"] = messageArray["signature"]; doc["message"] = messageArray["message"]; - char jsonChar[measureJson(doc) + 1]; - serializeJson(doc, jsonChar, measureJson(doc) + 1); + std::string jsonStr; + jsonStr.reserve(docCapacity); + serializeJson(doc, &jsonStr[0], docCapacity); - return jsonChar; + return jsonStr; } /**/ From bcc4aa86a519d76920e00fba29303e44af4fd4f9 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 20 May 2019 19:58:27 -0700 Subject: [PATCH 07/29] chore: disable PlatformIO ESP8266 Tests (#87) AUnit has stopped correctly building tests for the partially-supported ESP8266 platform. It seems this may be a change in ESP8266 Core, so this PR disables ESP8266 tests in PlatformIO until support is worked out. --- CHANGELOG.md | 2 ++ test/platformio.ini | 19 ++++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 439e5550..1932f336 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +### Changed + - improved Windows support ([#83]) ## [0.3.1] - 2019-02-19 diff --git a/test/platformio.ini b/test/platformio.ini index 8b519ad4..a03ad134 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -20,15 +20,16 @@ build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto - src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - upload_speed = 921600 -[env:esp8266] -platform = espressif8266 -board = huzzah -framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} -lib_deps = ${common.lib_deps} -build_flags = ${common.build_flags} -src_filter = ${common.src_filter} -upload_speed = ${common.upload_speed} +# esp8266 unit tests disabled until support is worked out +#[env:esp8266] +#platform = espressif8266 +#board = huzzah +#framework = arduino +#lib_ldf_mode = ${common.lib_ldf_mode} +#lib_deps = ${common.lib_deps} +#build_flags = ${common.build_flags} +#src_filter = ${common.src_filter} +#upload_speed = ${common.upload_speed} [env:esp32] platform = espressif32 From f88815acc11064f006c27ba52cfe987002216771 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 20 May 2019 19:58:56 -0700 Subject: [PATCH 08/29] feat: Increase VendorField Size (#84) --- CHANGELOG.md | 8 +++++++- library.json | 2 +- library.properties | 2 +- src/transactions/transaction.cpp | 3 +-- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1932f336..72e4b14c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [0.4.0] - 2019-05-20 + +### Changed + +- updated vendorField to support 255 bytes in Core v2.4 ([#84]) +- updated ArduinoJson package to version v.6.10.0 ([#76]) +- updated tests to use Core fixtures ([#74]) ### Changed diff --git a/library.json b/library.json index f4404dd3..9cb19d62 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Crypto.git" }, - "version": "0.3.1", + "version": "0.4.0", "authors": [ { "name": "Ark Ecosystem", diff --git a/library.properties b/library.properties index f9450d1b..c9ac8409 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Crypto -version=0.3.1 +version=0.4.0 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple Cryptography Implementation in C++ for the ARK Blockchain. diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index 1c419a23..c174a177 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -87,7 +87,7 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); } - if (!this->vendorField.empty()) { + if (!this->vendorField.empty() && vendorField.length() <= 255) { bytes.insert(std::end(bytes), std::begin(this->vendorField), std::end(this->vendorField)); size_t diff = 64 - vendorField.length(); @@ -95,7 +95,6 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( std::vector filler(diff, 0); bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); } - } else { std::vector filler(64, 0); bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); From 4ea120b47c111403e31aca0cf1e79f3c0fd8cddb Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 20 May 2019 19:59:15 -0700 Subject: [PATCH 09/29] fix: 0 ARKtoshi amount handling (#85) --- CHANGELOG.md | 3 +++ src/include/cpp-crypto/transactions/builder.h | 9 +++++++++ src/transactions/builder.cpp | 2 ++ src/transactions/transaction.cpp | 4 ++++ test/transactions/builder.cpp | 10 ++++++++++ 5 files changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e4b14c..eb1308b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed +### Changed + +- properly handle 0 ARKtoshi Transaction amounts. - improved Windows support ([#83]) ## [0.3.1] - 2019-02-19 diff --git a/src/include/cpp-crypto/transactions/builder.h b/src/include/cpp-crypto/transactions/builder.h index 665a3469..bf69dde0 100644 --- a/src/include/cpp-crypto/transactions/builder.h +++ b/src/include/cpp-crypto/transactions/builder.h @@ -18,8 +18,17 @@ namespace Transactions { class Builder { public: + /** + * Builder::buildTransfer() + * + * note: The 'Type 0'/Transfer amount must be greater than 0 ARKtoshi. + * If amount is not > 0, Builder will return an empty Transaction object and + * validation will fail. + **/ static Transaction buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, std::string passphrase, std::string secondPassphrase = ""); + /**/ + static Transaction buildSecondSignatureRegistration(std::string passphrase, std::string secondPassphrase = ""); static Transaction buildDelegateRegistration(std::string username, std::string passphrase, std::string secondPassphrase = ""); diff --git a/src/transactions/builder.cpp b/src/transactions/builder.cpp index 9f1736d4..f6775358 100644 --- a/src/transactions/builder.cpp +++ b/src/transactions/builder.cpp @@ -13,6 +13,8 @@ namespace Transactions { Transaction Builder::buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, std::string passphrase, std::string secondPassphrase) { Transaction transaction; + if (amount < 1ull) { return transaction; }; + transaction.type = Enums::Types::TRANSFER; transaction.fee = Configuration::Fee().get(Enums::Types::TRANSFER); transaction.recipientId = std::move(recipientId); diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index c174a177..5c8fe64e 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -58,6 +58,8 @@ bool Ark::Crypto::Transactions::Transaction::internalVerify( std::string publicKey, std::vector bytes, std::string signature) const { + if (bytes.empty()) { return false; }; + const auto hash = Sha256::getHash(&bytes[0], bytes.size()); const auto key = Identities::PublicKey::fromHex(publicKey.c_str()); auto signatureBytes = HexToBytes(signature.c_str()); @@ -69,6 +71,8 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( bool skipSecondSignature) const { std::vector bytes; + if (this->type == 0 && amount < 1ull) { return bytes; }; + pack(bytes, this->type); pack(bytes, this->timestamp); diff --git a/test/transactions/builder.cpp b/test/transactions/builder.cpp index 35ce86f3..034f8bfe 100644 --- a/test/transactions/builder.cpp +++ b/test/transactions/builder.cpp @@ -13,4 +13,14 @@ TEST(transactions, build_transfer) { ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); ASSERT_TRUE(100000000 == actual.amount); ASSERT_STREQ("", actual.vendorField.c_str()); + + // test 0 ARKtoshi value + const auto shouldBeEmpty = Ark::Crypto::Transactions::Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 0, + "", + "Secret passphrase"); + ASSERT_STREQ("", shouldBeEmpty.recipientId.c_str()); + ASSERT_EQ(0, shouldBeEmpty.amount); + ASSERT_FALSE(shouldBeEmpty.verify()); } From 453f87f66ffb54fc063b02b681c42c114793fdd5 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 20 May 2019 20:01:14 -0700 Subject: [PATCH 10/29] chore(ci): setup Appveyor (#89) --- .appveyor.yml | 20 ++++++++++++++++++++ CHANGELOG.md | 6 ++---- 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 .appveyor.yml diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..62c568dd --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,20 @@ +version: 1.0.{build} + +image: Visual Studio 2017 + +environment: + matrix: + - CONFIGURATION: Debug + - CONFIGURATION: Release + +install: + - git submodule update --init --recursive + +before_build: + - cmake -G "Visual Studio 15 2017 Win64" . + +build: + project: $(APPVEYOR_BUILD_FOLDER)\Ark-Cpp-Crypto.sln + +test_script: + - cmd: '%APPVEYOR_BUILD_FOLDER%\test\%CONFIGURATION%\Ark-Cpp-Crypto-tests.exe' diff --git a/CHANGELOG.md b/CHANGELOG.md index eb1308b5..5a4cd161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,13 +12,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - updated vendorField to support 255 bytes in Core v2.4 ([#84]) - updated ArduinoJson package to version v.6.10.0 ([#76]) - updated tests to use Core fixtures ([#74]) +- improved Windows support ([#83]) -### Changed - -### Changed +### Fixed - properly handle 0 ARKtoshi Transaction amounts. -- improved Windows support ([#83]) ## [0.3.1] - 2019-02-19 From 3f20868d9cf50e38366af4689a1d3af475f73425 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 23 May 2019 19:47:32 -0700 Subject: [PATCH 11/29] refactor: Use BIP66 Library (#88) --- .circleci/script_arduino.sh | 1 + .gitmodules | 3 + CHANGELOG.md | 3 +- extras/ARDUINO_IDE.sh | 5 +- platformio.ini | 4 +- src/CMakeLists.txt | 7 +- src/helpers/crypto.cpp | 22 +- src/helpers/encoding/der.cpp | 111 --------- src/include/cpp-crypto/helpers/encoding/der.h | 35 --- src/lib/BIP66 | 1 + test/CMakeLists.txt | 1 - test/helpers/encoding/der.cpp | 220 ------------------ test/platformio.ini | 4 +- 13 files changed, 30 insertions(+), 387 deletions(-) delete mode 100644 src/helpers/encoding/der.cpp delete mode 100644 src/include/cpp-crypto/helpers/encoding/der.h create mode 160000 src/lib/BIP66 delete mode 100644 test/helpers/encoding/der.cpp diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index a0d36579..87107574 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -6,5 +6,6 @@ mkdir -p ~/Arduino/libraries/cpp-crypto/ mv ~/project/* ~/Arduino/libraries/cpp-crypto arduino-cli lib install "ArduinoJson@6.10.0" +arduino-cli lib install "BIP66" arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/arduino/ESP32/ESP32.ino --debug diff --git a/.gitmodules b/.gitmodules index 164236c2..398e14cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "src/lib/ArduinoJson"] path = src/lib/ArduinoJson url = https://github.com/bblanchon/ArduinoJson +[submodule "src/lib/BIP66"] + path = src/lib/BIP66 + url = https://github.com/sleepdefic1t/BIP66 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a4cd161..d04e81a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed +- changed to BIP66 lib for DER ser/des. ([#88]) - updated vendorField to support 255 bytes in Core v2.4 ([#84]) - updated ArduinoJson package to version v.6.10.0 ([#76]) - updated tests to use Core fixtures ([#74]) @@ -16,7 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed -- properly handle 0 ARKtoshi Transaction amounts. +- properly handle 0 ARKtoshi Transaction amounts. ([#85]) ## [0.3.1] - 2019-02-19 diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index d296f211..4ed924ce 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -112,8 +112,8 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_ENUMS_DIR}/types.h ${SRC_ENUMS_DIR} echo -e "Moving 'helpers' headers.\n" - mv ${INCLUDE_HELPERS_DIR}/encoding/der.h ${SRC_HELPERS_DIR}/encoding - mv ${INCLUDE_HELPERS_DIR}/encoding/hex.h ${SRC_HELPERS_DIR}/encoding + mkdir ${SRC_ENCODING_DIR} + mv ${INCLUDE_HELPERS_DIR}/encoding/hex.h ${SRC_ENCODING_DIR} ## 'bip39' library is not supported in Arduino echo -e "Backing up and removing 'mnemonic.h'.\n" @@ -192,6 +192,7 @@ else echo -e "Moving 'helpers/encoding' headers.\n" mv ${SRC_ENCODING_DIR}/hex.h ${INCLUDE_ENCODING_DIR} + rm ${SRC_ENCODING_DIR} echo -e "Moving 'identities' headers.\n" mv ${SRC_IDENTITIES_DIR}/address.h ${INCLUDE_IDENTITIES_DIR} diff --git a/platformio.ini b/platformio.ini index 522182d1..8cc3220f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,9 +13,9 @@ description = "A simple Cryptography Implementation in C++ for the ARK Blockchai [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, ArduinoJson@6.10.0 +lib_deps = micro-ecc, bip39@^1.1, ArduinoJson@6.10.0, BIP66 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - - - - - +src_filter = +<*> -<.git/> - - - - - - upload_speed = 921600 [env:esp8266] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efca42da..7e1c1144 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,10 @@ project(Ark-Cpp-Crypto-lib C CXX) add_subdirectory(lib/bip39/src) +set(BIP66_SRC + ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp +) + set(BCL_SRC lib/bcl/Base58Check.cpp lib/bcl/CurvePoint.cpp @@ -26,7 +30,6 @@ set(COMMON_SRC configuration/fee.cpp configuration/network.cpp helpers/crypto.cpp - helpers/encoding/der.cpp identities/address.cpp identities/mnemonic.cpp identities/privatekey.cpp @@ -45,6 +48,7 @@ add_library(${PROJECT_NAME} STATIC ${BCL_SRC} ${uECC_SRC} + ${BIP66_SRC} ${COMMON_SRC} ) @@ -59,6 +63,7 @@ include_directories(${PROJECT_SOURCE_DIR}/lib/bcl) include_directories(${PROJECT_SOURCE_DIR}/lib/bip39) include_directories(${PROJECT_SOURCE_DIR}/lib/rfc6979) include_directories(${PROJECT_SOURCE_DIR}/lib/uECC) +include_directories(${PROJECT_SOURCE_DIR}/lib/BIP66/src) target_include_directories( ${PROJECT_NAME} PUBLIC ${cpp_crypto_build_include_dirs} diff --git a/src/helpers/crypto.cpp b/src/helpers/crypto.cpp index 508c744d..79494fae 100644 --- a/src/helpers/crypto.cpp +++ b/src/helpers/crypto.cpp @@ -4,10 +4,10 @@ #include "bcl/Ecdsa.hpp" #include "bcl/Sha256.hpp" #include "bcl/Uint256.hpp" -#include "helpers/encoding/der.h" #include "helpers/crypto_helpers.h" #include "rfc6979/rfc6979.h" #include "uECC.h" +#include "bip66.h" void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, std::vector& signature) { Uint256 r; @@ -19,13 +19,11 @@ void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, auto ret = Ecdsa::sign(Uint256(privateKey.toBytes()), hash, Uint256(nonce32), r, s); assert(ret); - std::vector r_der(PRIVATEKEY_SIZE); - r.getBigEndianBytes(&r_der[0]); + std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); + r.getBigEndianBytes(&rValue[0]); + s.getBigEndianBytes(&sValue[0]); - std::vector s_der(PRIVATEKEY_SIZE); - s.getBigEndianBytes(&s_der[0]); - - encodeDER(toDER(r_der), toDER(s_der), signature); + BIP66::encode(rValue, sValue, signature); } bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, std::vector& signature) { @@ -52,12 +50,12 @@ bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, CurvePoint curvePoint(x, y); /* Decode signature from DER into r & s buffers */ - std::vector r; // create r-value buffer - std::vector s; // create s-value buffer - decodeDER(signature, r, s); + std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); + + BIP66::decode(signature, rValue, sValue); - Uint256 r256(r.data()); // create Uint256/BigNumber from r-value buffer - Uint256 s256(s.data()); // create Uint256/BigNumber from s-value buffer + Uint256 r256(rValue.data()); // create Uint256/BigNumber from r-value buffer + Uint256 s256(sValue.data()); // create Uint256/BigNumber from s-value buffer /* Verify */ return Ecdsa::verify(curvePoint, hash, r256, s256); diff --git a/src/helpers/encoding/der.cpp b/src/helpers/encoding/der.cpp deleted file mode 100644 index 9265a315..00000000 --- a/src/helpers/encoding/der.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "helpers/encoding/der.h" - -#include -#include -#include -#include - -/** - * DER Encode/Decode Helpers - **/ -std::vector& toDER(std::vector& buffer) { - // if the sign bit is set, pad with a 0x00 byte - if (buffer.size() > 1 && (buffer[0] & 0x80) != 0) { - buffer.insert(buffer.begin(), 0x00); - } - return buffer; -} - -/**/ - -void decodeDER(std::vector& signature, std::vector& r, std::vector& s) { - // Adapted from https://github.com/bitcoinjs/bip66/blob/master/index.js - assert(signature.size() > 8); // DER sequence length is too short - assert(signature.size() < 72); // DER sequence length is too long - assert(signature[0] == 0x30); // Expected DER sequence - assert(signature[1] == signature.size() - 2); // DER sequence length is invalid - assert(signature[2] == 0x02); // Expected DER integer - - /* Get the length of the signatures R-value (signature 4th-byte/signature[3]) */ - int lenR = signature[3]; - assert(lenR != 0); // R length is zero - assert(5u + lenR <= signature.size()); // R length is too long - assert(signature[4 + lenR] == 0x02); // Expected DER integer (2) - - /* Get the length of the signatures R-value (signature 6th-byte/signature[5]) */ - int lenS = signature[5 + lenR]; - assert(lenS != 0); // S length is zero - assert((6u + lenR + lenS) == signature.size()); // S length is invalid - - assert(signature[4] != 0x80); // R value is negative - assert((lenR > 1)); // && (signature[4] == 0x00) && !(signature[5] == 0x80)); // R value excessively padded - - assert(signature[lenR + 6] != 0x80); // S value is negative - assert(lenS > - 1); // && (signature[lenR + 6] != 0x00) && !(signature[lenR + 7] == 0x80)); // S value excessively padded - - /* non-BIP66 - extract R, S values */ - r = std::vector(&signature[4], &signature[4] + lenR); - s = std::vector(&signature[6 + lenR], &signature[6 + lenR] + lenS); -} - -/**/ - -void encodeDER(const std::vector& r, const std::vector& s, std::vector& signature) { - /* Adapted from https://github.com/bitcoinjs/bip66/blob/master/index.js */ - auto lenR = r.size(); - auto lenS = s.size(); - assert(lenR != 0); // must be non zero - assert(lenS != 0); - assert(lenR <= 33); // must be less than 34 bytes - assert(lenS <= 33); - assert((r[0] & 0x80) == 0); // must not be negative - assert((s[0] & 0x80) == 0); - assert(lenR == 1 || r[0] != 0x00 || (r[1] & 0x80) != 0); // must have zero pad for negative number - assert(lenS == 1 || s[0] != 0x00 || (s[1] & 0x80) != 0); - - auto it = r.begin(); - while (lenR > 1 && *it == 0 && *(it + 1) < 0x80) { - --lenR; - ++it; - } - it = s.begin(); - while (lenS > 1 && *it == 0 && *(it + 1) < 0x80) { - --lenS; - ++it; - } - - signature.clear(); - signature.reserve(6 + lenR + lenS); - - /* 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S] */ - signature.push_back(0x30); // [0] - signature.push_back(static_cast(6 + lenR + lenS - 2)); // [1] - signature.push_back(0x02); // [2] - signature.push_back(static_cast(lenR)); // [3] - signature.insert(signature.end(), r.begin(), r.end()); //[4] - signature.push_back(0x02); // [4 + lenR] - signature.push_back(static_cast(lenS)); // [5 + lenR] - signature.insert(signature.end(), s.begin(), s.end()); //[6 + lenR] -} - -/**/ - -void encodeDER(uint8_t packed_signature[DEFAULT_PRIVATEKEY_SIZE * 2], std::vector& signature) { - std::vector r(DEFAULT_PRIVATEKEY_SIZE); - std::vector s(DEFAULT_PRIVATEKEY_SIZE); - - memcpy(&r[0], packed_signature, DEFAULT_PRIVATEKEY_SIZE); - memcpy(&s[0], packed_signature + DEFAULT_PRIVATEKEY_SIZE, DEFAULT_PRIVATEKEY_SIZE); - - encodeDER(toDER(r), toDER(s), signature); -} diff --git a/src/include/cpp-crypto/helpers/encoding/der.h b/src/include/cpp-crypto/helpers/encoding/der.h deleted file mode 100644 index 8d3c67b2..00000000 --- a/src/include/cpp-crypto/helpers/encoding/der.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef DER_H -#define DER_H - -#include -#include - -const auto DEFAULT_PRIVATEKEY_SIZE = 32u; - -/** - * DER Encode/Decode Helpers - **/ -std::vector& toDER(std::vector& buffer); - -/**/ - -void decodeDER(std::vector& signature, std::vector& r, std::vector& s); - -/**/ - -void encodeDER(const std::vector& r, const std::vector& s, std::vector& signature); - -/**/ - -void encodeDER(uint8_t packed_signature[DEFAULT_PRIVATEKEY_SIZE * 2], std::vector& signature); - -#endif diff --git a/src/lib/BIP66 b/src/lib/BIP66 new file mode 160000 index 00000000..5f024b4b --- /dev/null +++ b/src/lib/BIP66 @@ -0,0 +1 @@ +Subproject commit 5f024b4b70fb0d267da483304afb72bb884413cb diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5739a897..9cb1b7d4 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -23,7 +23,6 @@ set (TEST_SRC ${PROJECT_SOURCE_DIR}/configuration/network.cpp ${PROJECT_SOURCE_DIR}/enums/fees.cpp ${PROJECT_SOURCE_DIR}/enums/types.cpp - ${PROJECT_SOURCE_DIR}/helpers/encoding/der.cpp ${PROJECT_SOURCE_DIR}/identities/address.cpp ${PROJECT_SOURCE_DIR}/identities/mnemonic.cpp ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp diff --git a/test/helpers/encoding/der.cpp b/test/helpers/encoding/der.cpp deleted file mode 100644 index 6a94c19c..00000000 --- a/test/helpers/encoding/der.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "gtest/gtest.h" - -#include "helpers/encoding/der.h" -#include "helpers/encoding/hex.h" - -TEST(helpers_encoding_der, decodeDER) { - auto signature = HexToBytes( - "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b" - "7db4d5fdf0071de069fa54342262"); - std::vector r; - std::vector s; - - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("33A69CD2065432A30F3D1CE4EB0D59B8AB58C74F27C41A7FDB5696AD4E6108C9", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("6F807982866F785D3F6418D24163DDAE117B7DB4D5FDF0071DE069FA54342262", BytesToHex(s).c_str()); - - signature = HexToBytes( - "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7d" - "b55a07e9861d1fb3cb1f421044a5"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("54C4A33C6423D689378F160A7FF8B61330444ABB58FB470F96EA16D99D4A2FED", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("07082304410EFA6B2943111B6A4E0AAA7B7DB55A07E9861D1FB3CB1F421044A5", BytesToHex(s).c_str()); - - signature = HexToBytes( - "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc771514" - "55d46ed48f5589b7db7771a332b283"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("00FF466A9F1B7B273E2F4C3FFE032EB2E814121ED18EF84665D0F515360DAB3DD0", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("6FC95F5132E5ECFDC8E5E6E616CC77151455D46ED48F5589B7DB7771A332B283", BytesToHex(s).c_str()); - - signature = HexToBytes( - "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa15" - "5847f614d80078a90292fe205064d3"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("00C0DAFEC8251F1D5010289D210232220B03202CBA34EC11FEC58B3E93A85B91D3", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("75AFDC06B7D6322A590955BF264E7AAA155847F614D80078A90292FE205064D3", BytesToHex(s).c_str()); - - signature = HexToBytes( - "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e85" - "4c86d58abdd00c46c16441085df6"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("7186363571D65E084E7F02B0B77C3EC44FB1B257DEE26274C38C928986FEA45D", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("0DE0B38E06807E46BDA1F1E293F4F6323E854C86D58ABDD00C46C16441085DF6", BytesToHex(s).c_str()); - - signature = HexToBytes( - "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b8" - "2da89baa5b895f612619edf34cbd37"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("00FBFE5076A15860BA8ED00E75E9BD22E05D230F02A936B653EB55B61C99DDA487", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("0E68880EBB0050FE4312B1B1EB0899E1B82DA89BAA5B895F612619EDF34CBD37", BytesToHex(s).c_str()); - - signature = HexToBytes( - "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11" - "ec4661cc38cd8badf90115fbd03cef"); - decodeDER(signature, r, s); - ASSERT_STRCASEEQ("00CDE1302D83F8DD835D89AEF803C74A119F561FBAEF3EB9129E45F30DE86ABBF9", BytesToHex(r).c_str()); - ASSERT_STRCASEEQ("06CE643F5049EE1F27890467B77A6A8E11EC4661CC38CD8BADF90115FBD03CEF", BytesToHex(s).c_str()); -} - -TEST(helpers_encoding_der, encodeDER) { - auto r = HexToBytes( - "33A69CD2065432A30F3D1CE4EB0D59B8AB58C74F27C41A7FDB5696AD4E6108C9"); // dec: - // 23362334225185207751494092901091441011938859014081160902781146257181456271561 - auto s = HexToBytes( - "6F807982866F785D3F6418D24163DDAE117B7DB4D5FDF0071DE069FA54342262"); // dec: - // 50433721247292933944369538617440297985091596895097604618403996029256432099938 - std::vector signature; - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b" - "7db4d5fdf0071de069fa54342262", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "54C4A33C6423D689378F160A7FF8B61330444ABB58FB470F96EA16D99D4A2FED"); // dec: - // 38341707918488238920692284707283974715538935465589664377561695343399725051885 - s = HexToBytes( - "07082304410EFA6B2943111B6A4E0AAA7B7DB55A07E9861D1FB3CB1F421044A5"); // dec: - // 3180566392414476763164587487324397066658063772201694230600609996154610926757 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7d" - "b55a07e9861d1fb3cb1f421044a5", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "FF466A9F1B7B273E2F4C3FFE032EB2E814121ED18EF84665D0F515360DAB3DD0"); // dec: - // 115464191557905790016094131873849783294273568009648050793030031933291767741904 - s = HexToBytes( - "6FC95F5132E5ECFDC8E5E6E616CC77151455D46ED48F5589B7DB7771A332B283"); // dec: - // 50562520307781850052192542766631199590053690478900449960232079510155113443971 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc771514" - "55d46ed48f5589b7db7771a332b283", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "C0DAFEC8251F1D5010289D210232220B03202CBA34EC11FEC58B3E93A85B91D3"); // dec: - // 87230998027579607140680851455601772643840468630989315269459846730712163783123 - s = HexToBytes( - "75AFDC06B7D6322A590955BF264E7AAA155847F614D80078A90292FE205064D3"); // dec: - // 53231320085894623106179381504478252331065330583563809963303318469380290929875 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa15" - "5847f614d80078a90292fe205064d3", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "7186363571D65E084E7F02B0B77C3EC44FB1B257DEE26274C38C928986FEA45D"); // dec: - // 51348483531757779992459563033975330355971795607481991320287437101831125115997 - s = HexToBytes( - "0DE0B38E06807E46BDA1F1E293F4F6323E854C86D58ABDD00C46C16441085DF6"); // dec: - // 6277080015686056199074771961940657638578000617958603212944619747099038735862 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e85" - "4c86d58abdd00c46c16441085df6", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "FBFE5076A15860BA8ED00E75E9BD22E05D230F02A936B653EB55B61C99DDA487"); // dec: - // 113979859486826658566290715281614250298918272782414232881639314569529560769671 - s = HexToBytes( - "0E68880EBB0050FE4312B1B1EB0899E1B82DA89BAA5B895F612619EDF34CBD37"); // dec: - // 6517071009538626957379450615706485096874328019806177698938278220732027419959 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b8" - "2da89baa5b895f612619edf34cbd37", - BytesToHex(signature).c_str()); - - r = HexToBytes( - "CDE1302D83F8DD835D89AEF803C74A119F561FBAEF3EB9129E45F30DE86ABBF9"); // dec: - // 93122007060065279508564838030979550535085999589142852106617159184757394422777 - s = HexToBytes( - "06CE643F5049EE1F27890467B77A6A8E11EC4661CC38CD8BADF90115FBD03CEF"); // dec: - // 3078539468410661027472930027406594684630312677495124015420811882501887769839 - encodeDER(toDER(r), toDER(s), signature); - ASSERT_STRCASEEQ( - "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11" - "ec4661cc38cd8badf90115fbd03cef", - BytesToHex(signature).c_str()); -} - -TEST(helpers_encoding_der_packed, encodeDER) { - auto packed_signature = HexToBytes( - "33A69CD2065432A30F3D1CE4EB0D59B8AB58C74F27C41A7FDB5696AD4E6108C96F807982866F785D3F6418D24163DDAE117B7DB4D5FDF007" - "1DE069FA54342262"); - std::vector signature; - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b" - "7db4d5fdf0071de069fa54342262", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "54C4A33C6423D689378F160A7FF8B61330444ABB58FB470F96EA16D99D4A2FED07082304410EFA6B2943111B6A4E0AAA7B7DB55A07E9861D" - "1FB3CB1F421044A5"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7d" - "b55a07e9861d1fb3cb1f421044a5", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "FF466A9F1B7B273E2F4C3FFE032EB2E814121ED18EF84665D0F515360DAB3DD06FC95F5132E5ECFDC8E5E6E616CC77151455D46ED48F5589" - "B7DB7771A332B283"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc771514" - "55d46ed48f5589b7db7771a332b283", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "C0DAFEC8251F1D5010289D210232220B03202CBA34EC11FEC58B3E93A85B91D375AFDC06B7D6322A590955BF264E7AAA155847F614D80078" - "A90292FE205064D3"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa15" - "5847f614d80078a90292fe205064d3", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "7186363571D65E084E7F02B0B77C3EC44FB1B257DEE26274C38C928986FEA45D0DE0B38E06807E46BDA1F1E293F4F6323E854C86D58ABDD0" - "0C46C16441085DF6"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e85" - "4c86d58abdd00c46c16441085df6", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "FBFE5076A15860BA8ED00E75E9BD22E05D230F02A936B653EB55B61C99DDA4870E68880EBB0050FE4312B1B1EB0899E1B82DA89BAA5B895F" - "612619EDF34CBD37"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b8" - "2da89baa5b895f612619edf34cbd37", - BytesToHex(signature).c_str()); - - packed_signature = HexToBytes( - "CDE1302D83F8DD835D89AEF803C74A119F561FBAEF3EB9129E45F30DE86ABBF906CE643F5049EE1F27890467B77A6A8E11EC4661CC38CD8B" - "ADF90115FBD03CEF"); - encodeDER(&packed_signature[0], signature); - ASSERT_STRCASEEQ( - "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11" - "ec4661cc38cd8badf90115fbd03cef", - BytesToHex(signature).c_str()); -} diff --git a/test/platformio.ini b/test/platformio.ini index a03ad134..bcfd048e 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -15,9 +15,9 @@ lib_dir = .. [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@6.10.0 +lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@6.10.0, BIP66 build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - +src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - - upload_speed = 921600 # esp8266 unit tests disabled until support is worked out From 8396209835c062cfb70d60dcd46937c1b1fbb941 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 24 May 2019 20:08:58 -0700 Subject: [PATCH 12/29] refactor: Remove bip39 library (#86) --- .gitmodules | 3 - CHANGELOG.md | 6 + docs/INSTALL_PLATFORMIO.md | 4 +- docs/cpp.md | 12 -- examples/cmake_example/main.cpp | 5 - examples/platformio_example/src/main.ino | 5 - extras/ARDUINO_IDE.sh | 20 --- keywords.txt | 1 - library.json | 5 +- library.properties | 2 +- platformio.ini | 2 +- src/CMakeLists.txt | 6 - src/identities/mnemonic.cpp | 43 ----- src/include/cpp-crypto/arkCrypto.h | 1 - src/include/cpp-crypto/identities/mnemonic.h | 30 ---- src/lib/bip39 | 1 - test/CMakeLists.txt | 1 - test/identities/mnemonic.cpp | 169 ------------------- test/platformio.ini | 2 +- 19 files changed, 12 insertions(+), 306 deletions(-) delete mode 100644 src/identities/mnemonic.cpp delete mode 100644 src/include/cpp-crypto/identities/mnemonic.h delete mode 160000 src/lib/bip39 delete mode 100644 test/identities/mnemonic.cpp diff --git a/.gitmodules b/.gitmodules index 398e14cd..cce2097f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "src/lib/uECC"] path = src/lib/uECC url = https://github.com/kmackay/micro-ecc -[submodule "src/lib/bip39"] - path = src/lib/bip39 - url = https://github.com/ciband/bip39.git [submodule "test/lib/googletest"] path = test/lib/googletest url = https://github.com/google/googletest.git diff --git a/CHANGELOG.md b/CHANGELOG.md index d04e81a0..900370c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [0.5.0] - 2019-02-20 + +### Changed + +- removed bip39 and mnemonic feature ([#86]) + ## [0.4.0] - 2019-05-20 ### Changed diff --git a/docs/INSTALL_PLATFORMIO.md b/docs/INSTALL_PLATFORMIO.md index 7466e153..f1eab693 100644 --- a/docs/INSTALL_PLATFORMIO.md +++ b/docs/INSTALL_PLATFORMIO.md @@ -18,8 +18,8 @@ or also install platformio dependencies: -> install AUnit (2778), micro-ecc (1665) bip39 (5886) ArduinoJson@6.10.0 libraries ->```platformio lib -g install 2778 1665 5886 ArduinoJson@6.10.0``` +> install AUnit (2778), micro-ecc (1665) ArduinoJson@6.10.0 libraries +>```platformio lib -g install 2778 1665 ArduinoJson@6.10.0``` # diff --git a/docs/cpp.md b/docs/cpp.md index ed031d48..14ebd569 100644 --- a/docs/cpp.md +++ b/docs/cpp.md @@ -68,18 +68,6 @@ message.verify(); ## Identities -### Passphrase - -#### Generate a default passphrase with 12 words in English -```cpp -const auto passphrase = Ark::Crypto::Identies::Mnemonic::generate(); -``` - -#### Generate a passphrase with the given language and 24 words -```cpp -const auto passphrase = Ark::Crypto::Identies::Mnemonic::generate(24, Ark::Crypto::Identies::Language::en); -``` - ### Address #### Get an address from a passphrase diff --git a/examples/cmake_example/main.cpp b/examples/cmake_example/main.cpp index 240df745..b42f2bac 100644 --- a/examples/cmake_example/main.cpp +++ b/examples/cmake_example/main.cpp @@ -34,11 +34,6 @@ int main(int argc, char* argv[]) { std::cout << "\tVerified: " << std::boolalpha << message.verify() << '\n'; std::cout << '\n'; - // Mnemonic - const auto new_passphrase = Ark::Crypto::Identities::Mnemonic::generate(); - std::cout << "Generated Mnemonic: " << new_passphrase << '\n'; - std::cout << '\n'; - // Address - from passphrase const uint8_t networkVersion = 0x1E; auto address = Address::fromPassphrase(passphrase, networkVersion); diff --git a/examples/platformio_example/src/main.ino b/examples/platformio_example/src/main.ino index 9194ae72..c6eee361 100644 --- a/examples/platformio_example/src/main.ino +++ b/examples/platformio_example/src/main.ino @@ -42,11 +42,6 @@ void loop() { Serial.print("\tVerified: "); Serial.print(message.verify()); Serial.println(); Serial.println(); - // Mnemonic - const auto new_passphrase = Ark::Crypto::Identities::Mnemonic::generate(); - Serial.print("Generated Mnemonic: "); Serial.print(new_passphrase.c_str()); Serial.println(); - Serial.println(); - // Address - from passphrase const uint8_t networkVersion = 0x1E; auto address = Address::fromPassphrase(passphrase, networkVersion); diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index 4ed924ce..53ddf899 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -115,15 +115,6 @@ if [[ -d ${INCLUDE_DIR} ]]; then mkdir ${SRC_ENCODING_DIR} mv ${INCLUDE_HELPERS_DIR}/encoding/hex.h ${SRC_ENCODING_DIR} - ## 'bip39' library is not supported in Arduino - echo -e "Backing up and removing 'mnemonic.h'.\n" - mkdir ${EXTRAS_BACKUP_DIR} - mkdir ${EXTRAS_IDENTITIES_DIR} - mv ${INCLUDE_IDENTITIES_DIR}/mnemonic.h ${EXTRAS_IDENTITIES_DIR} - mv ${SRC_IDENTITIES_DIR}/mnemonic.cpp ${EXTRAS_IDENTITIES_DIR} - echo "// this is a dummy file" >> ${SRC_IDENTITIES_DIR}/mnemonic.h - echo "// this is a dummy file" >> ${SRC_IDENTITIES_DIR}/mnemonic.cpp - echo -e "Moving 'identites' headers.\n" mv ${INCLUDE_IDENTITIES_DIR}/address.h ${SRC_IDENTITIES_DIR} mv ${INCLUDE_IDENTITIES_DIR}/privatekey.h ${SRC_IDENTITIES_DIR} @@ -144,7 +135,6 @@ if [[ -d ${INCLUDE_DIR} ]]; then echo -e "Backing up, moving, and removing relevant modules from the 'lib' directory.\n" mv ${SRC_LIB_DIR}/ArduinoJson ${EXTRAS_BACKUP_DIR} - mv ${SRC_LIB_DIR}/bip39 ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/uECC ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/bcl ${SRC_DIR} mv ${SRC_LIB_DIR}/date ${SRC_DIR} @@ -196,7 +186,6 @@ else echo -e "Moving 'identities' headers.\n" mv ${SRC_IDENTITIES_DIR}/address.h ${INCLUDE_IDENTITIES_DIR} - mv ${SRC_IDENTITIES_DIR}/mnemonic.h ${INCLUDE_IDENTITIES_DIR} mv ${SRC_IDENTITIES_DIR}/privatekey.h ${INCLUDE_IDENTITIES_DIR} mv ${SRC_IDENTITIES_DIR}/publickey.h ${INCLUDE_IDENTITIES_DIR} mv ${SRC_IDENTITIES_DIR}/wif.h ${INCLUDE_IDENTITIES_DIR} @@ -213,18 +202,9 @@ else mv ${SRC_TRANSACTIONS_DIR}/serializer.h ${INCLUDE_TRANSACTIONS_DIR} mv ${SRC_TRANSACTIONS_DIR}/transaction.h ${INCLUDE_TRANSACTIONS_DIR} - ## 'bip39' library is not supported in Arduino - echo -e "Restoring 'mnemonic.h'.\n" - rm -rf ${SRC_IDENTITIES_DIR}/mnemonic.h - rm -rf ${SRC_IDENTITIES_DIR}/mnemonic.cpp - mv ${EXTRAS_IDENTITIES_DIR}/mnemonic.h ${INCLUDE_IDENTITIES_DIR} - mv ${EXTRAS_IDENTITIES_DIR}/mnemonic.cpp ${SRC_IDENTITIES_DIR} - rm -rf ${EXTRAS_IDENTITIES_DIR}/mnemonic.cpp - echo -e "Restoring the 'lib' directory.\n" mkdir ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/ArduinoJson ${SRC_LIB_DIR} - mv ${EXTRAS_BACKUP_DIR}/bip39 ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/uECC ${SRC_LIB_DIR} mv ${SRC_DIR}/bcl ${SRC_LIB_DIR} mv ${SRC_DIR}/date ${SRC_LIB_DIR} diff --git a/keywords.txt b/keywords.txt index 88450489..98cd5e48 100644 --- a/keywords.txt +++ b/keywords.txt @@ -22,7 +22,6 @@ Fees KEYWORD1 Types KEYWORD1 Address KEYWORD1 -Mnemonic KEYWORD1 PrivateKey KEYWORD1 PublicKey KEYWORD1 WIF KEYWORD1 diff --git a/library.json b/library.json index 9cb19d62..c02cabc3 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Crypto.git" }, - "version": "0.4.0", + "version": "0.5.0", "authors": [ { "name": "Ark Ecosystem", @@ -21,9 +21,6 @@ { "name": "micro-ecc" }, - { - "name": "bip39" - }, { "name": "ArduinoJson" } diff --git a/library.properties b/library.properties index c9ac8409..7821733c 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Crypto -version=0.4.0 +version=0.5.0 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple Cryptography Implementation in C++ for the ARK Blockchain. diff --git a/platformio.ini b/platformio.ini index 8cc3220f..5ad5519d 100644 --- a/platformio.ini +++ b/platformio.ini @@ -15,7 +15,7 @@ description = "A simple Cryptography Implementation in C++ for the ARK Blockchai lib_ldf_mode = off lib_deps = micro-ecc, bip39@^1.1, ArduinoJson@6.10.0, BIP66 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - - - - - - +src_filter = +<*> -<.git/> - -- - - upload_speed = 921600 [env:esp8266] diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e1c1144..0511290d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,8 +3,6 @@ cmake_minimum_required(VERSION 3.2.2) project(Ark-Cpp-Crypto-lib C CXX) -add_subdirectory(lib/bip39/src) - set(BIP66_SRC ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp ) @@ -31,7 +29,6 @@ set(COMMON_SRC configuration/network.cpp helpers/crypto.cpp identities/address.cpp - identities/mnemonic.cpp identities/privatekey.cpp identities/publickey.cpp identities/wif.cpp @@ -60,7 +57,6 @@ include_directories(${cpp_crypto_build_include_dirs}) include_directories(${PROJECT_SOURCE_DIR}/lib/) include_directories(${PROJECT_SOURCE_DIR}/lib/ArduinoJson) include_directories(${PROJECT_SOURCE_DIR}/lib/bcl) -include_directories(${PROJECT_SOURCE_DIR}/lib/bip39) include_directories(${PROJECT_SOURCE_DIR}/lib/rfc6979) include_directories(${PROJECT_SOURCE_DIR}/lib/uECC) include_directories(${PROJECT_SOURCE_DIR}/lib/BIP66/src) @@ -69,8 +65,6 @@ target_include_directories( ${PROJECT_NAME} PUBLIC ${cpp_crypto_build_include_dirs} ) -target_link_libraries(${PROJECT_NAME} PRIVATE bip39) - if (MSVC) target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) endif() diff --git a/src/identities/mnemonic.cpp b/src/identities/mnemonic.cpp deleted file mode 100644 index d3bffc76..00000000 --- a/src/identities/mnemonic.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "identities/mnemonic.h" - -#include "bip39/bip39.h" - -#include - -namespace Ark { -namespace Crypto { -namespace Identities { - -std::string Mnemonic::generate(size_t num_words /* = 12u */, Language language /* = Language::en */) { - static const std::map words_to_entropy = {{12, BIP39::entropy_bits_t::_128}, - {15, BIP39::entropy_bits_t::_160}, - {18, BIP39::entropy_bits_t::_192}, - {21, BIP39::entropy_bits_t::_224}, - {24, BIP39::entropy_bits_t::_256}}; - static const std::map language_map = { - {Language::en, BIP39::language::en}, {Language::es, BIP39::language::es}, - {Language::ja, BIP39::language::ja}, {Language::it, BIP39::language::it}, - {Language::fr, BIP39::language::fr}, {Language::ko, BIP39::language::ko}, - {Language::zh_Hans, BIP39::language::zh_Hans}, {Language::zh_Hant, BIP39::language::zh_Hant}}; - - const auto entropy_it = words_to_entropy.find(num_words); - assert(entropy_it != words_to_entropy.end()); - - const auto lang = language_map.find(language); - assert(lang != language_map.end()); - - return BIP39::generate_mnemonic(entropy_it->second, lang->second).to_string(); -} - -} // namespace Identities -} // namespace Crypto -} // namespace Ark diff --git a/src/include/cpp-crypto/arkCrypto.h b/src/include/cpp-crypto/arkCrypto.h index ff9f56b9..17f23742 100644 --- a/src/include/cpp-crypto/arkCrypto.h +++ b/src/include/cpp-crypto/arkCrypto.h @@ -22,7 +22,6 @@ #include "enums/types.h" #include "identities/address.h" -#include "identities/mnemonic.h" #include "identities/privatekey.h" #include "identities/publickey.h" #include "identities/wif.h" diff --git a/src/include/cpp-crypto/identities/mnemonic.h b/src/include/cpp-crypto/identities/mnemonic.h deleted file mode 100644 index 831a1988..00000000 --- a/src/include/cpp-crypto/identities/mnemonic.h +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef MNEMONIC_H -#define MNEMONIC_H - -#include - -namespace Ark { -namespace Crypto { -namespace Identities { - -enum class Language { en, es, ja, it, fr, ko, zh_Hans, zh_Hant }; - -class Mnemonic { - public: - /// Generate a BIP39 passphrase with the given number of words (12,15,18,21,24) and given language - static std::string generate(size_t num_words = 12u, Language language = Language::en); -}; - -} // namespace Identities -} // namespace Crypto -} // namespace Ark -#endif diff --git a/src/lib/bip39 b/src/lib/bip39 deleted file mode 160000 index ea4224e8..00000000 --- a/src/lib/bip39 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ea4224e8055210f2578a862ce00fee7429fabeba diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9cb1b7d4..b79d8dc9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,7 +24,6 @@ set (TEST_SRC ${PROJECT_SOURCE_DIR}/enums/fees.cpp ${PROJECT_SOURCE_DIR}/enums/types.cpp ${PROJECT_SOURCE_DIR}/identities/address.cpp - ${PROJECT_SOURCE_DIR}/identities/mnemonic.cpp ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp ${PROJECT_SOURCE_DIR}/identities/publickey.cpp ${PROJECT_SOURCE_DIR}/identities/wif.cpp diff --git a/test/identities/mnemonic.cpp b/test/identities/mnemonic.cpp deleted file mode 100644 index c021244d..00000000 --- a/test/identities/mnemonic.cpp +++ /dev/null @@ -1,169 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/mnemonic.h" - -#include -#include - -namespace { - -const auto MAX_WORD_BYTES = - ((8 * 4) + 1) * - 24; // ((8 characters per word * 4 potential octets per character) + 1 nul terminator) * maximum of 24 words -} - -// Note: generate_mnemonic_valid_[lang] tests could be refactored to use a single helper function with a language -// argument. -// This causes problems with AUnit when building and testing IoT due to ASSERT macros not being available. -TEST(mnemonic, generate_mnemonic_valid_en) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::en); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_es) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::es); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_ja) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::ja); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_it) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::it); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_fr) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::fr); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_ko) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::ko); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_zh_Hans) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = - Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::zh_Hans); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -TEST(mnemonic, generate_mnemonic_valid_zh_Hant) { - for (auto num_words = 12u; num_words <= 24u; num_words += 3) { - auto passphrase = - Ark::Crypto::Identities::Mnemonic::generate(num_words, Ark::Crypto::Identities::Language::zh_Hant); - // use a set to ensure no duplicate words can be added - std::set words; - char s[MAX_WORD_BYTES] = {}; - strncpy(s, passphrase.c_str(), sizeof(s)); - auto pch = strtok(s, " "); - while (pch != nullptr) { - ASSERT_TRUE(words.insert(pch).second); - pch = strtok(nullptr, " "); - } - - ASSERT_EQ(num_words, words.size()); - } -} - -// These tests depend on the library asserting, disable this test for Release builds -#ifdef DEBUG -TEST(mnemonic, generate_mnemonic_invalid) { - for (auto num_words = 0u; num_words <= 100u; ++num_words) { - // skip the valid word cases - if (num_words == 12u || num_words == 15u || num_words == 18u || num_words == 21u || num_words == 24u) { - continue; - } - - ASSERT_DEATH(Ark::Crypto::Identities::Mnemonic::generate(num_words), ""); - } -} -#endif diff --git a/test/platformio.ini b/test/platformio.ini index bcfd048e..e510f98c 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -17,7 +17,7 @@ lib_dir = .. lib_ldf_mode = off lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@6.10.0, BIP66 build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - - +src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - upload_speed = 921600 # esp8266 unit tests disabled until support is worked out From 48e014c3eb64df0f96ca761c824cfc7b5f69cbff Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 25 May 2019 20:08:48 -0700 Subject: [PATCH 13/29] refactor(slots): Improve Slots Implementations (#92) - Further decouple OS code from IoT code. - Add missing ESP8266 functionality. - Allow removal of lib/STL dependency. - STL lib is only included to provide a conv. method for IoT to use date.h - date.h is now only used by OS builds, which will have the STL by default. - update changelog. - add PIO filters for lib/date. --- CHANGELOG.md | 6 ++ platformio.ini | 4 +- src/helpers/crypto_helpers.h | 17 ++-- src/lib/stl/array | 54 ---------- src/lib/stl/cassert | 4 - src/lib/stl/cctype | 4 - src/lib/stl/cstddef | 4 - src/lib/stl/cstdint | 4 - src/lib/stl/cstdio | 4 - src/lib/stl/cstring | 4 - src/lib/stl/details/to_string.h | 171 -------------------------------- src/lib/stl/memory | 128 ------------------------ src/utils/slot.cpp | 111 ++++++++++++--------- test/platformio.ini | 4 +- 14 files changed, 84 insertions(+), 435 deletions(-) delete mode 100644 src/lib/stl/array delete mode 100644 src/lib/stl/cassert delete mode 100644 src/lib/stl/cctype delete mode 100644 src/lib/stl/cstddef delete mode 100644 src/lib/stl/cstdint delete mode 100644 src/lib/stl/cstdio delete mode 100644 src/lib/stl/cstring delete mode 100644 src/lib/stl/details/to_string.h delete mode 100644 src/lib/stl/memory diff --git a/CHANGELOG.md b/CHANGELOG.md index 900370c5..58bf0e2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- improved Slots implementations ([#92]) + ## [0.5.0] - 2019-02-20 ### Changed diff --git a/platformio.ini b/platformio.ini index 5ad5519d..82761003 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,9 +13,9 @@ description = "A simple Cryptography Implementation in C++ for the ARK Blockchai [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, ArduinoJson@6.10.0, BIP66 +lib_deps = micro-ecc, ArduinoJson@6.10.0, BIP66 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - -- - - +src_filter = +<*> -<.git/> - - - - - - upload_speed = 921600 [env:esp8266] diff --git a/src/helpers/crypto_helpers.h b/src/helpers/crypto_helpers.h index e7881826..b34a48ca 100644 --- a/src/helpers/crypto_helpers.h +++ b/src/helpers/crypto_helpers.h @@ -1,4 +1,11 @@ - +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ #ifndef CRYPTO_HELPERS_H #define CRYPTO_HELPERS_H @@ -17,17 +24,9 @@ const auto WIF_SIZE = 52u; #define USE_IOT -// Including missing implementations of std::to_string -#include "stl/details/to_string.h" - #include #include -// undef the C macros to allow the C++ STL to take over -// This is to have compatibility with various board implementations of the STL -#undef min -#undef max - #endif // Write data into dst diff --git a/src/lib/stl/array b/src/lib/stl/array deleted file mode 100644 index 59d741d6..00000000 --- a/src/lib/stl/array +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __ARRAY__ -#define __ARRAY__ - -namespace std { - -template -class array { - public: - typedef T value_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef pointer iterator; - typedef const_pointer const_iterator; - typedef size_t size_type; - - private: - value_type _data[N ? N : 1]; - - public: - array() = default; - array& operator=(const array& other) = default; - - reference operator[](size_type i) { return _data[i]; } - const_reference operator[](size_type i) const { return _data[i]; } - reference front() { return _data[0]; } - const_reference front() const { return _data[0]; } - reference back() { return _data[N - 1]; } - const_reference back() const { return _data[N - 1]; } - pointer data() noexcept { return _data; } - const_pointer data() const noexcept { return _data; } - - iterator begin() noexcept { return _data; } - const_iterator begin() const noexcept { return _data; } - const_iterator cbegin() const noexcept { return _data; } - iterator end() noexcept { return _data + N; } - const_iterator end() const noexcept { return _data + N; } - const_iterator cend() const noexcept { return _data + N; } - - bool empty() const noexcept { return begin() == end(); } - size_type size() const noexcept { return N; } - size_type max_size() const noexcept { return N; } - - void fill(const_reference value) { - for (auto i = 0u; i < N; ++i) { - _data[i] = value; - } - } -}; - -} // namespace std - -#endif diff --git a/src/lib/stl/cassert b/src/lib/stl/cassert deleted file mode 100644 index 3e27dc73..00000000 --- a/src/lib/stl/cassert +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/cctype b/src/lib/stl/cctype deleted file mode 100644 index 24a602fe..00000000 --- a/src/lib/stl/cctype +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/cstddef b/src/lib/stl/cstddef deleted file mode 100644 index 640f294e..00000000 --- a/src/lib/stl/cstddef +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/cstdint b/src/lib/stl/cstdint deleted file mode 100644 index e3c1098a..00000000 --- a/src/lib/stl/cstdint +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/cstdio b/src/lib/stl/cstdio deleted file mode 100644 index d6da5ec5..00000000 --- a/src/lib/stl/cstdio +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/cstring b/src/lib/stl/cstring deleted file mode 100644 index 49ec72cd..00000000 --- a/src/lib/stl/cstring +++ /dev/null @@ -1,4 +0,0 @@ -namespace std { - -#include -} diff --git a/src/lib/stl/details/to_string.h b/src/lib/stl/details/to_string.h deleted file mode 100644 index 2c747bd4..00000000 --- a/src/lib/stl/details/to_string.h +++ /dev/null @@ -1,171 +0,0 @@ -#ifndef ARDUINO_STL_DETAILS_TO_STRING_H -#define ARDUINO_STL_DETAILS_TO_STRING_H - -#include -#include -#include -#include - -namespace std { - -inline std::string to_string(int value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%d", value); - return buf; -} -inline std::string to_string(long value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%ld", value); - return buf; -} -inline std::string to_string(long long value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%lld", value); - return buf; -} -inline std::string to_string(unsigned value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%u", value); - return buf; -} -inline std::string to_string(unsigned long value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%lu", value); - return buf; -} -inline std::string to_string(unsigned long long value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%llu", value); - return buf; -} -inline std::string to_string(float value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%f", value); - return buf; -} -inline std::string to_string(double value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%lf", value); - return buf; -} -inline std::string to_string(long double value) { - char buf[24] = {}; - snprintf(buf, sizeof(buf), "%Lf", value); - return buf; -} - -inline float stof(const std::string& str, std::size_t* pos = 0) { - char* end = nullptr; - auto ret = strtof(str.c_str(), &end); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} -inline double stod(const std::string& str, std::size_t* pos = 0) { - char* end = nullptr; - auto ret = strtod(str.c_str(), &end); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} -inline long double stold(const std::string& str, std::size_t* pos = 0) { - char* end = nullptr; - auto ret = strtold(str.c_str(), &end); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} - -inline int stoi(const std::string& str, std::size_t* pos = 0, int base = 10) { - char* end = nullptr; - auto ret = strtol(str.c_str(), &end, base); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return static_cast(ret); -} -inline long stol(const std::string& str, std::size_t* pos = 0, int base = 10) { - char* end = nullptr; - auto ret = strtol(str.c_str(), &end, base); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} -inline long long stoll(const std::string& str, std::size_t* pos = 0, int base = 10) { - char* end = nullptr; - auto ret = strtoll(str.c_str(), &end, base); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} - -inline unsigned long stoul(const std::string& str, std::size_t* pos = 0, int base = 10) { - char* end = nullptr; - auto ret = strtoul(str.c_str(), &end, base); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} -inline unsigned long long stoull(const std::string& str, std::size_t* pos = 0, int base = 10) { - char* end = nullptr; - auto ret = strtoull(str.c_str(), &end, base); - if (pos != nullptr) { - *pos = end - str.c_str(); - } - return ret; -} - -inline std::wstring to_wstring(int value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%d", value); - return buf; -} -inline std::wstring to_wstring(long value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%ld", value); - return buf; -} -inline std::wstring to_wstring(long long value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%lld", value); - return buf; -} -inline std::wstring to_wstring(unsigned value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%u", value); - return buf; -} -inline std::wstring to_wstring(unsigned long value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%lu", value); - return buf; -} -inline std::wstring to_wstring(unsigned long long value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%llu", value); - return buf; -} -inline std::wstring to_wstring(float value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%f", value); - return buf; -} -inline std::wstring to_wstring(double value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%lf", value); - return buf; -} -inline std::wstring to_wstring(long double value) { - wchar_t buf[24] = {}; - swprintf(buf, sizeof(buf), L"%Lf", value); - return buf; -} -} // namespace std - -#endif diff --git a/src/lib/stl/memory b/src/lib/stl/memory deleted file mode 100644 index 8047c6eb..00000000 --- a/src/lib/stl/memory +++ /dev/null @@ -1,128 +0,0 @@ -#ifndef __MEMORY__ -#define __MEMORY__ - -#include - -namespace std { - -template -struct default_delete { - default_delete() {} - - template - default_delete(const default_delete&) {} - - void operator()(T* ptr) const { delete ptr; } -}; - -template -struct default_delete { - void operator()(T* ptr) const { delete[] ptr; } -}; - -template > -class unique_ptr { - typedef T* pointer; - typedef T& reference; - - private: - pointer _p; - bool _own; - - public: - constexpr unique_ptr() noexcept : _p(nullptr), _own(false) {} - - explicit unique_ptr(pointer p) : _p(p), _own(true) {} - - template - explicit unique_ptr(U u) : _p(u), _own(true) {} - - unique_ptr(unique_ptr&& other) : _p(other._p), _own(other._own) { - other._p = nullptr; - other._own = false; - } - - unique_ptr& operator=(unique_ptr&& other) { - if (this != &other) { - _p = other._p; - _own = other._own; - - other._p = nullptr; - other._own = false; - } - return *this; - } - - ~unique_ptr() { reset(); } - - pointer get() const noexcept { return _p; } - pointer release() noexcept { - _own = false; - return _p; - } - void reset(pointer p = pointer()) noexcept { - D d; - d(_p); - _p = p; - _own = true; - } - - explicit operator bool() const noexcept { return _p != nullptr; } - reference operator*() const { return *_p; } - pointer operator->() const noexcept { return _p; } -}; - -template -class unique_ptr { - typedef T* pointer; - typedef T& reference; - - private: - pointer _p; - bool _own; - - public: - constexpr unique_ptr() noexcept : _p(nullptr), _own(false) {} - - explicit unique_ptr(pointer p) : _p(p), _own(true) {} - - template - explicit unique_ptr(U u) : _p(u), _own(true) {} - - unique_ptr(unique_ptr&& other) : _p(other._p), _own(other._own) { - other._p = nullptr; - other._own = false; - } - - unique_ptr& operator=(unique_ptr&& other) { - if (this != &other) { - _p = other._p; - _own = other._own; - - other._p = nullptr; - other._own = false; - } - return *this; - } - - ~unique_ptr() { reset(); } - - pointer get() const noexcept { return _p; } - pointer release() noexcept { - _own = false; - return _p; - } - void reset(pointer p = pointer()) noexcept { - D d; - d(_p); - _p = p; - _own = true; - } - - explicit operator bool() const noexcept { return _p != nullptr; } - reference operator[](size_t i) const { return _p[i]; } -}; - -} // namespace std - -#endif diff --git a/src/utils/slot.cpp b/src/utils/slot.cpp index 02ff2240..e8244b02 100644 --- a/src/utils/slot.cpp +++ b/src/utils/slot.cpp @@ -2,60 +2,81 @@ #include "helpers/crypto_helpers.h" #include "utils/slot.h" -#include -#include - -#undef round -#include "date/date.h" - -uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { - // https://stackoverflow.com/questions/33421450/c-c-time-zone-correct-time-conversion-to-seconds-since-epoch/33438989#33438989 - std::istringstream in(network.epoch()); - std::chrono::system_clock::time_point tp; - in >> date::parse("%FT%TZ", tp); - if (in.fail()) { - in.clear(); - in.str(network.epoch()); - in >> date::parse("%FT%T%z", tp); - }; - // cast milliseconds as uint64_t in seconds(/ 1000) - return static_cast( - std::chrono::duration_cast( - tp.time_since_epoch() - ).count() - ) / 1000; -} +#ifndef USE_IOT // OS Builds + + #include + #include + + #undef round + #include "date/date.h" + + uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + // https://stackoverflow.com/questions/33421450/c-c-time-zone-correct-time-conversion-to-seconds-since-epoch/33438989#33438989 + std::istringstream in(network.epoch()); + std::chrono::system_clock::time_point tp; + in >> date::parse("%FT%TZ", tp); + if (in.fail()) { + in.clear(); + in.str(network.epoch()); + in >> date::parse("%FT%T%z", tp); + }; + // cast milliseconds as uint64_t in seconds(/ 1000) + return static_cast( + std::chrono::duration_cast( + tp.time_since_epoch() + ).count() + ) / 1000; + } + + uint64_t Ark::Crypto::Utils::Slot::now() { + return std::chrono::duration_cast( + std::chrono::system_clock::now().time_since_epoch() + ).count(); + } + +#endif uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork network) { const auto time = now() - epoch(network); return (time > 0) ? time : 0; } -#ifdef ESP32 +#if defined(ESP32) || defined(ESP8266) -uint64_t Ark::Crypto::Utils::Slot::now() { - struct tm t; - std::stringstream ss; - if(getLocalTime(&t)){ - ss << std::mktime(&t); - } else { - return 0; - }; - uint64_t temp; - ss >> temp; - return temp; -}; + #include + #include /* strtol */ + #include -#elif defined(ESP8266) // NOT STABLE/NOT SUPPORTED + uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + constexpr const size_t expectedLength = sizeof("2017-03-21T13:00:00.000Z") - 1; + if (expectedLength != 24) { return 0; } // Unexpected ISO 8601 date/time length -uint64_t Ark::Crypto::Utils::Slot::now() { return 0; } + std::string input(network.epoch()); -#else // OS Builds + if (input.length() < expectedLength) { + return 0; + }; -uint64_t Ark::Crypto::Utils::Slot::now() { - return std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch() - ).count(); -} + struct tm time; + time.tm_year = strtol(&input[0], nullptr, 10) - 1900; + time.tm_mon = strtol(&input[5], nullptr, 10) - 1; + time.tm_mday = strtol(&input[8], nullptr, 10); + time.tm_hour = strtol(&input[11], nullptr, 10); + time.tm_min = strtol(&input[14], nullptr, 10); + time.tm_sec = strtol(&input[17], nullptr, 10); + time.tm_isdst = 0; + + return mktime(&time); + } + + /***/ + + // 'time(0) will collide with Slot::time + // so we create the call outside the Slot namespace. + uint64_t NOW() { return time(0); } + + uint64_t Ark::Crypto::Utils::Slot::now() { + return NOW(); + } -#endif // #ifndef USE_IOT +#endif diff --git a/test/platformio.ini b/test/platformio.ini index e510f98c..bbdd161c 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -15,9 +15,9 @@ lib_dir = .. [common] lib_ldf_mode = off -lib_deps = micro-ecc, bip39@^1.1, AUnit, ArduinoJson@6.10.0, BIP66 +lib_deps = micro-ecc, AUnit, ArduinoJson@6.10.0, BIP66 build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - +src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - - upload_speed = 921600 # esp8266 unit tests disabled until support is worked out From a1b0629341c94ac78c1d0f8a4ffcafb58e55e9a3 Mon Sep 17 00:00:00 2001 From: Brian Faust Date: Mon, 27 May 2019 09:47:51 +0200 Subject: [PATCH 14/29] chore: use organization-wide GitHub Configuration (#94) --- .github/CODE_OF_CONDUCT.md | 71 ----------------------- .github/CONTRIBUTING.md | 1 - .github/ISSUE_TEMPLATE/Bug_report.md | 27 --------- .github/ISSUE_TEMPLATE/Feature_request.md | 16 ----- .github/PULL_REQUEST_TEMPLATE.md | 34 ----------- 5 files changed, 149 deletions(-) delete mode 100644 .github/CODE_OF_CONDUCT.md delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/ISSUE_TEMPLATE/Bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/Feature_request.md delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md deleted file mode 100644 index b6b28dab..00000000 --- a/.github/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,71 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, race, -religion, or sexual identity and orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or - advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at info@ark.io. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][https://www.contributor-covenant.org], version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 825605e1..00000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1 +0,0 @@ -Please see [CONTRIBUTING](https://docs.ark.io/guidebook/contribution-guidelines/contributing.html) for details before opening your pull request. diff --git a/.github/ISSUE_TEMPLATE/Bug_report.md b/.github/ISSUE_TEMPLATE/Bug_report.md deleted file mode 100644 index bfa4acc9..00000000 --- a/.github/ISSUE_TEMPLATE/Bug_report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Server (please complete the following information):** - - OS: [e.g. Ubuntu] - - Version [e.g. 16.04] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md deleted file mode 100644 index a09db44f..00000000 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 7837d925..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,34 +0,0 @@ -## Proposed changes - - -## Types of changes - - -- [ ] Bugfix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Refactoring (improve a current implementation without adding a new feature or fixing a bug) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Build (changes that affect the build system) -- [ ] Docs (documentation only changes) -- [ ] Test (adding missing tests or fixing existing tests) -- [ ] Other... Please describe: - -## Checklist - - -- [ ] I have read the [CONTRIBUTING](https://docs.ark.io/guidebook/contribution-guidelines/contributing.html) documentation -- [ ] Lint and unit tests pass locally with my changes -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] I have added necessary documentation (if appropriate) - -## Further comments - From 5c80c20b538c2807e9561d5ea53e0d03a2a3e270 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 28 May 2019 20:13:55 -0700 Subject: [PATCH 15/29] style: Improve Formatting and Maintainability (#98) --- .appveyor.yml | 4 +- .circleci/clang_tidy.sh | 2 +- .circleci/config.yml | 23 +- CHANGELOG.md | 1 + CMakeLists.txt | 30 +- extras/ARDUINO_IDE.sh | 2 +- src/CMakeLists.txt | 70 +-- src/configuration/fee.cpp | 31 +- src/configuration/network.cpp | 27 +- src/helpers/crypto.cpp | 78 ++- src/helpers/crypto.h | 13 +- src/helpers/crypto_helpers.h | 16 +- src/helpers/json.h | 4 +- src/identities/address.cpp | 164 +++--- src/identities/privatekey.cpp | 140 +++-- src/identities/publickey.cpp | 147 +++--- src/identities/wif.cpp | 70 +-- src/include/cpp-crypto/configuration/fee.h | 37 +- .../cpp-crypto/configuration/network.h | 15 +- src/include/cpp-crypto/enums/fees.h | 25 +- src/include/cpp-crypto/enums/types.h | 26 +- src/include/cpp-crypto/helpers/encoding/hex.h | 67 +-- src/include/cpp-crypto/identities/address.h | 35 +- .../cpp-crypto/identities/privatekey.h | 38 +- src/include/cpp-crypto/identities/publickey.h | 35 +- src/include/cpp-crypto/identities/wif.h | 28 +- .../cpp-crypto/networks/abstractnetwork.h | 45 +- src/include/cpp-crypto/networks/devnet.h | 26 +- src/include/cpp-crypto/networks/mainnet.h | 26 +- src/include/cpp-crypto/networks/testnet.h | 26 +- src/include/cpp-crypto/transactions/builder.h | 60 ++- .../cpp-crypto/transactions/deserializer.h | 22 +- .../cpp-crypto/transactions/serializer.h | 14 +- .../cpp-crypto/transactions/transaction.h | 21 +- src/networks/abstractnetwork.cpp | 108 ++-- src/transactions/builder.cpp | 111 +++- src/transactions/deserializer.cpp | 216 +++++--- src/transactions/serializer.cpp | 198 +++++--- src/transactions/transaction.cpp | 302 +++++++---- src/utils/message.cpp | 55 +- src/utils/message.h | 10 +- src/utils/slot.cpp | 16 +- src/utils/slot.h | 14 +- test/CMakeLists.txt | 43 +- test/configuration/fee.cpp | 56 +- test/configuration/network.cpp | 2 + test/enums/fees.cpp | 39 +- test/enums/types.cpp | 19 +- test/helpers/crypto.cpp | 108 ++++ test/helpers/crypto_helpers.cpp | 30 ++ test/helpers/encoding/hex.cpp | 41 ++ test/identities/address.cpp | 99 +++- test/identities/privatekey.cpp | 51 +- test/identities/publickey.cpp | 66 ++- test/identities/wif.cpp | 47 +- test/networks/abstractnetwork.cpp | 68 ++- test/networks/devnet.cpp | 9 + test/networks/mainnet.cpp | 9 + test/networks/testnet.cpp | 9 + test/transactions/builder.cpp | 24 +- test/transactions/deserializer.cpp | 170 ++++--- test/transactions/serializer.cpp | 121 ++--- test/transactions/transaction.cpp | 480 +++++++++++------- test/utils/message.cpp | 37 +- test/utils/slot.cpp | 9 +- 65 files changed, 2263 insertions(+), 1672 deletions(-) create mode 100644 test/helpers/crypto.cpp create mode 100644 test/helpers/crypto_helpers.cpp create mode 100644 test/helpers/encoding/hex.cpp diff --git a/.appveyor.yml b/.appveyor.yml index 62c568dd..38629ea7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,8 @@ image: Visual Studio 2017 environment: matrix: - - CONFIGURATION: Debug - - CONFIGURATION: Release + - CONFIGURATION: Debug + - CONFIGURATION: Release install: - git submodule update --init --recursive diff --git a/.circleci/clang_tidy.sh b/.circleci/clang_tidy.sh index b97b592d..ae917a5e 100644 --- a/.circleci/clang_tidy.sh +++ b/.circleci/clang_tidy.sh @@ -7,7 +7,7 @@ if [[ -n $(grep "error: " output.txt) ]]; then echo "You must pass the clang tidy checks before submitting a pull request" echo "" grep --color -E '^|warning: |error: ' output.txt - exit -1; + exit 1; else # still output the file to show warnings echo "" diff --git a/.circleci/config.yml b/.circleci/config.yml index 67c56785..f0429e33 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: steps: - checkout - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Install @@ -18,7 +18,7 @@ jobs: steps: - checkout - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Install @@ -34,16 +34,15 @@ jobs: name: Install dependencies command: | sudo apt-get remove cmake cmake-data - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test sudo apt-add-repository -y ppa:george-edison55/cmake-3.x sudo apt-get update sudo apt-get -y install g++-7 gcc-7 lcov cmake sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7 sudo update-alternatives --config gcc - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - - run: name: Build command: ./.circleci/script_desktop.sh @@ -63,28 +62,22 @@ jobs: sudo apt-get update sudo apt install python-lldb-5.0 lcov cmake sudo apt install clang-5.0 clang-tidy-5.0 clang-format-5.0 clang-5.0-doc libclang-common-5.0-dev libclang-5.0-dev libclang1-5.0 libllvm5.0 lldb-5.0 llvm-5.0 llvm-5.0-dev - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-5.0 60 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 50 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-5.0 60 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 50 - - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - - run: name: Build command: ./.circleci/script_desktop.sh - - run: name: Clang Tidy command: ./.circleci/clang_tidy.sh - - run: name: Clang Format command: ./.circleci/clang_format.sh - build-macos-9-2: macos: xcode: "9.2.0" @@ -95,7 +88,7 @@ jobs: name: Install dependencies command: brew install cmake lcov - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Build @@ -109,12 +102,11 @@ jobs: name: Install dependencies command: brew install cmake lcov - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Build command: ./.circleci/script_desktop.sh - workflows: version: 2 build: @@ -125,4 +117,3 @@ workflows: - build-linux-clang-5 - build-macos-9-2 - build-macos-9-3 - diff --git a/CHANGELOG.md b/CHANGELOG.md index 58bf0e2e..f3f55e87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed +- improved formatting and maintainability ([#98]) - improved Slots implementations ([#92]) ## [0.5.0] - 2019-02-20 diff --git a/CMakeLists.txt b/CMakeLists.txt index d116fc67..f63af177 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,20 +7,20 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) if (MSVC) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - -DNOMINMAX - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") + add_definitions( + -D_CRT_SECURE_NO_WARNINGS + -D_SCL_SECURE_NO_WARNINGS + -DNOMINMAX + ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") endif() # clone submodules execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND git submodule update --init --recursive + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) # ------------------------------------------------------------------------------ @@ -28,7 +28,6 @@ execute_process( # ------------------------------------------------------------------------------ if(ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN clang-tidy-5.0) find_program(RUN_CLANG_TIDY_BIN run-clang-tidy-5.0.py) @@ -36,13 +35,13 @@ if(ENABLE_CLANG_TIDY) message(FATAL_ERROR "unable to locate clang-tidy-5.0") endif() - if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") - endif() + if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") + message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") + endif() list(APPEND RUN_CLANG_TIDY_BIN_ARGS -clang-tidy-binary ${CLANG_TIDY_BIN} - -header-filter=.* + "\"-header-filter=.*\\b(src|test|examples)\\b\\/(?!lib\/*).*\"" #Only run clang tidy on src, test, examples and skip 3rd party libraries -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor,-cppcoreguidelines-* ) @@ -51,7 +50,6 @@ if(ENABLE_CLANG_TIDY) COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS} COMMENT "running clang tidy" ) - endif() add_subdirectory(src) diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index 53ddf899..dce38a15 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -27,7 +27,7 @@ if [ "$1" == "--auto" ]; then fi # Directories -EXTRAS_DIR=`dirname "$0"` +EXTRAS_DIR=$(dirname $0) PROJECT_ROOT=${EXTRAS_DIR}/../ INCLUDE_DIR=${EXTRAS_DIR}/../src/include INCLUDE_CRYPTO_DIR=${INCLUDE_DIR}/cpp-crypto diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0511290d..019aa765 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,55 +4,55 @@ cmake_minimum_required(VERSION 3.2.2) project(Ark-Cpp-Crypto-lib C CXX) set(BIP66_SRC - ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp + ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp ) set(BCL_SRC - lib/bcl/Base58Check.cpp - lib/bcl/CurvePoint.cpp - lib/bcl/Ecdsa.cpp - lib/bcl/FieldInt.cpp - lib/bcl/Ripemd160.cpp - lib/bcl/Sha256Hash.cpp - lib/bcl/Sha256.cpp - lib/bcl/Sha512.cpp - lib/bcl/Uint256.cpp - lib/bcl/Utils.cpp + lib/bcl/Base58Check.cpp + lib/bcl/CurvePoint.cpp + lib/bcl/Ecdsa.cpp + lib/bcl/FieldInt.cpp + lib/bcl/Ripemd160.cpp + lib/bcl/Sha256Hash.cpp + lib/bcl/Sha256.cpp + lib/bcl/Sha512.cpp + lib/bcl/Uint256.cpp + lib/bcl/Utils.cpp ) set(uECC_SRC - lib/uECC/uECC.c + lib/uECC/uECC.c ) set(COMMON_SRC - configuration/fee.cpp - configuration/network.cpp - helpers/crypto.cpp - identities/address.cpp - identities/privatekey.cpp - identities/publickey.cpp - identities/wif.cpp - networks/abstractnetwork.cpp - transactions/builder.cpp - transactions/deserializer.cpp - transactions/serializer.cpp - transactions/transaction.cpp - utils/message.cpp - utils/slot.cpp + configuration/fee.cpp + configuration/network.cpp + helpers/crypto.cpp + identities/address.cpp + identities/privatekey.cpp + identities/publickey.cpp + identities/wif.cpp + networks/abstractnetwork.cpp + transactions/builder.cpp + transactions/deserializer.cpp + transactions/serializer.cpp + transactions/transaction.cpp + utils/message.cpp + utils/slot.cpp ) -add_library(${PROJECT_NAME} - STATIC - ${BCL_SRC} - ${uECC_SRC} - ${BIP66_SRC} - ${COMMON_SRC} +add_library(${PROJECT_NAME} STATIC + ${BCL_SRC} + ${uECC_SRC} + ${BIP66_SRC} + ${COMMON_SRC} ) set(cpp_crypto_build_include_dirs ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include/cpp-crypto ) + include_directories(${cpp_crypto_build_include_dirs}) include_directories(${PROJECT_SOURCE_DIR}/lib/) include_directories(${PROJECT_SOURCE_DIR}/lib/ArduinoJson) @@ -61,10 +61,10 @@ include_directories(${PROJECT_SOURCE_DIR}/lib/rfc6979) include_directories(${PROJECT_SOURCE_DIR}/lib/uECC) include_directories(${PROJECT_SOURCE_DIR}/lib/BIP66/src) -target_include_directories( ${PROJECT_NAME} - PUBLIC ${cpp_crypto_build_include_dirs} +target_include_directories( ${PROJECT_NAME} PUBLIC + ${cpp_crypto_build_include_dirs} ) if (MSVC) - target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) + target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) endif() diff --git a/src/configuration/fee.cpp b/src/configuration/fee.cpp index 6f6fe63d..7863f80d 100644 --- a/src/configuration/fee.cpp +++ b/src/configuration/fee.cpp @@ -1,32 +1,17 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "configuration/fee.h" -/** - * @brief Get the transaction fee for the given type. - * - * @param const int type - * @return uint64_t - **/ -uint64_t Ark::Crypto::Configuration::Fee::get(int type) { +#include + +uint64_t Ark::Crypto::Configuration::Fee::get( + int type) { return this->fees_[type]; }; + /**/ -/** - * @brief Set the transaction fee for the given type. - * - * @param const int type - * @param const uint64_t fee - **/ -void Ark::Crypto::Configuration::Fee::set(int type, uint64_t fee) { +void Ark::Crypto::Configuration::Fee::set( + int type, + uint64_t fee) { this->fees_[type] = fee; }; -/**/ diff --git a/src/configuration/network.cpp b/src/configuration/network.cpp index b3355091..d9d61142 100644 --- a/src/configuration/network.cpp +++ b/src/configuration/network.cpp @@ -1,30 +1,15 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "configuration/network.h" -/** - * @brief Get the network used for crypto operations. - * - * @return AbstractNetwork - **/ Ark::Crypto::Networks::AbstractNetwork Ark::Crypto::Configuration::Network::get() { - return (this->network_.getBase58Prefix(BASE58_ADDRESS_P2PKH) == 0x00) ? (Devnet) : (this->network_); + return (this->network_.getBase58Prefix(BASE58_ADDRESS_P2PKH) == 0x00) + ? (Devnet) + : (this->network_); } + /**/ -/** - * @brief Set the network used for crypto operations. - * - * @param AbstractNetwork network - **/ -void Ark::Crypto::Configuration::Network::set(const Ark::Crypto::Networks::AbstractNetwork& network) { +void Ark::Crypto::Configuration::Network::set( + const Ark::Crypto::Networks::AbstractNetwork& network) { this->network_ = network; }; -/**/ diff --git a/src/helpers/crypto.cpp b/src/helpers/crypto.cpp index 79494fae..9d2d9a85 100644 --- a/src/helpers/crypto.cpp +++ b/src/helpers/crypto.cpp @@ -1,6 +1,6 @@ + #include "helpers/crypto.h" -#include #include "bcl/Ecdsa.hpp" #include "bcl/Sha256.hpp" #include "bcl/Uint256.hpp" @@ -9,34 +9,66 @@ #include "uECC.h" #include "bip66.h" -void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, std::vector& signature) { +void cryptoSign( + Sha256Hash hash, + Ark::Crypto::Identities::PrivateKey privateKey, + std::vector& signature) { + // create r & s-values Uint256 r; Uint256 s; + // create the nonce uint8_t nonce32[32] = {}; - nonce_function_rfc6979(nonce32, hash.value, privateKey.toBytes(), nullptr, nullptr, 0); + nonce_function_rfc6979( + nonce32, + hash.value, + privateKey.toBytes(), + nullptr, nullptr, 0); + + // sign the hash using privateKey-bytes and nonce. + // outputs r & s-values. + Ecdsa::sign( + Uint256(privateKey.toBytes()), + hash, + Uint256(nonce32), + r, s); - auto ret = Ecdsa::sign(Uint256(privateKey.toBytes()), hash, Uint256(nonce32), r, s); - assert(ret); + // create r & s-value uint8_t vector + std::vector rValue(PRIVATEKEY_SIZE); + std::vector sValue(PRIVATEKEY_SIZE); - std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); + // plate big-endian bytes into r & s-value buffers r.getBigEndianBytes(&rValue[0]); s.getBigEndianBytes(&sValue[0]); + // encode r & s-values into a BIP66/DER-encoded signature. BIP66::encode(rValue, sValue, signature); } -bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, std::vector& signature) { - /* Get the Uncompressed PublicKey */ - auto publicKeyBytes = publicKey.toBytes(); // compressed publicKey bytes (uint8_t*) - uint8_t uncompressedPublicKey[64] = {}; // create uncompressed publicKey buffer (uint8_t[64]) - const struct uECC_Curve_t* curve = uECC_secp256k1(); // define the curve-type - uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); // decompress the key +/**/ + +bool cryptoVerify( + Ark::Crypto::Identities::PublicKey publicKey, + Sha256Hash hash, + std::vector& signature) { + // Get the Uncompressed PublicKey + + // compressed publicKey bytes (uint8_t*) + auto publicKeyBytes = publicKey.toBytes(); + + // create uncompressed publicKey buffer (uint8_t[64]) + uint8_t uncompressedPublicKey[64] = {}; + + // define the curve-type + const struct uECC_Curve_t* curve = uECC_secp256k1(); + + // decompress the key + uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); if (uECC_valid_public_key(uncompressedPublicKey, curve) == 0) { return false; }; // validate the uncompressed publicKey - /* Split uncompressed publicKey into (x,y) coordinate buffers */ + // Split uncompressed publicKey into (x,y) coordinate buffers char xBuffer[65] = "\0"; char yBuffer[65] = "\0"; for (int i = 0; i < 32; i++) { @@ -44,19 +76,21 @@ bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, snprintf(&yBuffer[i * 2], 64, "%02x", uncompressedPublicKey[i + 32]); } - /* Create curvepoint of uncompressed publicKey(x,y) */ - FieldInt x(xBuffer); // convert xBuffer to FieldInteger - FieldInt y(yBuffer); // convert yBuffer to FieldInteger + // Create curvepoint of uncompressed publicKey(x,y) + // convert xBuffer & yBuffer to FieldInteger + FieldInt x(xBuffer); + FieldInt y(yBuffer); CurvePoint curvePoint(x, y); - /* Decode signature from DER into r & s buffers */ - std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); - + /// Decode signature from DER into r & s buffers + std::vector rValue(PRIVATEKEY_SIZE); + std::vector sValue(PRIVATEKEY_SIZE); BIP66::decode(signature, rValue, sValue); - Uint256 r256(rValue.data()); // create Uint256/BigNumber from r-value buffer - Uint256 s256(sValue.data()); // create Uint256/BigNumber from s-value buffer + // create Uint256/BigNumber from r & s-value buffers + Uint256 r256(rValue.data()); + Uint256 s256(sValue.data()); - /* Verify */ + // Verify return Ecdsa::verify(curvePoint, hash, r256, s256); } diff --git a/src/helpers/crypto.h b/src/helpers/crypto.h index 204adaa4..a1c9629b 100644 --- a/src/helpers/crypto.h +++ b/src/helpers/crypto.h @@ -17,7 +17,16 @@ #ifndef CRYPTO_H #define CRYPTO_H -void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, std::vector& signature); -bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, std::vector& signature); +void cryptoSign( + Sha256Hash hash, + Ark::Crypto::Identities::PrivateKey privateKey, + std::vector& signature); + +/**/ + +bool cryptoVerify( + Ark::Crypto::Identities::PublicKey publicKey, + Sha256Hash hash, + std::vector& signature); #endif diff --git a/src/helpers/crypto_helpers.h b/src/helpers/crypto_helpers.h index b34a48ca..15e95ce1 100644 --- a/src/helpers/crypto_helpers.h +++ b/src/helpers/crypto_helpers.h @@ -15,10 +15,10 @@ #include #include -const auto ADDRESS_LENGTH = 34u; -const auto COMPRESSED_PUBLICKEY_SIZE = 33u; -const auto PRIVATEKEY_SIZE = 32u; -const auto WIF_SIZE = 52u; +const auto ADDRESS_LENGTH = 34U; +const auto COMPRESSED_PUBLICKEY_SIZE = 33U; +const auto PRIVATEKEY_SIZE = 32U; +const auto WIF_SIZE = 52U; #if (defined ARDUINO || defined ESP8266 || defined ESP32) @@ -44,8 +44,12 @@ inline void unpack(T* dst, uint8_t* src, size_t size = -1) { // Join string vector inline std::string join(const std::vector& strings) { - return std::accumulate(strings.begin(), strings.end(), std::string(), - [](const std::string& a, const std::string& b) -> std::string { return a + b; }); + return std::accumulate( + strings.begin(), + strings.end(), + std::string(), + [](const std::string& a, const std::string& b) + -> std::string { return a + b; }); } #endif diff --git a/src/helpers/json.h b/src/helpers/json.h index a4b8c984..d28d8234 100644 --- a/src/helpers/json.h +++ b/src/helpers/json.h @@ -2,12 +2,12 @@ #ifndef JSON_H #define JSON_H -/* ArduinoJson Presets */ +// ArduinoJson Presets #define ARDUINOJSON_USE_LONG_LONG 1 #define ARDUINOJSON_ENABLE_STD_STRING 1 // Enable 'std::string' #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 // disable 'String' -/* ArduinoJson Header */ +// ArduinoJson Header #include "ArduinoJson.h" #endif diff --git a/src/identities/address.cpp b/src/identities/address.cpp index ce1ff11e..5fbfac68 100644 --- a/src/identities/address.cpp +++ b/src/identities/address.cpp @@ -1,147 +1,110 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/address.h" -/** - * @brief: constructor - * - * @param: const char *const newAddressStr - **/ -Ark::Crypto::Identities::Address::Address(const char *const newAddressStr) { +#include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" + +#include + +Ark::Crypto::Identities::Address::Address( + const char* newAddressStr) { (strlen(newAddressStr) == ADDRESS_LENGTH) - ? void(memmove(this->bytes_, reinterpret_cast(newAddressStr), ADDRESS_LENGTH)) + ? void(memmove( + this->bytes_, + reinterpret_cast(newAddressStr), + ADDRESS_LENGTH)) : void(this->bytes_[COMPRESSED_PUBLICKEY_SIZE] = {'\0'}); } /**/ -Ark::Crypto::Identities::Address::Address(const uint8_t *newAddressBytes) { +Ark::Crypto::Identities::Address::Address( + const uint8_t* newAddressBytes) { memmove(this->bytes_, newAddressBytes, ADDRESS_LENGTH); } + /**/ -/** - * @brief: returns bytes of Address - * - * @return const uint8_t - **/ const uint8_t *Ark::Crypto::Identities::Address::toBytes() { return this->bytes_; } + /**/ -/** - * @brief: returns std::string representation of stored bytes - **/ std::string Ark::Crypto::Identities::Address::toString() const { return std::string(this->bytes_, this->bytes_ + ADDRESS_LENGTH); } + /**/ -/** - * @brief Derive the address from the given passphrase. - * - * @param const char* const passphrase - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPassphrase(const char *const passphrase, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPassphrase( + const char* passphrase, + uint8_t networkVersion) { PublicKey publicKey = PublicKey::fromPassphrase(passphrase); return fromPublicKey(publicKey, networkVersion); } + /**/ -/** - * @brief Derive the address from the given private key. - * - * @param PrivateKey privateKey - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPrivateKey(PrivateKey privateKey, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPrivateKey( + PrivateKey privateKey, + uint8_t networkVersion) { PublicKey publicKey = PublicKey::fromPrivateKey(privateKey); return fromPublicKey(publicKey, networkVersion); } + /**/ -/** - * @brief Derive the address from the given public key. - * - * @param PublicKey publicKey - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPublicKey(PublicKey publicKey, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPublicKey( + PublicKey publicKey, + uint8_t networkVersion) { std::vector seed(Ripemd160::HASH_LEN); - Ripemd160::getHash(publicKey.toBytes(), COMPRESSED_PUBLICKEY_SIZE, &seed[0]); + Ripemd160::getHash( + publicKey.toBytes(), + COMPRESSED_PUBLICKEY_SIZE, + &seed[0]); std::string s(35, '\0'); Base58Check::pubkeyHashToBase58Check(&seed[0], networkVersion, &s[0]); - return {s.c_str()}; + return { s.c_str() }; } + /**/ -/** - * @brief Validate the given address. - * - * @param Address address - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(Address address, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + Address address, + uint8_t networkVersion) { std::uint8_t pub_key_hash[Ripemd160::HASH_LEN] = {}; uint8_t version = 0; - Base58Check::pubkeyHashFromBase58Check(address.toString().c_str(), pub_key_hash, &version); + Base58Check::pubkeyHashFromBase58Check( + address.toString().c_str(), + pub_key_hash, + &version); return version == networkVersion; } + /**/ -/** - * @brief Validate the given Address string to the network version. - * - * @param const char *const privateKey - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(const char *const addressStr, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + const char* addressStr, + uint8_t networkVersion) { return validate(Address(addressStr), networkVersion); } + /**/ -/** - * @brief Validate the given Address bytes to the network version. - * - * @param const uint8_t *addressBytes - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(const uint8_t *addressBytes, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + const uint8_t* addressBytes, + uint8_t networkVersion) { return validate(Address(addressBytes), networkVersion); } + /**/ -/** - * @brief Reads 21 bytes from source and returns an base58 encoded string - * - * @param uint8_t *source - * - * @return std::string - **/ -std::string Ark::Crypto::Identities::Address::base58encode(const uint8_t *source) { +std::string Ark::Crypto::Identities::Address::base58encode( + const uint8_t* source) { // Magic numbers from Base58Check::pubkeyHashToBase58Check uint8_t temp[21 + 4] = {}; char out[ADDRESS_LENGTH + 1] = {}; @@ -154,18 +117,17 @@ std::string Ark::Crypto::Identities::Address::base58encode(const uint8_t *source return std::string(out); } -/** - * @brief Decodes the base58 encoded address - * - * @param const char* const address - * - * @return std::vector - **/ -std::vector Ark::Crypto::Identities::Address::bytesFromBase58Check(const char *const address) { +/**/ + +std::vector Ark::Crypto::Identities::Address::bytesFromBase58Check( + const char* address) { std::vector recipientIdBytes; recipientIdBytes.resize(Ripemd160::HASH_LEN); uint8_t version = 0; - Base58Check::pubkeyHashFromBase58Check(address, &recipientIdBytes[0], &version); + Base58Check::pubkeyHashFromBase58Check( + address, + &recipientIdBytes[0], + &version); recipientIdBytes.insert(recipientIdBytes.begin(), version); return recipientIdBytes; diff --git a/src/identities/privatekey.cpp b/src/identities/privatekey.cpp index 2c49d4c9..35c17435 100644 --- a/src/identities/privatekey.cpp +++ b/src/identities/privatekey.cpp @@ -1,125 +1,101 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/privatekey.h" -/** - * - **/ -Ark::Crypto::Identities::PrivateKey::PrivateKey(const char *const newPrivateKeyStr) { - memmove(this->bytes_, &HexToBytes(newPrivateKeyStr).data()[0], PRIVATEKEY_SIZE); +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" +#include "bcl/Sha256.hpp" +#include "bcl/Sha256Hash.hpp" + +#include +#include +#include + +Ark::Crypto::Identities::PrivateKey::PrivateKey( + const char* newPrivateKeyStr) { + memmove( + this->bytes_, + HexToBytes(newPrivateKeyStr).data(), + PRIVATEKEY_SIZE); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PrivateKey::PrivateKey(const uint8_t *newPrivateKeyBytes) { +Ark::Crypto::Identities::PrivateKey::PrivateKey( + const uint8_t* newPrivateKeyBytes) { memmove(this->bytes_, newPrivateKeyBytes, PRIVATEKEY_SIZE); } + /**/ -/** - * - **/ const uint8_t *Ark::Crypto::Identities::PrivateKey::toBytes() { return this->bytes_; }; + /**/ -/** - * - **/ std::string Ark::Crypto::Identities::PrivateKey::toString() const { return BytesToHex(this->bytes_, this->bytes_ + PRIVATEKEY_SIZE); } + /**/ -/** - * @brief Derive the private key for the given passphrase. - * - * @param const char* const passphrase - * - * @return std::string - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromPassphrase(const char *const passphrase) { +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromPassphrase( + const char* passphrase) { std::vector privateKey(PRIVATEKEY_SIZE); - auto hash = Sha256::getHash(reinterpret_cast(passphrase), strlen(passphrase)); + auto hash = Sha256::getHash( + reinterpret_cast(passphrase), + strlen(passphrase)); memcpy(&privateKey[0], hash.value, privateKey.size()); - return {BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str()}; + return { + BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Create a private key instance from a hex string. - * - * @param const char *const privateKey - * - * @return PrivateKey - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromHex(const char *const privateKey) { - return {privateKey}; +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromHex( + const char* privateKey) { + return { privateKey }; } + /**/ -/** - * @brief Derive the private key for the given WIF. - * - * @param const char* wifStr - * @param uint8_t wifByte - * - * @return PrivateKey - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromWIFString(const char *wifStr, - uint8_t wifByte) { +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromWIFString( + const char* wifStr, + uint8_t wifByte) { Uint256 bigNum; bool compressed = true; - auto ret = Base58Check::privateKeyFromBase58Check(wifStr, bigNum, &wifByte, &compressed); - assert(ret); + Base58Check::privateKeyFromBase58Check( + wifStr, + bigNum, + &wifByte, + &compressed); std::vector privateKey(PRIVATEKEY_SIZE); bigNum.getBigEndianBytes(&privateKey[0]); - return {BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str()}; + return { + BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Validate the given private key. - * - * @param PrivateKey privateKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(PrivateKey privateKey) { +bool Ark::Crypto::Identities::PrivateKey::validate( + PrivateKey privateKey) { return PrivateKey::validate(privateKey.toString().c_str()); -}; +} + /**/ -/** - * @brief Validate the given private key. - * - * @param const char *const privateKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(const char *privateKeyStr) { - return ((strlen(privateKeyStr) / 2) == PRIVATEKEY_SIZE); // check length +bool Ark::Crypto::Identities::PrivateKey::validate( + const char* privateKeyStr) { + // check length + return ((strlen(privateKeyStr) / 2) == PRIVATEKEY_SIZE); } + /**/ -/** - * @brief Validate the given private key. - * - * @param const uint8_t *privateKeyBytes - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(const uint8_t *privateKeyBytes) { +bool Ark::Crypto::Identities::PrivateKey::validate( + const uint8_t* privateKeyBytes) { return validate(PrivateKey(privateKeyBytes)); } -/**/ diff --git a/src/identities/publickey.cpp b/src/identities/publickey.cpp index 3363f879..c33b7129 100644 --- a/src/identities/publickey.cpp +++ b/src/identities/publickey.cpp @@ -1,134 +1,113 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ + #include "identities/publickey.h" + +#include "helpers/encoding/hex.h" + #include "uECC.h" -/** - * - **/ -Ark::Crypto::Identities::PublicKey::PublicKey(const char *const newPublicKeyStr) { - memmove(this->bytes_, &HexToBytes(newPublicKeyStr).data()[0], COMPRESSED_PUBLICKEY_SIZE); + +#include +#include +#include +#include + +Ark::Crypto::Identities::PublicKey::PublicKey( + const char* newPublicKeyStr) { + memmove( + this->bytes_, + HexToBytes(newPublicKeyStr).data(), + COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PublicKey::PublicKey(const uint8_t *newPublicKeyBytes) { +Ark::Crypto::Identities::PublicKey::PublicKey( + const uint8_t* newPublicKeyBytes) { memmove(this->bytes_, newPublicKeyBytes, COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * - **/ -const uint8_t *Ark::Crypto::Identities::PublicKey::toBytes() { +const uint8_t* Ark::Crypto::Identities::PublicKey::toBytes() { return this->bytes_; } + /**/ -/** - * - **/ bool Ark::Crypto::Identities::PublicKey::isValid() { return PublicKey::validate(*this); } + /**/ -/** - * - **/ std::string Ark::Crypto::Identities::PublicKey::toString() const { return BytesToHex(this->bytes_, this->bytes_ + COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * @brief Derive the public from the given passphrase. - * - * @param const char *const passphrase - * - * @return std::string - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPassphrase(const char *const passphrase) { +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPassphrase( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); return PublicKey::fromPrivateKey(privateKey); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPrivateKey(PrivateKey privateKey) { +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPrivateKey( + PrivateKey privateKey) { std::vector publicKey(COMPRESSED_PUBLICKEY_SIZE); const struct uECC_Curve_t *curve = uECC_secp256k1(); uint8_t pub[64] = {}; // TODO: using the current uECC implementation, a private key value of "1" will return a false negative. // It appears to be not supported given the following issue: https://github.com/kmackay/micro-ecc/issues/128 const uint8_t *privkeyBytes = privateKey.toBytes(); - auto ret = uECC_compute_public_key( - &privkeyBytes[0], pub, curve); // Don't check the return inline with the assert. MSVC optimizer does bad things. - assert(ret != 0); - assert(publicKey.size() == COMPRESSED_PUBLICKEY_SIZE); + // Don't check the return inline with the assert. MSVC optimizer does bad things. + uECC_compute_public_key( + &privkeyBytes[0], + pub, + curve); uECC_compress(pub, &publicKey[0], curve); - return {BytesToHex(&publicKey[0], &publicKey[0] + COMPRESSED_PUBLICKEY_SIZE).c_str()}; + return { + BytesToHex(&publicKey[0], &publicKey[0] + COMPRESSED_PUBLICKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Create a public key instance from a hex string. - * - * @param const char *const publicKey - * - * @return PublicKey - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromHex(const char *const publicKey) { - return {publicKey}; -}; +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromHex( + const char* publicKey) { + return { publicKey }; +} + /**/ -/** - * @brief Validate the given public key. - * - * @param PublicKey publicKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(PublicKey publicKey) { - auto publicKeyBytes = publicKey.toBytes(); // compressed publicKey bytes (uint8_t*) - uint8_t uncompressedPublicKey[64] = {}; // create uncompressed publicKey buffer (uint8_t[64]) - const struct uECC_Curve_t *curve = uECC_secp256k1(); // define the curve-type - uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); // decompress the key - return uECC_valid_public_key(uncompressedPublicKey, curve); // validate the uncompressed publicKey +bool Ark::Crypto::Identities::PublicKey::validate( + PublicKey publicKey) { + // compressed publicKey bytes (uint8_t*) + auto publicKeyBytes = publicKey.toBytes(); + // create uncompressed publicKey buffer (uint8_t[64]) + uint8_t uncompressedPublicKey[64] = {}; + // define the curve-type + const struct uECC_Curve_t *curve = uECC_secp256k1(); + + // decompress the key + uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); + + // validate the uncompressed publicKey + return (uECC_valid_public_key(uncompressedPublicKey, curve) != 0); } + /**/ -/** - * @brief Validate the given public key. - * - * @param const char *const publicKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(const char *publicKeyStr) { +bool Ark::Crypto::Identities::PublicKey::validate( + const char* publicKeyStr) { return validate(PublicKey(publicKeyStr)); } + /**/ -/** - * @brief Validate the given public key. - * - * @param const uint8_t *publicKeyBytes - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(const uint8_t *publicKeyBytes) { +bool Ark::Crypto::Identities::PublicKey::validate( + const uint8_t* publicKeyBytes) { return validate(PublicKey(publicKeyBytes)); } -/**/ diff --git a/src/identities/wif.cpp b/src/identities/wif.cpp index f1cbc294..14e71e28 100644 --- a/src/identities/wif.cpp +++ b/src/identities/wif.cpp @@ -1,53 +1,63 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/wif.h" -/**/ -Ark::Crypto::Identities::WIF::WIF(const char *const newWIFStr) { - (std::strlen(newWIFStr) == WIF_SIZE) - ? void(std::memmove(this->bytes_, reinterpret_cast(newWIFStr), WIF_SIZE)) +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" +#include "bcl/Uint256.hpp" + +#include +#include +#include +#include + +Ark::Crypto::Identities::WIF::WIF( + const char* newWIFStr) { + (strlen(newWIFStr) == WIF_SIZE) + ? void(memmove( + this->bytes_, + reinterpret_cast(newWIFStr), + WIF_SIZE)) : void(this->bytes_[WIF_SIZE - 1] = {'\0'}); } -/**/ /**/ -Ark::Crypto::Identities::WIF::WIF(const uint8_t *newWIFBytes) { - std::memmove(this->bytes_, newWIFBytes, WIF_SIZE); + +Ark::Crypto::Identities::WIF::WIF( + const uint8_t* newWIFBytes) { + memmove(this->bytes_, newWIFBytes, WIF_SIZE); } -/**/ /**/ + const uint8_t *Ark::Crypto::Identities::WIF::toBytes() { return this->bytes_; }; -/**/ /**/ + std::string Ark::Crypto::Identities::WIF::toString() const { return std::string(this->bytes_, this->bytes_ + WIF_SIZE); } + +/**/ + +bool Ark::Crypto::Identities::WIF::validate(WIF wif) { + const auto wifString = wif.toString(); + return strrchr(wifString.c_str(), '\0') == nullptr; +} + /**/ -/** - * @brief Derive the WIF from the given passphrase. - * - * @param const char *const passphrase - * @param uint8_t wifByte - * - * @return WIF - **/ -Ark::Crypto::Identities::WIF Ark::Crypto::Identities::WIF::fromPassphrase(const char *const passphrase, - uint8_t wifByte) { +Ark::Crypto::Identities::WIF Ark::Crypto::Identities::WIF::fromPassphrase( + const char* passphrase, + uint8_t wifByte) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); std::string wifStr(53, '\0'); - Base58Check::privateKeyToBase58Check(Uint256(privateKey.toString().c_str()), wifByte, true, &wifStr[0]); - return {wifStr.c_str()}; + Base58Check::privateKeyToBase58Check( + Uint256(privateKey.toString().c_str()), + wifByte, + true, + &wifStr[0]); + return { wifStr.c_str() }; } -/**/ diff --git a/src/include/cpp-crypto/configuration/fee.h b/src/include/cpp-crypto/configuration/fee.h index 986c5634..d982b225 100644 --- a/src/include/cpp-crypto/configuration/fee.h +++ b/src/include/cpp-crypto/configuration/fee.h @@ -12,6 +12,7 @@ #include "enums/fees.h" #include "enums/types.h" + using namespace Ark::Crypto::Enums; #include @@ -19,33 +20,27 @@ using namespace Ark::Crypto::Enums; namespace Ark { namespace Crypto { namespace Configuration { -/** - * This is the fee configuration class. - * - * @author Simon Downey - **/ +/**/ class Fee { - private: - /** - * @brief The default transaction fees array. - **/ - uint64_t fees_[9] = {Fees::TRANSFER, - Fees::SECOND_SIGNATURE_REGISTRATION, - Fees::DELEGATE_REGISTRATION, - Fees::VOTE, - Fees::MULTI_SIGNATURE_REGISTRATION, - Fees::IPFS, - Fees::TIMELOCK_TRANSFER, - Fees::MULTI_PAYMENT, - Fees::DELEGATE_RESIGNATION}; - /**/ - public: +private: + uint64_t fees_[9] = { + Fees::TRANSFER, + Fees::SECOND_SIGNATURE_REGISTRATION, + Fees::DELEGATE_REGISTRATION, + Fees::VOTE, + Fees::MULTI_SIGNATURE_REGISTRATION, + Fees::IPFS, + Fees::TIMELOCK_TRANSFER, + Fees::MULTI_PAYMENT, + Fees::DELEGATE_RESIGNATION + }; + +public: Fee() = default; uint64_t get(int type); void set(int type, uint64_t fee); }; /**/ - }; // namespace Configuration }; // namespace Crypto }; // namespace Ark diff --git a/src/include/cpp-crypto/configuration/network.h b/src/include/cpp-crypto/configuration/network.h index a6bb4d4e..9093291e 100644 --- a/src/include/cpp-crypto/configuration/network.h +++ b/src/include/cpp-crypto/configuration/network.h @@ -15,24 +15,17 @@ #include "networks/mainnet.h" #include "networks/testnet.h" -#include - namespace Ark { namespace Crypto { namespace Configuration { - +/**/ using namespace Ark::Crypto::Networks; - -/** - * @brief This is the network configuration class. - * - * @author Simon Downey - **/ +/**/ class Network { - private: +private: AbstractNetwork network_; - public: +public: AbstractNetwork get(); void set(const AbstractNetwork& network); }; diff --git a/src/include/cpp-crypto/enums/fees.h b/src/include/cpp-crypto/enums/fees.h index 9aa58e22..38a3eeb2 100644 --- a/src/include/cpp-crypto/enums/fees.h +++ b/src/include/cpp-crypto/enums/fees.h @@ -15,22 +15,17 @@ namespace Ark { namespace Crypto { namespace Enums { -/** - * This is the transaction fees class. - * - * @author Simon Downey - **/ +/**/ struct Fees { - public: - static const uint64_t TRANSFER = 10000000; - static const uint64_t SECOND_SIGNATURE_REGISTRATION = 500000000; - static const uint64_t DELEGATE_REGISTRATION = 2500000000; - static const uint64_t VOTE = 100000000; - static const uint64_t MULTI_SIGNATURE_REGISTRATION = 500000000; - static const uint64_t IPFS = 0; - static const uint64_t TIMELOCK_TRANSFER = 0; - static const uint64_t MULTI_PAYMENT = 0; - static const uint64_t DELEGATE_RESIGNATION = 0; + static const uint64_t TRANSFER = 10000000ULL; + static const uint64_t SECOND_SIGNATURE_REGISTRATION = 500000000ULL; + static const uint64_t DELEGATE_REGISTRATION = 2500000000ULL; + static const uint64_t VOTE = 100000000ULL; + static const uint64_t MULTI_SIGNATURE_REGISTRATION = 500000000ULL; + static const uint64_t IPFS = 0ULL; + static const uint64_t TIMELOCK_TRANSFER = 0ULL; + static const uint64_t MULTI_PAYMENT = 0ULL; + static const uint64_t DELEGATE_RESIGNATION = 0ULL; }; /**/ }; // namespace Enums diff --git a/src/include/cpp-crypto/enums/types.h b/src/include/cpp-crypto/enums/types.h index b7e6a088..33c04d01 100644 --- a/src/include/cpp-crypto/enums/types.h +++ b/src/include/cpp-crypto/enums/types.h @@ -13,21 +13,17 @@ namespace Ark { namespace Crypto { namespace Enums { -/** - * This is the transaction types class. - * - * @author Simon Downey - **/ -enum Types : int { - TRANSFER = 0, - SECOND_SIGNATURE_REGISTRATION = 1, - DELEGATE_REGISTRATION = 2, - VOTE = 3, - MULTI_SIGNATURE_REGISTRATION = 4, - IPFS = 5, - TIMELOCK_TRANSFER = 6, - MULTI_PAYMENT = 7, - DELEGATE_RESIGNATION = 8 +/**/ +enum Types : unsigned { + TRANSFER = 0U, + SECOND_SIGNATURE_REGISTRATION = 1U, + DELEGATE_REGISTRATION = 2U, + VOTE = 3U, + MULTI_SIGNATURE_REGISTRATION = 4U, + IPFS = 5U, + TIMELOCK_TRANSFER = 6U, + MULTI_PAYMENT = 7U, + DELEGATE_RESIGNATION = 8U }; /**/ }; // namespace Enums diff --git a/src/include/cpp-crypto/helpers/encoding/hex.h b/src/include/cpp-crypto/helpers/encoding/hex.h index bc14ad19..88954764 100644 --- a/src/include/cpp-crypto/helpers/encoding/hex.h +++ b/src/include/cpp-crypto/helpers/encoding/hex.h @@ -17,49 +17,58 @@ * Hex Helpers **/ template -inline std::string BytesToHex(const T itbegin, const T itend, bool fSpaces = false) { +inline std::string BytesToHex( + const T itbegin, + const T itend) { + static const char hexmap[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' + }; + std::string rv; - static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; rv.reserve((itend - itbegin) * 3); for (T it = itbegin; it < itend; ++it) { const auto val = static_cast(*it); - if (fSpaces && it != itbegin) { - rv.push_back(' '); - } rv.push_back(hexmap[val >> 4]); rv.push_back(hexmap[val & 15]); } return rv; -} +}; /**/ template -inline std::string BytesToHex(const T& vch, bool fSpaces = false) { - return BytesToHex(vch.begin(), vch.end(), fSpaces); -} +inline std::string BytesToHex(const T& vch) { + return BytesToHex(vch.begin(), vch.end()); +}; -/********/ +/****/ const int8_t p_util_hexdigit[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; /**/ inline int8_t HexDigit(char c) { return p_util_hexdigit[static_cast(c)]; -} +}; /**/ @@ -67,23 +76,17 @@ inline std::vector HexToBytes(const char* psz) { // convert hex dump to vector std::vector vch; for (;;) { - while (isspace(*psz) != 0) { - psz++; - } + while (isspace(*psz) != 0) { psz++; }; auto c = HexDigit(*psz++); - if (c == static_cast(-1)) { - break; - } + if (c == static_cast(-1)) { break; }; int8_t n = (c << 4); c = HexDigit(*psz++); - if (c == static_cast(-1)) { - break; - } + if (c == static_cast(-1)) { break; }; n |= c; vch.push_back(n); - } + }; return vch; -} +}; /**/ diff --git a/src/include/cpp-crypto/identities/address.h b/src/include/cpp-crypto/identities/address.h index 7e71087d..48cb3cdb 100644 --- a/src/include/cpp-crypto/identities/address.h +++ b/src/include/cpp-crypto/identities/address.h @@ -10,42 +10,39 @@ #ifndef ADDRESS_H #define ADDRESS_H -#include -#include "helpers/encoding/hex.h" #include "helpers/crypto_helpers.h" + #include "identities/privatekey.h" #include "identities/publickey.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the address class. - * - * @author Simon Downey - **/ +/**/ class Address { - protected: - uint8_t bytes_[ADDRESS_LENGTH]; +private: + uint8_t bytes_[ADDRESS_LENGTH] {}; - public: - Address() : bytes_(){}; - Address(const char *const newAddressStr); - Address(const uint8_t *newAddressBytes); +public: + Address() : bytes_() {}; + Address(const char* newAddressStr); + Address(const uint8_t* newAddressBytes); const uint8_t *toBytes(); std::string toString() const; - static Address fromPassphrase(const char *const passphrase, uint8_t networkVersion); + static Address fromPassphrase(const char* passphrase, uint8_t networkVersion); static Address fromPrivateKey(PrivateKey privateKey, uint8_t networkVersion); static Address fromPublicKey(PublicKey publicKey, uint8_t networkVersion); static bool validate(Address address, uint8_t networkVersion); - static bool validate(const char *const addressStr, uint8_t networkVersion); - static bool validate(const uint8_t *addressBytes, uint8_t networkVersion); - static std::string base58encode(const uint8_t *source); - static std::vector bytesFromBase58Check(const char *const address); + static bool validate(const char* addressStr, uint8_t networkVersion); + static bool validate(const uint8_t* addressBytes, uint8_t networkVersion); + static std::string base58encode(const uint8_t* source); + static std::vector bytesFromBase58Check(const char* address); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/privatekey.h b/src/include/cpp-crypto/identities/privatekey.h index f69da3c7..e442fb1d 100644 --- a/src/include/cpp-crypto/identities/privatekey.h +++ b/src/include/cpp-crypto/identities/privatekey.h @@ -10,42 +10,34 @@ #ifndef PRIVATEKEY_H #define PRIVATEKEY_H -#include -#include -#include "bcl/Base58Check.hpp" -#include "bcl/Sha256.hpp" -#include "bcl/Sha256Hash.hpp" -#include "helpers/encoding/hex.h" #include "helpers/crypto_helpers.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the private key class. - * - * @author Simon Downey - **/ +/**/ class PrivateKey { - protected: - uint8_t bytes_[PRIVATEKEY_SIZE]; +private: + uint8_t bytes_[PRIVATEKEY_SIZE] {}; - public: - PrivateKey() : bytes_(){}; - PrivateKey(const char *const newPrivateKeyStr); - PrivateKey(const uint8_t *newPrivateKeyBytes); +public: + PrivateKey() : bytes_() {}; + PrivateKey(const char* newPrivateKeyStr); + PrivateKey(const uint8_t* newPrivateKeyBytes); const uint8_t *toBytes(); std::string toString() const; - static PrivateKey fromPassphrase(const char *const passphrase); - static PrivateKey fromHex(const char *const privateKey); - static PrivateKey fromWIFString(const char *wifStr, uint8_t wifByte); + static PrivateKey fromPassphrase(const char* passphrase); + static PrivateKey fromHex(const char* privateKey); + static PrivateKey fromWIFString(const char* wifStr, uint8_t wifByte); static bool validate(PrivateKey privateKey); - static bool validate(const char *privateKeyStr); - static bool validate(const uint8_t *privateKeyBytes); + static bool validate(const char* privateKeyStr); + static bool validate(const uint8_t* privateKeyBytes); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/publickey.h b/src/include/cpp-crypto/identities/publickey.h index 5dd35642..03cc4d2c 100644 --- a/src/include/cpp-crypto/identities/publickey.h +++ b/src/include/cpp-crypto/identities/publickey.h @@ -10,40 +10,39 @@ #ifndef PUBLICKEY_H #define PUBLICKEY_H -#include -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" #include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "helpers/crypto_helpers.h" + +#include +#include namespace Ark { namespace Crypto { namespace Identities { -/** - * This is the public key class. - * - * @author Simon Downey - **/ +/**/ class PublicKey { - protected: - uint8_t bytes_[COMPRESSED_PUBLICKEY_SIZE]; +private: + uint8_t bytes_[COMPRESSED_PUBLICKEY_SIZE] {}; - public: - PublicKey() : bytes_(){}; - PublicKey(const char *const newPublicKeyStr); - PublicKey(const uint8_t *newPublicKeyBytes); +public: + PublicKey() : bytes_() {}; + PublicKey(const char* newPublicKeyStr); + PublicKey(const uint8_t* newPublicKeyBytes); const uint8_t *toBytes(); bool isValid(); std::string toString() const; - static PublicKey fromPassphrase(const char *const passphrase); + static PublicKey fromPassphrase(const char* passphrase); static PublicKey fromPrivateKey(PrivateKey privateKey); - static PublicKey fromHex(const char *const publicKey); + static PublicKey fromHex(const char* publicKey); static bool validate(PublicKey publicKey); - static bool validate(const char *publicKeyStr); - static bool validate(const uint8_t *publicKeyBytes); + static bool validate(const char* publicKeyStr); + static bool validate(const uint8_t* publicKeyBytes); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/wif.h b/src/include/cpp-crypto/identities/wif.h index 096eac64..8d00d9ae 100644 --- a/src/include/cpp-crypto/identities/wif.h +++ b/src/include/cpp-crypto/identities/wif.h @@ -10,32 +10,30 @@ #ifndef WIF_H #define WIF_H -#include -#include "helpers/encoding/hex.h" #include "identities/privatekey.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the wif class. - * - * @author Simon Downey - **/ +/**/ class WIF { - protected: - uint8_t bytes_[WIF_SIZE]; +private: + uint8_t bytes_[WIF_SIZE] {}; - public: - WIF() : bytes_(){}; - WIF(const char *const newWIFStr); - WIF(const uint8_t *newWIFBytes); +public: + WIF() : bytes_() {}; + WIF(const char* newWIFStr); + WIF(const uint8_t* newWIFBytes); const uint8_t *toBytes(); std::string toString() const; - static WIF fromPassphrase(const char *const passphrase, uint8_t wifByte); + static WIF fromPassphrase(const char* passphrase, uint8_t wifByte); + + static bool validate(WIF wif); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/networks/abstractnetwork.h b/src/include/cpp-crypto/networks/abstractnetwork.h index 9d49d0ef..a0f2086c 100644 --- a/src/include/cpp-crypto/networks/abstractnetwork.h +++ b/src/include/cpp-crypto/networks/abstractnetwork.h @@ -21,7 +21,11 @@ namespace Networks { /** * @brief Base58 Prefix Type **/ -enum Base58PrefixType : int { BASE58_ADDRESS_P2PKH = 0, BASE58_ADDRESS_P2SH, BASE58_WIF }; +enum Base58PrefixType : int { + BASE58_ADDRESS_P2PKH = 0, + BASE58_ADDRESS_P2SH, + BASE58_WIF +}; /**/ /** @@ -37,8 +41,12 @@ struct base58_t { /** * @brief BIP32 Prefix Type **/ -enum BIP32PrefixType : int { BIP32_PREFIX_XPUB = 0, BIP32_PREFIX_XPRV }; +enum BIP32PrefixType : int { + BIP32_PREFIX_XPUB = 0, + BIP32_PREFIX_XPRV +}; /**/ + /** * @brief BIP32 Prefix Container **/ @@ -50,34 +58,29 @@ struct bip32_t { /** * @brief This is the abstract network class. - * - * @author Simon Downey **/ class AbstractNetwork { - protected: +private: base58_t base58_; bip32_t bip32_; char epoch_[34]; bool isLocked_; - public: - AbstractNetwork() = default; +public: + AbstractNetwork() : isLocked_(false) {}; + virtual ~AbstractNetwork() = default; - /** - * @brief Abstract Network Parameter Instantiation interface - * - * @param base58_t base58 - * @param bip32_t bip32 - * @param char epoch[34] - * @param bool isEditable // default false - **/ - AbstractNetwork(base58_t base58, bip32_t bip32, const char* epoch, bool locked = true) - : base58_(base58), bip32_(bip32), epoch_(), isLocked_(locked) { - std::strncpy(this->epoch_, epoch, 34); + AbstractNetwork( + base58_t base58, + bip32_t bip32, + const char* epoch, + bool locked = true) + : base58_(base58), + bip32_(bip32), + epoch_(), + isLocked_(locked) { + strncpy(this->epoch_, epoch, 34); }; - /**/ - - virtual ~AbstractNetwork() = default; uint8_t getBase58Prefix(Base58PrefixType prefix) const; void setBase58Prefix(Base58PrefixType prefix, uint8_t newByte); diff --git a/src/include/cpp-crypto/networks/devnet.h b/src/include/cpp-crypto/networks/devnet.h index 3e48f276..504b1d73 100644 --- a/src/include/cpp-crypto/networks/devnet.h +++ b/src/include/cpp-crypto/networks/devnet.h @@ -15,22 +15,18 @@ namespace Ark { namespace Crypto { namespace Networks { -/** - * This is the devnet network class. - * - * @author Simon Downey - **/ +/**/ const AbstractNetwork Devnet = { - { - 0x1E, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch + { + 0x1E, // BASE58_ADDRESS_P2PKH + 0x00, // BASE58_ADDRESS_P2SH + 0xaa // BASE58_WIF + }, + { + 46090600, // BIP32_PREFIX_XPUB + 46089520 // BIP32_PREFIX_XPRV + }, + "2017-03-21T13:00:00.000Z" // Epoch }; /**/ }; // namespace Networks diff --git a/src/include/cpp-crypto/networks/mainnet.h b/src/include/cpp-crypto/networks/mainnet.h index 00a6d189..da8fbae7 100644 --- a/src/include/cpp-crypto/networks/mainnet.h +++ b/src/include/cpp-crypto/networks/mainnet.h @@ -15,22 +15,18 @@ namespace Ark { namespace Crypto { namespace Networks { -/** - * @brief This is the mainnet network class. - * - * @author Simon Downey - **/ +/**/ const AbstractNetwork Mainnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch + { + 0x17, // BASE58_ADDRESS_P2PKH + 0x00, // BASE58_ADDRESS_P2SH + 0xaa // BASE58_WIF + }, + { + 46090600, // BIP32_PREFIX_XPUB + 46089520 // BIP32_PREFIX_XPRV + }, + "2017-03-21T13:00:00.000Z" // Epoch }; /**/ }; // namespace Networks diff --git a/src/include/cpp-crypto/networks/testnet.h b/src/include/cpp-crypto/networks/testnet.h index 97689c78..e66e36aa 100644 --- a/src/include/cpp-crypto/networks/testnet.h +++ b/src/include/cpp-crypto/networks/testnet.h @@ -15,22 +15,18 @@ namespace Ark { namespace Crypto { namespace Networks { -/** - * @brief This is the testnet network class. - * - * @author Simon Downey - **/ +/**/ const AbstractNetwork Testnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xba // BASE58_WIF - }, - { - 70617039, // BIP32_PREFIX_XPUB - 70615956 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch + { + 0x17, // BASE58_ADDRESS_P2PKH + 0x00, // BASE58_ADDRESS_P2SH + 0xba // BASE58_WIF + }, + { + 70617039, // BIP32_PREFIX_XPUB + 70615956 // BIP32_PREFIX_XPRV + }, + "2017-03-21T13:00:00.000Z" // Epoch }; /**/ }; // namespace Networks diff --git a/src/include/cpp-crypto/transactions/builder.h b/src/include/cpp-crypto/transactions/builder.h index bf69dde0..13004855 100644 --- a/src/include/cpp-crypto/transactions/builder.h +++ b/src/include/cpp-crypto/transactions/builder.h @@ -12,12 +12,16 @@ #include "transactions/transaction.h" +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Builder { - public: +public: /** * Builder::buildTransfer() * @@ -25,26 +29,46 @@ class Builder { * If amount is not > 0, Builder will return an empty Transaction object and * validation will fail. **/ - static Transaction buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, - std::string passphrase, std::string secondPassphrase = ""); + static Transaction buildTransfer( + std::string recipientId, + uint64_t amount, + std::string vendorField, + std::string passphrase, + std::string secondPassphrase = ""); /**/ - static Transaction buildSecondSignatureRegistration(std::string passphrase, std::string secondPassphrase = ""); - static Transaction buildDelegateRegistration(std::string username, std::string passphrase, - std::string secondPassphrase = ""); - static Transaction buildVote(std::vector votes, std::string passphrase, - std::string secondPassphrase = ""); - static Transaction buildMultiSignatureRegistration(uint8_t min, uint8_t lifetime, std::vector keysgroup, - std::string passphrase, std::string secondPassphrase = ""); + static Transaction buildSecondSignatureRegistration( + std::string passphrase, + std::string secondPassphrase = ""); + + static Transaction buildDelegateRegistration( + std::string username, + std::string passphrase, + std::string secondPassphrase = ""); - private: + static Transaction buildVote( + std::vector votes, + std::string passphrase, + std::string secondPassphrase = ""); + + static Transaction buildMultiSignatureRegistration( + uint8_t min, + uint8_t lifetime, + std::vector& keysgroup, + std::string passphrase, + std::string secondPassphrase = ""); + +private: Builder(); - static Transaction sign(Transaction transaction, std::string passphrase, std::string secondPassphrase = ""); + static Transaction sign( + Transaction transaction, + std::string passphrase, + std::string secondPassphrase = ""); Builder sign(const std::string& passphrase); - private: +private: void serializeVendorField(std::vector& bytes); void serializeType(std::vector& bytes); void serializeTransfer(std::vector& bytes); @@ -56,9 +80,9 @@ class Builder { Transaction _transaction; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/include/cpp-crypto/transactions/deserializer.h b/src/include/cpp-crypto/transactions/deserializer.h index 869b2f54..ccaf217d 100644 --- a/src/include/cpp-crypto/transactions/deserializer.h +++ b/src/include/cpp-crypto/transactions/deserializer.h @@ -10,22 +10,22 @@ #ifndef DESERIALIZER_H #define DESERIALIZER_H -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" -#include "identities/privatekey.h" -#include "identities/publickey.h" #include "transactions/transaction.h" +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Deserializer { - public: +public: Deserializer(const std::string& serialized); Transaction deserialize(); - private: +private: void deserializeHeader(Transaction& transaction); void deserializeType(Transaction& transaction); void deserializeTransfer(Transaction& transaction); @@ -44,9 +44,9 @@ class Deserializer { std::vector _binary; uint32_t _assetOffset; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/include/cpp-crypto/transactions/serializer.h b/src/include/cpp-crypto/transactions/serializer.h index e70c4282..b33994d5 100644 --- a/src/include/cpp-crypto/transactions/serializer.h +++ b/src/include/cpp-crypto/transactions/serializer.h @@ -12,16 +12,20 @@ #include "transactions/transaction.h" +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Serializer { - public: - Serializer(const Transaction& transaction); +public: + Serializer(Transaction transaction); std::string serialize(); - private: +private: void serializeVendorField(std::vector& bytes); void serializeType(std::vector& bytes); void serializeTransfer(std::vector& bytes); @@ -33,7 +37,7 @@ class Serializer { Transaction _transaction; }; - +/**/ } // namespace Transactions } // namespace Crypto } // namespace Ark diff --git a/src/include/cpp-crypto/transactions/transaction.h b/src/include/cpp-crypto/transactions/transaction.h index 1f1ef9b0..07472338 100644 --- a/src/include/cpp-crypto/transactions/transaction.h +++ b/src/include/cpp-crypto/transactions/transaction.h @@ -10,8 +10,6 @@ #ifndef TRANSACTION_H #define TRANSACTION_H -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" #include "identities/privatekey.h" #include "identities/publickey.h" @@ -22,7 +20,7 @@ namespace Ark { namespace Crypto { namespace Transactions { - +/**/ struct TransactionAsset { struct { std::string publicKey; @@ -40,10 +38,10 @@ struct TransactionAsset { std::vector keysgroup; } multiSignature; }; - +/**/ class Transaction { public: - Transaction(); + Transaction() = default; std::string getId() const; @@ -79,11 +77,14 @@ class Transaction { uint64_t timelock = 0; private: - bool internalVerify(std::string publicKey, std::vector bytes, std::string signature) const; + bool internalVerify( + std::string publicKey, + std::vector bytes, + std::string signature) const; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/networks/abstractnetwork.cpp b/src/networks/abstractnetwork.cpp index d5499245..e2f06219 100644 --- a/src/networks/abstractnetwork.cpp +++ b/src/networks/abstractnetwork.cpp @@ -1,111 +1,67 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "networks/abstractnetwork.h" -/** - * @brief get the networks Base58 prefix byte given a prefix name - * - * @param Base58PrefixType prefix - * @return uint8_t - **/ -uint8_t Ark::Crypto::Networks::AbstractNetwork::getBase58Prefix(Base58PrefixType prefix) const { +#include + +uint8_t Ark::Crypto::Networks::AbstractNetwork::getBase58Prefix( + Base58PrefixType prefix) const { switch (prefix) { - case 0: - return this->base58_.ADDRESS_P2PKH; - case 1: - return this->base58_.ADDRESS_P2SH; - case 2: - return this->base58_.WIF; - default: - return 0; - } + case 0: return this->base58_.ADDRESS_P2PKH; + case 1: return this->base58_.ADDRESS_P2SH; + case 2: return this->base58_.WIF; + }; } + /**/ -/** - * @brief sets the networks Base58 prefix given a prefix name and byte - * - * @param Base58PrefixType prefix - * @param uint8_t newByte - **/ -void Ark::Crypto::Networks::AbstractNetwork::setBase58Prefix(Base58PrefixType prefix, uint8_t newByte) { +void Ark::Crypto::Networks::AbstractNetwork::setBase58Prefix( + Base58PrefixType prefix, + uint8_t newByte) { if (!isLocked_) { switch (prefix) { - case 0: - this->base58_.ADDRESS_P2PKH = newByte; - case 1: - this->base58_.ADDRESS_P2SH = newByte; - case 2: - this->base58_.WIF = newByte; + case 0: this->base58_.ADDRESS_P2PKH = newByte; break; + case 1: this->base58_.ADDRESS_P2SH = newByte; break; + case 2: this->base58_.WIF = newByte; break; }; - } + }; } + /**/ -/** - * @brief get the networks BIP32 prefix byte given a prefix name - * - * @param Base58PrefixType prefix - * @return long - **/ -long Ark::Crypto::Networks::AbstractNetwork::getBIP32Prefix(BIP32PrefixType prefix) const { - return (prefix == 0) ? this->bip32_.PREFIX_XPUB : this->bip32_.PREFIX_XPRV; +long Ark::Crypto::Networks::AbstractNetwork::getBIP32Prefix( + BIP32PrefixType prefix) const { + return (prefix == 0) + ? this->bip32_.PREFIX_XPUB + : this->bip32_.PREFIX_XPRV; } + /**/ -/** - * @brief sets the networks BIP32 prefix given a prefix name and byte - * - * @param BIP32PrefixType prefix - * @param long newByte - **/ -void Ark::Crypto::Networks::AbstractNetwork::setBIP32Prefix(BIP32PrefixType prefix, long newByte) { +void Ark::Crypto::Networks::AbstractNetwork::setBIP32Prefix( + BIP32PrefixType prefix, + long newByte) { if (!isLocked_) { switch (prefix) { - case 0: - this->bip32_.PREFIX_XPUB = newByte; - break; - case 1: - this->bip32_.PREFIX_XPRV = newByte; - break; + case 0: this->bip32_.PREFIX_XPUB = newByte; break; + case 1: this->bip32_.PREFIX_XPRV = newByte; break; }; - } + }; } + /**/ -/** - * Get the network epoch. - * - * @return const char* - **/ bool Ark::Crypto::Networks::AbstractNetwork::isLocked() const { return this->isLocked_; } + /**/ -/** - * Get the network epoch. - * - * @return const char* - **/ const char* Ark::Crypto::Networks::AbstractNetwork::epoch() const { return this->epoch_; } + /**/ -/** - * Get the network version as number. - * - * @return int - **/ uint8_t Ark::Crypto::Networks::AbstractNetwork::version() const { return uint8_t(base58_.ADDRESS_P2PKH); } -/**/ diff --git a/src/transactions/builder.cpp b/src/transactions/builder.cpp index f6775358..ed3bdb80 100644 --- a/src/transactions/builder.cpp +++ b/src/transactions/builder.cpp @@ -1,86 +1,143 @@ + #include "transactions/builder.h" #include "configuration/fee.h" #include "configuration/network.h" #include "enums/types.h" -#include "helpers/crypto_helpers.h" #include "identities/address.h" #include "utils/slot.h" +#include "helpers/crypto_helpers.h" + +#include +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { -Transaction Builder::buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, - std::string passphrase, std::string secondPassphrase) { +Transaction Builder::buildTransfer( + std::string recipientId, + uint64_t amount, + std::string vendorField, + std::string passphrase, + std::string secondPassphrase) { Transaction transaction; - if (amount < 1ull) { return transaction; }; + if (amount < 1ULL) { return transaction; }; transaction.type = Enums::Types::TRANSFER; transaction.fee = Configuration::Fee().get(Enums::Types::TRANSFER); transaction.recipientId = std::move(recipientId); - transaction.amount = std::move(amount); + transaction.amount = amount; transaction.vendorField = std::move(vendorField); - return sign(transaction, std::move(passphrase), std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildSecondSignatureRegistration(std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildSecondSignatureRegistration( + std::string passphrase, + std::string secondPassphrase) { Transaction transaction; transaction.type = Enums::Types::SECOND_SIGNATURE_REGISTRATION; - transaction.fee = Configuration::Fee().get(Enums::Types::SECOND_SIGNATURE_REGISTRATION); + transaction.fee = Configuration::Fee().get( + Enums::Types::SECOND_SIGNATURE_REGISTRATION); - const auto publicKey = Identities::PublicKey::fromPassphrase(secondPassphrase.c_str()); + const auto publicKey = Identities::PublicKey::fromPassphrase( + secondPassphrase.c_str()); transaction.asset.signature.publicKey = publicKey.toString(); - return sign(transaction, std::move(passphrase), secondPassphrase); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildDelegateRegistration(std::string username, std::string passphrase, - std::string secondPassphrase) { +/**/ + +Transaction Builder::buildDelegateRegistration( + std::string username, + std::string passphrase, + std::string secondPassphrase) { Transaction transaction; transaction.type = Enums::Types::DELEGATE_REGISTRATION; - transaction.fee = Configuration::Fee().get(Enums::Types::DELEGATE_REGISTRATION); + transaction.fee = Configuration::Fee().get( + Enums::Types::DELEGATE_REGISTRATION); transaction.asset.delegate.username = std::move(username); - return sign(transaction, std::move(passphrase), std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildVote(std::vector votes, std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildVote( + std::vector votes, + std::string passphrase, + std::string secondPassphrase) { Transaction transaction; transaction.type = Enums::Types::VOTE; transaction.fee = Configuration::Fee().get(Enums::Types::VOTE); transaction.asset.votes = std::move(votes); - const auto recipient = - Identities::Address::fromPassphrase(passphrase.c_str(), Configuration::Network().get().version()); + const auto recipient = Identities::Address::fromPassphrase( + passphrase.c_str(), + Configuration::Network().get().version()); transaction.recipientId = recipient.toString(); - return sign(transaction, passphrase, std::move(secondPassphrase)); + return sign(transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildMultiSignatureRegistration(uint8_t min, uint8_t lifetime, std::vector keysgroup, - std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildMultiSignatureRegistration( + uint8_t min, + uint8_t lifetime, + std::vector& keysgroup, + std::string passphrase, + std::string secondPassphrase) { Transaction transaction; transaction.type = Enums::Types::MULTI_SIGNATURE_REGISTRATION; - transaction.fee = (keysgroup.size() + 1) * Configuration::Fee().get(Enums::Types::MULTI_SIGNATURE_REGISTRATION); + transaction.fee = ( + keysgroup.size() + 1) + * Configuration::Fee().get(Enums::Types::MULTI_SIGNATURE_REGISTRATION); transaction.asset.multiSignature.min = min; transaction.asset.multiSignature.lifetime = lifetime; transaction.asset.multiSignature.keysgroup = keysgroup; - const auto recipient = - Identities::Address::fromPassphrase(passphrase.c_str(), Configuration::Network().get().version()); + const auto recipient = Identities::Address::fromPassphrase( + passphrase.c_str(), + Configuration::Network().get().version()); transaction.recipientId = recipient.toString(); - return sign(transaction, passphrase, std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::sign(Transaction transaction, std::string passphrase, std::string secondPassphrase) { - transaction.timestamp = static_cast(Utils::Slot::time(Configuration::Network().get())); +/**/ + +Transaction Builder::sign( + Transaction transaction, + std::string passphrase, + std::string secondPassphrase) { + transaction.timestamp = static_cast( + Utils::Slot::time(Configuration::Network().get())); transaction.sign(passphrase.c_str()); if (secondPassphrase.length() > 0) { transaction.secondSign(secondPassphrase.c_str()); - } + }; transaction.id = transaction.getId(); diff --git a/src/transactions/deserializer.cpp b/src/transactions/deserializer.cpp index 6a05c17d..64dac533 100644 --- a/src/transactions/deserializer.cpp +++ b/src/transactions/deserializer.cpp @@ -1,19 +1,32 @@ + #include "transactions/deserializer.h" -#include "bcl/Sha256.hpp" + #include "enums/types.h" -#include "helpers/crypto.h" #include "identities/address.h" +#include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "helpers/crypto.h" +#include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" + +#include "bcl/Sha256.hpp" #include +#include #include #include +#include +#include namespace Ark { namespace Crypto { namespace Transactions { Deserializer::Deserializer(const std::string& serialized) - : _serialized(serialized), _binary(HexToBytes(serialized.c_str())), _assetOffset(0) {} + : _serialized(serialized), + _binary(HexToBytes(serialized.c_str())), + _assetOffset(0) {} Transaction Deserializer::deserialize() { Transaction transaction; @@ -24,20 +37,24 @@ Transaction Deserializer::deserialize() { if (transaction.version == 1) { handleVersionOne(transaction); - } + }; return transaction; } +/**/ + void Deserializer::deserializeHeader(Transaction& transaction) { - unpack(&transaction.header, &this->_binary[0]); // 1 Byte - unpack(&transaction.version, &this->_binary[1]); // 1 Byte - unpack(&transaction.network, &this->_binary[2]); // 1 Byte - unpack(&transaction.type, &this->_binary[3]); // 1 Byte - unpack(&transaction.timestamp, &this->_binary[4]); // 4 Byte + unpack(&transaction.header, &this->_binary[0]); // 1 Byte + unpack(&transaction.version, &this->_binary[1]); // 1 Byte + unpack(&transaction.network, &this->_binary[2]); // 1 Byte + unpack(&transaction.type, &this->_binary[3]); // 1 Byte + unpack(&transaction.timestamp, &this->_binary[4]); // 4 Byte // 33 Byte - transaction.senderPublicKey = BytesToHex(this->_binary.begin() + 8, this->_binary.begin() + 33 + 8); + transaction.senderPublicKey = BytesToHex( + this->_binary.begin() + 8, + this->_binary.begin() + 33 + 8); unpack(&transaction.fee, &this->_binary[41]); // 8 Byte @@ -45,89 +62,103 @@ void Deserializer::deserializeHeader(Transaction& transaction) { uint8_t vendorFieldLength = 0; unpack(&vendorFieldLength, &this->_binary[49]); // 1 Byte if (vendorFieldLength > 0) { - transaction.vendorFieldHex = this->_serialized.substr(vendorFieldOffset, vendorFieldLength * 2); - } + transaction.vendorFieldHex = this->_serialized.substr( + vendorFieldOffset, + vendorFieldLength * 2); + }; _assetOffset = vendorFieldOffset + vendorFieldLength * 2; } -void Deserializer::deserializeType(Transaction& transaction) { +/**/ + +void Deserializer::deserializeType( + Transaction& transaction) { switch (transaction.type) { case Enums::Types::TRANSFER: { deserializeTransfer(transaction); break; - } + }; case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { deserializeSecondSignatureRegistration(transaction); break; - } + }; case Enums::Types::DELEGATE_REGISTRATION: { deserializeDelegateRegistration(transaction); break; - } + }; case Enums::Types::VOTE: { deserializeVote(transaction); break; - } + }; case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { deserializeMultiSignatureRegistration(transaction); break; - } - case Enums::Types::IPFS: { - break; - } - case Enums::Types::TIMELOCK_TRANSFER: { - break; - } - case Enums::Types::MULTI_PAYMENT: { - break; - } - case Enums::Types::DELEGATE_RESIGNATION: { - break; - } - } + }; + case Enums::Types::IPFS: { break; }; + case Enums::Types::TIMELOCK_TRANSFER: { break; }; + case Enums::Types::MULTI_PAYMENT: { break; }; + case Enums::Types::DELEGATE_RESIGNATION: { break; }; + }; } -void Deserializer::deserializeTransfer(Transaction& transaction) { +/**/ + +void Deserializer::deserializeTransfer( + Transaction& transaction) { unpack(&transaction.amount, &this->_binary[_assetOffset / 2]); unpack(&transaction.expiration, &this->_binary[_assetOffset / 2 + 8]); - transaction.recipientId = Identities::Address::base58encode(&this->_binary[(_assetOffset / 2) + 12]); + transaction.recipientId = Identities::Address::base58encode( + &this->_binary[(_assetOffset / 2) + 12]); _assetOffset += (8 + 4 + 21) * 2; -} +}; -void Deserializer::deserializeSecondSignatureRegistration(Transaction& transaction) { - transaction.asset.signature.publicKey = this->_serialized.substr(_assetOffset, 66); +void Deserializer::deserializeSecondSignatureRegistration( + Transaction& transaction) { + transaction.asset.signature.publicKey = this->_serialized.substr( + _assetOffset, + 66); _assetOffset += 66; -} +}; -void Deserializer::deserializeDelegateRegistration(Transaction& transaction) { +void Deserializer::deserializeDelegateRegistration( + Transaction& transaction) { uint8_t usernameLength = 0; unpack(&usernameLength, &this->_binary[_assetOffset / 2]); usernameLength &= 0xff; - std::string username = this->_serialized.substr((_assetOffset / 2 + 1) * 2, usernameLength * 2); - std::vector bytes = HexToBytes(username.c_str()); - transaction.asset.delegate.username = std::string(bytes.begin(), bytes.end()); + std::string username = this->_serialized.substr( + (_assetOffset / 2 + 1) * 2, usernameLength * 2); + std::vector bytes = HexToBytes(username.c_str()); + transaction.asset.delegate.username = std::string( + bytes.begin(), + bytes.end()); _assetOffset += (usernameLength + 1) * 2; -} +}; -void Deserializer::deserializeVote(Transaction& transaction) { +void Deserializer::deserializeVote( + Transaction& transaction) { uint8_t voteLength = 0; unpack(&voteLength, &this->_binary[_assetOffset / 2]); voteLength &= 0xff; for (uint8_t i = 0; i < voteLength; i++) { - std::string vote = this->_serialized.substr(_assetOffset + 2 + i * 2 * 32, 68); + std::string vote = this->_serialized.substr( + _assetOffset + 2 + i * 2 * 32, + 68); vote = (vote[1] == '1' ? "+" : "-") + vote.substr(2); transaction.asset.votes.push_back(vote); - } + }; _assetOffset += 2 + voteLength * 34 * 2; } -void Deserializer::deserializeMultiSignatureRegistration(Transaction& transaction) { +/**/ + +void Deserializer::deserializeMultiSignatureRegistration( + Transaction& transaction) { uint8_t min = 0; unpack(&min, &this->_binary[_assetOffset / 2]); min &= 0xff; @@ -144,85 +175,114 @@ void Deserializer::deserializeMultiSignatureRegistration(Transaction& transactio transaction.asset.multiSignature.lifetime = lifetime; for (uint8_t i = 0; i < count; i++) { - std::string key = this->_serialized.substr(_assetOffset + 6 + i * 66, 66); + std::string key = this->_serialized.substr( + _assetOffset + 6 + i * 66, + 66); transaction.asset.multiSignature.keysgroup.push_back(key); - } + }; _assetOffset += 6 + count * 66; } +/**/ + static uint8_t parseSignatureLength(const std::string& hex) { - assert(hex.length() <= 2); + if (hex.length() > 2) { return 0; }; unsigned int length; sscanf(hex.c_str(), "%x", &length); return static_cast(length + 2); } -void Deserializer::deserializeSignatures(Transaction& transaction) { +/**/ + +void Deserializer::deserializeSignatures( + Transaction& transaction) { std::string signature = this->_serialized.substr(_assetOffset); size_t multiSignatureOffset = 0; if (!signature.empty()) { size_t signatureLength = parseSignatureLength(signature.substr(2, 2)); - transaction.signature = this->_serialized.substr(_assetOffset, signatureLength * 2); + transaction.signature = this->_serialized.substr( + _assetOffset, + signatureLength * 2); multiSignatureOffset += signatureLength * 2; - transaction.secondSignature = this->_serialized.substr((_assetOffset + signatureLength * 2)); + transaction.secondSignature = this->_serialized.substr( + (_assetOffset + signatureLength * 2)); if (!transaction.secondSignature.empty()) { if (transaction.secondSignature.substr(0, 2) == "ff") { transaction.secondSignature = ""; } else { - size_t secondSignatureLength = parseSignatureLength(transaction.secondSignature.substr(2, 2)); - transaction.secondSignature = transaction.secondSignature.substr(0, secondSignatureLength * 2); + size_t secondSignatureLength = parseSignatureLength( + transaction.secondSignature.substr(2, 2)); + transaction.secondSignature = transaction.secondSignature.substr( + 0, + secondSignatureLength * 2); multiSignatureOffset += secondSignatureLength * 2; - } - } + }; + }; - std::string signatures = this->_serialized.substr(_assetOffset + multiSignatureOffset); + std::string signatures = this->_serialized.substr( + _assetOffset + multiSignatureOffset); if (!signatures.empty() && signatures.substr(0, 2) == "ff") { signatures = signatures.substr(2); while (!signatures.empty()) { - size_t multiSignatureLength = parseSignatureLength(signatures.substr(2, 2)); + size_t multiSignatureLength = parseSignatureLength( + signatures.substr(2, 2)); if (multiSignatureLength > 0) { - transaction.signatures.push_back(signatures.substr(0, multiSignatureLength * 2)); - } + transaction.signatures.push_back( + signatures.substr(0, + multiSignatureLength * 2)); + }; signatures = signatures.substr(multiSignatureLength * 2); - } - } - } + }; + }; + }; } -void Deserializer::handleVersionOne(Transaction& transaction) { +/**/ + +void Deserializer::handleVersionOne( + Transaction& transaction) { transaction.signSignature = transaction.secondSignature; if (transaction.type == Enums::Types::VOTE) { - const auto publicKey = Identities::PublicKey::fromHex(transaction.senderPublicKey.c_str()); - const auto address = Identities::Address::fromPublicKey(publicKey, transaction.network); + const auto publicKey = Identities::PublicKey::fromHex( + transaction.senderPublicKey.c_str()); + const auto address = Identities::Address::fromPublicKey( + publicKey, + transaction.network); transaction.recipientId = address.toString(); - } + }; if (transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { - std::for_each(transaction.asset.multiSignature.keysgroup.begin(), transaction.asset.multiSignature.keysgroup.end(), - [](std::string& key) { key.insert(0, "+"); }); - } + std::for_each( + transaction.asset.multiSignature.keysgroup.begin(), + transaction.asset.multiSignature.keysgroup.end(), + [](std::string& key) { key.insert(0, "+"); } + ); + }; if (!transaction.vendorFieldHex.empty()) { const auto bytes = HexToBytes(transaction.vendorFieldHex.c_str()); transaction.vendorField = std::string(bytes.begin(), bytes.end()); - } + }; if (transaction.id.empty()) { transaction.id = transaction.getId(); - } - - if (transaction.type == Enums::Types::SECOND_SIGNATURE_REGISTRATION || - transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { - const auto publicKey = Identities::PublicKey::fromHex(transaction.senderPublicKey.c_str()); - const auto address = Identities::Address::fromPublicKey(publicKey, transaction.network); + }; + + if (transaction.type == Enums::Types::SECOND_SIGNATURE_REGISTRATION + || transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + const auto publicKey = Identities::PublicKey::fromHex( + transaction.senderPublicKey.c_str()); + const auto address = Identities::Address::fromPublicKey( + publicKey, + transaction.network); transaction.recipientId = address.toString(); - } + }; } } // namespace Transactions diff --git a/src/transactions/serializer.cpp b/src/transactions/serializer.cpp index e3e4b519..1d60dd7c 100644 --- a/src/transactions/serializer.cpp +++ b/src/transactions/serializer.cpp @@ -1,27 +1,46 @@ + #include "transactions/serializer.h" + #include "configuration/network.h" #include "enums/types.h" -#include "helpers/crypto_helpers.h" #include "identities/address.h" +#include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" + +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { // TODO: remove class ? -Serializer::Serializer(const Transaction& transaction) : _transaction(transaction) {} +Serializer::Serializer(Transaction transaction) + : _transaction(std::move(transaction)) {} std::string Serializer::serialize() { std::vector bytes; bytes.push_back(0xff); - bytes.push_back(_transaction.version > 0 ? _transaction.version : 0x01); - bytes.push_back(_transaction.network > 0 ? _transaction.network : Configuration::Network().get().version()); + bytes.push_back( + _transaction.version > 0 + ? _transaction.version + : 0x01); + bytes.push_back( + _transaction.network > 0 + ? _transaction.network + : Configuration::Network().get().version()); bytes.push_back(_transaction.type); pack(bytes, _transaction.timestamp); - std::vector senderPublicKeyBytes = HexToBytes(_transaction.senderPublicKey.c_str()); - bytes.insert(bytes.end(), senderPublicKeyBytes.begin(), senderPublicKeyBytes.end()); + std::vector senderPublicKeyBytes = HexToBytes( + _transaction.senderPublicKey.c_str()); + bytes.insert( + bytes.end(), + senderPublicKeyBytes.begin(), + senderPublicKeyBytes.end()); pack(bytes, _transaction.fee); @@ -32,129 +51,186 @@ std::string Serializer::serialize() { return BytesToHex(bytes); } -void Serializer::serializeVendorField(std::vector& bytes) { +/**/ + +void Serializer::serializeVendorField( + std::vector& bytes) { if (_transaction.vendorField.length() > 0) { - auto vendorFieldLength = static_cast(_transaction.vendorField.length()); + auto vendorFieldLength = static_cast( + _transaction.vendorField.length()); bytes.push_back(vendorFieldLength); - bytes.insert(bytes.end(), std::begin(_transaction.vendorField), std::end(_transaction.vendorField)); - + bytes.insert( + bytes.end(), + std::begin(_transaction.vendorField), + std::end(_transaction.vendorField)); } else if (_transaction.vendorFieldHex.length() > 0) { - auto vendorFieldHexLength = static_cast(_transaction.vendorFieldHex.length() / 2); + auto vendorFieldHexLength = static_cast( + _transaction.vendorFieldHex.length() / 2); bytes.push_back(vendorFieldHexLength); - bytes.insert(bytes.end(), std::begin(_transaction.vendorFieldHex), std::end(_transaction.vendorFieldHex)); + bytes.insert( + bytes.end(), + std::begin(_transaction.vendorFieldHex), + std::end(_transaction.vendorFieldHex)); } else { bytes.push_back(0x00); - } + }; } -void Serializer::serializeType(std::vector& bytes) { +/**/ + +void Serializer::serializeType( + std::vector& bytes) { switch (_transaction.type) { case Enums::Types::TRANSFER: { serializeTransfer(bytes); break; - } + }; case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { serializeSecondSignatureRegistration(bytes); break; - } + }; case Enums::Types::DELEGATE_REGISTRATION: { serializeDelegateRegistration(bytes); break; - } + }; case Enums::Types::VOTE: { serializeVote(bytes); break; - } + }; case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { serializeMultiSignatureRegistration(bytes); break; - } - case Enums::Types::IPFS: { - break; - } - case Enums::Types::TIMELOCK_TRANSFER: { - break; - } - case Enums::Types::MULTI_PAYMENT: { - break; - } - case Enums::Types::DELEGATE_RESIGNATION: { - break; - } - } + }; + case Enums::Types::IPFS: { break; }; + case Enums::Types::TIMELOCK_TRANSFER: { break; }; + case Enums::Types::MULTI_PAYMENT: { break; }; + case Enums::Types::DELEGATE_RESIGNATION: { break; }; + }; } -void Serializer::serializeTransfer(std::vector& bytes) { +/**/ + +void Serializer::serializeTransfer( + std::vector& bytes) { pack(bytes, _transaction.amount); pack(bytes, _transaction.expiration); - std::vector recipientIdBytes = Identities::Address::bytesFromBase58Check(_transaction.recipientId.c_str()); - bytes.insert(bytes.end(), recipientIdBytes.begin(), recipientIdBytes.end()); + std::vector recipientIdBytes = Identities::Address::bytesFromBase58Check( + _transaction.recipientId.c_str()); + bytes.insert( + bytes.end(), + recipientIdBytes.begin(), + recipientIdBytes.end()); } -void Serializer::serializeSecondSignatureRegistration(std::vector& bytes) { - std::vector publicKeyBytes = HexToBytes(_transaction.asset.signature.publicKey.c_str()); - bytes.insert(bytes.end(), publicKeyBytes.begin(), publicKeyBytes.end()); +/**/ + +void Serializer::serializeSecondSignatureRegistration( + std::vector& bytes) { + std::vector publicKeyBytes = HexToBytes( + _transaction.asset.signature.publicKey.c_str()); + bytes.insert( + bytes.end(), + publicKeyBytes.begin(), + publicKeyBytes.end()); } -void Serializer::serializeDelegateRegistration(std::vector& bytes) { +/**/ + +void Serializer::serializeDelegateRegistration( + std::vector& bytes) { const auto username = _transaction.asset.delegate.username; bytes.push_back(static_cast(username.size())); - bytes.insert(bytes.end(), username.begin(), username.end()); + bytes.insert( + bytes.end(), + username.begin(), + username.end()); } -void Serializer::serializeVote(std::vector& bytes) { +/**/ + +void Serializer::serializeVote( + std::vector& bytes) { std::string votes; for (const auto& vote : _transaction.asset.votes) { votes += (vote[0] == '+' ? "01" : "00") + vote.substr(1); - } + }; std::vector voteBytes = HexToBytes(votes.c_str()); - bytes.push_back(static_cast(_transaction.asset.votes.size())); - bytes.insert(bytes.end(), voteBytes.begin(), voteBytes.end()); + bytes.push_back(static_cast( + _transaction.asset.votes.size())); + bytes.insert( + bytes.end(), + voteBytes.begin(), + voteBytes.end()); } -void Serializer::serializeMultiSignatureRegistration(std::vector& bytes) { +/**/ + +void Serializer::serializeMultiSignatureRegistration( + std::vector& bytes) { std::string keysgroup; if (_transaction.version == 1) { for (const auto& kg : _transaction.asset.multiSignature.keysgroup) { keysgroup += kg.substr(1); - } + }; } else { keysgroup = join(_transaction.asset.multiSignature.keysgroup); - } + }; bytes.push_back(_transaction.asset.multiSignature.min); - bytes.push_back(static_cast(_transaction.asset.multiSignature.keysgroup.size())); + bytes.push_back(static_cast( + _transaction.asset.multiSignature.keysgroup.size())); bytes.push_back(_transaction.asset.multiSignature.lifetime); std::vector keysgroupBytes = HexToBytes(keysgroup.c_str()); - bytes.insert(bytes.end(), keysgroupBytes.begin(), keysgroupBytes.end()); + bytes.insert( + bytes.end(), + keysgroupBytes.begin(), + keysgroupBytes.end()); } -void Serializer::serializeSignatures(std::vector& bytes) { +/**/ + +void Serializer::serializeSignatures( + std::vector& bytes) { if (_transaction.signature.length() > 0) { - std::vector signatureBytes = HexToBytes(_transaction.signature.c_str()); - bytes.insert(bytes.end(), signatureBytes.begin(), signatureBytes.end()); - } + std::vector signatureBytes = HexToBytes( + _transaction.signature.c_str()); + bytes.insert( + bytes.end(), + signatureBytes.begin(), + signatureBytes.end()); + }; if (_transaction.secondSignature.length() > 0) { - std::vector secondSignatureBytes = HexToBytes(_transaction.secondSignature.c_str()); - bytes.insert(bytes.end(), secondSignatureBytes.begin(), secondSignatureBytes.end()); + std::vector secondSignatureBytes = HexToBytes( + _transaction.secondSignature.c_str()); + bytes.insert( + bytes.end(), + secondSignatureBytes.begin(), + secondSignatureBytes.end()); } else if (_transaction.signSignature.length() > 0) { - std::vector signSignatureBytes = HexToBytes(_transaction.signSignature.c_str()); - bytes.insert(bytes.end(), signSignatureBytes.begin(), signSignatureBytes.end()); - } + std::vector signSignatureBytes = HexToBytes( + _transaction.signSignature.c_str()); + bytes.insert( + bytes.end(), + signSignatureBytes.begin(), + signSignatureBytes.end()); + }; if (!_transaction.signatures.empty()) { bytes.push_back(0xff); std::string joined = join(_transaction.signatures); for (const auto& signature : _transaction.signatures) { std::vector signatureBytes = HexToBytes(signature.c_str()); - bytes.insert(bytes.end(), std::begin(signatureBytes), std::end(signatureBytes)); - } - } + bytes.insert( + bytes.end(), + std::begin(signatureBytes), + std::end(signatureBytes)); + }; + }; } } // namespace Transactions diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index 5c8fe64e..1345f9a2 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -1,28 +1,40 @@ + #include "transactions/transaction.h" -#include "bcl/Sha256.hpp" + #include "enums/types.h" +#include "identities/address.h" +#include "identities/privatekey.h" + #include "helpers/crypto.h" #include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" #include "helpers/json.h" -#include "identities/address.h" -#include "identities/privatekey.h" + +#include "bcl/Sha256.hpp" #include +#include +#include -using namespace Ark::Crypto::Identities; +#define __STDC_FORMAT_MACROS 1 +#include -Ark::Crypto::Transactions::Transaction::Transaction() {} +using namespace Ark::Crypto::Identities; std::string Ark::Crypto::Transactions::Transaction::getId() const { auto bytes = this->toBytes(false, false); const auto shaHash = Sha256::getHash(&bytes[0], bytes.size()); - memcpy(&bytes[0], shaHash.value, shaHash.HASH_LEN); - return BytesToHex(&bytes[0], &bytes[0] + shaHash.HASH_LEN); + memcpy(&bytes[0], shaHash.value, Sha256Hash::HASH_LEN); + return BytesToHex(&bytes[0], &bytes[0] + Sha256Hash::HASH_LEN); } -std::string Ark::Crypto::Transactions::Transaction::sign(const char* passphrase) { +/**/ + +std::string Ark::Crypto::Transactions::Transaction::sign( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); - this->senderPublicKey = Identities::PublicKey::fromPrivateKey(privateKey).toString(); + this->senderPublicKey = Identities::PublicKey::fromPrivateKey( + privateKey).toString(); const auto bytes = this->toBytes(); const auto hash = Sha256::getHash(&bytes[0], bytes.size()); @@ -34,7 +46,10 @@ std::string Ark::Crypto::Transactions::Transaction::sign(const char* passphrase) return this->signature; } -std::string Ark::Crypto::Transactions::Transaction::secondSign(const char* passphrase) { +/**/ + +std::string Ark::Crypto::Transactions::Transaction::secondSign( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); const auto bytes = this->toBytes(false); const auto hash = Sha256::getHash(&bytes[0], bytes.size()); @@ -46,14 +61,28 @@ std::string Ark::Crypto::Transactions::Transaction::secondSign(const char* passp return this->secondSignature; } +/**/ + bool Ark::Crypto::Transactions::Transaction::verify() const { - return this->internalVerify(this->senderPublicKey, this->toBytes(), this->signature); + return this->internalVerify( + this->senderPublicKey, + this->toBytes(), + this->signature); } -bool Ark::Crypto::Transactions::Transaction::secondVerify(const char* secondPublicKey) const { - return this->internalVerify(secondPublicKey, this->toBytes(false), this->secondSignature); +/**/ + +bool Ark::Crypto::Transactions::Transaction::secondVerify( + const char* secondPublicKey) const { + std::string secondPublicKeyString = secondPublicKey; + return this->internalVerify( + secondPublicKeyString, + this->toBytes(false), + this->secondSignature); } +/**/ + bool Ark::Crypto::Transactions::Transaction::internalVerify( std::string publicKey, std::vector bytes, @@ -63,120 +92,172 @@ bool Ark::Crypto::Transactions::Transaction::internalVerify( const auto hash = Sha256::getHash(&bytes[0], bytes.size()); const auto key = Identities::PublicKey::fromHex(publicKey.c_str()); auto signatureBytes = HexToBytes(signature.c_str()); + return cryptoVerify(key, hash, signatureBytes); } +/**/ + std::vector Ark::Crypto::Transactions::Transaction::toBytes( bool skipSignature, bool skipSecondSignature) const { std::vector bytes; - if (this->type == 0 && amount < 1ull) { return bytes; }; + if (this->type == 0 && amount < 1ULL) { return bytes; }; pack(bytes, this->type); pack(bytes, this->timestamp); - const auto senderKeyBytes = HexToBytes(this->senderPublicKey.c_str()); - bytes.insert(std::end(bytes), std::begin(senderKeyBytes), std::end(senderKeyBytes)); + const auto senderKeyBytes = HexToBytes( + this->senderPublicKey.c_str()); + bytes.insert( + std::end(bytes), + std::begin(senderKeyBytes), + std::end(senderKeyBytes)); - const auto skipRecipientId = type - == Enums::Types::SECOND_SIGNATURE_REGISTRATION + const auto skipRecipientId = + type == Enums::Types::SECOND_SIGNATURE_REGISTRATION || type == Enums::Types::MULTI_SIGNATURE_REGISTRATION; if (!this->recipientId.empty() && !skipRecipientId) { - std::vector recipientIdBytes = Address::bytesFromBase58Check(this->recipientId.c_str()); - bytes.insert(std::end(bytes), std::begin(recipientIdBytes), std::end(recipientIdBytes)); + std::vector recipientIdBytes = Address::bytesFromBase58Check( + this->recipientId.c_str()); + bytes.insert( + std::end(bytes), + std::begin(recipientIdBytes), + std::end(recipientIdBytes)); } else { std::vector filler(21, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; if (!this->vendorField.empty() && vendorField.length() <= 255) { - bytes.insert(std::end(bytes), std::begin(this->vendorField), std::end(this->vendorField)); - + bytes.insert( + std::end(bytes), + std::begin(this->vendorField), + std::end(this->vendorField)); size_t diff = 64 - vendorField.length(); if (diff > 0) { std::vector filler(diff, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; } else { std::vector filler(64, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; pack(bytes, this->amount); pack(bytes, this->fee); if (type == Enums::Types::SECOND_SIGNATURE_REGISTRATION) { - const auto publicKeyBytes = HexToBytes(this->asset.signature.publicKey.c_str()); - bytes.insert(std::end(bytes), std::begin(publicKeyBytes), std::end(publicKeyBytes)); - + // SECOND_SIGNATURE_REGISTRATION + const auto publicKeyBytes = HexToBytes( + this->asset.signature.publicKey.c_str()); + bytes.insert( + std::end(bytes), + std::begin(publicKeyBytes), + std::end(publicKeyBytes)); } else if (type == Enums::Types::DELEGATE_REGISTRATION) { - bytes.insert(std::end(bytes), std::begin(this->asset.delegate.username), std::end(this->asset.delegate.username)); - + // DELEGATE_REGISTRATION + bytes.insert( + std::end(bytes), + std::begin(this->asset.delegate.username), + std::end(this->asset.delegate.username)); } else if (type == Enums::Types::VOTE) { + // VOTE const auto joined = join(this->asset.votes); - bytes.insert(std::end(bytes), std::begin(joined), std::end(joined)); - + bytes.insert( + std::end(bytes), + std::begin(joined), + std::end(joined)); } else if (type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + // MULTI_SIGNATURE_REGISTRATION pack(bytes, this->asset.multiSignature.min); pack(bytes, this->asset.multiSignature.lifetime); const auto joined = join(this->asset.multiSignature.keysgroup); - bytes.insert(std::end(bytes), std::begin(joined), std::end(joined)); - } + bytes.insert( + std::end(bytes), + std::begin(joined), + std::end(joined)); + }; if (!skipSignature && !this->signature.empty()) { const auto signatureBytes = HexToBytes(this->signature.c_str()); - bytes.insert(std::end(bytes), std::begin(signatureBytes), std::end(signatureBytes)); - } + bytes.insert( + std::end(bytes), + std::begin(signatureBytes), + std::end(signatureBytes)); + }; if (!skipSecondSignature && !this->secondSignature.empty()) { - const auto secondSignatureBytes = HexToBytes(this->secondSignature.c_str()); - bytes.insert(std::end(bytes), std::begin(secondSignatureBytes), std::end(secondSignatureBytes)); - } + const auto secondSignatureBytes = HexToBytes( + this->secondSignature.c_str()); + bytes.insert( + std::end(bytes), + std::begin(secondSignatureBytes), + std::end(secondSignatureBytes)); + }; return bytes; } +/**/ + std::map Ark::Crypto::Transactions::Transaction::toArray() { // buffers for variable and non-string type-values. - char amount[24], - assetName[16], - assetValue[512], - fee[24], - network[8], - signatures[512], - timestamp[36], - type[8], - version[8]; + char amount[24]; + char assetName[16]; + char assetValue[512]; + char fee[24]; + char network[8]; + char signatures[512]; + char timestamp[36]; + char type[8]; + char version[8]; // Amount - sprintf(amount, "%llu", this->amount); + snprintf(amount, sizeof(amount), "%" PRIu64, this->amount); // Asset - if (this->type == 0) { // Transfer - //do nothing - } else if (this->type == 1) { // Second Signature Registration - - strcpy(assetName, "publicKey"); - strcpy(assetValue, this->asset.signature.publicKey.c_str()); - - } else if (this->type == 2) { // Delegate Registration - - strcpy(assetName, "username"); - strcpy(assetValue, this->asset.delegate.username.c_str()); - - } else if (this->type == 3) { // Vote - - strcpy(assetName, "votes"); - strcpy(assetValue, ""); + if (this->type == 0) { + // Transfer + // do nothing + } else if (this->type == 1) { + // Second Signature Registration + strncpy(assetName, "publicKey", sizeof(assetName)); + strncpy( + assetValue, + this->asset.signature.publicKey.c_str(), + this->asset.signature.publicKey.length() + 1); + } else if (this->type == 2) { + // Delegate Registration + strncpy(assetName, "username", sizeof(assetName)); + strncpy( + assetValue, + this->asset.delegate.username.c_str(), + this->asset.delegate.username.length() + 1); + } else if (this->type == 3) { + // Vote + strncpy(assetName, "votes", sizeof(assetName)); + strncpy(assetValue, "", 1); for (unsigned int i = 0; i < this->asset.votes.size(); ++i) { - strcat(assetValue, this->asset.votes[i].c_str()); - + strncat( + assetValue, + this->asset.votes[i].c_str(), + this->asset.votes[i].length() + 1); if (i < this->asset.votes.size() - 1) { - strcat(assetValue, ","); - } - } + strncat(assetValue, ",", 1); + }; + }; // } else if (this->type == 4) { // Multisignature Registration // // TODO @@ -191,29 +272,31 @@ std::map Ark::Crypto::Transactions::Transaction::toArr }; // Fee - // fee << this->fee; - sprintf(fee, "%llu", this->fee); + snprintf(fee, sizeof(fee), "%" PRIu64, this->fee); // Signatures strcpy(signatures, ""); for (unsigned int i = 0; i < this->signatures.size(); ++i) { - strcat(signatures, this->signatures[i].c_str()); + strncat( + signatures, + this->signatures[i].c_str(), + this->signatures[i].length() + 1); if (i < this->signatures.size() - 1) { - strcpy(signatures, ","); - } - } + strncpy(signatures, ",", 1); + }; + }; // Network - sprintf(network, "%d", this->network); + snprintf(network, sizeof(network), "%d", this->network); // Timestamp - sprintf(timestamp, "%d", this->timestamp); + snprintf(timestamp, sizeof(timestamp), "%d", this->timestamp); // Type - sprintf(type, "%d", this->type); + snprintf(type, sizeof(type), "%u", this->type); // Version - sprintf(version, "%d", this->version); + snprintf(version, sizeof(version), "%d", this->version); return { { "amount", amount }, @@ -234,6 +317,8 @@ std::map Ark::Crypto::Transactions::Transaction::toArr }; } +/**/ + std::string Ark::Crypto::Transactions::Transaction::toJson() { std::map txArray = this->toArray(); @@ -244,32 +329,31 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { doc["amount"] = txArray["amount"]; // Asset - if (this->type == 0) { // Transfer + if (this->type == 0) { + // Transfer //do nothing - } else if (this->type == 1) { // Second Signature Registration - + } else if (this->type == 1) { + // Second Signature Registration JsonObject tAsset = doc.createNestedObject("asset"); JsonObject signature = tAsset.createNestedObject("signature"); signature["publicKey"] = txArray["publicKey"]; - - } else if (this->type == 2) { // Delegate Registration - + } else if (this->type == 2) { + // Delegate Registration JsonObject dAsset = doc.createNestedObject("asset"); JsonObject delegate = dAsset.createNestedObject("delegate"); delegate["username"] = txArray["username"]; - - }else if (this->type == 3) { // Vote - + }else if (this->type == 3) { + // Vote JsonObject vAsset = doc.createNestedObject("asset"); JsonArray votes = vAsset.createNestedArray("votes"); - std::string::size_type lastPos = txArray["votes"].find_first_not_of(",", 0); - std::string::size_type pos = txArray["votes"].find_first_of(",", lastPos); + std::string::size_type lastPos = txArray["votes"].find_first_not_of(',', 0); + std::string::size_type pos = txArray["votes"].find_first_of(',', lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { votes.add(txArray["votes"].substr(lastPos, pos - lastPos)); - lastPos = txArray["votes"].find_first_not_of(",", pos); - pos = txArray["votes"].find_first_of(",", lastPos); - } + lastPos = txArray["votes"].find_first_not_of(',', pos); + pos = txArray["votes"].find_first_of(',', lastPos); + }; // } else if (this->type == 4) { // Multisignature Registration // // TODO @@ -292,7 +376,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // Network if (txArray["network"] != "0") { doc["network"] = txArray["network"]; - } + }; // RecipientId doc["recipientId"] = txArray["recipientId"]; @@ -300,7 +384,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // SecondSignature if (std::strlen(txArray["secondSignature"].c_str()) > 0) { doc["secondSignature"] = txArray["secondSignature"]; - } + }; // SenderPublicKey doc["senderPublicKey"] = txArray["senderPublicKey"]; @@ -309,21 +393,21 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { doc["signature"] = txArray["signature"]; // Signatures - if (this->signatures.size() > 0) { + if (!this->signatures.empty()) { JsonArray signatures = doc.createNestedArray("signatures"); - std::string::size_type lastPos = txArray["signatures"].find_first_not_of(",", 0); - std::string::size_type pos = txArray["signatures"].find_first_of(",", lastPos); + std::string::size_type lastPos = txArray["signatures"].find_first_not_of(',', 0); + std::string::size_type pos = txArray["signatures"].find_first_of(',', lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { signatures.add(txArray["signatures"].substr(lastPos, pos - lastPos)); - lastPos = txArray["signatures"].find_first_not_of(",", pos); - pos = txArray["signatures"].find_first_of(",", lastPos); - } - } + lastPos = txArray["signatures"].find_first_not_of(',', pos); + pos = txArray["signatures"].find_first_of(',', lastPos); + }; + }; // SignSignature if (std::strlen(txArray["signSignature"].c_str()) > 0) { doc["signSignature"] = txArray["signSignature"]; - } + }; // Timestamp doc["timestamp"] = txArray["timestamp"]; @@ -334,12 +418,12 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // VendorField if (std::strlen(txArray["vendorField"].c_str()) > 0) { doc["vendorField"] = txArray["vendorField"]; - } + }; // Version if (txArray["version"] != "0") { doc["version"] = txArray["version"]; - } + }; char jsonChar[docCapacity]; serializeJson(doc, jsonChar, docCapacity); diff --git a/src/utils/message.cpp b/src/utils/message.cpp index 916fc0d4..c5a8feaf 100644 --- a/src/utils/message.cpp +++ b/src/utils/message.cpp @@ -1,43 +1,21 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "utils/message.h" #include "helpers/json.h" -/** - * @brief Create a message object for checking its validity. - * - * @param std::string msg - * @param PublicKey pubKey - * @param std::vector sig - **/ Ark::Crypto::Utils::Message::Message( std::string msg, PublicKey pubKey, std::vector sig) - : message(msg), + : message(std::move(msg)), publicKey(pubKey), - signature(sig){}; + signature(std::move(sig)) {}; + /**/ -/** - * @brief Sign a message using the given passphrase. - * - * @param string message - * @param string passphrase - * - * @return bool - **/ bool Ark::Crypto::Utils::Message::sign( std::string newMessage, const char *const passphrase) { - this->message = newMessage; + this->message = std::move(newMessage); /* Get the PrivateKey */ auto privateKey = PrivateKey::fromPassphrase(passphrase); @@ -46,7 +24,8 @@ bool Ark::Crypto::Utils::Message::sign( this->publicKey = PublicKey::fromPrivateKey(privateKey); /* Get the Hash */ - const auto unsignedMessage = reinterpret_cast(message.c_str()); + const auto unsignedMessage = reinterpret_cast( + message.c_str()); const auto hash = Sha256::getHash(unsignedMessage, this->message.length()); /* Sign it */ @@ -54,27 +33,20 @@ bool Ark::Crypto::Utils::Message::sign( return this->verify(); }; + /**/ -/** - * @brief Verify the message contents. - * - * @return bool - **/ bool Ark::Crypto::Utils::Message::verify() { // cast message to unsigned char* - const auto unsignedMessage = reinterpret_cast(this->message.c_str()); + const auto unsignedMessage = reinterpret_cast( + this->message.c_str()); const auto hash = Sha256::getHash(unsignedMessage, this->message.length()); return cryptoVerify(this->publicKey, hash, this->signature); }; + /**/ -/** - * @brief Convert the message to its array representation using an array of pairs - * - * @return std::map - **/ std::map Ark::Crypto::Utils::Message::toArray() { return { { "publickey", this->publicKey.toString() }, @@ -82,13 +54,9 @@ std::map Ark::Crypto::Utils::Message::toArray() { { "message", this->message } }; } + /**/ -/** - * @brief Convert the message to its JSON representation. - * - * @return std::string - **/ std::string Ark::Crypto::Utils::Message::toJson() { std::map messageArray = this->toArray(); @@ -110,4 +78,3 @@ std::string Ark::Crypto::Utils::Message::toJson() { return jsonStr; } -/**/ diff --git a/src/utils/message.h b/src/utils/message.h index f159c549..53d9eba4 100644 --- a/src/utils/message.h +++ b/src/utils/message.h @@ -24,8 +24,6 @@ #include "rfc6979/rfc6979.h" -#include -#include #include #include #include @@ -35,12 +33,7 @@ using namespace Ark::Crypto::Identities; namespace Ark { namespace Crypto { namespace Utils { - -/** - * This is the message class. - * - * @author Simon Downey - **/ +/**/ class Message { public: std::string message; @@ -57,7 +50,6 @@ class Message { std::string toJson(); }; /**/ - }; // namespace Utils }; // namespace Crypto }; // namespace Ark diff --git a/src/utils/slot.cpp b/src/utils/slot.cpp index e8244b02..9584a565 100644 --- a/src/utils/slot.cpp +++ b/src/utils/slot.cpp @@ -10,16 +10,12 @@ #undef round #include "date/date.h" - uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + uint64_t Ark::Crypto::Utils::Slot::epoch(const Crypto::Networks::AbstractNetwork& network) { // https://stackoverflow.com/questions/33421450/c-c-time-zone-correct-time-conversion-to-seconds-since-epoch/33438989#33438989 std::istringstream in(network.epoch()); std::chrono::system_clock::time_point tp; in >> date::parse("%FT%TZ", tp); - if (in.fail()) { - in.clear(); - in.str(network.epoch()); - in >> date::parse("%FT%T%z", tp); - }; + // cast milliseconds as uint64_t in seconds(/ 1000) return static_cast( std::chrono::duration_cast( @@ -36,7 +32,7 @@ #endif -uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork network) { +uint64_t Ark::Crypto::Utils::Slot::time(const Crypto::Networks::AbstractNetwork& network) { const auto time = now() - epoch(network); return (time > 0) ? time : 0; } @@ -47,7 +43,7 @@ uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork networ #include /* strtol */ #include - uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + uint64_t Ark::Crypto::Utils::Slot::epoch(const Crypto::Networks::AbstractNetwork& network) { constexpr const size_t expectedLength = sizeof("2017-03-21T13:00:00.000Z") - 1; if (expectedLength != 24) { return 0; } // Unexpected ISO 8601 date/time length @@ -73,10 +69,10 @@ uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork networ // 'time(0) will collide with Slot::time // so we create the call outside the Slot namespace. - uint64_t NOW() { return time(0); } + static uint64_t Now() { return time(0); } uint64_t Ark::Crypto::Utils::Slot::now() { - return NOW(); + return Now(); } #endif diff --git a/src/utils/slot.h b/src/utils/slot.h index 93650f19..085eacc0 100644 --- a/src/utils/slot.h +++ b/src/utils/slot.h @@ -15,18 +15,18 @@ namespace Ark { namespace Crypto { namespace Utils { - +/**/ class Slot { public: - static uint64_t epoch(Crypto::Networks::AbstractNetwork network); - static uint64_t time(Crypto::Networks::AbstractNetwork network); + static uint64_t epoch(const Crypto::Networks::AbstractNetwork& network); + static uint64_t time(const Crypto::Networks::AbstractNetwork& network); private: static uint64_t now(); }; - -} // namespace Utils -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Utils +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b79d8dc9..48555655 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.2.2) project(Ark-Cpp-Crypto-tests C CXX) -set(BUILD_GMOCK OFF FORCE) - add_subdirectory(lib/googletest) include(CTest) @@ -19,24 +17,27 @@ include_directories(${PROJECT_SOURCE_DIR}/../src/lib/ArduinoJson) include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) set (TEST_SRC - ${PROJECT_SOURCE_DIR}/configuration/fee.cpp - ${PROJECT_SOURCE_DIR}/configuration/network.cpp - ${PROJECT_SOURCE_DIR}/enums/fees.cpp - ${PROJECT_SOURCE_DIR}/enums/types.cpp - ${PROJECT_SOURCE_DIR}/identities/address.cpp - ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp - ${PROJECT_SOURCE_DIR}/identities/publickey.cpp - ${PROJECT_SOURCE_DIR}/identities/wif.cpp - ${PROJECT_SOURCE_DIR}/networks/abstractnetwork.cpp - ${PROJECT_SOURCE_DIR}/networks/devnet.cpp - ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp - ${PROJECT_SOURCE_DIR}/networks/testnet.cpp - ${PROJECT_SOURCE_DIR}/transactions/builder.cpp - ${PROJECT_SOURCE_DIR}/transactions/deserializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/serializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/transaction.cpp - ${PROJECT_SOURCE_DIR}/utils/message.cpp - ${PROJECT_SOURCE_DIR}/utils/slot.cpp + ${PROJECT_SOURCE_DIR}/configuration/fee.cpp + ${PROJECT_SOURCE_DIR}/configuration/network.cpp + ${PROJECT_SOURCE_DIR}/enums/fees.cpp + ${PROJECT_SOURCE_DIR}/enums/types.cpp + ${PROJECT_SOURCE_DIR}/helpers/crypto_helpers.cpp + ${PROJECT_SOURCE_DIR}/helpers/crypto.cpp + ${PROJECT_SOURCE_DIR}/helpers/encoding/hex.cpp + ${PROJECT_SOURCE_DIR}/identities/address.cpp + ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp + ${PROJECT_SOURCE_DIR}/identities/publickey.cpp + ${PROJECT_SOURCE_DIR}/identities/wif.cpp + ${PROJECT_SOURCE_DIR}/networks/abstractnetwork.cpp + ${PROJECT_SOURCE_DIR}/networks/devnet.cpp + ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp + ${PROJECT_SOURCE_DIR}/networks/testnet.cpp + ${PROJECT_SOURCE_DIR}/transactions/builder.cpp + ${PROJECT_SOURCE_DIR}/transactions/deserializer.cpp + ${PROJECT_SOURCE_DIR}/transactions/serializer.cpp + ${PROJECT_SOURCE_DIR}/transactions/transaction.cpp + ${PROJECT_SOURCE_DIR}/utils/message.cpp + ${PROJECT_SOURCE_DIR}/utils/slot.cpp ) find_library(Ark-Cpp-Crypto-tests PUBLIC) @@ -54,4 +55,4 @@ if (CMAKE_BUILD_TYPE STREQUAL "Coverage") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" +endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" diff --git a/test/configuration/fee.cpp b/test/configuration/fee.cpp index 99c5d1eb..000b636d 100644 --- a/test/configuration/fee.cpp +++ b/test/configuration/fee.cpp @@ -4,36 +4,38 @@ TEST(configuration, fee_get) { Ark::Crypto::Configuration::Fee fee; - ASSERT_TRUE(10000000 == fee.get(0)); - ASSERT_TRUE(500000000 == fee.get(1)); - ASSERT_TRUE(2500000000 == fee.get(2)); - ASSERT_TRUE(100000000 == fee.get(3)); - ASSERT_TRUE(500000000 == fee.get(4)); - ASSERT_TRUE(0 == fee.get(5)); - ASSERT_TRUE(0 == fee.get(6)); - ASSERT_TRUE(0 == fee.get(7)); - ASSERT_TRUE(0 == fee.get(8)); + ASSERT_EQ(10000000ULL, fee.get(0)); + ASSERT_EQ(500000000ULL, fee.get(1)); + ASSERT_EQ(2500000000ULL, fee.get(2)); + ASSERT_EQ(100000000ULL, fee.get(3)); + ASSERT_EQ(500000000ULL, fee.get(4)); + ASSERT_EQ(0ULL, fee.get(5)); + ASSERT_EQ(0ULL, fee.get(6)); + ASSERT_EQ(0ULL, fee.get(7)); + ASSERT_EQ(0ULL, fee.get(8)); } +/**/ + TEST(configuration, fee_set) { Ark::Crypto::Configuration::Fee fee; - fee.set(0, 20000000ul); - fee.set(1, 1000000000ul); - fee.set(2, 4000000000ul); - fee.set(3, 200000000ul); - fee.set(4, 1000000000ul); - fee.set(5, 1ul); - fee.set(6, 1ul); - fee.set(7, 1ul); - fee.set(8, 1ul); + fee.set(0ULL, 20000000ULL); + fee.set(1ULL, 1000000000ULL); + fee.set(2ULL, 4000000000ULL); + fee.set(3ULL, 200000000ULL); + fee.set(4ULL, 1000000000ULL); + fee.set(5ULL, 1ULL); + fee.set(6ULL, 1ULL); + fee.set(7ULL, 1ULL); + fee.set(8ULL, 1ULL); - ASSERT_TRUE(20000000 == fee.get(0)); - ASSERT_TRUE(1000000000 == fee.get(1)); - ASSERT_TRUE(4000000000 == fee.get(2)); - ASSERT_TRUE(200000000 == fee.get(3)); - ASSERT_TRUE(1000000000 == fee.get(4)); - ASSERT_TRUE(1 == fee.get(5)); - ASSERT_TRUE(1 == fee.get(6)); - ASSERT_TRUE(1 == fee.get(7)); - ASSERT_TRUE(1 == fee.get(8)); + ASSERT_EQ(20000000ULL, fee.get(0)); + ASSERT_EQ(1000000000ULL, fee.get(1)); + ASSERT_EQ(4000000000ULL, fee.get(2)); + ASSERT_EQ(200000000ULL, fee.get(3)); + ASSERT_EQ(1000000000ULL, fee.get(4)); + ASSERT_EQ(1ULL, fee.get(5)); + ASSERT_EQ(1ULL, fee.get(6)); + ASSERT_EQ(1ULL, fee.get(7)); + ASSERT_EQ(1ULL, fee.get(8)); } diff --git a/test/configuration/network.cpp b/test/configuration/network.cpp index 41aa3763..d0d561f0 100644 --- a/test/configuration/network.cpp +++ b/test/configuration/network.cpp @@ -14,6 +14,8 @@ TEST(configuration, network_get) { ASSERT_EQ(30, network.version()); } +/**/ + TEST(configuration, network_set) { Network network; network.set(Testnet); diff --git a/test/enums/fees.cpp b/test/enums/fees.cpp index d1aedb5b..6df1be31 100644 --- a/test/enums/fees.cpp +++ b/test/enums/fees.cpp @@ -1,34 +1,33 @@ + #include "gtest/gtest.h" #include "enums/fees.h" TEST(enums, fees) { - Ark::Crypto::Enums::Fees fees; - - auto feeZERO = fees.TRANSFER; - ASSERT_TRUE(10000000 == feeZERO); + auto feeZERO = Ark::Crypto::Enums::Fees::TRANSFER; + ASSERT_EQ(10000000ULL, feeZERO); - auto feeONE = fees.SECOND_SIGNATURE_REGISTRATION; - ASSERT_TRUE(500000000 == feeONE); + auto feeONE = Ark::Crypto::Enums::Fees::SECOND_SIGNATURE_REGISTRATION; + ASSERT_EQ(500000000ULL, feeONE); - auto feeTWO = fees.DELEGATE_REGISTRATION; - ASSERT_TRUE(2500000000 == feeTWO); + auto feeTWO = Ark::Crypto::Enums::Fees::DELEGATE_REGISTRATION; + ASSERT_EQ(2500000000ULL, feeTWO); - auto feeTHREE = fees.VOTE; - ASSERT_TRUE(100000000 == feeTHREE); + auto feeTHREE = Ark::Crypto::Enums::Fees::VOTE; + ASSERT_EQ(100000000ULL, feeTHREE); - auto feeFOUR = fees.MULTI_SIGNATURE_REGISTRATION; - ASSERT_TRUE(500000000 == feeFOUR); + auto feeFOUR = Ark::Crypto::Enums::Fees::MULTI_SIGNATURE_REGISTRATION; + ASSERT_EQ(500000000ULL, feeFOUR); - auto feeFIVE = fees.IPFS; - ASSERT_TRUE(0 == feeFIVE); + auto feeFIVE = Ark::Crypto::Enums::Fees::IPFS; + ASSERT_EQ(0ULL, feeFIVE); - auto feeSIX = fees.TIMELOCK_TRANSFER; - ASSERT_TRUE(0 == feeSIX); + auto feeSIX = Ark::Crypto::Enums::Fees::TIMELOCK_TRANSFER; + ASSERT_EQ(0ULL, feeSIX); - auto feeSEVEN = fees.MULTI_PAYMENT; - ASSERT_TRUE(0 == feeSEVEN); + auto feeSEVEN = Ark::Crypto::Enums::Fees::MULTI_PAYMENT; + ASSERT_EQ(0ULL, feeSEVEN); - auto feeEIGHT = fees.DELEGATE_RESIGNATION; - ASSERT_TRUE(0 == feeEIGHT); + auto feeEIGHT = Ark::Crypto::Enums::Fees::DELEGATE_RESIGNATION; + ASSERT_EQ(0ULL, feeEIGHT); } diff --git a/test/enums/types.cpp b/test/enums/types.cpp index 4d482025..dd031c54 100644 --- a/test/enums/types.cpp +++ b/test/enums/types.cpp @@ -1,15 +1,16 @@ + #include "gtest/gtest.h" #include "enums/types.h" TEST(enums, types) { - ASSERT_EQ(0, Ark::Crypto::Enums::Types::TRANSFER); - ASSERT_EQ(1, Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION); - ASSERT_EQ(2, Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION); - ASSERT_EQ(3, Ark::Crypto::Enums::Types::VOTE); - ASSERT_EQ(4, Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION); - ASSERT_EQ(5, Ark::Crypto::Enums::Types::IPFS); - ASSERT_EQ(6, Ark::Crypto::Enums::Types::TIMELOCK_TRANSFER); - ASSERT_EQ(7, Ark::Crypto::Enums::Types::MULTI_PAYMENT); - ASSERT_EQ(8, Ark::Crypto::Enums::Types::DELEGATE_RESIGNATION); + ASSERT_EQ(0U, Ark::Crypto::Enums::Types::TRANSFER); + ASSERT_EQ(1U, Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION); + ASSERT_EQ(2U, Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION); + ASSERT_EQ(3U, Ark::Crypto::Enums::Types::VOTE); + ASSERT_EQ(4U, Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION); + ASSERT_EQ(5U, Ark::Crypto::Enums::Types::IPFS); + ASSERT_EQ(6U, Ark::Crypto::Enums::Types::TIMELOCK_TRANSFER); + ASSERT_EQ(7U, Ark::Crypto::Enums::Types::MULTI_PAYMENT); + ASSERT_EQ(8U, Ark::Crypto::Enums::Types::DELEGATE_RESIGNATION); } diff --git a/test/helpers/crypto.cpp b/test/helpers/crypto.cpp new file mode 100644 index 00000000..2acea58f --- /dev/null +++ b/test/helpers/crypto.cpp @@ -0,0 +1,108 @@ + +#include "gtest/gtest.h" + +#include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "bcl/Sha256.hpp" +#include "bcl/Uint256.hpp" + +#include "helpers/crypto.h" + +namespace { // NOLINT + std::vector MessageHashTestBytes = { + 165, 145, 166, 212, 11, 244, 32, 64, + 74, 1, 23, 51, 207, 183, 177, 144, + 214, 44, 101, 191, 11, 205, 163, 43, + 87, 178, 119, 217, 173, 159, 20, 110 + }; + + std::vector PrivateKeyTestBytes = { + 216, 131, 156, 36, 50, 191, 208, 166, + 126, 241, 10, 128, 75, 169, 145, 234, + 187, 161, 159, 21, 74, 61, 112, 121, + 23, 104, 29, 69, 130, 42, 87, 18 + }; + + std::vector PublicKeyTestBytes = { + 3, + 65, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + std::vector InvalidPublicKeyTestBytes = { + 3, + 66, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + + std::vector RValueTestBytes = { + 15, 180, 173, 221, 209, 241, 214, 82, + 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, + 141, 176, 202, 235, 250, 104, 146, 158 + }; + + std::vector SValueTestBytes = { + 94, 203, 46, 28, 99, 178, 152, 121, + 194, 236, 241, 37, 93, 181, 6, 214, + 113, 200, 179, 250, 96, 23, 246, 124, + 253, 27, 240, 126, 110, 221, 28, 200 + }; + + std::vector SignatureTestBytes = { + 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, + 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, + 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, + 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, + 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, + 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 + }; +}; + +/**/ + +TEST(helpers, crypto_sign) { + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + Ark::Crypto::Identities::PrivateKey privateKey(&PrivateKeyTestBytes[0]); + std::vector signature; + cryptoSign( + hash, + privateKey, + signature); + + for (auto i = 0; i < signature.size(); ++i) { + ASSERT_EQ(signature[i], SignatureTestBytes[i]); + }; +} + +/**/ + +TEST(helpers, crypto_verify_valid) { + Ark::Crypto::Identities::PublicKey publicKey(&PublicKeyTestBytes[0]); + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + + bool isValid = cryptoVerify( + publicKey, + hash, + SignatureTestBytes); + ASSERT_TRUE(isValid); +} + +/**/ + +TEST(helpers, crypto_verify_invalid) { + Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); +// Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + + bool isValid = cryptoVerify( + publicKey, + hash, + SignatureTestBytes); + ASSERT_FALSE(isValid); +} diff --git a/test/helpers/crypto_helpers.cpp b/test/helpers/crypto_helpers.cpp new file mode 100644 index 00000000..e3bc51ec --- /dev/null +++ b/test/helpers/crypto_helpers.cpp @@ -0,0 +1,30 @@ + +#include "gtest/gtest.h" + +#include "helpers/crypto_helpers.h" + +#include +#include + +TEST(helpers, pack_unpack) { + std::vector packBuffer; + uint8_t packValue = 23; + pack(packBuffer, packValue); + + uint8_t unpackValue; + unpack(&unpackValue, &packBuffer[0]); + ASSERT_EQ(packValue, unpackValue); +} + +/**/ + +TEST(helpers, join) { + const auto strBuffer = "123"; + std::vector vstr(3); + vstr[0] = strBuffer[0]; + vstr[1] = strBuffer[1]; + vstr[2]= strBuffer[2]; + + std::string joined = join(vstr); + ASSERT_STREQ(joined.c_str(), strBuffer); +} diff --git a/test/helpers/encoding/hex.cpp b/test/helpers/encoding/hex.cpp new file mode 100644 index 00000000..5c0cb8f7 --- /dev/null +++ b/test/helpers/encoding/hex.cpp @@ -0,0 +1,41 @@ + +#include "gtest/gtest.h" + +#include "helpers/encoding/hex.h" + +namespace { // NOLINT + std::vector SignatureTestBytes = { + 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, + 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, + 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, + 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, + 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, + 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 + }; + const auto SignatureTestString = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; + const auto SignatureTestStringSpaces = "30 44 02 20 0f b4 ad dd d1 f1 d6 52 b5 44 ea 6a b6 28 28 a0 a6 5b 71 2e d4 47 e2 53 8d b0 ca eb fa 68 92 9e 02 20 5e cb 2e 1c 63 b2 98 79 c2 ec f1 25 5d b5 06 d6 71 c8 b3 fa 60 17 f6 7c fd 1b f0 7e 6e dd 1c c8"; +} + +TEST(helpers, hex_bytes_to_hex) { + const auto result = BytesToHex(&SignatureTestBytes[0], &SignatureTestBytes[0] + SignatureTestBytes.size()); + ASSERT_STREQ(result.c_str(), SignatureTestString); +} + +/**/ + +TEST(helpers, hex_hex_to_bytes) { + const auto result = HexToBytes(SignatureTestString); + for (auto i = 0; i < result.size(); ++i) { + ASSERT_TRUE(result[i] == SignatureTestBytes[i]); + }; +} + +/**/ + +TEST(helpers, hex_hex_to_bytes_spaces) { + const auto result = HexToBytes(SignatureTestStringSpaces); + for (auto i = 0; i < result.size(); ++i) { + ASSERT_TRUE(result[i] == SignatureTestBytes[i]); + }; +} diff --git a/test/identities/address.cpp b/test/identities/address.cpp index 9b0e85e6..ebbfaad3 100644 --- a/test/identities/address.cpp +++ b/test/identities/address.cpp @@ -4,39 +4,104 @@ #include "identities/address.h" #include "identities/privatekey.h" #include "identities/publickey.h" + +#include + using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t networkVersion = 0x1E; + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t NetworkVersion = 0x1E; + const auto AddressString = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; + const uint8_t TestAddressBytes[34] = { + 68, 54, 49, 109, 102, 83, 103, 103, + 122, 98, 118, 81, 103, 84, 85, 101, + 54, 74, 104, 89, 75, 72, 50, 100, + 111, 72, 97, 113, 74, 51, 68, 121, 105, 98 + }; } // namespace +/**/ + +TEST(identities, address_from_bytes) { + Address address(TestAddressBytes); + ASSERT_STREQ(address.toString().c_str(), AddressString); +} + +/**/ + +TEST(identities, address_to_bytes) { + Address address(AddressString); + const auto addressBytes = address.toBytes(); + for (auto i = 0; i < 34; ++i) { + ASSERT_EQ(addressBytes[i], TestAddressBytes[i]); + }; +} + +/**/ + TEST(identities, address_from_passphrase) { - Address address = Address::fromPassphrase(passphrase, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + Address address = Address::fromPassphrase(Passphrase, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_privatekey) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - Address address = Address::fromPrivateKey(privateKey, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + const auto privateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; + PrivateKey privateKey(privateKeyString); + Address address = Address::fromPrivateKey(privateKey, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_publickey) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - Address address = Address::fromPublicKey(publicKey, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + const auto publicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; + PublicKey publicKey(publicKeyString); + Address address = Address::fromPublicKey(publicKey, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_string) { - Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + Address address(AddressString); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + +TEST(identities, address_validate_address) { + Address address(AddressString); + ASSERT_TRUE(Address::validate(address, NetworkVersion)); +} + +/**/ + TEST(identities, address_validate) { - Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); - ASSERT_TRUE(Address::validate(address, networkVersion)); + Address address(AddressString); + ASSERT_TRUE(Address::validate(address, NetworkVersion)); +} + +/**/ + +TEST(identities, address_validate_string) { + ASSERT_TRUE(Address::validate(AddressString, NetworkVersion)); +} + +/**/ + +TEST(identities, address_validate_bytes) { + ASSERT_TRUE(Address::validate(TestAddressBytes, NetworkVersion)); +} + +/**/ + +TEST(identities, address_invalid) { + const auto invalidAddressStr = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyi"; + Address address(invalidAddressStr); + ASSERT_FALSE(Address::validate(address, NetworkVersion)); } diff --git a/test/identities/privatekey.cpp b/test/identities/privatekey.cpp index 9243a34a..b7594c29 100644 --- a/test/identities/privatekey.cpp +++ b/test/identities/privatekey.cpp @@ -5,68 +5,67 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testPrivateKeyBytes[32] = { + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestPrivateKeyBytes[32] = { 216, 131, 156, 36, 50, 191, 208, 166, 126, 241, 10, 128, 75, 169, 145, 234, 187, 161, 159, 21, 74, 61, 112, 121, - 23, 104, 29, 69, 130, 42, 87, 18 -}; -const uint8_t wifByte = 0xaa; - + 23, 104, 29, 69, 130, 42, 87, 18 + }; + const uint8_t WIFByte = 0xaa; + const auto PrivateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; } // namespace TEST(identities, privatekey_construct_bytes) { - PrivateKey privateKey(testPrivateKeyBytes); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(TestPrivateKeyBytes); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_construct_string) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_hex) { - PrivateKey privateKey = PrivateKey::fromHex("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromHex(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_passphrase) { - PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromPassphrase(Passphrase); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_string) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_wif_string) { const char* wifStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; - PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, wifByte); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, WIFByte); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_get_bytes) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + PrivateKey privateKey(PrivateKeyString); const auto privateKeyBytes = privateKey.toBytes(); for (unsigned int i = 0; i < PRIVATEKEY_SIZE; i++) { - ASSERT_EQ(privateKeyBytes[i], testPrivateKeyBytes[i]); + ASSERT_EQ(privateKeyBytes[i], TestPrivateKeyBytes[i]); }; } TEST(identities, privatekey_validate) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + PrivateKey privateKey(PrivateKeyString); ASSERT_TRUE(PrivateKey::validate(privateKey)); } TEST(identities, privatekey_validate_bytes) { - ASSERT_TRUE(PrivateKey::validate(testPrivateKeyBytes)); + ASSERT_TRUE(PrivateKey::validate(TestPrivateKeyBytes)); } TEST(identities, privatekey_validate_string) { - ASSERT_TRUE(PrivateKey::validate("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712")); + ASSERT_TRUE(PrivateKey::validate(PrivateKeyString)); } diff --git a/test/identities/publickey.cpp b/test/identities/publickey.cpp index 5e9cfdc8..098833f3 100644 --- a/test/identities/publickey.cpp +++ b/test/identities/publickey.cpp @@ -5,57 +5,73 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testPublicKeyBytes[33] = { - 3, - 65, 81, 163, 236, 70, 181, 103, 10, - 104, 43, 10, 99, 57, 79, 134, 53, - 135, 209, 188, 151, 72, 59, 27, 108, - 112, 235, 88, 231, 240, 174, 209, 146 -}; - + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestPublicKeyBytes[33] = { + 3, + 65, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + const auto PublicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; } // namespace +/**/ + TEST(identities, publickey_from_bytes) { - PublicKey publicKey(testPublicKeyBytes); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey(TestPublicKeyBytes); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_hex) { - PublicKey publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey = PublicKey::fromHex(PublicKeyString); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_passphrase) { - PublicKey publicKey = PublicKey::fromPassphrase(passphrase); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey = PublicKey::fromPassphrase(Passphrase); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_string) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey(PublicKeyString); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_get_bytes) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + PublicKey publicKey(PublicKeyString); const auto publicKeyBytes = publicKey.toBytes(); for (unsigned int i = 0; i < COMPRESSED_PUBLICKEY_SIZE; i++) { - ASSERT_EQ(publicKeyBytes[i], testPublicKeyBytes[i]); + ASSERT_EQ(publicKeyBytes[i], TestPublicKeyBytes[i]); }; } +/**/ + TEST(identities, publickey_validate) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + PublicKey publicKey(PublicKeyString); ASSERT_TRUE(PublicKey::validate(publicKey)); + ASSERT_TRUE(publicKey.isValid()); } +/**/ + TEST(identities, publickey_validate_bytes) { - ASSERT_TRUE(PublicKey::validate(testPublicKeyBytes)); + ASSERT_TRUE(PublicKey::validate(TestPublicKeyBytes)); } +/**/ + TEST(identities, publickey_validate_string) { - ASSERT_TRUE(PublicKey::validate("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192")); + ASSERT_TRUE(PublicKey::validate(PublicKeyString)); } diff --git a/test/identities/wif.cpp b/test/identities/wif.cpp index 275acf2a..84678de5 100644 --- a/test/identities/wif.cpp +++ b/test/identities/wif.cpp @@ -5,39 +5,54 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testWIFBytes[52] = { + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestWIFBytes[52] = { 83, 71, 113, 52, 120, 76, 103, 90, 75, 67, 71, 120, 115, 55, 98, 106, 109, 119, 110, 66, 114, 87, 99, 84, 52, 67, 49, 65, 68, 70, 69, 101, 114, 109, 106, 56, 52, 54, 75, 67, 57, 55, 70, 83, 118, 49, 87, 70, 68, 49, 100, 65 -}; -const uint8_t wifByte = 0xaa; - + }; + const uint8_t WIFByte = 0xaa; + const auto AddressString = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; } // namespace +/**/ + TEST(identities, wif_from_bytes) { - WIF wif(testWIFBytes); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif(TestWIFBytes); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_from_passphrase) { - WIF wif = WIF::fromPassphrase(passphrase, wifByte); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif = WIF::fromPassphrase(Passphrase, WIFByte); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_from_string) { - WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif(AddressString); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_get_bytes) { - WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); + WIF wif(AddressString); const auto wifBytes = wif.toBytes(); for (unsigned int i = 0; i < WIF_SIZE; i++) { - ASSERT_EQ(wifBytes[i], testWIFBytes[i]); + ASSERT_EQ(wifBytes[i], TestWIFBytes[i]); }; } + +/**/ + +TEST(identities, wif_invalid) { + const auto invalidWIFStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1d"; + WIF wif(invalidWIFStr); + ASSERT_FALSE(WIF::validate(wif)); +} diff --git a/test/networks/abstractnetwork.cpp b/test/networks/abstractnetwork.cpp index 42a2ef4b..e6dfc0b5 100644 --- a/test/networks/abstractnetwork.cpp +++ b/test/networks/abstractnetwork.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "networks/abstractnetwork.h" @@ -6,25 +7,57 @@ using namespace Ark::Crypto::Networks; #include AbstractNetwork CUSTOM_NETWORK = { - { - 0x01, // BASE58_ADDRESS_P2PKH - 0x02, // BASE58_ADDRESS_P2SH - 0x03 // BASE58_WIF - }, - { - 00010100, // BIP32_PREFIX_XPUB - 00010101 // BIP32_PREFIX_XPRV - }, - "0000-00-00T00:00:00.000Z", // Epoch - false // isLocked + { + 0x01, // BASE58_ADDRESS_P2PKH + 0x02, // BASE58_ADDRESS_P2SH + 0x03 // BASE58_WIF + }, + { + 00010100, // BIP32_PREFIX_XPUB + 00010101 // BIP32_PREFIX_XPRV + }, + "0000-00-00T00:00:00.000Z", // Epoch + false // isLocked +}; + +/**/ + +TEST(networks, abstract_network_default) { + AbstractNetwork abstractNetwork; + ASSERT_FALSE(abstractNetwork.isLocked()); }; +/**/ + +TEST(networks, abstract_network_custom) { + base58_t base58 = { 0x01, 0x02, 0x03 }; + bip32_t bip32 = { 00010100, 00010101 }; + const auto epoch = "0000-00-00T00:00:00.000Z"; + + AbstractNetwork testNetwork(base58, bip32, epoch, true); + + ASSERT_EQ( + CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH), + testNetwork.getBase58Prefix(BASE58_ADDRESS_P2PKH)); + ASSERT_EQ( + CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH), + testNetwork.getBase58Prefix(BASE58_ADDRESS_P2SH)); + ASSERT_EQ( + CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF), + testNetwork.getBase58Prefix(BASE58_WIF)); + ASSERT_TRUE(testNetwork.isLocked()); +} + +/**/ + TEST(networks, abstract_network_base58_prefix_get) { ASSERT_EQ(1, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); ASSERT_EQ(2, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH)); ASSERT_EQ(3, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); } +/**/ + TEST(networks, abstract_network_base58_prefix_set) { CUSTOM_NETWORK.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x10); ASSERT_EQ(0x10, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); @@ -36,11 +69,15 @@ TEST(networks, abstract_network_base58_prefix_set) { ASSERT_EQ(0x30, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); } +/**/ + TEST(networks, abstract_network_bip32_prefix_get) { ASSERT_EQ(00010100, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); ASSERT_EQ(00010101, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); } +/**/ + TEST(networks, abstract_network_bip32_prefix_set) { CUSTOM_NETWORK.setBIP32Prefix(BIP32_PREFIX_XPUB, 1000000); ASSERT_EQ(1000000, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); @@ -49,14 +86,21 @@ TEST(networks, abstract_network_bip32_prefix_set) { ASSERT_EQ(1000001, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); } +/**/ + TEST(networks, abstract_network_epoch) { - ASSERT_STREQ("0000-00-00T00:00:00.000Z", CUSTOM_NETWORK.epoch()); + const auto expected = "0000-00-00T00:00:00.000Z"; + ASSERT_STREQ(expected, CUSTOM_NETWORK.epoch()); } +/**/ + TEST(networks, abstract_network_is_locked) { ASSERT_EQ(false, CUSTOM_NETWORK.isLocked()); } +/**/ + TEST(networks, abstract_network_version) { AbstractNetwork customNetwork = CUSTOM_NETWORK; customNetwork.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x14); diff --git a/test/networks/devnet.cpp b/test/networks/devnet.cpp index f02bdc49..20553618 100644 --- a/test/networks/devnet.cpp +++ b/test/networks/devnet.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "networks/devnet.h" @@ -9,19 +10,27 @@ TEST(networks, devnet_base58_prefix_get) { ASSERT_EQ(0xaa, Devnet.getBase58Prefix(BASE58_WIF)); } +/**/ + TEST(networks, devnet_bip32_prefix_get) { ASSERT_EQ(46090600, Devnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); ASSERT_EQ(46089520, Devnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); } +/**/ + TEST(networks, devnet_epoch) { ASSERT_STREQ("2017-03-21T13:00:00.000Z", Devnet.epoch()); } +/**/ + TEST(networks, devnet_is_locked) { ASSERT_EQ(true, Devnet.isLocked()); } +/**/ + TEST(networks, devnet_version) { ASSERT_EQ(30, Devnet.version()); } diff --git a/test/networks/mainnet.cpp b/test/networks/mainnet.cpp index 36acb4f1..654d1d60 100644 --- a/test/networks/mainnet.cpp +++ b/test/networks/mainnet.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "networks/mainnet.h" @@ -9,19 +10,27 @@ TEST(networks, mainnet_base58_prefix_get) { ASSERT_EQ(0xaa, Mainnet.getBase58Prefix(BASE58_WIF)); } +/**/ + TEST(networks, mainnet_bip32_prefix_get) { ASSERT_EQ(46090600, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); ASSERT_EQ(46089520, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); } +/**/ + TEST(networks, mainnet_epoch) { ASSERT_STREQ("2017-03-21T13:00:00.000Z", Mainnet.epoch()); } +/**/ + TEST(networks, mainnet_is_locked) { ASSERT_EQ(true, Mainnet.isLocked()); } +/**/ + TEST(networks, mainnet_version) { ASSERT_EQ(23, Mainnet.version()); } diff --git a/test/networks/testnet.cpp b/test/networks/testnet.cpp index 2a56c867..9aa9482e 100644 --- a/test/networks/testnet.cpp +++ b/test/networks/testnet.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "networks/testnet.h" @@ -9,19 +10,27 @@ TEST(networks, testnet_base58_prefix_get) { ASSERT_EQ(0xba, Testnet.getBase58Prefix(BASE58_WIF)); } +/**/ + TEST(networks, testnet_bip32_prefix_get) { ASSERT_EQ(70617039, Testnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); ASSERT_EQ(70615956, Testnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); } +/**/ + TEST(networks, testnet_epoch) { ASSERT_STREQ("2017-03-21T13:00:00.000Z", Testnet.epoch()); } +/**/ + TEST(networks, testnet_is_locked) { ASSERT_EQ(true, Testnet.isLocked()); } +/**/ + TEST(networks, testnet_version) { ASSERT_EQ(23, Testnet.version()); } diff --git a/test/transactions/builder.cpp b/test/transactions/builder.cpp index 034f8bfe..96d4ddb9 100644 --- a/test/transactions/builder.cpp +++ b/test/transactions/builder.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "configuration/fee.h" @@ -6,21 +7,30 @@ using namespace Ark::Crypto::Transactions; TEST(transactions, build_transfer) { - const auto actual = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 100000000, - "", "Secret passphrase"); + const auto actual = Ark::Crypto::Transactions::Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "", + "Secret passphrase"); ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); - ASSERT_TRUE(Ark::Crypto::Configuration::Fee().get(Ark::Crypto::Enums::Types::TRANSFER) == actual.fee); + ASSERT_EQ( + Ark::Crypto::Configuration::Fee().get(Ark::Crypto::Enums::Types::TRANSFER), + actual.fee); ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); - ASSERT_TRUE(100000000 == actual.amount); - ASSERT_STREQ("", actual.vendorField.c_str()); + ASSERT_EQ(100000000ULL, actual.amount); + ASSERT_TRUE(actual.vendorField.empty()); +} + +/**/ +TEST(transactions, build_empty_transaction) { // test 0 ARKtoshi value const auto shouldBeEmpty = Ark::Crypto::Transactions::Builder::buildTransfer( "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 0, "", "Secret passphrase"); - ASSERT_STREQ("", shouldBeEmpty.recipientId.c_str()); - ASSERT_EQ(0, shouldBeEmpty.amount); + ASSERT_TRUE(shouldBeEmpty.recipientId.empty()); + ASSERT_EQ(0ULL, shouldBeEmpty.amount); ASSERT_FALSE(shouldBeEmpty.verify()); } diff --git a/test/transactions/deserializer.cpp b/test/transactions/deserializer.cpp index 88cbad91..8254e85e 100644 --- a/test/transactions/deserializer.cpp +++ b/test/transactions/deserializer.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "enums/types.h" @@ -5,56 +6,65 @@ #include "identities/publickey.h" #include "transactions/deserializer.h" -TEST(transactions, deserialize_transfer) { +TEST(transactions, deserialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f20" - "576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067bbfc8" - "fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"); + "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" + "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" + "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); - ASSERT_EQ(41443847, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(10000000 == actual.fee); + ASSERT_EQ(41443847UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_TRUE(10000000ULL == actual.fee); ASSERT_STREQ("48656c6c6f20576f726c64", actual.vendorFieldHex.c_str()); ASSERT_STREQ("Hello World", actual.vendorField.c_str()); - ASSERT_TRUE(200000000 == actual.amount); - ASSERT_STREQ("ecf558fbddd62ae42edcfcba02f402d987a94b72a7636ef1121e8625487e2a1e", actual.id.c_str()); + ASSERT_TRUE(200000000ULL == actual.amount); + ASSERT_STREQ( + "ecf558fbddd62ae42edcfcba02f402d987a94b72a7636ef1121e8625487e2a1e", + actual.id.c_str()); ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); ASSERT_STREQ( - "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500ad" - "db830c79f49b9de484ec616bb1e1", + "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", actual.signature.c_str()); ASSERT_TRUE(actual.verify()); } -TEST(transactions, deserialize_second_signature_registration) { +/**/ + +TEST(transactions, deserialize_second_signature_registration) { // NOLINT // second_signature_registration/second-passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003699e966b25" - "25f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf0" - "2c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"); + "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" + "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" + "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); ASSERT_EQ(Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION, actual.type); - ASSERT_EQ(41271867, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(500000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_EQ(41271867UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_TRUE(500000000ULL == actual.fee); + ASSERT_TRUE(0UL == actual.amount); ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ("6d1615924d172d352c8f44d4ded84cbbece3c03ebb3e4fc3f3334784ae332590", actual.id.c_str()); - ASSERT_STREQ("03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609", - actual.asset.signature.publicKey.c_str()); ASSERT_STREQ( - "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb46" - "10cdeca3b9e20d6c8773f869831c", + "6d1615924d172d352c8f44d4ded84cbbece3c03ebb3e4fc3f3334784ae332590", + actual.id.c_str()); + ASSERT_STREQ( + "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609", + actual.asset.signature.publicKey.c_str()); + ASSERT_STREQ( + "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", actual.signature.c_str()); ASSERT_TRUE(actual.verify()); @@ -64,48 +74,64 @@ TEST(transactions, deserialize_second_signature_registration) { ASSERT_STREQ(address.toString().c_str(), actual.recipientId.c_str()); } +/**/ + #if 0 -TEST(transactions, deserialize_delegate_registration) -{ - // delegate_registration/second-passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer("ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f90295000000000009626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION, actual.type); - ASSERT_EQ(41269424, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(2500000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); - ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ("bf7e018ff9c0066f7a9f51e95d3f78c08cad5dd8581325d630d64350181a91bb", actual.id.c_str()); - ASSERT_STREQ("boldninja", actual.asset.delegate.username.c_str()); - ASSERT_STREQ("3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94", actual.signature.c_str()); - ASSERT_STREQ("304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", actual.secondSignature.c_str()); - ASSERT_TRUE(actual.verify()); +TEST(transactions, deserialize_delegate_registration) { // NOLINT + // delegate_registration/second-passphrase.json + Ark::Crypto::Transactions::Deserializer deserializer( + "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" + "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" + "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" + "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c" + ); + auto actual = deserializer.deserialize(); + + ASSERT_EQ(0xFF, actual.header); + ASSERT_EQ(2, actual.type); + ASSERT_EQ(1, actual.version); + ASSERT_EQ(30, actual.network); + ASSERT_EQ(Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION, actual.type); + ASSERT_EQ(41269424UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_EQ(2500000000ULL, actual.fee); + ASSERT_EQ(0ULL, actual.amount); + ASSERT_EQ(0, actual.expiration); + ASSERT_STREQ( + "bf7e018ff9c0066f7a9f51e95d3f78c08cad5dd8581325d630d64350181a91bb", + actual.id.c_str()); + ASSERT_STREQ("boldninja", actual.asset.delegate.username.c_str()); + ASSERT_STREQ( + "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94", + actual.signature.c_str()); + ASSERT_STREQ( + "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", + actual.secondSignature.c_str()); + ASSERT_TRUE(actual.verify())); } #endif -TEST(transactions, deserialize_vote) { +/**/ + +TEST(transactions, deserialize_vote) { // NOLINT // vote/second-passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda" - "66"); + "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); ASSERT_EQ(Ark::Crypto::Enums::Types::VOTE, actual.type); - ASSERT_EQ(41269366, actual.timestamp); + ASSERT_EQ(41269366UL, actual.timestamp); ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(100000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_TRUE(100000000ULL == actual.fee); + ASSERT_TRUE(0ULL == actual.amount); ASSERT_EQ(0, actual.expiration); ASSERT_STREQ("16f28a180cd6f3ea46c10f358a457989e956e9d355258230d0c7b07acec10b73", actual.id.c_str()); ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); @@ -115,17 +141,17 @@ TEST(transactions, deserialize_vote) { ASSERT_STREQ(votes[0].c_str(), actual.asset.votes[0].c_str()); ASSERT_STREQ( - "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0" - "d5828ed2d7c53a5e8db08cb6d068", + "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068", actual.signature.c_str()); ASSERT_STREQ( - "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353e" - "d7881dc29787a5e8ecbee2dfda66", + "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", actual.secondSignature.c_str()); ASSERT_TRUE(actual.verify()); } -TEST(transactions, deserialize_multi_signature_registration) { +/**/ + +TEST(transactions, deserialize_multi_signature_registration) { // NOLINT // multi_signature_registration/passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( "ff011704724c9a00036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d76000943577000000000002031803543c" @@ -136,23 +162,24 @@ TEST(transactions, deserialize_multi_signature_registration) { "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913" - "d"); + "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(23, actual.network); ASSERT_EQ(Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION, actual.type); - ASSERT_EQ(10112114, actual.timestamp); + ASSERT_EQ(10112114UL, actual.timestamp); ASSERT_STREQ("036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760", actual.senderPublicKey.c_str()); - ASSERT_TRUE(2000000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_TRUE(2000000000ULL == actual.fee); + ASSERT_TRUE(0ULL == actual.amount); ASSERT_EQ(0, actual.expiration); - std::vector keysgroup = {"+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31"}; + std::vector keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; ASSERT_EQ(3, actual.asset.multiSignature.keysgroup.size()); ASSERT_EQ(2, actual.asset.multiSignature.min); @@ -160,26 +187,21 @@ TEST(transactions, deserialize_multi_signature_registration) { for (uint8_t i = 0; i < keysgroup.size(); i++) { ASSERT_STREQ(keysgroup[i].c_str(), actual.asset.multiSignature.keysgroup[i].c_str()); - } + }; ASSERT_STREQ("cbd6862966bb1b03ba742397b7e5a88d6eefb393a362ead0d605723b840db2af", actual.id.c_str()); ASSERT_STREQ( - "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93" - "753c82a711c3558045e787bc01a5", + "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5", actual.signature.c_str()); ASSERT_STREQ( - "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488e" - "b89b697c711f91e8c03b9620e0b1", + "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1", actual.secondSignature.c_str()); std::vector signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4e" - "d1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2e" - "aaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89" - "085c328817919939f2efeabd913d"}; + "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", + "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", + "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"}; ASSERT_EQ(3, actual.signatures.size()); for (uint8_t i = 0; i < signatures.size(); i++) { diff --git a/test/transactions/serializer.cpp b/test/transactions/serializer.cpp index a5b29cb1..b41196ec 100644 --- a/test/transactions/serializer.cpp +++ b/test/transactions/serializer.cpp @@ -1,98 +1,93 @@ + #include "gtest/gtest.h" #include "transactions/serializer.h" -TEST(transactions, serialize_transfer) { +TEST(transactions, serialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 0; - transaction.fee = 10000000; - transaction.amount = 200000000; - transaction.timestamp = 41443847; + transaction.fee = 10000000ULL; + transaction.amount = 200000000ULL; + transaction.timestamp = 41443847UL; transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; transaction.vendorField = "Hello World"; - transaction.signature = - "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500ad" - "db830c79f49b9de484ec616bb1e1"; + transaction.signature = "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f20" - "576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067bbfc8" - "fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", + "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" + "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" + "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", actual.c_str()); } -TEST(transactions, serialize_second_signature_registration) { +/**/ + +TEST(transactions, serialize_second_signature_registration) { // NOLINT // second_signature_registration/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 1; - transaction.fee = 500000000; - transaction.timestamp = 41271867; + transaction.fee = 500000000ULL; + transaction.timestamp = 41271867UL; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb46" - "10cdeca3b9e20d6c8773f869831c"; + transaction.signature = "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"; transaction.asset.signature.publicKey = "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003699e966b25" - "25f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf0" - "2c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", + "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" + "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" + "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", actual.c_str()); } -TEST(transactions, serialize_delegate_registration) { +/**/ + +TEST(transactions, serialize_delegate_registration) { // NOLINT // delegate_registration/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 2; - transaction.fee = 2500000000; - transaction.timestamp = 41269424; + transaction.fee = 2500000000ULL; + transaction.timestamp = 41269424UL; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7" - "e40958c7709aec0e1555087ea9ad94"; - transaction.secondSignature = - "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b34" - "5d48a9c2ae98be57dced869cf38c"; + transaction.signature = "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94"; + transaction.secondSignature = "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c"; transaction.asset.delegate.username = "boldninja"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f90295000000000009626f6c646e" - "696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27a" - "a0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302" - "200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", + "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" + "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" + "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" + "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", actual.c_str()); } -TEST(transactions, serialize_vote) { +/**/ + +TEST(transactions, serialize_vote) { // NOLINT // vote/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 3; - transaction.fee = 100000000; - transaction.timestamp = 41269366; + transaction.fee = 100000000ULL; + transaction.timestamp = 41269366UL; transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0" - "d5828ed2d7c53a5e8db08cb6d068"; - transaction.secondSignature = - "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353e" - "d7881dc29787a5e8ecbee2dfda66"; - transaction.asset.votes = {"+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d"}; + transaction.signature = "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068"; + transaction.secondSignature = "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"; + transaction.asset.votes = { "+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d" }; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); @@ -101,38 +96,35 @@ TEST(transactions, serialize_vote) { "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda" - "66", + "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", actual.c_str()); } -TEST(transactions, serialize_multi_signature_registration) { +/**/ + +TEST(transactions, serialize_multi_signature_registration) { // NOLINT // multi_signature_registration/passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 4; transaction.version = 1; transaction.network = 23; - transaction.fee = 2000000000; - transaction.timestamp = 10112114; + transaction.fee = 2000000000ULL; + transaction.timestamp = 10112114UL; transaction.senderPublicKey = "036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760"; - transaction.signature = - "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93" - "753c82a711c3558045e787bc01a5"; - transaction.secondSignature = - "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488e" - "b89b697c711f91e8c03b9620e0b1"; + transaction.signature = "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5"; + transaction.secondSignature = "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1"; transaction.signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4e" - "d1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2e" - "aaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89" - "085c328817919939f2efeabd913d"}; - - transaction.asset.multiSignature.keysgroup = {"+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31"}; + "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", + "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", + "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d" + }; + + transaction.asset.multiSignature.keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; transaction.asset.multiSignature.lifetime = 24; transaction.asset.multiSignature.min = 2; @@ -148,7 +140,6 @@ TEST(transactions, serialize_multi_signature_registration) { "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913" - "d", + "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d", actual.c_str()); } diff --git a/test/transactions/transaction.cpp b/test/transactions/transaction.cpp index 1870cdab..202bc306 100644 --- a/test/transactions/transaction.cpp +++ b/test/transactions/transaction.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "transactions/builder.h" @@ -6,196 +7,299 @@ #include #include +/**/ + +TEST(transactions, transaction_default) { + Ark::Crypto::Transactions::Transaction transaction; + ASSERT_FALSE(transaction.verify()); +}; + +/**/ + TEST(transactions, transaction_to_array) { - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 1, "", "Secret passphrase"); - std::map tArray = transfer.toArray(); - - // Amount - ASSERT_STREQ("1", tArray["amount"].c_str()); - // Fee - ASSERT_STREQ("10000000", tArray["fee"].c_str()); - // Id - ASSERT_STRNE("", tArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tArray["recipientId"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", tArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", tArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("0", tArray["type"].c_str()); - - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration("Secret passphrase", "Second Secret passphrase"); - std::map ssArray = secondSignatureRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", ssArray["amount"].c_str()); - // Asset - ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssArray["publicKey"].c_str()); - // Fee - ASSERT_STREQ("500000000", ssArray["fee"].c_str()); - // Id - ASSERT_STRNE("", ssArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("", ssArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STRNE("", ssArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", ssArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", ssArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("1", ssArray["type"].c_str()); - - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration("testName", "Secret passphrase"); - std::map dArray = delegateRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", dArray["amount"].c_str()); - // Asset - ASSERT_STREQ("testName", dArray["username"].c_str()); - // Fee - ASSERT_STREQ("2500000000", dArray["fee"].c_str()); - // Id - ASSERT_STRNE("", dArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("", dArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STREQ("", dArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", dArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", dArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("2", dArray["type"].c_str()); - - - // Type 3 - std::vector votes = { "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::map vArray = vote.toArray(); - - // Amount - ASSERT_STREQ("0", vArray["amount"].c_str()); - // Asset - ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6,+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vArray["votes"].c_str()); - // Fee - ASSERT_STREQ("100000000", vArray["fee"].c_str()); - // Id - ASSERT_STRNE("", vArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STREQ("", vArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", vArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", vArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("3", vArray["type"].c_str()); + // Type 0 + auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 1, + "", + "Secret passphrase"); + std::map tArray = transfer.toArray(); + + // Amount + ASSERT_STREQ("1", tArray["amount"].c_str()); + // Fee + ASSERT_STREQ("10000000", tArray["fee"].c_str()); + // Id + ASSERT_FALSE(tArray["id"].empty()); + // RecipientId + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tArray["recipientId"].c_str()); + // SenderPublicKey + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + tArray["senderPublicKey"].c_str()); + // Signature + ASSERT_FALSE(tArray["signature"].empty()); + // Timestamp + ASSERT_FALSE(tArray["timestamp"].empty()); + // Type + ASSERT_STREQ("0", tArray["type"].c_str()); + + // Type 1 + auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration( + "Secret passphrase", + "Second Secret passphrase"); + std::map ssArray = secondSignatureRegistration.toArray(); + + // Amount + ASSERT_STREQ("0", ssArray["amount"].c_str()); + // Asset + ASSERT_STREQ( + "02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", + ssArray["publicKey"].c_str()); + // Fee + ASSERT_STREQ("500000000", ssArray["fee"].c_str()); + // Id + ASSERT_FALSE(ssArray["id"].empty()); + // RecipientId + ASSERT_TRUE(ssArray["recipientId"].empty()); + // SecondSignature + ASSERT_FALSE(ssArray["secondSignature"].empty()); + // SenderPublicKey + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + ssArray["senderPublicKey"].c_str()); + // Signature + ASSERT_FALSE(ssArray["signature"].empty()); + // Timestamp + ASSERT_FALSE(ssArray["timestamp"].empty()); + // Type + ASSERT_STREQ("1", ssArray["type"].c_str()); + + // Type 2 + auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration( + "testName", + "Secret passphrase"); + std::map dArray = delegateRegistration.toArray(); + + // Amount + ASSERT_STREQ("0", dArray["amount"].c_str()); + // Asset + ASSERT_STREQ("testName", dArray["username"].c_str()); + // Fee + ASSERT_STREQ("2500000000", dArray["fee"].c_str()); + // Id + ASSERT_FALSE(dArray["id"].empty()); + // RecipientId + ASSERT_TRUE(dArray["recipientId"].empty()); + // SecondSignature + ASSERT_TRUE(dArray["secondSignature"].empty()); + // SenderPublicKey + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + dArray["senderPublicKey"].c_str()); + // Signature + ASSERT_FALSE(dArray["signature"].empty()); + // ASSERT_FALSE + ASSERT_FALSE(dArray["timestamp"].empty()); + // Type + ASSERT_STREQ("2", dArray["type"].c_str()); + + // Type 3 + std::vector votes = { + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" + }; + auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); + std::map vArray = vote.toArray(); + + // Amount + ASSERT_STREQ("0", vArray["amount"].c_str()); + // Asset + ASSERT_STREQ( + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vArray["votes"].c_str()); + // Fee + ASSERT_STREQ("100000000", vArray["fee"].c_str()); + // Id + ASSERT_FALSE(vArray["id"].empty()); + // RecipientId + ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vArray["recipientId"].c_str()); + // SecondSignature + ASSERT_TRUE(vArray["secondSignature"].empty()); + // SenderPublicKey + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + vArray["senderPublicKey"].c_str()); + // Signature + ASSERT_FALSE(vArray["signature"].empty()); + // Timestamp + ASSERT_FALSE(vArray["timestamp"].empty()); + // Type + ASSERT_STREQ("3", vArray["type"].c_str()); } -TEST(transactions, transaction_to_json) { +/**/ - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 1, "", "Secret passphrase"); - std::string tJson = transfer.toJson(); - - const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; - DynamicJsonDocument tDoc(tCapacity); - - DeserializationError tError = deserializeJson(tDoc, tJson); - ASSERT_FALSE(tError); - - ASSERT_EQ(tDoc["amount"], 1); - ASSERT_EQ(tDoc["fee"], 10000000); - ASSERT_STRNE("", tDoc["id"].as()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tDoc["senderPublicKey"].as()); - ASSERT_STRNE("", tDoc["signature"].as()); - ASSERT_GT(tDoc["timestamp"], 50000000); - ASSERT_LT(tDoc["timestamp"], 1000000000); - ASSERT_EQ(tDoc["type"], 0); - - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration("Secret passphrase", "Second Secret passphrase"); - std::string ssJson = secondSignatureRegistration.toJson(); - - const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; - DynamicJsonDocument ssDoc(ssCapacity); - - DeserializationError ssError = deserializeJson(ssDoc, ssJson); - ASSERT_FALSE(ssError); - - ASSERT_EQ(ssDoc["amount"], 0); - ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssDoc["asset"]["signature"]["publicKey"].as()); - ASSERT_EQ(ssDoc["fee"], 500000000); - ASSERT_STRNE("", ssDoc["id"].as()); - ASSERT_STREQ("", ssDoc["recipientId"].as()); - ASSERT_STRNE("", ssDoc["secondSignature"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssDoc["senderPublicKey"].as()); - ASSERT_STRNE("", ssDoc["signature"].as()); - ASSERT_GT(ssDoc["timestamp"], 50000000); - ASSERT_LT(ssDoc["timestamp"], 1000000000); - ASSERT_EQ(ssDoc["type"], 1); - - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration("testName", "Secret passphrase"); - std::string dJson = delegateRegistration.toJson(); - - const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; - DynamicJsonDocument dDoc(dCapacity); - - DeserializationError dError = deserializeJson(dDoc, dJson); - ASSERT_FALSE(dError); - - ASSERT_EQ(dDoc["amount"], 0); - ASSERT_STREQ("testName", dDoc["asset"]["delegate"]["username"].as()); - ASSERT_EQ(dDoc["fee"], 2500000000); - ASSERT_STRNE("", dDoc["id"].as()); - ASSERT_STREQ("", dDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dDoc["senderPublicKey"].as()); - ASSERT_STRNE("", dDoc["signature"].as()); - ASSERT_GT(dDoc["timestamp"], 50000000); - ASSERT_LT(dDoc["timestamp"], 1000000000); - ASSERT_EQ(dDoc["type"], 2); - - - // Type 3 - std::vector votes = { "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6,+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::string vJson = vote.toJson(); - - const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 700; - DynamicJsonDocument vDoc(vCapacity); - - DeserializationError vError = deserializeJson(vDoc, vJson); - ASSERT_FALSE(vError); - - ASSERT_EQ(vDoc["amount"], 0); - ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][0].as()); - ASSERT_STREQ("+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][1].as()); - ASSERT_EQ(vDoc["fee"], 100000000); - ASSERT_STRNE("", vDoc["id"].as()); - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vDoc["senderPublicKey"].as()); - ASSERT_STRNE("", vDoc["signature"].as()); - ASSERT_GT(vDoc["timestamp"], 50000000); - ASSERT_LT(vDoc["timestamp"], 1000000000); - ASSERT_EQ(vDoc["type"], 3); +TEST(transactions, transaction_to_json) { + // Type 0 + auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 1, + "", + "Secret passphrase"); + std::string tJson = transfer.toJson(); + + const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; + DynamicJsonDocument tDoc(tCapacity); + + DeserializationError tError = deserializeJson(tDoc, tJson); + ASSERT_FALSE(tError); + + ASSERT_EQ(tDoc["amount"].as(), 1ULL); + ASSERT_EQ(tDoc["fee"].as(), 10000000ULL); + ASSERT_FALSE(tDoc["id"].as().empty()); + ASSERT_STREQ( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + tDoc["recipientId"].as()); + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + tDoc["senderPublicKey"].as()); + ASSERT_FALSE(tDoc["signature"].as().empty()); + ASSERT_GT(tDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(tDoc["timestamp"].as(), 1000000000UL); + ASSERT_EQ(tDoc["type"].as(), 0); + + // Type 1 + auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration( + "Secret passphrase", + "Second Secret passphrase"); + std::string ssJson = secondSignatureRegistration.toJson(); + + const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; + DynamicJsonDocument ssDoc(ssCapacity); + + DeserializationError ssError = deserializeJson(ssDoc, ssJson); + ASSERT_FALSE(ssError); + + ASSERT_EQ(ssDoc["amount"].as(), 0ULL); + ASSERT_STREQ( + "02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", + ssDoc["asset"]["signature"]["publicKey"].as()); + ASSERT_EQ(ssDoc["fee"].as(), 500000000ULL); + ASSERT_FALSE(ssDoc["id"].as().empty()); + ASSERT_TRUE(ssDoc["recipientId"].as().empty()); + ASSERT_FALSE(ssDoc["secondSignature"].as().empty()); + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + ssDoc["senderPublicKey"].as()); + ASSERT_FALSE(ssDoc["signature"].as().empty()); + ASSERT_GT(ssDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(ssDoc["timestamp"].as(), 1000000000UL); + ASSERT_EQ(ssDoc["type"].as(), 1); + + // Type 2 + auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration( + "testName", + "Secret passphrase"); + std::string dJson = delegateRegistration.toJson(); + + const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; + DynamicJsonDocument dDoc(dCapacity); + + DeserializationError dError = deserializeJson(dDoc, dJson); + ASSERT_FALSE(dError); + + ASSERT_EQ(dDoc["amount"].as(), 0ULL); + ASSERT_STREQ("testName", dDoc["asset"]["delegate"]["username"].as()); + ASSERT_EQ(dDoc["fee"].as(), 2500000000ULL); + ASSERT_FALSE(dDoc["id"].as().empty()); + ASSERT_TRUE(dDoc["recipientId"].as().empty()); + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + dDoc["senderPublicKey"].as()); + ASSERT_FALSE(dDoc["signature"].as().empty()); + ASSERT_GT(dDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(dDoc["timestamp"].as(), 1000000000UL); + ASSERT_EQ(dDoc["type"].as(), 2); + + // Type 3 + std::vector votes = { + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" + }; + auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); + std::string vJson = vote.toJson(); + + const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 700; + DynamicJsonDocument vDoc(vCapacity); + + DeserializationError vError = deserializeJson(vDoc, vJson); + ASSERT_FALSE(vError); + + ASSERT_EQ(vDoc["amount"].as(), 0ULL); + ASSERT_STREQ( + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vDoc["asset"]["votes"][0].as()); + ASSERT_STREQ( + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vDoc["asset"]["votes"][1].as()); + ASSERT_EQ(vDoc["fee"].as(), 100000000ULL); + ASSERT_FALSE(vDoc["id"].as().empty()); + ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vDoc["recipientId"].as()); + ASSERT_STREQ( + "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + vDoc["senderPublicKey"].as()); + ASSERT_FALSE(vDoc["signature"].as().empty()); + ASSERT_GT(vDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(vDoc["timestamp"].as(), 1000000000UL); + ASSERT_EQ(vDoc["type"].as(), 3); }; + +/**/ + +TEST(transactions, transaction_empty) { + Ark::Crypto::Transactions::Transaction transaction; + bool isValid = transaction.verify(); + ASSERT_FALSE(isValid); +} + +/**/ + +TEST(transactions, transaction_asset_signature) { // NOLINT + const auto publicKeyString = "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699"; + Ark::Crypto::Transactions::TransactionAsset asset; + asset.signature.publicKey = publicKeyString; + ASSERT_STREQ(asset.signature.publicKey.c_str(), publicKeyString); +} + +/**/ + +TEST(transactions, transaction_asset_delegate) { + const auto testUsername = "testUsername"; + Ark::Crypto::Transactions::TransactionAsset asset; + asset.delegate.username = "testUsername"; + ASSERT_STREQ(asset.delegate.username.c_str(), testUsername); +} + +/**/ + +TEST(transactions, transaction_asset_multisignature) { + const auto min = 2; + const auto lifetime = 24; + std::vector keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; + + Ark::Crypto::Transactions::TransactionAsset asset; + asset.multiSignature.min = min; + asset.multiSignature.lifetime = lifetime; + asset.multiSignature.keysgroup = keysgroup; + ASSERT_EQ(asset.multiSignature.min, min); + ASSERT_EQ(asset.multiSignature.lifetime, lifetime); + ASSERT_TRUE(asset.multiSignature.keysgroup[0] == keysgroup[0]); + ASSERT_TRUE(asset.multiSignature.keysgroup[1] == keysgroup[1]); + ASSERT_TRUE(asset.multiSignature.keysgroup[2] == keysgroup[2]); +} diff --git a/test/utils/message.cpp b/test/utils/message.cpp index a538045c..45333523 100644 --- a/test/utils/message.cpp +++ b/test/utils/message.cpp @@ -6,51 +6,52 @@ #include namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts -const auto text = "Hello World"; -const auto passphrase = "this is a top secret passphrase"; -const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; -const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; -const auto expectedJsonString = "{\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\",\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\",\"message\":\"Hello World\"}"; - + //ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts + const auto text = "Hello World"; + const auto passphrase = "this is a top secret passphrase"; + const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; + const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; + const auto expectedJsonString = "{" + "\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\"," + "\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\"," + "\"message\":\"Hello World\"" + "}"; } // namespace +/**/ + TEST(utils, message_sign) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedSignature, BytesToHex(message.signature).c_str()); ASSERT_TRUE(message.verify()); } +/**/ + TEST(utils, message_to_array) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - std::map messageArray = message.toArray(); - ASSERT_STREQ(expectedPublicKey, messageArray["publickey"].c_str()); ASSERT_STREQ(expectedSignature, messageArray["signature"].c_str()); ASSERT_STREQ(text, messageArray["message"].c_str()); } +/**/ + TEST(utils, message_to_json) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedJsonString, message.toJson().c_str()); } +/**/ + TEST(utils, message_verify) { PublicKey publicKey = PublicKey::fromHex(expectedPublicKey); std::vector signature = HexToBytes(expectedSignature); - Ark::Crypto::Utils::Message message(text, publicKey, signature); - ASSERT_TRUE(message.verify()); } diff --git a/test/utils/slot.cpp b/test/utils/slot.cpp index 80a46b41..845e26e3 100644 --- a/test/utils/slot.cpp +++ b/test/utils/slot.cpp @@ -1,3 +1,4 @@ + #include "gtest/gtest.h" #include "gtest/gtest.h" @@ -6,19 +7,21 @@ TEST(utilities, slots_epoch) { const auto devnet = Ark::Crypto::Networks::Devnet; - const auto arkEpoch = 1490101200ull; + const auto arkEpoch = 1490101200ULL; ASSERT_EQ(arkEpoch, Ark::Crypto::Utils::Slot::epoch(devnet)); } +/**/ + TEST(utilities, slots_time) { const auto devnet = Ark::Crypto::Networks::Devnet; // 28 Jan 2019(in seconds) - Ark Epoch (seconds) - const auto testTime = (1548725761ull - 1490101200ull); + const auto testTime = (1548725761ULL - 1490101200ULL); const auto slotTime = Ark::Crypto::Utils::Slot::time(devnet); // test that slot-time is more recent than 'testTime', ASSERT_GT(slotTime , testTime); // also check that the 'slotTime' is not too large (e.g. from an overflow). - ASSERT_LT(slotTime, (testTime) + 315360000); // 315360000s = 10yrs + ASSERT_LT(slotTime, (testTime) + 315360000ULL); // 315360000s = 10yrs } From 899c1d0723552734efb3dd14b4c84b421c5044ac Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 31 May 2019 06:50:11 -0700 Subject: [PATCH 16/29] chore: use correct field separator in keywords.txt (#96) The Arduino IDE requires the use of a single true tab separator between the keyword name and identifier. When spaces are used rather than a true tab, the keyword is not highlighted. Reference: https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#keywords --- keywords.txt | 60 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/keywords.txt b/keywords.txt index 98cd5e48..ea73155b 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,33 +6,33 @@ # Datatypes (KEYWORD1) ####################################### -Ark KEYWORD1 -Crypto KEYWORD1 -Configuration KEYWORD1 -Enums KEYWORD1 -Identities KEYWORD1 -Networks KEYWORD1 -Transactions KEYWORD1 -Utils KEYWORD1 - -Fee KEYWORD1 -Network KEYWORD1 - -Fees KEYWORD1 -Types KEYWORD1 - -Address KEYWORD1 -PrivateKey KEYWORD1 -PublicKey KEYWORD1 -WIF KEYWORD1 - -Builder KEYWORD1 -Deserializer KEYWORD1 -Serializer KEYWORD1 -Transaction KEYWORD1 - -Message KEYWORD1 -Slot KEYWORD1 +Ark KEYWORD1 +Crypto KEYWORD1 +Configuration KEYWORD1 +Enums KEYWORD1 +Identities KEYWORD1 +Networks KEYWORD1 +Transactions KEYWORD1 +Utils KEYWORD1 + +Fee KEYWORD1 +Network KEYWORD1 + +Fees KEYWORD1 +Types KEYWORD1 + +Address KEYWORD1 +PrivateKey KEYWORD1 +PublicKey KEYWORD1 +WIF KEYWORD1 + +Builder KEYWORD1 +Deserializer KEYWORD1 +Serializer KEYWORD1 +Transaction KEYWORD1 + +Message KEYWORD1 +Slot KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) @@ -42,6 +42,6 @@ Slot KEYWORD1 # Constants (LITERAL1) ####################################### -Devnet LITERAL1 -Mainnet LITERAL1 -Testnet LITERAL1 +Devnet LITERAL1 +Mainnet LITERAL1 +Testnet LITERAL1 From d9322d20e7ecdf782ff78f4d8cbee223e818337e Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 20 Jun 2019 20:21:17 -0700 Subject: [PATCH 17/29] build(platformio): Improve PlatformIO Configuration (#101) --- .circleci/config.yml | 5 +++++ .circleci/platformio.cpp | 21 +++++++++++++++++++++ CHANGELOG.md | 1 + platformio.ini | 7 +++---- test/platformio.ini | 10 ++++------ 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 .circleci/platformio.cpp diff --git a/.circleci/config.yml b/.circleci/config.yml index f0429e33..b5836792 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -23,6 +23,11 @@ jobs: - run: name: Install command: ./.circleci/install_platform_io.sh + - run: + name: Empty Git Submodule Folders + command: | + rm -rf ./src/lib/{ArduinoJson/*,BIP66/*,uECC/*} + rm -rf ./test/lib/googletest/* - run: name: Build command: ./.circleci/script_platform_io.sh diff --git a/.circleci/platformio.cpp b/.circleci/platformio.cpp new file mode 100644 index 00000000..5b9fd3a5 --- /dev/null +++ b/.circleci/platformio.cpp @@ -0,0 +1,21 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +// This is a dummy prototype 'setup' & 'loop' for CI testing. +// This isn't intended for project or production use. +// It is only used in the 'pio run' command from root in CI; +// successful completion of which asserts that the ARK Cpp-Crypto library builds on its own. +#if (defined PLATFORMIO && !defined UNIT_TEST) + +#include + +void setup() {} +void loop() {} + +#endif diff --git a/CHANGELOG.md b/CHANGELOG.md index f3f55e87..39d707dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Changed +- improved PlatformIO configuration ([#101]) - improved formatting and maintainability ([#98]) - improved Slots implementations ([#92]) diff --git a/platformio.ini b/platformio.ini index 82761003..487f4469 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,19 +10,19 @@ [platformio] description = "A simple Cryptography Implementation in C++ for the ARK Blockchain." +build_dir = .pio/.pioenvs +libdeps_dir = .pio/.piolibdeps [common] -lib_ldf_mode = off lib_deps = micro-ecc, ArduinoJson@6.10.0, BIP66 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - - - - - - +src_filter = +<*> +<../.circleci/platformio.cpp> upload_speed = 921600 [env:esp8266] platform = espressif8266 board = huzzah framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} @@ -32,7 +32,6 @@ upload_speed = ${common.upload_speed} platform = espressif32 board = esp32dev framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} diff --git a/test/platformio.ini b/test/platformio.ini index bbdd161c..a8bfa36d 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -11,13 +11,13 @@ [platformio] description = "Unit Tests for Ark-Cpp-Crypto" src_dir = .. -lib_dir = .. +build_dir = .pio/.pioenvs +libdeps_dir = .pio/.piolibdeps [common] -lib_ldf_mode = off lib_deps = micro-ecc, AUnit, ArduinoJson@6.10.0, BIP66 -build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - - +build_flags = -I../test -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST +src_filter = + + - upload_speed = 921600 # esp8266 unit tests disabled until support is worked out @@ -25,7 +25,6 @@ upload_speed = 921600 #platform = espressif8266 #board = huzzah #framework = arduino -#lib_ldf_mode = ${common.lib_ldf_mode} #lib_deps = ${common.lib_deps} #build_flags = ${common.build_flags} #src_filter = ${common.src_filter} @@ -35,7 +34,6 @@ upload_speed = 921600 platform = espressif32 board = esp32dev framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} From 81647dac1a63779b84219085df99055298508ba8 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 20 Jun 2019 20:48:05 -0700 Subject: [PATCH 18/29] test(networks): Fix AbstractNetwork Tests (#102) Current tests are ran in different orders per platform. This led to a modified global test custom_network being modified improperly. This PR properly handles that order variation by creating a local object to be modified. In future iterations, an AbstractNetwork will allow `const`. --- test/networks/abstractnetwork.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/test/networks/abstractnetwork.cpp b/test/networks/abstractnetwork.cpp index e6dfc0b5..bb2962c6 100644 --- a/test/networks/abstractnetwork.cpp +++ b/test/networks/abstractnetwork.cpp @@ -59,14 +59,16 @@ TEST(networks, abstract_network_base58_prefix_get) { /**/ TEST(networks, abstract_network_base58_prefix_set) { - CUSTOM_NETWORK.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x10); - ASSERT_EQ(0x10, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); + AbstractNetwork testNetwork = CUSTOM_NETWORK; - CUSTOM_NETWORK.setBase58Prefix(BASE58_ADDRESS_P2SH, 0x20); - ASSERT_EQ(0x20, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH)); + testNetwork.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x10); + ASSERT_EQ(0x10, testNetwork.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - CUSTOM_NETWORK.setBase58Prefix(BASE58_WIF, 0x30); - ASSERT_EQ(0x30, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); + testNetwork.setBase58Prefix(BASE58_ADDRESS_P2SH, 0x20); + ASSERT_EQ(0x20, testNetwork.getBase58Prefix(BASE58_ADDRESS_P2SH)); + + testNetwork.setBase58Prefix(BASE58_WIF, 0x30); + ASSERT_EQ(0x30, testNetwork.getBase58Prefix(BASE58_WIF)); } /**/ @@ -79,11 +81,13 @@ TEST(networks, abstract_network_bip32_prefix_get) { /**/ TEST(networks, abstract_network_bip32_prefix_set) { - CUSTOM_NETWORK.setBIP32Prefix(BIP32_PREFIX_XPUB, 1000000); - ASSERT_EQ(1000000, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); + AbstractNetwork testNetwork = CUSTOM_NETWORK; + + testNetwork.setBIP32Prefix(BIP32_PREFIX_XPUB, 1000000); + ASSERT_EQ(1000000, testNetwork.getBIP32Prefix(BIP32_PREFIX_XPUB)); - CUSTOM_NETWORK.setBIP32Prefix(BIP32_PREFIX_XPRV, 1000001); - ASSERT_EQ(1000001, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); + testNetwork.setBIP32Prefix(BIP32_PREFIX_XPRV, 1000001); + ASSERT_EQ(1000001, testNetwork.getBIP32Prefix(BIP32_PREFIX_XPRV)); } /**/ From ed0ab5780dbd5e66ab7a6f89b6695c65f416823f Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 21 Jun 2019 02:19:50 -0700 Subject: [PATCH 19/29] fix(transaction): Improve Numeric Json Serialization (#103) Current implementation sometimes fails to properly serialize numbers in the `toJson()` method. This is especially detrimental to some Linux builds and all Arduino IDE builds (Arduino IDE Library version (Cpp-Crypto-Arduino-v.0.3.0)). Specifically, this PR does the following: - moves `` to `crypto_helpers.h` for non-IoT builds. - forces type serialization for: - `amount` (llu/uint64_t). - `fee` (llu/uint64_t). - `network` (uint8_t/int). - `timestamp` (lu/uint32_t). - `type` (uint8_t/int). - `version` (uint8_t/int). - updates the changelog. --- CHANGELOG.md | 4 ++++ src/helpers/crypto_helpers.h | 7 +++++++ src/transactions/transaction.cpp | 18 ++++++++---------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39d707dd..1a3e37cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - improved formatting and maintainability ([#98]) - improved Slots implementations ([#92]) +### Fixed + +- fixed Transaction Json numeric serialization ([#103]) + ## [0.5.0] - 2019-02-20 ### Changed diff --git a/src/helpers/crypto_helpers.h b/src/helpers/crypto_helpers.h index 15e95ce1..2982f712 100644 --- a/src/helpers/crypto_helpers.h +++ b/src/helpers/crypto_helpers.h @@ -29,6 +29,13 @@ const auto WIF_SIZE = 52U; #endif +#ifndef USE_IOT + +#define __STDC_FORMAT_MACROS 1 +#include + +#endif + // Write data into dst template inline void pack(std::vector& dst, T& data) { diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index 1345f9a2..49f1af16 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -12,13 +12,11 @@ #include "bcl/Sha256.hpp" +#include #include #include #include -#define __STDC_FORMAT_MACROS 1 -#include - using namespace Ark::Crypto::Identities; std::string Ark::Crypto::Transactions::Transaction::getId() const { @@ -326,7 +324,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { DynamicJsonDocument doc(docCapacity); // Amount - doc["amount"] = txArray["amount"]; + doc["amount"] = strtoull(txArray["amount"].c_str(), nullptr, 10); // Asset if (this->type == 0) { @@ -342,7 +340,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { JsonObject dAsset = doc.createNestedObject("asset"); JsonObject delegate = dAsset.createNestedObject("delegate"); delegate["username"] = txArray["username"]; - }else if (this->type == 3) { + } else if (this->type == 3) { // Vote JsonObject vAsset = doc.createNestedObject("asset"); JsonArray votes = vAsset.createNestedArray("votes"); @@ -368,14 +366,14 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { }; // Fee - doc["fee"] = txArray["fee"]; + doc["fee"] = strtoull(txArray["fee"].c_str(), nullptr, 10); // Id doc["id"] = txArray["id"]; // Network if (txArray["network"] != "0") { - doc["network"] = txArray["network"]; + doc["network"] = atoi(txArray["network"].c_str()); }; // RecipientId @@ -410,10 +408,10 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { }; // Timestamp - doc["timestamp"] = txArray["timestamp"]; + doc["timestamp"] = strtoul(txArray["timestamp"].c_str(), nullptr, 10); // Type - doc["type"] = txArray["type"]; + doc["type"] = atoi(txArray["type"].c_str()); // VendorField if (std::strlen(txArray["vendorField"].c_str()) > 0) { @@ -422,7 +420,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // Version if (txArray["version"] != "0") { - doc["version"] = txArray["version"]; + doc["version"] = atoi(txArray["version"].c_str()); }; char jsonChar[docCapacity]; From 6feae41f2eeddeb9227509cf1dbf8398c9c9ecb4 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 07:44:00 -0700 Subject: [PATCH 20/29] refactor(configuration): support bridgechain configurations The current implementation only allows use with Devnet unless values are manually changed in `/src`. This PR enables network configuration via the public api. (Devnet, Mainnet, Testnet, and Custom Networks (bridgechains). Specifically this PR does the following: - Creates a Configuration class. - Creates Fee and Network Manager children for the Configuration class. - Allows passing a `Configuration to` Transaction Builder with a default value of `Devnet` & `StaticFees` (non-breaking). - Adds a FeePolicy-type. - Adds a Fee class (container for fee policies). - Adds a Networks class (container for preset networks). - Updates the TransactionTypes enum. - Improves the `Network` class and Network implementions. - Updates the `Slot` class to reflect changes (non-breaking). - Updates Transaction-related classes to reflect updates (non-breaking). - Adds tests for all changes. - Updates the Arduino IDE script. - Updates `.ino` Arduino sketches with Configuration examples. - Updates documentation with Configuration examples. - Updates the `keywords.txt` file to reflect changes. - Updates the changelog. - Updates version to `v.0.6.0`. Some small changes are technically breaking-changes. (e.g. `Devnet` vs `Devnet()`, and `Fees` vs `Fees::StaticFeePolicy`) --- CHANGELOG.md | 4 + docs/cpp.md | 73 ++++++++++ examples/arduino/ESP32/ESP32.ino | 33 ++++- examples/arduino/ESP8266/ESP8266.ino | 32 ++++- extras/ARDUINO_IDE.sh | 75 +++++----- keywords.txt | 18 ++- library.json | 2 +- library.properties | 2 +- src/CMakeLists.txt | 11 +- src/common/configuration.cpp | 27 ++++ src/common/network.cpp | 49 +++++++ src/configuration/fee.cpp | 17 --- src/configuration/network.cpp | 15 -- src/defaults/static_fees.cpp | 37 +++++ src/include/cpp-crypto/arkCrypto.h | 27 ++-- .../cpp-crypto/common/configuration.hpp | 45 ++++++ src/include/cpp-crypto/common/fee_policy.hpp | 24 ++++ src/include/cpp-crypto/common/network.hpp | 56 ++++++++ src/include/cpp-crypto/configuration/fee.h | 48 ------- .../cpp-crypto/configuration/network.h | 37 ----- .../cpp-crypto/defaults/fee_policies.hpp | 30 ++++ .../cpp-crypto/defaults/static_fees.hpp | 29 ++++ .../cpp-crypto/defaults/transaction_types.hpp | 35 +++++ src/include/cpp-crypto/enums/fees.h | 35 ----- src/include/cpp-crypto/enums/types.h | 33 ----- .../cpp-crypto/networks/abstractnetwork.h | 101 ------------- src/include/cpp-crypto/networks/devnet.h | 36 ----- src/include/cpp-crypto/networks/devnet.hpp | 23 +++ src/include/cpp-crypto/networks/mainnet.h | 36 ----- src/include/cpp-crypto/networks/mainnet.hpp | 23 +++ src/include/cpp-crypto/networks/networks.hpp | 28 ++++ src/include/cpp-crypto/networks/testnet.h | 36 ----- src/include/cpp-crypto/networks/testnet.hpp | 23 +++ src/include/cpp-crypto/transactions/builder.h | 23 +-- src/managers/fee_manager.cpp | 67 +++++++++ src/managers/fee_manager.hpp | 46 ++++++ src/managers/network_manager.cpp | 42 ++++++ src/managers/network_manager.hpp | 43 ++++++ src/networks/abstractnetwork.cpp | 67 --------- src/networks/devnet.cpp | 28 ++++ src/networks/mainnet.cpp | 28 ++++ src/networks/testnet.cpp | 28 ++++ src/transactions/builder.cpp | 63 ++++---- src/transactions/deserializer.cpp | 51 ++++--- src/transactions/serializer.cpp | 33 +++-- src/transactions/transaction.cpp | 25 ++-- src/utils/slot.cpp | 14 +- src/utils/slot.h | 8 +- test/CMakeLists.txt | 12 +- test/common/configuration.cpp | 134 ++++++++++++++++++ test/common/fee_policy.cpp | 20 +++ test/common/network.cpp | 67 +++++++++ test/configuration/fee.cpp | 41 ------ test/configuration/network.cpp | 31 ---- test/defaults/static_fees.cpp | 40 ++++++ test/defaults/transaction_types.cpp | 30 ++++ test/enums/fees.cpp | 33 ----- test/enums/types.cpp | 16 --- test/managers/fee_manager.cpp | 100 +++++++++++++ test/managers/network_manager.cpp | 67 +++++++++ test/networks/abstractnetwork.cpp | 112 --------------- test/networks/devnet.cpp | 49 +++---- test/networks/mainnet.cpp | 49 +++---- test/networks/testnet.cpp | 49 +++---- test/transactions/builder.cpp | 54 +++++-- test/transactions/deserializer.cpp | 15 +- test/transactions/serializer.cpp | 2 +- test/utils/slot.cpp | 13 +- 68 files changed, 1599 insertions(+), 1001 deletions(-) create mode 100644 src/common/configuration.cpp create mode 100644 src/common/network.cpp delete mode 100644 src/configuration/fee.cpp delete mode 100644 src/configuration/network.cpp create mode 100644 src/defaults/static_fees.cpp create mode 100644 src/include/cpp-crypto/common/configuration.hpp create mode 100644 src/include/cpp-crypto/common/fee_policy.hpp create mode 100644 src/include/cpp-crypto/common/network.hpp delete mode 100644 src/include/cpp-crypto/configuration/fee.h delete mode 100644 src/include/cpp-crypto/configuration/network.h create mode 100644 src/include/cpp-crypto/defaults/fee_policies.hpp create mode 100644 src/include/cpp-crypto/defaults/static_fees.hpp create mode 100644 src/include/cpp-crypto/defaults/transaction_types.hpp delete mode 100644 src/include/cpp-crypto/enums/fees.h delete mode 100644 src/include/cpp-crypto/enums/types.h delete mode 100644 src/include/cpp-crypto/networks/abstractnetwork.h delete mode 100644 src/include/cpp-crypto/networks/devnet.h create mode 100644 src/include/cpp-crypto/networks/devnet.hpp delete mode 100644 src/include/cpp-crypto/networks/mainnet.h create mode 100644 src/include/cpp-crypto/networks/mainnet.hpp create mode 100644 src/include/cpp-crypto/networks/networks.hpp delete mode 100644 src/include/cpp-crypto/networks/testnet.h create mode 100644 src/include/cpp-crypto/networks/testnet.hpp create mode 100644 src/managers/fee_manager.cpp create mode 100644 src/managers/fee_manager.hpp create mode 100644 src/managers/network_manager.cpp create mode 100644 src/managers/network_manager.hpp delete mode 100644 src/networks/abstractnetwork.cpp create mode 100644 src/networks/devnet.cpp create mode 100644 src/networks/mainnet.cpp create mode 100644 src/networks/testnet.cpp create mode 100644 test/common/configuration.cpp create mode 100644 test/common/fee_policy.cpp create mode 100644 test/common/network.cpp delete mode 100644 test/configuration/fee.cpp delete mode 100644 test/configuration/network.cpp create mode 100644 test/defaults/static_fees.cpp create mode 100644 test/defaults/transaction_types.cpp delete mode 100644 test/enums/fees.cpp delete mode 100644 test/enums/types.cpp create mode 100644 test/managers/fee_manager.cpp create mode 100644 test/managers/network_manager.cpp delete mode 100644 test/networks/abstractnetwork.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a3e37cb..0d5db682 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased +### Added + +- added Bridgechain support ([#105]) + ### Changed - improved PlatformIO configuration ([#101]) diff --git a/docs/cpp.md b/docs/cpp.md index 14ebd569..724c6eec 100644 --- a/docs/cpp.md +++ b/docs/cpp.md @@ -16,6 +16,79 @@ This project is still under development. This page will get more content as the * [macOS >= 10.10](#OS) * [Windows >= 7](#OS) +### ARK Transactions + +#### Devnet + +```cpp +const auto DevnetTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a devnet transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too"); +``` + +#### Mainnet + +```cpp +const Configuration MainnetConfiguration(Networks::Mainnet()); + +const auto MainnetTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a mainnet transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MainnetConfiguration); +``` + +#### BridgeChain Transaction + +```cpp +static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; + +const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + +const auto MyBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); +``` + + +#### With custom Fees + +```cpp +static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; + +const FeePolicy MyCustomFees = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; + +ßconst Configuration MyBridgechainConfiguration(MyBridgechainNetwork, + MyCustomFees); + +const auto MyBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "", + "this is a top secret passphrase", + "", + MyBridgechainConfiguration); +``` ### Sign diff --git a/examples/arduino/ESP32/ESP32.ino b/examples/arduino/ESP32/ESP32.ino index 2c82de74..8b514ab7 100644 --- a/examples/arduino/ESP32/ESP32.ino +++ b/examples/arduino/ESP32/ESP32.ino @@ -31,13 +31,40 @@ /****************************************/ void checkCrypto() { + + /** + * Create a BridgeChain transaction, tailored for your custom network. + */ + static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + + auto myBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); + + Serial.print("\nBridgechain Transaction: "); + Serial.println(myBridgechainTransaction.toJson().c_str()); + + /**/ + + /********************/ + /** * This is how you can check the default 'Network' "Transaction 'Fees' by type. * In this example, it should return a 'uint64_t' integer of '10000000' as the default 'Fee' for a 'Transaction' of 'Type' '0'. */ - Ark::Crypto::Configuration::Fee fee; - unsigned long typeZeroTransactionFee = fee.get(0); - Serial.print("\n Type 0 default Transaction Fee: "); + Configuration config; + unsigned long typeZeroTransactionFee = config.getFee(0); + Serial.print("\nType 0 default Transaction Fee: "); Serial.println(typeZeroTransactionFee); // The response is a 'uint64_t' integer. /**/ diff --git a/examples/arduino/ESP8266/ESP8266.ino b/examples/arduino/ESP8266/ESP8266.ino index 876a2aaf..5cd91181 100644 --- a/examples/arduino/ESP8266/ESP8266.ino +++ b/examples/arduino/ESP8266/ESP8266.ino @@ -31,13 +31,39 @@ /****************************************/ void checkCrypto() { + /** + * Create a BridgeChain transaction, tailored for your custom network. + */ + static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + + auto myBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); + + Serial.print("\nBridgechain Transaction: "); + Serial.println(myBridgechainTransaction.toJson().c_str()); + + /**/ + + /********************/ + /** * This is how you can check the default 'Network' "Transaction 'Fees' by type. * In this example, it should return a 'uint64_t' integer of '10000000' as the default 'Fee' for a 'Transaction' of 'Type' '0'. */ - Ark::Crypto::Configuration::Fee fee; - unsigned long typeZeroTransactionFee = fee.get(0); - Serial.print("\n Type 0 default Transaction Fee: "); + Configuration config; + unsigned long typeZeroTransactionFee = config.getFee(0); + Serial.print("\nType 0 default Transaction Fee: "); Serial.println(typeZeroTransactionFee); // The response is a 'uint64_t' integer. /**/ diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index dce38a15..1fdc3a8a 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -38,22 +38,20 @@ EXTRAS_BACKUP_DIR=${EXTRAS_DIR}/BACKUP SRC_LIB_DIR=${SRC_DIR}/lib EXTRAS_LIB_DIR=${EXTRAS_BACKUP_DIR}/lib -EXTRAS_IDENTITIES_DIR=${EXTRAS_BACKUP_DIR}/identities +SRC_COMMON_DIR=${SRC_DIR}/common +INCLUDE_COMMON_DIR=${INCLUDE_CRYPTO_DIR}/common -INCLUDE_CONFIGURATION_DIR=${INCLUDE_CRYPTO_DIR}/configuration -SRC_CONFIGURATION_DIR=${SRC_DIR}/configuration +SRC_DEFAULTS_DIR=${SRC_DIR}/defaults +INCLUDE_DEFAULTS_DIR=${INCLUDE_CRYPTO_DIR}/defaults -INCLUDE_ENUMS_DIR=${INCLUDE_CRYPTO_DIR}/enums -SRC_ENUMS_DIR=${SRC_DIR}/enums - -INCLUDE_HELPERS_DIR=${INCLUDE_CRYPTO_DIR}/helpers SRC_HELPERS_DIR=${SRC_DIR}/helpers +INCLUDE_HELPERS_DIR=${INCLUDE_CRYPTO_DIR}/helpers -INCLUDE_ENCODING_DIR=${INCLUDE_HELPERS_DIR}/encoding SRC_ENCODING_DIR=${SRC_HELPERS_DIR}/encoding +INCLUDE_ENCODING_DIR=${INCLUDE_HELPERS_DIR}/encoding -INCLUDE_IDENTITIES_DIR=${INCLUDE_CRYPTO_DIR}/identities SRC_IDENTITIES_DIR=${SRC_DIR}/identities +INCLUDE_IDENTITIES_DIR=${INCLUDE_CRYPTO_DIR}/identities INCLUDE_NETWORKS_DIR=${INCLUDE_CRYPTO_DIR}/networks SRC_NETWORKS_DIR=${SRC_DIR}/networks @@ -100,16 +98,15 @@ if [[ -d ${INCLUDE_DIR} ]]; then echo -e "Moving 'arkCrypto.h' to 'src' directory.\n" mv ${INCLUDE_CRYPTO_DIR}/arkCrypto.h ${SRC_DIR} - echo -e "Moving 'configuration' headers.\n" - mv ${INCLUDE_CONFIGURATION_DIR}/fee.h ${SRC_CONFIGURATION_DIR} - mv ${INCLUDE_CONFIGURATION_DIR}/network.h ${SRC_CONFIGURATION_DIR} - - echo "Creating 'enums' folder 🗂" - mkdir ${SRC_ENUMS_DIR} + echo -e "Moving 'common' headers.\n" + mv ${INCLUDE_COMMON_DIR}/configuration.hpp ${SRC_COMMON_DIR} + mv ${INCLUDE_COMMON_DIR}/fee_policy.hpp ${SRC_COMMON_DIR} + mv ${INCLUDE_COMMON_DIR}/network.hpp ${SRC_COMMON_DIR} - echo -e "Moving 'enums' headers.\n" - mv ${INCLUDE_ENUMS_DIR}/fees.h ${SRC_ENUMS_DIR} - mv ${INCLUDE_ENUMS_DIR}/types.h ${SRC_ENUMS_DIR} + echo -e "Moving 'defaults' headers.\n" + mv ${INCLUDE_DEFAULTS_DIR}/fee_policies.hpp ${SRC_DEFAULTS_DIR} + mv ${INCLUDE_DEFAULTS_DIR}/static_fees.hpp ${SRC_DEFAULTS_DIR} + mv ${INCLUDE_DEFAULTS_DIR}/transaction_types.hpp ${SRC_DEFAULTS_DIR} echo -e "Moving 'helpers' headers.\n" mkdir ${SRC_ENCODING_DIR} @@ -122,10 +119,10 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_IDENTITIES_DIR}/wif.h ${SRC_IDENTITIES_DIR} echo -e "Moving 'networks' headers.\n" - mv ${INCLUDE_NETWORKS_DIR}/abstractnetwork.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/devnet.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/mainnet.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/testnet.h ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/networks.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/devnet.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/mainnet.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/testnet.hpp ${SRC_NETWORKS_DIR} echo -e "Moving 'transactions' headers.\n" mv ${INCLUDE_TRANSACTIONS_DIR}/builder.h ${SRC_TRANSACTIONS_DIR} @@ -133,13 +130,14 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_TRANSACTIONS_DIR}/serializer.h ${SRC_TRANSACTIONS_DIR} mv ${INCLUDE_TRANSACTIONS_DIR}/transaction.h ${SRC_TRANSACTIONS_DIR} - echo -e "Backing up, moving, and removing relevant modules from the 'lib' directory.\n" + echo -e "Backing up, moving, and removing dependencies from the 'src/lib' directory.\n" + mkdir ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/ArduinoJson ${EXTRAS_BACKUP_DIR} + mv ${SRC_LIB_DIR}/BIP66 ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/uECC ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/bcl ${SRC_DIR} mv ${SRC_LIB_DIR}/date ${SRC_DIR} mv ${SRC_LIB_DIR}/rfc6979 ${SRC_DIR} - mv ${SRC_LIB_DIR}/stl ${SRC_DIR} echo -e "Moving Docs to the './extras' directory.\n" mv ${PROJECT_ROOT}/docs ${EXTRAS_DIR} @@ -161,8 +159,8 @@ else echo -e "Creating the 'include' directory tree 🗂\n" mkdir ${INCLUDE_DIR} mkdir ${INCLUDE_CRYPTO_DIR} - mkdir ${INCLUDE_CONFIGURATION_DIR} - mkdir ${INCLUDE_ENUMS_DIR} + mkdir ${INCLUDE_COMMON_DIR} + mkdir ${INCLUDE_DEFAULTS_DIR} mkdir ${INCLUDE_HELPERS_DIR} mkdir ${INCLUDE_ENCODING_DIR} mkdir ${INCLUDE_IDENTITIES_DIR} @@ -172,13 +170,15 @@ else echo -e "Moving 'arkCrypto.h' back to the 'include/cpp-crypto/' directory.\n" mv ${SRC_DIR}/arkCrypto.h ${INCLUDE_CRYPTO_DIR} - echo -e "Moving 'configuration' headers.\n" - mv ${SRC_CONFIGURATION_DIR}/fee.h ${INCLUDE_CONFIGURATION_DIR} - mv ${SRC_CONFIGURATION_DIR}/network.h ${INCLUDE_CONFIGURATION_DIR} + echo -e "Moving 'common' headers.\n" + mv ${SRC_COMMON_DIR}/configuration.hpp ${INCLUDE_COMMON_DIR} + mv ${SRC_COMMON_DIR}/fee_policy.hpp ${INCLUDE_COMMON_DIR} + mv ${SRC_COMMON_DIR}/network.hpp ${INCLUDE_COMMON_DIR} - echo -e "Moving 'enums' headers.\n" - mv ${SRC_ENUMS_DIR}/fees.h ${INCLUDE_ENUMS_DIR} - mv ${SRC_ENUMS_DIR}/types.h ${INCLUDE_ENUMS_DIR} + echo -e "Moving 'defaults' headers.\n" + mv ${SRC_DEFAULTS_DIR}/fee_policies.hpp ${INCLUDE_DEFAULTS_DIR} + mv ${SRC_DEFAULTS_DIR}/static_fees.hpp ${INCLUDE_DEFAULTS_DIR} + mv ${SRC_DEFAULTS_DIR}/transaction_types.hpp ${INCLUDE_DEFAULTS_DIR} echo -e "Moving 'helpers/encoding' headers.\n" mv ${SRC_ENCODING_DIR}/hex.h ${INCLUDE_ENCODING_DIR} @@ -191,10 +191,10 @@ else mv ${SRC_IDENTITIES_DIR}/wif.h ${INCLUDE_IDENTITIES_DIR} echo -e "Moving 'networks' headers.\n" - mv ${SRC_NETWORKS_DIR}/abstractnetwork.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/devnet.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/mainnet.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/testnet.h ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/networks.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/devnet.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/mainnet.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/testnet.hpp ${INCLUDE_NETWORKS_DIR} echo -e "Moving 'transactions' headers.\n" mv ${SRC_TRANSACTIONS_DIR}/builder.h ${INCLUDE_TRANSACTIONS_DIR} @@ -205,17 +205,16 @@ else echo -e "Restoring the 'lib' directory.\n" mkdir ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/ArduinoJson ${SRC_LIB_DIR} + mv ${EXTRAS_BACKUP_DIR}/BIP66 ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/uECC ${SRC_LIB_DIR} mv ${SRC_DIR}/bcl ${SRC_LIB_DIR} mv ${SRC_DIR}/date ${SRC_LIB_DIR} mv ${SRC_DIR}/rfc6979 ${SRC_LIB_DIR} - mv ${SRC_DIR}/stl ${SRC_LIB_DIR} echo -e "Moving Docs back to the project root directory.\n" mv ${EXTRAS_DIR}/docs ${PROJECT_ROOT} echo -e "Removing old directories 🗑\n" - rm -rf ${SRC_ENUMS_DIR} rm -rf ${EXTRAS_BACKUP_DIR} echo -e "****************************************\n" diff --git a/keywords.txt b/keywords.txt index ea73155b..5ef6954f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -8,24 +8,24 @@ Ark KEYWORD1 Crypto KEYWORD1 -Configuration KEYWORD1 -Enums KEYWORD1 +common KEYWORD1 +defaults KEYWORD1 Identities KEYWORD1 -Networks KEYWORD1 +managers KEYWORD1 Transactions KEYWORD1 Utils KEYWORD1 -Fee KEYWORD1 +Configuration KEYWORD1 +FeePolicy KEYWORD1 Network KEYWORD1 -Fees KEYWORD1 -Types KEYWORD1 - Address KEYWORD1 PrivateKey KEYWORD1 PublicKey KEYWORD1 WIF KEYWORD1 +Networks KEYWORD1 + Builder KEYWORD1 Deserializer KEYWORD1 Serializer KEYWORD1 @@ -42,6 +42,10 @@ Slot KEYWORD1 # Constants (LITERAL1) ####################################### +Fees KEYWORD1 +StaticFeePolicy KEYWORD1 +TransactionTypes KEYWORD1 + Devnet LITERAL1 Mainnet LITERAL1 Testnet LITERAL1 diff --git a/library.json b/library.json index c02cabc3..1b742dc5 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Crypto.git" }, - "version": "0.5.0", + "version": "0.6.0", "authors": [ { "name": "Ark Ecosystem", diff --git a/library.properties b/library.properties index 7821733c..83dd41dc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Crypto -version=0.5.0 +version=0.6.0 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple Cryptography Implementation in C++ for the ARK Blockchain. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 019aa765..4ce31358 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,14 +25,19 @@ set(uECC_SRC ) set(COMMON_SRC - configuration/fee.cpp - configuration/network.cpp + common/configuration.cpp + common/network.cpp + defaults/static_fees.cpp helpers/crypto.cpp identities/address.cpp identities/privatekey.cpp identities/publickey.cpp identities/wif.cpp - networks/abstractnetwork.cpp + managers/fee_manager.cpp + managers/network_manager.cpp + networks/devnet.cpp + networks/mainnet.cpp + networks/testnet.cpp transactions/builder.cpp transactions/deserializer.cpp transactions/serializer.cpp diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp new file mode 100644 index 00000000..fcd79095 --- /dev/null +++ b/src/common/configuration.cpp @@ -0,0 +1,27 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "common/configuration.hpp" + +namespace Ark { +namespace Crypto { + +bool Configuration::operator==(const Configuration& rhs) const { + return this->getNetwork() == rhs.getNetwork() + && this->getPolicy() == rhs.getPolicy(); +} + +/**/ + +bool Configuration::operator!=(const Configuration& rhs) const { + return this->getNetwork() != rhs.getNetwork() + || this->getPolicy() != rhs.getPolicy();} + +} // namespace Crypto +} // namespace Ark diff --git a/src/common/network.cpp b/src/common/network.cpp new file mode 100644 index 00000000..53664322 --- /dev/null +++ b/src/common/network.cpp @@ -0,0 +1,49 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "common/network.hpp" +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { + +Network::Network() { *this = Networks::Devnet(); } + +/**/ + +std::string Network::nethash() const { return this->nethash_; } +uint8_t Network::slip44() const { return this->slip44_; } +uint8_t Network::wif() const { return this->wif_; } +uint8_t Network::version() const { return this->version_; } +std::string Network::epoch() const { return this->epoch_; } + +/**/ + +bool Network::operator==(const Network& rhs) const { + bool numericsMatch = (this->slip44_ == rhs.slip44_) + && (this->wif_ == rhs.wif_) + && (this->version_ == rhs.version_); + bool stringsMatch = (this->nethash_ == rhs.nethash_) + && (this->epoch_ == rhs.epoch_); + return numericsMatch && stringsMatch; +} + +/**/ + +bool Network::operator!=(const Network& rhs) const { + bool numericsMatch = (this->slip44_ != rhs.slip44_) + || (this->wif_ != rhs.wif_) + || (this->version_ != rhs.version_); + bool stringsMatch = (this->nethash_ != rhs.nethash_) + || (this->epoch_ != rhs.epoch_); + return numericsMatch || stringsMatch; +} + +} // namespace Crypto +} // namespace Ark diff --git a/src/configuration/fee.cpp b/src/configuration/fee.cpp deleted file mode 100644 index 7863f80d..00000000 --- a/src/configuration/fee.cpp +++ /dev/null @@ -1,17 +0,0 @@ - -#include "configuration/fee.h" - -#include - -uint64_t Ark::Crypto::Configuration::Fee::get( - int type) { - return this->fees_[type]; -}; - -/**/ - -void Ark::Crypto::Configuration::Fee::set( - int type, - uint64_t fee) { - this->fees_[type] = fee; -}; diff --git a/src/configuration/network.cpp b/src/configuration/network.cpp deleted file mode 100644 index d9d61142..00000000 --- a/src/configuration/network.cpp +++ /dev/null @@ -1,15 +0,0 @@ - -#include "configuration/network.h" - -Ark::Crypto::Networks::AbstractNetwork Ark::Crypto::Configuration::Network::get() { - return (this->network_.getBase58Prefix(BASE58_ADDRESS_P2PKH) == 0x00) - ? (Devnet) - : (this->network_); -} - -/**/ - -void Ark::Crypto::Configuration::Network::set( - const Ark::Crypto::Networks::AbstractNetwork& network) { - this->network_ = network; -}; diff --git a/src/defaults/static_fees.cpp b/src/defaults/static_fees.cpp new file mode 100644 index 00000000..eace0c83 --- /dev/null +++ b/src/defaults/static_fees.cpp @@ -0,0 +1,37 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "defaults/static_fees.hpp" + +#include + +#include "common/fee_policy.hpp" + +namespace Ark { +namespace Crypto { +namespace defaults { + +// Default ARK Static Fees +const FeePolicy Fees::StaticFeePolicy() { + return { + 10000000ULL, // Transfer + 500000000ULL, // SecondSignatureRegistration + 2500000000ULL, // DelegateRegistration + 100000000ULL, // Vote + 500000000ULL, // MultiSignatureRegistration + 0ULL, // Ipfs + 0ULL, // TimelockTransfer + 0ULL, // MultiPayment + 2500000000ULL // DelegateResignation + }; +} + +} // namespace defaults +} // namespace Crypto +} // namespace Ark diff --git a/src/include/cpp-crypto/arkCrypto.h b/src/include/cpp-crypto/arkCrypto.h index 17f23742..ec069466 100644 --- a/src/include/cpp-crypto/arkCrypto.h +++ b/src/include/cpp-crypto/arkCrypto.h @@ -10,26 +10,22 @@ #ifndef ARKCRYPTO_H #define ARKCRYPTO_H -#define HAS_CRYPTO +#include "common/configuration.hpp" +#include "common/fee_policy.hpp" +#include "common/network.hpp" -#if (defined ARDUINO || defined ESP8266 || defined ESP32) -#define USE_IOT -#endif - -#include "configuration/fee.h" -#include "configuration/network.h" -#include "enums/fees.h" -#include "enums/types.h" +#include "defaults/fee_policies.hpp" +#include "defaults/static_fees.hpp" +#include "defaults/transaction_types.hpp" #include "identities/address.h" #include "identities/privatekey.h" #include "identities/publickey.h" #include "identities/wif.h" -#include "networks/abstractnetwork.h" -#include "networks/devnet.h" -#include "networks/mainnet.h" -#include "networks/testnet.h" +#include "networks/devnet.hpp" +#include "networks/mainnet.hpp" +#include "networks/testnet.hpp" #include "transactions/builder.h" #include "transactions/deserializer.h" @@ -39,10 +35,9 @@ #include "utils/message.h" #include "utils/slot.h" -using namespace Ark::Crypto::Configuration; -using namespace Ark::Crypto::Enums; +using namespace Ark::Crypto; using namespace Ark::Crypto::Identities; -using namespace Ark::Crypto::Networks; using namespace Ark::Crypto::Transactions; +using namespace Ark::Crypto::Utils; #endif diff --git a/src/include/cpp-crypto/common/configuration.hpp b/src/include/cpp-crypto/common/configuration.hpp new file mode 100644 index 00000000..abc7eaf0 --- /dev/null +++ b/src/include/cpp-crypto/common/configuration.hpp @@ -0,0 +1,45 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_CONFIGURATION_HPP +#define COMMON_CONFIGURATION_HPP + +#include "common/network.hpp" +#include "managers/network_manager.hpp" +#include "common/fee_policy.hpp" +#include "managers/fee_manager.hpp" + +namespace Ark { +namespace Crypto { +/**/ +class Configuration : public managers::NetworkManager, + public managers::FeeManager { + public: + // Default initialization: using ARK Devnet & StaticFees + Configuration() = default; + ~Configuration() = default; + + // Network initialization: Custom Network & StaticFees + explicit Configuration(const Network& network) : NetworkManager(network) {} + + // FeePolicy initialization: ARK Devnet & Custom Fees + explicit Configuration(const FeePolicy& policy) : FeeManager(policy) {} + + // Network & Fee initialization: Custom Network & Custom Fees + Configuration(const Network& network, const FeePolicy& policy) + : NetworkManager(network), FeeManager(policy) {} + + bool operator==(const Configuration& rhs) const; + bool operator!=(const Configuration& rhs) const; +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/common/fee_policy.hpp b/src/include/cpp-crypto/common/fee_policy.hpp new file mode 100644 index 00000000..bede2c6a --- /dev/null +++ b/src/include/cpp-crypto/common/fee_policy.hpp @@ -0,0 +1,24 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_TRANSACTION_FEE_POLICY_HPP +#define COMMON_TRANSACTION_FEE_POLICY_HPP + +#include +#include + +namespace Ark { +namespace Crypto { +/**/ +typedef std::vector FeePolicy; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/common/network.hpp b/src/include/cpp-crypto/common/network.hpp new file mode 100644 index 00000000..d93a19bd --- /dev/null +++ b/src/include/cpp-crypto/common/network.hpp @@ -0,0 +1,56 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_NETWORK_H +#define COMMON_NETWORK_H + +#include +#include + +namespace Ark { +namespace Crypto { +/**/ +// Abstract Network class +// +// Default initialization is ARK Devnet +class Network final { + public: + Network(); + Network(std::string nethash, + uint8_t slip44, + uint8_t wif, + uint8_t version, + std::string epoch) + : nethash_(nethash), + slip44_(slip44), + wif_(wif), + version_(version), + epoch_(epoch) {} + + std::string nethash() const; + uint8_t slip44() const; + uint8_t wif() const; + uint8_t version() const; + std::string epoch() const; + + bool operator==(const Network& rhs) const; + bool operator!=(const Network& rhs) const; + + private: + std::string nethash_; + uint8_t slip44_; + uint8_t wif_; + uint8_t version_; + std::string epoch_; +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/configuration/fee.h b/src/include/cpp-crypto/configuration/fee.h deleted file mode 100644 index d982b225..00000000 --- a/src/include/cpp-crypto/configuration/fee.h +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef FEE_H -#define FEE_H - -#include "enums/fees.h" -#include "enums/types.h" - -using namespace Ark::Crypto::Enums; - -#include - -namespace Ark { -namespace Crypto { -namespace Configuration { -/**/ -class Fee { -private: - uint64_t fees_[9] = { - Fees::TRANSFER, - Fees::SECOND_SIGNATURE_REGISTRATION, - Fees::DELEGATE_REGISTRATION, - Fees::VOTE, - Fees::MULTI_SIGNATURE_REGISTRATION, - Fees::IPFS, - Fees::TIMELOCK_TRANSFER, - Fees::MULTI_PAYMENT, - Fees::DELEGATE_RESIGNATION - }; - -public: - Fee() = default; - uint64_t get(int type); - void set(int type, uint64_t fee); -}; -/**/ -}; // namespace Configuration -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/configuration/network.h b/src/include/cpp-crypto/configuration/network.h deleted file mode 100644 index 9093291e..00000000 --- a/src/include/cpp-crypto/configuration/network.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef NETWORK_H -#define NETWORK_H - -#include "networks/abstractnetwork.h" -#include "networks/devnet.h" -#include "networks/mainnet.h" -#include "networks/testnet.h" - -namespace Ark { -namespace Crypto { -namespace Configuration { -/**/ -using namespace Ark::Crypto::Networks; -/**/ -class Network { -private: - AbstractNetwork network_; - -public: - AbstractNetwork get(); - void set(const AbstractNetwork& network); -}; -/**/ -}; // namespace Configuration -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/defaults/fee_policies.hpp b/src/include/cpp-crypto/defaults/fee_policies.hpp new file mode 100644 index 00000000..390f3474 --- /dev/null +++ b/src/include/cpp-crypto/defaults/fee_policies.hpp @@ -0,0 +1,30 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_FEE_POLICIES_HPP +#define DEFAULTS_TRANSACTIONS_FEE_POLICIES_HPP + +#include + +#include "common/fee_policy.hpp" + +namespace Ark { +namespace Crypto { +namespace defaults { +/**/ +class Fees { + public: + static const FeePolicy StaticFeePolicy(); +}; +/**/ +} // namespace defaults +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/defaults/static_fees.hpp b/src/include/cpp-crypto/defaults/static_fees.hpp new file mode 100644 index 00000000..ccddd95c --- /dev/null +++ b/src/include/cpp-crypto/defaults/static_fees.hpp @@ -0,0 +1,29 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_STATIC_FEES_HPP +#define DEFAULTS_TRANSACTIONS_STATIC_FEES_HPP + +#include "defaults/fee_policies.hpp" + +// const FeePolicy Fees::StaticFeePolicy() { +// return { +// 10000000ULL, // Transfer +// 500000000ULL, // SecondSignatureRegistration +// 2500000000ULL, // DelegateRegistration +// 100000000ULL, // Vote +// 500000000ULL, // MultiSignatureRegistration +// 0ULL, // Ipfs +// 0ULL, // TimelockTransfer +// 0ULL, // MultiPayment +// 2500000000ULL // DelegateResignation +// }; +// } + +#endif diff --git a/src/include/cpp-crypto/defaults/transaction_types.hpp b/src/include/cpp-crypto/defaults/transaction_types.hpp new file mode 100644 index 00000000..09cf5056 --- /dev/null +++ b/src/include/cpp-crypto/defaults/transaction_types.hpp @@ -0,0 +1,35 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_TYPES_HPP +#define DEFAULTS_TRANSACTIONS_TYPES_HPP + +#include + +namespace Ark { +namespace Crypto { +namespace defaults { +/**/ +enum TransactionTypes : uint8_t { + Transfer = 0, + SecondSignatureRegistration = 1, + DelegateRegistration = 2, + Vote = 3, + MultiSignatureRegistration = 4, + Ipfs = 5, + TimelockTransfer = 6, + MultiPayment = 7, + DelegateResignation = 8 +}; +/**/ +} // namespace defaults +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/enums/fees.h b/src/include/cpp-crypto/enums/fees.h deleted file mode 100644 index 38a3eeb2..00000000 --- a/src/include/cpp-crypto/enums/fees.h +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef FEES_H -#define FEES_H - -#include - -namespace Ark { -namespace Crypto { -namespace Enums { -/**/ -struct Fees { - static const uint64_t TRANSFER = 10000000ULL; - static const uint64_t SECOND_SIGNATURE_REGISTRATION = 500000000ULL; - static const uint64_t DELEGATE_REGISTRATION = 2500000000ULL; - static const uint64_t VOTE = 100000000ULL; - static const uint64_t MULTI_SIGNATURE_REGISTRATION = 500000000ULL; - static const uint64_t IPFS = 0ULL; - static const uint64_t TIMELOCK_TRANSFER = 0ULL; - static const uint64_t MULTI_PAYMENT = 0ULL; - static const uint64_t DELEGATE_RESIGNATION = 0ULL; -}; -/**/ -}; // namespace Enums -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/enums/types.h b/src/include/cpp-crypto/enums/types.h deleted file mode 100644 index 33c04d01..00000000 --- a/src/include/cpp-crypto/enums/types.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef TYPES_H -#define TYPES_H - -namespace Ark { -namespace Crypto { -namespace Enums { -/**/ -enum Types : unsigned { - TRANSFER = 0U, - SECOND_SIGNATURE_REGISTRATION = 1U, - DELEGATE_REGISTRATION = 2U, - VOTE = 3U, - MULTI_SIGNATURE_REGISTRATION = 4U, - IPFS = 5U, - TIMELOCK_TRANSFER = 6U, - MULTI_PAYMENT = 7U, - DELEGATE_RESIGNATION = 8U -}; -/**/ -}; // namespace Enums -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/abstractnetwork.h b/src/include/cpp-crypto/networks/abstractnetwork.h deleted file mode 100644 index a0f2086c..00000000 --- a/src/include/cpp-crypto/networks/abstractnetwork.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef ABSTRACT_NETWORK_H -#define ABSTRACT_NETWORK_H - -#include -#include -#include - -namespace Ark { -namespace Crypto { -namespace Networks { - -/** - * @brief Base58 Prefix Type - **/ -enum Base58PrefixType : int { - BASE58_ADDRESS_P2PKH = 0, - BASE58_ADDRESS_P2SH, - BASE58_WIF -}; -/**/ - -/** - * @brief Base58 Prefix Container - **/ -struct base58_t { - uint8_t ADDRESS_P2PKH; - uint8_t ADDRESS_P2SH; - uint8_t WIF; -}; -/**/ - -/** - * @brief BIP32 Prefix Type - **/ -enum BIP32PrefixType : int { - BIP32_PREFIX_XPUB = 0, - BIP32_PREFIX_XPRV -}; -/**/ - -/** - * @brief BIP32 Prefix Container - **/ -struct bip32_t { - long PREFIX_XPUB; - long PREFIX_XPRV; -}; -/**/ - -/** - * @brief This is the abstract network class. - **/ -class AbstractNetwork { -private: - base58_t base58_; - bip32_t bip32_; - char epoch_[34]; - bool isLocked_; - -public: - AbstractNetwork() : isLocked_(false) {}; - virtual ~AbstractNetwork() = default; - - AbstractNetwork( - base58_t base58, - bip32_t bip32, - const char* epoch, - bool locked = true) - : base58_(base58), - bip32_(bip32), - epoch_(), - isLocked_(locked) { - strncpy(this->epoch_, epoch, 34); - }; - - uint8_t getBase58Prefix(Base58PrefixType prefix) const; - void setBase58Prefix(Base58PrefixType prefix, uint8_t newByte); - - long getBIP32Prefix(BIP32PrefixType prefix) const; - void setBIP32Prefix(BIP32PrefixType prefix, long newByte); - - bool isLocked() const; - - const char* epoch() const; - uint8_t version() const; -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/devnet.h b/src/include/cpp-crypto/networks/devnet.h deleted file mode 100644 index 504b1d73..00000000 --- a/src/include/cpp-crypto/networks/devnet.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef DEVNET_H -#define DEVNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/**/ -const AbstractNetwork Devnet = { - { - 0x1E, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/devnet.hpp b/src/include/cpp-crypto/networks/devnet.hpp new file mode 100644 index 00000000..57100d50 --- /dev/null +++ b/src/include/cpp-crypto/networks/devnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_DEVNET_HPP +#define NETWORKS_DEVNET_HPP + +#include "networks/networks.hpp" + +// const Network Devnet { +// "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", // nethash +// 1, // slip44 +// 0xaa, // wif +// 0x1E, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/networks/mainnet.h b/src/include/cpp-crypto/networks/mainnet.h deleted file mode 100644 index da8fbae7..00000000 --- a/src/include/cpp-crypto/networks/mainnet.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef MAINNET_H -#define MAINNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/**/ -const AbstractNetwork Mainnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/mainnet.hpp b/src/include/cpp-crypto/networks/mainnet.hpp new file mode 100644 index 00000000..624c728c --- /dev/null +++ b/src/include/cpp-crypto/networks/mainnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_MAINNET_HPP +#define NETWORKS_MAINNET_HPP + +#include "networks/networks.hpp" + +// const Network Mainnet { +// "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988", // nethash +// 111, // slip44 +// 0xaa, // wif +// 0x17, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/networks/networks.hpp b/src/include/cpp-crypto/networks/networks.hpp new file mode 100644 index 00000000..8385ec1e --- /dev/null +++ b/src/include/cpp-crypto/networks/networks.hpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_HPP +#define NETWORKS_HPP + +#include "common/network.hpp" + +namespace Ark { +namespace Crypto { +/**/ +class Networks { + public: + static const Network Devnet(); + static const Network Mainnet(); + static const Network Testnet(); +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/networks/testnet.h b/src/include/cpp-crypto/networks/testnet.h deleted file mode 100644 index e66e36aa..00000000 --- a/src/include/cpp-crypto/networks/testnet.h +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef TESTNET_H -#define TESTNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/**/ -const AbstractNetwork Testnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xba // BASE58_WIF - }, - { - 70617039, // BIP32_PREFIX_XPUB - 70615956 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/testnet.hpp b/src/include/cpp-crypto/networks/testnet.hpp new file mode 100644 index 00000000..a83feb93 --- /dev/null +++ b/src/include/cpp-crypto/networks/testnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_TESTNET_HPP +#define NETWORKS_TESTNET_HPP + +#include "networks/networks.hpp" + +// const Network Testnet { +// "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", // nethash +// 1, // slip44 +// 0xba, // wif +// 0x17, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/transactions/builder.h b/src/include/cpp-crypto/transactions/builder.h index 13004855..4f3d02ff 100644 --- a/src/include/cpp-crypto/transactions/builder.h +++ b/src/include/cpp-crypto/transactions/builder.h @@ -10,12 +10,13 @@ #ifndef BUILDER_H #define BUILDER_H -#include "transactions/transaction.h" - #include #include #include +#include "transactions/transaction.h" +#include "common/configuration.hpp" + namespace Ark { namespace Crypto { namespace Transactions { @@ -34,29 +35,34 @@ class Builder { uint64_t amount, std::string vendorField, std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); /**/ static Transaction buildSecondSignatureRegistration( std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); static Transaction buildDelegateRegistration( std::string username, std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); static Transaction buildVote( std::vector votes, std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); static Transaction buildMultiSignatureRegistration( uint8_t min, uint8_t lifetime, std::vector& keysgroup, std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); private: Builder(); @@ -64,7 +70,8 @@ class Builder { static Transaction sign( Transaction transaction, std::string passphrase, - std::string secondPassphrase = ""); + std::string secondPassphrase = "", + const Configuration& configuration = {}); Builder sign(const std::string& passphrase); diff --git a/src/managers/fee_manager.cpp b/src/managers/fee_manager.cpp new file mode 100644 index 00000000..8332014f --- /dev/null +++ b/src/managers/fee_manager.cpp @@ -0,0 +1,67 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "managers/fee_manager.hpp" + +#include + +namespace Ark { +namespace Crypto { +namespace managers { + +namespace { + static const uint64_t AMOUNT_ZERO = 0ULL; +} // namespace + +/**/ + +uint64_t FeeManager::getFee(uint8_t type) const { + std::size_t slot = type + 1; + return slot <= feePolicy_.size() + ? this->feePolicy_[type] + : AMOUNT_ZERO; +} + +/**/ + +void FeeManager::setFee(uint8_t type, uint64_t amount) { + std::size_t slot = type + 1; + if (slot > this->feePolicy_.size()) { + this->feePolicy_.resize(slot); + }; + this->feePolicy_[type] = amount; +} + +/**/ + +FeePolicy FeeManager::getPolicy() const { + return this->feePolicy_; +} + +/**/ + +void FeeManager::setPolicy(const FeePolicy& policy) { + this->feePolicy_ = policy; +} + +/**/ + +bool FeeManager::operator==(const FeeManager& rhs) const { + return this->getPolicy() == rhs.getPolicy(); +} + +/**/ + +bool FeeManager::operator!=(const FeeManager& rhs) const { + return this->getPolicy() != rhs.getPolicy(); +} + +} // namespace managers +} // namespace Crypto +} // namespace Ark diff --git a/src/managers/fee_manager.hpp b/src/managers/fee_manager.hpp new file mode 100644 index 00000000..05362937 --- /dev/null +++ b/src/managers/fee_manager.hpp @@ -0,0 +1,46 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef MANAGERS_FEE_MANAGER_HPP +#define MANAGERS_FEE_MANAGER_HPP + +#include "common/fee_policy.hpp" +#include "defaults/fee_policies.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { +/**/ +class FeeManager { + private: + FeePolicy feePolicy_ = defaults::Fees::StaticFeePolicy(); + + public: + // Default initialization: using ARK StaticFees + FeeManager() = default; + virtual ~FeeManager() = default; + + // FeePolicy initialization: Custom FeePolicy + FeeManager(const FeePolicy& policy) : feePolicy_(policy) {} + + uint64_t getFee(uint8_t type) const; + void setFee(uint8_t type, uint64_t amount); + + FeePolicy getPolicy() const; + void setPolicy(const FeePolicy& policy); + + bool operator==(const FeeManager& rhs) const; + bool operator!=(const FeeManager& rhs) const; +}; +/**/ +} // namespace managers +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/managers/network_manager.cpp b/src/managers/network_manager.cpp new file mode 100644 index 00000000..723d91ed --- /dev/null +++ b/src/managers/network_manager.cpp @@ -0,0 +1,42 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "managers/network_manager.hpp" + +#include "common/network.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { + +Network NetworkManager::getNetwork() const { + return this->network_; +} + +/**/ + +void NetworkManager::setNetwork(const Network& network) { + this->network_ = network; +} + +/**/ + +bool NetworkManager::operator==(const NetworkManager& rhs) const { + return this->getNetwork() == rhs.getNetwork(); +} + +/**/ + +bool NetworkManager::operator!=(const NetworkManager& rhs) const { + return this->getNetwork() != rhs.getNetwork(); +} + +} // namespace managers +} // namespace Crypto +} // namespace Ark diff --git a/src/managers/network_manager.hpp b/src/managers/network_manager.hpp new file mode 100644 index 00000000..ee5d2a5d --- /dev/null +++ b/src/managers/network_manager.hpp @@ -0,0 +1,43 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef MANAGERS_NETWORK_MANAGER_HPP +#define MANAGERS_NETWORK_MANAGER_HPP + +#include "common/network.hpp" +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { +/**/ +class NetworkManager { + private: + Network network_ = Networks::Devnet(); + + public: + // Default initialization: using ARK Devnet + NetworkManager() = default; + virtual ~NetworkManager() = default; + + // Network initialization: Custom Network + NetworkManager(const Network& network) : network_(network) {} + + Network getNetwork() const; + void setNetwork(const Network& network); + + bool operator==(const NetworkManager& rhs) const; + bool operator!=(const NetworkManager& rhs) const; +}; +/**/ +} // namespace managers +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/networks/abstractnetwork.cpp b/src/networks/abstractnetwork.cpp deleted file mode 100644 index e2f06219..00000000 --- a/src/networks/abstractnetwork.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -#include "networks/abstractnetwork.h" - -#include - -uint8_t Ark::Crypto::Networks::AbstractNetwork::getBase58Prefix( - Base58PrefixType prefix) const { - switch (prefix) { - case 0: return this->base58_.ADDRESS_P2PKH; - case 1: return this->base58_.ADDRESS_P2SH; - case 2: return this->base58_.WIF; - }; -} - -/**/ - -void Ark::Crypto::Networks::AbstractNetwork::setBase58Prefix( - Base58PrefixType prefix, - uint8_t newByte) { - if (!isLocked_) { - switch (prefix) { - case 0: this->base58_.ADDRESS_P2PKH = newByte; break; - case 1: this->base58_.ADDRESS_P2SH = newByte; break; - case 2: this->base58_.WIF = newByte; break; - }; - }; -} - -/**/ - -long Ark::Crypto::Networks::AbstractNetwork::getBIP32Prefix( - BIP32PrefixType prefix) const { - return (prefix == 0) - ? this->bip32_.PREFIX_XPUB - : this->bip32_.PREFIX_XPRV; -} - -/**/ - -void Ark::Crypto::Networks::AbstractNetwork::setBIP32Prefix( - BIP32PrefixType prefix, - long newByte) { - if (!isLocked_) { - switch (prefix) { - case 0: this->bip32_.PREFIX_XPUB = newByte; break; - case 1: this->bip32_.PREFIX_XPRV = newByte; break; - }; - }; -} - -/**/ - -bool Ark::Crypto::Networks::AbstractNetwork::isLocked() const { - return this->isLocked_; -} - -/**/ - -const char* Ark::Crypto::Networks::AbstractNetwork::epoch() const { - return this->epoch_; -} - -/**/ - -uint8_t Ark::Crypto::Networks::AbstractNetwork::version() const { - return uint8_t(base58_.ADDRESS_P2PKH); -} diff --git a/src/networks/devnet.cpp b/src/networks/devnet.cpp new file mode 100644 index 00000000..39e8e6df --- /dev/null +++ b/src/networks/devnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Devnet +// Default ARK Development Network +const Network Networks::Devnet() { // NOLINT + return Network( + "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", // nethash + 1, // slip44 + 0xaa, // wif + 0x1e, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/networks/mainnet.cpp b/src/networks/mainnet.cpp new file mode 100644 index 00000000..ef3229e3 --- /dev/null +++ b/src/networks/mainnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/mainnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Mainnet +// ARK Public Network +const Network Networks::Mainnet() { // NOLINT + return Network( + "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988", // nethash + 111, // slip44 + 0xaa, // wif + 0x17, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/networks/testnet.cpp b/src/networks/testnet.cpp new file mode 100644 index 00000000..1d2f99b1 --- /dev/null +++ b/src/networks/testnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/testnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Testnet +// ARK Test Network +const Network Networks::Testnet() { // NOLINT + return Network( + "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", // nethash + 1, // slip44 + 0xba, // wif + 0x17, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/transactions/builder.cpp b/src/transactions/builder.cpp index ed3bdb80..0fd24617 100644 --- a/src/transactions/builder.cpp +++ b/src/transactions/builder.cpp @@ -1,18 +1,17 @@ #include "transactions/builder.h" -#include "configuration/fee.h" -#include "configuration/network.h" -#include "enums/types.h" -#include "identities/address.h" -#include "utils/slot.h" - -#include "helpers/crypto_helpers.h" #include #include #include #include +#include "common/configuration.hpp" +#include "defaults/transaction_types.hpp" +#include "identities/address.h" +#include "utils/slot.h" +#include "helpers/crypto_helpers.h" + namespace Ark { namespace Crypto { namespace Transactions { @@ -22,12 +21,13 @@ Transaction Builder::buildTransfer( uint64_t amount, std::string vendorField, std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - if (amount < 1ULL) { return transaction; }; + if (amount < 1ULL) { return transaction; } - transaction.type = Enums::Types::TRANSFER; - transaction.fee = Configuration::Fee().get(Enums::Types::TRANSFER); + transaction.type = defaults::TransactionTypes::Transfer; + transaction.fee = configuration.getFee(defaults::TransactionTypes::Transfer); transaction.recipientId = std::move(recipientId); transaction.amount = amount; transaction.vendorField = std::move(vendorField); @@ -42,11 +42,12 @@ Transaction Builder::buildTransfer( Transaction Builder::buildSecondSignatureRegistration( std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::SECOND_SIGNATURE_REGISTRATION; - transaction.fee = Configuration::Fee().get( - Enums::Types::SECOND_SIGNATURE_REGISTRATION); + transaction.type = defaults::TransactionTypes::SecondSignatureRegistration; + transaction.fee = configuration.getFee( + defaults::TransactionTypes::SecondSignatureRegistration); const auto publicKey = Identities::PublicKey::fromPassphrase( secondPassphrase.c_str()); @@ -63,11 +64,12 @@ Transaction Builder::buildSecondSignatureRegistration( Transaction Builder::buildDelegateRegistration( std::string username, std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::DELEGATE_REGISTRATION; - transaction.fee = Configuration::Fee().get( - Enums::Types::DELEGATE_REGISTRATION); + transaction.type = defaults::TransactionTypes::DelegateRegistration; + transaction.fee = configuration.getFee( + defaults::TransactionTypes::DelegateRegistration); transaction.asset.delegate.username = std::move(username); return sign( @@ -81,15 +83,16 @@ Transaction Builder::buildDelegateRegistration( Transaction Builder::buildVote( std::vector votes, std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::VOTE; - transaction.fee = Configuration::Fee().get(Enums::Types::VOTE); + transaction.type = defaults::TransactionTypes::Vote; + transaction.fee = configuration.getFee(defaults::TransactionTypes::Vote); transaction.asset.votes = std::move(votes); const auto recipient = Identities::Address::fromPassphrase( passphrase.c_str(), - Configuration::Network().get().version()); + configuration.getNetwork().version()); transaction.recipientId = recipient.toString(); return sign(transaction, @@ -104,19 +107,20 @@ Transaction Builder::buildMultiSignatureRegistration( uint8_t lifetime, std::vector& keysgroup, std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::MULTI_SIGNATURE_REGISTRATION; + transaction.type = defaults::TransactionTypes::MultiSignatureRegistration; transaction.fee = ( keysgroup.size() + 1) - * Configuration::Fee().get(Enums::Types::MULTI_SIGNATURE_REGISTRATION); + * configuration.getFee(defaults::TransactionTypes::MultiSignatureRegistration); transaction.asset.multiSignature.min = min; transaction.asset.multiSignature.lifetime = lifetime; transaction.asset.multiSignature.keysgroup = keysgroup; const auto recipient = Identities::Address::fromPassphrase( passphrase.c_str(), - Configuration::Network().get().version()); + configuration.getNetwork().version()); transaction.recipientId = recipient.toString(); return sign( @@ -130,9 +134,10 @@ Transaction Builder::buildMultiSignatureRegistration( Transaction Builder::sign( Transaction transaction, std::string passphrase, - std::string secondPassphrase) { + std::string secondPassphrase, + const Configuration& configuration) { transaction.timestamp = static_cast( - Utils::Slot::time(Configuration::Network().get())); + Utils::Slot::time(configuration.getNetwork())); transaction.sign(passphrase.c_str()); if (secondPassphrase.length() > 0) { diff --git a/src/transactions/deserializer.cpp b/src/transactions/deserializer.cpp index 64dac533..e1576dee 100644 --- a/src/transactions/deserializer.cpp +++ b/src/transactions/deserializer.cpp @@ -1,24 +1,23 @@ #include "transactions/deserializer.h" -#include "enums/types.h" +#include +#include +#include +#include +#include +#include + +#include "defaults/transaction_types.hpp" #include "identities/address.h" #include "identities/privatekey.h" #include "identities/publickey.h" - #include "helpers/crypto.h" #include "helpers/crypto_helpers.h" #include "helpers/encoding/hex.h" #include "bcl/Sha256.hpp" -#include -#include -#include -#include -#include -#include - namespace Ark { namespace Crypto { namespace Transactions { @@ -45,10 +44,10 @@ Transaction Deserializer::deserialize() { /**/ void Deserializer::deserializeHeader(Transaction& transaction) { - unpack(&transaction.header, &this->_binary[0]); // 1 Byte - unpack(&transaction.version, &this->_binary[1]); // 1 Byte - unpack(&transaction.network, &this->_binary[2]); // 1 Byte - unpack(&transaction.type, &this->_binary[3]); // 1 Byte + unpack(&transaction.header, &this->_binary[0]); // 1 Byte + unpack(&transaction.version, &this->_binary[1]); // 1 Byte + unpack(&transaction.network, &this->_binary[2]); // 1 Byte + unpack(&transaction.type, &this->_binary[3]); // 1 Byte unpack(&transaction.timestamp, &this->_binary[4]); // 4 Byte // 33 Byte @@ -75,30 +74,30 @@ void Deserializer::deserializeHeader(Transaction& transaction) { void Deserializer::deserializeType( Transaction& transaction) { switch (transaction.type) { - case Enums::Types::TRANSFER: { + case defaults::TransactionTypes::Transfer: { deserializeTransfer(transaction); break; }; - case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { + case defaults::TransactionTypes::SecondSignatureRegistration: { deserializeSecondSignatureRegistration(transaction); break; }; - case Enums::Types::DELEGATE_REGISTRATION: { + case defaults::TransactionTypes::DelegateRegistration: { deserializeDelegateRegistration(transaction); break; }; - case Enums::Types::VOTE: { + case defaults::TransactionTypes::Vote: { deserializeVote(transaction); break; }; - case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { + case defaults::TransactionTypes::MultiSignatureRegistration: { deserializeMultiSignatureRegistration(transaction); break; }; - case Enums::Types::IPFS: { break; }; - case Enums::Types::TIMELOCK_TRANSFER: { break; }; - case Enums::Types::MULTI_PAYMENT: { break; }; - case Enums::Types::DELEGATE_RESIGNATION: { break; }; + case defaults::TransactionTypes::Ipfs: { break; }; + case defaults::TransactionTypes::TimelockTransfer: { break; }; + case defaults::TransactionTypes::MultiPayment: { break; }; + case defaults::TransactionTypes::DelegateResignation: { break; }; }; } @@ -248,7 +247,7 @@ void Deserializer::handleVersionOne( Transaction& transaction) { transaction.signSignature = transaction.secondSignature; - if (transaction.type == Enums::Types::VOTE) { + if (transaction.type == defaults::TransactionTypes::Vote) { const auto publicKey = Identities::PublicKey::fromHex( transaction.senderPublicKey.c_str()); const auto address = Identities::Address::fromPublicKey( @@ -257,7 +256,7 @@ void Deserializer::handleVersionOne( transaction.recipientId = address.toString(); }; - if (transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + if (transaction.type == defaults::TransactionTypes::MultiSignatureRegistration) { std::for_each( transaction.asset.multiSignature.keysgroup.begin(), transaction.asset.multiSignature.keysgroup.end(), @@ -274,8 +273,8 @@ void Deserializer::handleVersionOne( transaction.id = transaction.getId(); }; - if (transaction.type == Enums::Types::SECOND_SIGNATURE_REGISTRATION - || transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + if (transaction.type == defaults::TransactionTypes::SecondSignatureRegistration + || transaction.type == defaults::TransactionTypes::MultiSignatureRegistration) { const auto publicKey = Identities::PublicKey::fromHex( transaction.senderPublicKey.c_str()); const auto address = Identities::Address::fromPublicKey( diff --git a/src/transactions/serializer.cpp b/src/transactions/serializer.cpp index 1d60dd7c..7aaa78ca 100644 --- a/src/transactions/serializer.cpp +++ b/src/transactions/serializer.cpp @@ -1,17 +1,16 @@ #include "transactions/serializer.h" -#include "configuration/network.h" -#include "enums/types.h" -#include "identities/address.h" - -#include "helpers/crypto_helpers.h" -#include "helpers/encoding/hex.h" - #include #include #include +#include "common/configuration.hpp" +#include "defaults/transaction_types.hpp" +#include "identities/address.h" +#include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" + namespace Ark { namespace Crypto { namespace Transactions { @@ -30,7 +29,7 @@ std::string Serializer::serialize() { bytes.push_back( _transaction.network > 0 ? _transaction.network - : Configuration::Network().get().version()); + : Configuration().getNetwork().version()); bytes.push_back(_transaction.type); pack(bytes, _transaction.timestamp); @@ -81,30 +80,30 @@ void Serializer::serializeVendorField( void Serializer::serializeType( std::vector& bytes) { switch (_transaction.type) { - case Enums::Types::TRANSFER: { + case defaults::TransactionTypes::Transfer: { serializeTransfer(bytes); break; }; - case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { + case defaults::TransactionTypes::SecondSignatureRegistration: { serializeSecondSignatureRegistration(bytes); break; }; - case Enums::Types::DELEGATE_REGISTRATION: { + case defaults::TransactionTypes::DelegateRegistration: { serializeDelegateRegistration(bytes); break; }; - case Enums::Types::VOTE: { + case defaults::TransactionTypes::Vote: { serializeVote(bytes); break; }; - case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { + case defaults::TransactionTypes::MultiSignatureRegistration: { serializeMultiSignatureRegistration(bytes); break; }; - case Enums::Types::IPFS: { break; }; - case Enums::Types::TIMELOCK_TRANSFER: { break; }; - case Enums::Types::MULTI_PAYMENT: { break; }; - case Enums::Types::DELEGATE_RESIGNATION: { break; }; + case defaults::TransactionTypes::Ipfs: { break; }; + case defaults::TransactionTypes::TimelockTransfer: { break; }; + case defaults::TransactionTypes::MultiPayment: { break; }; + case defaults::TransactionTypes::DelegateResignation: { break; }; }; } diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index 49f1af16..e0d95b00 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -1,10 +1,14 @@ #include "transactions/transaction.h" -#include "enums/types.h" +#include +#include +#include +#include + +#include "defaults/transaction_types.hpp" #include "identities/address.h" #include "identities/privatekey.h" - #include "helpers/crypto.h" #include "helpers/crypto_helpers.h" #include "helpers/encoding/hex.h" @@ -12,11 +16,6 @@ #include "bcl/Sha256.hpp" -#include -#include -#include -#include - using namespace Ark::Crypto::Identities; std::string Ark::Crypto::Transactions::Transaction::getId() const { @@ -114,8 +113,8 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( std::end(senderKeyBytes)); const auto skipRecipientId = - type == Enums::Types::SECOND_SIGNATURE_REGISTRATION - || type == Enums::Types::MULTI_SIGNATURE_REGISTRATION; + type == defaults::TransactionTypes::SecondSignatureRegistration + || type ==defaults::TransactionTypes::MultiSignatureRegistration; if (!this->recipientId.empty() && !skipRecipientId) { std::vector recipientIdBytes = Address::bytesFromBase58Check( @@ -156,7 +155,7 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( pack(bytes, this->amount); pack(bytes, this->fee); - if (type == Enums::Types::SECOND_SIGNATURE_REGISTRATION) { + if (type == defaults::TransactionTypes::SecondSignatureRegistration) { // SECOND_SIGNATURE_REGISTRATION const auto publicKeyBytes = HexToBytes( this->asset.signature.publicKey.c_str()); @@ -164,20 +163,20 @@ std::vector Ark::Crypto::Transactions::Transaction::toBytes( std::end(bytes), std::begin(publicKeyBytes), std::end(publicKeyBytes)); - } else if (type == Enums::Types::DELEGATE_REGISTRATION) { + } else if (type == defaults::TransactionTypes::DelegateRegistration) { // DELEGATE_REGISTRATION bytes.insert( std::end(bytes), std::begin(this->asset.delegate.username), std::end(this->asset.delegate.username)); - } else if (type == Enums::Types::VOTE) { + } else if (type == defaults::TransactionTypes::Vote) { // VOTE const auto joined = join(this->asset.votes); bytes.insert( std::end(bytes), std::begin(joined), std::end(joined)); - } else if (type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + } else if (type == defaults::TransactionTypes::MultiSignatureRegistration) { // MULTI_SIGNATURE_REGISTRATION pack(bytes, this->asset.multiSignature.min); pack(bytes, this->asset.multiSignature.lifetime); diff --git a/src/utils/slot.cpp b/src/utils/slot.cpp index 9584a565..165f757c 100644 --- a/src/utils/slot.cpp +++ b/src/utils/slot.cpp @@ -1,7 +1,10 @@ -#include "helpers/crypto_helpers.h" #include "utils/slot.h" +#include "common/network.hpp" + +#include "helpers/crypto_helpers.h" + #ifndef USE_IOT // OS Builds #include @@ -10,7 +13,8 @@ #undef round #include "date/date.h" - uint64_t Ark::Crypto::Utils::Slot::epoch(const Crypto::Networks::AbstractNetwork& network) { + uint64_t Ark::Crypto::Utils::Slot::epoch( + const Ark::Crypto::Network& network) { // https://stackoverflow.com/questions/33421450/c-c-time-zone-correct-time-conversion-to-seconds-since-epoch/33438989#33438989 std::istringstream in(network.epoch()); std::chrono::system_clock::time_point tp; @@ -32,7 +36,8 @@ #endif -uint64_t Ark::Crypto::Utils::Slot::time(const Crypto::Networks::AbstractNetwork& network) { +uint64_t Ark::Crypto::Utils::Slot::time( + const Ark::Crypto::Network& network) { const auto time = now() - epoch(network); return (time > 0) ? time : 0; } @@ -43,7 +48,8 @@ uint64_t Ark::Crypto::Utils::Slot::time(const Crypto::Networks::AbstractNetwork& #include /* strtol */ #include - uint64_t Ark::Crypto::Utils::Slot::epoch(const Crypto::Networks::AbstractNetwork& network) { + uint64_t Ark::Crypto::Utils::Slot::epoch( + const Ark::Crypto::Network& network) { constexpr const size_t expectedLength = sizeof("2017-03-21T13:00:00.000Z") - 1; if (expectedLength != 24) { return 0; } // Unexpected ISO 8601 date/time length diff --git a/src/utils/slot.h b/src/utils/slot.h index 085eacc0..96865884 100644 --- a/src/utils/slot.h +++ b/src/utils/slot.h @@ -10,7 +10,9 @@ #ifndef ARK_UTILITIES_SLOTS_H #define ARK_UTILITIES_SLOTS_H -#include "configuration/network.h" +#include + +#include "common/network.hpp" namespace Ark { namespace Crypto { @@ -18,8 +20,8 @@ namespace Utils { /**/ class Slot { public: - static uint64_t epoch(const Crypto::Networks::AbstractNetwork& network); - static uint64_t time(const Crypto::Networks::AbstractNetwork& network); + static uint64_t epoch(const Network& network); + static uint64_t time(const Network& network); private: static uint64_t now(); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 48555655..668d43ba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,10 +17,11 @@ include_directories(${PROJECT_SOURCE_DIR}/../src/lib/ArduinoJson) include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) set (TEST_SRC - ${PROJECT_SOURCE_DIR}/configuration/fee.cpp - ${PROJECT_SOURCE_DIR}/configuration/network.cpp - ${PROJECT_SOURCE_DIR}/enums/fees.cpp - ${PROJECT_SOURCE_DIR}/enums/types.cpp + ${PROJECT_SOURCE_DIR}/common/configuration.cpp + ${PROJECT_SOURCE_DIR}/common/fee_policy.cpp + ${PROJECT_SOURCE_DIR}/common/network.cpp + ${PROJECT_SOURCE_DIR}/defaults/static_fees.cpp + ${PROJECT_SOURCE_DIR}/defaults/transaction_types.cpp ${PROJECT_SOURCE_DIR}/helpers/crypto_helpers.cpp ${PROJECT_SOURCE_DIR}/helpers/crypto.cpp ${PROJECT_SOURCE_DIR}/helpers/encoding/hex.cpp @@ -28,7 +29,8 @@ set (TEST_SRC ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp ${PROJECT_SOURCE_DIR}/identities/publickey.cpp ${PROJECT_SOURCE_DIR}/identities/wif.cpp - ${PROJECT_SOURCE_DIR}/networks/abstractnetwork.cpp + ${PROJECT_SOURCE_DIR}/managers/fee_manager.cpp + ${PROJECT_SOURCE_DIR}/managers/network_manager.cpp ${PROJECT_SOURCE_DIR}/networks/devnet.cpp ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp ${PROJECT_SOURCE_DIR}/networks/testnet.cpp diff --git a/test/common/configuration.cpp b/test/common/configuration.cpp new file mode 100644 index 00000000..f0ea4e6d --- /dev/null +++ b/test/common/configuration.cpp @@ -0,0 +1,134 @@ + +#include "gtest/gtest.h" + +#include + +#include + +namespace { +static const Network kDefaultNetwork = Networks::Devnet(); +static const Network kCustomNetwork = { // random parameters + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; +/**/ +static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +static const uint64_t kTestAmount = 1000000000ULL; +/**/ +static const Configuration kDefaultConfiguration = Configuration(); +static const Configuration kCustomFeeConfiguration(kCustomFeePolicy); +static const Configuration kCustomNetworkConfiguration(kCustomNetwork); +static const Configuration kCustomConfiguration(kCustomNetwork, + kCustomFeePolicy); +} //namespace + +/**/ + +//* +TEST(common, configuration_constructor_default) { + Configuration config; + bool isMatching = kDefaultConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_network) { + Configuration config(kCustomNetwork); + bool isMatching = kCustomNetworkConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_fee) { + Configuration config(kCustomFeePolicy); + bool isMatching = kCustomFeeConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_with_network_and_fee) { + Configuration config(kCustomNetwork, kCustomFeePolicy); + bool isMatching = kCustomConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_network_get) { + Configuration config; + auto network = config.getNetwork(); + bool isMatching = kDefaultNetwork == network; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_network_set) { + Configuration config; + config.setNetwork(kCustomNetwork); + auto network = config.getNetwork(); + bool isMatching = kCustomNetwork == network; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_fee_get) { + Configuration config; + auto transferType = defaults::TransactionTypes::Transfer; + auto defaultTransferFee = kDefaultFeePolicy[transferType]; + auto transferFee = config.getFee(transferType); + ASSERT_EQ(defaultTransferFee, transferFee); +} + +/**/ + +TEST(common, configuration_fee_set) { + Configuration config; + auto transferType = defaults::TransactionTypes::Transfer; + config.setFee(transferType, kTestAmount); + uint64_t newFee = config.getFee(transferType); + ASSERT_EQ(kTestAmount, newFee); +} + +/**/ + + +TEST(common, configuration_fees_get_policy) { + Configuration config; + bool isMatching = kDefaultFeePolicy == config.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_fees_policy_set) { + Configuration config; + config.setPolicy(kCustomFeePolicy); + bool isMatching = kCustomFeePolicy == config.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_comparison_equals) { + Configuration config; + bool isMatching = kDefaultConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_comparison_not_equal) { + Configuration config(kCustomNetwork); + bool notMatching = kCustomConfiguration != config; + ASSERT_TRUE(notMatching); +} diff --git a/test/common/fee_policy.cpp b/test/common/fee_policy.cpp new file mode 100644 index 00000000..2c59bc05 --- /dev/null +++ b/test/common/fee_policy.cpp @@ -0,0 +1,20 @@ + +#include "gtest/gtest.h" + +#include + +namespace { +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +} //namespace + +/**/ + +TEST(common, fee_policy_custom) { + const FeePolicy feePolicy(kCustomFeePolicy); + for (auto i = 0; i < kCustomFeePolicy.size(); ++i) { + ASSERT_EQ(kCustomFeePolicy[i], feePolicy[i]); + }; +} diff --git a/test/common/network.cpp b/test/common/network.cpp new file mode 100644 index 00000000..003cf425 --- /dev/null +++ b/test/common/network.cpp @@ -0,0 +1,67 @@ + +#include "gtest/gtest.h" + +#include + +namespace { // NOLINT +static const Network kDevnetNetwork = Networks::Devnet(); +/**/ +static const std::string kCustomNethash = "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df"; +static const uint8_t kCustomSlip44 = 1; +static const uint8_t kCustomWif = 0x53; +static const uint8_t kCustomVersion = 0xaa; +static const std::string kCustomEpoch = "2019-04-12T13:00:00.000Z"; +/**/ +static const Network kCustomNetwork { + kCustomNethash, + kCustomSlip44, kCustomWif, kCustomVersion, + kCustomEpoch +}; +} // namespace + +/**/ + +TEST(common, network_constructor_default) { + Network network; + bool networksMatch = kDevnetNetwork == network; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_constructor_list) { + Network customNetwork = { kCustomNethash, + kCustomSlip44, + kCustomWif, + kCustomVersion, + kCustomEpoch }; + bool networksMatch = kCustomNetwork == customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_comparison_equals) { + Network customNetwork(kDevnetNetwork); + bool networksMatch = kDevnetNetwork == customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_comparison_not_equal) { + Network customNetwork(kCustomNetwork); + bool networksMatch = kDevnetNetwork != customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_get_parameters) { + Network network(kDevnetNetwork); + ASSERT_STREQ(kDevnetNetwork.nethash().c_str(), network.nethash().c_str()); + ASSERT_EQ(kDevnetNetwork.slip44(), network.slip44()); + ASSERT_EQ(kDevnetNetwork.wif(), network.wif()); + ASSERT_EQ(kDevnetNetwork.version(), network.version()); + ASSERT_STREQ(kDevnetNetwork.epoch().c_str(), network.epoch().c_str()); +} diff --git a/test/configuration/fee.cpp b/test/configuration/fee.cpp deleted file mode 100644 index 000b636d..00000000 --- a/test/configuration/fee.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -#include "arkCrypto.h" -#include "gtest/gtest.h" - -TEST(configuration, fee_get) { - Ark::Crypto::Configuration::Fee fee; - ASSERT_EQ(10000000ULL, fee.get(0)); - ASSERT_EQ(500000000ULL, fee.get(1)); - ASSERT_EQ(2500000000ULL, fee.get(2)); - ASSERT_EQ(100000000ULL, fee.get(3)); - ASSERT_EQ(500000000ULL, fee.get(4)); - ASSERT_EQ(0ULL, fee.get(5)); - ASSERT_EQ(0ULL, fee.get(6)); - ASSERT_EQ(0ULL, fee.get(7)); - ASSERT_EQ(0ULL, fee.get(8)); -} - -/**/ - -TEST(configuration, fee_set) { - Ark::Crypto::Configuration::Fee fee; - fee.set(0ULL, 20000000ULL); - fee.set(1ULL, 1000000000ULL); - fee.set(2ULL, 4000000000ULL); - fee.set(3ULL, 200000000ULL); - fee.set(4ULL, 1000000000ULL); - fee.set(5ULL, 1ULL); - fee.set(6ULL, 1ULL); - fee.set(7ULL, 1ULL); - fee.set(8ULL, 1ULL); - - ASSERT_EQ(20000000ULL, fee.get(0)); - ASSERT_EQ(1000000000ULL, fee.get(1)); - ASSERT_EQ(4000000000ULL, fee.get(2)); - ASSERT_EQ(200000000ULL, fee.get(3)); - ASSERT_EQ(1000000000ULL, fee.get(4)); - ASSERT_EQ(1ULL, fee.get(5)); - ASSERT_EQ(1ULL, fee.get(6)); - ASSERT_EQ(1ULL, fee.get(7)); - ASSERT_EQ(1ULL, fee.get(8)); -} diff --git a/test/configuration/network.cpp b/test/configuration/network.cpp deleted file mode 100644 index d0d561f0..00000000 --- a/test/configuration/network.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -#include "arkCrypto.h" -#include "gtest/gtest.h" - -TEST(configuration, network_get) { - auto network = Network().get(); // defaults to devnet - ASSERT_EQ(0x1E, network.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, network.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, network.getBase58Prefix(BASE58_WIF)); - ASSERT_EQ(46090600, network.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, network.getBIP32Prefix(BIP32_PREFIX_XPRV)); - ASSERT_STREQ("2017-03-21T13:00:00.000Z", network.epoch()); - ASSERT_EQ(true, network.isLocked()); - ASSERT_EQ(30, network.version()); -} - -/**/ - -TEST(configuration, network_set) { - Network network; - network.set(Testnet); - auto testnet = network.get(); - ASSERT_EQ(0x17, testnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, testnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xba, testnet.getBase58Prefix(BASE58_WIF)); - ASSERT_EQ(70617039, testnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(70615956, testnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); - ASSERT_STREQ("2017-03-21T13:00:00.000Z", testnet.epoch()); - ASSERT_EQ(true, testnet.isLocked()); - ASSERT_EQ(23, testnet.version()); -} diff --git a/test/defaults/static_fees.cpp b/test/defaults/static_fees.cpp new file mode 100644 index 00000000..6951bf3c --- /dev/null +++ b/test/defaults/static_fees.cpp @@ -0,0 +1,40 @@ + +#include "gtest/gtest.h" + +#include + +#include + +namespace { +static const uint64_t kTransfer = 10000000ULL; +static const uint64_t kSecondSignatureRegistration = 500000000ULL; +static const uint64_t kDelegateRegistration = 2500000000ULL; +static const uint64_t kVote = 100000000ULL; +static const uint64_t kMultiSignatureRegistration = 500000000ULL; +static const uint64_t kIpfs = 0ULL; +static const uint64_t kTimelockTransfer = 0ULL; +static const uint64_t kMultiPayment = 0ULL; +static const uint64_t kDelegateResignation = 2500000000ULL; +static const uint8_t kTransferType = 0; +static const uint8_t kSecondSignatureRegistrationType = 1; +static const uint8_t kDelegateRegistrationType = 2; +static const uint8_t kVoteType = 3; +static const uint8_t kMultiSignatureRegistrationType = 4; +static const uint8_t kIpfsType = 5; +static const uint8_t kTimelockTransferType = 6; +static const uint8_t kMultiPaymentType = 7; +static const uint8_t kDelegateResignationType = 8; +} //namespace + +TEST(defaults, fees_static) { // NOLINT + const auto feePolicy = defaults::Fees::StaticFeePolicy(); + ASSERT_EQ(kTransfer, feePolicy[kTransferType]); + ASSERT_EQ(kSecondSignatureRegistration, feePolicy[kSecondSignatureRegistrationType]); + ASSERT_EQ(kDelegateRegistration, feePolicy[kDelegateRegistrationType]); + ASSERT_EQ(kVote, feePolicy[kVoteType]); + ASSERT_EQ(kMultiSignatureRegistration, feePolicy[kMultiSignatureRegistrationType]); + ASSERT_EQ(kIpfs, feePolicy[kIpfsType]); + ASSERT_EQ(kTimelockTransfer, feePolicy[kTimelockTransferType]); + ASSERT_EQ(kMultiPayment, feePolicy[kMultiPaymentType]); + ASSERT_EQ(kDelegateResignation, feePolicy[kDelegateResignationType]); +} diff --git a/test/defaults/transaction_types.cpp b/test/defaults/transaction_types.cpp new file mode 100644 index 00000000..3afab7c8 --- /dev/null +++ b/test/defaults/transaction_types.cpp @@ -0,0 +1,30 @@ + +#include "gtest/gtest.h" + +#include + +namespace { +static const uint8_t kTransferType = 0; +static const uint8_t kSecondSignatureRegistrationType = 1; +static const uint8_t kDelegateRegistrationType = 2; +static const uint8_t kVoteType = 3; +static const uint8_t kMultiSignatureRegistrationType = 4; +static const uint8_t kIpfsType = 5; +static const uint8_t kTimelockTransferType = 6; +static const uint8_t kMultiPaymentType = 7; +static const uint8_t kDelegateResignationType = 8; +} //namespace + +/**/ + +TEST(defaults, transaction_types) { // NOLINT + ASSERT_EQ(kTransferType, defaults::TransactionTypes::Transfer); + ASSERT_EQ(kSecondSignatureRegistrationType, defaults::TransactionTypes::SecondSignatureRegistration); + ASSERT_EQ(kDelegateRegistrationType, defaults::TransactionTypes::DelegateRegistration); + ASSERT_EQ(kVoteType, defaults::TransactionTypes::Vote); + ASSERT_EQ(kMultiSignatureRegistrationType, defaults::TransactionTypes::MultiSignatureRegistration); + ASSERT_EQ(kIpfsType, defaults::TransactionTypes::Ipfs); + ASSERT_EQ(kTimelockTransferType, defaults::TransactionTypes::TimelockTransfer); + ASSERT_EQ(kMultiPaymentType, defaults::TransactionTypes::MultiPayment); + ASSERT_EQ(kDelegateResignationType, defaults::TransactionTypes::DelegateResignation); +} diff --git a/test/enums/fees.cpp b/test/enums/fees.cpp deleted file mode 100644 index 6df1be31..00000000 --- a/test/enums/fees.cpp +++ /dev/null @@ -1,33 +0,0 @@ - -#include "gtest/gtest.h" - -#include "enums/fees.h" - -TEST(enums, fees) { - auto feeZERO = Ark::Crypto::Enums::Fees::TRANSFER; - ASSERT_EQ(10000000ULL, feeZERO); - - auto feeONE = Ark::Crypto::Enums::Fees::SECOND_SIGNATURE_REGISTRATION; - ASSERT_EQ(500000000ULL, feeONE); - - auto feeTWO = Ark::Crypto::Enums::Fees::DELEGATE_REGISTRATION; - ASSERT_EQ(2500000000ULL, feeTWO); - - auto feeTHREE = Ark::Crypto::Enums::Fees::VOTE; - ASSERT_EQ(100000000ULL, feeTHREE); - - auto feeFOUR = Ark::Crypto::Enums::Fees::MULTI_SIGNATURE_REGISTRATION; - ASSERT_EQ(500000000ULL, feeFOUR); - - auto feeFIVE = Ark::Crypto::Enums::Fees::IPFS; - ASSERT_EQ(0ULL, feeFIVE); - - auto feeSIX = Ark::Crypto::Enums::Fees::TIMELOCK_TRANSFER; - ASSERT_EQ(0ULL, feeSIX); - - auto feeSEVEN = Ark::Crypto::Enums::Fees::MULTI_PAYMENT; - ASSERT_EQ(0ULL, feeSEVEN); - - auto feeEIGHT = Ark::Crypto::Enums::Fees::DELEGATE_RESIGNATION; - ASSERT_EQ(0ULL, feeEIGHT); -} diff --git a/test/enums/types.cpp b/test/enums/types.cpp deleted file mode 100644 index dd031c54..00000000 --- a/test/enums/types.cpp +++ /dev/null @@ -1,16 +0,0 @@ - -#include "gtest/gtest.h" - -#include "enums/types.h" - -TEST(enums, types) { - ASSERT_EQ(0U, Ark::Crypto::Enums::Types::TRANSFER); - ASSERT_EQ(1U, Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION); - ASSERT_EQ(2U, Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION); - ASSERT_EQ(3U, Ark::Crypto::Enums::Types::VOTE); - ASSERT_EQ(4U, Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION); - ASSERT_EQ(5U, Ark::Crypto::Enums::Types::IPFS); - ASSERT_EQ(6U, Ark::Crypto::Enums::Types::TIMELOCK_TRANSFER); - ASSERT_EQ(7U, Ark::Crypto::Enums::Types::MULTI_PAYMENT); - ASSERT_EQ(8U, Ark::Crypto::Enums::Types::DELEGATE_RESIGNATION); -} diff --git a/test/managers/fee_manager.cpp b/test/managers/fee_manager.cpp new file mode 100644 index 00000000..1f1920f6 --- /dev/null +++ b/test/managers/fee_manager.cpp @@ -0,0 +1,100 @@ + +#include "gtest/gtest.h" + +#include + +using namespace managers; + +namespace { +static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +static const FeeManager kDefaultFeeManager = FeeManager(); +static const FeeManager kCustomFeeManager = FeeManager(kCustomFeePolicy); +static const uint8_t kInPolicyBounds = 5; +static const uint8_t kOutOfPolicyBounds = 11; +static const uint64_t kAmountZero = 0ULL; +static const uint64_t kCustomFee = 1000000000ULL; +} //namespace + +/**/ + +TEST(managers, fee_manager_constructor_default) { + FeeManager feeManager; + bool isMatching = kDefaultFeeManager == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_constructor_fee_policy) { + FeeManager feeManager(kCustomFeePolicy); + bool isMatching = kCustomFeeManager == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_fee_get_in_bounds) { + FeeManager feeManager; + ASSERT_EQ(kDefaultFeePolicy[kInPolicyBounds], + feeManager.getFee(kInPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_get_out_of_bounds) { + FeeManager feeManager; + ASSERT_EQ(kAmountZero, feeManager.getFee(kOutOfPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_set_in_bounds) { + FeeManager feeManager; + feeManager.setFee(kInPolicyBounds, kCustomFee); + ASSERT_EQ(kCustomFee, feeManager.getFee(kInPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_set_out_of_bounds) { + FeeManager feeManager; + feeManager.setFee(kOutOfPolicyBounds, kCustomFee); + ASSERT_EQ(kCustomFee, feeManager.getFee(kOutOfPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_policy_get) { + FeeManager feeManager; + bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_policy_set) { + FeeManager feeManager; + feeManager.setPolicy(kCustomFeePolicy); + bool isMatching = kCustomFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_comparison_equals) { + FeeManager feeManager; + bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_comparison_not_equal) { + FeeManager feeManager(kCustomFeePolicy); + bool notMatching = kDefaultFeePolicy != feeManager.getPolicy(); + ASSERT_TRUE(notMatching); +} diff --git a/test/managers/network_manager.cpp b/test/managers/network_manager.cpp new file mode 100644 index 00000000..4e1ac0f6 --- /dev/null +++ b/test/managers/network_manager.cpp @@ -0,0 +1,67 @@ + +#include "gtest/gtest.h" + +#include + +using namespace managers; + +namespace { // NOLINT +static const Network kDefaultNetwork = Networks::Devnet(); +static const Network kCustomNetwork { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; +/**/ +static const NetworkManager kDefaultNetworkManager = NetworkManager(); +static const NetworkManager kCustomNetworkManager = NetworkManager(kCustomNetwork); +} //namespace + +/**/ + +TEST(managers, network_manager_constructor_default) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_network_constructor) { + NetworkManager networkManager(kCustomNetwork); + bool isMatching = kCustomNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_get) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_set) { + NetworkManager networkManager; + networkManager.setNetwork(kCustomNetwork); + bool isMatching = kCustomNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_comparison_equals) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_comparison_not_equal) { + NetworkManager networkManager(kCustomNetwork); + bool notMatching = kDefaultNetworkManager != networkManager; + ASSERT_TRUE(notMatching); +} \ No newline at end of file diff --git a/test/networks/abstractnetwork.cpp b/test/networks/abstractnetwork.cpp deleted file mode 100644 index bb2962c6..00000000 --- a/test/networks/abstractnetwork.cpp +++ /dev/null @@ -1,112 +0,0 @@ - -#include "gtest/gtest.h" - -#include "networks/abstractnetwork.h" -using namespace Ark::Crypto::Networks; - -#include - -AbstractNetwork CUSTOM_NETWORK = { - { - 0x01, // BASE58_ADDRESS_P2PKH - 0x02, // BASE58_ADDRESS_P2SH - 0x03 // BASE58_WIF - }, - { - 00010100, // BIP32_PREFIX_XPUB - 00010101 // BIP32_PREFIX_XPRV - }, - "0000-00-00T00:00:00.000Z", // Epoch - false // isLocked -}; - -/**/ - -TEST(networks, abstract_network_default) { - AbstractNetwork abstractNetwork; - ASSERT_FALSE(abstractNetwork.isLocked()); -}; - -/**/ - -TEST(networks, abstract_network_custom) { - base58_t base58 = { 0x01, 0x02, 0x03 }; - bip32_t bip32 = { 00010100, 00010101 }; - const auto epoch = "0000-00-00T00:00:00.000Z"; - - AbstractNetwork testNetwork(base58, bip32, epoch, true); - - ASSERT_EQ( - CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH), - testNetwork.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ( - CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH), - testNetwork.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ( - CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF), - testNetwork.getBase58Prefix(BASE58_WIF)); - ASSERT_TRUE(testNetwork.isLocked()); -} - -/**/ - -TEST(networks, abstract_network_base58_prefix_get) { - ASSERT_EQ(1, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(2, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(3, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); -} - -/**/ - -TEST(networks, abstract_network_base58_prefix_set) { - AbstractNetwork testNetwork = CUSTOM_NETWORK; - - testNetwork.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x10); - ASSERT_EQ(0x10, testNetwork.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - - testNetwork.setBase58Prefix(BASE58_ADDRESS_P2SH, 0x20); - ASSERT_EQ(0x20, testNetwork.getBase58Prefix(BASE58_ADDRESS_P2SH)); - - testNetwork.setBase58Prefix(BASE58_WIF, 0x30); - ASSERT_EQ(0x30, testNetwork.getBase58Prefix(BASE58_WIF)); -} - -/**/ - -TEST(networks, abstract_network_bip32_prefix_get) { - ASSERT_EQ(00010100, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(00010101, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -/**/ - -TEST(networks, abstract_network_bip32_prefix_set) { - AbstractNetwork testNetwork = CUSTOM_NETWORK; - - testNetwork.setBIP32Prefix(BIP32_PREFIX_XPUB, 1000000); - ASSERT_EQ(1000000, testNetwork.getBIP32Prefix(BIP32_PREFIX_XPUB)); - - testNetwork.setBIP32Prefix(BIP32_PREFIX_XPRV, 1000001); - ASSERT_EQ(1000001, testNetwork.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -/**/ - -TEST(networks, abstract_network_epoch) { - const auto expected = "0000-00-00T00:00:00.000Z"; - ASSERT_STREQ(expected, CUSTOM_NETWORK.epoch()); -} - -/**/ - -TEST(networks, abstract_network_is_locked) { - ASSERT_EQ(false, CUSTOM_NETWORK.isLocked()); -} - -/**/ - -TEST(networks, abstract_network_version) { - AbstractNetwork customNetwork = CUSTOM_NETWORK; - customNetwork.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x14); - ASSERT_EQ(20, customNetwork.version()); -} diff --git a/test/networks/devnet.cpp b/test/networks/devnet.cpp index 20553618..d65d332f 100644 --- a/test/networks/devnet.cpp +++ b/test/networks/devnet.cpp @@ -1,36 +1,19 @@ #include "gtest/gtest.h" - -#include "networks/devnet.h" -using namespace Ark::Crypto::Networks; - -TEST(networks, devnet_base58_prefix_get) { - ASSERT_EQ(0x1E, Devnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Devnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, Devnet.getBase58Prefix(BASE58_WIF)); -} - -/**/ - -TEST(networks, devnet_bip32_prefix_get) { - ASSERT_EQ(46090600, Devnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, Devnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -/**/ - -TEST(networks, devnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Devnet.epoch()); -} - -/**/ - -TEST(networks, devnet_is_locked) { - ASSERT_EQ(true, Devnet.isLocked()); -} - -/**/ - -TEST(networks, devnet_version) { - ASSERT_EQ(30, Devnet.version()); +#include + +namespace { // NOLINT + static const std::string Nethash = "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867"; + static const uint8_t Slip44 = 1; + static const uint8_t Wif = 0xaa; + static const uint8_t Version = 0x1E; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace + +TEST(networks, devnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Devnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Devnet().slip44()); + ASSERT_EQ(Wif, Networks::Devnet().wif()); + ASSERT_EQ(Version, Networks::Devnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Devnet().epoch().c_str()); } diff --git a/test/networks/mainnet.cpp b/test/networks/mainnet.cpp index 654d1d60..91795a64 100644 --- a/test/networks/mainnet.cpp +++ b/test/networks/mainnet.cpp @@ -1,36 +1,19 @@ #include "gtest/gtest.h" - -#include "networks/mainnet.h" -using namespace Ark::Crypto::Networks; - -TEST(networks, mainnet_base58_prefix_get) { - ASSERT_EQ(0x17, Mainnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Mainnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, Mainnet.getBase58Prefix(BASE58_WIF)); -} - -/**/ - -TEST(networks, mainnet_bip32_prefix_get) { - ASSERT_EQ(46090600, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -/**/ - -TEST(networks, mainnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Mainnet.epoch()); -} - -/**/ - -TEST(networks, mainnet_is_locked) { - ASSERT_EQ(true, Mainnet.isLocked()); -} - -/**/ - -TEST(networks, mainnet_version) { - ASSERT_EQ(23, Mainnet.version()); +#include + +namespace { // NOLINT + static const std::string Nethash = "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988"; + static const uint8_t Slip44 = 111; + static const uint8_t Wif = 0xaa; + static const uint8_t Version = 0x17; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace + +TEST(networks, mainnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Mainnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Mainnet().slip44()); + ASSERT_EQ(Wif, Networks::Mainnet().wif()); + ASSERT_EQ(Version, Networks::Mainnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Mainnet().epoch().c_str()); } diff --git a/test/networks/testnet.cpp b/test/networks/testnet.cpp index 9aa9482e..d4212951 100644 --- a/test/networks/testnet.cpp +++ b/test/networks/testnet.cpp @@ -1,36 +1,19 @@ #include "gtest/gtest.h" - -#include "networks/testnet.h" -using namespace Ark::Crypto::Networks; - -TEST(networks, testnet_base58_prefix_get) { - ASSERT_EQ(0x17, Testnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Testnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xba, Testnet.getBase58Prefix(BASE58_WIF)); -} - -/**/ - -TEST(networks, testnet_bip32_prefix_get) { - ASSERT_EQ(70617039, Testnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(70615956, Testnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -/**/ - -TEST(networks, testnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Testnet.epoch()); -} - -/**/ - -TEST(networks, testnet_is_locked) { - ASSERT_EQ(true, Testnet.isLocked()); -} - -/**/ - -TEST(networks, testnet_version) { - ASSERT_EQ(23, Testnet.version()); +#include + +namespace { // NOLINT + static const std::string Nethash = "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192"; + static const uint8_t Slip44 = 1; + static const uint8_t Wif = 0xba; + static const uint8_t Version = 0x17; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace + +TEST(networks, testnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Testnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Testnet().slip44()); + ASSERT_EQ(Wif, Networks::Testnet().wif()); + ASSERT_EQ(Version, Networks::Testnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Testnet().epoch().c_str()); } diff --git a/test/transactions/builder.cpp b/test/transactions/builder.cpp index 96d4ddb9..6aeef1c8 100644 --- a/test/transactions/builder.cpp +++ b/test/transactions/builder.cpp @@ -1,28 +1,53 @@ #include "gtest/gtest.h" -#include "configuration/fee.h" -#include "enums/types.h" -#include "transactions/builder.h" -using namespace Ark::Crypto::Transactions; +#include TEST(transactions, build_transfer) { - const auto actual = Ark::Crypto::Transactions::Builder::buildTransfer( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 100000000ULL, - "", - "Secret passphrase"); - ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); - ASSERT_EQ( - Ark::Crypto::Configuration::Fee().get(Ark::Crypto::Enums::Types::TRANSFER), - actual.fee); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); + const auto actual = + Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "", + "Secret passphrase"); + + ASSERT_EQ(0, actual.type); + ASSERT_EQ(defaults::Fees::StaticFeePolicy()[actual.type], actual.fee); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + actual.recipientId.c_str()); ASSERT_EQ(100000000ULL, actual.amount); ASSERT_TRUE(actual.vendorField.empty()); } /**/ +TEST(transactions, build_transfer_custom_network) { + static const Network MyCustomNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration myCustomConfiguration(MyCustomNetwork); + + const auto transaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + myCustomConfiguration); + + ASSERT_EQ(0, transaction.type); + ASSERT_EQ(myCustomConfiguration.getFee(transaction.type), transaction.fee); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + transaction.recipientId.c_str()); + ASSERT_EQ(100000000ULL, transaction.amount); + ASSERT_STREQ("this is a custom bridgechain transaction", + transaction.vendorField.c_str()); +} + +/**/ + TEST(transactions, build_empty_transaction) { // test 0 ARKtoshi value const auto shouldBeEmpty = Ark::Crypto::Transactions::Builder::buildTransfer( @@ -30,6 +55,7 @@ TEST(transactions, build_empty_transaction) { 0, "", "Secret passphrase"); + ASSERT_TRUE(shouldBeEmpty.recipientId.empty()); ASSERT_EQ(0ULL, shouldBeEmpty.amount); ASSERT_FALSE(shouldBeEmpty.verify()); diff --git a/test/transactions/deserializer.cpp b/test/transactions/deserializer.cpp index 8254e85e..f7908204 100644 --- a/test/transactions/deserializer.cpp +++ b/test/transactions/deserializer.cpp @@ -1,10 +1,7 @@ #include "gtest/gtest.h" -#include "enums/types.h" -#include "identities/address.h" -#include "identities/publickey.h" -#include "transactions/deserializer.h" +#include TEST(transactions, deserialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json @@ -17,7 +14,7 @@ TEST(transactions, deserialize_transfer) { // NOLINT ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); + ASSERT_EQ(defaults::TransactionTypes::Transfer, actual.type); ASSERT_EQ(41443847UL, actual.timestamp); ASSERT_STREQ( "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", @@ -49,7 +46,7 @@ TEST(transactions, deserialize_second_signature_registration) { // NOLINT ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION, actual.type); + ASSERT_EQ(defaults::TransactionTypes::SecondSignatureRegistration, actual.type); ASSERT_EQ(41271867UL, actual.timestamp); ASSERT_STREQ( "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", @@ -91,7 +88,7 @@ TEST(transactions, deserialize_delegate_registration) { // NOLINT ASSERT_EQ(2, actual.type); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION, actual.type); + ASSERT_EQ(defaults::TransactionTypes::DelegateRegistration, actual.type); ASSERT_EQ(41269424UL, actual.timestamp); ASSERT_STREQ( "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", @@ -127,7 +124,7 @@ TEST(transactions, deserialize_vote) { // NOLINT ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::VOTE, actual.type); + ASSERT_EQ(defaults::TransactionTypes::Vote, actual.type); ASSERT_EQ(41269366UL, actual.timestamp); ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); ASSERT_TRUE(100000000ULL == actual.fee); @@ -168,7 +165,7 @@ TEST(transactions, deserialize_multi_signature_registration) { // NOLINT ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(23, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION, actual.type); + ASSERT_EQ(defaults::TransactionTypes::MultiSignatureRegistration, actual.type); ASSERT_EQ(10112114UL, actual.timestamp); ASSERT_STREQ("036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760", actual.senderPublicKey.c_str()); ASSERT_TRUE(2000000000ULL == actual.fee); diff --git a/test/transactions/serializer.cpp b/test/transactions/serializer.cpp index b41196ec..543fbf87 100644 --- a/test/transactions/serializer.cpp +++ b/test/transactions/serializer.cpp @@ -1,7 +1,7 @@ #include "gtest/gtest.h" -#include "transactions/serializer.h" +#include TEST(transactions, serialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json diff --git a/test/utils/slot.cpp b/test/utils/slot.cpp index 845e26e3..aaf3679a 100644 --- a/test/utils/slot.cpp +++ b/test/utils/slot.cpp @@ -1,24 +1,23 @@ -#include "gtest/gtest.h" #include "gtest/gtest.h" -#include "helpers/crypto_helpers.h" -#include "utils/slot.h" +#include "arkCrypto.h" TEST(utilities, slots_epoch) { - const auto devnet = Ark::Crypto::Networks::Devnet; + const auto devnet = Networks::Devnet(); const auto arkEpoch = 1490101200ULL; - ASSERT_EQ(arkEpoch, Ark::Crypto::Utils::Slot::epoch(devnet)); + ASSERT_EQ(arkEpoch, Slot::epoch(devnet)); } /**/ TEST(utilities, slots_time) { - const auto devnet = Ark::Crypto::Networks::Devnet; + const auto devnet = Networks::Devnet(); + // const auto mainnet = Networks::Mainnet; // 28 Jan 2019(in seconds) - Ark Epoch (seconds) const auto testTime = (1548725761ULL - 1490101200ULL); - const auto slotTime = Ark::Crypto::Utils::Slot::time(devnet); + const auto slotTime = Slot::time(devnet); // test that slot-time is more recent than 'testTime', ASSERT_GT(slotTime , testTime); From 3ea91efa20543666e6258d4f89a83cf4d95eb46c Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:26:28 -0700 Subject: [PATCH 21/29] chore(arduino): merge changes at #105 for arduino release. --- .appveyor.yml | 20 -- .circleci/clang_format.sh | 40 --- .circleci/clang_tidy.sh | 16 - .circleci/config.yml | 105 +----- .circleci/install_platform_io.sh | 8 - .circleci/platformio.cpp | 21 -- .circleci/script_desktop.sh | 12 - .circleci/script_platform_io.sh | 3 - .clang-format | 117 ------- .codecov.yml | 4 - .gitmodules | 12 - CMakeLists.txt | 57 ---- cmake/CodeCoverage.cmake | 204 ------------ examples/{arduino => }/ESP32/ESP32.ino | 0 examples/{arduino => }/ESP8266/ESP8266.ino | 0 examples/cmake_example/.gitmodules | 3 - examples/cmake_example/CMakeLists.txt | 31 -- examples/cmake_example/CMakeSettings.json | 88 ----- .../lib/put-cpp-crypto-folder-here | 0 examples/cmake_example/main.cpp | 107 ------ examples/platformio_example/platformio.ini | 26 -- examples/platformio_example/src/main.ino | 114 ------- .../docs/INSTALL_ARDUINO.md | 0 {docs => extras/docs}/INSTALL_OS.md | 0 {docs => extras/docs}/INSTALL_PLATFORMIO.md | 0 {docs => extras/docs}/cpp.md | 0 lib/readme.txt | 41 --- platformio.ini | 39 --- src/CMakeLists.txt | 75 ----- src/{include/cpp-crypto => }/arkCrypto.h | 0 src/{lib => }/bcl/Base58Check.cpp | 0 src/{lib => }/bcl/Base58Check.hpp | 0 src/{lib => }/bcl/CurvePoint.cpp | 0 src/{lib => }/bcl/CurvePoint.hpp | 0 src/{lib => }/bcl/Ecdsa.cpp | 0 src/{lib => }/bcl/Ecdsa.hpp | 0 src/{lib => }/bcl/FieldInt.cpp | 0 src/{lib => }/bcl/FieldInt.hpp | 0 src/{lib => }/bcl/Ripemd160.cpp | 0 src/{lib => }/bcl/Ripemd160.hpp | 0 src/{lib => }/bcl/Sha256.cpp | 0 src/{lib => }/bcl/Sha256.hpp | 0 src/{lib => }/bcl/Sha256Hash.cpp | 0 src/{lib => }/bcl/Sha256Hash.hpp | 0 src/{lib => }/bcl/Sha512.cpp | 0 src/{lib => }/bcl/Sha512.hpp | 0 src/{lib => }/bcl/Uint256.cpp | 0 src/{lib => }/bcl/Uint256.hpp | 0 src/{lib => }/bcl/Utils.cpp | 0 src/{lib => }/bcl/Utils.hpp | 0 .../cpp-crypto => }/common/configuration.hpp | 0 .../cpp-crypto => }/common/fee_policy.hpp | 0 .../cpp-crypto => }/common/network.hpp | 0 src/{lib => }/date/date.h | 0 .../cpp-crypto => }/defaults/fee_policies.hpp | 0 .../cpp-crypto => }/defaults/static_fees.hpp | 0 .../defaults/transaction_types.hpp | 0 .../cpp-crypto => }/helpers/encoding/hex.h | 0 .../cpp-crypto => }/identities/address.h | 0 .../cpp-crypto => }/identities/privatekey.h | 0 .../cpp-crypto => }/identities/publickey.h | 0 src/{include/cpp-crypto => }/identities/wif.h | 0 src/lib/ArduinoJson | 1 - src/lib/BIP66 | 1 - src/lib/uECC | 1 - .../cpp-crypto => }/networks/devnet.hpp | 0 .../cpp-crypto => }/networks/mainnet.hpp | 0 .../cpp-crypto => }/networks/networks.hpp | 0 .../cpp-crypto => }/networks/testnet.hpp | 0 src/{lib => }/rfc6979/rfc6979.h | 0 .../cpp-crypto => }/transactions/builder.h | 0 .../transactions/deserializer.h | 0 .../cpp-crypto => }/transactions/serializer.h | 0 .../transactions/transaction.h | 0 test/CMakeLists.txt | 60 ---- test/common/configuration.cpp | 134 -------- test/common/fee_policy.cpp | 20 -- test/common/network.cpp | 67 ---- test/defaults/static_fees.cpp | 40 --- test/defaults/transaction_types.cpp | 30 -- test/helpers/crypto.cpp | 108 ------- test/helpers/crypto_helpers.cpp | 30 -- test/helpers/encoding/hex.cpp | 41 --- test/identities/address.cpp | 107 ------ test/identities/privatekey.cpp | 71 ---- test/identities/publickey.cpp | 77 ----- test/identities/wif.cpp | 58 ---- test/iot/gtest/gtest.h | 7 - test/iot/test_main.cpp | 29 -- test/lib/googletest | 1 - test/managers/fee_manager.cpp | 100 ------ test/managers/network_manager.cpp | 67 ---- test/networks/devnet.cpp | 19 -- test/networks/mainnet.cpp | 19 -- test/networks/testnet.cpp | 19 -- test/platformio.ini | 40 --- test/transactions/builder.cpp | 62 ---- test/transactions/deserializer.cpp | 214 ------------ test/transactions/serializer.cpp | 145 --------- test/transactions/transaction.cpp | 305 ------------------ test/utils/message.cpp | 57 ---- test/utils/slot.cpp | 26 -- 102 files changed, 1 insertion(+), 3098 deletions(-) delete mode 100644 .appveyor.yml delete mode 100644 .circleci/clang_format.sh delete mode 100644 .circleci/clang_tidy.sh delete mode 100644 .circleci/install_platform_io.sh delete mode 100644 .circleci/platformio.cpp delete mode 100644 .circleci/script_desktop.sh delete mode 100644 .circleci/script_platform_io.sh delete mode 100644 .clang-format delete mode 100644 .codecov.yml delete mode 100644 .gitmodules delete mode 100644 CMakeLists.txt delete mode 100644 cmake/CodeCoverage.cmake rename examples/{arduino => }/ESP32/ESP32.ino (100%) rename examples/{arduino => }/ESP8266/ESP8266.ino (100%) delete mode 100644 examples/cmake_example/.gitmodules delete mode 100644 examples/cmake_example/CMakeLists.txt delete mode 100644 examples/cmake_example/CMakeSettings.json delete mode 100644 examples/cmake_example/lib/put-cpp-crypto-folder-here delete mode 100644 examples/cmake_example/main.cpp delete mode 100644 examples/platformio_example/platformio.ini delete mode 100644 examples/platformio_example/src/main.ino rename docs/INSTALL_ARDUINO.MD => extras/docs/INSTALL_ARDUINO.md (100%) rename {docs => extras/docs}/INSTALL_OS.md (100%) rename {docs => extras/docs}/INSTALL_PLATFORMIO.md (100%) rename {docs => extras/docs}/cpp.md (100%) delete mode 100644 lib/readme.txt delete mode 100644 platformio.ini delete mode 100644 src/CMakeLists.txt rename src/{include/cpp-crypto => }/arkCrypto.h (100%) rename src/{lib => }/bcl/Base58Check.cpp (100%) rename src/{lib => }/bcl/Base58Check.hpp (100%) rename src/{lib => }/bcl/CurvePoint.cpp (100%) rename src/{lib => }/bcl/CurvePoint.hpp (100%) rename src/{lib => }/bcl/Ecdsa.cpp (100%) rename src/{lib => }/bcl/Ecdsa.hpp (100%) rename src/{lib => }/bcl/FieldInt.cpp (100%) rename src/{lib => }/bcl/FieldInt.hpp (100%) rename src/{lib => }/bcl/Ripemd160.cpp (100%) rename src/{lib => }/bcl/Ripemd160.hpp (100%) rename src/{lib => }/bcl/Sha256.cpp (100%) rename src/{lib => }/bcl/Sha256.hpp (100%) rename src/{lib => }/bcl/Sha256Hash.cpp (100%) rename src/{lib => }/bcl/Sha256Hash.hpp (100%) rename src/{lib => }/bcl/Sha512.cpp (100%) rename src/{lib => }/bcl/Sha512.hpp (100%) rename src/{lib => }/bcl/Uint256.cpp (100%) rename src/{lib => }/bcl/Uint256.hpp (100%) rename src/{lib => }/bcl/Utils.cpp (100%) rename src/{lib => }/bcl/Utils.hpp (100%) rename src/{include/cpp-crypto => }/common/configuration.hpp (100%) rename src/{include/cpp-crypto => }/common/fee_policy.hpp (100%) rename src/{include/cpp-crypto => }/common/network.hpp (100%) rename src/{lib => }/date/date.h (100%) rename src/{include/cpp-crypto => }/defaults/fee_policies.hpp (100%) rename src/{include/cpp-crypto => }/defaults/static_fees.hpp (100%) rename src/{include/cpp-crypto => }/defaults/transaction_types.hpp (100%) rename src/{include/cpp-crypto => }/helpers/encoding/hex.h (100%) rename src/{include/cpp-crypto => }/identities/address.h (100%) rename src/{include/cpp-crypto => }/identities/privatekey.h (100%) rename src/{include/cpp-crypto => }/identities/publickey.h (100%) rename src/{include/cpp-crypto => }/identities/wif.h (100%) delete mode 160000 src/lib/ArduinoJson delete mode 160000 src/lib/BIP66 delete mode 160000 src/lib/uECC rename src/{include/cpp-crypto => }/networks/devnet.hpp (100%) rename src/{include/cpp-crypto => }/networks/mainnet.hpp (100%) rename src/{include/cpp-crypto => }/networks/networks.hpp (100%) rename src/{include/cpp-crypto => }/networks/testnet.hpp (100%) rename src/{lib => }/rfc6979/rfc6979.h (100%) rename src/{include/cpp-crypto => }/transactions/builder.h (100%) rename src/{include/cpp-crypto => }/transactions/deserializer.h (100%) rename src/{include/cpp-crypto => }/transactions/serializer.h (100%) rename src/{include/cpp-crypto => }/transactions/transaction.h (100%) delete mode 100644 test/CMakeLists.txt delete mode 100644 test/common/configuration.cpp delete mode 100644 test/common/fee_policy.cpp delete mode 100644 test/common/network.cpp delete mode 100644 test/defaults/static_fees.cpp delete mode 100644 test/defaults/transaction_types.cpp delete mode 100644 test/helpers/crypto.cpp delete mode 100644 test/helpers/crypto_helpers.cpp delete mode 100644 test/helpers/encoding/hex.cpp delete mode 100644 test/identities/address.cpp delete mode 100644 test/identities/privatekey.cpp delete mode 100644 test/identities/publickey.cpp delete mode 100644 test/identities/wif.cpp delete mode 100644 test/iot/gtest/gtest.h delete mode 100644 test/iot/test_main.cpp delete mode 160000 test/lib/googletest delete mode 100644 test/managers/fee_manager.cpp delete mode 100644 test/managers/network_manager.cpp delete mode 100644 test/networks/devnet.cpp delete mode 100644 test/networks/mainnet.cpp delete mode 100644 test/networks/testnet.cpp delete mode 100644 test/platformio.ini delete mode 100644 test/transactions/builder.cpp delete mode 100644 test/transactions/deserializer.cpp delete mode 100644 test/transactions/serializer.cpp delete mode 100644 test/transactions/transaction.cpp delete mode 100644 test/utils/message.cpp delete mode 100644 test/utils/slot.cpp diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 38629ea7..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,20 +0,0 @@ -version: 1.0.{build} - -image: Visual Studio 2017 - -environment: - matrix: - - CONFIGURATION: Debug - - CONFIGURATION: Release - -install: - - git submodule update --init --recursive - -before_build: - - cmake -G "Visual Studio 15 2017 Win64" . - -build: - project: $(APPVEYOR_BUILD_FOLDER)\Ark-Cpp-Crypto.sln - -test_script: - - cmd: '%APPVEYOR_BUILD_FOLDER%\test\%CONFIGURATION%\Ark-Cpp-Crypto-tests.exe' diff --git a/.circleci/clang_format.sh b/.circleci/clang_format.sh deleted file mode 100644 index 40201aad..00000000 --- a/.circleci/clang_format.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -ex - -grep -nr '\s$' src test examples .gitignore .gitmodules 2>&1 > /dev/null -if $?; then - echo Trailing whitespace found, aborting - exit 1 -fi - -# Default clang-format points to default 5.0 version one -CLANG_FORMAT=clang-format-5.0 -$CLANG_FORMAT --version - -#TODO: Create equivlient for CircleCI -#if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then -# # Get list of every file modified in this pull request -# files_to_lint="$(git diff --name-only --diff-filter=ACMRTUXB $TRAVIS_COMMIT_RANGE | grep '^src/[^.]*[.]\(cpp\|h\)$' || true)" -#else - # Check everything for branch pushes - files_to_lint="$(find . -not \( -path ./CMakeFiles -prune \) -not \( -path ./src/lib -prune \) -not \( -path ./test/lib -prune \) -not \( -path ./examples/cmake_example/lib -prune \) -not \( -path ./examples/cmake_example/CMakeFiles -prune \) -not \( -path ./examples/platformio_example -prune \) -name \*.h -o -name \*.cpp)" -#fi - -# Turn off tracing for this because it's too verbose -set +x - -for f in $files_to_lint; do - d=$(diff -u "$f" <($CLANG_FORMAT "$f") || true) - if ! [ -z "$d" ]; then - echo "!!! $f not compliant to coding style, here is the fix:" - echo "$d" - fail=1 - fi -done - -set -x - -if [ "$fail" = 1 ]; then - # Don't fail the build yet - #exit 1 - exit 0 -fi diff --git a/.circleci/clang_tidy.sh b/.circleci/clang_tidy.sh deleted file mode 100644 index ae917a5e..00000000 --- a/.circleci/clang_tidy.sh +++ /dev/null @@ -1,16 +0,0 @@ -# run clang tidy -cmake -DENABLE_CLANG_TIDY=ON . -make tidy > output.txt -#if [[ -n $(grep "warning: " output.txt) ]] || [[ -n $(grep "error: " output.txt) ]]; then -# for now only fail the test on errors. Change this as project matures -if [[ -n $(grep "error: " output.txt) ]]; then - echo "You must pass the clang tidy checks before submitting a pull request" - echo "" - grep --color -E '^|warning: |error: ' output.txt - exit 1; -else - # still output the file to show warnings - echo "" - grep --color -E '^|warning: |error: ' output.txt - echo -e "\033[1;32m\xE2\x9C\x93 passed:\033[0m $1"; -fi diff --git a/.circleci/config.yml b/.circleci/config.yml index b5836792..767ade27 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -13,112 +13,9 @@ jobs: - run: name: Build command: ./.circleci/script_arduino.sh - build-linux-default: - machine: true - steps: - - checkout - - run: - name: Make scripts executable - command: sudo chmod -R +x ./.circleci/*.sh - - run: - name: Install - command: ./.circleci/install_platform_io.sh - - run: - name: Empty Git Submodule Folders - command: | - rm -rf ./src/lib/{ArduinoJson/*,BIP66/*,uECC/*} - rm -rf ./test/lib/googletest/* - - run: - name: Build - command: ./.circleci/script_platform_io.sh - build-linux-gcc7: - machine: true - steps: - - checkout - - run: - name: Install dependencies - command: | - sudo apt-get remove cmake cmake-data - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test - sudo apt-add-repository -y ppa:george-edison55/cmake-3.x - sudo apt-get update - sudo apt-get -y install g++-7 gcc-7 lcov cmake - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7 - sudo update-alternatives --config gcc - - run: - name: Make scripts executable - command: sudo chmod -R +x ./.circleci/*.sh - - run: - name: Build - command: ./.circleci/script_desktop.sh - - run: - name: Codecov upload - command: bash <(curl -s https://codecov.io/bash) - build-linux-clang-5: - machine: true - steps: - - checkout - - run: - name: Install dependencies - command: | - sudo apt-get remove cmake cmake-data - sudo apt-add-repository -y "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" - sudo apt-add-repository -y ppa:george-edison55/cmake-3.x - sudo apt-get update - sudo apt install python-lldb-5.0 lcov cmake - sudo apt install clang-5.0 clang-tidy-5.0 clang-format-5.0 clang-5.0-doc libclang-common-5.0-dev libclang-5.0-dev libclang1-5.0 libllvm5.0 lldb-5.0 llvm-5.0 llvm-5.0-dev - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-5.0 60 - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 50 - sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-5.0 60 - sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 50 - - run: - name: Make scripts executable - command: sudo chmod -R +x ./.circleci/*.sh - - run: - name: Build - command: ./.circleci/script_desktop.sh - - run: - name: Clang Tidy - command: ./.circleci/clang_tidy.sh - - run: - name: Clang Format - command: ./.circleci/clang_format.sh - build-macos-9-2: - macos: - xcode: "9.2.0" - steps: - - checkout - - run: COMPILER=clang++ - - run: - name: Install dependencies - command: brew install cmake lcov - - run: - name: Make scripts executable - command: sudo chmod -R +x ./.circleci/*.sh - - run: - name: Build - command: ./.circleci/script_desktop.sh - build-macos-9-3: - macos: - xcode: "9.3.0" - steps: - - checkout - - run: - name: Install dependencies - command: brew install cmake lcov - - run: - name: Make scripts executable - command: sudo chmod -R +x ./.circleci/*.sh - - run: - name: Build - command: ./.circleci/script_desktop.sh workflows: version: 2 build: jobs: - build-arduino-default - - build-linux-default - - build-linux-gcc7 - - build-linux-clang-5 - - build-macos-9-2 - - build-macos-9-3 + diff --git a/.circleci/install_platform_io.sh b/.circleci/install_platform_io.sh deleted file mode 100644 index 080a666a..00000000 --- a/.circleci/install_platform_io.sh +++ /dev/null @@ -1,8 +0,0 @@ -# install PlatformIO -sudo pip install -U platformio - -# update PlatformIO -platformio update - -# ensure all git submodules have bee clone -git submodule update --init --recursive diff --git a/.circleci/platformio.cpp b/.circleci/platformio.cpp deleted file mode 100644 index 5b9fd3a5..00000000 --- a/.circleci/platformio.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -// This is a dummy prototype 'setup' & 'loop' for CI testing. -// This isn't intended for project or production use. -// It is only used in the 'pio run' command from root in CI; -// successful completion of which asserts that the ARK Cpp-Crypto library builds on its own. -#if (defined PLATFORMIO && !defined UNIT_TEST) - -#include - -void setup() {} -void loop() {} - -#endif diff --git a/.circleci/script_desktop.sh b/.circleci/script_desktop.sh deleted file mode 100644 index 1b353277..00000000 --- a/.circleci/script_desktop.sh +++ /dev/null @@ -1,12 +0,0 @@ -# run desktop builds -cmake . -DCMAKE_BUILD_TYPE=Coverage -cmake --build . - -# build examples -cd ./examples/cmake_example -cmake . -cmake --build . - -# run Gtest -cd ../../ -./test/Ark-Cpp-Crypto-tests diff --git a/.circleci/script_platform_io.sh b/.circleci/script_platform_io.sh deleted file mode 100644 index da9305f3..00000000 --- a/.circleci/script_platform_io.sh +++ /dev/null @@ -1,3 +0,0 @@ -# run PlatformIO builds -platformio run -platformio run -d ./test diff --git a/.clang-format b/.clang-format deleted file mode 100644 index d3f8d0c6..00000000 --- a/.clang-format +++ /dev/null @@ -1,117 +0,0 @@ ---- -Language: Cpp -# BasedOnStyle: Google -AccessModifierOffset: -1 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlines: Left -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: true -AllowShortLoopsOnASingleLine: true -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: true -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: true -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false - SplitEmptyFunction: true - SplitEmptyRecord: true - SplitEmptyNamespace: true -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Attach -BreakBeforeInheritanceComma: false -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: false -BreakConstructorInitializers: BeforeColon -BreakAfterJavaFieldAnnotations: false -BreakStringLiterals: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -CompactNamespaces: false -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: true -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -FixNamespaceComments: true -ForEachMacros: - - foreach - - Q_FOREACH - - BOOST_FOREACH -IncludeBlocks: Preserve -IncludeCategories: - - Regex: '^' - Priority: 2 - - Regex: '^<.*\.h>' - Priority: 1 - - Regex: '^<.*' - Priority: 2 - - Regex: '.*' - Priority: 3 -IncludeIsMainRegex: '([-_](test|unittest))?$' -IndentCaseLabels: true -IndentPPDirectives: None -IndentWidth: 2 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: false -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: false -PenaltyBreakAssignment: 2 -PenaltyBreakBeforeFirstCallParameter: 1 -PenaltyBreakComment: 300 -PenaltyBreakFirstLessLess: 120 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 200 -PointerAlignment: Left -RawStringFormats: - - Delimiter: pb - Language: TextProto - BasedOnStyle: google -ReflowComments: true -SortIncludes: true -SortUsingDeclarations: true -SpaceAfterCStyleCast: false -SpaceAfterTemplateKeyword: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 2 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Auto -TabWidth: 8 -UseTab: Never -... - diff --git a/.codecov.yml b/.codecov.yml deleted file mode 100644 index e43e15be..00000000 --- a/.codecov.yml +++ /dev/null @@ -1,4 +0,0 @@ -ignore: - - "src/lib" - - "test" - - "extras" diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index cce2097f..00000000 --- a/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "src/lib/uECC"] - path = src/lib/uECC - url = https://github.com/kmackay/micro-ecc -[submodule "test/lib/googletest"] - path = test/lib/googletest - url = https://github.com/google/googletest.git -[submodule "src/lib/ArduinoJson"] - path = src/lib/ArduinoJson - url = https://github.com/bblanchon/ArduinoJson -[submodule "src/lib/BIP66"] - path = src/lib/BIP66 - url = https://github.com/sleepdefic1t/BIP66 diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index f63af177..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,57 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(Ark-Cpp-Crypto) - -set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(CMAKE_CXX_STANDARD 11) - -set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) - -if (MSVC) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - -DNOMINMAX - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -endif() - -# clone submodules -execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -) - -# ------------------------------------------------------------------------------ -# Clang Tidy -# ------------------------------------------------------------------------------ - -if(ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN clang-tidy-5.0) - find_program(RUN_CLANG_TIDY_BIN run-clang-tidy-5.0.py) - - if(CLANG_TIDY_BIN STREQUAL "CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate clang-tidy-5.0") - endif() - - if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") - endif() - - list(APPEND RUN_CLANG_TIDY_BIN_ARGS - -clang-tidy-binary ${CLANG_TIDY_BIN} - "\"-header-filter=.*\\b(src|test|examples)\\b\\/(?!lib\/*).*\"" #Only run clang tidy on src, test, examples and skip 3rd party libraries - -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor,-cppcoreguidelines-* - ) - - add_custom_target( - tidy - COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS} - COMMENT "running clang tidy" - ) -endif() - -add_subdirectory(src) -add_subdirectory(test) - diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake deleted file mode 100644 index 71fd6b27..00000000 --- a/cmake/CodeCoverage.cmake +++ /dev/null @@ -1,204 +0,0 @@ -# Copyright (c) 2012 - 2015, Lars Bilke -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# -# -# 2012-01-31, Lars Bilke -# - Enable Code Coverage -# -# 2013-09-17, Joakim Söderberg -# - Added support for Clang. -# - Some additional usage instructions. -# -# USAGE: - -# 0. (Mac only) If you use Xcode 5.1 make sure to patch geninfo as described here: -# http://stackoverflow.com/a/22404544/80480 -# -# 1. Copy this file into your cmake modules path. -# -# 2. Add the following line to your CMakeLists.txt: -# INCLUDE(CodeCoverage) -# -# 3. Set compiler flags to turn off optimization and enable coverage: -# SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") -# SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage") -# -# 3. Use the function SETUP_TARGET_FOR_COVERAGE to create a custom make target -# which runs your test executable and produces a lcov code coverage report: -# Example: -# SETUP_TARGET_FOR_COVERAGE( -# my_coverage_target # Name for custom target. -# test_driver # Name of the test driver executable that runs the tests. -# # NOTE! This should always have a ZERO as exit code -# # otherwise the coverage generation will not complete. -# coverage # Name of output directory. -# ) -# -# 4. Build a Debug build: -# cmake -DCMAKE_BUILD_TYPE=Debug .. -# make -# make my_coverage_target -# -# - -# Check prereqs -FIND_PROGRAM( GCOV_PATH gcov ) -FIND_PROGRAM( LCOV_PATH lcov ) -FIND_PROGRAM( GENHTML_PATH genhtml ) -FIND_PROGRAM( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/tests) - -IF(NOT GCOV_PATH) - MESSAGE(FATAL_ERROR "gcov not found! Aborting...") -ENDIF() # NOT GCOV_PATH - -IF("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") - IF("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3) - MESSAGE(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") - ENDIF() -ELSEIF(NOT CMAKE_COMPILER_IS_GNUCXX) - MESSAGE(FATAL_ERROR "Compiler is not GNU gcc! Aborting...") -ENDIF() # CHECK VALID COMPILER - -SET(CMAKE_CXX_FLAGS_COVERAGE - "-g -O0 --coverage -fprofile-arcs -ftest-coverage" - CACHE STRING "Flags used by the C++ compiler during coverage builds." - FORCE ) -SET(CMAKE_C_FLAGS_COVERAGE - "-g -O0 --coverage -fprofile-arcs -ftest-coverage" - CACHE STRING "Flags used by the C compiler during coverage builds." - FORCE ) -SET(CMAKE_EXE_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used for linking binaries during coverage builds." - FORCE ) -SET(CMAKE_SHARED_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used by the shared libraries linker during coverage builds." - FORCE ) -MARK_AS_ADVANCED( - CMAKE_CXX_FLAGS_COVERAGE - CMAKE_C_FLAGS_COVERAGE - CMAKE_EXE_LINKER_FLAGS_COVERAGE - CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) - -IF ( NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "Coverage")) - MESSAGE( WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" ) -ENDIF() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug" - - -# Param _targetname The name of new the custom make target -# Param _testrunner The name of the target which runs the tests. -# MUST return ZERO always, even on errors. -# If not, no coverage report will be created! -# Param _outputname lcov output is generated as _outputname.info -# HTML report is generated in _outputname/index.html -# Optional fourth parameter is passed as arguments to _testrunner -# Pass them in list form, e.g.: "-j;2" for -j 2 -FUNCTION(SETUP_TARGET_FOR_COVERAGE _targetname _testrunner _outputname) - - IF(NOT LCOV_PATH) - MESSAGE(FATAL_ERROR "lcov not found! Aborting...") - ENDIF() # NOT LCOV_PATH - - IF(NOT GENHTML_PATH) - MESSAGE(FATAL_ERROR "genhtml not found! Aborting...") - ENDIF() # NOT GENHTML_PATH - - SET(coverage_info "${CMAKE_BINARY_DIR}/${_outputname}.info") - SET(coverage_cleaned "${coverage_info}.cleaned") - - SEPARATE_ARGUMENTS(test_command UNIX_COMMAND "${_testrunner}") - - # Setup target - ADD_CUSTOM_TARGET(${_targetname} - - # Cleanup lcov - ${LCOV_PATH} --directory . --zerocounters - - # Run tests - COMMAND ${test_command} ${ARGV3} - - COMMAND lcov --version - COMMAND gcov --version - COMMAND g++ --version - - # Capturing lcov counters and generating report - COMMAND ${LCOV_PATH} --directory . --base-directory . --capture --output-file coverage.info - COMMAND ${LCOV_PATH} --remove coverage.info '/usr*' '*/test/*' '*/ext/*' -o coverage.info - - #COMMAND ${LCOV_PATH} --directory . --capture --output-file ${coverage_info} - #COMMAND ${LCOV_PATH} --remove ${coverage_info} 'tests/*' '/usr/*' --output-file ${coverage_cleaned} - #COMMAND ${GENHTML_PATH} -o ${_outputname} ${coverage_cleaned} - #COMMAND ${CMAKE_COMMAND} -E remove ${coverage_info} ${coverage_cleaned} - - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." - ) - - # Show info where to find the report - #ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD - # COMMAND ; - # COMMENT "Open ./${_outputname}/index.html in your browser to view the coverage report." - #) - -ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE - -# Param _targetname The name of new the custom make target -# Param _testrunner The name of the target which runs the tests -# Param _outputname cobertura output is generated as _outputname.xml -# Optional fourth parameter is passed as arguments to _testrunner -# Pass them in list form, e.g.: "-j;2" for -j 2 -FUNCTION(SETUP_TARGET_FOR_COVERAGE_COBERTURA _targetname _testrunner _outputname) - - IF(NOT PYTHON_EXECUTABLE) - MESSAGE(FATAL_ERROR "Python not found! Aborting...") - ENDIF() # NOT PYTHON_EXECUTABLE - - IF(NOT GCOVR_PATH) - MESSAGE(FATAL_ERROR "gcovr not found! Aborting...") - ENDIF() # NOT GCOVR_PATH - - ADD_CUSTOM_TARGET(${_targetname} - - # Run tests - ${_testrunner} ${ARGV3} - - # Running gcovr - COMMAND ${GCOVR_PATH} -x -r ${CMAKE_SOURCE_DIR} -e '${CMAKE_SOURCE_DIR}/tests/' -o ${_outputname}.xml - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Running gcovr to produce Cobertura code coverage report." - ) - - # Show info where to find the report - ADD_CUSTOM_COMMAND(TARGET ${_targetname} POST_BUILD - COMMAND ; - COMMENT "Cobertura code coverage report saved in ${_outputname}.xml." - ) - -ENDFUNCTION() # SETUP_TARGET_FOR_COVERAGE_COBERTURA diff --git a/examples/arduino/ESP32/ESP32.ino b/examples/ESP32/ESP32.ino similarity index 100% rename from examples/arduino/ESP32/ESP32.ino rename to examples/ESP32/ESP32.ino diff --git a/examples/arduino/ESP8266/ESP8266.ino b/examples/ESP8266/ESP8266.ino similarity index 100% rename from examples/arduino/ESP8266/ESP8266.ino rename to examples/ESP8266/ESP8266.ino diff --git a/examples/cmake_example/.gitmodules b/examples/cmake_example/.gitmodules deleted file mode 100644 index 8ed2845c..00000000 --- a/examples/cmake_example/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "lib/cpp-crypto"] - path = lib/cpp-crypto - url = https://github.com/ArkEcosystem/cpp-crypto.git diff --git a/examples/cmake_example/CMakeLists.txt b/examples/cmake_example/CMakeLists.txt deleted file mode 100644 index c1834a43..00000000 --- a/examples/cmake_example/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -cmake_minimum_required(VERSION 3.2) -project(Cpp-Crypto-Example) - -set(CMAKE_CXX_STANDARD 11) - -set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) - -if (MSVC) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - -DNOMINMAX - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") -endif() - -# clone submodules -execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} -) - -add_subdirectory(lib/cpp-crypto/src) - -set(SOURCE_FILES main.cpp) - -add_executable(${PROJECT_NAME} ${SOURCE_FILES}) -target_link_libraries(${PROJECT_NAME} Ark-Cpp-Crypto-lib) - diff --git a/examples/cmake_example/CMakeSettings.json b/examples/cmake_example/CMakeSettings.json deleted file mode 100644 index 4ecdae92..00000000 --- a/examples/cmake_example/CMakeSettings.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "configurations": [ - { - "name": "x86-Debug", - "generator": "Visual Studio 15 2017", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x86" ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - }, - { - "name": "x86-Release", - "generator": "Visual Studio 15 2017", - "configurationType": "Release", - "inheritEnvironments": [ "msvc_x86" ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - }, - { - "name": "x64-Debug", - "generator": "Visual Studio 15 2017 Win64", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - }, - { - "name": "x64-Release", - "generator": "Visual Studio 15 2017 Win64", - "configurationType": "Release", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "" - }, - { - "name": "Linux-Debug", - "generator": "Unix Makefiles", - "remoteMachineName": "${defaultRemoteMachineName}", - "configurationType": "Debug", - "remoteCMakeListsRoot": "/var/tmp/src/${workspaceHash}/${name}", - "cmakeExecutable": "/usr/local/bin/cmake", - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "remoteBuildRoot": "/var/tmp/build/${workspaceHash}/build/${name}", - "remoteInstallRoot": "/var/tmp/build/${workspaceHash}/install/${name}", - "remoteCopySources": true, - "remoteCopySourcesOutputVerbosity": "Normal", - "remoteCopySourcesConcurrentCopies": "10", - "remoteCopySourcesMethod": "sftp", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "linux-x64" ] - }, - { - "name": "Linux-Release", - "generator": "Unix Makefiles", - "remoteMachineName": "${defaultRemoteMachineName}", - "configurationType": "Release", - "remoteCMakeListsRoot": "/var/tmp/src/${workspaceHash}/${name}", - "cmakeExecutable": "/usr/local/bin/cmake", - "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}", - "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}", - "remoteBuildRoot": "/var/tmp/build/${workspaceHash}/build/${name}", - "remoteInstallRoot": "/var/tmp/build/${workspaceHash}/install/${name}", - "remoteCopySources": true, - "remoteCopySourcesOutputVerbosity": "Normal", - "remoteCopySourcesConcurrentCopies": "10", - "remoteCopySourcesMethod": "sftp", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "inheritEnvironments": [ "linux-x64" ] - } - ] -} \ No newline at end of file diff --git a/examples/cmake_example/lib/put-cpp-crypto-folder-here b/examples/cmake_example/lib/put-cpp-crypto-folder-here deleted file mode 100644 index e69de29b..00000000 diff --git a/examples/cmake_example/main.cpp b/examples/cmake_example/main.cpp deleted file mode 100644 index b42f2bac..00000000 --- a/examples/cmake_example/main.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "arkCrypto.h" - -#include -#include -#include -#include - -int main(int argc, char* argv[]) { - const auto text = "Computer science is no more about computers than astronomy is about telescopes."; - const auto passphrase = "viable weasel wage promote praise inflict jaguar tackle color unusual exclude direct"; - - // Message - sign - Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - - std::cout << "Message\n"; - std::cout << "\tText: " << text << '\n'; - std::cout << "\tPassphrase: " << passphrase << '\n'; - std::cout << "\tJson: " << message.toJson() << '\n'; - std::cout << '\n'; - - // Message - verify - auto publicKey = PublicKey::fromHex("0275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a456"); - auto signature = HexToBytes("3044022021704f2adb2e4a10a3ddc1d7d64552b8061c05f6d12a168c69091c75581d611402200edf37689d2786fc690af9f0f6fa1f629c95695039f648a6d455484302402e93"); - - message = Ark::Crypto::Utils::Message( - text, - publicKey, - signature - ); - - std::cout << "Message\n"; - std::cout << "\tJson: " << message.toJson() << '\n'; - std::cout << "\tVerified: " << std::boolalpha << message.verify() << '\n'; - std::cout << '\n'; - - // Address - from passphrase - const uint8_t networkVersion = 0x1E; - auto address = Address::fromPassphrase(passphrase, networkVersion); - std::cout << "Address from passphrase\n"; - std::cout << "\tPassphrase: " << passphrase << '\n'; - std::cout << "\tNetwork Version: 0x" << std::hex << static_cast(networkVersion) << '\n'; - std::cout << "\tAddress: " << address.toString() << '\n'; - std::cout << '\n'; - - // Address - from publickey - publicKey = PublicKey("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); - address = Address::fromPublicKey(publicKey, networkVersion); - std::cout << "Address from public key\n"; - std::cout << "\tPublic Key: " << publicKey.toString() << '\n'; - std::cout << "\tAddress: " << address.toString() << '\n'; - std::cout << '\n'; - - // Address - from privatekey - PrivateKey privateKey("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); - address = Address::fromPrivateKey(privateKey, networkVersion); - std::cout << "Address from private key\n"; - std::cout << "\tPrivate Key: " << privateKey.toString() << '\n'; - std::cout << "\tAddress: " << address.toString() << '\n'; - std::cout << '\n'; - - // Address - validate - address = Address("DStZXkgpEjxbG355nQ26vnkp95p24U9tsV"); - auto isValidAddress = Address::validate(address, networkVersion); - std::cout << "Valid Address\n"; - std::cout << "\tAddress: " << address.toString() << '\n'; - std::cout << "\t Valid Address: " << std::boolalpha << isValidAddress << '\n'; - std::cout << '\n'; - - // Private Key - from passphrase - privateKey = PrivateKey::fromPassphrase(passphrase); - std::cout << "Private Key from passprase\n"; - std::cout << "\tPassphrase: " << passphrase << '\n'; - std::cout << "\tPrivate Key: " << privateKey.toString() << '\n'; - std::cout << '\n'; - - // Private Key - object from hex - privateKey = PrivateKey::fromHex("950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021"); - std::cout << "Private Key from hex\n"; - std::cout << "\tHex: 950981ce17df662dbc1d25305f8597a71309fb8f7232203a0944477e2534b021\n"; - std::cout << "\tPrivate Key: " << privateKey.toString() << '\n'; - std::cout << '\n'; - - // Public Key - from passphrase - publicKey = PublicKey::fromPassphrase(passphrase); - std::cout << "Public Key from passprase\n"; - std::cout << "\tPassphrase: " << passphrase << '\n'; - std::cout << "\tPublic Key: " << publicKey.toString() << '\n'; - std::cout << '\n'; - - // Public Key - object from hex - publicKey = PublicKey::fromHex("029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4"); - std::cout << "Public Key from hex\n"; - std::cout << "\tHex: 029fdf41a7d69d8efc7b236c21b9509a23d862ea4ed8b13a56e31eee58dbfd97b4\n"; - std::cout << "\tPublic Key: " << publicKey.toString() << '\n'; - std::cout << '\n'; - - // WIF - from passphrase - const uint8_t wifByte = 0xaa; - auto wif = WIF::fromPassphrase(passphrase, wifByte); - std::cout << "WIF from passphrase\n"; - std::cout << "\tPassphrase: " << passphrase << '\n'; - std::cout << "\tWIF Byte: 0x" << std::hex << static_cast(wifByte) << '\n'; - std::cout << "\tWIF: " << wif.toString() << std::endl; - - return 0; -} diff --git a/examples/platformio_example/platformio.ini b/examples/platformio_example/platformio.ini deleted file mode 100644 index 10720046..00000000 --- a/examples/platformio_example/platformio.ini +++ /dev/null @@ -1,26 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html - - -[platformio] - -[env:esp8266] -lib_deps = Ark-Cpp-Crypto -platform = espressif8266 -board = huzzah -framework = arduino -upload_speed = 921600 - -[env:esp32] -lib_deps = Ark-Cpp-Crypto -platform = espressif32 -board = esp32dev -framework = arduino -upload_speed = 921600 diff --git a/examples/platformio_example/src/main.ino b/examples/platformio_example/src/main.ino deleted file mode 100644 index c6eee361..00000000 --- a/examples/platformio_example/src/main.ino +++ /dev/null @@ -1,114 +0,0 @@ -#include "arkCrypto.h" - -#include -#include -#include - -#include - -void setup() { - Serial.begin(115200); - - while (!Serial) { delay(100); }; - // ^for the Arduino Leonardo/Micro only -} - -void loop() { - const auto text = "Hello World"; - const auto passphrase = "this is a top secret passphrase"; - - // Message - sign - Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - - Serial.println("Message"); - Serial.print("\tText: "); Serial.print(text); Serial.println(); - Serial.print("\tPassphrase: "); Serial.print(passphrase); Serial.println(); - Serial.print("\tJson: "); Serial.print(message.toJson().c_str()); Serial.println(); - Serial.println(); - - // Message - verify - auto publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - auto signature = HexToBytes("304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"); - - message = Ark::Crypto::Utils::Message( - text, - publicKey, - signature - ); - - Serial.println("Message"); - Serial.print("\tJson: "); Serial.print(message.toJson().c_str()); Serial.println(); - Serial.print("\tVerified: "); Serial.print(message.verify()); Serial.println(); - Serial.println(); - - // Address - from passphrase - const uint8_t networkVersion = 0x1E; - auto address = Address::fromPassphrase(passphrase, networkVersion); - Serial.println("Address from passphrase"); - Serial.print("\tPassphrase: "); Serial.print(passphrase); Serial.println(); - Serial.print("\tNetwork Version: 0x"); Serial.print(static_cast(networkVersion)); Serial.println(); - Serial.print("\tAddress: "); Serial.print(address.toString().c_str()); Serial.println(); - Serial.println(); - - // Address - from publickey - publicKey = PublicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - address = Address::fromPublicKey(publicKey, networkVersion); - Serial.println("Address from public key"); - Serial.print("\tPublic Key: "); Serial.print(publicKey.toString().c_str()); Serial.println(); - Serial.print("\tAddress: "); Serial.print(address.toString().c_str()); Serial.println(); - Serial.println(); - - // Address - from privatekey - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - address = Address::fromPrivateKey(privateKey, networkVersion); - Serial.println("Address from private key"); - Serial.print("\tPrivate Key: "); Serial.print(privateKey.toString().c_str()); Serial.println(); - Serial.print("\tAddress: "); Serial.print(address.toString().c_str()); Serial.println(); - Serial.println(); - - // Address - validate - address = Address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); - auto isValidAddress = Address::validate(address, networkVersion); - Serial.println("Valid Address"); - Serial.print("\tAddress: "); Serial.print(address.toString().c_str()); Serial.println(); - Serial.print("\t Valid Address: "); Serial.print(isValidAddress); Serial.println(); - Serial.println(); - - // Private Key - from passphrase - privateKey = PrivateKey::fromPassphrase(passphrase); - Serial.println("Private Key from passprase"); - Serial.print("\tPassphrase: "); Serial.print(passphrase); Serial.println(); - Serial.print("\tPrivate Key: "); Serial.print(privateKey.toString().c_str()); Serial.println(); - Serial.println(); - - // Private Key - object from hex - privateKey = PrivateKey::fromHex("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - Serial.println("Private Key from hex"); - Serial.println("\tHex: d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - Serial.print("\tPrivate Key: "); Serial.print(privateKey.toString().c_str()); Serial.println(); - Serial.println(); - - // Public Key - from passphrase - publicKey = PublicKey::fromPassphrase(passphrase); - Serial.println("Public Key from passprase"); - Serial.print("\tPassphrase: "); Serial.print(passphrase); Serial.println(); - Serial.print("\tPublic Key: "); Serial.print(publicKey.toString().c_str()); Serial.println(); - Serial.println(); - - // Public Key - object from hex - publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - Serial.println("Public Key from hex"); - Serial.println("\tHex: 034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - Serial.print("\tPublic Key: "); Serial.print(publicKey.toString().c_str()); Serial.println(); - Serial.println(); - - // WIF - from passphrase - const uint8_t wifByte = 0xaa; - auto wif = WIF::fromPassphrase(passphrase, wifByte); - Serial.println("WIF from passphrase"); - Serial.print("\tPassphrase: "); Serial.print(passphrase); Serial.println(); - Serial.print("\tWIF Byte: "); Serial.print(static_cast(wifByte)); Serial.println(); - Serial.print("\tWIF: "); Serial.print(wif.toString().c_str()); Serial.println(); - -} diff --git a/docs/INSTALL_ARDUINO.MD b/extras/docs/INSTALL_ARDUINO.md similarity index 100% rename from docs/INSTALL_ARDUINO.MD rename to extras/docs/INSTALL_ARDUINO.md diff --git a/docs/INSTALL_OS.md b/extras/docs/INSTALL_OS.md similarity index 100% rename from docs/INSTALL_OS.md rename to extras/docs/INSTALL_OS.md diff --git a/docs/INSTALL_PLATFORMIO.md b/extras/docs/INSTALL_PLATFORMIO.md similarity index 100% rename from docs/INSTALL_PLATFORMIO.md rename to extras/docs/INSTALL_PLATFORMIO.md diff --git a/docs/cpp.md b/extras/docs/cpp.md similarity index 100% rename from docs/cpp.md rename to extras/docs/cpp.md diff --git a/lib/readme.txt b/lib/readme.txt deleted file mode 100644 index 131f1bfd..00000000 --- a/lib/readme.txt +++ /dev/null @@ -1,41 +0,0 @@ - -This directory is intended for the project specific (private) libraries. -PlatformIO will compile them to static libraries and link to executable file. - -The source code of each library should be placed in separate directory, like -"lib/private_lib/[here are source files]". - -For example, see how can be organized `Foo` and `Bar` libraries: - -|--lib -| | -| |--Bar -| | |--docs -| | |--examples -| | |--src -| | |- Bar.c -| | |- Bar.h -| | |- library.json (optional, custom build options, etc) http://docs.platformio.org/page/librarymanager/config.html -| | -| |--Foo -| | |- Foo.c -| | |- Foo.h -| | -| |- readme.txt --> THIS FILE -| -|- platformio.ini -|--src - |- main.c - -Then in `src/main.c` you should use: - -#include -#include - -// rest H/C/CPP code - -PlatformIO will find your libraries automatically, configure preprocessor's -include paths and build them. - -More information about PlatformIO Library Dependency Finder -- http://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini deleted file mode 100644 index 487f4469..00000000 --- a/platformio.ini +++ /dev/null @@ -1,39 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html - -[platformio] -description = "A simple Cryptography Implementation in C++ for the ARK Blockchain." -build_dir = .pio/.pioenvs -libdeps_dir = .pio/.piolibdeps - -[common] -lib_deps = micro-ecc, ArduinoJson@6.10.0, BIP66 -build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> +<../.circleci/platformio.cpp> -upload_speed = 921600 - -[env:esp8266] -platform = espressif8266 -board = huzzah -framework = arduino -lib_deps = ${common.lib_deps} -build_flags = ${common.build_flags} -src_filter = ${common.src_filter} -upload_speed = ${common.upload_speed} - -[env:esp32] -platform = espressif32 -board = esp32dev -framework = arduino -lib_deps = ${common.lib_deps} -build_flags = ${common.build_flags} -src_filter = ${common.src_filter} -upload_speed = ${common.upload_speed} - diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 4ce31358..00000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,75 +0,0 @@ - -cmake_minimum_required(VERSION 3.2.2) - -project(Ark-Cpp-Crypto-lib C CXX) - -set(BIP66_SRC - ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp -) - -set(BCL_SRC - lib/bcl/Base58Check.cpp - lib/bcl/CurvePoint.cpp - lib/bcl/Ecdsa.cpp - lib/bcl/FieldInt.cpp - lib/bcl/Ripemd160.cpp - lib/bcl/Sha256Hash.cpp - lib/bcl/Sha256.cpp - lib/bcl/Sha512.cpp - lib/bcl/Uint256.cpp - lib/bcl/Utils.cpp -) - -set(uECC_SRC - lib/uECC/uECC.c -) - -set(COMMON_SRC - common/configuration.cpp - common/network.cpp - defaults/static_fees.cpp - helpers/crypto.cpp - identities/address.cpp - identities/privatekey.cpp - identities/publickey.cpp - identities/wif.cpp - managers/fee_manager.cpp - managers/network_manager.cpp - networks/devnet.cpp - networks/mainnet.cpp - networks/testnet.cpp - transactions/builder.cpp - transactions/deserializer.cpp - transactions/serializer.cpp - transactions/transaction.cpp - utils/message.cpp - utils/slot.cpp -) - -add_library(${PROJECT_NAME} STATIC - ${BCL_SRC} - ${uECC_SRC} - ${BIP66_SRC} - ${COMMON_SRC} -) - -set(cpp_crypto_build_include_dirs - ${PROJECT_SOURCE_DIR} - ${PROJECT_SOURCE_DIR}/include/cpp-crypto -) - -include_directories(${cpp_crypto_build_include_dirs}) -include_directories(${PROJECT_SOURCE_DIR}/lib/) -include_directories(${PROJECT_SOURCE_DIR}/lib/ArduinoJson) -include_directories(${PROJECT_SOURCE_DIR}/lib/bcl) -include_directories(${PROJECT_SOURCE_DIR}/lib/rfc6979) -include_directories(${PROJECT_SOURCE_DIR}/lib/uECC) -include_directories(${PROJECT_SOURCE_DIR}/lib/BIP66/src) - -target_include_directories( ${PROJECT_NAME} PUBLIC - ${cpp_crypto_build_include_dirs} -) - -if (MSVC) - target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) -endif() diff --git a/src/include/cpp-crypto/arkCrypto.h b/src/arkCrypto.h similarity index 100% rename from src/include/cpp-crypto/arkCrypto.h rename to src/arkCrypto.h diff --git a/src/lib/bcl/Base58Check.cpp b/src/bcl/Base58Check.cpp similarity index 100% rename from src/lib/bcl/Base58Check.cpp rename to src/bcl/Base58Check.cpp diff --git a/src/lib/bcl/Base58Check.hpp b/src/bcl/Base58Check.hpp similarity index 100% rename from src/lib/bcl/Base58Check.hpp rename to src/bcl/Base58Check.hpp diff --git a/src/lib/bcl/CurvePoint.cpp b/src/bcl/CurvePoint.cpp similarity index 100% rename from src/lib/bcl/CurvePoint.cpp rename to src/bcl/CurvePoint.cpp diff --git a/src/lib/bcl/CurvePoint.hpp b/src/bcl/CurvePoint.hpp similarity index 100% rename from src/lib/bcl/CurvePoint.hpp rename to src/bcl/CurvePoint.hpp diff --git a/src/lib/bcl/Ecdsa.cpp b/src/bcl/Ecdsa.cpp similarity index 100% rename from src/lib/bcl/Ecdsa.cpp rename to src/bcl/Ecdsa.cpp diff --git a/src/lib/bcl/Ecdsa.hpp b/src/bcl/Ecdsa.hpp similarity index 100% rename from src/lib/bcl/Ecdsa.hpp rename to src/bcl/Ecdsa.hpp diff --git a/src/lib/bcl/FieldInt.cpp b/src/bcl/FieldInt.cpp similarity index 100% rename from src/lib/bcl/FieldInt.cpp rename to src/bcl/FieldInt.cpp diff --git a/src/lib/bcl/FieldInt.hpp b/src/bcl/FieldInt.hpp similarity index 100% rename from src/lib/bcl/FieldInt.hpp rename to src/bcl/FieldInt.hpp diff --git a/src/lib/bcl/Ripemd160.cpp b/src/bcl/Ripemd160.cpp similarity index 100% rename from src/lib/bcl/Ripemd160.cpp rename to src/bcl/Ripemd160.cpp diff --git a/src/lib/bcl/Ripemd160.hpp b/src/bcl/Ripemd160.hpp similarity index 100% rename from src/lib/bcl/Ripemd160.hpp rename to src/bcl/Ripemd160.hpp diff --git a/src/lib/bcl/Sha256.cpp b/src/bcl/Sha256.cpp similarity index 100% rename from src/lib/bcl/Sha256.cpp rename to src/bcl/Sha256.cpp diff --git a/src/lib/bcl/Sha256.hpp b/src/bcl/Sha256.hpp similarity index 100% rename from src/lib/bcl/Sha256.hpp rename to src/bcl/Sha256.hpp diff --git a/src/lib/bcl/Sha256Hash.cpp b/src/bcl/Sha256Hash.cpp similarity index 100% rename from src/lib/bcl/Sha256Hash.cpp rename to src/bcl/Sha256Hash.cpp diff --git a/src/lib/bcl/Sha256Hash.hpp b/src/bcl/Sha256Hash.hpp similarity index 100% rename from src/lib/bcl/Sha256Hash.hpp rename to src/bcl/Sha256Hash.hpp diff --git a/src/lib/bcl/Sha512.cpp b/src/bcl/Sha512.cpp similarity index 100% rename from src/lib/bcl/Sha512.cpp rename to src/bcl/Sha512.cpp diff --git a/src/lib/bcl/Sha512.hpp b/src/bcl/Sha512.hpp similarity index 100% rename from src/lib/bcl/Sha512.hpp rename to src/bcl/Sha512.hpp diff --git a/src/lib/bcl/Uint256.cpp b/src/bcl/Uint256.cpp similarity index 100% rename from src/lib/bcl/Uint256.cpp rename to src/bcl/Uint256.cpp diff --git a/src/lib/bcl/Uint256.hpp b/src/bcl/Uint256.hpp similarity index 100% rename from src/lib/bcl/Uint256.hpp rename to src/bcl/Uint256.hpp diff --git a/src/lib/bcl/Utils.cpp b/src/bcl/Utils.cpp similarity index 100% rename from src/lib/bcl/Utils.cpp rename to src/bcl/Utils.cpp diff --git a/src/lib/bcl/Utils.hpp b/src/bcl/Utils.hpp similarity index 100% rename from src/lib/bcl/Utils.hpp rename to src/bcl/Utils.hpp diff --git a/src/include/cpp-crypto/common/configuration.hpp b/src/common/configuration.hpp similarity index 100% rename from src/include/cpp-crypto/common/configuration.hpp rename to src/common/configuration.hpp diff --git a/src/include/cpp-crypto/common/fee_policy.hpp b/src/common/fee_policy.hpp similarity index 100% rename from src/include/cpp-crypto/common/fee_policy.hpp rename to src/common/fee_policy.hpp diff --git a/src/include/cpp-crypto/common/network.hpp b/src/common/network.hpp similarity index 100% rename from src/include/cpp-crypto/common/network.hpp rename to src/common/network.hpp diff --git a/src/lib/date/date.h b/src/date/date.h similarity index 100% rename from src/lib/date/date.h rename to src/date/date.h diff --git a/src/include/cpp-crypto/defaults/fee_policies.hpp b/src/defaults/fee_policies.hpp similarity index 100% rename from src/include/cpp-crypto/defaults/fee_policies.hpp rename to src/defaults/fee_policies.hpp diff --git a/src/include/cpp-crypto/defaults/static_fees.hpp b/src/defaults/static_fees.hpp similarity index 100% rename from src/include/cpp-crypto/defaults/static_fees.hpp rename to src/defaults/static_fees.hpp diff --git a/src/include/cpp-crypto/defaults/transaction_types.hpp b/src/defaults/transaction_types.hpp similarity index 100% rename from src/include/cpp-crypto/defaults/transaction_types.hpp rename to src/defaults/transaction_types.hpp diff --git a/src/include/cpp-crypto/helpers/encoding/hex.h b/src/helpers/encoding/hex.h similarity index 100% rename from src/include/cpp-crypto/helpers/encoding/hex.h rename to src/helpers/encoding/hex.h diff --git a/src/include/cpp-crypto/identities/address.h b/src/identities/address.h similarity index 100% rename from src/include/cpp-crypto/identities/address.h rename to src/identities/address.h diff --git a/src/include/cpp-crypto/identities/privatekey.h b/src/identities/privatekey.h similarity index 100% rename from src/include/cpp-crypto/identities/privatekey.h rename to src/identities/privatekey.h diff --git a/src/include/cpp-crypto/identities/publickey.h b/src/identities/publickey.h similarity index 100% rename from src/include/cpp-crypto/identities/publickey.h rename to src/identities/publickey.h diff --git a/src/include/cpp-crypto/identities/wif.h b/src/identities/wif.h similarity index 100% rename from src/include/cpp-crypto/identities/wif.h rename to src/identities/wif.h diff --git a/src/lib/ArduinoJson b/src/lib/ArduinoJson deleted file mode 160000 index 1c814d3b..00000000 --- a/src/lib/ArduinoJson +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1c814d3bb657752d29a342ef20ce8074f8cde5d7 diff --git a/src/lib/BIP66 b/src/lib/BIP66 deleted file mode 160000 index 5f024b4b..00000000 --- a/src/lib/BIP66 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5f024b4b70fb0d267da483304afb72bb884413cb diff --git a/src/lib/uECC b/src/lib/uECC deleted file mode 160000 index 601bd110..00000000 --- a/src/lib/uECC +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 601bd11062c551b108adbb43ba99f199b840777c diff --git a/src/include/cpp-crypto/networks/devnet.hpp b/src/networks/devnet.hpp similarity index 100% rename from src/include/cpp-crypto/networks/devnet.hpp rename to src/networks/devnet.hpp diff --git a/src/include/cpp-crypto/networks/mainnet.hpp b/src/networks/mainnet.hpp similarity index 100% rename from src/include/cpp-crypto/networks/mainnet.hpp rename to src/networks/mainnet.hpp diff --git a/src/include/cpp-crypto/networks/networks.hpp b/src/networks/networks.hpp similarity index 100% rename from src/include/cpp-crypto/networks/networks.hpp rename to src/networks/networks.hpp diff --git a/src/include/cpp-crypto/networks/testnet.hpp b/src/networks/testnet.hpp similarity index 100% rename from src/include/cpp-crypto/networks/testnet.hpp rename to src/networks/testnet.hpp diff --git a/src/lib/rfc6979/rfc6979.h b/src/rfc6979/rfc6979.h similarity index 100% rename from src/lib/rfc6979/rfc6979.h rename to src/rfc6979/rfc6979.h diff --git a/src/include/cpp-crypto/transactions/builder.h b/src/transactions/builder.h similarity index 100% rename from src/include/cpp-crypto/transactions/builder.h rename to src/transactions/builder.h diff --git a/src/include/cpp-crypto/transactions/deserializer.h b/src/transactions/deserializer.h similarity index 100% rename from src/include/cpp-crypto/transactions/deserializer.h rename to src/transactions/deserializer.h diff --git a/src/include/cpp-crypto/transactions/serializer.h b/src/transactions/serializer.h similarity index 100% rename from src/include/cpp-crypto/transactions/serializer.h rename to src/transactions/serializer.h diff --git a/src/include/cpp-crypto/transactions/transaction.h b/src/transactions/transaction.h similarity index 100% rename from src/include/cpp-crypto/transactions/transaction.h rename to src/transactions/transaction.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt deleted file mode 100644 index 668d43ba..00000000 --- a/test/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -cmake_minimum_required(VERSION 3.2.2) - -project(Ark-Cpp-Crypto-tests C CXX) - -add_subdirectory(lib/googletest) - -include(CTest) -enable_testing() - -set (PROJECT_INCLUDE_DIR ${PROJECT_SOURCE_DIR}/../include) -set (PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../lib") - -include_directories(${PROJECT_SOURCE_DIR}/../src) -include_directories(${PROJECT_SOURCE_DIR}/../src/lib) -include_directories(${PROJECT_SOURCE_DIR}/../src/lib/ArduinoJson) -include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) - -set (TEST_SRC - ${PROJECT_SOURCE_DIR}/common/configuration.cpp - ${PROJECT_SOURCE_DIR}/common/fee_policy.cpp - ${PROJECT_SOURCE_DIR}/common/network.cpp - ${PROJECT_SOURCE_DIR}/defaults/static_fees.cpp - ${PROJECT_SOURCE_DIR}/defaults/transaction_types.cpp - ${PROJECT_SOURCE_DIR}/helpers/crypto_helpers.cpp - ${PROJECT_SOURCE_DIR}/helpers/crypto.cpp - ${PROJECT_SOURCE_DIR}/helpers/encoding/hex.cpp - ${PROJECT_SOURCE_DIR}/identities/address.cpp - ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp - ${PROJECT_SOURCE_DIR}/identities/publickey.cpp - ${PROJECT_SOURCE_DIR}/identities/wif.cpp - ${PROJECT_SOURCE_DIR}/managers/fee_manager.cpp - ${PROJECT_SOURCE_DIR}/managers/network_manager.cpp - ${PROJECT_SOURCE_DIR}/networks/devnet.cpp - ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp - ${PROJECT_SOURCE_DIR}/networks/testnet.cpp - ${PROJECT_SOURCE_DIR}/transactions/builder.cpp - ${PROJECT_SOURCE_DIR}/transactions/deserializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/serializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/transaction.cpp - ${PROJECT_SOURCE_DIR}/utils/message.cpp - ${PROJECT_SOURCE_DIR}/utils/slot.cpp -) - -find_library(Ark-Cpp-Crypto-tests PUBLIC) - -add_executable(Ark-Cpp-Crypto-tests ${TEST_SRC}) - -target_link_libraries(Ark-Cpp-Crypto-tests Ark-Cpp-Crypto-lib gtest gtest_main) - -add_test(NAME test COMMAND Ark-Cpp-Crypto-tests) - -if (CMAKE_BUILD_TYPE STREQUAL "Coverage") - include("${CMAKE_SOURCE_DIR}/cmake/CodeCoverage.cmake") - - setup_target_for_coverage(${PROJECT_NAME}_coverage Ark-Cpp-Crypto-tests coverage) - - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") -endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" diff --git a/test/common/configuration.cpp b/test/common/configuration.cpp deleted file mode 100644 index f0ea4e6d..00000000 --- a/test/common/configuration.cpp +++ /dev/null @@ -1,134 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -#include - -namespace { -static const Network kDefaultNetwork = Networks::Devnet(); -static const Network kCustomNetwork = { // random parameters - "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", - 1, 0x53, 0xaa, - "2019-04-12T13:00:00.000Z" -}; -/**/ -static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); -static const FeePolicy kCustomFeePolicy = { - 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, - 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL -}; -static const uint64_t kTestAmount = 1000000000ULL; -/**/ -static const Configuration kDefaultConfiguration = Configuration(); -static const Configuration kCustomFeeConfiguration(kCustomFeePolicy); -static const Configuration kCustomNetworkConfiguration(kCustomNetwork); -static const Configuration kCustomConfiguration(kCustomNetwork, - kCustomFeePolicy); -} //namespace - -/**/ - -//* -TEST(common, configuration_constructor_default) { - Configuration config; - bool isMatching = kDefaultConfiguration == config; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_constructor_network) { - Configuration config(kCustomNetwork); - bool isMatching = kCustomNetworkConfiguration == config; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_constructor_fee) { - Configuration config(kCustomFeePolicy); - bool isMatching = kCustomFeeConfiguration == config; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_constructor_with_network_and_fee) { - Configuration config(kCustomNetwork, kCustomFeePolicy); - bool isMatching = kCustomConfiguration == config; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_network_get) { - Configuration config; - auto network = config.getNetwork(); - bool isMatching = kDefaultNetwork == network; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_network_set) { - Configuration config; - config.setNetwork(kCustomNetwork); - auto network = config.getNetwork(); - bool isMatching = kCustomNetwork == network; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_fee_get) { - Configuration config; - auto transferType = defaults::TransactionTypes::Transfer; - auto defaultTransferFee = kDefaultFeePolicy[transferType]; - auto transferFee = config.getFee(transferType); - ASSERT_EQ(defaultTransferFee, transferFee); -} - -/**/ - -TEST(common, configuration_fee_set) { - Configuration config; - auto transferType = defaults::TransactionTypes::Transfer; - config.setFee(transferType, kTestAmount); - uint64_t newFee = config.getFee(transferType); - ASSERT_EQ(kTestAmount, newFee); -} - -/**/ - - -TEST(common, configuration_fees_get_policy) { - Configuration config; - bool isMatching = kDefaultFeePolicy == config.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_fees_policy_set) { - Configuration config; - config.setPolicy(kCustomFeePolicy); - bool isMatching = kCustomFeePolicy == config.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_comparison_equals) { - Configuration config; - bool isMatching = kDefaultConfiguration == config; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(common, configuration_comparison_not_equal) { - Configuration config(kCustomNetwork); - bool notMatching = kCustomConfiguration != config; - ASSERT_TRUE(notMatching); -} diff --git a/test/common/fee_policy.cpp b/test/common/fee_policy.cpp deleted file mode 100644 index 2c59bc05..00000000 --- a/test/common/fee_policy.cpp +++ /dev/null @@ -1,20 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -namespace { -static const FeePolicy kCustomFeePolicy = { - 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, - 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL -}; -} //namespace - -/**/ - -TEST(common, fee_policy_custom) { - const FeePolicy feePolicy(kCustomFeePolicy); - for (auto i = 0; i < kCustomFeePolicy.size(); ++i) { - ASSERT_EQ(kCustomFeePolicy[i], feePolicy[i]); - }; -} diff --git a/test/common/network.cpp b/test/common/network.cpp deleted file mode 100644 index 003cf425..00000000 --- a/test/common/network.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -namespace { // NOLINT -static const Network kDevnetNetwork = Networks::Devnet(); -/**/ -static const std::string kCustomNethash = "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df"; -static const uint8_t kCustomSlip44 = 1; -static const uint8_t kCustomWif = 0x53; -static const uint8_t kCustomVersion = 0xaa; -static const std::string kCustomEpoch = "2019-04-12T13:00:00.000Z"; -/**/ -static const Network kCustomNetwork { - kCustomNethash, - kCustomSlip44, kCustomWif, kCustomVersion, - kCustomEpoch -}; -} // namespace - -/**/ - -TEST(common, network_constructor_default) { - Network network; - bool networksMatch = kDevnetNetwork == network; - ASSERT_TRUE(networksMatch); -} - -/**/ - -TEST(common, network_constructor_list) { - Network customNetwork = { kCustomNethash, - kCustomSlip44, - kCustomWif, - kCustomVersion, - kCustomEpoch }; - bool networksMatch = kCustomNetwork == customNetwork; - ASSERT_TRUE(networksMatch); -} - -/**/ - -TEST(common, network_comparison_equals) { - Network customNetwork(kDevnetNetwork); - bool networksMatch = kDevnetNetwork == customNetwork; - ASSERT_TRUE(networksMatch); -} - -/**/ - -TEST(common, network_comparison_not_equal) { - Network customNetwork(kCustomNetwork); - bool networksMatch = kDevnetNetwork != customNetwork; - ASSERT_TRUE(networksMatch); -} - -/**/ - -TEST(common, network_get_parameters) { - Network network(kDevnetNetwork); - ASSERT_STREQ(kDevnetNetwork.nethash().c_str(), network.nethash().c_str()); - ASSERT_EQ(kDevnetNetwork.slip44(), network.slip44()); - ASSERT_EQ(kDevnetNetwork.wif(), network.wif()); - ASSERT_EQ(kDevnetNetwork.version(), network.version()); - ASSERT_STREQ(kDevnetNetwork.epoch().c_str(), network.epoch().c_str()); -} diff --git a/test/defaults/static_fees.cpp b/test/defaults/static_fees.cpp deleted file mode 100644 index 6951bf3c..00000000 --- a/test/defaults/static_fees.cpp +++ /dev/null @@ -1,40 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -#include - -namespace { -static const uint64_t kTransfer = 10000000ULL; -static const uint64_t kSecondSignatureRegistration = 500000000ULL; -static const uint64_t kDelegateRegistration = 2500000000ULL; -static const uint64_t kVote = 100000000ULL; -static const uint64_t kMultiSignatureRegistration = 500000000ULL; -static const uint64_t kIpfs = 0ULL; -static const uint64_t kTimelockTransfer = 0ULL; -static const uint64_t kMultiPayment = 0ULL; -static const uint64_t kDelegateResignation = 2500000000ULL; -static const uint8_t kTransferType = 0; -static const uint8_t kSecondSignatureRegistrationType = 1; -static const uint8_t kDelegateRegistrationType = 2; -static const uint8_t kVoteType = 3; -static const uint8_t kMultiSignatureRegistrationType = 4; -static const uint8_t kIpfsType = 5; -static const uint8_t kTimelockTransferType = 6; -static const uint8_t kMultiPaymentType = 7; -static const uint8_t kDelegateResignationType = 8; -} //namespace - -TEST(defaults, fees_static) { // NOLINT - const auto feePolicy = defaults::Fees::StaticFeePolicy(); - ASSERT_EQ(kTransfer, feePolicy[kTransferType]); - ASSERT_EQ(kSecondSignatureRegistration, feePolicy[kSecondSignatureRegistrationType]); - ASSERT_EQ(kDelegateRegistration, feePolicy[kDelegateRegistrationType]); - ASSERT_EQ(kVote, feePolicy[kVoteType]); - ASSERT_EQ(kMultiSignatureRegistration, feePolicy[kMultiSignatureRegistrationType]); - ASSERT_EQ(kIpfs, feePolicy[kIpfsType]); - ASSERT_EQ(kTimelockTransfer, feePolicy[kTimelockTransferType]); - ASSERT_EQ(kMultiPayment, feePolicy[kMultiPaymentType]); - ASSERT_EQ(kDelegateResignation, feePolicy[kDelegateResignationType]); -} diff --git a/test/defaults/transaction_types.cpp b/test/defaults/transaction_types.cpp deleted file mode 100644 index 3afab7c8..00000000 --- a/test/defaults/transaction_types.cpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -namespace { -static const uint8_t kTransferType = 0; -static const uint8_t kSecondSignatureRegistrationType = 1; -static const uint8_t kDelegateRegistrationType = 2; -static const uint8_t kVoteType = 3; -static const uint8_t kMultiSignatureRegistrationType = 4; -static const uint8_t kIpfsType = 5; -static const uint8_t kTimelockTransferType = 6; -static const uint8_t kMultiPaymentType = 7; -static const uint8_t kDelegateResignationType = 8; -} //namespace - -/**/ - -TEST(defaults, transaction_types) { // NOLINT - ASSERT_EQ(kTransferType, defaults::TransactionTypes::Transfer); - ASSERT_EQ(kSecondSignatureRegistrationType, defaults::TransactionTypes::SecondSignatureRegistration); - ASSERT_EQ(kDelegateRegistrationType, defaults::TransactionTypes::DelegateRegistration); - ASSERT_EQ(kVoteType, defaults::TransactionTypes::Vote); - ASSERT_EQ(kMultiSignatureRegistrationType, defaults::TransactionTypes::MultiSignatureRegistration); - ASSERT_EQ(kIpfsType, defaults::TransactionTypes::Ipfs); - ASSERT_EQ(kTimelockTransferType, defaults::TransactionTypes::TimelockTransfer); - ASSERT_EQ(kMultiPaymentType, defaults::TransactionTypes::MultiPayment); - ASSERT_EQ(kDelegateResignationType, defaults::TransactionTypes::DelegateResignation); -} diff --git a/test/helpers/crypto.cpp b/test/helpers/crypto.cpp deleted file mode 100644 index 2acea58f..00000000 --- a/test/helpers/crypto.cpp +++ /dev/null @@ -1,108 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/privatekey.h" -#include "identities/publickey.h" - -#include "bcl/Sha256.hpp" -#include "bcl/Uint256.hpp" - -#include "helpers/crypto.h" - -namespace { // NOLINT - std::vector MessageHashTestBytes = { - 165, 145, 166, 212, 11, 244, 32, 64, - 74, 1, 23, 51, 207, 183, 177, 144, - 214, 44, 101, 191, 11, 205, 163, 43, - 87, 178, 119, 217, 173, 159, 20, 110 - }; - - std::vector PrivateKeyTestBytes = { - 216, 131, 156, 36, 50, 191, 208, 166, - 126, 241, 10, 128, 75, 169, 145, 234, - 187, 161, 159, 21, 74, 61, 112, 121, - 23, 104, 29, 69, 130, 42, 87, 18 - }; - - std::vector PublicKeyTestBytes = { - 3, - 65, 81, 163, 236, 70, 181, 103, 10, - 104, 43, 10, 99, 57, 79, 134, 53, - 135, 209, 188, 151, 72, 59, 27, 108, - 112, 235, 88, 231, 240, 174, 209, 146 - }; - std::vector InvalidPublicKeyTestBytes = { - 3, - 66, 81, 163, 236, 70, 181, 103, 10, - 104, 43, 10, 99, 57, 79, 134, 53, - 135, 209, 188, 151, 72, 59, 27, 108, - 112, 235, 88, 231, 240, 174, 209, 146 - }; - - std::vector RValueTestBytes = { - 15, 180, 173, 221, 209, 241, 214, 82, - 181, 68, 234, 106, 182, 40, 40, 160, - 166, 91, 113, 46, 212, 71, 226, 83, - 141, 176, 202, 235, 250, 104, 146, 158 - }; - - std::vector SValueTestBytes = { - 94, 203, 46, 28, 99, 178, 152, 121, - 194, 236, 241, 37, 93, 181, 6, 214, - 113, 200, 179, 250, 96, 23, 246, 124, - 253, 27, 240, 126, 110, 221, 28, 200 - }; - - std::vector SignatureTestBytes = { - 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, - 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, - 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, - 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, - 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, - 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, - 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 - }; -}; - -/**/ - -TEST(helpers, crypto_sign) { - Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); - Ark::Crypto::Identities::PrivateKey privateKey(&PrivateKeyTestBytes[0]); - std::vector signature; - cryptoSign( - hash, - privateKey, - signature); - - for (auto i = 0; i < signature.size(); ++i) { - ASSERT_EQ(signature[i], SignatureTestBytes[i]); - }; -} - -/**/ - -TEST(helpers, crypto_verify_valid) { - Ark::Crypto::Identities::PublicKey publicKey(&PublicKeyTestBytes[0]); - Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); - - bool isValid = cryptoVerify( - publicKey, - hash, - SignatureTestBytes); - ASSERT_TRUE(isValid); -} - -/**/ - -TEST(helpers, crypto_verify_invalid) { - Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); -// Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); - Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); - - bool isValid = cryptoVerify( - publicKey, - hash, - SignatureTestBytes); - ASSERT_FALSE(isValid); -} diff --git a/test/helpers/crypto_helpers.cpp b/test/helpers/crypto_helpers.cpp deleted file mode 100644 index e3bc51ec..00000000 --- a/test/helpers/crypto_helpers.cpp +++ /dev/null @@ -1,30 +0,0 @@ - -#include "gtest/gtest.h" - -#include "helpers/crypto_helpers.h" - -#include -#include - -TEST(helpers, pack_unpack) { - std::vector packBuffer; - uint8_t packValue = 23; - pack(packBuffer, packValue); - - uint8_t unpackValue; - unpack(&unpackValue, &packBuffer[0]); - ASSERT_EQ(packValue, unpackValue); -} - -/**/ - -TEST(helpers, join) { - const auto strBuffer = "123"; - std::vector vstr(3); - vstr[0] = strBuffer[0]; - vstr[1] = strBuffer[1]; - vstr[2]= strBuffer[2]; - - std::string joined = join(vstr); - ASSERT_STREQ(joined.c_str(), strBuffer); -} diff --git a/test/helpers/encoding/hex.cpp b/test/helpers/encoding/hex.cpp deleted file mode 100644 index 5c0cb8f7..00000000 --- a/test/helpers/encoding/hex.cpp +++ /dev/null @@ -1,41 +0,0 @@ - -#include "gtest/gtest.h" - -#include "helpers/encoding/hex.h" - -namespace { // NOLINT - std::vector SignatureTestBytes = { - 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, - 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, - 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, - 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, - 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, - 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, - 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 - }; - const auto SignatureTestString = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; - const auto SignatureTestStringSpaces = "30 44 02 20 0f b4 ad dd d1 f1 d6 52 b5 44 ea 6a b6 28 28 a0 a6 5b 71 2e d4 47 e2 53 8d b0 ca eb fa 68 92 9e 02 20 5e cb 2e 1c 63 b2 98 79 c2 ec f1 25 5d b5 06 d6 71 c8 b3 fa 60 17 f6 7c fd 1b f0 7e 6e dd 1c c8"; -} - -TEST(helpers, hex_bytes_to_hex) { - const auto result = BytesToHex(&SignatureTestBytes[0], &SignatureTestBytes[0] + SignatureTestBytes.size()); - ASSERT_STREQ(result.c_str(), SignatureTestString); -} - -/**/ - -TEST(helpers, hex_hex_to_bytes) { - const auto result = HexToBytes(SignatureTestString); - for (auto i = 0; i < result.size(); ++i) { - ASSERT_TRUE(result[i] == SignatureTestBytes[i]); - }; -} - -/**/ - -TEST(helpers, hex_hex_to_bytes_spaces) { - const auto result = HexToBytes(SignatureTestStringSpaces); - for (auto i = 0; i < result.size(); ++i) { - ASSERT_TRUE(result[i] == SignatureTestBytes[i]); - }; -} diff --git a/test/identities/address.cpp b/test/identities/address.cpp deleted file mode 100644 index ebbfaad3..00000000 --- a/test/identities/address.cpp +++ /dev/null @@ -1,107 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/address.h" -#include "identities/privatekey.h" -#include "identities/publickey.h" - -#include - -using namespace Ark::Crypto::Identities; - -namespace { // NOLINT - // ARK Core test fixtures: - // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json - const auto Passphrase = "this is a top secret passphrase"; - const uint8_t NetworkVersion = 0x1E; - const auto AddressString = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; - const uint8_t TestAddressBytes[34] = { - 68, 54, 49, 109, 102, 83, 103, 103, - 122, 98, 118, 81, 103, 84, 85, 101, - 54, 74, 104, 89, 75, 72, 50, 100, - 111, 72, 97, 113, 74, 51, 68, 121, 105, 98 - }; -} // namespace - -/**/ - -TEST(identities, address_from_bytes) { - Address address(TestAddressBytes); - ASSERT_STREQ(address.toString().c_str(), AddressString); -} - -/**/ - -TEST(identities, address_to_bytes) { - Address address(AddressString); - const auto addressBytes = address.toBytes(); - for (auto i = 0; i < 34; ++i) { - ASSERT_EQ(addressBytes[i], TestAddressBytes[i]); - }; -} - -/**/ - -TEST(identities, address_from_passphrase) { - Address address = Address::fromPassphrase(Passphrase, NetworkVersion); - ASSERT_STREQ(AddressString, address.toString().c_str()); -} - -/**/ - -TEST(identities, address_from_privatekey) { - const auto privateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; - PrivateKey privateKey(privateKeyString); - Address address = Address::fromPrivateKey(privateKey, NetworkVersion); - ASSERT_STREQ(AddressString, address.toString().c_str()); -} - -/**/ - -TEST(identities, address_from_publickey) { - const auto publicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - PublicKey publicKey(publicKeyString); - Address address = Address::fromPublicKey(publicKey, NetworkVersion); - ASSERT_STREQ(AddressString, address.toString().c_str()); -} - -/**/ - -TEST(identities, address_from_string) { - Address address(AddressString); - ASSERT_STREQ(AddressString, address.toString().c_str()); -} - -/**/ - -TEST(identities, address_validate_address) { - Address address(AddressString); - ASSERT_TRUE(Address::validate(address, NetworkVersion)); -} - -/**/ - -TEST(identities, address_validate) { - Address address(AddressString); - ASSERT_TRUE(Address::validate(address, NetworkVersion)); -} - -/**/ - -TEST(identities, address_validate_string) { - ASSERT_TRUE(Address::validate(AddressString, NetworkVersion)); -} - -/**/ - -TEST(identities, address_validate_bytes) { - ASSERT_TRUE(Address::validate(TestAddressBytes, NetworkVersion)); -} - -/**/ - -TEST(identities, address_invalid) { - const auto invalidAddressStr = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyi"; - Address address(invalidAddressStr); - ASSERT_FALSE(Address::validate(address, NetworkVersion)); -} diff --git a/test/identities/privatekey.cpp b/test/identities/privatekey.cpp deleted file mode 100644 index b7594c29..00000000 --- a/test/identities/privatekey.cpp +++ /dev/null @@ -1,71 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/privatekey.h" -using namespace Ark::Crypto::Identities; - -namespace { // NOLINT - // ARK Core test fixtures: - // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json - const auto Passphrase = "this is a top secret passphrase"; - const uint8_t TestPrivateKeyBytes[32] = { - 216, 131, 156, 36, 50, 191, 208, 166, - 126, 241, 10, 128, 75, 169, 145, 234, - 187, 161, 159, 21, 74, 61, 112, 121, - 23, 104, 29, 69, 130, 42, 87, 18 - }; - const uint8_t WIFByte = 0xaa; - const auto PrivateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; -} // namespace - -TEST(identities, privatekey_construct_bytes) { - PrivateKey privateKey(TestPrivateKeyBytes); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_construct_string) { - PrivateKey privateKey(PrivateKeyString); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_from_hex) { - PrivateKey privateKey = PrivateKey::fromHex(PrivateKeyString); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_from_passphrase) { - PrivateKey privateKey = PrivateKey::fromPassphrase(Passphrase); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_from_string) { - PrivateKey privateKey(PrivateKeyString); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_from_wif_string) { - const char* wifStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; - PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, WIFByte); - ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); -} - -TEST(identities, privatekey_get_bytes) { - PrivateKey privateKey(PrivateKeyString); - const auto privateKeyBytes = privateKey.toBytes(); - for (unsigned int i = 0; i < PRIVATEKEY_SIZE; i++) { - ASSERT_EQ(privateKeyBytes[i], TestPrivateKeyBytes[i]); - }; -} - -TEST(identities, privatekey_validate) { - PrivateKey privateKey(PrivateKeyString); - ASSERT_TRUE(PrivateKey::validate(privateKey)); -} - -TEST(identities, privatekey_validate_bytes) { - ASSERT_TRUE(PrivateKey::validate(TestPrivateKeyBytes)); -} - -TEST(identities, privatekey_validate_string) { - ASSERT_TRUE(PrivateKey::validate(PrivateKeyString)); -} diff --git a/test/identities/publickey.cpp b/test/identities/publickey.cpp deleted file mode 100644 index 098833f3..00000000 --- a/test/identities/publickey.cpp +++ /dev/null @@ -1,77 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/publickey.h" -using namespace Ark::Crypto::Identities; - -namespace { // NOLINT - // ARK Core test fixtures: - // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json - const auto Passphrase = "this is a top secret passphrase"; - const uint8_t TestPublicKeyBytes[33] = { - 3, - 65, 81, 163, 236, 70, 181, 103, 10, - 104, 43, 10, 99, 57, 79, 134, 53, - 135, 209, 188, 151, 72, 59, 27, 108, - 112, 235, 88, 231, 240, 174, 209, 146 - }; - const auto PublicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; -} // namespace - -/**/ - -TEST(identities, publickey_from_bytes) { - PublicKey publicKey(TestPublicKeyBytes); - ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); -} - -/**/ - -TEST(identities, publickey_from_hex) { - PublicKey publicKey = PublicKey::fromHex(PublicKeyString); - ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); -} - -/**/ - -TEST(identities, publickey_from_passphrase) { - PublicKey publicKey = PublicKey::fromPassphrase(Passphrase); - ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); -} - -/**/ - -TEST(identities, publickey_from_string) { - PublicKey publicKey(PublicKeyString); - ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); -} - -/**/ - -TEST(identities, publickey_get_bytes) { - PublicKey publicKey(PublicKeyString); - const auto publicKeyBytes = publicKey.toBytes(); - for (unsigned int i = 0; i < COMPRESSED_PUBLICKEY_SIZE; i++) { - ASSERT_EQ(publicKeyBytes[i], TestPublicKeyBytes[i]); - }; -} - -/**/ - -TEST(identities, publickey_validate) { - PublicKey publicKey(PublicKeyString); - ASSERT_TRUE(PublicKey::validate(publicKey)); - ASSERT_TRUE(publicKey.isValid()); -} - -/**/ - -TEST(identities, publickey_validate_bytes) { - ASSERT_TRUE(PublicKey::validate(TestPublicKeyBytes)); -} - -/**/ - -TEST(identities, publickey_validate_string) { - ASSERT_TRUE(PublicKey::validate(PublicKeyString)); -} diff --git a/test/identities/wif.cpp b/test/identities/wif.cpp deleted file mode 100644 index 84678de5..00000000 --- a/test/identities/wif.cpp +++ /dev/null @@ -1,58 +0,0 @@ - -#include "gtest/gtest.h" - -#include "identities/wif.h" -using namespace Ark::Crypto::Identities; - -namespace { // NOLINT - // ARK Core test fixtures: - // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json - const auto Passphrase = "this is a top secret passphrase"; - const uint8_t TestWIFBytes[52] = { - 83, 71, 113, 52, 120, 76, 103, 90, 75, 67, 71, 120, 115, - 55, 98, 106, 109, 119, 110, 66, 114, 87, 99, 84, 52, 67, - 49, 65, 68, 70, 69, 101, 114, 109, 106, 56, 52, 54, 75, - 67, 57, 55, 70, 83, 118, 49, 87, 70, 68, 49, 100, 65 - }; - const uint8_t WIFByte = 0xaa; - const auto AddressString = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; -} // namespace - -/**/ - -TEST(identities, wif_from_bytes) { - WIF wif(TestWIFBytes); - ASSERT_STREQ(AddressString, wif.toString().c_str()); -} - -/**/ - -TEST(identities, wif_from_passphrase) { - WIF wif = WIF::fromPassphrase(Passphrase, WIFByte); - ASSERT_STREQ(AddressString, wif.toString().c_str()); -} - -/**/ - -TEST(identities, wif_from_string) { - WIF wif(AddressString); - ASSERT_STREQ(AddressString, wif.toString().c_str()); -} - -/**/ - -TEST(identities, wif_get_bytes) { - WIF wif(AddressString); - const auto wifBytes = wif.toBytes(); - for (unsigned int i = 0; i < WIF_SIZE; i++) { - ASSERT_EQ(wifBytes[i], TestWIFBytes[i]); - }; -} - -/**/ - -TEST(identities, wif_invalid) { - const auto invalidWIFStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1d"; - WIF wif(invalidWIFStr); - ASSERT_FALSE(WIF::validate(wif)); -} diff --git a/test/iot/gtest/gtest.h b/test/iot/gtest/gtest.h deleted file mode 100644 index 49e5ebec..00000000 --- a/test/iot/gtest/gtest.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __GTEST_H__ -#define __GTEST_H__ - -#include -#include - -#endif diff --git a/test/iot/test_main.cpp b/test/iot/test_main.cpp deleted file mode 100644 index ddc1f14f..00000000 --- a/test/iot/test_main.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#if (defined PLATFORMIO && defined UNIT_TEST) - -#include - -// Set Dummy Time for testing board -#include -void setDummyTime() { - // set board time to: 21 March 2019(in seconds) - // 2 years after Mainnet launch. - struct timeval tv; - tv.tv_sec = 1553173200ull; - settimeofday(&tv, NULL); -}; - -void setup() { - Serial.begin(115200); - - setDummyTime(); - - aunit::TestRunner::setTimeout(0); - - delay(1000); -} - -void loop() { - aunit::TestRunner::run(); -} - -#endif diff --git a/test/lib/googletest b/test/lib/googletest deleted file mode 160000 index 3cf8f514..00000000 --- a/test/lib/googletest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3cf8f514d859d65b7202e51c662a03a92887b8e2 diff --git a/test/managers/fee_manager.cpp b/test/managers/fee_manager.cpp deleted file mode 100644 index 1f1920f6..00000000 --- a/test/managers/fee_manager.cpp +++ /dev/null @@ -1,100 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -using namespace managers; - -namespace { -static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); -static const FeePolicy kCustomFeePolicy = { - 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, - 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL -}; -static const FeeManager kDefaultFeeManager = FeeManager(); -static const FeeManager kCustomFeeManager = FeeManager(kCustomFeePolicy); -static const uint8_t kInPolicyBounds = 5; -static const uint8_t kOutOfPolicyBounds = 11; -static const uint64_t kAmountZero = 0ULL; -static const uint64_t kCustomFee = 1000000000ULL; -} //namespace - -/**/ - -TEST(managers, fee_manager_constructor_default) { - FeeManager feeManager; - bool isMatching = kDefaultFeeManager == feeManager.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, fee_manager_constructor_fee_policy) { - FeeManager feeManager(kCustomFeePolicy); - bool isMatching = kCustomFeeManager == feeManager.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, fee_manager_fee_get_in_bounds) { - FeeManager feeManager; - ASSERT_EQ(kDefaultFeePolicy[kInPolicyBounds], - feeManager.getFee(kInPolicyBounds)); -} - -/**/ - -TEST(managers, fee_manager_fee_get_out_of_bounds) { - FeeManager feeManager; - ASSERT_EQ(kAmountZero, feeManager.getFee(kOutOfPolicyBounds)); -} - -/**/ - -TEST(managers, fee_manager_fee_set_in_bounds) { - FeeManager feeManager; - feeManager.setFee(kInPolicyBounds, kCustomFee); - ASSERT_EQ(kCustomFee, feeManager.getFee(kInPolicyBounds)); -} - -/**/ - -TEST(managers, fee_manager_fee_set_out_of_bounds) { - FeeManager feeManager; - feeManager.setFee(kOutOfPolicyBounds, kCustomFee); - ASSERT_EQ(kCustomFee, feeManager.getFee(kOutOfPolicyBounds)); -} - -/**/ - -TEST(managers, fee_manager_policy_get) { - FeeManager feeManager; - bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, fee_manager_policy_set) { - FeeManager feeManager; - feeManager.setPolicy(kCustomFeePolicy); - bool isMatching = kCustomFeePolicy == feeManager.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, fee_manager_comparison_equals) { - FeeManager feeManager; - bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, fee_manager_comparison_not_equal) { - FeeManager feeManager(kCustomFeePolicy); - bool notMatching = kDefaultFeePolicy != feeManager.getPolicy(); - ASSERT_TRUE(notMatching); -} diff --git a/test/managers/network_manager.cpp b/test/managers/network_manager.cpp deleted file mode 100644 index 4e1ac0f6..00000000 --- a/test/managers/network_manager.cpp +++ /dev/null @@ -1,67 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -using namespace managers; - -namespace { // NOLINT -static const Network kDefaultNetwork = Networks::Devnet(); -static const Network kCustomNetwork { - "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", - 1, 0x53, 0xaa, - "2019-04-12T13:00:00.000Z" -}; -/**/ -static const NetworkManager kDefaultNetworkManager = NetworkManager(); -static const NetworkManager kCustomNetworkManager = NetworkManager(kCustomNetwork); -} //namespace - -/**/ - -TEST(managers, network_manager_constructor_default) { - NetworkManager networkManager; - bool isMatching = kDefaultNetworkManager == networkManager; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, network_manager_network_constructor) { - NetworkManager networkManager(kCustomNetwork); - bool isMatching = kCustomNetworkManager == networkManager; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, network_manager_get) { - NetworkManager networkManager; - bool isMatching = kDefaultNetworkManager == networkManager; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, network_manager_set) { - NetworkManager networkManager; - networkManager.setNetwork(kCustomNetwork); - bool isMatching = kCustomNetworkManager == networkManager; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, network_manager_comparison_equals) { - NetworkManager networkManager; - bool isMatching = kDefaultNetworkManager == networkManager; - ASSERT_TRUE(isMatching); -} - -/**/ - -TEST(managers, network_manager_comparison_not_equal) { - NetworkManager networkManager(kCustomNetwork); - bool notMatching = kDefaultNetworkManager != networkManager; - ASSERT_TRUE(notMatching); -} \ No newline at end of file diff --git a/test/networks/devnet.cpp b/test/networks/devnet.cpp deleted file mode 100644 index d65d332f..00000000 --- a/test/networks/devnet.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "gtest/gtest.h" -#include - -namespace { // NOLINT - static const std::string Nethash = "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867"; - static const uint8_t Slip44 = 1; - static const uint8_t Wif = 0xaa; - static const uint8_t Version = 0x1E; - static const std::string Epoch = "2017-03-21T13:00:00.000Z"; -}; // namespace - -TEST(networks, devnet) { - ASSERT_STREQ(Nethash.c_str(), Networks::Devnet().nethash().c_str()); - ASSERT_EQ(Slip44, Networks::Devnet().slip44()); - ASSERT_EQ(Wif, Networks::Devnet().wif()); - ASSERT_EQ(Version, Networks::Devnet().version()); - ASSERT_STREQ(Epoch.c_str(), Networks::Devnet().epoch().c_str()); -} diff --git a/test/networks/mainnet.cpp b/test/networks/mainnet.cpp deleted file mode 100644 index 91795a64..00000000 --- a/test/networks/mainnet.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "gtest/gtest.h" -#include - -namespace { // NOLINT - static const std::string Nethash = "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988"; - static const uint8_t Slip44 = 111; - static const uint8_t Wif = 0xaa; - static const uint8_t Version = 0x17; - static const std::string Epoch = "2017-03-21T13:00:00.000Z"; -}; // namespace - -TEST(networks, mainnet) { - ASSERT_STREQ(Nethash.c_str(), Networks::Mainnet().nethash().c_str()); - ASSERT_EQ(Slip44, Networks::Mainnet().slip44()); - ASSERT_EQ(Wif, Networks::Mainnet().wif()); - ASSERT_EQ(Version, Networks::Mainnet().version()); - ASSERT_STREQ(Epoch.c_str(), Networks::Mainnet().epoch().c_str()); -} diff --git a/test/networks/testnet.cpp b/test/networks/testnet.cpp deleted file mode 100644 index d4212951..00000000 --- a/test/networks/testnet.cpp +++ /dev/null @@ -1,19 +0,0 @@ - -#include "gtest/gtest.h" -#include - -namespace { // NOLINT - static const std::string Nethash = "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192"; - static const uint8_t Slip44 = 1; - static const uint8_t Wif = 0xba; - static const uint8_t Version = 0x17; - static const std::string Epoch = "2017-03-21T13:00:00.000Z"; -}; // namespace - -TEST(networks, testnet) { - ASSERT_STREQ(Nethash.c_str(), Networks::Testnet().nethash().c_str()); - ASSERT_EQ(Slip44, Networks::Testnet().slip44()); - ASSERT_EQ(Wif, Networks::Testnet().wif()); - ASSERT_EQ(Version, Networks::Testnet().version()); - ASSERT_STREQ(Epoch.c_str(), Networks::Testnet().epoch().c_str()); -} diff --git a/test/platformio.ini b/test/platformio.ini deleted file mode 100644 index a8bfa36d..00000000 --- a/test/platformio.ini +++ /dev/null @@ -1,40 +0,0 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter -; Upload options: custom upload port, speed and extra flags -; Library options: dependencies, extra library storages -; Advanced options: extra scripting -; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html - -[platformio] -description = "Unit Tests for Ark-Cpp-Crypto" -src_dir = .. -build_dir = .pio/.pioenvs -libdeps_dir = .pio/.piolibdeps - -[common] -lib_deps = micro-ecc, AUnit, ArduinoJson@6.10.0, BIP66 -build_flags = -I../test -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = + + - -upload_speed = 921600 - -# esp8266 unit tests disabled until support is worked out -#[env:esp8266] -#platform = espressif8266 -#board = huzzah -#framework = arduino -#lib_deps = ${common.lib_deps} -#build_flags = ${common.build_flags} -#src_filter = ${common.src_filter} -#upload_speed = ${common.upload_speed} - -[env:esp32] -platform = espressif32 -board = esp32dev -framework = arduino -lib_deps = ${common.lib_deps} -build_flags = ${common.build_flags} -src_filter = ${common.src_filter} -upload_speed = ${common.upload_speed} diff --git a/test/transactions/builder.cpp b/test/transactions/builder.cpp deleted file mode 100644 index 6aeef1c8..00000000 --- a/test/transactions/builder.cpp +++ /dev/null @@ -1,62 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -TEST(transactions, build_transfer) { - const auto actual = - Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 100000000ULL, - "", - "Secret passphrase"); - - ASSERT_EQ(0, actual.type); - ASSERT_EQ(defaults::Fees::StaticFeePolicy()[actual.type], actual.fee); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - actual.recipientId.c_str()); - ASSERT_EQ(100000000ULL, actual.amount); - ASSERT_TRUE(actual.vendorField.empty()); -} - -/**/ - -TEST(transactions, build_transfer_custom_network) { - static const Network MyCustomNetwork = { - "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", - 1, 0x53, 0xaa, - "2019-04-12T13:00:00.000Z" - }; - - const Configuration myCustomConfiguration(MyCustomNetwork); - - const auto transaction = Builder::buildTransfer( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 100000000ULL, - "this is a custom bridgechain transaction", - "this is a top secret passphrase", - "this is a top secret passphrase too", - myCustomConfiguration); - - ASSERT_EQ(0, transaction.type); - ASSERT_EQ(myCustomConfiguration.getFee(transaction.type), transaction.fee); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - transaction.recipientId.c_str()); - ASSERT_EQ(100000000ULL, transaction.amount); - ASSERT_STREQ("this is a custom bridgechain transaction", - transaction.vendorField.c_str()); -} - -/**/ - -TEST(transactions, build_empty_transaction) { - // test 0 ARKtoshi value - const auto shouldBeEmpty = Ark::Crypto::Transactions::Builder::buildTransfer( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 0, - "", - "Secret passphrase"); - - ASSERT_TRUE(shouldBeEmpty.recipientId.empty()); - ASSERT_EQ(0ULL, shouldBeEmpty.amount); - ASSERT_FALSE(shouldBeEmpty.verify()); -} diff --git a/test/transactions/deserializer.cpp b/test/transactions/deserializer.cpp deleted file mode 100644 index f7908204..00000000 --- a/test/transactions/deserializer.cpp +++ /dev/null @@ -1,214 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -TEST(transactions, deserialize_transfer) { // NOLINT - // transfer/passphrase-with-vendor-field.json - Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" - "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" - "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(defaults::TransactionTypes::Transfer, actual.type); - ASSERT_EQ(41443847UL, actual.timestamp); - ASSERT_STREQ( - "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - actual.senderPublicKey.c_str()); - ASSERT_TRUE(10000000ULL == actual.fee); - ASSERT_STREQ("48656c6c6f20576f726c64", actual.vendorFieldHex.c_str()); - ASSERT_STREQ("Hello World", actual.vendorField.c_str()); - ASSERT_TRUE(200000000ULL == actual.amount); - ASSERT_STREQ( - "ecf558fbddd62ae42edcfcba02f402d987a94b72a7636ef1121e8625487e2a1e", - actual.id.c_str()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); - ASSERT_STREQ( - "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", - actual.signature.c_str()); - ASSERT_TRUE(actual.verify()); -} - -/**/ - -TEST(transactions, deserialize_second_signature_registration) { // NOLINT - // second_signature_registration/second-passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" - "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" - "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(defaults::TransactionTypes::SecondSignatureRegistration, actual.type); - ASSERT_EQ(41271867UL, actual.timestamp); - ASSERT_STREQ( - "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - actual.senderPublicKey.c_str()); - ASSERT_TRUE(500000000ULL == actual.fee); - ASSERT_TRUE(0UL == actual.amount); - ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ( - "6d1615924d172d352c8f44d4ded84cbbece3c03ebb3e4fc3f3334784ae332590", - actual.id.c_str()); - ASSERT_STREQ( - "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609", - actual.asset.signature.publicKey.c_str()); - ASSERT_STREQ( - "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", - actual.signature.c_str()); - ASSERT_TRUE(actual.verify()); - - // special case as the type 1 transaction itself has no recipientId - const auto publicKey = Ark::Crypto::Identities::PublicKey::fromHex(actual.senderPublicKey.c_str()); - const auto address = Ark::Crypto::Identities::Address::fromPublicKey(publicKey, actual.network); - ASSERT_STREQ(address.toString().c_str(), actual.recipientId.c_str()); -} - -/**/ - -#if 0 -TEST(transactions, deserialize_delegate_registration) { // NOLINT - // delegate_registration/second-passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" - "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" - "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" - "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c" - ); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(2, actual.type); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(defaults::TransactionTypes::DelegateRegistration, actual.type); - ASSERT_EQ(41269424UL, actual.timestamp); - ASSERT_STREQ( - "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", - actual.senderPublicKey.c_str()); - ASSERT_EQ(2500000000ULL, actual.fee); - ASSERT_EQ(0ULL, actual.amount); - ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ( - "bf7e018ff9c0066f7a9f51e95d3f78c08cad5dd8581325d630d64350181a91bb", - actual.id.c_str()); - ASSERT_STREQ("boldninja", actual.asset.delegate.username.c_str()); - ASSERT_STREQ( - "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94", - actual.signature.c_str()); - ASSERT_STREQ( - "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", - actual.secondSignature.c_str()); - ASSERT_TRUE(actual.verify())); -} -#endif - -/**/ - -TEST(transactions, deserialize_vote) { // NOLINT - // vote/second-passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" - "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" - "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(defaults::TransactionTypes::Vote, actual.type); - ASSERT_EQ(41269366UL, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(100000000ULL == actual.fee); - ASSERT_TRUE(0ULL == actual.amount); - ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ("16f28a180cd6f3ea46c10f358a457989e956e9d355258230d0c7b07acec10b73", actual.id.c_str()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); - - std::vector votes = {std::string("+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d")}; - ASSERT_EQ(1, actual.asset.votes.size()); - ASSERT_STREQ(votes[0].c_str(), actual.asset.votes[0].c_str()); - - ASSERT_STREQ( - "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068", - actual.signature.c_str()); - ASSERT_STREQ( - "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", - actual.secondSignature.c_str()); - ASSERT_TRUE(actual.verify()); -} - -/**/ - -TEST(transactions, deserialize_multi_signature_registration) { // NOLINT - // multi_signature_registration/passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer( - "ff011704724c9a00036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d76000943577000000000002031803543c" - "6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc80276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80" - "731b44ae89f1fc02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b3130440220324d89c5792e4a54ae70b4f1" - "e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a53044" - "02201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b" - "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" - "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" - "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(23, actual.network); - ASSERT_EQ(defaults::TransactionTypes::MultiSignatureRegistration, actual.type); - ASSERT_EQ(10112114UL, actual.timestamp); - ASSERT_STREQ("036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760", actual.senderPublicKey.c_str()); - ASSERT_TRUE(2000000000ULL == actual.fee); - ASSERT_TRUE(0ULL == actual.amount); - ASSERT_EQ(0, actual.expiration); - - std::vector keysgroup = { - "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" - }; - - ASSERT_EQ(3, actual.asset.multiSignature.keysgroup.size()); - ASSERT_EQ(2, actual.asset.multiSignature.min); - ASSERT_EQ(24, actual.asset.multiSignature.lifetime); - - for (uint8_t i = 0; i < keysgroup.size(); i++) { - ASSERT_STREQ(keysgroup[i].c_str(), actual.asset.multiSignature.keysgroup[i].c_str()); - }; - - ASSERT_STREQ("cbd6862966bb1b03ba742397b7e5a88d6eefb393a362ead0d605723b840db2af", actual.id.c_str()); - - ASSERT_STREQ( - "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5", - actual.signature.c_str()); - ASSERT_STREQ( - "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1", - actual.secondSignature.c_str()); - - std::vector signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"}; - - ASSERT_EQ(3, actual.signatures.size()); - for (uint8_t i = 0; i < signatures.size(); i++) { - ASSERT_STREQ(signatures[i].c_str(), actual.signatures[i].c_str()); - } - - ASSERT_TRUE(actual.verify()); - - // special case as the type 4 transaction itself has no recipientId - const auto publicKey = Ark::Crypto::Identities::PublicKey::fromHex(actual.senderPublicKey.c_str()); - const auto address = Ark::Crypto::Identities::Address::fromPublicKey(publicKey, actual.network); - ASSERT_STREQ(address.toString().c_str(), actual.recipientId.c_str()); -} diff --git a/test/transactions/serializer.cpp b/test/transactions/serializer.cpp deleted file mode 100644 index 543fbf87..00000000 --- a/test/transactions/serializer.cpp +++ /dev/null @@ -1,145 +0,0 @@ - -#include "gtest/gtest.h" - -#include - -TEST(transactions, serialize_transfer) { // NOLINT - // transfer/passphrase-with-vendor-field.json - Ark::Crypto::Transactions::Transaction transaction; - - transaction.type = 0; - transaction.fee = 10000000ULL; - transaction.amount = 200000000ULL; - transaction.timestamp = 41443847UL; - transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; - transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.vendorField = "Hello World"; - transaction.signature = "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"; - - Ark::Crypto::Transactions::Serializer serializer(transaction); - std::string actual = serializer.serialize(); - - ASSERT_STREQ( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" - "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" - "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", - actual.c_str()); -} - -/**/ - -TEST(transactions, serialize_second_signature_registration) { // NOLINT - // second_signature_registration/second-passphrase.json - Ark::Crypto::Transactions::Transaction transaction; - - transaction.type = 1; - transaction.fee = 500000000ULL; - transaction.timestamp = 41271867UL; - transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"; - transaction.asset.signature.publicKey = "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609"; - - Ark::Crypto::Transactions::Serializer serializer(transaction); - std::string actual = serializer.serialize(); - - ASSERT_STREQ( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" - "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" - "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", - actual.c_str()); -} - -/**/ - -TEST(transactions, serialize_delegate_registration) { // NOLINT - // delegate_registration/second-passphrase.json - Ark::Crypto::Transactions::Transaction transaction; - - transaction.type = 2; - transaction.fee = 2500000000ULL; - transaction.timestamp = 41269424UL; - transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94"; - transaction.secondSignature = "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c"; - transaction.asset.delegate.username = "boldninja"; - - Ark::Crypto::Transactions::Serializer serializer(transaction); - std::string actual = serializer.serialize(); - - ASSERT_STREQ( - "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" - "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" - "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" - "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", - actual.c_str()); -} - -/**/ - -TEST(transactions, serialize_vote) { // NOLINT - // vote/second-passphrase.json - Ark::Crypto::Transactions::Transaction transaction; - - transaction.type = 3; - transaction.fee = 100000000ULL; - transaction.timestamp = 41269366UL; - transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; - transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068"; - transaction.secondSignature = "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"; - transaction.asset.votes = { "+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d" }; - - Ark::Crypto::Transactions::Serializer serializer(transaction); - std::string actual = serializer.serialize(); - - ASSERT_STREQ( - "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" - "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" - "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", - actual.c_str()); -} - -/**/ - -TEST(transactions, serialize_multi_signature_registration) { // NOLINT - // multi_signature_registration/passphrase.json - Ark::Crypto::Transactions::Transaction transaction; - - transaction.type = 4; - transaction.version = 1; - transaction.network = 23; - transaction.fee = 2000000000ULL; - transaction.timestamp = 10112114UL; - transaction.senderPublicKey = "036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760"; - transaction.signature = "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5"; - transaction.secondSignature = "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1"; - transaction.signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d" - }; - - transaction.asset.multiSignature.keysgroup = { - "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" - }; - transaction.asset.multiSignature.lifetime = 24; - transaction.asset.multiSignature.min = 2; - - Ark::Crypto::Transactions::Serializer serializer(transaction); - std::string actual = serializer.serialize(); - - ASSERT_STREQ( - "ff011704724c9a00036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d76000943577000000000002031803543c" - "6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc80276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80" - "731b44ae89f1fc02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b3130440220324d89c5792e4a54ae70b4f1" - "e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a53044" - "02201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b" - "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" - "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" - "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d", - actual.c_str()); -} diff --git a/test/transactions/transaction.cpp b/test/transactions/transaction.cpp deleted file mode 100644 index 202bc306..00000000 --- a/test/transactions/transaction.cpp +++ /dev/null @@ -1,305 +0,0 @@ - -#include "gtest/gtest.h" - -#include "transactions/builder.h" -#include "helpers/json.h" - -#include -#include - -/**/ - -TEST(transactions, transaction_default) { - Ark::Crypto::Transactions::Transaction transaction; - ASSERT_FALSE(transaction.verify()); -}; - -/**/ - -TEST(transactions, transaction_to_array) { - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 1, - "", - "Secret passphrase"); - std::map tArray = transfer.toArray(); - - // Amount - ASSERT_STREQ("1", tArray["amount"].c_str()); - // Fee - ASSERT_STREQ("10000000", tArray["fee"].c_str()); - // Id - ASSERT_FALSE(tArray["id"].empty()); - // RecipientId - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tArray["recipientId"].c_str()); - // SenderPublicKey - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - tArray["senderPublicKey"].c_str()); - // Signature - ASSERT_FALSE(tArray["signature"].empty()); - // Timestamp - ASSERT_FALSE(tArray["timestamp"].empty()); - // Type - ASSERT_STREQ("0", tArray["type"].c_str()); - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration( - "Secret passphrase", - "Second Secret passphrase"); - std::map ssArray = secondSignatureRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", ssArray["amount"].c_str()); - // Asset - ASSERT_STREQ( - "02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", - ssArray["publicKey"].c_str()); - // Fee - ASSERT_STREQ("500000000", ssArray["fee"].c_str()); - // Id - ASSERT_FALSE(ssArray["id"].empty()); - // RecipientId - ASSERT_TRUE(ssArray["recipientId"].empty()); - // SecondSignature - ASSERT_FALSE(ssArray["secondSignature"].empty()); - // SenderPublicKey - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - ssArray["senderPublicKey"].c_str()); - // Signature - ASSERT_FALSE(ssArray["signature"].empty()); - // Timestamp - ASSERT_FALSE(ssArray["timestamp"].empty()); - // Type - ASSERT_STREQ("1", ssArray["type"].c_str()); - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration( - "testName", - "Secret passphrase"); - std::map dArray = delegateRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", dArray["amount"].c_str()); - // Asset - ASSERT_STREQ("testName", dArray["username"].c_str()); - // Fee - ASSERT_STREQ("2500000000", dArray["fee"].c_str()); - // Id - ASSERT_FALSE(dArray["id"].empty()); - // RecipientId - ASSERT_TRUE(dArray["recipientId"].empty()); - // SecondSignature - ASSERT_TRUE(dArray["secondSignature"].empty()); - // SenderPublicKey - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - dArray["senderPublicKey"].c_str()); - // Signature - ASSERT_FALSE(dArray["signature"].empty()); - // ASSERT_FALSE - ASSERT_FALSE(dArray["timestamp"].empty()); - // Type - ASSERT_STREQ("2", dArray["type"].c_str()); - - // Type 3 - std::vector votes = { - "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", - "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" - }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::map vArray = vote.toArray(); - - // Amount - ASSERT_STREQ("0", vArray["amount"].c_str()); - // Asset - ASSERT_STREQ( - "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," - "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", - vArray["votes"].c_str()); - // Fee - ASSERT_STREQ("100000000", vArray["fee"].c_str()); - // Id - ASSERT_FALSE(vArray["id"].empty()); - // RecipientId - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vArray["recipientId"].c_str()); - // SecondSignature - ASSERT_TRUE(vArray["secondSignature"].empty()); - // SenderPublicKey - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - vArray["senderPublicKey"].c_str()); - // Signature - ASSERT_FALSE(vArray["signature"].empty()); - // Timestamp - ASSERT_FALSE(vArray["timestamp"].empty()); - // Type - ASSERT_STREQ("3", vArray["type"].c_str()); -} - -/**/ - -TEST(transactions, transaction_to_json) { - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - 1, - "", - "Secret passphrase"); - std::string tJson = transfer.toJson(); - - const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; - DynamicJsonDocument tDoc(tCapacity); - - DeserializationError tError = deserializeJson(tDoc, tJson); - ASSERT_FALSE(tError); - - ASSERT_EQ(tDoc["amount"].as(), 1ULL); - ASSERT_EQ(tDoc["fee"].as(), 10000000ULL); - ASSERT_FALSE(tDoc["id"].as().empty()); - ASSERT_STREQ( - "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", - tDoc["recipientId"].as()); - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - tDoc["senderPublicKey"].as()); - ASSERT_FALSE(tDoc["signature"].as().empty()); - ASSERT_GT(tDoc["timestamp"].as(), 50000000UL); - ASSERT_LT(tDoc["timestamp"].as(), 1000000000UL); - ASSERT_EQ(tDoc["type"].as(), 0); - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration( - "Secret passphrase", - "Second Secret passphrase"); - std::string ssJson = secondSignatureRegistration.toJson(); - - const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; - DynamicJsonDocument ssDoc(ssCapacity); - - DeserializationError ssError = deserializeJson(ssDoc, ssJson); - ASSERT_FALSE(ssError); - - ASSERT_EQ(ssDoc["amount"].as(), 0ULL); - ASSERT_STREQ( - "02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", - ssDoc["asset"]["signature"]["publicKey"].as()); - ASSERT_EQ(ssDoc["fee"].as(), 500000000ULL); - ASSERT_FALSE(ssDoc["id"].as().empty()); - ASSERT_TRUE(ssDoc["recipientId"].as().empty()); - ASSERT_FALSE(ssDoc["secondSignature"].as().empty()); - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - ssDoc["senderPublicKey"].as()); - ASSERT_FALSE(ssDoc["signature"].as().empty()); - ASSERT_GT(ssDoc["timestamp"].as(), 50000000UL); - ASSERT_LT(ssDoc["timestamp"].as(), 1000000000UL); - ASSERT_EQ(ssDoc["type"].as(), 1); - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration( - "testName", - "Secret passphrase"); - std::string dJson = delegateRegistration.toJson(); - - const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; - DynamicJsonDocument dDoc(dCapacity); - - DeserializationError dError = deserializeJson(dDoc, dJson); - ASSERT_FALSE(dError); - - ASSERT_EQ(dDoc["amount"].as(), 0ULL); - ASSERT_STREQ("testName", dDoc["asset"]["delegate"]["username"].as()); - ASSERT_EQ(dDoc["fee"].as(), 2500000000ULL); - ASSERT_FALSE(dDoc["id"].as().empty()); - ASSERT_TRUE(dDoc["recipientId"].as().empty()); - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - dDoc["senderPublicKey"].as()); - ASSERT_FALSE(dDoc["signature"].as().empty()); - ASSERT_GT(dDoc["timestamp"].as(), 50000000UL); - ASSERT_LT(dDoc["timestamp"].as(), 1000000000UL); - ASSERT_EQ(dDoc["type"].as(), 2); - - // Type 3 - std::vector votes = { - "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," - "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" - }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::string vJson = vote.toJson(); - - const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 700; - DynamicJsonDocument vDoc(vCapacity); - - DeserializationError vError = deserializeJson(vDoc, vJson); - ASSERT_FALSE(vError); - - ASSERT_EQ(vDoc["amount"].as(), 0ULL); - ASSERT_STREQ( - "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", - vDoc["asset"]["votes"][0].as()); - ASSERT_STREQ( - "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", - vDoc["asset"]["votes"][1].as()); - ASSERT_EQ(vDoc["fee"].as(), 100000000ULL); - ASSERT_FALSE(vDoc["id"].as().empty()); - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vDoc["recipientId"].as()); - ASSERT_STREQ( - "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", - vDoc["senderPublicKey"].as()); - ASSERT_FALSE(vDoc["signature"].as().empty()); - ASSERT_GT(vDoc["timestamp"].as(), 50000000UL); - ASSERT_LT(vDoc["timestamp"].as(), 1000000000UL); - ASSERT_EQ(vDoc["type"].as(), 3); -}; - -/**/ - -TEST(transactions, transaction_empty) { - Ark::Crypto::Transactions::Transaction transaction; - bool isValid = transaction.verify(); - ASSERT_FALSE(isValid); -} - -/**/ - -TEST(transactions, transaction_asset_signature) { // NOLINT - const auto publicKeyString = "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699"; - Ark::Crypto::Transactions::TransactionAsset asset; - asset.signature.publicKey = publicKeyString; - ASSERT_STREQ(asset.signature.publicKey.c_str(), publicKeyString); -} - -/**/ - -TEST(transactions, transaction_asset_delegate) { - const auto testUsername = "testUsername"; - Ark::Crypto::Transactions::TransactionAsset asset; - asset.delegate.username = "testUsername"; - ASSERT_STREQ(asset.delegate.username.c_str(), testUsername); -} - -/**/ - -TEST(transactions, transaction_asset_multisignature) { - const auto min = 2; - const auto lifetime = 24; - std::vector keysgroup = { - "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" - }; - - Ark::Crypto::Transactions::TransactionAsset asset; - asset.multiSignature.min = min; - asset.multiSignature.lifetime = lifetime; - asset.multiSignature.keysgroup = keysgroup; - ASSERT_EQ(asset.multiSignature.min, min); - ASSERT_EQ(asset.multiSignature.lifetime, lifetime); - ASSERT_TRUE(asset.multiSignature.keysgroup[0] == keysgroup[0]); - ASSERT_TRUE(asset.multiSignature.keysgroup[1] == keysgroup[1]); - ASSERT_TRUE(asset.multiSignature.keysgroup[2] == keysgroup[2]); -} diff --git a/test/utils/message.cpp b/test/utils/message.cpp deleted file mode 100644 index 45333523..00000000 --- a/test/utils/message.cpp +++ /dev/null @@ -1,57 +0,0 @@ - -#include "gtest/gtest.h" - -#include "utils/message.h" - -#include - -namespace { // NOLINT - //ARK Core test fixtures: - // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts - const auto text = "Hello World"; - const auto passphrase = "this is a top secret passphrase"; - const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; - const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - const auto expectedJsonString = "{" - "\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\"," - "\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\"," - "\"message\":\"Hello World\"" - "}"; -} // namespace - -/**/ - -TEST(utils, message_sign) { - Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedSignature, BytesToHex(message.signature).c_str()); - ASSERT_TRUE(message.verify()); -} - -/**/ - -TEST(utils, message_to_array) { - Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - std::map messageArray = message.toArray(); - ASSERT_STREQ(expectedPublicKey, messageArray["publickey"].c_str()); - ASSERT_STREQ(expectedSignature, messageArray["signature"].c_str()); - ASSERT_STREQ(text, messageArray["message"].c_str()); -} - -/**/ - -TEST(utils, message_to_json) { - Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedJsonString, message.toJson().c_str()); -} - -/**/ - -TEST(utils, message_verify) { - PublicKey publicKey = PublicKey::fromHex(expectedPublicKey); - std::vector signature = HexToBytes(expectedSignature); - Ark::Crypto::Utils::Message message(text, publicKey, signature); - ASSERT_TRUE(message.verify()); -} diff --git a/test/utils/slot.cpp b/test/utils/slot.cpp deleted file mode 100644 index aaf3679a..00000000 --- a/test/utils/slot.cpp +++ /dev/null @@ -1,26 +0,0 @@ - -#include "gtest/gtest.h" - -#include "arkCrypto.h" - -TEST(utilities, slots_epoch) { - const auto devnet = Networks::Devnet(); - const auto arkEpoch = 1490101200ULL; - ASSERT_EQ(arkEpoch, Slot::epoch(devnet)); -} - -/**/ - -TEST(utilities, slots_time) { - const auto devnet = Networks::Devnet(); - // const auto mainnet = Networks::Mainnet; - - // 28 Jan 2019(in seconds) - Ark Epoch (seconds) - const auto testTime = (1548725761ULL - 1490101200ULL); - const auto slotTime = Slot::time(devnet); - - // test that slot-time is more recent than 'testTime', - ASSERT_GT(slotTime , testTime); - // also check that the 'slotTime' is not too large (e.g. from an overflow). - ASSERT_LT(slotTime, (testTime) + 315360000ULL); // 315360000s = 10yrs -} From 79d105708aa34d7cca186bcad41b6221cad1f266 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:32:49 -0700 Subject: [PATCH 22/29] ci: update sketch path --- .circleci/script_arduino.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 87107574..1d49b33a 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -8,4 +8,4 @@ mv ~/project/* ~/Arduino/libraries/cpp-crypto arduino-cli lib install "ArduinoJson@6.10.0" arduino-cli lib install "BIP66" -arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/arduino/ESP32/ESP32.ino --debug +arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/ESP32/ESP32.ino --debug From ff4b42a02a06bb624b72463ae0809fedd8548742 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:38:32 -0700 Subject: [PATCH 23/29] ci: remove arduino_ide bash call. --- .circleci/script_arduino.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 1d49b33a..5a0ed81b 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash -bash ./extras/ARDUINO_IDE.sh --auto - mkdir -p ~/Arduino/libraries/cpp-crypto/ mv ~/project/* ~/Arduino/libraries/cpp-crypto From 467eab2533af301d4b726d52916c39583c867ba3 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:41:32 -0700 Subject: [PATCH 24/29] ci: add micro-ecc arduino dependency --- .circleci/script_arduino.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 5a0ed81b..e70996d4 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -5,5 +5,6 @@ mv ~/project/* ~/Arduino/libraries/cpp-crypto arduino-cli lib install "ArduinoJson@6.10.0" arduino-cli lib install "BIP66" +arduino-cli lib install "micro-ecc" arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/ESP32/ESP32.ino --debug From 007c3a61f2282ddef6783c28de6fe702809e8539 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:45:53 -0700 Subject: [PATCH 25/29] chore(changelog): add v.0.6.0 tag --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d5db682..f5339077 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [0.6.0] - 2019-07-101 ### Added From 2510281468e9ea2a7bbf41ae56d5611520d65c65 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:46:21 -0700 Subject: [PATCH 26/29] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5339077..bf12b824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## [0.6.0] - 2019-07-101 +## [0.6.0] - 2019-07-01 ### Added From c23c65df2dc2b937881ae5d08ed40b4de67fa171 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 08:48:19 -0700 Subject: [PATCH 27/29] chore(changelog): add v.0.6.0 tag --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d5db682..93122b21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [0.6.0-arduino] - 2019-07-01 + +## [0.6.0] - 2019-07-01 ### Added From b1a8ac58d560a91ee73b063f679e56d1da62128a Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 09:05:58 -0700 Subject: [PATCH 28/29] ci: add micro-ecc arduino dependency --- .circleci/script_arduino.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 87107574..2431bd3b 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -7,5 +7,6 @@ mv ~/project/* ~/Arduino/libraries/cpp-crypto arduino-cli lib install "ArduinoJson@6.10.0" arduino-cli lib install "BIP66" +arduino-cli lib install "micro-ecc" arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/arduino/ESP32/ESP32.ino --debug From a9069d623f9216d650372c56d7387aa7f3d3656b Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 1 Jul 2019 09:37:33 -0700 Subject: [PATCH 29/29] Delete date.h --- src/date/date.h | 8344 ----------------------------------------------- 1 file changed, 8344 deletions(-) delete mode 100644 src/date/date.h diff --git a/src/date/date.h b/src/date/date.h deleted file mode 100644 index b67d14b3..00000000 --- a/src/date/date.h +++ /dev/null @@ -1,8344 +0,0 @@ -#ifndef DATE_H -#define DATE_H - -// The MIT License (MIT) -// -// Copyright (c) 2015, 2016, 2017 Howard Hinnant -// Copyright (c) 2016 Adrian Colomitchi -// Copyright (c) 2017 Florian Dang -// Copyright (c) 2017 Paul Thompson -// Copyright (c) 2018 Tomasz Kamiński -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// Our apologies. When the previous paragraph was written, lowercase had not yet -// been invented (that would involve another several millennia of evolution). -// We did not mean to shout. - -#ifndef HAS_STRING_VIEW -# if __cplusplus >= 201703 -# define HAS_STRING_VIEW 1 -# else -# define HAS_STRING_VIEW 0 -# endif -#endif // HAS_STRING_VIEW - -#include -#include -#include -#include -#include -#if !(__cplusplus >= 201402) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if HAS_STRING_VIEW -# include -#endif -#include -#include - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpedantic" -# if __GNUC__ < 5 - // GCC 4.9 Bug 61489 Wrong warning with -Wmissing-field-initializers -# pragma GCC diagnostic ignored "-Wmissing-field-initializers" -# endif -#endif - -namespace date -{ - -//---------------+ -// Configuration | -//---------------+ - -// Always use C locale to ensure maximum support for different compilers -// https ://github.com/HowardHinnant/date/issues/264 -#define ONLY_C_LOCALE 1 - -#if defined(_MSC_VER) && (!defined(__clang__) || (_MSC_VER < 1910)) -// MSVC -# define _SILENCE_CXX17_UNCAUGHT_EXCEPTION_DEPRECATION_WARNING -# if _MSC_VER < 1910 -// before VS2017 -# define CONSTDATA const -# define CONSTCD11 -# define CONSTCD14 -# define NOEXCEPT _NOEXCEPT -# else -// VS2017 and later -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 constexpr -# define NOEXCEPT noexcept -# endif - -#elif defined(__SUNPRO_CC) && __SUNPRO_CC <= 0x5150 -// Oracle Developer Studio 12.6 and earlier -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 -# define NOEXCEPT noexcept - -#elif __cplusplus >= 201402 -// C++14 -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 constexpr -# define NOEXCEPT noexcept -#else -// C++11 -# define CONSTDATA constexpr const -# define CONSTCD11 constexpr -# define CONSTCD14 -# define NOEXCEPT noexcept -#endif - -#ifndef HAS_VOID_T -# if __cplusplus >= 201703 -# define HAS_VOID_T 1 -# else -# define HAS_VOID_T 0 -# endif -#endif // HAS_VOID_T - -// Protect from Oracle sun macro -#ifdef sun -# undef sun -#endif - -//-----------+ -// Interface | -//-----------+ - -// durations - -using days = std::chrono::duration - , std::chrono::hours::period>>; - -using weeks = std::chrono::duration - , days::period>>; - -using years = std::chrono::duration - , days::period>>; - -using months = std::chrono::duration - >>; - -// time_point - -template - using sys_time = std::chrono::time_point; - -using sys_days = sys_time; -using sys_seconds = sys_time; - -struct local_t {}; - -template - using local_time = std::chrono::time_point; - -using local_seconds = local_time; -using local_days = local_time; - -// types - -struct last_spec -{ - explicit last_spec() = default; -}; - -class day; -class month; -class year; - -class weekday; -class weekday_indexed; -class weekday_last; - -class month_day; -class month_day_last; -class month_weekday; -class month_weekday_last; - -class year_month; - -class year_month_day; -class year_month_day_last; -class year_month_weekday; -class year_month_weekday_last; - -// date composition operators - -CONSTCD11 year_month operator/(const year& y, const month& m) NOEXCEPT; -CONSTCD11 year_month operator/(const year& y, int m) NOEXCEPT; - -CONSTCD11 month_day operator/(const day& d, const month& m) NOEXCEPT; -CONSTCD11 month_day operator/(const day& d, int m) NOEXCEPT; -CONSTCD11 month_day operator/(const month& m, const day& d) NOEXCEPT; -CONSTCD11 month_day operator/(const month& m, int d) NOEXCEPT; -CONSTCD11 month_day operator/(int m, const day& d) NOEXCEPT; - -CONSTCD11 month_day_last operator/(const month& m, last_spec) NOEXCEPT; -CONSTCD11 month_day_last operator/(int m, last_spec) NOEXCEPT; -CONSTCD11 month_day_last operator/(last_spec, const month& m) NOEXCEPT; -CONSTCD11 month_day_last operator/(last_spec, int m) NOEXCEPT; - -CONSTCD11 month_weekday operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT; -CONSTCD11 month_weekday operator/(int m, const weekday_indexed& wdi) NOEXCEPT; -CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT; -CONSTCD11 month_weekday operator/(const weekday_indexed& wdi, int m) NOEXCEPT; - -CONSTCD11 month_weekday_last operator/(const month& m, const weekday_last& wdl) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(int m, const weekday_last& wdl) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, const month& m) NOEXCEPT; -CONSTCD11 month_weekday_last operator/(const weekday_last& wdl, int m) NOEXCEPT; - -CONSTCD11 year_month_day operator/(const year_month& ym, const day& d) NOEXCEPT; -CONSTCD11 year_month_day operator/(const year_month& ym, int d) NOEXCEPT; -CONSTCD11 year_month_day operator/(const year& y, const month_day& md) NOEXCEPT; -CONSTCD11 year_month_day operator/(int y, const month_day& md) NOEXCEPT; -CONSTCD11 year_month_day operator/(const month_day& md, const year& y) NOEXCEPT; -CONSTCD11 year_month_day operator/(const month_day& md, int y) NOEXCEPT; - -CONSTCD11 - year_month_day_last operator/(const year_month& ym, last_spec) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const year& y, const month_day_last& mdl) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(int y, const month_day_last& mdl) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const month_day_last& mdl, const year& y) NOEXCEPT; -CONSTCD11 - year_month_day_last operator/(const month_day_last& mdl, int y) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const year& y, const month_weekday& mwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(int y, const month_weekday& mwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const month_weekday& mwd, const year& y) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator/(const month_weekday& mwd, int y) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(int y, const month_weekday_last& mwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator/(const month_weekday_last& mwdl, int y) NOEXCEPT; - -// Detailed interface - -// day - -class day -{ - unsigned char d_; - -public: - day() = default; - explicit CONSTCD11 day(unsigned d) NOEXCEPT; - - CONSTCD14 day& operator++() NOEXCEPT; - CONSTCD14 day operator++(int) NOEXCEPT; - CONSTCD14 day& operator--() NOEXCEPT; - CONSTCD14 day operator--(int) NOEXCEPT; - - CONSTCD14 day& operator+=(const days& d) NOEXCEPT; - CONSTCD14 day& operator-=(const days& d) NOEXCEPT; - - CONSTCD11 explicit operator unsigned() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator< (const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator> (const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const day& x, const day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const day& x, const day& y) NOEXCEPT; - -CONSTCD11 day operator+(const day& x, const days& y) NOEXCEPT; -CONSTCD11 day operator+(const days& x, const day& y) NOEXCEPT; -CONSTCD11 day operator-(const day& x, const days& y) NOEXCEPT; -CONSTCD11 days operator-(const day& x, const day& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const day& d); - -// month - -class month -{ - unsigned char m_; - -public: - month() = default; - explicit CONSTCD11 month(unsigned m) NOEXCEPT; - - CONSTCD14 month& operator++() NOEXCEPT; - CONSTCD14 month operator++(int) NOEXCEPT; - CONSTCD14 month& operator--() NOEXCEPT; - CONSTCD14 month operator--(int) NOEXCEPT; - - CONSTCD14 month& operator+=(const months& m) NOEXCEPT; - CONSTCD14 month& operator-=(const months& m) NOEXCEPT; - - CONSTCD11 explicit operator unsigned() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator< (const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator> (const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month& x, const month& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month& x, const month& y) NOEXCEPT; - -CONSTCD14 month operator+(const month& x, const months& y) NOEXCEPT; -CONSTCD14 month operator+(const months& x, const month& y) NOEXCEPT; -CONSTCD14 month operator-(const month& x, const months& y) NOEXCEPT; -CONSTCD14 months operator-(const month& x, const month& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month& m); - -// year - -class year -{ - short y_; - -public: - year() = default; - explicit CONSTCD11 year(int y) NOEXCEPT; - - CONSTCD14 year& operator++() NOEXCEPT; - CONSTCD14 year operator++(int) NOEXCEPT; - CONSTCD14 year& operator--() NOEXCEPT; - CONSTCD14 year operator--(int) NOEXCEPT; - - CONSTCD14 year& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 year operator-() const NOEXCEPT; - CONSTCD11 year operator+() const NOEXCEPT; - - CONSTCD11 bool is_leap() const NOEXCEPT; - - CONSTCD11 explicit operator int() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; - - static CONSTCD11 year min() NOEXCEPT; - static CONSTCD11 year max() NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator< (const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator> (const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year& x, const year& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year& x, const year& y) NOEXCEPT; - -CONSTCD11 year operator+(const year& x, const years& y) NOEXCEPT; -CONSTCD11 year operator+(const years& x, const year& y) NOEXCEPT; -CONSTCD11 year operator-(const year& x, const years& y) NOEXCEPT; -CONSTCD11 years operator-(const year& x, const year& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year& y); - -// weekday - -class weekday -{ - unsigned char wd_; -public: - weekday() = default; - explicit CONSTCD11 weekday(unsigned wd) NOEXCEPT; - CONSTCD11 weekday(const sys_days& dp) NOEXCEPT; - CONSTCD11 explicit weekday(const local_days& dp) NOEXCEPT; - - CONSTCD14 weekday& operator++() NOEXCEPT; - CONSTCD14 weekday operator++(int) NOEXCEPT; - CONSTCD14 weekday& operator--() NOEXCEPT; - CONSTCD14 weekday operator--(int) NOEXCEPT; - - CONSTCD14 weekday& operator+=(const days& d) NOEXCEPT; - CONSTCD14 weekday& operator-=(const days& d) NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; - - CONSTCD11 weekday_indexed operator[](unsigned index) const NOEXCEPT; - CONSTCD11 weekday_last operator[](last_spec) const NOEXCEPT; - -private: - static CONSTCD11 unsigned char weekday_from_days(int z) NOEXCEPT; - - friend CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; - friend CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; - friend CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; - template - friend std::basic_ostream& - operator<<(std::basic_ostream& os, const weekday& wd); - friend class weekday_indexed; -}; - -CONSTCD11 bool operator==(const weekday& x, const weekday& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday& x, const weekday& y) NOEXCEPT; - -CONSTCD14 weekday operator+(const weekday& x, const days& y) NOEXCEPT; -CONSTCD14 weekday operator+(const days& x, const weekday& y) NOEXCEPT; -CONSTCD14 weekday operator-(const weekday& x, const days& y) NOEXCEPT; -CONSTCD14 days operator-(const weekday& x, const weekday& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday& wd); - -// weekday_indexed - -class weekday_indexed -{ - unsigned char wd_ : 4; - unsigned char index_ : 4; - -public: - weekday_indexed() = default; - CONSTCD11 weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT; - - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 unsigned index() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_indexed& wdi); - -// weekday_last - -class weekday_last -{ - date::weekday wd_; - -public: - explicit CONSTCD11 weekday_last(const date::weekday& wd) NOEXCEPT; - - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT; -CONSTCD11 bool operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_last& wdl); - -namespace detail -{ - -struct unspecified_month_disambiguator {}; - -} // namespace detail - -// year_month - -class year_month -{ - date::year y_; - date::month m_; - -public: - year_month() = default; - CONSTCD11 year_month(const date::year& y, const date::month& m) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - - template - CONSTCD14 year_month& operator+=(const months& dm) NOEXCEPT; - template - CONSTCD14 year_month& operator-=(const months& dm) NOEXCEPT; - CONSTCD14 year_month& operator+=(const years& dy) NOEXCEPT; - CONSTCD14 year_month& operator-=(const years& dy) NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator< (const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator> (const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year_month& x, const year_month& y) NOEXCEPT; - -template -CONSTCD14 year_month operator+(const year_month& ym, const months& dm) NOEXCEPT; -template -CONSTCD14 year_month operator+(const months& dm, const year_month& ym) NOEXCEPT; -template -CONSTCD14 year_month operator-(const year_month& ym, const months& dm) NOEXCEPT; - -CONSTCD11 months operator-(const year_month& x, const year_month& y) NOEXCEPT; -CONSTCD11 year_month operator+(const year_month& ym, const years& dy) NOEXCEPT; -CONSTCD11 year_month operator+(const years& dy, const year_month& ym) NOEXCEPT; -CONSTCD11 year_month operator-(const year_month& ym, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month& ym); - -// month_day - -class month_day -{ - date::month m_; - date::day d_; - -public: - month_day() = default; - CONSTCD11 month_day(const date::month& m, const date::day& d) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::day day() const NOEXCEPT; - - CONSTCD14 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator< (const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator> (const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month_day& x, const month_day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month_day& x, const month_day& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day& md); - -// month_day_last - -class month_day_last -{ - date::month m_; - -public: - CONSTCD11 explicit month_day_last(const date::month& m) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator< (const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator> (const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT; -CONSTCD11 bool operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day_last& mdl); - -// month_weekday - -class month_weekday -{ - date::month m_; - date::weekday_indexed wdi_; -public: - CONSTCD11 month_weekday(const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT; -CONSTCD11 bool operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday& mwd); - -// month_weekday_last - -class month_weekday_last -{ - date::month m_; - date::weekday_last wdl_; - -public: - CONSTCD11 month_weekday_last(const date::month& m, - const date::weekday_last& wd) NOEXCEPT; - - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; - - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday_last& mwdl); - -// class year_month_day - -class year_month_day -{ - date::year y_; - date::month m_; - date::day d_; - -public: - year_month_day() = default; - CONSTCD11 year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT; - CONSTCD14 year_month_day(const year_month_day_last& ymdl) NOEXCEPT; - - CONSTCD14 year_month_day(sys_days dp) NOEXCEPT; - CONSTCD14 explicit year_month_day(local_days dp) NOEXCEPT; - - template - CONSTCD14 year_month_day& operator+=(const months& m) NOEXCEPT; - template - CONSTCD14 year_month_day& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::day day() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD14 bool ok() const NOEXCEPT; - -private: - static CONSTCD14 year_month_day from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 bool operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator< (const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator> (const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT; -CONSTCD11 bool operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT; - -template -CONSTCD14 year_month_day operator+(const year_month_day& ymd, const months& dm) NOEXCEPT; -template -CONSTCD14 year_month_day operator+(const months& dm, const year_month_day& ymd) NOEXCEPT; -template -CONSTCD14 year_month_day operator-(const year_month_day& ymd, const months& dm) NOEXCEPT; -CONSTCD11 year_month_day operator+(const year_month_day& ymd, const years& dy) NOEXCEPT; -CONSTCD11 year_month_day operator+(const years& dy, const year_month_day& ymd) NOEXCEPT; -CONSTCD11 year_month_day operator-(const year_month_day& ymd, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day& ymd); - -// year_month_day_last - -class year_month_day_last -{ - date::year y_; - date::month_day_last mdl_; - -public: - CONSTCD11 year_month_day_last(const date::year& y, - const date::month_day_last& mdl) NOEXCEPT; - - template - CONSTCD14 year_month_day_last& operator+=(const months& m) NOEXCEPT; - template - CONSTCD14 year_month_day_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_day_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_day_last& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::month_day_last month_day_last() const NOEXCEPT; - CONSTCD14 date::day day() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator< (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator> (const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; -CONSTCD11 - bool operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT; - -template -CONSTCD14 -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; - -template -CONSTCD14 -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT; - -template -CONSTCD14 -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day_last& ymdl); - -// year_month_weekday - -class year_month_weekday -{ - date::year y_; - date::month m_; - date::weekday_indexed wdi_; - -public: - year_month_weekday() = default; - CONSTCD11 year_month_weekday(const date::year& y, const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT; - CONSTCD14 year_month_weekday(const sys_days& dp) NOEXCEPT; - CONSTCD14 explicit year_month_weekday(const local_days& dp) NOEXCEPT; - - template - CONSTCD14 year_month_weekday& operator+=(const months& m) NOEXCEPT; - template - CONSTCD14 year_month_weekday& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 unsigned index() const NOEXCEPT; - CONSTCD11 date::weekday_indexed weekday_indexed() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD14 bool ok() const NOEXCEPT; - -private: - static CONSTCD14 year_month_weekday from_days(days dp) NOEXCEPT; - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 - bool operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; -CONSTCD11 - bool operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi); - -// year_month_weekday_last - -class year_month_weekday_last -{ - date::year y_; - date::month m_; - date::weekday_last wdl_; - -public: - CONSTCD11 year_month_weekday_last(const date::year& y, const date::month& m, - const date::weekday_last& wdl) NOEXCEPT; - - template - CONSTCD14 year_month_weekday_last& operator+=(const months& m) NOEXCEPT; - template - CONSTCD14 year_month_weekday_last& operator-=(const months& m) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator+=(const years& y) NOEXCEPT; - CONSTCD14 year_month_weekday_last& operator-=(const years& y) NOEXCEPT; - - CONSTCD11 date::year year() const NOEXCEPT; - CONSTCD11 date::month month() const NOEXCEPT; - CONSTCD11 date::weekday weekday() const NOEXCEPT; - CONSTCD11 date::weekday_last weekday_last() const NOEXCEPT; - - CONSTCD14 operator sys_days() const NOEXCEPT; - CONSTCD14 explicit operator local_days() const NOEXCEPT; - CONSTCD11 bool ok() const NOEXCEPT; - -private: - CONSTCD14 days to_days() const NOEXCEPT; -}; - -CONSTCD11 -bool -operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; - -CONSTCD11 -bool -operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT; - -template -CONSTCD14 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT; - -CONSTCD11 -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT; - -template -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl); - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -inline namespace literals -{ - -CONSTCD11 date::day operator "" _d(unsigned long long d) NOEXCEPT; -CONSTCD11 date::year operator "" _y(unsigned long long y) NOEXCEPT; - -} // inline namespace literals -#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) - -// CONSTDATA date::month January{1}; -// CONSTDATA date::month February{2}; -// CONSTDATA date::month March{3}; -// CONSTDATA date::month April{4}; -// CONSTDATA date::month May{5}; -// CONSTDATA date::month June{6}; -// CONSTDATA date::month July{7}; -// CONSTDATA date::month August{8}; -// CONSTDATA date::month September{9}; -// CONSTDATA date::month October{10}; -// CONSTDATA date::month November{11}; -// CONSTDATA date::month December{12}; -// -// CONSTDATA date::weekday Sunday{0u}; -// CONSTDATA date::weekday Monday{1u}; -// CONSTDATA date::weekday Tuesday{2u}; -// CONSTDATA date::weekday Wednesday{3u}; -// CONSTDATA date::weekday Thursday{4u}; -// CONSTDATA date::weekday Friday{5u}; -// CONSTDATA date::weekday Saturday{6u}; - -#if HAS_VOID_T - -template > -struct is_clock - : std::false_type -{}; - -template -struct is_clock> - : std::true_type -{}; - -#endif // HAS_VOID_T - -//----------------+ -// Implementation | -//----------------+ - -// utilities -namespace detail { - -template> -class save_istream -{ -protected: - std::basic_ios& is_; - CharT fill_; - std::ios::fmtflags flags_; - std::streamsize width_; - std::basic_ostream* tie_; - std::locale loc_; - -public: - ~save_istream() - { - is_.fill(fill_); - is_.flags(flags_); - is_.width(width_); - is_.imbue(loc_); - is_.tie(tie_); - } - - save_istream(const save_istream&) = delete; - save_istream& operator=(const save_istream&) = delete; - - explicit save_istream(std::basic_ios& is) - : is_(is) - , fill_(is.fill()) - , flags_(is.flags()) - , width_(is.width(0)) - , tie_(is.tie(nullptr)) - , loc_(is.getloc()) - { - if (tie_ != nullptr) - tie_->flush(); - } -}; - -template> -class save_ostream - : private save_istream -{ -public: - ~save_ostream() - { - if ((this->flags_ & std::ios::unitbuf) && -#if __cplusplus >= 201703 - std::uncaught_exceptions() == 0 && -#else - !std::uncaught_exception() && -#endif - this->is_.good()) - this->is_.rdbuf()->pubsync(); - } - - save_ostream(const save_ostream&) = delete; - save_ostream& operator=(const save_ostream&) = delete; - - explicit save_ostream(std::basic_ios& os) - : save_istream(os) - { - } -}; - -template -struct choose_trunc_type -{ - static const int digits = std::numeric_limits::digits; - using type = typename std::conditional - < - digits < 32, - std::int32_t, - typename std::conditional - < - digits < 64, - std::int64_t, -#ifdef __SIZEOF_INT128__ - __int128 -#else - std::int64_t -#endif - >::type - >::type; -}; - -template -CONSTCD11 -inline -typename std::enable_if -< - !std::chrono::treat_as_floating_point::value, - T ->::type -trunc(T t) NOEXCEPT -{ - return t; -} - -template -CONSTCD14 -inline -typename std::enable_if -< - std::chrono::treat_as_floating_point::value, - T ->::type -trunc(T t) NOEXCEPT -{ - using namespace std; - using I = typename choose_trunc_type::type; - CONSTDATA auto digits = numeric_limits::digits; - static_assert(digits < numeric_limits::digits, ""); - CONSTDATA auto max = I{1} << (digits-1); - CONSTDATA auto min = -max; - const auto negative = t < T{0}; - if (min <= t && t <= max && t != 0 && t == t) - { - t = static_cast(static_cast(t)); - if (t == 0 && negative) - t = -t; - } - return t; -} - -template -struct static_gcd -{ - static const std::intmax_t value = static_gcd::value; -}; - -template -struct static_gcd -{ - static const std::intmax_t value = Xp; -}; - -template <> -struct static_gcd<0, 0> -{ - static const std::intmax_t value = 1; -}; - -template -struct no_overflow -{ -private: - static const std::intmax_t gcd_n1_n2 = static_gcd::value; - static const std::intmax_t gcd_d1_d2 = static_gcd::value; - static const std::intmax_t n1 = R1::num / gcd_n1_n2; - static const std::intmax_t d1 = R1::den / gcd_d1_d2; - static const std::intmax_t n2 = R2::num / gcd_n1_n2; - static const std::intmax_t d2 = R2::den / gcd_d1_d2; - static const std::intmax_t max = -((std::intmax_t(1) << - (sizeof(std::intmax_t) * CHAR_BIT - 1)) + 1); - - template - struct mul // overflow == false - { - static const std::intmax_t value = Xp * Yp; - }; - - template - struct mul - { - static const std::intmax_t value = 1; - }; - -public: - static const bool value = (n1 <= max / d2) && (n2 <= max / d1); - typedef std::ratio::value, - mul::value> type; -}; - -} // detail - -// trunc towards zero -template -CONSTCD11 -inline -typename std::enable_if -< - detail::no_overflow::value, - To ->::type -trunc(const std::chrono::duration& d) -{ - return To{detail::trunc(std::chrono::duration_cast(d).count())}; -} - -template -CONSTCD11 -inline -typename std::enable_if -< - !detail::no_overflow::value, - To ->::type -trunc(const std::chrono::duration& d) -{ - using namespace std::chrono; - using rep = typename std::common_type::type; - return To{detail::trunc(duration_cast(duration_cast>(d)).count())}; -} - -#ifndef HAS_CHRONO_ROUNDING -# if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023918 || (_MSC_FULL_VER >= 190000000 && defined (__clang__))) -# define HAS_CHRONO_ROUNDING 1 -# elif defined(__cpp_lib_chrono) && __cplusplus > 201402 && __cpp_lib_chrono >= 201510 -# define HAS_CHRONO_ROUNDING 1 -# elif defined(_LIBCPP_VERSION) && __cplusplus > 201402 && _LIBCPP_VERSION >= 3800 -# define HAS_CHRONO_ROUNDING 1 -# else -# define HAS_CHRONO_ROUNDING 0 -# endif -#endif // HAS_CHRONO_ROUNDING - -#if HAS_CHRONO_ROUNDING == 0 - -// round down -template -CONSTCD14 -inline -typename std::enable_if -< - detail::no_overflow::value, - To ->::type -floor(const std::chrono::duration& d) -{ - auto t = trunc(d); - if (t > d) - return t - To{1}; - return t; -} - -template -CONSTCD14 -inline -typename std::enable_if -< - !detail::no_overflow::value, - To ->::type -floor(const std::chrono::duration& d) -{ - using namespace std::chrono; - using rep = typename std::common_type::type; - return floor(floor>(d)); -} - -// round to nearest, to even on tie -template -CONSTCD14 -inline -To -round(const std::chrono::duration& d) -{ - auto t0 = floor(d); - auto t1 = t0 + To{1}; - if (t1 == To{0} && t0 < To{0}) - t1 = -t1; - auto diff0 = d - t0; - auto diff1 = t1 - d; - if (diff0 == diff1) - { - if (t0 - trunc(t0/2)*2 == To{0}) - return t0; - return t1; - } - if (diff0 < diff1) - return t0; - return t1; -} - -// round up -template -CONSTCD14 -inline -To -ceil(const std::chrono::duration& d) -{ - auto t = trunc(d); - if (t < d) - return t + To{1}; - return t; -} - -template ::is_signed - >::type> -CONSTCD11 -std::chrono::duration -abs(std::chrono::duration d) -{ - return d >= d.zero() ? d : -d; -} - -// round down -template -CONSTCD11 -inline -std::chrono::time_point -floor(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{date::floor(tp.time_since_epoch())}; -} - -// round to nearest, to even on tie -template -CONSTCD11 -inline -std::chrono::time_point -round(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{round(tp.time_since_epoch())}; -} - -// round up -template -CONSTCD11 -inline -std::chrono::time_point -ceil(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{ceil(tp.time_since_epoch())}; -} - -#else // HAS_CHRONO_ROUNDING == 1 - -using std::chrono::floor; -using std::chrono::ceil; -using std::chrono::round; -using std::chrono::abs; - -#endif // HAS_CHRONO_ROUNDING - -// trunc towards zero -template -CONSTCD11 -inline -std::chrono::time_point -trunc(const std::chrono::time_point& tp) -{ - using std::chrono::time_point; - return time_point{trunc(tp.time_since_epoch())}; -} - -// day - -CONSTCD11 inline day::day(unsigned d) NOEXCEPT : d_(static_cast(d)) {} -CONSTCD14 inline day& day::operator++() NOEXCEPT {++d_; return *this;} -CONSTCD14 inline day day::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline day& day::operator--() NOEXCEPT {--d_; return *this;} -CONSTCD14 inline day day::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} -CONSTCD14 inline day& day::operator+=(const days& d) NOEXCEPT {*this = *this + d; return *this;} -CONSTCD14 inline day& day::operator-=(const days& d) NOEXCEPT {*this = *this - d; return *this;} -CONSTCD11 inline day::operator unsigned() const NOEXCEPT {return d_;} -CONSTCD11 inline bool day::ok() const NOEXCEPT {return 1 <= d_ && d_ <= 31;} - -CONSTCD11 -inline -bool -operator==(const day& x, const day& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const day& x, const day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const day& x, const day& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const day& x, const day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const day& x, const day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const day& x, const day& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD11 -inline -days -operator-(const day& x, const day& y) NOEXCEPT -{ - return days{static_cast(static_cast(x) - - static_cast(y))}; -} - -CONSTCD11 -inline -day -operator+(const day& x, const days& y) NOEXCEPT -{ - return day{static_cast(x) + static_cast(y.count())}; -} - -CONSTCD11 -inline -day -operator+(const days& x, const day& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD11 -inline -day -operator-(const day& x, const days& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const day& d) -{ - detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(d); - if (!d.ok()) - os << " is not a valid day"; - return os; -} - -// month - -CONSTCD11 inline month::month(unsigned m) NOEXCEPT : m_(static_cast(m)) {} -CONSTCD14 inline month& month::operator++() NOEXCEPT {*this += months{1}; return *this;} -CONSTCD14 inline month month::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline month& month::operator--() NOEXCEPT {*this -= months{1}; return *this;} -CONSTCD14 inline month month::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} - -CONSTCD14 -inline -month& -month::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -CONSTCD14 -inline -month& -month::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD11 inline month::operator unsigned() const NOEXCEPT {return m_;} -CONSTCD11 inline bool month::ok() const NOEXCEPT {return 1 <= m_ && m_ <= 12;} - -CONSTCD11 -inline -bool -operator==(const month& x, const month& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const month& x, const month& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month& x, const month& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const month& x, const month& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month& x, const month& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month& x, const month& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD14 -inline -months -operator-(const month& x, const month& y) NOEXCEPT -{ - auto const d = static_cast(x) - static_cast(y); - return months(d <= 11 ? d : d + 12); -} - -CONSTCD14 -inline -month -operator+(const month& x, const months& y) NOEXCEPT -{ - auto const mu = static_cast(static_cast(x)) + (y.count() - 1); - auto const yr = (mu >= 0 ? mu : mu-11) / 12; - return month{static_cast(mu - yr * 12 + 1)}; -} - -CONSTCD14 -inline -month -operator+(const months& x, const month& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD14 -inline -month -operator-(const month& x, const months& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month& m) -{ - if (m.ok()) - { - CharT fmt[] = {'%', 'b', 0}; - os << format(os.getloc(), fmt, m); - } - else - os << static_cast(m) << " is not a valid month"; - return os; -} - -// year - -CONSTCD11 inline year::year(int y) NOEXCEPT : y_(static_cast(y)) {} -CONSTCD14 inline year& year::operator++() NOEXCEPT {++y_; return *this;} -CONSTCD14 inline year year::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline year& year::operator--() NOEXCEPT {--y_; return *this;} -CONSTCD14 inline year year::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} -CONSTCD14 inline year& year::operator+=(const years& y) NOEXCEPT {*this = *this + y; return *this;} -CONSTCD14 inline year& year::operator-=(const years& y) NOEXCEPT {*this = *this - y; return *this;} -CONSTCD11 inline year year::operator-() const NOEXCEPT {return year{-y_};} -CONSTCD11 inline year year::operator+() const NOEXCEPT {return *this;} - -CONSTCD11 -inline -bool -year::is_leap() const NOEXCEPT -{ - return y_ % 4 == 0 && (y_ % 100 != 0 || y_ % 400 == 0); -} - -CONSTCD11 inline year::operator int() const NOEXCEPT {return y_;} - -CONSTCD11 -inline -bool -year::ok() const NOEXCEPT -{ - return y_ != std::numeric_limits::min(); -} - -CONSTCD11 -inline -year -year::min() NOEXCEPT -{ - return year{-32767}; -} - -CONSTCD11 -inline -year -year::max() NOEXCEPT -{ - return year{32767}; -} - -CONSTCD11 -inline -bool -operator==(const year& x, const year& y) NOEXCEPT -{ - return static_cast(x) == static_cast(y); -} - -CONSTCD11 -inline -bool -operator!=(const year& x, const year& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year& x, const year& y) NOEXCEPT -{ - return static_cast(x) < static_cast(y); -} - -CONSTCD11 -inline -bool -operator>(const year& x, const year& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year& x, const year& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year& x, const year& y) NOEXCEPT -{ - return !(x < y); -} - -CONSTCD11 -inline -years -operator-(const year& x, const year& y) NOEXCEPT -{ - return years{static_cast(x) - static_cast(y)}; -} - -CONSTCD11 -inline -year -operator+(const year& x, const years& y) NOEXCEPT -{ - return year{static_cast(x) + y.count()}; -} - -CONSTCD11 -inline -year -operator+(const years& x, const year& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD11 -inline -year -operator-(const year& x, const years& y) NOEXCEPT -{ - return year{static_cast(x) - y.count()}; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year& y) -{ - detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::internal); - os.width(4 + (y < year{0})); - os << static_cast(y); - if (!y.ok()) - os << " is not a valid year"; - return os; -} - -// weekday - -CONSTCD11 -inline -unsigned char -weekday::weekday_from_days(int z) NOEXCEPT -{ - return static_cast(static_cast( - z >= -4 ? (z+4) % 7 : (z+5) % 7 + 6)); -} - -CONSTCD11 -inline -weekday::weekday(unsigned wd) NOEXCEPT - : wd_(static_cast(wd != 7 ? wd : 0)) - {} - -CONSTCD11 -inline -weekday::weekday(const sys_days& dp) NOEXCEPT - : wd_(weekday_from_days(dp.time_since_epoch().count())) - {} - -CONSTCD11 -inline -weekday::weekday(const local_days& dp) NOEXCEPT - : wd_(weekday_from_days(dp.time_since_epoch().count())) - {} - -CONSTCD14 inline weekday& weekday::operator++() NOEXCEPT {*this += days{1}; return *this;} -CONSTCD14 inline weekday weekday::operator++(int) NOEXCEPT {auto tmp(*this); ++(*this); return tmp;} -CONSTCD14 inline weekday& weekday::operator--() NOEXCEPT {*this -= days{1}; return *this;} -CONSTCD14 inline weekday weekday::operator--(int) NOEXCEPT {auto tmp(*this); --(*this); return tmp;} - -CONSTCD14 -inline -weekday& -weekday::operator+=(const days& d) NOEXCEPT -{ - *this = *this + d; - return *this; -} - -CONSTCD14 -inline -weekday& -weekday::operator-=(const days& d) NOEXCEPT -{ - *this = *this - d; - return *this; -} - -CONSTCD11 inline bool weekday::ok() const NOEXCEPT {return wd_ <= 6;} - -CONSTCD11 -inline -bool -operator==(const weekday& x, const weekday& y) NOEXCEPT -{ - return x.wd_ == y.wd_; -} - -CONSTCD11 -inline -bool -operator!=(const weekday& x, const weekday& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD14 -inline -days -operator-(const weekday& x, const weekday& y) NOEXCEPT -{ - auto const wdu = x.wd_ - y.wd_; - auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; - return days{wdu - wk * 7}; -} - -CONSTCD14 -inline -weekday -operator+(const weekday& x, const days& y) NOEXCEPT -{ - auto const wdu = static_cast(static_cast(x.wd_)) + y.count(); - auto const wk = (wdu >= 0 ? wdu : wdu-6) / 7; - return weekday{static_cast(wdu - wk * 7)}; -} - -CONSTCD14 -inline -weekday -operator+(const days& x, const weekday& y) NOEXCEPT -{ - return y + x; -} - -CONSTCD14 -inline -weekday -operator-(const weekday& x, const days& y) NOEXCEPT -{ - return x + -y; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday& wd) -{ - if (wd.ok()) - { - CharT fmt[] = {'%', 'a', 0}; - os << format(fmt, wd); - } - else - os << static_cast(wd.wd_) << " is not a valid weekday"; - return os; -} - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -inline namespace literals -{ - -CONSTCD11 -inline -date::day -operator "" _d(unsigned long long d) NOEXCEPT -{ - return date::day{static_cast(d)}; -} - -CONSTCD11 -inline -date::year -operator "" _y(unsigned long long y) NOEXCEPT -{ - return date::year(static_cast(y)); -} -#endif // !defined(_MSC_VER) || (_MSC_VER >= 1900) - -CONSTDATA date::last_spec last{}; - -CONSTDATA date::month jan{1}; -CONSTDATA date::month feb{2}; -CONSTDATA date::month mar{3}; -CONSTDATA date::month apr{4}; -CONSTDATA date::month may{5}; -CONSTDATA date::month jun{6}; -CONSTDATA date::month jul{7}; -CONSTDATA date::month aug{8}; -CONSTDATA date::month sep{9}; -CONSTDATA date::month oct{10}; -CONSTDATA date::month nov{11}; -CONSTDATA date::month dec{12}; - -CONSTDATA date::weekday sun{0u}; -CONSTDATA date::weekday mon{1u}; -CONSTDATA date::weekday tue{2u}; -CONSTDATA date::weekday wed{3u}; -CONSTDATA date::weekday thu{4u}; -CONSTDATA date::weekday fri{5u}; -CONSTDATA date::weekday sat{6u}; - -#if !defined(_MSC_VER) || (_MSC_VER >= 1900) -} // inline namespace literals -#endif - -CONSTDATA date::month January{1}; -CONSTDATA date::month February{2}; -CONSTDATA date::month March{3}; -CONSTDATA date::month April{4}; -CONSTDATA date::month May{5}; -CONSTDATA date::month June{6}; -CONSTDATA date::month July{7}; -CONSTDATA date::month August{8}; -CONSTDATA date::month September{9}; -CONSTDATA date::month October{10}; -CONSTDATA date::month November{11}; -CONSTDATA date::month December{12}; - -CONSTDATA date::weekday Monday{1}; -CONSTDATA date::weekday Tuesday{2}; -CONSTDATA date::weekday Wednesday{3}; -CONSTDATA date::weekday Thursday{4}; -CONSTDATA date::weekday Friday{5}; -CONSTDATA date::weekday Saturday{6}; -CONSTDATA date::weekday Sunday{7}; - -// weekday_indexed - -CONSTCD11 -inline -weekday -weekday_indexed::weekday() const NOEXCEPT -{ - return date::weekday{static_cast(wd_)}; -} - -CONSTCD11 inline unsigned weekday_indexed::index() const NOEXCEPT {return index_;} - -CONSTCD11 -inline -bool -weekday_indexed::ok() const NOEXCEPT -{ - return weekday().ok() && 1 <= index_ && index_ <= 5; -} - -#ifdef __GNUC__ -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" -#endif // __GNUC__ - -CONSTCD11 -inline -weekday_indexed::weekday_indexed(const date::weekday& wd, unsigned index) NOEXCEPT - : wd_(static_cast(static_cast(wd.wd_))) - , index_(static_cast(index)) - {} - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif // __GNUC__ - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_indexed& wdi) -{ - os << wdi.weekday() << '[' << wdi.index(); - if (!(1 <= wdi.index() && wdi.index() <= 5)) - os << " is not a valid index"; - os << ']'; - return os; -} - -CONSTCD11 -inline -weekday_indexed -weekday::operator[](unsigned index) const NOEXCEPT -{ - return {*this, index}; -} - -CONSTCD11 -inline -bool -operator==(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT -{ - return x.weekday() == y.weekday() && x.index() == y.index(); -} - -CONSTCD11 -inline -bool -operator!=(const weekday_indexed& x, const weekday_indexed& y) NOEXCEPT -{ - return !(x == y); -} - -// weekday_last - -CONSTCD11 inline date::weekday weekday_last::weekday() const NOEXCEPT {return wd_;} -CONSTCD11 inline bool weekday_last::ok() const NOEXCEPT {return wd_.ok();} -CONSTCD11 inline weekday_last::weekday_last(const date::weekday& wd) NOEXCEPT : wd_(wd) {} - -CONSTCD11 -inline -bool -operator==(const weekday_last& x, const weekday_last& y) NOEXCEPT -{ - return x.weekday() == y.weekday(); -} - -CONSTCD11 -inline -bool -operator!=(const weekday_last& x, const weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const weekday_last& wdl) -{ - return os << wdl.weekday() << "[last]"; -} - -CONSTCD11 -inline -weekday_last -weekday::operator[](last_spec) const NOEXCEPT -{ - return weekday_last{*this}; -} - -// year_month - -CONSTCD11 -inline -year_month::year_month(const date::year& y, const date::month& m) NOEXCEPT - : y_(y) - , m_(m) - {} - -CONSTCD11 inline year year_month::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month::month() const NOEXCEPT {return m_;} -CONSTCD11 inline bool year_month::ok() const NOEXCEPT {return y_.ok() && m_.ok();} - -template -CONSTCD14 -inline -year_month& -year_month::operator+=(const months& dm) NOEXCEPT -{ - *this = *this + dm; - return *this; -} - -template -CONSTCD14 -inline -year_month& -year_month::operator-=(const months& dm) NOEXCEPT -{ - *this = *this - dm; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator+=(const years& dy) NOEXCEPT -{ - *this = *this + dy; - return *this; -} - -CONSTCD14 -inline -year_month& -year_month::operator-=(const years& dy) NOEXCEPT -{ - *this = *this - dy; - return *this; -} - -CONSTCD11 -inline -bool -operator==(const year_month& x, const year_month& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month& x, const year_month& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month() < y.month())); -} - -CONSTCD11 -inline -bool -operator>(const year_month& x, const year_month& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month& x, const year_month& y) NOEXCEPT -{ - return !(x < y); -} - -template -CONSTCD14 -inline -year_month -operator+(const year_month& ym, const months& dm) NOEXCEPT -{ - auto dmi = static_cast(static_cast(ym.month())) - 1 + dm.count(); - auto dy = (dmi >= 0 ? dmi : dmi-11) / 12; - dmi = dmi - dy * 12 + 1; - return (ym.year() + years(dy)) / month(static_cast(dmi)); -} - -template -CONSTCD14 -inline -year_month -operator+(const months& dm, const year_month& ym) NOEXCEPT -{ - return ym + dm; -} - -template -CONSTCD14 -inline -year_month -operator-(const year_month& ym, const months& dm) NOEXCEPT -{ - return ym + -dm; -} - -CONSTCD11 -inline -months -operator-(const year_month& x, const year_month& y) NOEXCEPT -{ - return (x.year() - y.year()) + - months(static_cast(x.month()) - static_cast(y.month())); -} - -CONSTCD11 -inline -year_month -operator+(const year_month& ym, const years& dy) NOEXCEPT -{ - return (ym.year() + dy) / ym.month(); -} - -CONSTCD11 -inline -year_month -operator+(const years& dy, const year_month& ym) NOEXCEPT -{ - return ym + dy; -} - -CONSTCD11 -inline -year_month -operator-(const year_month& ym, const years& dy) NOEXCEPT -{ - return ym + -dy; -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month& ym) -{ - return os << ym.year() << '/' << ym.month(); -} - -// month_day - -CONSTCD11 -inline -month_day::month_day(const date::month& m, const date::day& d) NOEXCEPT - : m_(m) - , d_(d) - {} - -CONSTCD11 inline date::month month_day::month() const NOEXCEPT {return m_;} -CONSTCD11 inline date::day month_day::day() const NOEXCEPT {return d_;} - -CONSTCD14 -inline -bool -month_day::ok() const NOEXCEPT -{ - CONSTDATA date::day d[] = - { - date::day(31), date::day(29), date::day(31), - date::day(30), date::day(31), date::day(30), - date::day(31), date::day(31), date::day(30), - date::day(31), date::day(30), date::day(31) - }; - return m_.ok() && date::day{1} <= d_ && d_ <= d[static_cast(m_)-1]; -} - -CONSTCD11 -inline -bool -operator==(const month_day& x, const month_day& y) NOEXCEPT -{ - return x.month() == y.month() && x.day() == y.day(); -} - -CONSTCD11 -inline -bool -operator!=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month_day& x, const month_day& y) NOEXCEPT -{ - return x.month() < y.month() ? true - : (x.month() > y.month() ? false - : (x.day() < y.day())); -} - -CONSTCD11 -inline -bool -operator>(const month_day& x, const month_day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month_day& x, const month_day& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day& md) -{ - return os << md.month() << '/' << md.day(); -} - -// month_day_last - -CONSTCD11 inline month month_day_last::month() const NOEXCEPT {return m_;} -CONSTCD11 inline bool month_day_last::ok() const NOEXCEPT {return m_.ok();} -CONSTCD11 inline month_day_last::month_day_last(const date::month& m) NOEXCEPT : m_(m) {} - -CONSTCD11 -inline -bool -operator==(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return x.month() == y.month(); -} - -CONSTCD11 -inline -bool -operator!=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return x.month() < y.month(); -} - -CONSTCD11 -inline -bool -operator>(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const month_day_last& x, const month_day_last& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_day_last& mdl) -{ - return os << mdl.month() << "/last"; -} - -// month_weekday - -CONSTCD11 -inline -month_weekday::month_weekday(const date::month& m, - const date::weekday_indexed& wdi) NOEXCEPT - : m_(m) - , wdi_(wdi) - {} - -CONSTCD11 inline month month_weekday::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday_indexed -month_weekday::weekday_indexed() const NOEXCEPT -{ - return wdi_; -} - -CONSTCD11 -inline -bool -month_weekday::ok() const NOEXCEPT -{ - return m_.ok() && wdi_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const month_weekday& x, const month_weekday& y) NOEXCEPT -{ - return x.month() == y.month() && x.weekday_indexed() == y.weekday_indexed(); -} - -CONSTCD11 -inline -bool -operator!=(const month_weekday& x, const month_weekday& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday& mwd) -{ - return os << mwd.month() << '/' << mwd.weekday_indexed(); -} - -// month_weekday_last - -CONSTCD11 -inline -month_weekday_last::month_weekday_last(const date::month& m, - const date::weekday_last& wdl) NOEXCEPT - : m_(m) - , wdl_(wdl) - {} - -CONSTCD11 inline month month_weekday_last::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday_last -month_weekday_last::weekday_last() const NOEXCEPT -{ - return wdl_; -} - -CONSTCD11 -inline -bool -month_weekday_last::ok() const NOEXCEPT -{ - return m_.ok() && wdl_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT -{ - return x.month() == y.month() && x.weekday_last() == y.weekday_last(); -} - -CONSTCD11 -inline -bool -operator!=(const month_weekday_last& x, const month_weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const month_weekday_last& mwdl) -{ - return os << mwdl.month() << '/' << mwdl.weekday_last(); -} - -// year_month_day_last - -CONSTCD11 -inline -year_month_day_last::year_month_day_last(const date::year& y, - const date::month_day_last& mdl) NOEXCEPT - : y_(y) - , mdl_(mdl) - {} - -template -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -template -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day_last& -year_month_day_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_day_last::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_day_last::month() const NOEXCEPT {return mdl_.month();} - -CONSTCD11 -inline -month_day_last -year_month_day_last::month_day_last() const NOEXCEPT -{ - return mdl_; -} - -CONSTCD14 -inline -day -year_month_day_last::day() const NOEXCEPT -{ - CONSTDATA date::day d[] = - { - date::day(31), date::day(28), date::day(31), - date::day(30), date::day(31), date::day(30), - date::day(31), date::day(31), date::day(30), - date::day(31), date::day(30), date::day(31) - }; - return month() != February || !y_.is_leap() ? - d[static_cast(month()) - 1] : date::day{29}; -} - -CONSTCD14 -inline -year_month_day_last::operator sys_days() const NOEXCEPT -{ - return sys_days(year()/month()/day()); -} - -CONSTCD14 -inline -year_month_day_last::operator local_days() const NOEXCEPT -{ - return local_days(year()/month()/day()); -} - -CONSTCD11 -inline -bool -year_month_day_last::ok() const NOEXCEPT -{ - return y_.ok() && mdl_.ok(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return x.year() == y.year() && x.month_day_last() == y.month_day_last(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month_day_last() < y.month_day_last())); -} - -CONSTCD11 -inline -bool -operator>(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month_day_last& x, const year_month_day_last& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day_last& ymdl) -{ - return os << ymdl.year() << '/' << ymdl.month_day_last(); -} - -template -CONSTCD14 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return (ymdl.year() / ymdl.month() + dm) / last; -} - -template -CONSTCD14 -inline -year_month_day_last -operator+(const months& dm, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dm; -} - -template -CONSTCD14 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const months& dm) NOEXCEPT -{ - return ymdl + (-dm); -} - -CONSTCD11 -inline -year_month_day_last -operator+(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return {ymdl.year()+dy, ymdl.month_day_last()}; -} - -CONSTCD11 -inline -year_month_day_last -operator+(const years& dy, const year_month_day_last& ymdl) NOEXCEPT -{ - return ymdl + dy; -} - -CONSTCD11 -inline -year_month_day_last -operator-(const year_month_day_last& ymdl, const years& dy) NOEXCEPT -{ - return ymdl + (-dy); -} - -// year_month_day - -CONSTCD11 -inline -year_month_day::year_month_day(const date::year& y, const date::month& m, - const date::day& d) NOEXCEPT - : y_(y) - , m_(m) - , d_(d) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(const year_month_day_last& ymdl) NOEXCEPT - : y_(ymdl.year()) - , m_(ymdl.month()) - , d_(ymdl.day()) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(sys_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} - -CONSTCD14 -inline -year_month_day::year_month_day(local_days dp) NOEXCEPT - : year_month_day(from_days(dp.time_since_epoch())) - {} - -CONSTCD11 inline year year_month_day::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_day::month() const NOEXCEPT {return m_;} -CONSTCD11 inline day year_month_day::day() const NOEXCEPT {return d_;} - -template -CONSTCD14 -inline -year_month_day& -year_month_day::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -template -CONSTCD14 -inline -year_month_day& -year_month_day::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_day& -year_month_day::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD14 -inline -days -year_month_day::to_days() const NOEXCEPT -{ - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const y = static_cast(y_) - (m_ <= February); - auto const m = static_cast(m_); - auto const d = static_cast(d_); - auto const era = (y >= 0 ? y : y-399) / 400; - auto const yoe = static_cast(y - era * 400); // [0, 399] - auto const doy = (153*(m > 2 ? m-3 : m+9) + 2)/5 + d-1; // [0, 365] - auto const doe = yoe * 365 + yoe/4 - yoe/100 + doy; // [0, 146096] - return days{era * 146097 + static_cast(doe) - 719468}; -} - -CONSTCD14 -inline -year_month_day::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_day::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD14 -inline -bool -year_month_day::ok() const NOEXCEPT -{ - if (!(y_.ok() && m_.ok())) - return false; - return date::day{1} <= d_ && d_ <= (y_ / m_ / last).day(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && x.day() == y.day(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(x == y); -} - -CONSTCD11 -inline -bool -operator<(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return x.year() < y.year() ? true - : (x.year() > y.year() ? false - : (x.month() < y.month() ? true - : (x.month() > y.month() ? false - : (x.day() < y.day())))); -} - -CONSTCD11 -inline -bool -operator>(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return y < x; -} - -CONSTCD11 -inline -bool -operator<=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(y < x); -} - -CONSTCD11 -inline -bool -operator>=(const year_month_day& x, const year_month_day& y) NOEXCEPT -{ - return !(x < y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_day& ymd) -{ - detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os << ymd.year() << '-'; - os.width(2); - os << static_cast(ymd.month()) << '-'; - os << ymd.day(); - if (!ymd.ok()) - os << " is not a valid date"; - return os; -} - -CONSTCD14 -inline -year_month_day -year_month_day::from_days(days dp) NOEXCEPT -{ - static_assert(std::numeric_limits::digits >= 18, - "This algorithm has not been ported to a 16 bit unsigned integer"); - static_assert(std::numeric_limits::digits >= 20, - "This algorithm has not been ported to a 16 bit signed integer"); - auto const z = dp.count() + 719468; - auto const era = (z >= 0 ? z : z - 146096) / 146097; - auto const doe = static_cast(z - era * 146097); // [0, 146096] - auto const yoe = (doe - doe/1460 + doe/36524 - doe/146096) / 365; // [0, 399] - auto const y = static_cast(yoe) + era * 400; - auto const doy = doe - (365*yoe + yoe/4 - yoe/100); // [0, 365] - auto const mp = (5*doy + 2)/153; // [0, 11] - auto const d = doy - (153*mp+2)/5 + 1; // [1, 31] - auto const m = mp < 10 ? mp+3 : mp-9; // [1, 12] - return year_month_day{date::year{y + (m <= 2)}, date::month(m), date::day(d)}; -} - -template -CONSTCD14 -inline -year_month_day -operator+(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return (ymd.year() / ymd.month() + dm) / ymd.day(); -} - -template -CONSTCD14 -inline -year_month_day -operator+(const months& dm, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dm; -} - -template -CONSTCD14 -inline -year_month_day -operator-(const year_month_day& ymd, const months& dm) NOEXCEPT -{ - return ymd + (-dm); -} - -CONSTCD11 -inline -year_month_day -operator+(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return (ymd.year() + dy) / ymd.month() / ymd.day(); -} - -CONSTCD11 -inline -year_month_day -operator+(const years& dy, const year_month_day& ymd) NOEXCEPT -{ - return ymd + dy; -} - -CONSTCD11 -inline -year_month_day -operator-(const year_month_day& ymd, const years& dy) NOEXCEPT -{ - return ymd + (-dy); -} - -// year_month_weekday - -CONSTCD11 -inline -year_month_weekday::year_month_weekday(const date::year& y, const date::month& m, - const date::weekday_indexed& wdi) - NOEXCEPT - : y_(y) - , m_(m) - , wdi_(wdi) - {} - -CONSTCD14 -inline -year_month_weekday::year_month_weekday(const sys_days& dp) NOEXCEPT - : year_month_weekday(from_days(dp.time_since_epoch())) - {} - -CONSTCD14 -inline -year_month_weekday::year_month_weekday(const local_days& dp) NOEXCEPT - : year_month_weekday(from_days(dp.time_since_epoch())) - {} - -template -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -template -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday& -year_month_weekday::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_weekday::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_weekday::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday -year_month_weekday::weekday() const NOEXCEPT -{ - return wdi_.weekday(); -} - -CONSTCD11 -inline -unsigned -year_month_weekday::index() const NOEXCEPT -{ - return wdi_.index(); -} - -CONSTCD11 -inline -weekday_indexed -year_month_weekday::weekday_indexed() const NOEXCEPT -{ - return wdi_; -} - -CONSTCD14 -inline -year_month_weekday::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_weekday::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD14 -inline -bool -year_month_weekday::ok() const NOEXCEPT -{ - if (!y_.ok() || !m_.ok() || !wdi_.weekday().ok() || wdi_.index() < 1) - return false; - if (wdi_.index() <= 4) - return true; - auto d2 = wdi_.weekday() - date::weekday(static_cast(y_/m_/1)) + - days((wdi_.index()-1)*7 + 1); - return static_cast(d2.count()) <= static_cast((y_/m_/last).day()); -} - -CONSTCD14 -inline -year_month_weekday -year_month_weekday::from_days(days d) NOEXCEPT -{ - sys_days dp{d}; - auto const wd = date::weekday(dp); - auto const ymd = year_month_day(dp); - return {ymd.year(), ymd.month(), wd[(static_cast(ymd.day())-1)/7+1]}; -} - -CONSTCD14 -inline -days -year_month_weekday::to_days() const NOEXCEPT -{ - auto d = sys_days(y_/m_/1); - return (d + (wdi_.weekday() - date::weekday(d) + days{(wdi_.index()-1)*7}) - ).time_since_epoch(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && - x.weekday_indexed() == y.weekday_indexed(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_weekday& x, const year_month_weekday& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday& ymwdi) -{ - return os << ymwdi.year() << '/' << ymwdi.month() - << '/' << ymwdi.weekday_indexed(); -} - -template -CONSTCD14 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return (ymwd.year() / ymwd.month() + dm) / ymwd.weekday_indexed(); -} - -template -CONSTCD14 -inline -year_month_weekday -operator+(const months& dm, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dm; -} - -template -CONSTCD14 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const months& dm) NOEXCEPT -{ - return ymwd + (-dm); -} - -CONSTCD11 -inline -year_month_weekday -operator+(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return {ymwd.year()+dy, ymwd.month(), ymwd.weekday_indexed()}; -} - -CONSTCD11 -inline -year_month_weekday -operator+(const years& dy, const year_month_weekday& ymwd) NOEXCEPT -{ - return ymwd + dy; -} - -CONSTCD11 -inline -year_month_weekday -operator-(const year_month_weekday& ymwd, const years& dy) NOEXCEPT -{ - return ymwd + (-dy); -} - -// year_month_weekday_last - -CONSTCD11 -inline -year_month_weekday_last::year_month_weekday_last(const date::year& y, - const date::month& m, - const date::weekday_last& wdl) NOEXCEPT - : y_(y) - , m_(m) - , wdl_(wdl) - {} - -template -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const months& m) NOEXCEPT -{ - *this = *this + m; - return *this; -} - -template -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const months& m) NOEXCEPT -{ - *this = *this - m; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator+=(const years& y) NOEXCEPT -{ - *this = *this + y; - return *this; -} - -CONSTCD14 -inline -year_month_weekday_last& -year_month_weekday_last::operator-=(const years& y) NOEXCEPT -{ - *this = *this - y; - return *this; -} - -CONSTCD11 inline year year_month_weekday_last::year() const NOEXCEPT {return y_;} -CONSTCD11 inline month year_month_weekday_last::month() const NOEXCEPT {return m_;} - -CONSTCD11 -inline -weekday -year_month_weekday_last::weekday() const NOEXCEPT -{ - return wdl_.weekday(); -} - -CONSTCD11 -inline -weekday_last -year_month_weekday_last::weekday_last() const NOEXCEPT -{ - return wdl_; -} - -CONSTCD14 -inline -year_month_weekday_last::operator sys_days() const NOEXCEPT -{ - return sys_days{to_days()}; -} - -CONSTCD14 -inline -year_month_weekday_last::operator local_days() const NOEXCEPT -{ - return local_days{to_days()}; -} - -CONSTCD11 -inline -bool -year_month_weekday_last::ok() const NOEXCEPT -{ - return y_.ok() && m_.ok() && wdl_.ok(); -} - -CONSTCD14 -inline -days -year_month_weekday_last::to_days() const NOEXCEPT -{ - auto const d = sys_days(y_/m_/last); - return (d - (date::weekday{d} - wdl_.weekday())).time_since_epoch(); -} - -CONSTCD11 -inline -bool -operator==(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT -{ - return x.year() == y.year() && x.month() == y.month() && - x.weekday_last() == y.weekday_last(); -} - -CONSTCD11 -inline -bool -operator!=(const year_month_weekday_last& x, const year_month_weekday_last& y) NOEXCEPT -{ - return !(x == y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const year_month_weekday_last& ymwdl) -{ - return os << ymwdl.year() << '/' << ymwdl.month() << '/' << ymwdl.weekday_last(); -} - -template -CONSTCD14 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return (ymwdl.year() / ymwdl.month() + dm) / ymwdl.weekday_last(); -} - -template -CONSTCD14 -inline -year_month_weekday_last -operator+(const months& dm, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dm; -} - -template -CONSTCD14 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const months& dm) NOEXCEPT -{ - return ymwdl + (-dm); -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return {ymwdl.year()+dy, ymwdl.month(), ymwdl.weekday_last()}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator+(const years& dy, const year_month_weekday_last& ymwdl) NOEXCEPT -{ - return ymwdl + dy; -} - -CONSTCD11 -inline -year_month_weekday_last -operator-(const year_month_weekday_last& ymwdl, const years& dy) NOEXCEPT -{ - return ymwdl + (-dy); -} - -// year_month from operator/() - -CONSTCD11 -inline -year_month -operator/(const year& y, const month& m) NOEXCEPT -{ - return {y, m}; -} - -CONSTCD11 -inline -year_month -operator/(const year& y, int m) NOEXCEPT -{ - return y / month(static_cast(m)); -} - -// month_day from operator/() - -CONSTCD11 -inline -month_day -operator/(const month& m, const day& d) NOEXCEPT -{ - return {m, d}; -} - -CONSTCD11 -inline -month_day -operator/(const day& d, const month& m) NOEXCEPT -{ - return m / d; -} - -CONSTCD11 -inline -month_day -operator/(const month& m, int d) NOEXCEPT -{ - return m / day(static_cast(d)); -} - -CONSTCD11 -inline -month_day -operator/(int m, const day& d) NOEXCEPT -{ - return month(static_cast(m)) / d; -} - -CONSTCD11 inline month_day operator/(const day& d, int m) NOEXCEPT {return m / d;} - -// month_day_last from operator/() - -CONSTCD11 -inline -month_day_last -operator/(const month& m, last_spec) NOEXCEPT -{ - return month_day_last{m}; -} - -CONSTCD11 -inline -month_day_last -operator/(last_spec, const month& m) NOEXCEPT -{ - return m/last; -} - -CONSTCD11 -inline -month_day_last -operator/(int m, last_spec) NOEXCEPT -{ - return month(static_cast(m))/last; -} - -CONSTCD11 -inline -month_day_last -operator/(last_spec, int m) NOEXCEPT -{ - return m/last; -} - -// month_weekday from operator/() - -CONSTCD11 -inline -month_weekday -operator/(const month& m, const weekday_indexed& wdi) NOEXCEPT -{ - return {m, wdi}; -} - -CONSTCD11 -inline -month_weekday -operator/(const weekday_indexed& wdi, const month& m) NOEXCEPT -{ - return m / wdi; -} - -CONSTCD11 -inline -month_weekday -operator/(int m, const weekday_indexed& wdi) NOEXCEPT -{ - return month(static_cast(m)) / wdi; -} - -CONSTCD11 -inline -month_weekday -operator/(const weekday_indexed& wdi, int m) NOEXCEPT -{ - return m / wdi; -} - -// month_weekday_last from operator/() - -CONSTCD11 -inline -month_weekday_last -operator/(const month& m, const weekday_last& wdl) NOEXCEPT -{ - return {m, wdl}; -} - -CONSTCD11 -inline -month_weekday_last -operator/(const weekday_last& wdl, const month& m) NOEXCEPT -{ - return m / wdl; -} - -CONSTCD11 -inline -month_weekday_last -operator/(int m, const weekday_last& wdl) NOEXCEPT -{ - return month(static_cast(m)) / wdl; -} - -CONSTCD11 -inline -month_weekday_last -operator/(const weekday_last& wdl, int m) NOEXCEPT -{ - return m / wdl; -} - -// year_month_day from operator/() - -CONSTCD11 -inline -year_month_day -operator/(const year_month& ym, const day& d) NOEXCEPT -{ - return {ym.year(), ym.month(), d}; -} - -CONSTCD11 -inline -year_month_day -operator/(const year_month& ym, int d) NOEXCEPT -{ - return ym / day(static_cast(d)); -} - -CONSTCD11 -inline -year_month_day -operator/(const year& y, const month_day& md) NOEXCEPT -{ - return y / md.month() / md.day(); -} - -CONSTCD11 -inline -year_month_day -operator/(int y, const month_day& md) NOEXCEPT -{ - return year(y) / md; -} - -CONSTCD11 -inline -year_month_day -operator/(const month_day& md, const year& y) NOEXCEPT -{ - return y / md; -} - -CONSTCD11 -inline -year_month_day -operator/(const month_day& md, int y) NOEXCEPT -{ - return year(y) / md; -} - -// year_month_day_last from operator/() - -CONSTCD11 -inline -year_month_day_last -operator/(const year_month& ym, last_spec) NOEXCEPT -{ - return {ym.year(), month_day_last{ym.month()}}; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const year& y, const month_day_last& mdl) NOEXCEPT -{ - return {y, mdl}; -} - -CONSTCD11 -inline -year_month_day_last -operator/(int y, const month_day_last& mdl) NOEXCEPT -{ - return year(y) / mdl; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const month_day_last& mdl, const year& y) NOEXCEPT -{ - return y / mdl; -} - -CONSTCD11 -inline -year_month_day_last -operator/(const month_day_last& mdl, int y) NOEXCEPT -{ - return year(y) / mdl; -} - -// year_month_weekday from operator/() - -CONSTCD11 -inline -year_month_weekday -operator/(const year_month& ym, const weekday_indexed& wdi) NOEXCEPT -{ - return {ym.year(), ym.month(), wdi}; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const year& y, const month_weekday& mwd) NOEXCEPT -{ - return {y, mwd.month(), mwd.weekday_indexed()}; -} - -CONSTCD11 -inline -year_month_weekday -operator/(int y, const month_weekday& mwd) NOEXCEPT -{ - return year(y) / mwd; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const month_weekday& mwd, const year& y) NOEXCEPT -{ - return y / mwd; -} - -CONSTCD11 -inline -year_month_weekday -operator/(const month_weekday& mwd, int y) NOEXCEPT -{ - return year(y) / mwd; -} - -// year_month_weekday_last from operator/() - -CONSTCD11 -inline -year_month_weekday_last -operator/(const year_month& ym, const weekday_last& wdl) NOEXCEPT -{ - return {ym.year(), ym.month(), wdl}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const year& y, const month_weekday_last& mwdl) NOEXCEPT -{ - return {y, mwdl.month(), mwdl.weekday_last()}; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(int y, const month_weekday_last& mwdl) NOEXCEPT -{ - return year(y) / mwdl; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const month_weekday_last& mwdl, const year& y) NOEXCEPT -{ - return y / mwdl; -} - -CONSTCD11 -inline -year_month_weekday_last -operator/(const month_weekday_last& mwdl, int y) NOEXCEPT -{ - return year(y) / mwdl; -} - -template -struct fields; - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev = nullptr, - const std::chrono::seconds* offset_sec = nullptr); - -template -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr); - -// time_of_day - -enum {am = 1, pm}; - -namespace detail -{ - -// width::value is the number of fractional decimal digits in 1/n -// width<0>::value and width<1>::value are defined to be 0 -// If 1/n takes more than 18 fractional decimal digits, -// the result is truncated to 19. -// Example: width<2>::value == 1 -// Example: width<3>::value == 19 -// Example: width<4>::value == 2 -// Example: width<10>::value == 1 -// Example: width<1000>::value == 3 -template -struct width -{ - static CONSTDATA unsigned value = 1 + width::value; -}; - -template -struct width -{ - static CONSTDATA unsigned value = 0; -}; - -template -struct static_pow10 -{ -private: - static CONSTDATA std::uint64_t h = static_pow10::value; -public: - static CONSTDATA std::uint64_t value = h * h * (exp % 2 ? 10 : 1); -}; - -template <> -struct static_pow10<0> -{ - static CONSTDATA std::uint64_t value = 1; -}; - -template -struct make_precision -{ - using type = std::chrono::duration::value>>; - static CONSTDATA unsigned width = w; -}; - -template -struct make_precision -{ - using type = std::chrono::duration; - static CONSTDATA unsigned width = 6; -}; - -template ::type::period::den>::value> -class decimal_format_seconds -{ -public: - using rep = typename std::common_type::type::rep; - using precision = typename make_precision::type; - static auto CONSTDATA width = make_precision::width; - -private: - std::chrono::seconds s_; - precision sub_s_; - -public: - CONSTCD11 decimal_format_seconds() - : s_() - , sub_s_() - {} - - CONSTCD11 explicit decimal_format_seconds(const Duration& d) NOEXCEPT - : s_(std::chrono::duration_cast(d)) - , sub_s_(std::chrono::duration_cast(d - s_)) - {} - - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} - CONSTCD11 precision subseconds() const NOEXCEPT {return sub_s_;} - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return s_ + sub_s_; - } - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - using namespace std::chrono; - return sub_s_ < std::chrono::seconds{1} && s_ < minutes{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const decimal_format_seconds& x) - { - date::detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << x.s_.count() << - std::use_facet>(os.getloc()).decimal_point(); - os.width(width); - os << static_cast(x.sub_s_.count()); - return os; - } -}; - -template -class decimal_format_seconds -{ - static CONSTDATA unsigned w = 0; -public: - using rep = typename std::common_type::type::rep; - using precision = std::chrono::duration; - static auto CONSTDATA width = make_precision::width; -private: - - std::chrono::seconds s_; - -public: - CONSTCD11 decimal_format_seconds() : s_() {} - CONSTCD11 explicit decimal_format_seconds(const precision& s) NOEXCEPT - : s_(s) - {} - - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_;} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_;} - CONSTCD14 precision to_duration() const NOEXCEPT {return s_;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - using namespace std::chrono; - return s_ < minutes{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const decimal_format_seconds& x) - { - date::detail::save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << x.s_.count(); - return os; - } -}; - -enum class classify -{ - not_valid, - hour, - minute, - second, - subsecond -}; - -template -struct classify_duration -{ - static CONSTDATA classify value = - std::is_convertible::value - ? classify::hour : - std::is_convertible::value - ? classify::minute : - std::is_convertible::value - ? classify::second : - std::chrono::treat_as_floating_point::value - ? classify::not_valid : - classify::subsecond; -}; - -template -inline -CONSTCD11 -typename std::enable_if - < - std::numeric_limits::is_signed, - std::chrono::duration - >::type -abs(std::chrono::duration d) -{ - return d >= d.zero() ? +d : -d; -} - -template -inline -CONSTCD11 -typename std::enable_if - < - !std::numeric_limits::is_signed, - std::chrono::duration - >::type -abs(std::chrono::duration d) -{ - return d; -} - -class time_of_day_base -{ -protected: - std::chrono::hours h_; - unsigned char mode_; - bool neg_; - - enum {is24hr}; - - CONSTCD11 time_of_day_base() NOEXCEPT - : h_(0) - , mode_(static_cast(is24hr)) - , neg_(false) - {} - - - CONSTCD11 time_of_day_base(std::chrono::hours h, bool neg, unsigned m) NOEXCEPT - : h_(detail::abs(h)) - , mode_(static_cast(m)) - , neg_(neg) - {} - - CONSTCD14 void make24() NOEXCEPT; - CONSTCD14 void make12() NOEXCEPT; - - CONSTCD14 std::chrono::hours to24hr() const; - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return !neg_ && h_ < days{1}; - } -}; - -CONSTCD14 -inline -std::chrono::hours -time_of_day_base::to24hr() const -{ - auto h = h_; - if (mode_ == am || mode_ == pm) - { - CONSTDATA auto h12 = std::chrono::hours(12); - if (mode_ == pm) - { - if (h != h12) - h = h + h12; - } - else if (h == h12) - h = std::chrono::hours(0); - } - return h; -} - -CONSTCD14 -inline -void -time_of_day_base::make24() NOEXCEPT -{ - h_ = to24hr(); - mode_ = is24hr; -} - -CONSTCD14 -inline -void -time_of_day_base::make12() NOEXCEPT -{ - if (mode_ == is24hr) - { - CONSTDATA auto h12 = std::chrono::hours(12); - if (h_ >= h12) - { - if (h_ > h12) - h_ = h_ - h12; - mode_ = pm; - } - else - { - if (h_ == std::chrono::hours(0)) - h_ = h12; - mode_ = am; - } - } -} - -template ::value> -class time_of_day_storage; - -template -class time_of_day_storage, detail::classify::hour> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - -public: - using precision = std::chrono::hours; - -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - CONSTCD11 time_of_day_storage() NOEXCEPT = default; -#else - CONSTCD11 time_of_day_storage() = default; -#endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */ - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours since_midnight) NOEXCEPT - : base(since_midnight, since_midnight < std::chrono::hours{0}, is24hr) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, unsigned md) NOEXCEPT - : base(h, h < std::chrono::hours{0}, md) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr(); - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_ostream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count(); - switch (t.mode_) - { - case time_of_day_storage::is24hr: - os << "00"; - break; - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } -}; - -template -class time_of_day_storage, detail::classify::minute> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - - std::chrono::minutes m_; - -public: - using precision = std::chrono::minutes; - - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::minutes since_midnight) NOEXCEPT - : base(std::chrono::duration_cast(since_midnight), - since_midnight < std::chrono::minutes{0}, is24hr) - , m_(detail::abs(since_midnight) - h_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1}; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_ostream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count(); - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } -}; - -template -class time_of_day_storage, detail::classify::second> - : private detail::time_of_day_base -{ - using base = detail::time_of_day_base; - using dfs = decimal_format_seconds; - - std::chrono::minutes m_; - dfs s_; - -public: - using precision = std::chrono::seconds; - - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - , s_() - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::seconds since_midnight) NOEXCEPT - : base(std::chrono::duration_cast(since_midnight), - since_midnight < std::chrono::seconds{0}, is24hr) - , m_(std::chrono::duration_cast(detail::abs(since_midnight) - h_)) - , s_(detail::abs(since_midnight) - h_ - m_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - std::chrono::seconds s, unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - , s_(s) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + s_.to_duration() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1} && - s_.in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_ostream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count() << ':' << t.s_; - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } - - template - friend - std::basic_ostream& - date::to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec); - - template - friend - std::basic_istream& - date::from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, - std::basic_string* abbrev, std::chrono::minutes* offset); -}; - -template -class time_of_day_storage, detail::classify::subsecond> - : private detail::time_of_day_base -{ -public: - using Duration = std::chrono::duration; - using dfs = decimal_format_seconds::type>; - using precision = typename dfs::precision; - -private: - using base = detail::time_of_day_base; - - std::chrono::minutes m_; - dfs s_; - -public: - CONSTCD11 time_of_day_storage() NOEXCEPT - : base() - , m_(0) - , s_() - {} - - CONSTCD11 explicit time_of_day_storage(Duration since_midnight) NOEXCEPT - : base(date::trunc(since_midnight), - since_midnight < Duration{0}, is24hr) - , m_(date::trunc(detail::abs(since_midnight) - h_)) - , s_(detail::abs(since_midnight) - h_ - m_) - {} - - CONSTCD11 explicit time_of_day_storage(std::chrono::hours h, std::chrono::minutes m, - std::chrono::seconds s, precision sub_s, - unsigned md) NOEXCEPT - : base(h, false, md) - , m_(m) - , s_(s + sub_s) - {} - - CONSTCD11 std::chrono::hours hours() const NOEXCEPT {return h_;} - CONSTCD11 std::chrono::minutes minutes() const NOEXCEPT {return m_;} - CONSTCD14 std::chrono::seconds& seconds() NOEXCEPT {return s_.seconds();} - CONSTCD11 std::chrono::seconds seconds() const NOEXCEPT {return s_.seconds();} - CONSTCD11 precision subseconds() const NOEXCEPT {return s_.subseconds();} - CONSTCD11 unsigned mode() const NOEXCEPT {return mode_;} - - CONSTCD14 explicit operator precision() const NOEXCEPT - { - auto p = to24hr() + s_.to_duration() + m_; - if (neg_) - p = -p; - return p; - } - - CONSTCD14 precision to_duration() const NOEXCEPT - { - return static_cast(*this); - } - - CONSTCD14 time_of_day_storage& make24() NOEXCEPT {base::make24(); return *this;} - CONSTCD14 time_of_day_storage& make12() NOEXCEPT {base::make12(); return *this;} - - CONSTCD11 bool in_conventional_range() const NOEXCEPT - { - return base::in_conventional_range() && m_ < std::chrono::hours{1} && - s_.in_conventional_range(); - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const time_of_day_storage& t) - { - using namespace std; - detail::save_ostream _(os); - if (t.neg_) - os << '-'; - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (t.mode_ != am && t.mode_ != pm) - os.width(2); - os << t.h_.count() << ':'; - os.width(2); - os << t.m_.count() << ':' << t.s_; - switch (t.mode_) - { - case am: - os << "am"; - break; - case pm: - os << "pm"; - break; - } - return os; - } - - template - friend - std::basic_ostream& - date::to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec); - - template - friend - std::basic_istream& - date::from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, - std::basic_string* abbrev, std::chrono::minutes* offset); -}; - -} // namespace detail - -template -class time_of_day - : public detail::time_of_day_storage -{ - using base = detail::time_of_day_storage; -public: -#if !defined(_MSC_VER) || _MSC_VER >= 1900 - CONSTCD11 time_of_day() NOEXCEPT = default; -#else - CONSTCD11 time_of_day() = default; -#endif /* !defined(_MSC_VER) || _MSC_VER >= 1900 */ - - CONSTCD11 explicit time_of_day(Duration since_midnight) NOEXCEPT - : base(since_midnight) - {} - - template - CONSTCD11 - explicit time_of_day(Arg0&& arg0, Arg1&& arg1, Args&& ...args) NOEXCEPT - : base(std::forward(arg0), std::forward(arg1), std::forward(args)...) - {} -}; - -template ::value>::type> -CONSTCD11 -inline -time_of_day> -make_time(const std::chrono::duration& d) -{ - return time_of_day>(d); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, unsigned md) -{ - return time_of_day(h, md); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - unsigned md) -{ - return time_of_day(h, m, md); -} - -CONSTCD11 -inline -time_of_day -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - const std::chrono::seconds& s, unsigned md) -{ - return time_of_day(h, m, s, md); -} - -template >::value>::type> -CONSTCD11 -inline -time_of_day> -make_time(const std::chrono::hours& h, const std::chrono::minutes& m, - const std::chrono::seconds& s, const std::chrono::duration& sub_s, - unsigned md) -{ - return time_of_day>(h, m, s, sub_s, md); -} - -template -inline -typename std::enable_if -< - !std::chrono::treat_as_floating_point::value && - std::ratio_less::value - , std::basic_ostream& ->::type -operator<<(std::basic_ostream& os, const sys_time& tp) -{ - auto const dp = date::floor(tp); - return os << year_month_day(dp) << ' ' << make_time(tp-dp); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const sys_days& dp) -{ - return os << year_month_day(dp); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, const local_time& ut) -{ - return (os << sys_time{ut.time_since_epoch()}); -} - -// to_stream - -CONSTDATA year nanyear{-32768}; - -template -struct fields -{ - year_month_day ymd{nanyear/0/0}; - weekday wd{8u}; - time_of_day tod{}; - bool has_tod = false; - -// https ://github.com/HowardHinnant/date/issues/264 -#ifdef USE_IOT - fields() : ymd{ year{0} / 0 / 0 }, wd{ 7u } {} -#else - fields() = default; -#endif - - fields(year_month_day ymd_) : ymd(ymd_) {} - fields(weekday wd_) : wd(wd_) {} - fields(time_of_day tod_) : tod(tod_), has_tod(true) {} - - fields(year_month_day ymd_, weekday wd_) : ymd(ymd_), wd(wd_) {} - fields(year_month_day ymd_, time_of_day tod_) : ymd(ymd_), tod(tod_), - has_tod(true) {} - - fields(weekday wd_, time_of_day tod_) : wd(wd_), tod(tod_), has_tod(true) {} - - fields(year_month_day ymd_, weekday wd_, time_of_day tod_) - : ymd(ymd_) - , wd(wd_) - , tod(tod_) - , has_tod(true) - {} -}; - -namespace detail -{ - -template -unsigned -extract_weekday(std::basic_ostream& os, const fields& fds) -{ - if (!fds.ymd.ok() && !fds.wd.ok()) - { - // fds does not contain a valid weekday - os.setstate(std::ios::failbit); - return 8; - } - weekday wd; - if (fds.ymd.ok()) - { - wd = weekday{sys_days(fds.ymd)}; - if (fds.wd.ok() && wd != fds.wd) - { - // fds.ymd and fds.wd are inconsistent - os.setstate(std::ios::failbit); - return 8; - } - } - else - wd = fds.wd; - return static_cast((wd - Sunday).count()); -} - -template -unsigned -extract_month(std::basic_ostream& os, const fields& fds) -{ - if (!fds.ymd.month().ok()) - { - // fds does not contain a valid month - os.setstate(std::ios::failbit); - return 0; - } - return static_cast(fds.ymd.month()); -} - -} // namespace detail - -#if ONLY_C_LOCALE - -namespace detail -{ - -inline -std::pair -weekday_names() -{ - static const std::string nm[] = - { - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", - "Sun", - "Mon", - "Tue", - "Wed", - "Thu", - "Fri", - "Sat" - }; - return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -inline -std::pair -month_names() -{ - static const std::string nm[] = - { - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", - "Jan", - "Feb", - "Mar", - "Apr", - "May", - "Jun", - "Jul", - "Aug", - "Sep", - "Oct", - "Nov", - "Dec" - }; - return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -inline -std::pair -ampm_names() -{ - static const std::string nm[] = - { - "AM", - "PM" - }; - return std::make_pair(nm, nm+sizeof(nm)/sizeof(nm[0])); -} - -template -FwdIter -scan_keyword(std::basic_istream& is, FwdIter kb, FwdIter ke) -{ - using namespace std; - size_t nkw = static_cast(std::distance(kb, ke)); - const unsigned char doesnt_match = '\0'; - const unsigned char might_match = '\1'; - const unsigned char does_match = '\2'; - unsigned char statbuf[100]; - unsigned char* status = statbuf; - unique_ptr stat_hold(0, free); - if (nkw > sizeof(statbuf)) - { - status = (unsigned char*)malloc(nkw); - if (status == nullptr) -# ifdef USE_IOT - return FwdIter(); -# else - throw bad_alloc(); -# endif - stat_hold.reset(status); - } - size_t n_might_match = nkw; // At this point, any keyword might match - size_t n_does_match = 0; // but none of them definitely do - // Initialize all statuses to might_match, except for "" keywords are does_match - unsigned char* st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (!ky->empty()) - *st = might_match; - else - { - *st = does_match; - --n_might_match; - ++n_does_match; - } - } - // While there might be a match, test keywords against the next CharT - for (size_t indx = 0; is && n_might_match > 0; ++indx) - { - // Peek at the next CharT but don't consume it - auto ic = is.peek(); - if (ic == EOF) - { - is.setstate(ios::eofbit); - break; - } - auto c = static_cast(toupper(ic)); - bool consume = false; - // For each keyword which might match, see if the indx character is c - // If a match if found, consume c - // If a match is found, and that is the last character in the keyword, - // then that keyword matches. - // If the keyword doesn't match this character, then change the keyword - // to doesn't match - st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (*st == might_match) - { - if (c == static_cast(toupper((*ky)[indx]))) - { - consume = true; - if (ky->size() == indx+1) - { - *st = does_match; - --n_might_match; - ++n_does_match; - } - } - else - { - *st = doesnt_match; - --n_might_match; - } - } - } - // consume if we matched a character - if (consume) - { - (void)is.get(); - // If we consumed a character and there might be a matched keyword that - // was marked matched on a previous iteration, then such keywords - // are now marked as not matching. - if (n_might_match + n_does_match > 1) - { - st = status; - for (auto ky = kb; ky != ke; ++ky, ++st) - { - if (*st == does_match && ky->size() != indx+1) - { - *st = doesnt_match; - --n_does_match; - } - } - } - } - } - // We've exited the loop because we hit eof and/or we have no more "might matches". - // Return the first matching result - for (st = status; kb != ke; ++kb, ++st) - if (*st == does_match) - break; - if (kb == ke) - is.setstate(ios_base::failbit); - return kb; -} - -} // namespace detail - -#endif // ONLY_C_LOCALE - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const fields& fds, const std::string* abbrev, - const std::chrono::seconds* offset_sec) -{ - using namespace std; - using namespace std::chrono; - using namespace detail; - date::detail::save_ostream ss(os); - os.fill(' '); - os.flags(std::ios::skipws | std::ios::dec); - os.width(0); - tm tm{}; - bool insert_negative = fds.has_tod && fds.tod.to_duration() < Duration::zero(); -#if !ONLY_C_LOCALE - auto& facet = use_facet>(os.getloc()); -#endif - const CharT* command = nullptr; - CharT modified = CharT{}; - for (; *fmt; ++fmt) - { - switch (*fmt) - { - case 'a': - case 'A': - if (command) - { - if (modified == CharT{}) - { - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else // ONLY_C_LOCALE - os << weekday_names().first[tm.tm_wday+7*(*fmt == 'a')]; -#endif // ONLY_C_LOCALE - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'b': - case 'B': - case 'h': - if (command) - { - if (modified == CharT{}) - { - tm.tm_mon = static_cast(extract_month(os, fds)) - 1; -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else // ONLY_C_LOCALE - os << month_names().first[tm.tm_mon+12*(*fmt != 'B')]; -#endif // ONLY_C_LOCALE - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'c': - case 'x': - if (command) - { - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.ok()) - os.setstate(std::ios::failbit); - if (*fmt == 'c' && !fds.has_tod) - os.setstate(std::ios::failbit); -#if !ONLY_C_LOCALE - tm = std::tm{}; - auto const& ymd = fds.ymd; - auto ld = local_days(ymd); - if (*fmt == 'c') - { - tm.tm_sec = static_cast(fds.tod.seconds().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_hour = static_cast(fds.tod.hours().count()); - } - tm.tm_mday = static_cast(static_cast(ymd.day())); - tm.tm_mon = static_cast(extract_month(os, fds) - 1); - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - CharT f[3] = {'%'}; - auto fe = begin(f) + 1; - if (modified == CharT{'E'}) - *fe++ = modified; - *fe++ = *fmt; - facet.put(os, os, os.fill(), &tm, begin(f), fe); -#else // ONLY_C_LOCALE - if (*fmt == 'c') - { - auto wd = static_cast(extract_weekday(os, fds)); - os << weekday_names().first[static_cast(wd)+7] - << ' '; - os << month_names().first[extract_month(os, fds)-1+12] << ' '; - auto d = static_cast(static_cast(fds.ymd.day())); - if (d < 10) - os << ' '; - os << d << ' ' - << make_time(duration_cast(fds.tod.to_duration())) - << ' ' << fds.ymd.year(); - - } - else // *fmt == 'x' - { - auto const& ymd = fds.ymd; - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(ymd.month()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.day()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.year()) % 100; - } -#endif // ONLY_C_LOCALE - } - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'C': - if (command) - { - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.year().ok()) - os.setstate(std::ios::failbit); - auto y = static_cast(fds.ymd.year()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - if (y >= 0) - { - os.width(2); - os << y/100; - } - else - { - os << CharT{'-'}; - os.width(2); - os << -(y-99)/100; - } - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'E'}) - { - tm.tm_year = y - 1900; - CharT f[3] = {'%', 'E', 'C'}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'd': - case 'e': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.day().ok()) - os.setstate(std::ios::failbit); - auto d = static_cast(static_cast(fds.ymd.day())); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - save_ostream _(os); - if (*fmt == CharT{'d'}) - os.fill('0'); - else - os.fill(' '); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << d; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - tm.tm_mday = d; - CharT f[3] = {'%', 'O', *fmt}; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'D': - if (command) - { - if (modified == CharT{}) - { - if (!fds.ymd.ok()) - os.setstate(std::ios::failbit); - auto const& ymd = fds.ymd; - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << static_cast(ymd.month()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.day()) << CharT{'/'}; - os.width(2); - os << static_cast(ymd.year()) % 100; - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'F': - if (command) - { - if (modified == CharT{}) - { - if (!fds.ymd.ok()) - os.setstate(std::ios::failbit); - auto const& ymd = fds.ymd; - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(4); - os << static_cast(ymd.year()) << CharT{'-'}; - os.width(2); - os << static_cast(ymd.month()) << CharT{'-'}; - os.width(2); - os << static_cast(ymd.day()); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'g': - case 'G': - if (command) - { - if (modified == CharT{}) - { - if (!fds.ymd.ok()) - os.setstate(std::ios::failbit); - auto ld = local_days(fds.ymd); - auto y = year_month_day{ld + days{3}}.year(); - auto start = local_days((y-years{1})/December/Thursday[last]) + - (Monday-Thursday); - if (ld < start) - --y; - if (*fmt == CharT{'G'}) - os << y; - else - { - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(2); - os << std::abs(static_cast(y)) % 100; - } - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'H': - case 'I': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); - if (insert_negative) - { - os << '-'; - insert_negative = false; - } - auto hms = fds.tod; -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - if (*fmt == CharT{'I'}) - hms.make12(); - if (hms.hours() < hours{10}) - os << CharT{'0'}; - os << hms.hours().count(); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_hour = static_cast(hms.hours().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'j': - if (command) - { - if (modified == CharT{}) - { - if (fds.ymd.ok() || fds.has_tod) - { - days doy; - if (fds.ymd.ok()) - { - auto ld = local_days(fds.ymd); - auto y = fds.ymd.year(); - doy = ld - local_days(y/January/1) + days{1}; - } - else - { - doy = duration_cast(fds.tod.to_duration()); - } - save_ostream _(os); - os.fill('0'); - os.flags(std::ios::dec | std::ios::right); - os.width(3); - os << doy.count(); - } - else - { - os.setstate(std::ios::failbit); - } - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'm': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.month().ok()) - os.setstate(std::ios::failbit); - auto m = static_cast(fds.ymd.month()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - if (m < 10) - os << CharT{'0'}; - os << m; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_mon = static_cast(m-1); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'M': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); - if (insert_negative) - { - os << '-'; - insert_negative = false; - } -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - if (fds.tod.minutes() < minutes{10}) - os << CharT{'0'}; - os << fds.tod.minutes().count(); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_min = static_cast(fds.tod.minutes().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'n': - if (command) - { - if (modified == CharT{}) - os << CharT{'\n'}; - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'p': - if (command) - { - if (modified == CharT{}) - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - tm.tm_hour = static_cast(fds.tod.hours().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else - if (fds.tod.hours() < hours{12}) - os << ampm_names().first[0]; - else - os << ampm_names().first[1]; -#endif - } - else - { - os << CharT{'%'} << modified << *fmt; - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'r': - if (command) - { - if (modified == CharT{}) - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); -#if !ONLY_C_LOCALE - const CharT f[] = {'%', *fmt}; - tm.tm_hour = static_cast(fds.tod.hours().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_sec = static_cast(fds.tod.seconds().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); -#else - time_of_day tod(duration_cast(fds.tod.to_duration())); - tod.make12(); - save_ostream _(os); - os.fill('0'); - os.width(2); - os << tod.hours().count() << CharT{':'}; - os.width(2); - os << tod.minutes().count() << CharT{':'}; - os.width(2); - os << tod.seconds().count() << CharT{' '}; - tod.make24(); - if (tod.hours() < hours{12}) - os << ampm_names().first[0]; - else - os << ampm_names().first[1]; -#endif - } - else - { - os << CharT{'%'} << modified << *fmt; - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'R': - if (command) - { - if (modified == CharT{}) - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); - if (fds.tod.hours() < hours{10}) - os << CharT{'0'}; - os << fds.tod.hours().count() << CharT{':'}; - if (fds.tod.minutes() < minutes{10}) - os << CharT{'0'}; - os << fds.tod.minutes().count(); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'S': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); - if (insert_negative) - { - os << '-'; - insert_negative = false; - } -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - os << fds.tod.s_; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_sec = static_cast(fds.tod.s_.seconds().count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 't': - if (command) - { - if (modified == CharT{}) - os << CharT{'\t'}; - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'T': - if (command) - { - if (modified == CharT{}) - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); - os << fds.tod; - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'u': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - auto wd = extract_weekday(os, fds); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - os << (wd != 0 ? wd : 7u); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_wday = static_cast(wd); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'U': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - auto const& ymd = fds.ymd; - if (!ymd.ok()) - os.setstate(std::ios::failbit); - auto ld = local_days(ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - auto st = local_days(Sunday[1]/January/ymd.year()); - if (ld < st) - os << CharT{'0'} << CharT{'0'}; - else - { - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; - } - } - #if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'V': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.ok()) - os.setstate(std::ios::failbit); - auto ld = local_days(fds.ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - auto y = year_month_day{ld + days{3}}.year(); - auto st = local_days((y-years{1})/12/Thursday[last]) + - (Monday-Thursday); - if (ld < st) - { - --y; - st = local_days((y - years{1})/12/Thursday[last]) + - (Monday-Thursday); - } - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - auto const& ymd = fds.ymd; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'w': - if (command) - { - auto wd = extract_weekday(os, fds); - if (os.fail()) - return os; -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - os << wd; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_wday = static_cast(wd); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - else - { - os << CharT{'%'} << modified << *fmt; - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'W': - if (command) - { - if (modified == CharT{'E'}) - os << CharT{'%'} << modified << *fmt; - else - { - auto const& ymd = fds.ymd; - if (!ymd.ok()) - os.setstate(std::ios::failbit); - auto ld = local_days(ymd); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - auto st = local_days(Monday[1]/January/ymd.year()); - if (ld < st) - os << CharT{'0'} << CharT{'0'}; - else - { - auto wn = duration_cast(ld - st).count() + 1; - if (wn < 10) - os << CharT{'0'}; - os << wn; - } - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(ymd.year()) - 1900; - tm.tm_wday = static_cast(extract_weekday(os, fds)); - if (os.fail()) - return os; - tm.tm_yday = static_cast((ld - local_days(ymd.year()/1/1)).count()); - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'X': - if (command) - { - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.has_tod) - os.setstate(std::ios::failbit); -#if !ONLY_C_LOCALE - tm = std::tm{}; - tm.tm_sec = static_cast(fds.tod.seconds().count()); - tm.tm_min = static_cast(fds.tod.minutes().count()); - tm.tm_hour = static_cast(fds.tod.hours().count()); - CharT f[3] = {'%'}; - auto fe = begin(f) + 1; - if (modified == CharT{'E'}) - *fe++ = modified; - *fe++ = *fmt; - facet.put(os, os, os.fill(), &tm, begin(f), fe); -#else - os << fds.tod; -#endif - } - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'y': - if (command) - { - if (!fds.ymd.year().ok()) - os.setstate(std::ios::failbit); - auto y = static_cast(fds.ymd.year()); -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - y = std::abs(y) % 100; - if (y < 10) - os << CharT{'0'}; - os << y; -#if !ONLY_C_LOCALE - } - else - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = y - 1900; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'Y': - if (command) - { - if (modified == CharT{'O'}) - os << CharT{'%'} << modified << *fmt; - else - { - if (!fds.ymd.year().ok()) - os.setstate(std::ios::failbit); - auto y = fds.ymd.year(); -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - os << y; - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'E'}) - { - const CharT f[] = {'%', modified, *fmt}; - tm.tm_year = static_cast(y) - 1900; - facet.put(os, os, os.fill(), &tm, begin(f), end(f)); - } -#endif - } - modified = CharT{}; - command = nullptr; - } - else - os << *fmt; - break; - case 'z': - if (command) - { - if (offset_sec == nullptr) - { - // Can not format %z with unknown offset - os.setstate(ios::failbit); - return os; - } - auto m = duration_cast(*offset_sec); - auto neg = m < minutes{0}; - m = date::abs(m); - auto h = duration_cast(m); - m -= h; - if (neg) - os << CharT{'-'}; - else - os << CharT{'+'}; - if (h < hours{10}) - os << CharT{'0'}; - os << h.count(); - if (modified != CharT{}) - os << CharT{':'}; - if (m < minutes{10}) - os << CharT{'0'}; - os << m.count(); - command = nullptr; - modified = CharT{}; - } - else - os << *fmt; - break; - case 'Z': - if (command) - { - if (modified == CharT{}) - { - if (abbrev == nullptr) - { - // Can not format %Z with unknown time_zone - os.setstate(ios::failbit); - return os; - } - for (auto c : *abbrev) - os << CharT(c); - } - else - { - os << CharT{'%'} << modified << *fmt; - modified = CharT{}; - } - command = nullptr; - } - else - os << *fmt; - break; - case 'E': - case 'O': - if (command) - { - if (modified == CharT{}) - { - modified = *fmt; - } - else - { - os << CharT{'%'} << modified << *fmt; - command = nullptr; - modified = CharT{}; - } - } - else - os << *fmt; - break; - case '%': - if (command) - { - if (modified == CharT{}) - { - os << CharT{'%'}; - command = nullptr; - } - else - { - os << CharT{'%'} << modified << CharT{'%'}; - command = nullptr; - modified = CharT{}; - } - } - else - command = fmt; - break; - default: - if (command) - { - os << CharT{'%'}; - command = nullptr; - } - if (modified != CharT{}) - { - os << modified; - modified = CharT{}; - } - os << *fmt; - break; - } - } - if (command) - os << CharT{'%'}; - if (modified != CharT{}) - os << modified; - return os; -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const year& y) -{ - using CT = std::chrono::seconds; - fields fds{y/0/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const month& m) -{ - using CT = std::chrono::seconds; - fields fds{m/0/nanyear}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const day& d) -{ - using CT = std::chrono::seconds; - fields fds{d/0/nanyear}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const weekday& wd) -{ - using CT = std::chrono::seconds; - fields fds{wd}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const year_month& ym) -{ - using CT = std::chrono::seconds; - fields fds{ym/0}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, const month_day& md) -{ - using CT = std::chrono::seconds; - fields fds{md/nanyear}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const year_month_day& ymd) -{ - using CT = std::chrono::seconds; - fields fds{ymd}; - return to_stream(os, fmt, fds); -} - -template -inline -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const std::chrono::duration& d) -{ - using Duration = std::chrono::duration; - using CT = typename std::common_type::type; - fields fds{time_of_day{d}}; - return to_stream(os, fmt, fds); -} - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const local_time& tp, const std::string* abbrev = nullptr, - const std::chrono::seconds* offset_sec = nullptr) -{ - using CT = typename std::common_type::type; - auto ld = floor(tp); - fields fds{year_month_day{ld}, time_of_day{tp-local_seconds{ld}}}; - return to_stream(os, fmt, fds, abbrev, offset_sec); -} - -template -std::basic_ostream& -to_stream(std::basic_ostream& os, const CharT* fmt, - const sys_time& tp) -{ - using namespace std::chrono; - using CT = typename std::common_type::type; - const std::string abbrev("UTC"); - CONSTDATA seconds offset{0}; - auto sd = floor(tp); - fields fds{year_month_day{sd}, time_of_day{tp-sys_seconds{sd}}}; - return to_stream(os, fmt, fds, &abbrev, &offset); -} - -// format - -template -auto -format(const std::locale& loc, const CharT* fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt, tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - os.imbue(loc); - to_stream(os, fmt, tp); - return os.str(); -} - -template -auto -format(const CharT* fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt, tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - to_stream(os, fmt, tp); - return os.str(); -} - -template -auto -format(const std::locale& loc, const std::basic_string& fmt, - const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - os.imbue(loc); - to_stream(os, fmt.c_str(), tp); - return os.str(); -} - -template -auto -format(const std::basic_string& fmt, const Streamable& tp) - -> decltype(to_stream(std::declval&>(), fmt.c_str(), tp), - std::basic_string{}) -{ - std::basic_ostringstream os; - os.exceptions(std::ios::failbit | std::ios::badbit); - to_stream(os, fmt.c_str(), tp); - return os.str(); -} - -// parse - -namespace detail -{ - -template -bool -read_char(std::basic_istream& is, CharT fmt, std::ios::iostate& err) -{ - auto ic = is.get(); - if (Traits::eq_int_type(ic, Traits::eof()) || - !Traits::eq(Traits::to_char_type(ic), fmt)) - { - err |= std::ios::failbit; - is.setstate(std::ios::failbit); - return false; - } - return true; -} - -template -unsigned -read_unsigned(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - unsigned x = 0; - unsigned count = 0; - while (true) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - break; - auto c = static_cast(Traits::to_char_type(ic)); - if (!('0' <= c && c <= '9')) - break; - (void)is.get(); - ++count; - x = 10*x + static_cast(c - '0'); - if (count == M) - break; - } - if (count < m) - is.setstate(std::ios::failbit); - return x; -} - -template -int -read_signed(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - auto ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if (('0' <= c && c <= '9') || c == '-' || c == '+') - { - if (c == '-' || c == '+') - (void)is.get(); - auto x = static_cast(read_unsigned(is, std::max(m, 1u), M)); - if (!is.fail()) - { - if (c == '-') - x = -x; - return x; - } - } - } - if (m > 0) - is.setstate(std::ios::failbit); - return 0; -} - -template -long double -read_long_double(std::basic_istream& is, unsigned m = 1, unsigned M = 10) -{ - using namespace std; - unsigned count = 0; - auto decimal_point = Traits::to_int_type( - use_facet>(is.getloc()).decimal_point()); - std::string buf; - while (true) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - break; - if (Traits::eq_int_type(ic, decimal_point)) - { - buf += '.'; - decimal_point = Traits::eof(); - is.get(); - } - else - { - auto c = static_cast(Traits::to_char_type(ic)); - if (!('0' <= c && c <= '9')) - break; - buf += c; - (void)is.get(); - } - if (++count == M) - break; - } - if (count < m) - { - is.setstate(std::ios::failbit); - return 0; - } - return std::stold(buf); -} - -struct rs -{ - int& i; - unsigned m; - unsigned M; -}; - -struct ru -{ - int& i; - unsigned m; - unsigned M; -}; - -struct rld -{ - long double& i; - unsigned m; - unsigned M; -}; - -template -void -read(std::basic_istream&) -{ -} - -template -void -read(std::basic_istream& is, CharT a0, Args&& ...args); - -template -void -read(std::basic_istream& is, rs a0, Args&& ...args); - -template -void -read(std::basic_istream& is, ru a0, Args&& ...args); - -template -void -read(std::basic_istream& is, int a0, Args&& ...args); - -template -void -read(std::basic_istream& is, rld a0, Args&& ...args); - -template -void -read(std::basic_istream& is, CharT a0, Args&& ...args) -{ - // No-op if a0 == CharT{} - if (a0 != CharT{}) - { - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - { - is.setstate(std::ios::failbit | std::ios::eofbit); - return; - } - if (!Traits::eq(Traits::to_char_type(ic), a0)) - { - is.setstate(std::ios::failbit); - return; - } - (void)is.get(); - } - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, rs a0, Args&& ...args) -{ - auto x = read_signed(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = x; - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, ru a0, Args&& ...args) -{ - auto x = read_unsigned(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = static_cast(x); - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, int a0, Args&& ...args) -{ - if (a0 != -1) - { - auto u = static_cast(a0); - CharT buf[std::numeric_limits::digits10+2] = {}; - auto e = buf; - do - { - *e++ = CharT(u % 10) + CharT{'0'}; - u /= 10; - } while (u > 0); - std::reverse(buf, e); - for (auto p = buf; p != e && is.rdstate() == std::ios::goodbit; ++p) - read(is, *p); - } - if (is.rdstate() == std::ios::goodbit) - read(is, std::forward(args)...); -} - -template -void -read(std::basic_istream& is, rld a0, Args&& ...args) -{ - auto x = read_long_double(is, a0.m, a0.M); - if (is.fail()) - return; - a0.i = x; - read(is, std::forward(args)...); -} - -template -inline -void -checked_set(T& value, T from, T not_a_value, std::basic_ios& is) -{ - if (!is.fail()) - { - if (value == not_a_value) - value = std::move(from); - else if (value != from) - is.setstate(std::ios::failbit); - } -} - -} // namespace detail; - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - fields& fds, std::basic_string* abbrev, - std::chrono::minutes* offset) -{ - using namespace std; - using namespace std::chrono; - typename basic_istream::sentry ok{is, true}; - if (ok) - { - date::detail::save_istream ss(is); - is.fill(' '); - is.flags(std::ios::skipws | std::ios::dec); - is.width(0); -#if !ONLY_C_LOCALE - auto& f = use_facet>(is.getloc()); - std::tm tm{}; -#endif - const CharT* command = nullptr; - auto modified = CharT{}; - auto width = -1; - - CONSTDATA int not_a_year = numeric_limits::min(); - CONSTDATA int not_a_2digit_year = 100; - CONSTDATA int not_a_century = not_a_year / 100; - CONSTDATA int not_a_month = 0; - CONSTDATA int not_a_day = 0; - CONSTDATA int not_a_hour = numeric_limits::min(); - CONSTDATA int not_a_hour_12_value = 0; - CONSTDATA int not_a_minute = not_a_hour; - CONSTDATA Duration not_a_second = Duration::min(); - CONSTDATA int not_a_doy = -1; - CONSTDATA int not_a_weekday = 8; - CONSTDATA int not_a_week_num = 100; - CONSTDATA int not_a_ampm = -1; - CONSTDATA minutes not_a_offset = minutes::min(); - - int Y = not_a_year; // c, F, Y * - int y = not_a_2digit_year; // D, x, y * - int g = not_a_2digit_year; // g * - int G = not_a_year; // G * - int C = not_a_century; // C * - int m = not_a_month; // b, B, h, m, c, D, F, x * - int d = not_a_day; // c, d, D, e, F, x * - int j = not_a_doy; // j * - int wd = not_a_weekday; // a, A, u, w * - int H = not_a_hour; // c, H, R, T, X * - int I = not_a_hour_12_value; // I, r * - int p = not_a_ampm; // p, r * - int M = not_a_minute; // c, M, r, R, T, X * - Duration s = not_a_second; // c, r, S, T, X * - int U = not_a_week_num; // U * - int V = not_a_week_num; // V * - int W = not_a_week_num; // W * - std::basic_string temp_abbrev; // Z * - minutes temp_offset = not_a_offset; // z * - - using detail::read; - using detail::rs; - using detail::ru; - using detail::rld; - using detail::checked_set; - for (; *fmt && is.rdstate() == std::ios::goodbit; ++fmt) - { - switch (*fmt) - { - case 'a': - case 'A': - case 'u': - case 'w': // wd: a, A, u, w - if (command) - { - int trial_wd = not_a_weekday; - if (*fmt == 'a' || *fmt == 'A') - { - if (modified == CharT{}) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - is.setstate(err); - if (!is.fail()) - trial_wd = tm.tm_wday; -#else - auto nm = detail::weekday_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (!is.fail()) - trial_wd = i % 7; -#endif - } - else - read(is, CharT{'%'}, width, modified, *fmt); - } - else // *fmt == 'u' || *fmt == 'w' - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - read(is, ru{trial_wd, 1, width == -1 ? - 1u : static_cast(width)}); - if (!is.fail()) - { - if (*fmt == 'u') - { - if (!(1 <= trial_wd && trial_wd <= 7)) - { - trial_wd = not_a_weekday; - is.setstate(ios_base::failbit); - } - else if (trial_wd == 7) - trial_wd = 0; - } - else // *fmt == 'w' - { - if (!(0 <= trial_wd && trial_wd <= 6)) - { - trial_wd = not_a_weekday; - is.setstate(ios_base::failbit); - } - } - } - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - is.setstate(err); - if (!is.fail()) - trial_wd = tm.tm_wday; - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - } - if (trial_wd != not_a_weekday) - checked_set(wd, trial_wd, not_a_weekday, is); - } - else // !command - read(is, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - break; - case 'b': - case 'B': - case 'h': - if (command) - { - if (modified == CharT{}) - { - int ttm = not_a_month; -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - ttm = tm.tm_mon + 1; - is.setstate(err); -#else - auto nm = detail::month_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - if (!is.fail()) - ttm = i % 12 + 1; -#endif - checked_set(m, ttm, not_a_month, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'c': - if (command) - { - if (modified != CharT{'O'}) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - checked_set(Y, tm.tm_year + 1900, not_a_year, is); - checked_set(m, tm.tm_mon + 1, not_a_month, is); - checked_set(d, tm.tm_mday, not_a_day, is); - checked_set(H, tm.tm_hour, not_a_hour, is); - checked_set(M, tm.tm_min, not_a_minute, is); - checked_set(s, duration_cast(seconds{tm.tm_sec}), - not_a_second, is); - } - is.setstate(err); -#else - // "%a %b %e %T %Y" - auto nm = detail::weekday_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - checked_set(wd, static_cast(i % 7), not_a_weekday, is); - ws(is); - nm = detail::month_names(); - i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - checked_set(m, static_cast(i % 12 + 1), not_a_month, is); - ws(is); - int td = not_a_day; - read(is, rs{td, 1, 2}); - checked_set(d, td, not_a_day, is); - ws(is); - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int tH; - int tM; - long double S; - read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, - CharT{':'}, rld{S, 1, w}); - checked_set(H, tH, not_a_hour, is); - checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), - not_a_second, is); - ws(is); - int tY = not_a_year; - read(is, rs{tY, 1, 4u}); - checked_set(Y, tY, not_a_year, is); -#endif - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'x': - if (command) - { - if (modified != CharT{'O'}) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - checked_set(Y, tm.tm_year + 1900, not_a_year, is); - checked_set(m, tm.tm_mon + 1, not_a_month, is); - checked_set(d, tm.tm_mday, not_a_day, is); - } - is.setstate(err); -#else - // "%m/%d/%y" - int ty = not_a_2digit_year; - int tm = not_a_month; - int td = not_a_day; - read(is, ru{tm, 1, 2}, CharT{'/'}, ru{td, 1, 2}, CharT{'/'}, - rs{ty, 1, 2}); - checked_set(y, ty, not_a_2digit_year, is); - checked_set(m, tm, not_a_month, is); - checked_set(d, td, not_a_day, is); -#endif - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'X': - if (command) - { - if (modified != CharT{'O'}) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - checked_set(H, tm.tm_hour, not_a_hour, is); - checked_set(M, tm.tm_min, not_a_minute, is); - checked_set(s, duration_cast(seconds{tm.tm_sec}), - not_a_second, is); - } - is.setstate(err); -#else - // "%T" - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int tH = not_a_hour; - int tM = not_a_minute; - long double S; - read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, - CharT{':'}, rld{S, 1, w}); - checked_set(H, tH, not_a_hour, is); - checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), - not_a_second, is); -#endif - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'C': - if (command) - { - int tC = not_a_century; -#if !ONLY_C_LOCALE - if (modified == CharT{}) - { -#endif - read(is, rs{tC, 1, width == -1 ? 2u : static_cast(width)}); -#if !ONLY_C_LOCALE - } - else - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - auto tY = tm.tm_year + 1900; - tC = (tY >= 0 ? tY : tY-99) / 100; - } - is.setstate(err); - } -#endif - checked_set(C, tC, not_a_century, is); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'D': - if (command) - { - if (modified == CharT{}) - { - int tn = not_a_month; - int td = not_a_day; - int ty = not_a_2digit_year; - read(is, ru{tn, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, - ru{td, 1, 2}, CharT{'\0'}, CharT{'/'}, CharT{'\0'}, - rs{ty, 1, 2}); - checked_set(y, ty, not_a_2digit_year, is); - checked_set(m, tn, not_a_month, is); - checked_set(d, td, not_a_day, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'F': - if (command) - { - if (modified == CharT{}) - { - int tY = not_a_year; - int tn = not_a_month; - int td = not_a_day; - read(is, rs{tY, 1, width == -1 ? 4u : static_cast(width)}, - CharT{'-'}, ru{tn, 1, 2}, CharT{'-'}, ru{td, 1, 2}); - checked_set(Y, tY, not_a_year, is); - checked_set(m, tn, not_a_month, is); - checked_set(d, td, not_a_day, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'd': - case 'e': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - int td = not_a_day; - read(is, rs{td, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(d, td, not_a_day, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - command = nullptr; - width = -1; - modified = CharT{}; - if ((err & ios::failbit) == 0) - checked_set(d, tm.tm_mday, not_a_day, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'H': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - int tH = not_a_hour; - read(is, ru{tH, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(H, tH, not_a_hour, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(H, tm.tm_hour, not_a_hour, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'I': - if (command) - { - if (modified == CharT{}) - { - int tI = not_a_hour_12_value; - // reads in an hour into I, but most be in [1, 12] - read(is, rs{tI, 1, width == -1 ? 2u : static_cast(width)}); - if (!(1 <= tI && tI <= 12)) - is.setstate(ios::failbit); - checked_set(I, tI, not_a_hour_12_value, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'j': - if (command) - { - if (modified == CharT{}) - { - int tj = not_a_doy; - read(is, ru{tj, 1, width == -1 ? 3u : static_cast(width)}); - checked_set(j, tj, not_a_doy, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'M': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - int tM = not_a_minute; - read(is, ru{tM, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(M, tM, not_a_minute, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(M, tm.tm_min, not_a_minute, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'm': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - int tn = not_a_month; - read(is, rs{tn, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(m, tn, not_a_month, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(m, tm.tm_mon + 1, not_a_month, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'n': - case 't': - if (command) - { - if (modified == CharT{}) - { - // %n matches a single white space character - // %t matches 0 or 1 white space characters - auto ic = is.peek(); - if (Traits::eq_int_type(ic, Traits::eof())) - { - ios_base::iostate err = ios_base::eofbit; - if (*fmt == 'n') - err |= ios_base::failbit; - is.setstate(err); - break; - } - if (isspace(ic)) - { - (void)is.get(); - } - else if (*fmt == 'n') - is.setstate(ios_base::failbit); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'p': - if (command) - { - if (modified == CharT{}) - { - int tp = not_a_ampm; -#if !ONLY_C_LOCALE - tm = std::tm{}; - tm.tm_hour = 1; - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - is.setstate(err); - if (tm.tm_hour == 1) - tp = 0; - else if (tm.tm_hour == 13) - tp = 1; - else - is.setstate(err); -#else - auto nm = detail::ampm_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - tp = i; -#endif - checked_set(p, tp, not_a_ampm, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - - break; - case 'r': - if (command) - { - if (modified == CharT{}) - { -#if !ONLY_C_LOCALE - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - { - checked_set(H, tm.tm_hour, not_a_hour, is); - checked_set(M, tm.tm_min, not_a_hour, is); - checked_set(s, duration_cast(seconds{tm.tm_sec}), - not_a_second, is); - } - is.setstate(err); -#else - // "%I:%M:%S %p" - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - long double S; - int tI = not_a_hour_12_value; - int tM = not_a_minute; - read(is, ru{tI, 1, 2}, CharT{':'}, ru{tM, 1, 2}, - CharT{':'}, rld{S, 1, w}); - checked_set(I, tI, not_a_hour_12_value, is); - checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), - not_a_second, is); - ws(is); - auto nm = detail::ampm_names(); - auto i = detail::scan_keyword(is, nm.first, nm.second) - nm.first; - checked_set(p, static_cast(i), not_a_ampm, is); -#endif - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'R': - if (command) - { - if (modified == CharT{}) - { - int tH = not_a_hour; - int tM = not_a_minute; - read(is, ru{tH, 1, 2}, CharT{'\0'}, CharT{':'}, CharT{'\0'}, - ru{tM, 1, 2}, CharT{'\0'}); - checked_set(H, tH, not_a_hour, is); - checked_set(M, tM, not_a_minute, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'S': - if (command) - { - #if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'E'}) -#endif - { - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - long double S; - read(is, rld{S, 1, width == -1 ? w : static_cast(width)}); - checked_set(s, round(duration{S}), - not_a_second, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'O'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(s, duration_cast(seconds{tm.tm_sec}), - not_a_second, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'T': - if (command) - { - if (modified == CharT{}) - { - using dfs = detail::decimal_format_seconds; - CONSTDATA auto w = Duration::period::den == 1 ? 2 : 3 + dfs::width; - int tH = not_a_hour; - int tM = not_a_minute; - long double S; - read(is, ru{tH, 1, 2}, CharT{':'}, ru{tM, 1, 2}, - CharT{':'}, rld{S, 1, w}); - checked_set(H, tH, not_a_hour, is); - checked_set(M, tM, not_a_minute, is); - checked_set(s, round(duration{S}), - not_a_second, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'Y': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#else - if (modified != CharT{'O'}) -#endif - { - int tY = not_a_year; - read(is, rs{tY, 1, width == -1 ? 4u : static_cast(width)}); - checked_set(Y, tY, not_a_year, is); - } -#if !ONLY_C_LOCALE - else if (modified == CharT{'E'}) - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(Y, tm.tm_year + 1900, not_a_year, is); - is.setstate(err); - } -#endif - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'y': - if (command) - { -#if !ONLY_C_LOCALE - if (modified == CharT{}) -#endif - { - int ty = not_a_2digit_year; - read(is, ru{ty, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(y, ty, not_a_2digit_year, is); - } -#if !ONLY_C_LOCALE - else - { - ios_base::iostate err = ios_base::goodbit; - f.get(is, nullptr, is, err, &tm, command, fmt+1); - if ((err & ios::failbit) == 0) - checked_set(Y, tm.tm_year + 1900, not_a_year, is); - is.setstate(err); - } -#endif - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'g': - if (command) - { - if (modified == CharT{}) - { - int tg = not_a_2digit_year; - read(is, ru{tg, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(g, tg, not_a_2digit_year, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'G': - if (command) - { - if (modified == CharT{}) - { - int tG = not_a_year; - read(is, rs{tG, 1, width == -1 ? 4u : static_cast(width)}); - checked_set(G, tG, not_a_year, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'U': - if (command) - { - if (modified == CharT{}) - { - int tU = not_a_week_num; - read(is, ru{tU, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(U, tU, not_a_week_num, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'V': - if (command) - { - if (modified == CharT{}) - { - int tV = not_a_week_num; - read(is, ru{tV, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(V, tV, not_a_week_num, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'W': - if (command) - { - if (modified == CharT{}) - { - int tW = not_a_week_num; - read(is, ru{tW, 1, width == -1 ? 2u : static_cast(width)}); - checked_set(W, tW, not_a_week_num, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'E': - case 'O': - if (command) - { - if (modified == CharT{}) - { - modified = *fmt; - } - else - { - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - } - else - read(is, *fmt); - break; - case '%': - if (command) - { - if (modified == CharT{}) - read(is, *fmt); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - command = fmt; - break; - case 'z': - if (command) - { - int tH, tM; - minutes toff = not_a_offset; - bool neg = false; - auto ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if (c == '-') - neg = true; - } - if (modified == CharT{}) - { - read(is, rs{tH, 2, 2}); - if (!is.fail()) - toff = hours{std::abs(tH)}; - if (is.good()) - { - ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if ('0' <= c && c <= '9') - { - read(is, ru{tM, 2, 2}); - if (!is.fail()) - toff += minutes{tM}; - } - } - } - } - else - { - read(is, rs{tH, 1, 2}); - if (!is.fail()) - toff = hours{std::abs(tH)}; - if (is.good()) - { - ic = is.peek(); - if (!Traits::eq_int_type(ic, Traits::eof())) - { - auto c = static_cast(Traits::to_char_type(ic)); - if (c == ':') - { - (void)is.get(); - read(is, ru{tM, 2, 2}); - if (!is.fail()) - toff += minutes{tM}; - } - } - } - } - if (neg) - toff = -toff; - checked_set(temp_offset, toff, not_a_offset, is); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - case 'Z': - if (command) - { - if (modified == CharT{}) - { - std::basic_string buf; - while (is.rdstate() == std::ios::goodbit) - { - auto i = is.rdbuf()->sgetc(); - if (Traits::eq_int_type(i, Traits::eof())) - { - is.setstate(ios::eofbit); - break; - } - auto wc = Traits::to_char_type(i); - auto c = static_cast(wc); - // is c a valid time zone name or abbreviation character? - if (!(CharT{1} < wc && wc < CharT{127}) || !(isalnum(c) || - c == '_' || c == '/' || c == '-' || c == '+')) - break; - buf.push_back(c); - is.rdbuf()->sbumpc(); - } - if (buf.empty()) - is.setstate(ios::failbit); - checked_set(temp_abbrev, buf, {}, is); - } - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - else - read(is, *fmt); - break; - default: - if (command) - { - if (width == -1 && modified == CharT{} && '0' <= *fmt && *fmt <= '9') - { - width = static_cast(*fmt) - '0'; - while ('0' <= fmt[1] && fmt[1] <= '9') - width = 10*width + static_cast(*++fmt) - '0'; - } - else - { - if (modified == CharT{}) - read(is, CharT{'%'}, width, *fmt); - else - read(is, CharT{'%'}, width, modified, *fmt); - command = nullptr; - width = -1; - modified = CharT{}; - } - } - else // !command - { - if (isspace(static_cast(*fmt))) - ws(is); // space matches 0 or more white space characters - else - read(is, *fmt); - } - break; - } - } - // is.rdstate() != ios::goodbit || *fmt == CharT{} - if (is.rdstate() == ios::goodbit && command) - { - if (modified == CharT{}) - read(is, CharT{'%'}, width); - else - read(is, CharT{'%'}, width, modified); - } - if (is.rdstate() != ios::goodbit && *fmt != CharT{} && !is.fail()) - is.setstate(ios::failbit); - if (!is.fail()) - { - if (y != not_a_2digit_year) - { - // Convert y and an optional C to Y - if (!(0 <= y && y <= 99)) - goto broken; - if (C == not_a_century) - { - if (Y == not_a_year) - { - if (y >= 69) - C = 19; - else - C = 20; - } - else - { - C = (Y >= 0 ? Y : Y-100) / 100; - } - } - int tY; - if (C >= 0) - tY = 100*C + y; - else - tY = 100*(C+1) - (y == 0 ? 100 : y); - if (Y != not_a_year && Y != tY) - goto broken; - Y = tY; - } - if (g != not_a_2digit_year) - { - // Convert g and an optional C to G - if (!(0 <= g && g <= 99)) - goto broken; - if (C == not_a_century) - { - if (G == not_a_year) - { - if (g >= 69) - C = 19; - else - C = 20; - } - else - { - C = (G >= 0 ? G : G-100) / 100; - } - } - int tG; - if (C >= 0) - tG = 100*C + g; - else - tG = 100*(C+1) - (g == 0 ? 100 : g); - if (G != not_a_year && G != tG) - goto broken; - G = tG; - } - if (Y < static_cast(year::min()) || Y > static_cast(year::max())) - Y = not_a_year; - bool computed = false; - if (G != not_a_year && V != not_a_week_num && wd != not_a_weekday) - { - year_month_day ymd_trial = sys_days(year{G-1}/December/Thursday[last]) + - (Monday-Thursday) + weeks{V-1} + - (weekday{static_cast(wd)}-Monday); - if (Y == not_a_year) - Y = static_cast(ymd_trial.year()); - else if (year{Y} != ymd_trial.year()) - goto broken; - if (m == not_a_month) - m = static_cast(static_cast(ymd_trial.month())); - else if (month(static_cast(m)) != ymd_trial.month()) - goto broken; - if (d == not_a_day) - d = static_cast(static_cast(ymd_trial.day())); - else if (day(static_cast(d)) != ymd_trial.day()) - goto broken; - computed = true; - } - if (Y != not_a_year && U != not_a_week_num && wd != not_a_weekday) - { - year_month_day ymd_trial = sys_days(year{Y}/January/Sunday[1]) + - weeks{U-1} + - (weekday{static_cast(wd)} - Sunday); - if (Y == not_a_year) - Y = static_cast(ymd_trial.year()); - else if (year{Y} != ymd_trial.year()) - goto broken; - if (m == not_a_month) - m = static_cast(static_cast(ymd_trial.month())); - else if (month(static_cast(m)) != ymd_trial.month()) - goto broken; - if (d == not_a_day) - d = static_cast(static_cast(ymd_trial.day())); - else if (day(static_cast(d)) != ymd_trial.day()) - goto broken; - computed = true; - } - if (Y != not_a_year && W != not_a_week_num && wd != not_a_weekday) - { - year_month_day ymd_trial = sys_days(year{Y}/January/Monday[1]) + - weeks{W-1} + - (weekday{static_cast(wd)} - Monday); - if (Y == not_a_year) - Y = static_cast(ymd_trial.year()); - else if (year{Y} != ymd_trial.year()) - goto broken; - if (m == not_a_month) - m = static_cast(static_cast(ymd_trial.month())); - else if (month(static_cast(m)) != ymd_trial.month()) - goto broken; - if (d == not_a_day) - d = static_cast(static_cast(ymd_trial.day())); - else if (day(static_cast(d)) != ymd_trial.day()) - goto broken; - computed = true; - } - if (j != not_a_doy && Y != not_a_year) - { - auto ymd_trial = year_month_day{local_days(year{Y}/1/1) + days{j-1}}; - if (m == 0) - m = static_cast(static_cast(ymd_trial.month())); - else if (month(static_cast(m)) != ymd_trial.month()) - goto broken; - if (d == 0) - d = static_cast(static_cast(ymd_trial.day())); - else if (day(static_cast(d)) != ymd_trial.day()) - goto broken; - j = not_a_doy; - } - auto ymd = year{Y}/m/d; - if (ymd.ok()) - { - if (wd == not_a_weekday) - wd = static_cast((weekday(sys_days(ymd)) - Sunday).count()); - else if (wd != static_cast((weekday(sys_days(ymd)) - Sunday).count())) - goto broken; - if (!computed) - { - if (G != not_a_year || V != not_a_week_num) - { - sys_days sd = ymd; - auto G_trial = year_month_day{sd + days{3}}.year(); - auto start = sys_days((G_trial - years{1})/December/Thursday[last]) + - (Monday - Thursday); - if (sd < start) - { - --G_trial; - if (V != not_a_week_num) - start = sys_days((G_trial - years{1})/December/Thursday[last]) - + (Monday - Thursday); - } - if (G != not_a_year && G != static_cast(G_trial)) - goto broken; - if (V != not_a_week_num) - { - auto V_trial = duration_cast(sd - start).count() + 1; - if (V != V_trial) - goto broken; - } - } - if (U != not_a_week_num) - { - auto start = sys_days(Sunday[1]/January/ymd.year()); - auto U_trial = floor(sys_days(ymd) - start).count() + 1; - if (U != U_trial) - goto broken; - } - if (W != not_a_week_num) - { - auto start = sys_days(Monday[1]/January/ymd.year()); - auto W_trial = floor(sys_days(ymd) - start).count() + 1; - if (W != W_trial) - goto broken; - } - } - } - fds.ymd = ymd; - if (I != not_a_hour_12_value) - { - if (!(1 <= I && I <= 12)) - goto broken; - if (p != not_a_ampm) - { - // p is in [0, 1] == [AM, PM] - // Store trial H in I - if (I == 12) - --p; - I += p*12; - // Either set H from I or make sure H and I are consistent - if (H == not_a_hour) - H = I; - else if (I != H) - goto broken; - } - else // p == not_a_ampm - { - // if H, make sure H and I could be consistent - if (H != not_a_hour) - { - if (I == 12) - { - if (H != 0 && H != 12) - goto broken; - } - else if (!(I == H || I == H+12)) - { - goto broken; - } - } - } - } - if (H != not_a_hour) - { - fds.has_tod = true; - fds.tod = time_of_day{hours{H}}; - } - if (M != not_a_minute) - { - fds.has_tod = true; - fds.tod.m_ = minutes{M}; - } - if (s != not_a_second) - { - fds.has_tod = true; - fds.tod.s_ = detail::decimal_format_seconds{s}; - } - if (j != not_a_doy) - { - fds.has_tod = true; - fds.tod.h_ += hours{days{j}}; - } - if (wd != not_a_weekday) - fds.wd = weekday{static_cast(wd)}; - if (abbrev != nullptr) - *abbrev = std::move(temp_abbrev); - if (offset != nullptr && temp_offset != not_a_offset) - *offset = temp_offset; - } - return is; - } -broken: - is.setstate(ios_base::failbit); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, year& y, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.year().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - y = fds.ymd.year(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, month& m, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - m = fds.ymd.month(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, day& d, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.day().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - d = fds.ymd.day(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, weekday& wd, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.wd.ok()) - is.setstate(ios::failbit); - if (!is.fail()) - wd = fds.wd; - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, year_month& ym, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - ym = fds.ymd.year()/fds.ymd.month(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, month_day& md, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.month().ok() || !fds.ymd.day().ok()) - is.setstate(ios::failbit); - if (!is.fail()) - md = fds.ymd.month()/fds.ymd.day(); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - year_month_day& ymd, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = seconds; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.ok()) - is.setstate(ios::failbit); - if (!is.fail()) - ymd = fds.ymd; - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - sys_time& tp, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - minutes offset_local{}; - auto offptr = offset ? offset : &offset_local; - fields fds{}; - fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offptr); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); - if (!is.fail()) - tp = round(sys_days(fds.ymd) - *offptr + fds.tod.to_duration()); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - local_time& tp, std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using CT = typename common_type::type; - fields fds{}; - fds.has_tod = true; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.ymd.ok() || !fds.tod.in_conventional_range()) - is.setstate(ios::failbit); - if (!is.fail()) - tp = round(local_seconds{local_days(fds.ymd)} + fds.tod.to_duration()); - return is; -} - -template > -std::basic_istream& -from_stream(std::basic_istream& is, const CharT* fmt, - std::chrono::duration& d, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) -{ - using namespace std; - using namespace std::chrono; - using Duration = std::chrono::duration; - using CT = typename common_type::type; - fields fds{}; - from_stream(is, fmt, fds, abbrev, offset); - if (!fds.has_tod) - is.setstate(ios::failbit); - if (!is.fail()) - d = duration_cast(fds.tod.to_duration()); - return is; -} - -template , - class Alloc = std::allocator> -struct parse_manip -{ - const std::basic_string format_; - Parsable& tp_; - std::basic_string* abbrev_; - std::chrono::minutes* offset_; - -public: - parse_manip(std::basic_string format, Parsable& tp, - std::basic_string* abbrev = nullptr, - std::chrono::minutes* offset = nullptr) - : format_(std::move(format)) - , tp_(tp) - , abbrev_(abbrev) - , offset_(offset) - {} - -}; - -template -std::basic_istream& -operator>>(std::basic_istream& is, - const parse_manip& x) -{ - return from_stream(is, x.format_.c_str(), x.tp_, x.abbrev_, x.offset_); -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp), - parse_manip{format, tp}) -{ - return {format, tp}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, &abbrev), - parse_manip{format, tp, &abbrev}) -{ - return {format, tp, &abbrev}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, - std::declval*>(), - &offset), - parse_manip{format, tp, nullptr, &offset}) -{ - return {format, tp, nullptr, &offset}; -} - -template -inline -auto -parse(const std::basic_string& format, Parsable& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), - format.c_str(), tp, &abbrev, &offset), - parse_manip{format, tp, &abbrev, &offset}) -{ - return {format, tp, &abbrev, &offset}; -} - -// const CharT* formats - -template -inline -auto -parse(const CharT* format, Parsable& tp) - -> decltype(from_stream(std::declval&>(), format, tp), - parse_manip{format, tp}) -{ - return {format, tp}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, std::basic_string& abbrev) - -> decltype(from_stream(std::declval&>(), format, - tp, &abbrev), - parse_manip{format, tp, &abbrev}) -{ - return {format, tp, &abbrev}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, - tp, std::declval*>(), &offset), - parse_manip{format, tp, nullptr, &offset}) -{ - return {format, tp, nullptr, &offset}; -} - -template -inline -auto -parse(const CharT* format, Parsable& tp, - std::basic_string& abbrev, std::chrono::minutes& offset) - -> decltype(from_stream(std::declval&>(), format, - tp, &abbrev, &offset), - parse_manip{format, tp, &abbrev, &offset}) -{ - return {format, tp, &abbrev, &offset}; -} - -// duration streaming - -namespace detail -{ - -template -class string_literal; - -template -inline -CONSTCD14 -string_literal::type, - N1 + N2 - 1> -operator+(const string_literal& x, const string_literal& y) NOEXCEPT; - -template -class string_literal -{ - CharT p_[N]; - - CONSTCD11 string_literal() NOEXCEPT - : p_{} - {} - -public: - using const_iterator = const CharT*; - - string_literal(string_literal const&) = default; - string_literal& operator=(string_literal const&) = delete; - - template ::type> - CONSTCD11 string_literal(CharT c) NOEXCEPT - : p_{c} - { - } - - template ::type> - CONSTCD11 string_literal(CharT c1, CharT c2) NOEXCEPT - : p_{c1, c2} - { - } - - template ::type> - CONSTCD11 string_literal(CharT c1, CharT c2, CharT c3) NOEXCEPT - : p_{c1, c2, c3} - { - } - - CONSTCD14 string_literal(const CharT(&a)[N]) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - template ::type> - CONSTCD14 string_literal(const char(&a)[N]) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - template ::value>::type> - CONSTCD14 string_literal(string_literal const& a) NOEXCEPT - : p_{} - { - for (std::size_t i = 0; i < N; ++i) - p_[i] = a[i]; - } - - CONSTCD11 const CharT* data() const NOEXCEPT {return p_;} - CONSTCD11 std::size_t size() const NOEXCEPT {return N-1;} - - CONSTCD11 const_iterator begin() const NOEXCEPT {return p_;} - CONSTCD11 const_iterator end() const NOEXCEPT {return p_ + N-1;} - - CONSTCD11 CharT const& operator[](std::size_t n) const NOEXCEPT - { - return p_[n]; - } - - template - friend - std::basic_ostream& - operator<<(std::basic_ostream& os, const string_literal& s) - { - return os << s.p_; - } - - template - friend - CONSTCD14 - string_literal::type, - N1 + N2 - 1> - operator+(const string_literal& x, const string_literal& y) NOEXCEPT; -}; - -template -CONSTCD11 -inline -string_literal -operator+(const string_literal& x, const string_literal& y) NOEXCEPT -{ - return string_literal(x[0], y[0]); -} - -template -CONSTCD11 -inline -string_literal -operator+(const string_literal& x, const string_literal& y) NOEXCEPT -{ - return string_literal(x[0], x[1], y[0]); -} - -template -CONSTCD14 -inline -string_literal::type, - N1 + N2 - 1> -operator+(const string_literal& x, const string_literal& y) NOEXCEPT -{ - using CT = typename std::conditional::type; - - string_literal r; - std::size_t i = 0; - for (; i < N1-1; ++i) - r.p_[i] = CT(x.p_[i]); - for (std::size_t j = 0; j < N2; ++j, ++i) - r.p_[i] = CT(y.p_[j]); - - return r; -} - - -template -inline -std::basic_string -operator+(std::basic_string x, const string_literal& y) -{ - x.append(y.data(), y.size()); - return x; -} - -#if __cplusplus >= 201402 && (!defined(__EDG_VERSION__) || __EDG_VERSION__ > 411) \ - && (!defined(__SUNPRO_CC) || __SUNPRO_CC > 0x5150) - -template {} || - std::is_same{} || - std::is_same{} || - std::is_same{}>> -CONSTCD14 -inline -string_literal -msl(CharT c) NOEXCEPT -{ - return string_literal{c}; -} - -CONSTCD14 -inline -std::size_t -to_string_len(std::intmax_t i) -{ - std::size_t r = 0; - do - { - i /= 10; - ++r; - } while (i > 0); - return r; -} - -template -CONSTCD14 -inline -std::enable_if_t -< - N < 10, - string_literal -> -msl() NOEXCEPT -{ - return msl(char(N % 10 + '0')); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - 10 <= N, - string_literal -> -msl() NOEXCEPT -{ - return msl() + msl(char(N % 10 + '0')); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - std::ratio::type::den != 1, - string_literal::type::num) + - to_string_len(std::ratio::type::den) + 4> -> -msl(std::ratio) NOEXCEPT -{ - using R = typename std::ratio::type; - return msl(CharT{'['}) + msl() + msl(CharT{'/'}) + - msl() + msl(CharT{']'}); -} - -template -CONSTCD14 -inline -std::enable_if_t -< - std::ratio::type::den == 1, - string_literal::type::num) + 3> -> -msl(std::ratio) NOEXCEPT -{ - using R = typename std::ratio::type; - return msl(CharT{'['}) + msl() + msl(CharT{']'}); -} - - -#else // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) - -inline -std::string -to_string(std::uint64_t x) -{ - return std::to_string(x); -} - -template -inline -std::basic_string -to_string(std::uint64_t x) -{ - auto y = std::to_string(x); - return std::basic_string(y.begin(), y.end()); -} - -template -inline -typename std::enable_if -< - std::ratio::type::den != 1, - std::basic_string ->::type -msl(std::ratio) -{ - using R = typename std::ratio::type; - return std::basic_string(1, '[') + to_string(R::num) + CharT{'/'} + - to_string(R::den) + CharT{']'}; -} - -template -inline -typename std::enable_if -< - std::ratio::type::den == 1, - std::basic_string ->::type -msl(std::ratio) -{ - using R = typename std::ratio::type; - return std::basic_string(1, '[') + to_string(R::num) + CharT{']'}; -} - -#endif // __cplusplus < 201402 || (defined(__EDG_VERSION__) && __EDG_VERSION__ <= 411) - -template -CONSTCD11 -inline -string_literal -msl(std::atto) NOEXCEPT -{ - return string_literal{'a'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::femto) NOEXCEPT -{ - return string_literal{'f'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::pico) NOEXCEPT -{ - return string_literal{'p'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::nano) NOEXCEPT -{ - return string_literal{'n'}; -} - -template -CONSTCD11 -inline -typename std::enable_if -< - std::is_same::value, - string_literal ->::type -msl(std::micro) NOEXCEPT -{ - return string_literal{'\xC2', '\xB5'}; -} - -template -CONSTCD11 -inline -typename std::enable_if -< - !std::is_same::value, - string_literal ->::type -msl(std::micro) NOEXCEPT -{ - return string_literal{CharT{static_cast('\xB5')}}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::milli) NOEXCEPT -{ - return string_literal{'m'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::centi) NOEXCEPT -{ - return string_literal{'c'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::deca) NOEXCEPT -{ - return string_literal{'d', 'a'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::deci) NOEXCEPT -{ - return string_literal{'d'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::hecto) NOEXCEPT -{ - return string_literal{'h'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::kilo) NOEXCEPT -{ - return string_literal{'k'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::mega) NOEXCEPT -{ - return string_literal{'M'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::giga) NOEXCEPT -{ - return string_literal{'G'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::tera) NOEXCEPT -{ - return string_literal{'T'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::peta) NOEXCEPT -{ - return string_literal{'P'}; -} - -template -CONSTCD11 -inline -string_literal -msl(std::exa) NOEXCEPT -{ - return string_literal{'E'}; -} - -template -CONSTCD11 -inline -auto -get_units(Period p) - -> decltype(msl(p) + string_literal{'s'}) -{ - return msl(p) + string_literal{'s'}; -} - -template -CONSTCD11 -inline -string_literal -get_units(std::ratio<1>) -{ - return string_literal{'s'}; -} - -template -CONSTCD11 -inline -string_literal -get_units(std::ratio<3600>) -{ - return string_literal{'h'}; -} - -template -CONSTCD11 -inline -string_literal -get_units(std::ratio<60>) -{ - return string_literal{'m', 'i', 'n'}; -} - -template -CONSTCD11 -inline -string_literal -get_units(std::ratio<86400>) -{ - return string_literal{'d'}; -} - -template > -struct make_string; - -template <> -struct make_string -{ - template - static - std::string - from(Rep n) - { - return std::to_string(n); - } -}; - -template -struct make_string -{ - template - static - std::basic_string - from(Rep n) - { - auto s = std::to_string(n); - return std::basic_string(s.begin(), s.end()); - } -}; - -template <> -struct make_string -{ - template - static - std::wstring - from(Rep n) - { - return std::to_wstring(n); - } -}; - -template -struct make_string -{ - template - static - std::basic_string - from(Rep n) - { - auto s = std::to_wstring(n); - return std::basic_string(s.begin(), s.end()); - } -}; - -} // namespace detail - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, - const std::chrono::duration& d) -{ - using namespace detail; - return os << make_string::from(d.count()) + - get_units(typename Period::type{}); -} - -} // namespace date - -#ifdef __GNUC__ -# pragma GCC diagnostic pop -#endif - -#endif // DATE_H