diff --git a/contrib/db/liblmdb/mdb.c b/contrib/db/liblmdb/mdb.c index ca9f3b12..f9b48233 100644 --- a/contrib/db/liblmdb/mdb.c +++ b/contrib/db/liblmdb/mdb.c @@ -133,7 +133,7 @@ extern int cacheflush(char *addr, int nbytes, int cache); #ifdef _WIN32 typedef int64_t off64_t; #else -typedef off_t off64_t; +//typedef off_t off64_t; #endif diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 00000000..f27305af --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,75 @@ +name: zano +base: core18 +adopt-info: zano +summary: "Zano coin: official wallet. Secure. Scalable. Easy to Use." +description: | + Zano is a scalable and secure coin, designed for use in e-commerce. + The technology behind our blockchain provides reliability, security, + and flexibility a perfect option for P2P transactions. + More info: http://zano.org +grade: stable +confinement: strict + +architectures: + - build-on: amd64 + - build-on: i386 + +parts: + zano: + source: https://github.com/hyle-team/zano.git + plugin: cmake + override-pull: | + snapcraftctl pull + snapcraftctl set-version "$(git describe)" + configflags: + - -DBUILD_GUI=TRUE + override-build: | + snapcraftctl build + mkdir -p $SNAPCRAFT_PART_INSTALL/opt/Zano + cp $SNAPCRAFT_PART_BUILD/src/Zano $SNAPCRAFT_PART_INSTALL/opt/Zano/ + cp $SNAPCRAFT_PART_BUILD/src/simplewallet $SNAPCRAFT_PART_INSTALL/opt/Zano/ + cp $SNAPCRAFT_PART_BUILD/src/zanod $SNAPCRAFT_PART_INSTALL/opt/Zano/ + rsync -a $SNAPCRAFT_PART_SRC/src/gui/qt-daemon/html $SNAPCRAFT_PART_INSTALL/opt/Zano --exclude less --exclude package.json --exclude gulpfile.js + build-packages: + - make + - g++ + - libboost-all-dev + - qtwebengine5-dev + - rsync + build-attributes: [keep-execstack] + stage-packages: + - libboost-system1.65.1 + - libboost-filesystem1.65.1 + - libboost-thread1.65.1 + - libboost-date-time1.65.1 + - libboost-chrono1.65.1 + - libboost-regex1.65.1 + - libboost-serialization1.65.1 + - libboost-program-options1.65.1 + - libboost-locale1.65.1 + +apps: + zano: + command: opt/Zano/Zano --data-dir $SNAP_USER_COMMON + extensions: + - kde-neon + plugs: + - network + - home + - desktop + - opengl #for QML support + - browser-support #for Qt WebEngine support + - audio-playback + - unity7 #for tray icon support + simplewallet: + command: opt/Zano/simplewallet + plugs: + - network + - home + zanod: + command: opt/Zano/zanod --data-dir $SNAP_USER_COMMON + environment: + LC_ALL: C + plugs: + - network + - network-bind diff --git a/src/gui/qt-daemon/application/mainwindow.cpp b/src/gui/qt-daemon/application/mainwindow.cpp index 80777b98..78a1ac0d 100644 --- a/src/gui/qt-daemon/application/mainwindow.cpp +++ b/src/gui/qt-daemon/application/mainwindow.cpp @@ -941,9 +941,12 @@ QString MainWindow::set_localization_strings(const QString param) else { m_localization = lr.strings; - m_quit_action->setText(QString().fromUtf8(m_localization[localization_id_quit].c_str())); - m_restore_action->setText(QString().fromUtf8(m_localization[localization_id_tray_menu_show].c_str())); - m_minimize_action->setText(QString().fromUtf8(m_localization[localization_id_tray_menu_minimize].c_str())); + if(m_quit_action) + m_quit_action->setText(QString::fromStdString(m_localization[localization_id_quit])); + if(m_restore_action) + m_restore_action->setText(QString::fromStdString(m_localization[localization_id_tray_menu_show])); + if(m_minimize_action) + m_minimize_action->setText(QString::fromStdString(m_localization[localization_id_tray_menu_minimize])); resp.error_code = API_RETURN_CODE_OK; LOG_PRINT_L0("New localization set, language title: " << lr.language_title << ", strings " << lr.strings.size()); } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c37fef0a..3770251a 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -756,8 +756,9 @@ bool simple_wallet::list_recent_transfers(const std::vector& args) std::vector unconfirmed; std::vector recent; uint64_t total = 0; - m_wallet->get_recent_transfers_history(recent, 0, 0, total); - m_wallet->get_unconfirmed_transfers(unconfirmed); + uint64_t last_index = 0; + m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false); + m_wallet->get_unconfirmed_transfers(unconfirmed, false); //workaround for missed fee success_msg_writer() << "Unconfirmed transfers: "; @@ -809,8 +810,9 @@ bool simple_wallet::export_recent_transfers(const std::vector& args std::vector unconfirmed; std::vector recent; uint64_t total = 0; - m_wallet->get_recent_transfers_history(recent, 0, 0, total); - m_wallet->get_unconfirmed_transfers(unconfirmed); + uint64_t last_index = 0; + m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false); + m_wallet->get_unconfirmed_transfers(unconfirmed, false); //workaround for missed fee stringstream ss; LOG_PRINT_GREEN("Generating text....", LOG_LEVEL_0); diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 7a31708b..cf6e7987 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -158,6 +158,7 @@ void wallet2::init(const std::string& daemon_address) { m_miner_text_info = PROJECT_VERSION_LONG; m_core_proxy->set_connection_addr(daemon_address); + m_core_proxy->check_connection(); } //---------------------------------------------------------------------------------------------------- bool wallet2::set_core_proxy(const std::shared_ptr& proxy) @@ -327,42 +328,12 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t const currency::txin_to_key& intk = boost::get(in); // check if this input spends our output - //transfer_details* p_td = nullptr; uint64_t tid = UINT64_MAX; if (is_auditable() && is_watch_only()) { - // auditable wallet - // try to find a reference among own UTXOs - std::vector abs_key_offsets = relative_output_offsets_to_absolute(intk.key_offsets); // potential speed-up: don't convert to abs offsets as we interested only in direct spends for auditable wallets. Now it's kind a bit paranoid. - for(auto v : abs_key_offsets) - { - if (v.type() != typeid(uint64_t)) - continue; - uint64_t gindex = boost::get(v); - auto it = m_amount_gindex_to_transfer_id.find(std::make_pair(intk.amount, gindex)); - if (it != m_amount_gindex_to_transfer_id.end()) - { - tid = it->second; - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(tid < m_transfers.size(), "invalid tid: " << tid << ", ref from input with amount: " << intk.amount << ", gindex: " << gindex); - auto& td = m_transfers[it->second]; - if (intk.key_offsets.size() != 1) - { - // own output was used in non-direct transaction - // the core should not allow this to happen, the only way it may happen - mixing in own output that was sent without mix_attr == 1 - // log strange situation - std::stringstream ss; - ss << "own transfer tid=" << tid << " tx=" << td.tx_hash() << " mix_attr=" << td.mix_attr() << ", is referenced by a transaction with mixins, ref from input with amount: " << intk.amount << ", gindex: " << gindex; - WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0); - if (m_wcallback) - m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str()); - continue; - } - WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(!td.is_spent(), "transfer is spent, tid: " << tid << ", ref from input with amount: " << intk.amount << ", gindex: " << gindex); - // own output is spent, handle it - break; - } - } + // tracking wallet, assuming all outputs are spent directly because of mix_attr = 1 + tid = get_directly_spent_transfer_id_by_input_in_tracking_wallet(intk); } else { @@ -1584,6 +1555,49 @@ bool wallet2::has_related_alias_entry_unconfirmed(const currency::transaction& t return false; } //---------------------------------------------------------------------------------------------------- +uint64_t wallet2::get_directly_spent_transfer_id_by_input_in_tracking_wallet(const currency::txin_to_key& intk) +{ + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(is_auditable() && is_watch_only(), "this is not an auditable-watch-only (tracking) wallet"); + + uint64_t tid = UINT64_MAX; + + // try to find a reference among own UTXOs + std::vector abs_key_offsets = relative_output_offsets_to_absolute(intk.key_offsets); // potential speed-up: don't convert to abs offsets as we interested only in direct spends for auditable wallets. Now it's kind a bit paranoid. + for (auto v : abs_key_offsets) + { + if (v.type() != typeid(uint64_t)) + continue; + uint64_t gindex = boost::get(v); + auto it = m_amount_gindex_to_transfer_id.find(std::make_pair(intk.amount, gindex)); + if (it != m_amount_gindex_to_transfer_id.end()) + { + tid = it->second; + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(tid < m_transfers.size(), "invalid tid: " << tid << ", ref from input with amount: " << intk.amount << ", gindex: " << gindex); + auto& td = m_transfers[it->second]; + if (intk.key_offsets.size() != 1) + { + // own output was used in non-direct transaction + // the core should not allow this to happen, the only way it may happen - mixing in own output that was sent without mix_attr == 1 + // log strange situation + std::stringstream ss; + ss << "own transfer tid=" << tid << " tx=" << td.tx_hash() << " mix_attr=" << td.mix_attr() << ", is referenced by a transaction with mixins, ref from input with amount: " << intk.amount << ", gindex: " << gindex; + WLT_LOG_YELLOW(ss.str(), LOG_LEVEL_0); + if (m_wcallback) + m_wcallback->on_message(i_wallet2_callback::ms_yellow, ss.str()); + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.mix_attr() != CURRENCY_TO_KEY_OUT_FORCED_NO_MIX, ss.str()); // if mix_attr == 1 this should never happen (mixing in an output with mix_attr = 1) as the core must reject such txs + // our own output has mix_attr != 1 for some reason (a sender did not set correct mix_attr e.g.) + // but mixin count > 1 so we can't say it is spent for sure + tid = UINT64_MAX; + continue; + } + WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_spent_height == 0, "transfer is spent in blockchain, tid: " << tid << ", ref from input with amount: " << intk.amount << ", gindex: " << gindex); + // okay, own output is being spent, return it + break; + } + } + return tid; +} +//---------------------------------------------------------------------------------------------------- void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed) { //get transaction pool content @@ -1663,12 +1677,29 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed) auto& in = tx.vin[i]; if (in.type() == typeid(currency::txin_to_key)) { - auto it = m_key_images.find(boost::get(in).k_image); - if (it != m_key_images.end()) + const currency::txin_to_key& intk = boost::get(in); + uint64_t tid = UINT64_MAX; + if (is_auditable() && is_watch_only()) { - tx_money_spent_in_ins += boost::get(in).amount; + // tracking wallet, assuming all outputs are spent directly because of mix_attr = 1 + tid = get_directly_spent_transfer_id_by_input_in_tracking_wallet(intk); + } + else + { + // wallet with spend secret key -- we can calculate own key images and then search among them + auto it = m_key_images.find(intk.k_image); + if (it != m_key_images.end()) + { + tid = it->second; + } + } + + if (tid != UINT64_MAX) + { + // own output is being spent by this input + tx_money_spent_in_ins += intk.amount; td.spent_indices.push_back(i); - spend_transfers.push_back(it->second); + spend_transfers.push_back(tid); } } else if (in.type() == typeid(currency::txin_multisig)) @@ -4281,7 +4312,7 @@ bool wallet2::is_transfer_ready_to_go(const transfer_details& td, uint64_t fake_ void wallet2::wipeout_extra_if_needed(std::vector& transfer_history) { WLT_LOG_L0("Processing [wipeout_extra_if_needed]..."); - for (auto it = transfer_history.begin(); it != transfer_history.end(); ) + for (auto it = transfer_history.begin(); it != transfer_history.end(); it++ ) { if (it->height > 638000) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 4f3a5b48..e0507696 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -936,6 +936,7 @@ private: //void check_if_block_matched(uint64_t i, const crypto::hash& id, bool& block_found, bool& block_matched, bool& full_reset_needed); uint64_t detach_from_block_ids(uint64_t height); uint64_t get_wallet_minimum_height(); + uint64_t get_directly_spent_transfer_id_by_input_in_tracking_wallet(const currency::txin_to_key& intk); void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector& extra); void remove_transfer_from_amount_gindex_map(uint64_t tid); diff --git a/tests/core_tests/multisig_wallet_tests.cpp b/tests/core_tests/multisig_wallet_tests.cpp index 9bc3be84..88c86b24 100644 --- a/tests/core_tests/multisig_wallet_tests.cpp +++ b/tests/core_tests/multisig_wallet_tests.cpp @@ -1622,7 +1622,7 @@ multisig_and_checkpoints::multisig_and_checkpoints() bool multisig_and_checkpoints::set_cp(currency::core& c, size_t ev_index, const std::vector& events) { currency::checkpoints checkpoints; - checkpoints.add_checkpoint(15, "72d63d6500c62d6783108f5a2e2c9f1dc1f0aae57011cf123583eec679a52cf9"); + checkpoints.add_checkpoint(15, "6f9194c144afd73077478e7f04e947c50160b5673558e6f696a4f662a3ca261e"); c.set_checkpoints(std::move(checkpoints)); return true; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index cb202875..bd23fdf0 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -934,7 +934,7 @@ bool gen_crypted_attachments::check_crypted_tx(currency::core& c, size_t ev_inde std::vector at; bool r = currency::decrypt_payload_items(true, *ptx_from_bc, bob_acc.get_keys(), at); CHECK_EQ(r, true); - CHECK_EQ(at.size(), 7); // custom attachments: 1) tx_payer, 2) tx_comment, 3) std::string; system attachments: 4) tx_crypto_checksum; system extra: 5) tx pub key, 6) extra_attachment_info + CHECK_EQ(at.size(), 8); // custom attachments: 1) tx_payer, 2) tx_comment, 3) std::string; system attachments: 4) tx_crypto_checksum; system extra: 5) tx pub key, 6) extra_attachment_info, 7) etc_tx_flags16_t currency::tx_payer decrypted_pr = AUTO_VAL_INIT(decrypted_pr); r = get_type_in_variant_container(at, decrypted_pr);