diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 9e8d1d37..b99037ab 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,5 +1,9 @@ ## Release Notes +### v3.4.2-beta-20190412 (Amethyst) + +- Fixed a stagenet voting bug. + ### v3.4.2-beta-20190411 (Amethyst) - Fixed problem when `bytecoind` stops responding via JSON RPC API. @@ -14,7 +18,7 @@ - Trezor and Ledger early support in `walletd`. *Incompatible API changes* -- deprecated `binary_size` field removed from transaction in all contexts. Please use the `size` field. +- Deprecated `binary_size` field removed from transaction in all contexts. Please use the `size` field. ### v3.4.1 (Amethyst) diff --git a/src/Core/BlockChain.cpp b/src/Core/BlockChain.cpp index 3e5c8dd8..c062317a 100644 --- a/src/Core/BlockChain.cpp +++ b/src/Core/BlockChain.cpp @@ -1092,7 +1092,7 @@ bool BlockChain::add_blod_impl(const api::BlockHeader &header) { bit->second.children.push_back(&blod); blod.checkpoint_difficulty = blod.parent->checkpoint_difficulty; - if (m_currency.upgrade_desired_major_version) { + if (m_currency.wish_to_upgrade()) { blod.vote_for_upgrade = uint8_t(m_currency.is_upgrade_vote(header.major_version, header.minor_version)); blod.upgrade_decided_height = blod.parent->upgrade_decided_height; if (!blod.upgrade_decided_height) { @@ -1103,14 +1103,11 @@ bool BlockChain::add_blod_impl(const api::BlockHeader &header) { invariant(blod.votes_for_upgrade_in_voting_window.size() <= m_currency.upgrade_voting_window, ""); size_t count = std::count(blod.votes_for_upgrade_in_voting_window.begin(), blod.votes_for_upgrade_in_voting_window.end(), uint8_t(1)); - // if(count != 0) - // std::cout << "Votes for version=" << int(m_currency.upgrade_desired_major_version) << " - // height=" << header.height << " votes=" << count << std::endl; if (count >= m_currency.upgrade_votes_required()) { blod.upgrade_decided_height = blod.height + m_currency.upgrade_window; - m_log(logging::INFO) << "Consensus upgrade decided on height=" << header.height - << " decided_height=" << blod.upgrade_decided_height << " bid=" << header.hash - << std::endl; + m_log(logging::INFO) << "Consensus upgrade votes gathered on height=" << header.height + << " upgrade_decided_height=" << blod.upgrade_decided_height + << " bid=" << header.hash << std::endl; blod.votes_for_upgrade_in_voting_window.clear(); } } @@ -1142,6 +1139,9 @@ void BlockChain::build_blods() { api::BlockHeader last_hard_checkpoint_header; if (!get_header(m_currency.last_hard_checkpoint().hash, &last_hard_checkpoint_header)) return; + invariant(last_hard_checkpoint_header.hash == m_currency.genesis_block_hash || last_hard_checkpoint_header.major_version == 1 + m_currency.upgrade_heights.size(), + "When adding checkpoint after consensus update, always update currency.upgrade_heights"); + std::set bad_header_hashes; // sidechains that do not pass through last hard checkpoint std::set good_header_hashes; // sidechains that pass through last hard checkpoint std::vector good_headers; @@ -1188,7 +1188,7 @@ void BlockChain::build_blods() { Blod &blod = m_blods[ha.hash]; blod.height = ha.height; blod.hash = ha.hash; - if (m_currency.upgrade_desired_major_version) { + if (m_currency.wish_to_upgrade()) { blod.vote_for_upgrade = uint8_t(m_currency.is_upgrade_vote(ha.major_version, ha.minor_version)); Height first_height = m_currency.last_hard_checkpoint().height < m_currency.upgrade_voting_window - 1 @@ -1200,10 +1200,8 @@ void BlockChain::build_blods() { blod.votes_for_upgrade_in_voting_window.push_back(vote); } blod.votes_for_upgrade_in_voting_window.push_back(blod.vote_for_upgrade); - size_t count = std::count(blod.votes_for_upgrade_in_voting_window.begin(), - blod.votes_for_upgrade_in_voting_window.end(), uint8_t(1)); - invariant( - count < m_currency.upgrade_votes_required(), "Upgrade happened before or on last hard checkpoint"); + // size_t count = std::count(blod.votes_for_upgrade_in_voting_window.begin(), + // blod.votes_for_upgrade_in_voting_window.end(), uint8_t(1)); } } } @@ -1213,7 +1211,7 @@ void BlockChain::build_blods() { void BlockChain::fill_statistics(api::cnd::GetStatistics::Response &res) const { res.checkpoints = get_latest_checkpoints(); - if (!m_currency.upgrade_desired_major_version) + if (!m_currency.wish_to_upgrade()) return; auto bit = m_blods.find(get_tip_bid()); if (bit == m_blods.end()) @@ -1225,14 +1223,13 @@ void BlockChain::fill_statistics(api::cnd::GetStatistics::Response &res) const { } bool BlockChain::fill_next_block_versions( - const api::BlockHeader &prev_info, bool cooperative, uint8_t *major_mm, uint8_t *major_cm, uint8_t *minor) const { + const api::BlockHeader &prev_info, uint8_t *major_mm, uint8_t *major_cm) const { *major_cm = *major_mm = m_currency.get_block_major_version_for_height(prev_info.height + 1); +#if bytecoin_ALLOW_CM if (*major_cm >= m_currency.amethyst_block_version) *major_cm += 1; - *minor = 0; - if (*major_mm == m_currency.upgrade_from_major_version) - *minor = m_currency.upgrade_indicator_minor_version; - if (!m_currency.upgrade_desired_major_version) +#endif + if (!m_currency.wish_to_upgrade()) return true; if (m_blods.empty()) return true; @@ -1241,10 +1238,11 @@ bool BlockChain::fill_next_block_versions( return false; if (!bit->second.upgrade_decided_height || prev_info.height + 1 < bit->second.upgrade_decided_height) return true; - *major_cm = *major_mm = m_currency.upgrade_desired_major_version; + *major_cm = *major_mm = m_currency.upgrade_desired_major; +#if bytecoin_ALLOW_CM if (*major_cm >= m_currency.amethyst_block_version) *major_cm += 1; - *minor = 0; +#endif return true; } diff --git a/src/Core/BlockChain.hpp b/src/Core/BlockChain.hpp index ea0db62d..a255767e 100644 --- a/src/Core/BlockChain.hpp +++ b/src/Core/BlockChain.hpp @@ -216,8 +216,7 @@ class BlockChain { protected: void build_blods(); - bool fill_next_block_versions(const api::BlockHeader &prev_info, bool cooperative, uint8_t *major_mm, - uint8_t *major_cm, uint8_t *minor) const; + bool fill_next_block_versions(const api::BlockHeader &prev_info, uint8_t *major_mm, uint8_t *major_cm) const; }; } // namespace cn diff --git a/src/Core/BlockChainState.cpp b/src/Core/BlockChainState.cpp index e9ae5c3b..88d5eb68 100644 --- a/src/Core/BlockChainState.cpp +++ b/src/Core/BlockChainState.cpp @@ -272,8 +272,8 @@ void BlockChainState::check_standalone_consensus( const bool is_amethyst = block.header.major_version >= m_currency.amethyst_block_version; const auto body_proxy = get_body_proxy_from_template(block.header); - uint8_t should_be_major_mm = 0, should_be_major_cm = 0, might_be_minor = 0; - if (!fill_next_block_versions(prev_info, false, &should_be_major_mm, &should_be_major_cm, &might_be_minor)) + uint8_t should_be_major_mm = 0, should_be_major_cm = 0; + if (!fill_next_block_versions(prev_info, &should_be_major_mm, &should_be_major_cm)) throw ConsensusError("Block does not pass through last hard checkpoint"); if (block.header.major_version != should_be_major_mm && block.header.major_version != should_be_major_cm) throw ConsensusError(common::to_string("Block version wrong", int(block.header.major_version), "instead of", @@ -491,8 +491,9 @@ void BlockChainState::create_mining_block_template(const Hash &parent_bid, const throw std::runtime_error("Attempt to mine from block we do not have"); *height = parent_info.height + 1; *b = BlockTemplate{}; + b->minor_version = m_currency.upgrade_vote_minor; uint8_t major_version_cm = 0; - if (!fill_next_block_versions(parent_info, false, &b->major_version, &major_version_cm, &b->minor_version)) + if (!fill_next_block_versions(parent_info, &b->major_version, &major_version_cm)) throw std::runtime_error( "Mining of block in chain not passing through last hard checkpoint is not possible (will not be accepted by network anyway)"); const bool is_amethyst = b->major_version >= m_currency.amethyst_block_version; diff --git a/src/Core/Currency.cpp b/src/Core/Currency.cpp index d14d43c0..b6002656 100644 --- a/src/Core/Currency.cpp +++ b/src/Core/Currency.cpp @@ -73,19 +73,20 @@ Currency::Currency(const std::string &net) , key_image_subgroup_checking_height(KEY_IMAGE_SUBGROUP_CHECKING_HEIGHT) , amethyst_block_version(BLOCK_VERSION_AMETHYST) , amethyst_transaction_version(TRANSACTION_VERSION_AMETHYST) - , upgrade_from_major_version(3) - , upgrade_indicator_minor_version(7) - , upgrade_desired_major_version(4) + , upgrade_vote_minor(7) + , upgrade_indicator_minor(7) + , upgrade_desired_major(4) , upgrade_voting_window(UPGRADE_VOTING_WINDOW) , upgrade_window(UPGRADE_WINDOW) , sendproof_base58_prefix(SENDPROOF_BASE58_PREFIX) { + // for upgrade_desired_major=4 upgrade_indicator_minor=7 if (net == "test") { upgrade_heights = {1, 1}; // block 1 is already V3 upgrade_voting_window = 30; upgrade_window = 10; } if (net == "stage") { - upgrade_heights = {1, 1}; // block 1 is already V3 + upgrade_heights = {1, 1, 64233}; // block 1 is already V3 upgrade_window = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; } { @@ -165,15 +166,11 @@ bool Currency::is_transaction_unlocked(uint8_t block_major_version, BlockOrTimes } bool Currency::is_upgrade_vote(uint8_t major, uint8_t minor) const { - if (major == upgrade_from_major_version) - return minor == upgrade_indicator_minor_version; -#if bytecoin_ALLOW_CM - if (upgrade_from_major_version >= amethyst_block_version && major == upgrade_from_major_version + 1) - return minor == upgrade_indicator_minor_version; -#endif - return false; + return minor >= upgrade_indicator_minor; } +bool Currency::wish_to_upgrade() const { return upgrade_desired_major > 1 + upgrade_heights.size(); } + Height Currency::expected_blocks_per_day() const { return 24 * 60 * 60 / difficulty_target / platform::get_time_multiplier_for_tests(); } @@ -407,20 +404,20 @@ bool Currency::parse_account_address_string(const std::string &str, AccountAddre } // We used C-style here to have same code on Ledger -static void c_ffw(Amount am, size_t digs, char * buf) { - for(;digs > 0; digs -= 1 ) { - Amount d = am % 10; - am = am / 10; - buf[digs - 1] = '0' + d; +static void c_ffw(Amount am, size_t digs, char *buf) { + while (digs-- > 0) { + Amount d = am % 10; + am = am / 10; + buf[digs] = '0' + d; } } -size_t c_format_amount(Amount amount, char * buffer, size_t len){ +size_t c_format_amount(Amount amount, char *buffer, size_t len) { const size_t COIN = 100000000; const size_t CENT = COIN / 100; - Amount ia = amount / COIN; - Amount fa = amount - ia * COIN; - size_t pos = 0; + Amount ia = amount / COIN; + Amount fa = amount - ia * COIN; + size_t pos = 0; while (ia >= 1000) { pos += 4; memmove(buffer + 4, buffer, pos); @@ -428,13 +425,13 @@ size_t c_format_amount(Amount amount, char * buffer, size_t len){ c_ffw(ia % 1000, 3, buffer + 1); ia /= 1000; } - while(true){ + while (true) { Amount d = ia % 10; - ia = ia / 10; + ia = ia / 10; pos += 1; memmove(buffer + 1, buffer, pos); buffer[0] = '0' + d; - if(ia == 0) + if (ia == 0) break; } if (fa != 0) { // cents @@ -444,13 +441,13 @@ size_t c_format_amount(Amount amount, char * buffer, size_t len){ fa %= CENT; } if (fa != 0) { -// buffer[pos++] = '\''; + // buffer[pos++] = '\''; c_ffw(fa / 1000, 3, buffer + pos); pos += 3; fa %= 1000; } if (fa != 0) { -// buffer[pos++] = '\''; + // buffer[pos++] = '\''; c_ffw(fa, 3, buffer + pos); pos += 3; } @@ -478,15 +475,15 @@ std::string Currency::format_amount(size_t number_of_decimal_places, Amount amou fa %= DECIMAL_PLACES.at(number_of_decimal_places - 2); } if (fa != 0) { - result += ffw(fa / 1000, 3); // "'" + + result += ffw(fa / 1000, 3); fa %= 1000; } if (fa != 0) - result += ffw(fa, 3); // "'" + -// char buffer[64]{}; -// std::string res2(buffer, c_format_amount(amount, buffer, sizeof(buffer))); -// invariant(res2 == result, ""); -// std::cout << amount << " -> " << result << std::endl; + result += ffw(fa, 3); + // char buffer[64]{}; + // std::string res2(buffer, c_format_amount(amount, buffer, sizeof(buffer))); + // invariant(res2 == result, "c_format_amount error"); + // std::cout << amount << " -> " << result << std::endl; return result; } diff --git a/src/Core/Currency.hpp b/src/Core/Currency.hpp index 871802a9..54f52c7b 100644 --- a/src/Core/Currency.hpp +++ b/src/Core/Currency.hpp @@ -70,10 +70,11 @@ class Currency { // Consensus calculations depend on those parameters uint8_t amethyst_transaction_version; // upgrade voting threshold must not be reached before or at last sw checkpoint! - uint8_t upgrade_from_major_version; - uint8_t upgrade_indicator_minor_version; + uint8_t upgrade_vote_minor; + uint8_t upgrade_indicator_minor; bool is_upgrade_vote(uint8_t major, uint8_t minor) const; - uint8_t upgrade_desired_major_version; + bool wish_to_upgrade() const; + uint8_t upgrade_desired_major; Height upgrade_voting_window; Height upgrade_votes_required() const; Height upgrade_window; diff --git a/src/Core/Wallet.cpp b/src/Core/Wallet.cpp index 3e842ea4..3c2c4abf 100644 --- a/src/Core/Wallet.cpp +++ b/src/Core/Wallet.cpp @@ -765,7 +765,8 @@ WalletHD::WalletHD(const Currency ¤cy, logging::ILogger &log, const std::s const std::string &password, bool readonly) : Wallet(currency, log, path) { bool created = false; - ewrap(m_db_dbi.open_check_create(readonly ? platform::O_READ_EXISTING : platform::O_OPEN_EXISTING, path, &created), Exception(api::WALLET_FILE_READ_ERROR, "Cannot open wallet file " + path)); + ewrap(m_db_dbi.open_check_create(readonly ? platform::O_READ_EXISTING : platform::O_OPEN_EXISTING, path, &created), + Exception(api::WALLET_FILE_READ_ERROR, "Cannot open wallet file " + path)); if (get_is_hardware()) { auto connected = hardware::HardwareWallet::get_connected(); @@ -817,7 +818,8 @@ WalletHD::WalletHD(const Currency ¤cy, logging::ILogger &log, const std::s m_hw = std::make_unique(std::move(connected.back())); } bool created = false; - ewrap(m_db_dbi.open_check_create(platform::O_CREATE_NEW, path, &created), Exception(api::WALLET_FILE_READ_ERROR, "Cannot create wallet file " + path)); + ewrap(m_db_dbi.open_check_create(platform::O_CREATE_NEW, path, &created), + Exception(api::WALLET_FILE_READ_ERROR, "Cannot create wallet file " + path)); m_db_dbi.exec( "CREATE TABLE unencrypted(key BLOB PRIMARY KEY COLLATE BINARY NOT NULL, value BLOB NOT NULL) WITHOUT ROWID"); m_db_dbi.exec( diff --git a/src/Core/hardware/Ledger.cpp b/src/Core/hardware/Ledger.cpp index b765b109..d7e0513a 100644 --- a/src/Core/hardware/Ledger.cpp +++ b/src/Core/hardware/Ledger.cpp @@ -300,7 +300,7 @@ int Ledger::sendApdu(const uint8_t *data, size_t len, uint8_t *out, size_t out_l // int length_ignore = 0; // int result = libusb_interrupt_transfer(m_device.handle, 0x82, chunk, static_cast(MAX_BLOCK), //&length_ignore, TIMEOUT); if (result < 0) return result; if( !parse_chunk(chunk, - //MAX_BLOCK, DEFAULT_LEDGER_CHANNEL, sequence, &response_length, &response)) return -1; + // MAX_BLOCK, DEFAULT_LEDGER_CHANNEL, sequence, &response_length, &response)) return -1; // } // if(response.size() < 2) // return -1; @@ -391,12 +391,12 @@ static void write_big_endian(T value, size_t size, common::IOutputStream *s) { void Ledger::get_app_info() { common::VectorStream vs; - vs = common::VectorStream(sendApdu(INS_GET_APP_INFO, vs.buffer())); + vs = common::VectorStream(sendApdu(INS_GET_APP_INFO, vs.buffer())); m_app_info.major_version = vs.read_byte(); m_app_info.minor_version = vs.read_byte(); m_app_info.patch_version = vs.read_byte(); - static constexpr char expected_app_name[] = "Bytecoin"; + static constexpr char expected_app_name[] = "Bytecoin"; static constexpr uint8_t expected_app_name_size = sizeof(expected_app_name) - 1; const uint8_t app_name_size = vs.read_byte(); @@ -407,7 +407,7 @@ void Ledger::get_app_info() { throw std::runtime_error("invalid ledger app is running"); static constexpr uint8_t max_reasonable_version_size = 50; - const uint8_t version_size = vs.read_byte(); + const uint8_t version_size = vs.read_byte(); if (version_size > max_reasonable_version_size) throw std::runtime_error("invalid ledger app version"); vs.read(m_app_info.app_version, version_size); diff --git a/src/CryptoNote.hpp b/src/CryptoNote.hpp index 711c2d4c..d6739410 100644 --- a/src/CryptoNote.hpp +++ b/src/CryptoNote.hpp @@ -111,7 +111,7 @@ struct BlockHeader { // versions are serialized as varints, but values > 127 will break most miners // which assume nonce is at fixed offset. Those miners also expect timestamp to occupy exactly 5 bytes. uint8_t major_version = 0; - uint8_t minor_version = 0; // Not version at all, used for hard fork voting + uint8_t minor_version = 0; // Not version at all, used for consensus update voting Timestamp timestamp = 0; Hash previous_block_hash; BinaryArray nonce; // 4 bytes, except in blocks with is_cm_mined() (variable-length there) diff --git a/src/CryptoNoteConfig.hpp b/src/CryptoNoteConfig.hpp index c2ce5cb1..9c6a7e61 100644 --- a/src/CryptoNoteConfig.hpp +++ b/src/CryptoNoteConfig.hpp @@ -215,12 +215,19 @@ constexpr const HardCheckpoint CHECKPOINTS[] = { {1628000, common::pfh("4e7b55e53402c71c45cb97f8ed78ed3f128c802008c83b0153aa52c30b740c68")}, {1670000, common::pfh("58770b800108c72512a386783fd0a4326c74dc9f99b538337a195945b89a9a6f")}, {1709000, common::pfh("82185d3365e730074c4804b151c19d29ee4b2407772467853f96839567d8b45a")}, - {1740000, common::pfh("769ef18196c1ebeab9ef372e40475c2ce8c65ca7e22b0894e41f3d675343ab49")}, - {1764000, common::pfh("b79c80df808d6447965e5e75d0e2a40ab07e591e9efa8efa1be3945fe3278669")}}; + {1740000, common::pfh("769ef18196c1ebeab9ef372e40475c2ce8c65ca7e22b0894e41f3d675343ab49")}, + {1764000, common::pfh("b79c80df808d6447965e5e75d0e2a40ab07e591e9efa8efa1be3945fe3278669")}}; + +// When adding checkpoint and BEFORE release, you MUST check that daemon fully syncs both mainnet and stagenet. + +// Be extra careful when setting checkpoint around consensus update heights. Follow rules: +// 1. never set checkpoint after or to height where required # of votes for upgrade was gathered +// 2. never set checkpoint before height where upgrade happened (with desired major version) +// 3. after setting checkpoint after upgrade, modify upgrade_heights array constexpr const HardCheckpoint CHECKPOINTS_STAGENET[] = { {450, common::pfh("c69823a6b3e0c1f724411e697219a9d31a2df900cb49bb0488b1a91a9989a805")}, {30000, common::pfh("4a3b02206d120bab6c3bef4a7bcbc1934b5327c27c181d790f4db407dc92c640")}, - {49000, common::pfh("1960a677cda6afd47dd4a928bf876b7cb7c9bd86107e3193ca9b0fd0926bad4c")}, - {70000, common::pfh("10ce87ab253c1142414a700336795057781572b5d9f026c57463ae420e456240")}}; + {49000, common::pfh("1960a677cda6afd47dd4a928bf876b7cb7c9bd86107e3193ca9b0fd0926bad4c")}, + {70000, common::pfh("10ce87ab253c1142414a700336795057781572b5d9f026c57463ae420e456240")}}; }} // namespace cn::parameters diff --git a/src/common/Ipv4Address.cpp b/src/common/Ipv4Address.cpp index 5dd95b3f..5f10c163 100644 --- a/src/common/Ipv4Address.cpp +++ b/src/common/Ipv4Address.cpp @@ -100,8 +100,8 @@ void parse_ip_address_and_port(const std::string &addr, BinaryArray *ip, uint16_ // // *ip = BinaryArray{ // static_cast(v[0]), static_cast(v[1]), static_cast(v[2]), - //static_cast(v[3])}; if (local_port > 65535) return false; *port = static_cast(local_port); - // return true; + // static_cast(v[3])}; if (local_port > 65535) return false; *port = + // static_cast(local_port); return true; } void parse_ip_address_and_port(const std::string &addr, std::string *ip, uint16_t *port) { diff --git a/src/platform/DBsqlite3.cpp b/src/platform/DBsqlite3.cpp index 0a995f18..9960a2e8 100644 --- a/src/platform/DBsqlite3.cpp +++ b/src/platform/DBsqlite3.cpp @@ -27,9 +27,11 @@ void sqlite::Dbi::open_check_create(OpenMode open_mode, const std::string &full_ "sqlite3_open "); invariant(open_mode != OpenMode::O_CREATE_ALWAYS, "sqlite database does not support clearing existing data"); if (open_mode == OpenMode::O_READ_EXISTING) - exec("BEGIN TRANSACTION", "modifying database impossible. Disk read-only or database used by other running instance?"); + exec("BEGIN TRANSACTION", + "modifying database impossible. Disk read-only or database used by other running instance?"); else - exec("BEGIN IMMEDIATE TRANSACTION", "modifying database impossible. Disk read-only or database used by other running instance?"); + exec("BEGIN IMMEDIATE TRANSACTION", + "modifying database impossible. Disk read-only or database used by other running instance?"); sqlite::Stmt stmt_get_tables; stmt_get_tables.prepare(*this, "SELECT name FROM sqlite_master WHERE type = 'table'"); *created = !stmt_get_tables.step(); @@ -38,14 +40,20 @@ void sqlite::Dbi::open_check_create(OpenMode open_mode, const std::string &full_ sqlite::check(sqlite3_busy_timeout(handle, 5000), "sqlite3_busy_timeout"); // ms } -void sqlite::Dbi::exec(const char *statement, const char * err_msg) { +void sqlite::Dbi::exec(const char *statement, const char *err_msg) { auto rc = sqlite3_exec(handle, statement, nullptr, nullptr, nullptr); if (rc != SQLITE_OK) - throw Error((err_msg ? err_msg : "") + std::string(" sqlite error code=") + common::to_string(rc) + " for db path=" + full_path); + throw Error((err_msg ? err_msg : "") + std::string(" sqlite error code=") + common::to_string(rc) + + " for db path=" + full_path); +} +void sqlite::Dbi::commit_txn() { + exec("COMMIT TRANSACTION", "saving database data failed. Disk unplugged or out of disk space?"); } -void sqlite::Dbi::commit_txn() { exec("COMMIT TRANSACTION", "saving database data failed. Disk unplugged or out of disk space?"); } void sqlite::Dbi::begin_txn() { - exec("BEGIN IMMEDIATE TRANSACTION", "modifying database impossible. Disk read-only or database used by other running instance?"); // TODO - if readonly, will throw + exec("BEGIN IMMEDIATE TRANSACTION", + "modifying database impossible. Disk read-only or database used by other running instance?"); // TODO - if + // readonly, will + // throw } sqlite::Dbi::~Dbi() { diff --git a/src/platform/DBsqlite3.hpp b/src/platform/DBsqlite3.hpp index 8ce073f3..203412fb 100644 --- a/src/platform/DBsqlite3.hpp +++ b/src/platform/DBsqlite3.hpp @@ -16,9 +16,9 @@ namespace platform { namespace sqlite { struct Dbi : private common::Nocopy { sqlite3 *handle = nullptr; - std::string full_path; // Remembered after open for better error messages + std::string full_path; // Remembered after open for better error messages void open_check_create(OpenMode open_mode, const std::string &full_path, bool *created); - void exec(const char *statement, const char * err_msg = nullptr); + void exec(const char *statement, const char *err_msg = nullptr); void commit_txn(); void begin_txn(); ~Dbi(); diff --git a/src/version.hpp b/src/version.hpp index 346634ee..906d8fb0 100644 --- a/src/version.hpp +++ b/src/version.hpp @@ -4,8 +4,8 @@ #pragma once // defines are for Windows resource compiler -#define bytecoin_VERSION_WINDOWS_COMMA 3, 19, 4, 11 -#define bytecoin_VERSION_STRING "v3.4.2-beta-20190411 (amethyst)" +#define bytecoin_VERSION_WINDOWS_COMMA 3, 19, 4, 12 +#define bytecoin_VERSION_STRING "v3.4.2-beta-20190412 (amethyst)" #ifndef RC_INVOKED // Windows resource compiler